[Editor] Improve XML syntax highlighting
This commit is contained in:
@@ -7,60 +7,54 @@ import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class XmlSyntaxHighlighter : SyntaxHighlighter {
|
||||
private val XML_TAG =
|
||||
"""(?<ELEMENT>(?<OPEN></?\h*)(?<ELEM>[\w:]+)(?<ATTRS>[^<>]*)(?<CLOSE>\h*/?>))|(?<COMMENT><!--[^<>]+-->)|(?<PROLOG><\?[^<>?]+?\?>)""".toRegex()
|
||||
|
||||
private val ATTRIBUTES = """(?<ATTR>[\w:]+\h*)(?<EQ>=)(?<VALUE>\h*"[^"]+")""".toRegex()
|
||||
|
||||
override fun highlight(code: String) = StyleSpansBuilder<Collection<String>>().let {
|
||||
var lastKwEnd = 0;
|
||||
override fun highlight(code: String) = StyleSpansBuilder<Collection<String>>().apply {
|
||||
var last = 0;
|
||||
|
||||
XML_TAG.findAll(code).forEach { matcher ->
|
||||
it.add(emptyList(), matcher.start - lastKwEnd);
|
||||
add(emptyList(), matcher.start - last);
|
||||
|
||||
when {
|
||||
matcher.groups["PROLOG"] != null -> {
|
||||
it.add(listOf("prolog"), matcher.end - matcher.start)
|
||||
add(listOf("prolog"), matcher.end - matcher.start)
|
||||
}
|
||||
|
||||
matcher.groups["COMMENT"] != null -> {
|
||||
it.add(listOf("comment"), matcher.end - matcher.start)
|
||||
add(listOf("comment"), matcher.end - matcher.start)
|
||||
}
|
||||
|
||||
matcher.groups["ELEMENT"] != null -> {
|
||||
it.add(listOf("tagmark"), matcher.end("OPEN") - matcher.start("OPEN"))
|
||||
it.add(listOf("anytag"), matcher.end("ELEM") - matcher.end("OPEN"))
|
||||
add(listOf("tagmark"), matcher.end("OPEN") - matcher.start("OPEN"))
|
||||
add(listOf("namespace"), matcher.end("NS") - matcher.end("OPEN"))
|
||||
add(listOf("anytag"), matcher.end("ELEM") - matcher.end("NS"))
|
||||
|
||||
val attributesString = matcher.groups["ATTRS"]?.let(MatchGroup::value)?.takeIf(String::isNotEmpty)
|
||||
val attributesStringLength = attributesString?.length ?: 0
|
||||
|
||||
if (attributesString?.isNotEmpty() == true) {
|
||||
lastKwEnd = 0
|
||||
last = 0
|
||||
ATTRIBUTES.findAll(attributesString).forEach { attr ->
|
||||
it.add(emptyList(), attr.range.first - lastKwEnd)
|
||||
it.add(listOf("attribute"), attr.end("ATTR") - attr.start("ATTR"))
|
||||
it.add(listOf("tagmark"), attr.end("EQ") - attr.end("ATTR"))
|
||||
it.add(listOf("avalue"), attr.end("VALUE") - attr.end("EQ"))
|
||||
lastKwEnd = attr.end
|
||||
add(emptyList(), attr.range.first - last)
|
||||
add(listOf("attribute"), attr.end("ATTR") - attr.start("ATTR"))
|
||||
add(listOf("tagmark"), attr.end("EQ") - attr.end("ATTR"))
|
||||
add(listOf("avalue"), attr.end("VALUE") - attr.end("EQ"))
|
||||
last = attr.end
|
||||
}
|
||||
|
||||
if (attributesStringLength > lastKwEnd) {
|
||||
it.add(emptyList(), attributesStringLength - lastKwEnd)
|
||||
if (attributesStringLength > last) {
|
||||
add(emptyList(), attributesStringLength - last)
|
||||
}
|
||||
}
|
||||
|
||||
lastKwEnd = matcher.end("ATTRS")
|
||||
it.add(listOf("tagmark"), matcher.end("CLOSE") - lastKwEnd)
|
||||
last = matcher.end("ATTRS")
|
||||
add(listOf("tagmark"), matcher.end("CLOSE") - last)
|
||||
}
|
||||
}
|
||||
|
||||
lastKwEnd = matcher.end
|
||||
last = matcher.end
|
||||
}
|
||||
|
||||
it.add(emptyList(), code.length - lastKwEnd)
|
||||
|
||||
it.create()
|
||||
}
|
||||
add(emptyList(), code.length - last)
|
||||
}.create()
|
||||
|
||||
private val MatchResult.start: Int
|
||||
get() = this.range.first
|
||||
@@ -68,12 +62,17 @@ class XmlSyntaxHighlighter : SyntaxHighlighter {
|
||||
private val MatchResult.end: Int
|
||||
get() = this.range.last + 1
|
||||
|
||||
private fun MatchResult.start(group: Int) = this.groups[group]?.range?.first ?: 0
|
||||
private fun MatchResult.start(group: String) = this.groups[group]?.range?.first ?: 0
|
||||
|
||||
private fun MatchResult.end(group: Int) = (this.groups[group]?.range?.last ?: 0) + 1
|
||||
private fun MatchResult.end(group: String) = (this.groups[group]?.range?.last ?: 0) + 1
|
||||
|
||||
override val stylesheet = XmlSyntaxHighlightingStylesheet()
|
||||
|
||||
companion object {
|
||||
private val XML_TAG =
|
||||
"""(?<ELEMENT>(?<OPEN></?\h*)(?<ELEM>(?<NS>\w+:)?\w+)(?<ATTRS>[^<>]*)(?<CLOSE>\h*/?>))|(?<COMMENT><!--[^<>]+-->)|(?<PROLOG><\?[^<>?]+?\?>)""".toRegex()
|
||||
|
||||
private val ATTRIBUTES = """(?<ATTR>[:\w]+\h*)(?<EQ>=)(?<VALUE>\h*"[^"]+")""".toRegex()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import tornadofx.cssclass
|
||||
class XmlSyntaxHighlightingStylesheet : Stylesheet() {
|
||||
companion object {
|
||||
val prolog by cssclass()
|
||||
val namespace by cssclass()
|
||||
val tagmark by cssclass()
|
||||
val anytag by cssclass()
|
||||
val paren by cssclass()
|
||||
@@ -25,6 +26,10 @@ class XmlSyntaxHighlightingStylesheet : Stylesheet() {
|
||||
fontStyle = FontPosture.ITALIC
|
||||
}
|
||||
|
||||
namespace {
|
||||
fill = Color.DARKRED
|
||||
}
|
||||
|
||||
tagmark {
|
||||
fill = Color.GRAY
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user