Allow line break shorthand tags
This commit is contained in:
+10
-8
@@ -1,7 +1,5 @@
|
|||||||
package se.ajpanton.statusbartweak.runtime.features.clock;
|
package se.ajpanton.statusbartweak.runtime.features.clock;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -94,7 +92,7 @@ final class ClockMarkupSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void applyParsedTag(StringBuilder out, TagState state, ParsedTag parsedTag) {
|
static void applyParsedTag(StringBuilder out, TagState state, ParsedTag parsedTag) {
|
||||||
if (TextUtils.isEmpty(parsedTag.name)) {
|
if (isEmpty(parsedTag.name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (parsedTag.selfClosing) {
|
if (parsedTag.selfClosing) {
|
||||||
@@ -125,7 +123,7 @@ final class ClockMarkupSupport {
|
|||||||
String literal,
|
String literal,
|
||||||
TagCategory category
|
TagCategory category
|
||||||
) {
|
) {
|
||||||
if (TextUtils.isEmpty(name) || TextUtils.isEmpty(literal)) {
|
if (isEmpty(name) || isEmpty(literal)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (category == TagCategory.FONT_COLOR) {
|
if (category == TagCategory.FONT_COLOR) {
|
||||||
@@ -140,7 +138,7 @@ final class ClockMarkupSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void closeTag(StringBuilder out, TagState state, String name) {
|
private static void closeTag(StringBuilder out, TagState state, String name) {
|
||||||
if (TextUtils.isEmpty(name)) {
|
if (isEmpty(name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String normalized = name.toLowerCase(Locale.ROOT);
|
String normalized = name.toLowerCase(Locale.ROOT);
|
||||||
@@ -187,7 +185,7 @@ final class ClockMarkupSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ParsedTag parseTagLiteral(String literal) {
|
static ParsedTag parseTagLiteral(String literal) {
|
||||||
if (TextUtils.isEmpty(literal)) {
|
if (isEmpty(literal)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String trimmed = literal.trim();
|
String trimmed = literal.trim();
|
||||||
@@ -232,7 +230,7 @@ final class ClockMarkupSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static List<Integer> findPipePositions(String markup) {
|
static List<Integer> findPipePositions(String markup) {
|
||||||
if (TextUtils.isEmpty(markup)) {
|
if (isEmpty(markup)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
ArrayList<Integer> positions = new ArrayList<>();
|
ArrayList<Integer> positions = new ArrayList<>();
|
||||||
@@ -262,7 +260,7 @@ final class ClockMarkupSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static boolean containsSecondsPattern(String pattern) {
|
static boolean containsSecondsPattern(String pattern) {
|
||||||
if (TextUtils.isEmpty(pattern)) {
|
if (isEmpty(pattern)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
boolean insideTag = false;
|
boolean insideTag = false;
|
||||||
@@ -300,4 +298,8 @@ final class ClockMarkupSupport {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isEmpty(CharSequence value) {
|
||||||
|
return value == null || value.length() == 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-9
@@ -1,7 +1,5 @@
|
|||||||
package se.ajpanton.statusbartweak.runtime.features.clock;
|
package se.ajpanton.statusbartweak.runtime.features.clock;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -42,6 +40,13 @@ final class ClockPatternParser {
|
|||||||
rowMarkup = new StringBuilder();
|
rowMarkup = new StringBuilder();
|
||||||
ClockMarkupSupport.appendOpenTags(rowMarkup, carriedState);
|
ClockMarkupSupport.appendOpenTags(rowMarkup, carriedState);
|
||||||
rowSyntaxError = false;
|
rowSyntaxError = false;
|
||||||
|
if (!isEmpty(lineBreak.trailingShorthand)) {
|
||||||
|
try {
|
||||||
|
appendShorthandBlock(rowMarkup, rowState, lineBreak.trailingShorthand);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
rowSyntaxError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
gapBeforePx = lineBreak.gapBeforePx;
|
gapBeforePx = lineBreak.gapBeforePx;
|
||||||
index = lineBreak.endIndex;
|
index = lineBreak.endIndex;
|
||||||
continue;
|
continue;
|
||||||
@@ -111,7 +116,7 @@ final class ClockPatternParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ClockParsedPattern.ClockParsedRow buildParsedRow(String markup, int gapBeforePx) {
|
private ClockParsedPattern.ClockParsedRow buildParsedRow(String markup, int gapBeforePx) {
|
||||||
if (TextUtils.isEmpty(markup)) {
|
if (isEmpty(markup)) {
|
||||||
return ClockParsedPattern.ClockParsedRow.plain("", gapBeforePx);
|
return ClockParsedPattern.ClockParsedRow.plain("", gapBeforePx);
|
||||||
}
|
}
|
||||||
List<Integer> pipePositions = ClockMarkupSupport.findPipePositions(markup);
|
List<Integer> pipePositions = ClockMarkupSupport.findPipePositions(markup);
|
||||||
@@ -153,7 +158,7 @@ final class ClockPatternParser {
|
|||||||
}
|
}
|
||||||
ArrayList<String> tokens = tokenizeShorthand(trimmed);
|
ArrayList<String> tokens = tokenizeShorthand(trimmed);
|
||||||
for (String token : tokens) {
|
for (String token : tokens) {
|
||||||
if (TextUtils.isEmpty(token)) {
|
if (isEmpty(token)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ("/font".equalsIgnoreCase(token)) {
|
if ("/font".equalsIgnoreCase(token)) {
|
||||||
@@ -260,6 +265,10 @@ final class ClockPatternParser {
|
|||||||
&& value.endsWith(")");
|
&& value.endsWith(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isEmpty(CharSequence value) {
|
||||||
|
return value == null || value.length() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
private void openClockColorTag(
|
private void openClockColorTag(
|
||||||
StringBuilder out,
|
StringBuilder out,
|
||||||
ClockMarkupSupport.TagState tagState,
|
ClockMarkupSupport.TagState tagState,
|
||||||
@@ -281,7 +290,7 @@ final class ClockPatternParser {
|
|||||||
|
|
||||||
private LineBreakToken tryParseLineBreak(String pattern, int index) {
|
private LineBreakToken tryParseLineBreak(String pattern, int index) {
|
||||||
if (pattern.startsWith("\\n", index)) {
|
if (pattern.startsWith("\\n", index)) {
|
||||||
return new LineBreakToken(index + 2, false, ROW_GAP_AUTO);
|
return new LineBreakToken(index + 2, false, ROW_GAP_AUTO, "");
|
||||||
}
|
}
|
||||||
if (pattern.charAt(index) != '{') {
|
if (pattern.charAt(index) != '{') {
|
||||||
return null;
|
return null;
|
||||||
@@ -296,10 +305,11 @@ final class ClockPatternParser {
|
|||||||
resetPropagation = true;
|
resetPropagation = true;
|
||||||
body = body.substring(1).trim();
|
body = body.substring(1).trim();
|
||||||
}
|
}
|
||||||
if (!body.startsWith("\\n")) {
|
ArrayList<String> tokens = tokenizeShorthand(body);
|
||||||
|
if (tokens.isEmpty() || !tokens.get(0).startsWith("\\n")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String gapText = body.substring(2).trim();
|
String gapText = tokens.get(0).substring(2).trim();
|
||||||
int gapBeforePx = ROW_GAP_AUTO;
|
int gapBeforePx = ROW_GAP_AUTO;
|
||||||
if (!gapText.isEmpty()) {
|
if (!gapText.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
@@ -308,18 +318,27 @@ final class ClockPatternParser {
|
|||||||
throw new IllegalArgumentException("Invalid row gap", e);
|
throw new IllegalArgumentException("Invalid row gap", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new LineBreakToken(end + 1, resetPropagation, gapBeforePx);
|
StringBuilder trailingShorthand = new StringBuilder();
|
||||||
|
for (int i = 1; i < tokens.size(); i++) {
|
||||||
|
if (trailingShorthand.length() > 0) {
|
||||||
|
trailingShorthand.append(' ');
|
||||||
|
}
|
||||||
|
trailingShorthand.append(tokens.get(i));
|
||||||
|
}
|
||||||
|
return new LineBreakToken(end + 1, resetPropagation, gapBeforePx, trailingShorthand.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class LineBreakToken {
|
private static final class LineBreakToken {
|
||||||
final int endIndex;
|
final int endIndex;
|
||||||
final boolean resetPropagation;
|
final boolean resetPropagation;
|
||||||
final int gapBeforePx;
|
final int gapBeforePx;
|
||||||
|
final String trailingShorthand;
|
||||||
|
|
||||||
LineBreakToken(int endIndex, boolean resetPropagation, int gapBeforePx) {
|
LineBreakToken(int endIndex, boolean resetPropagation, int gapBeforePx, String trailingShorthand) {
|
||||||
this.endIndex = endIndex;
|
this.endIndex = endIndex;
|
||||||
this.resetPropagation = resetPropagation;
|
this.resetPropagation = resetPropagation;
|
||||||
this.gapBeforePx = gapBeforePx;
|
this.gapBeforePx = gapBeforePx;
|
||||||
|
this.trailingShorthand = trailingShorthand != null ? trailingShorthand : "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package se.ajpanton.statusbartweak.runtime.features.clock;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public final class ClockPatternParserTest {
|
||||||
|
private final ClockPatternParser parser = new ClockPatternParser();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lineBreakBlockAcceptsFollowingShorthandTags() {
|
||||||
|
ClockParsedPattern combined = parser.parse("HH{\\n30 big}mm");
|
||||||
|
ClockParsedPattern split = parser.parse("HH{\\n30}{big}mm");
|
||||||
|
|
||||||
|
assertEquals(split.rows.size(), combined.rows.size());
|
||||||
|
assertEquals(2, combined.rows.size());
|
||||||
|
assertEquals(split.rows.get(1).gapBeforePx, combined.rows.get(1).gapBeforePx);
|
||||||
|
assertEquals(30, combined.rows.get(1).gapBeforePx);
|
||||||
|
assertEquals(split.rows.get(1).markup, combined.rows.get(1).markup);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user