From 7e2809754f799e79724e3cb17c6113bd6a735513 Mon Sep 17 00:00:00 2001 From: Abby Berkers Date: Sat, 30 Dec 2023 20:59:24 +0100 Subject: [PATCH 1/2] Fix #3336: disable alignment of & in \url commands in table --- .../formatting/spacingrules/TableAlignRule.kt | 6 ++++- .../hannahsten/texifyidea/util/parser/Psi.kt | 10 +++++++++ .../texifyidea/formatting/TableAlignTest.kt | 22 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/nl/hannahsten/texifyidea/formatting/spacingrules/TableAlignRule.kt b/src/nl/hannahsten/texifyidea/formatting/spacingrules/TableAlignRule.kt index 1f068c2d8..91077ff44 100644 --- a/src/nl/hannahsten/texifyidea/formatting/spacingrules/TableAlignRule.kt +++ b/src/nl/hannahsten/texifyidea/formatting/spacingrules/TableAlignRule.kt @@ -11,6 +11,7 @@ import nl.hannahsten.texifyidea.psi.getEnvironmentName import nl.hannahsten.texifyidea.util.getIndent import nl.hannahsten.texifyidea.util.magic.EnvironmentMagic import nl.hannahsten.texifyidea.util.parser.firstParentOfType +import nl.hannahsten.texifyidea.util.parser.inUrl import kotlin.math.min /** At this length, we put table cells on their own line. */ @@ -20,9 +21,10 @@ const val LINE_LENGTH = 80 * Align spaces to the right of & */ fun rightTableSpaceAlign(latexCommonSettings: CommonCodeStyleSettings, parent: ASTBlock, left: ASTBlock): Spacing? { - // Only add spaces after &, unless escaped + // Only add spaces after &, unless escaped or inside url. if (left.node?.text?.endsWith("&") == false) return null if (left.node?.text?.endsWith("\\&") == true) return null + if (left.node?.psi?.inUrl() == true) return null if (parent.node?.psi?.firstParentOfType(LatexEnvironmentContent::class) ?.firstParentOfType(LatexEnvironment::class)?.getEnvironmentName() !in EnvironmentMagic.getAllTableEnvironments( @@ -43,6 +45,8 @@ fun rightTableSpaceAlign(latexCommonSettings: CommonCodeStyleSettings, parent: A * Align spaces to the left of & or \\ */ fun leftTableSpaceAlign(latexCommonSettings: CommonCodeStyleSettings, parent: ASTBlock, right: ASTBlock): Spacing? { + if (right.node?.psi?.inUrl() == true) return null + // Check if parent is in environment content of a table environment val contentElement = parent.node?.psi?.firstParentOfType(LatexEnvironmentContent::class) val project = parent.node?.psi?.project ?: ProjectManager.getInstance().defaultProject diff --git a/src/nl/hannahsten/texifyidea/util/parser/Psi.kt b/src/nl/hannahsten/texifyidea/util/parser/Psi.kt index f71b1967e..e05bfa7af 100644 --- a/src/nl/hannahsten/texifyidea/util/parser/Psi.kt +++ b/src/nl/hannahsten/texifyidea/util/parser/Psi.kt @@ -17,6 +17,7 @@ import nl.hannahsten.texifyidea.lang.DefaultEnvironment import nl.hannahsten.texifyidea.lang.Environment import nl.hannahsten.texifyidea.lang.magic.TextBasedMagicCommentParser import nl.hannahsten.texifyidea.psi.* +import nl.hannahsten.texifyidea.util.magic.CommandMagic import nl.hannahsten.texifyidea.util.magic.EnvironmentMagic import kotlin.reflect.KClass @@ -179,6 +180,15 @@ fun PsiElement.inComment() = inDirectEnvironmentContext(Environment.Context.COMM else -> this is LeafPsiElement && elementType == LatexTypes.COMMAND_TOKEN } +/** + * Check if the element is in a url command. + */ +fun PsiElement?.inUrl(): Boolean { + return this?.hasParentMatching(100) { + (it as? LatexCommands)?.name in CommandMagic.urls + } ?: false +} + /** * Checks if the element is inside a verbatim context. */ diff --git a/test/nl/hannahsten/texifyidea/formatting/TableAlignTest.kt b/test/nl/hannahsten/texifyidea/formatting/TableAlignTest.kt index fdb5e0683..23d137a5b 100644 --- a/test/nl/hannahsten/texifyidea/formatting/TableAlignTest.kt +++ b/test/nl/hannahsten/texifyidea/formatting/TableAlignTest.kt @@ -375,6 +375,28 @@ class TableAlignTest : BasePlatformTestCase() { """.trimIndent() } + fun testAmpersandsInUrl() { + """ + \documentclass{article} + \usepackage{hyperref} + \begin{document} + \begin{tabular}{ll} + a & \url{https://youtu.be/dQw4w9WgXcQ?si=SHq6ADlwRNZ1hwOB&t=18} & c \\ + be & \url{https://youtu.be/dQw4w9WgXcQ?si=SHq6ADlwRNZ1hwOB&t=18} & d + \end{tabular} + \end{document} + """.trimIndent() `should be reformatted to` """ + \documentclass{article} + \usepackage{hyperref} + \begin{document} + \begin{tabular}{ll} + a & \url{https://youtu.be/dQw4w9WgXcQ?si=SHq6ADlwRNZ1hwOB&t=18} & c \\ + be & \url{https://youtu.be/dQw4w9WgXcQ?si=SHq6ADlwRNZ1hwOB&t=18} & d + \end{tabular} + \end{document} + """.trimIndent() + } + fun testVeryWideTable() { val start = """ \documentclass[11pt]{article} From 7cb227a46b6669c3001c0e4ffde41a33725599e5 Mon Sep 17 00:00:00 2001 From: Abby Berkers Date: Sun, 14 Jan 2024 11:55:22 +0100 Subject: [PATCH 2/2] #3336: Disable alignment of & when parsed as raw text inside table --- .../formatting/spacingrules/TableAlignRule.kt | 6 +++--- src/nl/hannahsten/texifyidea/util/parser/Psi.kt | 10 ---------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/nl/hannahsten/texifyidea/formatting/spacingrules/TableAlignRule.kt b/src/nl/hannahsten/texifyidea/formatting/spacingrules/TableAlignRule.kt index 91077ff44..39665c6c3 100644 --- a/src/nl/hannahsten/texifyidea/formatting/spacingrules/TableAlignRule.kt +++ b/src/nl/hannahsten/texifyidea/formatting/spacingrules/TableAlignRule.kt @@ -7,11 +7,11 @@ import com.intellij.psi.codeStyle.CommonCodeStyleSettings import nl.hannahsten.texifyidea.formatting.createSpacing import nl.hannahsten.texifyidea.psi.LatexEnvironment import nl.hannahsten.texifyidea.psi.LatexEnvironmentContent +import nl.hannahsten.texifyidea.psi.LatexTypes import nl.hannahsten.texifyidea.psi.getEnvironmentName import nl.hannahsten.texifyidea.util.getIndent import nl.hannahsten.texifyidea.util.magic.EnvironmentMagic import nl.hannahsten.texifyidea.util.parser.firstParentOfType -import nl.hannahsten.texifyidea.util.parser.inUrl import kotlin.math.min /** At this length, we put table cells on their own line. */ @@ -24,7 +24,7 @@ fun rightTableSpaceAlign(latexCommonSettings: CommonCodeStyleSettings, parent: A // Only add spaces after &, unless escaped or inside url. if (left.node?.text?.endsWith("&") == false) return null if (left.node?.text?.endsWith("\\&") == true) return null - if (left.node?.psi?.inUrl() == true) return null + if (left.node?.elementType == LatexTypes.RAW_TEXT_TOKEN || parent.node?.elementType == LatexTypes.RAW_TEXT) return null if (parent.node?.psi?.firstParentOfType(LatexEnvironmentContent::class) ?.firstParentOfType(LatexEnvironment::class)?.getEnvironmentName() !in EnvironmentMagic.getAllTableEnvironments( @@ -45,7 +45,7 @@ fun rightTableSpaceAlign(latexCommonSettings: CommonCodeStyleSettings, parent: A * Align spaces to the left of & or \\ */ fun leftTableSpaceAlign(latexCommonSettings: CommonCodeStyleSettings, parent: ASTBlock, right: ASTBlock): Spacing? { - if (right.node?.psi?.inUrl() == true) return null + if (right.node?.elementType == LatexTypes.RAW_TEXT_TOKEN || parent.node?.elementType == LatexTypes.RAW_TEXT) return null // Check if parent is in environment content of a table environment val contentElement = parent.node?.psi?.firstParentOfType(LatexEnvironmentContent::class) diff --git a/src/nl/hannahsten/texifyidea/util/parser/Psi.kt b/src/nl/hannahsten/texifyidea/util/parser/Psi.kt index e05bfa7af..f71b1967e 100644 --- a/src/nl/hannahsten/texifyidea/util/parser/Psi.kt +++ b/src/nl/hannahsten/texifyidea/util/parser/Psi.kt @@ -17,7 +17,6 @@ import nl.hannahsten.texifyidea.lang.DefaultEnvironment import nl.hannahsten.texifyidea.lang.Environment import nl.hannahsten.texifyidea.lang.magic.TextBasedMagicCommentParser import nl.hannahsten.texifyidea.psi.* -import nl.hannahsten.texifyidea.util.magic.CommandMagic import nl.hannahsten.texifyidea.util.magic.EnvironmentMagic import kotlin.reflect.KClass @@ -180,15 +179,6 @@ fun PsiElement.inComment() = inDirectEnvironmentContext(Environment.Context.COMM else -> this is LeafPsiElement && elementType == LatexTypes.COMMAND_TOKEN } -/** - * Check if the element is in a url command. - */ -fun PsiElement?.inUrl(): Boolean { - return this?.hasParentMatching(100) { - (it as? LatexCommands)?.name in CommandMagic.urls - } ?: false -} - /** * Checks if the element is inside a verbatim context. */