14

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.

rsgny
  • 565
  • 1
  • 6
  • 17
  • 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. – tarleb Sep 15 '18 at 09:30
  • 1
    I think you'd have to post-process the output if it bothers you that much.. using `sed` e.g. – mb21 Sep 15 '18 at 15:13
  • 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. – rsgny Oct 02 '18 at 12:23
  • 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. – rsgny Oct 03 '18 at 03:32
  • 2
    Pandoc adds \hypertarget to context output too. The hyperref package is not compatible with context This is kind of an issue. – El Andi Jun 21 '19 at 07:37
  • 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. – Fran Feb 15 '23 at 11:04
  • 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 https://tex.stackexchange.com/questions/180571/making-clickable-links-to-sections-with-hyperref) – user4815162342 Mar 14 '23 at 14:59

2 Answers2

23

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

gsl
  • 1,063
  • 1
  • 16
  • 27
2

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)
tarleb
  • 19,863
  • 4
  • 51
  • 80