You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Since Grazie works by first checking leaf elements, and if it gets null tries one level higher, we cannot return anything (e.g. literal for a command, comment for comments) other than LatexContent because then LatexContent itself will not be used as a root.
31
34
// However, we do need it as a root because we need to filter out certain things like inline math ourselves, so that we can make sure all the whitespace around ignored items is correct.
32
35
val domain =TextContent.TextDomain.PLAIN_TEXT
@@ -37,29 +40,38 @@ class LatexTextExtractor : TextExtractor() {
// Always keep newlines, as they may be the only whitespace splitting consecutive commands
62
+
.filter { text -> text !isPsiWhiteSpace|| text.text.contains("\n") }
63
+
// Skip arguments of non-text commands, but keep arguments of unknown commands, in particular if they are in the middle of a sentence
64
+
// Even commends which have no text as argument, for example certain reference commands like auteref, may need to be kept in to get correct punctuation
65
+
.filterNot { text -> text isLatexParameterText&&LatexCommand.lookup(text.firstParentOfType(LatexCommands::class)?.name)?.firstOrNull()?.arguments?.any { it.type !=Argument.Type.TEXT&& it.type !=Argument.Type.LABEL } ==true }
66
+
// Environment names are never part of a sentence
67
+
.filterNot { text -> text.firstParentOfType<LatexBeginCommand>() !=null|| text.firstParentOfType<LatexEndCommand>() !=null }
68
+
// If we encounter an unescaped &, we are in some language construct like a tabular, so we ignore this because ofter a tabular does not contain full sentences
69
+
.filter { text -> text.node.children().none { it.elementType ==LatexTypes.AMPERSAND } }
70
+
// NOTE: it is not allowed to start the text we send to Grazie with a newline! If we do, then Grazie will just not do anything. So we exclude whitespace at the start
71
+
.dropWhile { it isPsiWhiteSpace }
55
72
// Ranges that we need to keep
56
73
// Note that textRangeInParent will not be correct because that's the text range in the direct parent, not in the root
57
74
.flatMap { text ->
58
-
// Skip arguments of non-text commands
59
-
if (text isLatexParameterText&&LatexCommand.lookup(text.firstParentOfType(LatexCommands::class)?.name)?.firstOrNull()?.arguments?.any { it.type ==Argument.Type.TEXT } !=true) {
60
-
return@flatMap emptyList()
61
-
}
62
-
63
75
var start = text.textRange.startOffset - root.startOffset
64
76
// If LatexNormalText starts after a newline following a command, the newline is not part of the LatexNormalText so we include it manually to make sure that it is seen as a space between sentences
65
77
// NOTE: it is not allowed to start the text we send to Grazie with a newline! If we do, then Grazie will just not do anything. So we exclude the newline for the first normal text in the file.
@@ -71,7 +83,7 @@ class LatexTextExtractor : TextExtractor() {
71
83
72
84
// -1 Because endOffset is exclusive, but we are working with inclusive end here
73
85
var end = text.textRange.endOffset -1- root.startOffset
74
-
// If LatexNormalText ends, for example because it is followed by a command, we do want to include the space in front of the command, since it is still typeset as a space, which is not true for the space after the command
86
+
// If LatexNormalText ends, for example because it is followed by a command, we do want to include the space in front of the command, since it is still typeset as a space, which is not true for the space after the command if the command has no arguments,
75
87
// except when the space is followed by inline math, since we ignore inline math altogether (which is probably not correct) we should also ignore the space
76
88
if (setOf('', '\n').contains(rootText.getOrNull(end +1)) && rootText.getOrNull(end +2) !='$') {
77
89
end +=1
@@ -100,14 +112,10 @@ class LatexTextExtractor : TextExtractor() {
100
112
ranges.removeAll(overlapped.toSet())
101
113
ranges.add(indent.merge(overlapped))
102
114
}
103
-
// This is approximately (except at the start) the text we send to Grazie
104
-
// val text = ranges.sortedBy { it.first }.flatMap { listOf(it.first, it.last) }.toMutableList().also { it.add(0, -1) }
All <GRAMMAR_ERROR descr="The verb 'is' is singular. Did you mean: this is or those are?">those is</GRAMMAR_ERROR> problems in the middle of a sentence.
45
+
% <GRAMMAR_ERROR descr="The verb 'is' is singular. Did you mean: this is or Those are?">Those is</GRAMMAR_ERROR> a problem in a comment
46
+
<GRAMMAR_ERROR descr="The verb 'is' is singular. Did you mean: this is or Those are?">Those is</GRAMMAR_ERROR> a problem at the beginning of a sentence.
LatexFileType, """Does Grazie detect ${'$'}m$ as a sentence?"""
55
+
LatexFileType,
56
+
"""
57
+
\begin{document}
58
+
<GRAMMAR_ERROR descr="Use An instead of 'A' if the following word starts with a vowel sound, e.g. 'an article', 'an hour'.">A</GRAMMAR_ERROR> apple a day keeps the doctor away.
* These rules are not enabled by default in Grazie Lite, but do show up by default in Grazie Pro.
173
+
* To find a rule id, search for the name in https://community.languagetool.org/rule/list and use the id together with the prefex from LangTool.globalIdPrefix
myFixture.configureByText(LatexFileType, """The principles of a generic \ac{PID} controller.""")
185
+
myFixture.checkHighlighting()
186
+
}
187
+
188
+
/*
189
+
* Grazie Pro
190
+
*
191
+
* These tests only test false positives in Grazie Pro (com.intellij.grazie.pro.style.StyleInspection), but that is not possible to test at the moment: https://youtrack.jetbrains.com/issue/GRZ-5023
0 commit comments