Pandoc Markdown 页面分页

142

最近我开始使用Pandoc Markdown,它似乎是LaTeX的一个很好的替代品,因为我的文档没有很多数学公式,并且我没有任何关于LaTeX的经验,再加上不到2周的提交截止日期,这是一个很好的解决方案。

但有一件事情我还没有解决,就是如何强制让它留下页面剩余部分为空,请问是否有人可以帮忙解决?


6
使用 Pandoc-flavored Markdown 进行数学公式时效果很棒。 - A. Donda
5个回答

179

看起来 pandoc markdown 使用标准 LaTeX 标签来实现这一目的:

\newpage\pagebreak


10
都可以使用(谢谢!),但是这两者有什么区别或它们完全等效吗? - Kalin
20
newpage命令用于结束当前页面,而pagebreak更像是一个友好的请求 - 它可能会发生,也可能不会。请参见http://www.personal.ceu.hu/tex/breaking.htm。 - parvus
7
如果输出结果能够理解latex命令,那么原始的latex命令将被直接传递。 - Matthew Pickering
但它以Markdown格式显示... 有没有一种干净的方法来执行它? - Verthais

42

TL;DR: 使用Lua过滤器中的\newpage\pagebreak(或者这里)可以在许多格式中获得分页。对于R Markdown用户,无需进行任何额外操作,该过滤器已经包含在默认设置中。


Pandoc将所有输入解析为内部文档格式。该内部格式没有专门的表示分页符的方式,但仍然可以用其他方式编码信息。一种方法是使用原始的LaTeX \newpage。当输出LaTeX(或通过LaTeX创建的PDF)时,这种方法非常有效。但是,如果目标格式不同,例如HTML或docx,则会遇到问题。
针对其他格式的简单解决方案是使用pandoc过滤器,它可以转换内部文档表示,以适应我们的需求。Pandoc 2.0及更高版本甚至允许使用包含的Lua解释器执行此转换。
假设我们通过在像空行一样包围的行中放置\newpage来指示分页符:
lorem ipsum

\newpage

more text
\newpage将被解析为包含原始TeXRawBlock。只有目标格式可以包含原始TeX(即LaTeX、Markdown、Org等)时,该块才会包含在输出中。
当面向不同格式时,我们可以使用简单的Lua过滤器来进行翻译。以下内容适用于docx、LaTeX、epub和轻量级标记。
--- Return a block element causing a page break in the given format.
local function newpage(format)
  if format == 'docx' then
    local pagebreak = '<w:p><w:r><w:br w:type="page"/></w:r></w:p>'
    return pandoc.RawBlock('openxml', pagebreak)
  elseif format:match 'html.*' then
    return pandoc.RawBlock('html', '<div style=""></div>')
  elseif format:match 'tex$' then
    return pandoc.RawBlock('tex', '\\newpage{}')
  elseif format:match 'epub' then
    local pagebreak = '<p style="page-break-after: always;"> </p>'
    return pandoc.RawBlock('html', pagebreak)
  else
    -- fall back to insert a form feed character
    return pandoc.Para{pandoc.Str '\f'}
  end
end

-- Filter function called on each RawBlock element.
function RawBlock (el)
  -- check that the block is TeX or LaTeX and contains only \newpage or
  -- \pagebreak.
  if el.text:match '\\newpage' then
    -- use format-specific pagebreak marker. FORMAT is set by pandoc to
    -- the targeted output format.
    return newpage(FORMAT)
  end
  -- otherwise, leave the block unchanged
  return nil
end

我们发布了一个更新的、功能更丰富的版本。它可以从官方pandoc lua-filters仓库中获取。R Markdown项目维护了一个分支;它随R包一起发布,因此该功能可以立即使用
注意:要将latex转换为docx,您必须将源语言设置为latex+raw_tex,以便pandoc AST将其传递github问题

14
这段代码非常适用于强制在pandoc的MS Word输出格式中使用\newpage来进行分页。要使用此过滤器,请将此答案中的代码保存为例如 pagebreak.lua,然后通过指定参数--lua-filter=pagebreak.lua来调用pandoc。 - Christian Long

5

我发现这种方法不适用于.doc和.odt格式。我找到的一个解决方法是在文本编辑器(例如我的LibreOffice)中插入一条水平线-----------------并将“水平线”样式设置为分页后不可见。


你会如何格式化“水平线”样式以分页? - nilon
2
我只知道HTML输出,然后我将其打印到PDF中。Chrome对于打印的CSS解释有非常好的实现。在这种情况下,hr {opacity:0;page-break-after: always;}可以胜任此工作。如果您想将<hr>用于其他用途,则可以牺牲其他元素。 - Joaquin

5

无法编辑LucasSeveryn的答案,提示队列已满,因此在此添加一些信息。

方法一:+raw_tex

\newpage\pagebreak 需要开启 raw_tex 扩展。

// 使用 pandoc 2.9.2.1,不能与 docx 或 html 输出一起使用,--verbose 显示如下

[INFO] Not rendering RawBlock (Format "tex") "\\pagebreak"
[INFO] Not rendering RawBlock (Format "tex") "\\newpage"

方式二:+原始属性

https://pandoc.org/MANUAL.html#extension-raw_attribute

```{=openxml}
<w:p>
  <w:r>
    <w:br w:type="page"/>
  </w:r>
</w:p>
```

// 在gfm输入格式中也不支持。
// 这适用于docx输出,但不适用于html输出。

扩展通知

这需要+raw_tex格式扩展。 这并不适用于pandoc中的所有markdown变体。

https://pandoc.org/MANUAL.html#markdown-variants

Note, however, that commonmark and gfm have limited support for extensions.  

Only those listed below (and smart, raw_tex, and hard_line_breaks) will work.  

The extensions can, however, all be individually disabled.

Also, raw_tex only affects gfm output, not input.

所以 -f markdown 是有效的,但是 -f gfm 无效。

格式扩展

https://pandoc.org/MANUAL.html#option--from

Extensions can be individually enabled or disabled by appending 
+EXTENSION or -EXTENSION to the format name.

例如:

-t html+raw_tex:输出启用 raw_tex。

-f markdown-raw_tex-raw_attribute:输入禁用 raw_tex 和 raw_attribute。


3
如果您要将文件从Markdown转换为epub格式,可以采用以下方法:
<div style="page-break-before:always;"></div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接