-
-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3081 from Hannah-Sten/inspection/suspicious-sec-f…
…ormat Add inspection for suspicious formatting in section-like commands
- Loading branch information
Showing
5 changed files
with
176 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
resources/inspectionDescriptions/LatexSuspiciousSectionFormatting.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<html> | ||
<body> | ||
Reports usages of <tt>~</tt> and <tt>\\</tt> in a Section-like command and suggests to add an optional argument to the | ||
command. | ||
<p> | ||
This inspection is based on the following paragraph from The LaTeX Companion (2nd edition, page 23): | ||
<p> | ||
If you try to advise TeX on how to split the heading over a few lines using the '~' symbol so the '\\' command, then | ||
side effects may result when formatting the table of contents or generating the running head. | ||
In this case the simplest solution is to repeat the heading text without the specific markup in the optional | ||
parameter of the sectioning command. | ||
<!-- tooltip end --> | ||
</body> | ||
</html> |
80 changes: 80 additions & 0 deletions
80
...n/texifyidea/inspections/latex/probablebugs/LatexSuspiciousSectionFormattingInspection.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package nl.hannahsten.texifyidea.inspections.latex.probablebugs | ||
|
||
import com.intellij.codeInspection.InspectionManager | ||
import com.intellij.codeInspection.LocalQuickFix | ||
import com.intellij.codeInspection.ProblemDescriptor | ||
import com.intellij.codeInspection.ProblemHighlightType | ||
import com.intellij.openapi.project.Project | ||
import com.intellij.openapi.util.TextRange | ||
import com.intellij.psi.PsiFile | ||
import com.intellij.webSymbols.references.WebSymbolReferenceProvider.Companion.startOffsetIn | ||
import nl.hannahsten.texifyidea.inspections.InsightGroup | ||
import nl.hannahsten.texifyidea.inspections.TexifyInspectionBase | ||
import nl.hannahsten.texifyidea.psi.LatexCommands | ||
import nl.hannahsten.texifyidea.psi.LatexPsiHelper | ||
import nl.hannahsten.texifyidea.psi.LatexRequiredParam | ||
import nl.hannahsten.texifyidea.util.containsAny | ||
import nl.hannahsten.texifyidea.util.files.commandsInFile | ||
import nl.hannahsten.texifyidea.util.firstChildOfType | ||
import nl.hannahsten.texifyidea.util.magic.CommandMagic | ||
import nl.hannahsten.texifyidea.util.requiredParameter | ||
|
||
open class LatexSuspiciousSectionFormattingInspection : TexifyInspectionBase() { | ||
|
||
override val inspectionGroup = InsightGroup.LATEX | ||
|
||
override fun getDisplayName() = "Suspicious formatting in the required argument of a sectioning command" | ||
|
||
override val inspectionId = "SuspiciousSectionFormatting" | ||
|
||
override fun inspectFile(file: PsiFile, manager: InspectionManager, isOntheFly: Boolean): List<ProblemDescriptor> { | ||
return file.commandsInFile() | ||
.asSequence() | ||
.filter { it.name in CommandMagic.sectionMarkers } | ||
.filter { it.optionalParameterMap.isEmpty() } | ||
.filter { it.requiredParameter(0)?.containsAny(formatting) == true } | ||
.map { psiElement -> | ||
val requiredParam = psiElement.firstChildOfType(LatexRequiredParam::class) | ||
// Plus 1 for the opening brace. | ||
val startOffset = requiredParam?.startOffsetIn(psiElement)?.plus(1) ?: 0 | ||
// Minus 2 for the braces surrounding the parameter. | ||
val endOffset = requiredParam?.textLength?.minus(2)?.plus(startOffset) ?: psiElement.textLength | ||
manager.createProblemDescriptor( | ||
psiElement, | ||
TextRange(startOffset, endOffset), | ||
"Suspicious formatting in ${psiElement.name}", | ||
ProblemHighlightType.WARNING, | ||
isOntheFly, | ||
AddOptionalArgumentQuickFix() | ||
) | ||
} | ||
.toList() | ||
} | ||
|
||
class AddOptionalArgumentQuickFix : LocalQuickFix { | ||
|
||
override fun getFamilyName(): String { | ||
return "Fix formatting in table of contents and running head" | ||
} | ||
|
||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { | ||
val command = descriptor.psiElement as LatexCommands | ||
val requiredParamText = command.requiredParameter(0) | ||
val optionalParamText = requiredParamText?.replace(Regex(formatting.joinToString("", prefix = "[", postfix = "]")), " ") | ||
?: return | ||
val optionalArgument = LatexPsiHelper(project).createOptionalParameter(optionalParamText) | ||
|
||
command.addAfter(optionalArgument, command.commandToken) | ||
// Create a new command and completely replace the old command so all the psi methods will recompute instead | ||
// of using old values from their cache. | ||
val newCommand = LatexPsiHelper(project).createFromText(command.text).firstChildOfType(LatexCommands::class) | ||
?: return | ||
command.replace(newCommand) | ||
} | ||
} | ||
|
||
companion object { | ||
|
||
val formatting = setOf("~", "\\\\") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
...xifyidea/inspections/latex/probablebugs/LatexSuspiciousSectionFormattingInspectionTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package nl.hannahsten.texifyidea.inspections.latex.probablebugs | ||
|
||
import nl.hannahsten.texifyidea.file.LatexFileType | ||
import nl.hannahsten.texifyidea.inspections.TexifyInspectionTestBase | ||
|
||
internal class LatexSuspiciousSectionFormattingInspectionTest : TexifyInspectionTestBase(LatexSuspiciousSectionFormattingInspection()) { | ||
|
||
fun `test ~ warning`() { | ||
myFixture.configureByText( | ||
LatexFileType, | ||
"\\section{<warning descr=\"Suspicious formatting in \\section\">You should not use~in the title of a section</warning>}" | ||
) | ||
myFixture.checkHighlighting(true, false, true, false) | ||
} | ||
|
||
fun `test ~ warning for short section`() { | ||
myFixture.configureByText( | ||
LatexFileType, | ||
"\\section{<warning descr=\"Suspicious formatting in \\section\">a~b</warning>}" | ||
) | ||
myFixture.checkHighlighting(true, false, true, false) | ||
} | ||
|
||
fun `test backslash warning`() { | ||
myFixture.configureByText( | ||
LatexFileType, | ||
"\\section{<warning descr=\"Suspicious formatting in \\section\">You should not use\\\\in the title of a section</warning>}" | ||
) | ||
myFixture.checkHighlighting(true, false, true, false) | ||
} | ||
|
||
fun `test multiple warnings in one section`() { | ||
myFixture.configureByText( | ||
LatexFileType, | ||
"\\section{<warning descr=\"Suspicious formatting in \\section\">You should not use~in the title~of a section</warning>}" | ||
) | ||
myFixture.checkHighlighting(true, false, true, false) | ||
} | ||
|
||
fun `test no warning for ~ when optional argument is present`() { | ||
myFixture.configureByText( | ||
LatexFileType, | ||
"\\section[Table of contents long title]{Title with explicit~formatting}" | ||
) | ||
myFixture.checkHighlighting(true, false, true, false) | ||
} | ||
|
||
fun `test no warning for backslash when optional argument is present`() { | ||
myFixture.configureByText( | ||
LatexFileType, | ||
"\\section[Table of contents long title]{Title with explicit \\\\ formatting}" | ||
) | ||
myFixture.checkHighlighting(true, false, true, false) | ||
} | ||
|
||
fun `test simple quickfix for ~`() { | ||
myFixture.configureByText( | ||
LatexFileType, | ||
"\\section{You should not use~in the title}" | ||
) | ||
testQuickFix("\\section{You should not use~in the title}", "\\section[You should not use in the title]{You should not use~in the title}") | ||
myFixture.checkHighlighting(true, false, true, false) | ||
} | ||
|
||
fun `test simple quickfix for backslash`() { | ||
myFixture.configureByText( | ||
LatexFileType, | ||
"\\section{You should not use~in the title}" | ||
) | ||
testQuickFix("\\section{You should not use \\\\ in the title}", "\\section[You should not use in the title]{You should not use \\\\ in the title}") | ||
myFixture.checkHighlighting(true, false, true, false) | ||
} | ||
} |