Skip to content

LaTeX writer: a span with an id inside a header will have an extra right brace #2136

Closed
bpj opened this Issue · 5 comments

3 participants

@bpj
bpj commented

When converting with pandoc to LaTeX a span with an id inside a header will have an extra right brace appear which causes a syntax error in latex. The brace marked with ^ in the LaTeX output is one too many, as can be readily seen in an editor which highlights matching braces. From these tests it appears to happen only when converting from Markdown, but I first noticed it when converting from HTML from various web pages. Apparently they put an empty span in the header instead of giving the header an id. They must be using (non-pandoc) Markdown! It doesn't happen when there is no id in the span.

Testing:

## <span id="a-header-with-a-span-in-it">A header with a span in it</span>

Paragraph

Converting markdown to html
Converting html to pdf
No errors
Converting markdown to pdf
Stderr:

! Argument of \@sect has an extra }.
<inserted text> 
                \par 
l.121 it}}{A header with a span in it}}

pandoc: Error producing PDF from TeX source

Latex output:


\subsection{\texorpdfstring{\hyperdef{}{a-header-with-a-span-in-it}{}{A
header with a span in
it}}{A header with a span in it}}\label{a-header-with-a-span-in-it}
   ^

Paragraph
@bpj bpj changed the title from LaTeX a span with an id inside a header will have an extra right brace to LaTeX writer: a span with an id inside a header will have an extra right brace
@jgm
Owner
@lierdakil

The problem is \hyperdef is used inside moving arguments. A simple workaround is to add \protect before \hyperdef. Now then, equivalent could be done with some TeX magic in template, e.g.

\let\oldhyperdef\hyperdef
\DeclareRobustCommand{\hyperdef}{\oldhyperdef}

But it could also be implemented in pandoc with \protect, e.g. this will work:

\subsection{\texorpdfstring{\protect\hyperdef{}{a-header-with-a-span-in-it}{}{A
header with a span in
it}}{A header with a span in it}}\label{a-header-with-a-span-in-it}

While first option is generally more robust, second would work for non-standalone LaTeX output. There are other environments in which \hyperdef can (and likely will) break though.

See TeX stackexchange for more info on this topic.

Also see http://www.giss.nasa.gov/tools/latex/fragile.html for other examples where \hyperdef would break (most notably, inside \caption arguments)

@lierdakil

P.S. Now that I think about it, \oldsomething is really not the best name choice, since this could be redefined by user. Better option would be to use @ to avoid collisions, e.g.

\makeatletter
\let\hyperdef@original\hyperdef
\DeclareRobustCommand{\hyperdef}{\hyperdef@original}
\makeatother
@jgm
Owner
jgm commented

I think just adding a \protect to the output before each \hyperdef might be the best approach.
(Or maybe just inside headers? Which pandoc contexts correspond to "moving arguments" in LaTeX?)

@lierdakil
@jgm jgm added a commit that closed this issue
@jgm LaTeX writer: add `\protect` to `\hyperdef` in inline context.
This way we don't get an error when this is used as a moveable
argument.

Closes #2136.
198862e
@jgm jgm closed this in 198862e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.