关于我开发的idea插件(Markdown HTML Syntax Highlighter)
背景
我真的非常疑惑,为什么idea的markdown插件对markdown文本中的简单html语法不支持高亮显示(但是复杂html语法和代码块指定的html的片段是可以高亮的)。我直接写一行html闭合标签是没有语法高亮的,我真的非常疑惑。
算了,直接写一个idea插件吧,大概可能也就20多行代码
实现
这种寻找左标签和匹配标签,像聪明的人直接用栈来写了。
简单写一下,大概是这样写的
val openingTagsStack = Stack<String>()
for (element in elements) {
if (isOpeningTag(element)) {
openingTagsStack.push(getTagName(element))
} else if (isClosingTag(element)) {
if (!openingTagsStack.isEmpty() && openingTagsStack.peek() == getTagName(element)) {
openingTagsStack.pop()
} else {
// 处理不匹配的闭合标签
highlightError(element)
}
}
}
但是我是个啥b,直接正则,求助美国朋友给我生成一个正则表达式
private val HTML_TAG_PATTERN = Regex(
"</?([a-zA-Z][a-zA-Z0-9]*)(\\s+[^>]*)?>|<([a-zA-Z][a-zA-Z0-9]*)(\\s+[^>]*)?/>"
)
private val HTML_TAG_NAME_PATTERN = Regex("</?([a-zA-Z][a-zA-Z0-9]*)")
private val HTML_ATTRIBUTE_PATTERN = Regex("([a-zA-Z][a-zA-Z0-9-]*)\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)")
private val HTML_COMMENT_PATTERN = Regex("<!--[\\s\\S]*?-->")
当当当,生成好了
学过正则表达式的小伙伴们也许可以看出来,HTML_TAG_PATTERN是匹配html标签的,HTML_TAG_NAME_PATTERN是匹配标签名的,HTML_ATTRIBUTE_PATTERN是匹配属性的,HTML_COMMENT_PATTERN是匹配注释的
接下来该怎么做呢??
当然是寻找匹配的元素啦
if (!HTML_TAG_PATTERN.containsMatchIn(text) && !HTML_COMMENT_PATTERN.containsMatchIn(text)) {
return
}
有人问,这样效率是不是低了,没有一些剪枝的部分??
那这些肯定不关我事了,遇到问题再优化吧,你就说功能有没有实现吧
后面又怎么写呢??
这还要问,肯定是找插件的Api进行高亮显示啦
HTML_COMMENT_PATTERN.findAll(text).forEach { matchResult ->
val start = baseOffset + matchResult.range.first
val end = baseOffset + matchResult.range.last + 1
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
.range(TextRange(start, end))
.textAttributes(DefaultLanguageHighlighterColors.BLOCK_COMMENT)
.create()
}
这样之后再进行打包测试就行了,这对大家来说有手就行
