Repository: hannah-sten/texify-idea
Issue: Cannot Add Quoted Arguments With Spaces To Run Configuration.

#### Type of JetBrains IDE (IntelliJ, PyCharm, etc.) and version
Dump of "about" page:
```
IntelliJ IDEA 2021.1 (Ultimate Edition)
Build #IU-211.6693.111, built on April 6, 2021
Licensed to Will Free
Subscription is active until November 26, 2021.
For educational use only.
Runtime version: 11.0.10+9-b1341.35 amd64
VM: Dynamic Code Evolution 64-Bit Server VM by JetBrains s.r.o.
Linux 5.12.1-arch1-1
GC: G1 Young Generation, G1 Old Generation
Memory: 3072M
Cores: 12
Registry: ide.balloon.shadow.size=0
Non-Bundled Plugins: Key Promoter X (2021.1.1), Statistic (4.1.7), com.floobits.unique.plugin.id (1.7.3), com.fwdekker.randomness (2.7.0), com.github.b3er.idea.plugins.arc.browser (0.23), com.intellij.ideolog (203.0.27.0), com.intellij.nativeDebug (211.6693.111), com.intellij.plugins.kdekeymap (203.5981.152), com.jetbrains.plugins.ini4idea (211.6693.44), com.ultrahob.zerolength.plugin (0.93), com.wakatime.intellij.plugin (13.0.1), net.codestats.plugin.atom.intellij (1.0.9), net.seesharpsoft.intellij.plugins.csv (2.16.3), one.util.ideaplugin.screenshoter (1.7), org.antlr.intellij.plugin (1.16), com.virtuslab.git-machete (0.9.1), com.almightyalpaca.intellij.plugins.discord (1.6.1), mobi.hsz.idea.gitignore (4.1.0), Builder Generator (1.1.8), Code Iris (2.4-beta), String Manipulation (8.15.203.000.3), com.godwin.json.parser (1.4.2), com.github.shiraji.findpullrequest (1.7.2), org.github.otanikotani.checks-plugin (1.1.9), org.jetbrains.idea.grammar (2021.1.1), org.sonarlint.idea (4.15.0.30553), zd.zero.waifu-motivator-plugin (2.0.1), net.javaru.idea.frc (1.5.0-2021.1), com.demonwav.minecraft-dev (2021.1-1.5.8), com.hotswap.agent.plugin (1.3.0), com.godwin.kdocer (1.5), com.suusan2go.kotlin-fill-class (1.0.7), zielu.gittoolbox (203.5.8), com.intellij.lang.jsgraphql (2.9.1), izhangzhihao.rainbow.brackets (6.17), ru.adelf.idea.dotenv (2021.1), PlantUML integration (5.3.0), nl.rubensten.texifyidea (0.8.0-alpha.1)
Kotlin: 211-1.4.32-release-IJ6693.72
Current Desktop: KDE
```

#### Operating System 
Arch Linux x86_64 5.12.1-arch1-1


#### TeXiFy IDEA version
0.8.0-alpha.1

#### What I did (steps to reproduce)
1. Create some super basic latex document.
2. Now, modify the run task to use the latexmk compiler.
3. Set the compiler arguments to `-g -f -xelatex -pdfxelatex="xelatex --shell-escape %O %S"` (Okay, `-g -f` is not needed. That's just what I happened to have when I found it.)
4. Compile the file.

#### Minimal example to reproduce the problem
(The document doesn't matter since the issue isn't there. Just really use whatever compiles tbh.)
```latex
\\documentclass{article}

\\begin{document}
    Hello.
\\end{document}
```

#### Expected behavior
I would expect that the list of arguments provided to `latexmk` would look like this:
```json
[
  "latexmk",
  "-output-format=pdf",
  "-output-directory=/home/solonovamax/Private/Flirting/Tex/out",
  "-g",
  "-f",
  "-xelatex",
  "-pdfxelatex=xelatex -shell-escape %O %S",
  "MainFile.tex"
]
```

#### Actual behavior
But instead of that, the arguments look like the following before running `latexmk`:
```json
[
  "latexmk",
  "-output-format=pdf",
  "-output-directory=/home/solonovamax/Private/Flirting/Tex/out",
  "-g",
  "-f",
  "-xelatex",
  "-pdfxelatex=\\"xelatex",
  "-shell-escape",
  "%O",
  "%S\\"",
  "MainFile.tex"
]
```
This means that instead of latexmk interpreting `-pdfxelatex=xelatex -shell-escape %O %S` as a single option, it interperts `-pdfxelatex=\\"xelatex`, `-shell-escape`, `%O`, `%S\\"`, each as separate options.

Here is the output when you attempt to run the task:
```
latexmk -output-format=pdf -output-directory=/home/solonovamax/Private/Flirting/Tex/out -g -f -xelatex -pdfxelatex=\\"xelatex -shell-escape %O %S\\" MainFile.tex

Rc files read:
  /home/solonovamax/.latexmkrc
Latexmk: This is Latexmk, John Collins, 29 September 2020, version: 4.70b.
Latexmk: Filename '%O' contains character not allowed for TeX file.
Latexmk: Filename '%S"' contains character not allowed for TeX file.
Latexmk: Filename '%S"' contains unbalanced quotes, not allowed.
Latexmk: Stopping because of bad filename(s).

Process finished with exit code 2.Set environment variable BIBINPUTS='/home/solonovamax/Private/Flirting/Tex/out:'
Set environment variable TEXINPUTS='/home/solonovamax/Private/Flirting/Tex/out:'
```

As you can see, it's interpreting "`-pdfxelatex=\\"xelatex`, `-shell-escape`, `%O`, `%S\\"`" as multiple arguments, rather than as a single argument like this: "`-pdfxelatex=xelatex -shell-escape %O %S`"

The specific line causing this is [`LatexCompiler#288`](https://github.com/Hannah-Sten/TeXiFy-IDEA/blob/655644b217e3954ae1286d7070a9357f2748f6a6/src/nl/hannahsten/texifyidea/run/compiler/LatexCompiler.kt#L288)

---

Here's a nice little regex that I wrote, which you can `.split()` on:
```regexp
(\\"?\\s|\\"$)(?=(?:[^\\"]*\\"[^\\"]*\\")*[^\\"]*$)\\"?
```
Here's some example inputs & outputs I made from just throwing random things together that I found in my `~/.bash_history`: (note: I was just using [regex101](https://regex101.com/) to substitute with newlines)
in: `-march=native -ftree-vectorize -O2 -Ofast -mtune=generic -pipe -fno-plt`
out:
```
-march=native
-ftree-vectorize
-O2
-Ofast
-mtune=generic
-pipe
-fno-plt
```
in: `-g -f -xelatex "-pdfxelatex=xelatex --shell-escape %O %S" eawerwae waewa ewajnmewkla "huwkeahuiwk a"`
out:
```
-g
-f
-xelatex
-pdfxelatex=xelatex --shell-escape %O %S
eawerwae
waewa
ewajnmewkla
huwkeahuiwk a
```

It seems to work for the most part. But even though I wrote it, I don't fully understand it tbh.
But it does get fucky if you have unclosed quotes:
in: `-g -f -xelatex "-pdfxelatex=xelatex --shell-escape %O %S" eawerwae waewa ewajnmewkla "huwkeahuiwk a`
out:
```
-g -f -xelatex "-pdfxelatex=xelatex
--shell-escape
%O
%S" eawerwae waewa ewajnmewkla "huwkeahuiwk
a
```
in: `-march=native -ftree-vectorize -O2 -Ofast -mtune="generic -pipe -fno-plt`
out:
```
-march=native -ftree-vectorize -O2 -Ofast -mtune="generic
-pipe
-fno-plt
```

Honestly, it might just be best to pass the arguments straight to a bash shell/cmd shell, that way they can do their fancy magic. Because this dark magic regex doesn't support escapes, though it might be possible to add it if you wanted.

Changed files:
src/nl/hannahsten/texifyidea/run/compiler/bibtex/BibtexCompiler.kt, src/nl/hannahsten/texifyidea/run/compiler/bibtex/BiberCompiler.kt, src/nl/hannahsten/texifyidea/run/compiler/latex/LatexCompiler.kt

diff --git a/src/nl/hannahsten/texifyidea/run/compiler/bibtex/BiberCompiler.kt b/src/nl/hannahsten/texifyidea/run/compiler/bibtex/BiberCompiler.kt
index aa451ae81..47e079a1e 100644
--- a/src/nl/hannahsten/texifyidea/run/compiler/bibtex/BiberCompiler.kt
+++ b/src/nl/hannahsten/texifyidea/run/compiler/bibtex/BiberCompiler.kt
@@ -1,5 +1,6 @@
 package nl.hannahsten.texifyidea.run.compiler.bibtex
 
+import com.intellij.util.execution.ParametersListUtil
 import nl.hannahsten.texifyidea.run.step.BibliographyCompileStep
 import nl.hannahsten.texifyidea.settings.sdk.LatexSdkUtil
 
@@ -16,7 +17,7 @@ object BiberCompiler : SupportedBibliographyCompiler("Biber", "biber") {
         // The extra directory added is the directory from which the path to the .bib resource file is searched as specified in the .bcf file.
         add("--input-directory=${step.configuration.mainFile?.parent?.path ?: ""}")
 
-        step.state.compilerArguments?.let { addAll(it.split("""\\s+""".toRegex())) }
+        step.state.compilerArguments?.let { addAll(ParametersListUtil.parse(it)) }
 
         add(step.configuration.mainFile?.nameWithoutExtension ?: return null)
     }
diff --git a/src/nl/hannahsten/texifyidea/run/compiler/bibtex/BibtexCompiler.kt b/src/nl/hannahsten/texifyidea/run/compiler/bibtex/BibtexCompiler.kt
index b4825d7dd..ad0598d6a 100644
--- a/src/nl/hannahsten/texifyidea/run/compiler/bibtex/BibtexCompiler.kt
+++ b/src/nl/hannahsten/texifyidea/run/compiler/bibtex/BibtexCompiler.kt
@@ -1,6 +1,7 @@
 package nl.hannahsten.texifyidea.run.compiler.bibtex
 
 import com.intellij.openapi.roots.ProjectRootManager
+import com.intellij.util.execution.ParametersListUtil
 import nl.hannahsten.texifyidea.run.step.BibliographyCompileStep
 import nl.hannahsten.texifyidea.settings.sdk.LatexSdkUtil
 
@@ -17,7 +18,7 @@ object BibtexCompiler : SupportedBibliographyCompiler("BibTeX", "bibtex") {
         command.apply {
             add(LatexSdkUtil.getExecutableName(executableName, step.configuration.project))
 
-            step.state.compilerArguments?.let { addAll(it.split("""\\s+""".toRegex())) }
+            step.state.compilerArguments?.let { addAll(ParametersListUtil.parse(it)) }
 
             // Include files from auxiliary directory on MiKTeX
             if (step.configuration.latexDistribution.isMiktex()) {
diff --git a/src/nl/hannahsten/texifyidea/run/compiler/latex/LatexCompiler.kt b/src/nl/hannahsten/texifyidea/run/compiler/latex/LatexCompiler.kt
index 267feef12..1bbb87909 100644
--- a/src/nl/hannahsten/texifyidea/run/compiler/latex/LatexCompiler.kt
+++ b/src/nl/hannahsten/texifyidea/run/compiler/latex/LatexCompiler.kt
@@ -3,6 +3,7 @@ package nl.hannahsten.texifyidea.run.compiler.latex
 import com.intellij.execution.configurations.GeneralCommandLine
 import com.intellij.openapi.roots.ProjectRootManager
 import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.util.execution.ParametersListUtil
 import nl.hannahsten.texifyidea.run.compiler.Compiler
 import nl.hannahsten.texifyidea.run.compiler.CustomCompiler
 import nl.hannahsten.texifyidea.run.compiler.SupportedCompiler
@@ -157,8 +158,7 @@ abstract class SupportedLatexCompiler(
 
         // Custom compiler arguments specified by the user
         runConfig.compilerArguments?.let { arguments ->
-            arguments.splitWhitespace()
-                .dropLastWhile { it.isEmpty() }
+            ParametersListUtil.parse(arguments)
                 .forEach { command.add(it) }
         }