|
17 | 17 |
|
18 | 18 | public class XMLEditor extends Application { |
19 | 19 |
|
20 | | - private static final Pattern XML_TAG = Pattern.compile("(?<ELEMENT>(</?)(\\w+)([^<>]*)(/?>))" |
| 20 | + private static final Pattern XML_TAG = Pattern.compile("(?<ELEMENT>(</?\\h*)(\\w+)([^<>]*)(\\h*/?>))" |
21 | 21 | +"|(?<COMMENT><!--[^<>]+-->)"); |
22 | 22 |
|
23 | 23 | private static final Pattern ATTRIBUTES = Pattern.compile("(\\w+\\h*)(=)(\\h*\"[^\"]+\")"); |
| 24 | + |
| 25 | + private static final int GROUP_OPEN_BRACKET = 2; |
| 26 | + private static final int GROUP_ELEMENT_NAME = 3; |
| 27 | + private static final int GROUP_ATTRIBUTES_SECTION = 4; |
| 28 | + private static final int GROUP_CLOSE_BRACKET = 5; |
| 29 | + private static final int GROUP_ATTRIBUTE_NAME = 1; |
| 30 | + private static final int GROUP_EQUAL_SYMBOL = 2; |
| 31 | + private static final int GROUP_ATTRIBUTE_VALUE = 3; |
24 | 32 |
|
25 | 33 | private static final String sampleCode = String.join("\n", new String[] { |
26 | 34 | "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>", |
27 | 35 | "<!-- Sample XML -->", |
28 | | - "<orders>", |
| 36 | + "< orders >", |
29 | 37 | " <Order number=\"1\" table=\"center\">", |
30 | 38 | " <items>", |
31 | 39 | " <Item>", |
@@ -92,28 +100,30 @@ private static StyleSpans<Collection<String>> computeHighlighting(String text) { |
92 | 100 | } |
93 | 101 | else { |
94 | 102 | if(matcher.group("ELEMENT") != null) { |
95 | | - String openBracket = matcher.group(2); |
96 | | - String elementName = matcher.group(3); |
97 | | - String attributesText = matcher.group(4); |
98 | | - String closeBracket = matcher.group(5); |
| 103 | + String attributesText = matcher.group(GROUP_ATTRIBUTES_SECTION); |
99 | 104 |
|
100 | | - spansBuilder.add(Collections.singleton("tagmark"), openBracket.length()); |
101 | | - spansBuilder.add(Collections.singleton("anytag"), elementName.length()); |
| 105 | + spansBuilder.add(Collections.singleton("tagmark"), matcher.end(GROUP_OPEN_BRACKET) - matcher.start(GROUP_OPEN_BRACKET)); |
| 106 | + spansBuilder.add(Collections.singleton("anytag"), matcher.end(GROUP_ELEMENT_NAME) - matcher.end(GROUP_OPEN_BRACKET)); |
| 107 | + |
102 | 108 | if(!attributesText.isEmpty()) { |
103 | 109 |
|
104 | | - int lastAttrEnd = 0; |
| 110 | + lastKwEnd = 0; |
105 | 111 |
|
106 | 112 | Matcher amatcher = ATTRIBUTES.matcher(attributesText); |
107 | 113 | while(amatcher.find()) { |
108 | | - spansBuilder.add(Collections.emptyList(), amatcher.start() - lastAttrEnd); |
109 | | - spansBuilder.add(Collections.singleton("attribute"), amatcher.group(1).length()); |
110 | | - spansBuilder.add(Collections.singleton("tagmark"), amatcher.group(2).length()); |
111 | | - spansBuilder.add(Collections.singleton("avalue"), amatcher.group(3).length()); |
112 | | - lastAttrEnd = amatcher.end(); |
| 114 | + spansBuilder.add(Collections.emptyList(), amatcher.start() - lastKwEnd); |
| 115 | + spansBuilder.add(Collections.singleton("attribute"), amatcher.end(GROUP_ATTRIBUTE_NAME) - amatcher.start(GROUP_ATTRIBUTE_NAME)); |
| 116 | + spansBuilder.add(Collections.singleton("tagmark"), amatcher.end(GROUP_EQUAL_SYMBOL) - amatcher.end(GROUP_ATTRIBUTE_NAME)); |
| 117 | + spansBuilder.add(Collections.singleton("avalue"), amatcher.end(GROUP_ATTRIBUTE_VALUE) - amatcher.end(GROUP_EQUAL_SYMBOL)); |
| 118 | + lastKwEnd = amatcher.end(); |
113 | 119 | } |
| 120 | + if(attributesText.length() > lastKwEnd) |
| 121 | + spansBuilder.add(Collections.emptyList(), attributesText.length() - lastKwEnd); |
114 | 122 | } |
| 123 | + |
| 124 | + lastKwEnd = matcher.end(GROUP_ATTRIBUTES_SECTION); |
115 | 125 |
|
116 | | - spansBuilder.add(Collections.singleton("tagmark"), closeBracket.length()); |
| 126 | + spansBuilder.add(Collections.singleton("tagmark"), matcher.end(GROUP_CLOSE_BRACKET) - lastKwEnd); |
117 | 127 | } |
118 | 128 | } |
119 | 129 | lastKwEnd = matcher.end(); |
|
0 commit comments