Remove \hypertarget from pandoc LaTex output
Asked Answered
C

2

16

I am using pypandoc to convert a markdown file to LaTex. My markdown file has a header, for example:

# Header Text # 

When pypandoc renders the file as a .tex file, this appears as:

\hypertarget{header-text}{%
\section{Header Text}\label{header-text}}

While this is a nice feature to make it easy to link back to section headers, I don't necessarily want that and would prefer in this case for pypandoc to just generate:

\section{Header Text}

Is there a pandoc setting, or a pypandoc setting, that can be used to turn off the \hypertarget{} feature? I have reviewed the documentation for pandoc and didn't see it anywhere.

Chronicle answered 15/9, 2018 at 2:14 Comment(7)
Could you add a few words on why you'd prefer the plain \section{} over the more complete version? The \hypertarget{} shouldn't give any problems AFAIK.Aksoyn
I think you'd have to post-process the output if it bothers you that much.. using sed e.g.Lathan
Sorry for the delayed response, but I would like to clarify one reason why I don't want pandoc to add the \hypertarget{} feature. As you will see above, pandoc ends the line with "%". For some reason, that "%" sign is causing an error when I then use jinja2 templating. This is strange, I know. If I simply process the pandoc-created .tex file in LaTex, it works just fine. However, when I process in python using jinja2, for some reason that "%" symbol triggers an error. It has something to do with how jinja2 is trying to interpret the % sign, but I cannot figure out what is happening.Chronicle
REVISED: Sorry for the delayed response, but I would like to clarify one reason why I don't want pandoc to add the \hypertarget{} feature. As you will see above, pandoc ends the line with "%", which is a typical LaTex way to ensure that the rest of the line is ignored. But jinja then sees the last two characters as "{%" and interprets that as the start of a block. If I simply process the pandoc-created .tex file in LaTex, it works just fine. However, when I process in python using jinja2, the "%" symbol triggers an error.Chronicle
Pandoc adds \hypertarget to context output too. The hyperref package is not compatible with context This is kind of an issue.Gurgitation
Another good reason to want a clean \section{} command is that is more readable for human beings and latex editors. When LaTeX is only the intermediate step between markdown and the PDF format, all this code is OK. When LaTeX is the goal and you do not want links sections very often, this is very annoying noising code.Rabush
I'm a LaTeX newbie, but doesn't the hyperref package create the link targets for sectioning commands automatically? It seems like the \hypertarget should be unnecessary, especially since it's also emitting \label to specify the label already. (see tex.stackexchange.com/questions/180571/…)Tatiana
G
24

I had the same need, and I am using the -auto_identifiers switch,

pandoc -r markdown-auto_identifiers -w latex test.md -o test.tex

That will remove both

\hypertarget{header-text}{%

and

\label{header-text}}

leaving only

\section{Header Text}

like you requested.

Source

Geisler answered 24/1, 2019 at 17:37 Comment(0)
A
1

There is no such switch. If you want different output, you'd either have to use a pandoc filter or, as @mb21 already noted, post-process the output.

Neither of these options is very good: using a filter to manually define header output will lose you all kinds of other pandoc features, like --top-level-division and support for unnumbered headers. Post-processing, on the other hand, tends to be brittle and difficult to get right.

Anyway, below is a panflute filter, which will replace headers with a custom command. Save it to a file and pass it to pypandoc via the filters option; this should give you the desired output.

from panflute import *

sectionTypes = ["section", "subsection", "subsubsection",
                "paragraph", "subparagraph"]

def reduce_header(elem, doc):
    if type(elem) == Header:
        cmd = "\\%s{" % sectionTypes[elem.level - 1]
        inlines = [RawInline(cmd, "tex")]
        inlines.extend(elem.content)
        inlines.append(RawInline("}", "tex"))
        return Plain(*inlines)

if __name__ == "__main__":
    run_filter(reduce_header)
Aksoyn answered 16/9, 2018 at 7:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.