从markdown生成pdf的Pandoc,不尊重标题格式

时间:2014-01-17 23:43:19

标签: latex markdown pandoc pdflatex

我正在使用pandoc从某个markdown生成pdf。我通过哈希符号使用h1到h4。例子h1 =#,h4 = ####。当我生成这样的文档时:

pandoc input.md -o output.pdf

我得到一个文件,其中h1,h2和h3后面有换行符,但h4没有换行符。文本与标题在同一行开始(它的格式不同,但之间没有换行符)。

我尝试在####之后添加空格并使用我的编辑器添加手动行返回但似乎没有任何效果。

有什么想法吗?

5 个答案:

答案 0 :(得分:10)

pandoc通过LaTeX生成PDF。在LaTeX中,使用以下命令生成“标题”:

  1. \section
  2. \subsection
  3. \subsubsection
  4. \paragraph
  5. \subparagraph
  6. 如您所见,“四级标题”对应于\paragraph命令,该命令在您描述时呈现。根本没有\subsubsubsection命令可供使用。

    获得所需内容的唯一方法是重新定义\paragraph命令,这非常棘手。我无法使用Pandoc。

答案 1 :(得分:2)

移动标题

可以说,解决此问题的最佳方法是通过转移4级标题对应的位置来完全避免该问题。 pandoc的默认设置是对第一级标题使用\section命令,对于第四级标题使用\paragraph。可以通过--top-level-division参数进行更改:

  

--top-level-division=[default|section|chapter|part]

     

在LaTeX输出中将顶级标题作为给定的分隔类型。层次结构顺序是:部分,章节,然后是部分;所有标头都进行了移位,以使顶级标头成为指定的类型。默认行为是通过启发式方法确定最佳除法类型[...]

因此,对于--top-level-division=chapter,将通过\subsubsection命令生成一个4级标题。

通过LaTeX设置样式

如果这不是一个选项,那么下一个最佳方法是配置相应的LaTeX命令的布局:对于四级标头,默认情况下为\paragraph。以下方法摘自TeX StackExchange answers

默认文档类

默认方法是通过 titlesec 软件包配置\paragraph。为此,我们可以使用 header-includes 元数据字段,pandoc会将其包含在中间LaTeX文档中。

---
header-includes: |
  ``` {=latex}
  \usepackage{titlesec}
  \titlespacing*{\paragraph}{0pt}{1ex}{-\parskip}
  \titleformat{\paragraph}[hang]
      {\normalfont\bfseries}
      {}
      {0pt}
      {}
  ```
---

KOMA文档类

对于使用KOMA类(例如 scrartcl )的文档,使用 titlesec 不能正常工作,因为KOMA拥有自己的处理方式。对于这些,请使用以下替代代码片段:

---
documentclass: scrartcl
header-includes: |
  ``` {=latex}
  \makeatletter
  \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
    {-3.25ex \@plus -1ex \@minus -0.2ex}%
    {0.01pt}%
    {\raggedsection\normalfont\sectfont\nobreak\size@paragraph}%
  }
  \makeatother
  ```
---

答案 2 :(得分:2)

虽然上述解决方案可以正常工作,但pandoc提供了一个内置变量来启用\ paragraph的块标题。

pandoc -s -o out.pdf some.md -V block-headings

Pandoc Manual

答案 3 :(得分:1)

@tarleb的答案肯定是最好的(除了它指定了一个 垂直空间量不正确),这是“简单”(某种程度上来说) 但更具hacky(至少以LaTeX术语而言)的解决方案,可以选择使用Pandoc Lua过滤器或LaTeX hack,但避免加载其他LaTeX软件包。

我们希望LaTeX源看起来像这样:

\hypertarget{level-4-heading}{%
\paragraph{Level 4 heading}\label{level-4-heading}}

\hfill

Lorem ipsum dolor sit amet.

该LaTeX看起来很糟糕,但是如果您不需要保留或共享LaTeX 源它会执行您可能想要的操作:4级之间的空间 标题及其后的段落等于第3级之间的空格 标题及其后的段落。

Level 4 heading with paragraph break

这是它的工作方式:因为一行上的\hfill本身大约等于 关闭,因为您可以在LaTeX中找到一个空的段落 段落-以标题开头的段落-仅包含 水平空白直到行尾,然后立即 在新段落之后(标题之后的实际第一段) 在标题和标题之间只有一个普通的段落空间。这个 可能还会破坏LaTeX关于\paragraph应该是什么的想法 越少越好。

“手动”操作方法如下:

    #### Level 4 heading

    ````{=latex}
    \hfill
    ````

    Lorem ipsum dolor sit amet.

它使用Pandoc相对较新的原始标记语法-“代码块” 实际上是一个原始的LaTeX块-但看起来比 产生的LaTeX来源!插入也很麻烦 每个第4级标题之后。换句话说,您想插入 原始LaTeX自动生成,而 可以通过Lua过滤器完成:

    --[======================================================================[

    latex-h4-break.lua - Pandoc filter to get break after a level 4 heading.

    Usage:

        $ pandoc --lua-filter latex-h4-break.lua input.md -o output.pdf

    --]======================================================================]

    -- create it once, use it many times!
    local hfill_block = pandoc.RawBlock('latex', '\\hfill')

    function Header (elem)
        if 4 == elem.level then 
            return { elem, hfill_block }
        else -- ignore headings at other levels!
            return nil 
        end
    end

不过,您也可以在header-includes中进行简单的LaTeX黑客攻击 元数据块获得相同的效果:

    ---
    header-includes: 
      - |
        ``` {=latex}
        \let\originAlParaGraph\paragraph
        \renewcommand{\paragraph}[1]{\originAlParaGraph{#1} \hfill}
        ```
    ---

    #### Level 4 heading

    Lorem ipsum dolor sit amet.

这是通过首先创建\paragraph命令的“别名”并 然后使用[]中的别名重新定义\paragraph命令本身 新定义,因此现在无论Pandoc创建的LaTeX源位于何处 包含\paragraph{Foo},是否包含 \paragraph{Foo} \hfill可以实现我们想要的零附加费 依赖! (以防您混淆了“别名”的古怪拼写 命令是为了最大程度地减少与任何物体碰撞的风险 已经存在,因为TeX \let命令不会对此进行检查。我们 当然不希望覆盖任何现有命令!)

注意:如果您真的应该比平常多多少少的空间 标题后面的段落分隔符只需添加适当的\vspace \hfill之后的命令:\hfill \vspace{-0.5\parskip}

答案 4 :(得分:0)

我不确定,为什么,但这对我有用:

$\ \\ $放在#### headline

之后的第一行