From 1a64e0e21de3294103ce932b7c04fbcfb2b2671b Mon Sep 17 00:00:00 2001 From: Julian Valentin Date: Sun, 28 Nov 2021 16:19:23 +0100 Subject: [PATCH] Add support for ConTeXt Fixes #120. --- README.md | 2 +- changelog.xml | 3 ++ .../parsing/CodeAnnotatedTextBuilder.kt | 21 ++++++---- .../ltexls/parsing/CodeFragmentizer.kt | 21 ++++++---- .../latex/LatexAnnotatedTextBuilder.kt | 42 +++++++++++++++---- .../LatexAnnotatedTextBuilderDefaults.kt | 25 +++++++++++ .../latex/LatexEnvironmentSignature.kt | 9 ++-- .../latex/LatexAnnotatedTextBuilderTest.kt | 20 ++++++++- 8 files changed, 113 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index ceed113f..23fe26b3 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Find more information (how to install, how to use, etc.) at the [website of LTEX, LATEX, Markdown, Org, reStructuredText, R Sweave, XHTML +- **Supported markup languages:** BibTEX, ConTEXt, LATEX, Markdown, Org, reStructuredText, R Sweave, XHTML - Comment checking in **many popular programming languages** (optional, opt-in) - Comes with **everything included,** no need to install Java or LanguageTool - **Offline checking:** Does not upload anything to the internet diff --git a/changelog.xml b/changelog.xml index f68c5c6c..c430af06 100644 --- a/changelog.xml +++ b/changelog.xml @@ -13,6 +13,9 @@ + + Add support for ConTeXt + Add support for strikethrough as in [GitHub Flavored Markdown](https://github.github.com/gfm/#strikethrough-extension-) diff --git a/src/main/kotlin/org/bsplines/ltexls/parsing/CodeAnnotatedTextBuilder.kt b/src/main/kotlin/org/bsplines/ltexls/parsing/CodeAnnotatedTextBuilder.kt index 1ff6ccc0..0b1b17ce 100644 --- a/src/main/kotlin/org/bsplines/ltexls/parsing/CodeAnnotatedTextBuilder.kt +++ b/src/main/kotlin/org/bsplines/ltexls/parsing/CodeAnnotatedTextBuilder.kt @@ -34,19 +34,24 @@ abstract class CodeAnnotatedTextBuilder( @Suppress("ComplexMethod") fun create(codeLanguageId: String): CodeAnnotatedTextBuilder { return when (codeLanguageId) { - "bib" -> LatexAnnotatedTextBuilder(codeLanguageId) - "bibtex" -> LatexAnnotatedTextBuilder(codeLanguageId) - "html" -> HtmlAnnotatedTextBuilder(codeLanguageId) - "latex" -> LatexAnnotatedTextBuilder(codeLanguageId) + "bib", + "bibtex", + -> LatexAnnotatedTextBuilder(codeLanguageId) + "html", + "xhtml", + -> HtmlAnnotatedTextBuilder(codeLanguageId) + "context", + "context.tex", + "latex", + "plaintex", + "rsweave", + "tex", + -> LatexAnnotatedTextBuilder(codeLanguageId) "markdown" -> MarkdownAnnotatedTextBuilder(codeLanguageId) "nop" -> NopAnnotatedTextBuilder(codeLanguageId) "org" -> OrgAnnotatedTextBuilder(codeLanguageId) - "plaintex" -> LatexAnnotatedTextBuilder(codeLanguageId) "plaintext" -> PlaintextAnnotatedTextBuilder(codeLanguageId) "restructuredtext" -> RestructuredtextAnnotatedTextBuilder(codeLanguageId) - "rsweave" -> LatexAnnotatedTextBuilder(codeLanguageId) - "tex" -> LatexAnnotatedTextBuilder(codeLanguageId) - "xhtml" -> HtmlAnnotatedTextBuilder(codeLanguageId) else -> { if (ProgramCommentRegexs.isSupportedCodeLanguageId(codeLanguageId)) { ProgramAnnotatedTextBuilder(codeLanguageId) diff --git a/src/main/kotlin/org/bsplines/ltexls/parsing/CodeFragmentizer.kt b/src/main/kotlin/org/bsplines/ltexls/parsing/CodeFragmentizer.kt index 83fead91..0a17c3f0 100644 --- a/src/main/kotlin/org/bsplines/ltexls/parsing/CodeFragmentizer.kt +++ b/src/main/kotlin/org/bsplines/ltexls/parsing/CodeFragmentizer.kt @@ -44,19 +44,24 @@ abstract class CodeFragmentizer( @Suppress("ComplexMethod") fun create(codeLanguageId: String): CodeFragmentizer { return when (codeLanguageId) { - "bib" -> BibtexFragmentizer(codeLanguageId) - "bibtex" -> BibtexFragmentizer(codeLanguageId) - "html" -> HtmlFragmentizer(codeLanguageId) - "latex" -> LatexFragmentizer(codeLanguageId) + "bib", + "bibtex", + -> BibtexFragmentizer(codeLanguageId) + "html", + "xhtml", + -> HtmlFragmentizer(codeLanguageId) + "context", + "context.tex", + "latex", + "plaintex", + "rsweave", + "tex", + -> LatexFragmentizer(codeLanguageId) "markdown" -> MarkdownFragmentizer(codeLanguageId) "nop" -> NopFragmentizer(codeLanguageId) "org" -> OrgFragmentizer(codeLanguageId) - "plaintex" -> LatexFragmentizer(codeLanguageId) "plaintext" -> PlaintextFragmentizer(codeLanguageId) "restructuredtext" -> RestructuredtextFragmentizer(codeLanguageId) - "rsweave" -> LatexFragmentizer(codeLanguageId) - "tex" -> LatexFragmentizer(codeLanguageId) - "xhtml" -> HtmlFragmentizer(codeLanguageId) else -> { if (ProgramCommentRegexs.isSupportedCodeLanguageId(codeLanguageId)) { ProgramFragmentizer(codeLanguageId) diff --git a/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilder.kt b/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilder.kt index ee90643e..66948dcf 100644 --- a/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilder.kt +++ b/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilder.kt @@ -177,18 +177,35 @@ class LatexAnnotatedTextBuilder( private fun processBackslash() { var command = matchFromPositionAsString(COMMAND_REGEX) - if ((command == "\\begin") || (command == "\\end")) { + if ( + (command == "\\begin") + || (command == "\\end") + || command.startsWith("\\start") + || command.startsWith("\\stop") + ) { this.preserveDummyLast = true - val argument: String = matchFromPositionAsString(ARGUMENT_REGEX, this.pos + command.length) - val environmentName: String = - if (argument.length >= 2) argument.substring(1, argument.length - 1) else "" + val isBeginEnvironment: Boolean = ((command == "\\begin") || command.startsWith("\\start")) + val argument: String + val environmentName: String + + if ((command == "\\begin") || (command == "\\end")) { + argument = matchFromPositionAsString(ARGUMENT_REGEX, this.pos + command.length) + environmentName = + if (argument.length >= 2) argument.substring(1, argument.length - 1) else "" + } else { + argument = "" + environmentName = command.substring( + if (isBeginEnvironment) LENGTH_OF_START_PREFIX else LENGTH_OF_STOP_PREFIX, + ) + } + var argumentsProcessed = false var interpretAs = "" if (MATH_ENVIRONMENTS.contains(environmentName)) { addMarkup(command) - if (command == "\\begin") { + if (isBeginEnvironment) { if (environmentName == "math") { enterInlineMath() } else { @@ -198,7 +215,7 @@ class LatexAnnotatedTextBuilder( popMode() interpretAs = generateDummy() } - } else if (command == "\\begin") { + } else if (isBeginEnvironment) { val possibleEnvironmentSignatures: List = this.environmentSignatureMap[command + argument] ?: emptyList() @@ -220,8 +237,11 @@ class LatexAnnotatedTextBuilder( if (matchingEnvironmentSignature != null) { if (matchingEnvironmentSignature.action == LatexCommandSignature.Action.Ignore) { this.modeStack.add(Mode.IgnoreEnvironment) - this.ignoreEnvironmentEndRegex = - Regex("^\\\\end\\{" + Regex.escape(environmentName) + "}") + this.ignoreEnvironmentEndRegex = if (command == "\\begin") { + Regex("^\\\\end\\{" + Regex.escape(environmentName) + "}") + } else { + Regex("^\\\\stop" + Regex.escape(environmentName) + "(?![A-Za-z])") + } } if (matchingEnvironmentSignature.ignoreAllArguments) { @@ -245,7 +265,7 @@ class LatexAnnotatedTextBuilder( if (!argumentsProcessed) { addMarkup(argument, interpretAs) - if (command == "\\begin") processEnvironmentArguments() + if (isBeginEnvironment) processEnvironmentArguments() } } } else if ((command == "\\$") || (command == "\\%") || (command == "\\&")) { @@ -893,6 +913,7 @@ class LatexAnnotatedTextBuilder( "equation*", "flalign", "flalign*", + "formula", "gather", "gather*", "math", @@ -900,6 +921,9 @@ class LatexAnnotatedTextBuilder( "multline*", ) + private const val LENGTH_OF_START_PREFIX = 6 + private const val LENGTH_OF_STOP_PREFIX = 5 + private fun createCommandSignatureMap( commandSignatures: List, ): Map> { diff --git a/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilderDefaults.kt b/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilderDefaults.kt index 10f5b603..c00ad452 100644 --- a/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilderDefaults.kt +++ b/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilderDefaults.kt @@ -110,6 +110,7 @@ object LatexAnnotatedTextBuilderDefaults { LatexCommandSignature("\\algnewcommand{}{}"), LatexCommandSignature("\\algrenewcommand{}{}"), LatexCommandSignature("\\arabic{}", LatexCommandSignature.Action.Dummy), + LatexCommandSignature("\\at{}[]", LatexCommandSignature.Action.Dummy), LatexCommandSignature("\\AtBeginEnvironment{}{}"), LatexCommandSignature("\\AtEndEnvironment{}{}"), LatexCommandSignature("\\autocite{}", LatexCommandSignature.Action.Dummy), @@ -402,6 +403,7 @@ object LatexAnnotatedTextBuilderDefaults { LatexCommandSignature("\\color[]{}"), LatexCommandSignature("\\colorbox{}"), LatexCommandSignature("\\colorlet{}{}"), + LatexCommandSignature("\\ConTeXt", LatexCommandSignature.Action.Dummy), LatexCommandSignature("\\counterwithin{}{}"), LatexCommandSignature("\\counterwithin*{}{}"), LatexCommandSignature("\\counterwithout{}{}"), @@ -439,6 +441,7 @@ object LatexAnnotatedTextBuilderDefaults { LatexCommandSignature("\\defbibheading{}{}"), LatexCommandSignature("\\defbibheading{}[]{}"), LatexCommandSignature("\\defbibnote{}{}"), + LatexCommandSignature("\\definecolor[][]"), LatexCommandSignature("\\definecolor{}{}{}"), LatexCommandSignature("\\definespotcolor{}{}{}"), LatexCommandSignature("\\directlua{}"), @@ -451,6 +454,7 @@ object LatexAnnotatedTextBuilderDefaults { LatexCommandSignature("\\etocsetlevel{}{}"), LatexCommandSignature("\\etocsetnexttocdepth{}"), LatexCommandSignature("\\etocsettocstyle{}{}"), + LatexCommandSignature("\\externalfigure[]", LatexCommandSignature.Action.Dummy), LatexCommandSignature("\\fcolorbox{}"), LatexCommandSignature("\\floatname{}{}"), LatexCommandSignature("\\floatstyle{}"), @@ -470,6 +474,8 @@ object LatexAnnotatedTextBuilderDefaults { "\\foreignlanguage[]{}{}", LatexCommandSignature.Action.Dummy, ), + LatexCommandSignature("\\framed[]"), + LatexCommandSignature("\\from[]", LatexCommandSignature.Action.Dummy), LatexCommandSignature("\\GenericWarning{}{}"), LatexCommandSignature("\\geometry{}"), LatexCommandSignature("\\gls{}", LatexCommandSignature.Action.Dummy), @@ -543,11 +549,13 @@ object LatexAnnotatedTextBuilderDefaults { LatexCommandSignature("\\ifentrytype{}"), LatexCommandSignature("\\@ifpackageloaded{}"), LatexCommandSignature("\\iftoggle{}"), + LatexCommandSignature("\\in[]", LatexCommandSignature.Action.Dummy), LatexCommandSignature("\\include{}"), LatexCommandSignature("\\includegraphics{}"), LatexCommandSignature("\\includegraphics[]{}"), LatexCommandSignature("\\includepdf{}"), LatexCommandSignature("\\includepdf[]{}"), + LatexCommandSignature("\\index{}"), LatexCommandSignature("\\input{}"), LatexCommandSignature("\\inputminted{}{}"), LatexCommandSignature("\\inputminted[]{}{}"), @@ -622,6 +630,9 @@ object LatexAnnotatedTextBuilderDefaults { LatexCommandSignature("\\pgfmathsetmacro{}{}"), LatexCommandSignature("\\pgfmathsetseed{}"), LatexCommandSignature("\\phantom{}"), + LatexCommandSignature("\\placefigure[]{}"), + LatexCommandSignature("\\placefigure[][]"), + LatexCommandSignature("\\placeformula[]"), LatexCommandSignature("\\printacronyms[]"), LatexCommandSignature("\\printbibliography[]"), LatexCommandSignature("\\printglossary[]"), @@ -678,7 +689,19 @@ object LatexAnnotatedTextBuilderDefaults { LatexCommandSignature("\\@setplength{}{}"), LatexCommandSignature("\\setplength{}{}"), LatexCommandSignature("\\setstretch{}"), + LatexCommandSignature("\\setupbodyfont[]"), + LatexCommandSignature("\\setupcolors[]"), + LatexCommandSignature("\\setupfooter[]"), + LatexCommandSignature("\\setupfootertexts[]"), + LatexCommandSignature("\\setuphead[][]"), + LatexCommandSignature("\\setupindenting[]"), + LatexCommandSignature("\\setupinteraction[]"), + LatexCommandSignature("\\setupitemize[]"), + LatexCommandSignature("\\setuplayout[]"), + LatexCommandSignature("\\setuppagenumbering[]"), + LatexCommandSignature("\\setuppapersize[][]"), LatexCommandSignature("\\setuptoc{}{}"), + LatexCommandSignature("\\setupwhitespace[]"), LatexCommandSignature("\\sisetup{}"), LatexCommandSignature("\\smartcite{}", LatexCommandSignature.Action.Dummy), LatexCommandSignature("\\smartcite[]{}", LatexCommandSignature.Action.Dummy), @@ -817,6 +840,7 @@ object LatexAnnotatedTextBuilderDefaults { LatexCommandSignature("\\usepackage{}"), LatexCommandSignature("\\usepackage[]{}"), LatexCommandSignature("\\usetikzlibrary{}"), + LatexCommandSignature("\\useURL[][][][]"), LatexCommandSignature("\\value{}"), LatexCommandSignature("\\vphantom{}"), LatexCommandSignature("\\vspace{}"), @@ -841,6 +865,7 @@ object LatexAnnotatedTextBuilderDefaults { LatexEnvironmentSignature("minted"), LatexEnvironmentSignature("otherlanguage"), LatexEnvironmentSignature("otherlanguage*"), + LatexEnvironmentSignature("\\starttikzpicture"), LatexEnvironmentSignature("textpos"), LatexEnvironmentSignature("textpos*"), LatexEnvironmentSignature("tikzpicture"), diff --git a/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexEnvironmentSignature.kt b/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexEnvironmentSignature.kt index ad9f69ff..3be6c595 100644 --- a/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexEnvironmentSignature.kt +++ b/src/main/kotlin/org/bsplines/ltexls/parsing/latex/LatexEnvironmentSignature.kt @@ -22,9 +22,12 @@ class LatexEnvironmentSignature( val environmentName: String? init { - val environmentName: String? = PREFIX_REGEX.find(environmentPrototype)?.groups?.get(1)?.value + val matchResult: MatchResult? = PREFIX_REGEX.find(environmentPrototype) + val environmentName: String = matchResult?.groups?.get(1)?.value.orEmpty().ifEmpty { + matchResult?.groups?.get(2)?.value.orEmpty() + } - if (environmentName != null) { + if (environmentName.isNotEmpty()) { this.ignoreAllArguments = false this.environmentName = environmentName } else { @@ -34,6 +37,6 @@ class LatexEnvironmentSignature( } companion object { - private val PREFIX_REGEX = Regex("^\\\\begin\\{([^}]+)}") + private val PREFIX_REGEX = Regex("^(?:\\\\begin\\{([^}]+)}|\\\\start([A-Za-z]+))") } } diff --git a/src/test/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilderTest.kt b/src/test/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilderTest.kt index b05fd779..fa76d8f2 100644 --- a/src/test/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilderTest.kt +++ b/src/test/kotlin/org/bsplines/ltexls/parsing/latex/LatexAnnotatedTextBuilderTest.kt @@ -453,7 +453,7 @@ class LatexAnnotatedTextBuilderTest : CodeAnnotatedTextBuilderTest("latex") { } @Test - fun testRsweaveMode() { + fun testRsweave() { assertPlainText( """ \SweaveOpts{prefix.string=figures} @@ -493,6 +493,24 @@ class LatexAnnotatedTextBuilderTest : CodeAnnotatedTextBuilderTest("latex") { ) } + @Test + fun testContext() { + assertPlainText( + """ + This is a first sentence. + + \startformula + E = mc^2 + \stopformula + + This is a second sentence. + + """.trimIndent(), + "This is a first sentence.\n\nDummy0 \n\nThis is a second sentence. ", + "context", + ) + } + private fun assertOriginalTextPositions( code: String, plainTextStartPos: Int,