jgm / pandoc

Universal markup converter
https://pandoc.org
Other
34.02k stars 3.35k forks source link

LaTeX macros wrongly expanded markdown -> latex #5507

Open spgarbet opened 5 years ago

spgarbet commented 5 years ago

If I have a table that I change the horizontal psacing of using the typical LaTeX:

\renewcommand{\arraystretch}{1.5}

Pandoc's behavior becomes erratic after this directive is issued.

If a second one exists, it changes it to this. \renewcommand{1.5}{1.5}

And it typically drops everything following this from the last table in the LaTeX.

Invocation:

pandoc +RTS -K512m -RTS untitled.utf8.md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output untitled.tex --template /home/garbetsp/R/x86_64-pc-linux-gnu-library/3.6/rmarkdown/rmd/latex/default-1.17.0.2.tex --highlight-style tango --variable graphics=yes --variable 'geometry:margin=1in' --variable 'compact-title:yes'

untitled.utf8.md.txt

spgarbet commented 5 years ago

I tried alternatives of getting rid of the enclosing {} for the environment and the alternative \def\arraystretch{1.5} as well as suggested here: https://tex.stackexchange.com/questions/31672/column-and-row-padding-in-tables

These fail as well.

jgm commented 5 years ago

Can you give a minimal example? What happens when you do

pandoc -f markdown -t latex
\renewcommand{\arraystretch}{1.5}

\renewcommand{\arraystretch}{1.5}
^D

I get (pandoc 2.7.2):

\renewcommand{\arraystretch}{1.5}

\renewcommand{\arraystretch}{1.5}

Do you get \renewcommand{1.5}{1.5}?

spgarbet commented 5 years ago

That short examples works for me just fine. I took the longer example I uploaded and shaved it down to the minimal example that creates the problem. The arraystretch has to be inside a table environment.

pandoc -f markdown -t latex
\begin{table}
\def\arraystretch{1.2}
\end{table}

\begin{table}
\def\arraystretch{1.2}
\end{table}
^D

Returns for me (2.3 and 2.7.2):

\begin{table}
\def\arraystretch{1.2}
\end{table}

\begin{table}
\def1.2{1.2}
\end{table}

This happens for both renewcommand and def. I'm not able to isolate with this small example what happens when I have 10 tables and LaTeX output just stops altogether right at this command on the 10th table. That maybe another issue altogether, but the fact it's right at the renewcommand or def I suspect it's related. I'll work on isolating that as well.

jgm commented 5 years ago

Simpler repro:

\def\arraystretch{1.2}

\foobar\def\arraystretch{1.2}

It doesn't have to do with tables specifically, but with raw LaTeX blocks.

jgm commented 5 years ago

Probably due to the logic in the LaTeX reader:

rawLaTeXBlock :: (PandocMonad m, HasMacros s, HasReaderOptions s)
              => ParserT String s m String
rawLaTeXBlock = do
  lookAhead (try (char '\\' >> letter))
  snd <$> (rawLaTeXParser False macroDef blocks
      <|> (rawLaTeXParser True
             (do choice (map controlSeq
                   ["include", "input", "subfile", "usepackage"])
                 skipMany opt
                 braced
                 return mempty) blocks)
      <|> rawLaTeXParser True
           (environment <|> blockCommand)
           (mconcat <$> (many (block <|> beginOrEndCommand))))

Macro definitions are treated specially here (the False argument to rawLaTeXParser says "don't expand macros yet in reading this"), but this only works when they come at the beginning of the raw LaTeX block. Otherwise they get read in the third clause of the alternative.

jgm commented 5 years ago

Here are some failing command tests:

% pandoc -f markdown -t latex \def\arraystretch{1.2}

\foobar\def\arraystretch{1.2} ^D \def\arraystretch{1.2}

\foobar\def\arraystretch{1.2}

% pandoc -f markdown -t latex \def\arraystretch{1.2}

\begin{foo} \def\arraystretch{1.2} \end{foo} ^D \def\arraystretch{1.2}

\begin{foo} \def\arraystretch{1.2} \end{foo}

This issue affects:

Both fairly rare cases. It's actually nontrivial to fix this, so putting on the back burner for now.

spgarbet commented 5 years ago

It's the recommended approach to changing vertical spacing inside a table in LaTeX. I'm more than happy to do another way can you recommend one?

jgm commented 5 years ago

Yes, you're right, maybe it's not such an edge case after all.

You can work around this by using the raw attribute to designate the whole table as raw latex.

```{=latex}
\begin{table}
\def..etc...
...
\end{table}
spgarbet commented 5 years ago

Thanks. I know exactly when it's raw latex and can do exactly this. That will help a lot!!!