Pandoc

komantao 2019-12-12 2020-01-22 字数 8699 阅读量 1465


Pandoc是一个用haskell编写的开源文本转换工具(通用标记转换器),小巧迅速且支持格式广泛,堪称文本转换应用的瑞士军刀。支持很多种输入输出。最大缺点:Pandoc是命令行工具,没有图形用户界面。

Pandoc是一个命令行工具,没有图形用户界面。因此,使用前需要打开一个终端窗口。

若使用cmd,在使用pandoc前键入chcp 65001,将编码设置为UTF-8。因为Markdown编辑器的编码通常设置为UTF-8,若cmd的编码不一致,转换时,将会产生乱码

1553222238024

键入chcp 65001

1553222320647

一、安装

1、安装pandoc

在官方网站(https://pandoc.org/)选择平台下载最新版本即可。

  • windows.msi版本是传统的安装方式,windows.zip版本解压后即可使用

  • 解压后即可使用,得到五个文件:.rtf与.txt文件应该都是版权声明文件,一个.html的用户指南,pandoc.exe、pandoc-citeproc.exe都是命令行工具。pandoc-citeproc.exe不清楚其作用,主要使用pandoc.exe来进行文件转换。

    1553219979988

安装后,检查是否已将pandoc.exe的路径配置到环境变量中去。

在命令行键入:pandoc --version,验证是否安装了pandoc:

1553175763771

安装后或会发现Typora用不了:

20190322002521491

重新安装 Typora 即可。

如果已经安装了Anaconda,可直接使用Pandoc,因为该程序已经被集成到Anaconda中。

2、安装LaTeX

2.1 安装Tex Live 2018

LaTeX是一种基于TeX的排版系统,主要目的是为了方便排版,非常适用于生成高印刷质量的科技和数学类文档,对于生成复杂表格和数学公式,这一点表现得尤为突出。

  • pandoc不能直接生成pdf文档,需要借助LaTeX引擎
  • Markdown文档内含有LaTeX公式,需要LaTeX引擎
  • 为了支持中文,需要使用XeLaTeX编译器
    • XeLaTeX是对LaTeX的一种扩展,支持Unicode,使得LaTeX能够非常方便地支持各种国家的语言,是当前比较流行的书写中文的方法,相比之下CJK显得过时了
  • Tex Live是LaTeX发布版的集成版本,包括了各种插件和宏,还有默认的编辑器TeXworks,用其语法可直接编辑生成pdf文档
    • 最新版本“texlive2018.iso”文件有3.3G,安装占用了5个G的硬盘空间

下载安装Tex Live 2018,具体过程参阅:Win10 安装 LaTex。安装路径貌似不能有中文。

成功安装Tex Live 2018后,就能使用tex、latex和xelatex的相关命令。

2.2 加载中文字体

XeLaTeX支持中文并不代表可以像写英文一样直接在tex文件中写中文,还需要载入字体。载入字体要用到fontspec宏包,但是使用宏包的命令非常的冗长,不是很方便,所以将常用的中文字体作成一个简单的命令。为了中文显示的美观和避免一些可能的问题,还要再加一些命令。有人把这些命令整合起来,写成一个宏包,一般叫zhfontcfg.sty。

  1. 字体来源

    自己安装字体:或从网上下载,或在win下copy。

    • XeLaTeX原生支持系统字体,可直接使用系统已安装的字体,无需再额外编译字体

    • 在命令行下,

      查看本地字体的命令:fc-list

      查看本地中文字体的命令:fc-list :lang=zh。备注:冒号前面有空格

  2. 编辑宏包

    使用Notepad ++ 编辑整合添加字体命令,形成一个宏包,例如命名为zhfontcfg.sty

    • % xetex/xelatex 字体设定宏包
    • \ProvidesPackage{zhfontcfg}
    • \usepackage[cm-default]{fontspec} %[cm-default]选项主要用来解决使用数学环境时数学符号不能正常显示的问题
    • \usepackage{xunicode,xltxtra}
    • \defaultfontfeatures{Mapping=tex-text} %如果没有它,会有一些 tex 特殊字符无法正常使用,比如连字符。
    • % 中文断行
    • \XeTeXlinebreaklocale "zh"
    • \XeTeXlinebreakskip = 0pt plus 1pt minus 0.1pt
    • %将系统字体名映射为逻辑字体名称,主要是为了维护的方便
    • \newcommand\fontnamehei{Microsoft YaHei}
    • \newcommand\fontnamesong{SimSun}
    • \newcommand\fontnamekai{AR PL KaitiM GB}
    • \newcommand\fontnamemono{DejaVu Sans Mono}
    • \newcommand\fontnameroman{Times New Roman}
    • %%设置常用中文字号,方便调用
    • \newcommand{\erhao}{\fontsize{22pt}{\baselineskip}\selectfont}
    • \newcommand{\xiaoerhao}{\fontsize{18pt}{\baselineskip}\selectfont}
    • \newcommand{\sanhao}{\fontsize{16pt}{\baselineskip}\selectfont}
    • \newcommand{\xiaosanhao}{\fontsize{15pt}{\baselineskip}\selectfont}
    • \newcommand{\sihao}{\fontsize{14pt}{\baselineskip}\selectfont}
    • \newcommand{\xiaosihao}{\fontsize{12pt}{\baselineskip}\selectfont}
    • \newcommand{\wuhao}{\fontsize{10.5pt}{\baselineskip}\selectfont}
    • \newcommand{\xiaowuhao}{\fontsize{9pt}{\baselineskip}\selectfont}
    • \newcommand{\liuhao}{\fontsize{7.5pt}{\baselineskip}\selectfont}
    • %设置文档正文字体为宋体
    • \setmainfont[BoldFont=\fontnamehei]{\fontnamesong}
    • \setsansfont[BoldFont=\fontnamehei]{\fontnamekai}
    • \setmonofont{\fontnamemono}
  3. 保存宏包(zhfontcfg.sty)

    宏包要放在TEXMFLOCAL/tex/latex或者TEXMFHOME/tex/latex文件夹下

    这两个路径的位置可以在texmf.cnf中找到,或使用命令tlmgr conf查看:

    1553657140423

  4. 宏包发生更改后,保持同步更新

    使用命令mktexlsr更新。

宏包使用的简单示例:

  • \documentclass{article}
  • \usepackage{zhfontcfg}
  • \usepackage[colorlinks,linkcolor=black]{hyperref}
  • %opening
  • \title{latex多字体简易示例}
  • \begin{document}
  • \maketitle
  • \section{楷体}
  • \kai{楷体}
  • \section{黑体}
  • \hei{黑体}
  • \end{document}

使用用xelatex编译文档出现以下问题,尚未解决:

1553312265518

二、命令

  • 语法:pandoc [OPTIONS] [FILES]
  • 如果没有指定输入文件,pandoc从标准输入读取
  • 若指定有多个输入文件,可以以空格分割
  • 默认输出是标准输出,可以使用-o选项输出到指定的文件中
  • 默认情况下,pandoc只产生文件片段,不是一个包含头尾的完整文件,如果需要产生一个独立的文件,使用-s--standalone选项,比如生成HTML文件
  • 有时候输入文件可能是一个URI,此时pandoc可以通过http获取内容
  • 如果指定多个输入文件,pandoc也可以将多个文件合并转换成一个文件。当然,输入文件像EPUB、odt和docx这种,是不支持的

常用选项:

选项 含义
-f FORMAT, -r FORMAT, –from=FORMAT, –read=FORMAT 指定输入文件的格式,若不指定,pandoc可以从明显的文件后缀名中推测,若无明显提示,默认的输入文件格式是markdown
-D FORMAT, –print-default-template=FORMAT 打印输出格式的系统默认模板。(有关可能的格式列表,请参见-t。)用户数据目录中的模板将被忽略。
-t FORMAT, -w FORMAT, –to=FORMAT, –write=FORMAT 指定输出文件的格式,默认的输出文件格式是html。注意,除非强制使用-o -,否则odt、docx和epub输出不会被定向到stdout。
-o FILE, –output=FILE 将输出写入文件(FILE为文件名)。如果FILE是-,将输出到stdout。
–list-input-formats 列出支持的输入文件格式
–list-output-formats 列出支持的输出文件格式
–list-extensions[=FORMAT] 列出支持的markdown扩展,+代表默认支持,-代表默认不支持
-s, –standalone 产生输出文件时自动附带适当的头注和脚注(比如html),使用自动模板修改了HTML文档的head标签,主要包含有:meta标签、title标签、style标签(css样式文件)。
–toc-depth=NUMBER 指定在目录(TOC)中的标题级别的层数。默认值是3(这意味着在目录列表中列出级别1、2和3个标题)。
–self-contained 生成一个没有外部依赖关系的独立HTML文件:在转换HTML文件过程中,将依赖的“脚本(scripts)、样式表(stylesheets,)、图片(images)、视频(videos)”等文件的内容内嵌到目标HTML文件中。
-c URL, –css=URL 链接到CSS样式表,即目标格式文件最后使用的CSS文件。URL为指定路径的css文件。若没有使用此选项(css文件或样式表(stylesheet)的元数据(metadata)字段)提供任何文件,pandoc生成EPUB将缺省使用epub.css文件,生成HTML将缺省使用text.css文件。如果没有找到,将使用合理的默认值。默认的CSS文件,展现效果非常丑陋,需要使用独立的CSS文件。
–pdf-engine=PROGRAM 在生成PDF输出时使用指定的引擎。PROGRAM的有效值为pdflatex、lualatex、xelatex、latexmk、tectonic、wkhtmltopdf、weasyprint、prince、context和pdfroff。默认值是pdflatex。如果引擎不在您的路径中,可以在这里指定引擎的完整路径。
-f PROGRAM, –filter=PROGRAM 指定一个可执行文件作为过滤器,在解析输入和编写输出之前转换pandoc AST。过滤器可以用任何语言编写。

三、输出格式

1、CSS样式表

通过 CSS(Cascading Style Sheets,层叠样式表)来自定义文章的样式,获得个性化的主题。

markdownPad-github.css

  • /* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
  • /* RESET
  • =============================================================================*/
  • html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  • margin: 0;
  • padding: 0;
  • border: 0;
  • }
  • /* BODY
  • =============================================================================*/
  • body {
  • font-family: Helvetica, arial, freesans, clean, sans-serif;
  • font-size: 14px;
  • line-height: 1.6;
  • color: #333;
  • background-color: #fff;
  • padding: 20px;
  • max-width: 960px;
  • margin: 0 auto;
  • }
  • body>*:first-child {
  • margin-top: 0 !important;
  • }
  • body>*:last-child {
  • margin-bottom: 0 !important;
  • }
  • /* BLOCKS
  • =============================================================================*/
  • p, blockquote, ul, ol, dl, table, pre {
  • margin: 15px 0;
  • }
  • /* HEADERS
  • =============================================================================*/
  • h1, h2, h3, h4, h5, h6 {
  • margin: 20px 0 10px;
  • padding: 0;
  • font-weight: bold;
  • -webkit-font-smoothing: antialiased;
  • }
  • h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
  • font-size: inherit;
  • }
  • h1 {
  • font-size: 28px;
  • color: #000;
  • }
  • h2 {
  • font-size: 24px;
  • border-bottom: 1px solid #ccc;
  • color: #000;
  • }
  • h3 {
  • font-size: 18px;
  • }
  • h4 {
  • font-size: 16px;
  • }
  • h5 {
  • font-size: 14px;
  • }
  • h6 {
  • color: #777;
  • font-size: 14px;
  • }
  • body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
  • margin-top: 0;
  • padding-top: 0;
  • }
  • a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  • margin-top: 0;
  • padding-top: 0;
  • }
  • h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
  • margin-top: 10px;
  • }
  • /* LINKS
  • =============================================================================*/
  • a {
  • color: #4183C4;
  • text-decoration: none;
  • }
  • a:hover {
  • text-decoration: underline;
  • }
  • /* LISTS
  • =============================================================================*/
  • ul, ol {
  • padding-left: 30px;
  • }
  • ul li > :first-child,
  • ol li > :first-child,
  • ul li ul:first-of-type,
  • ol li ol:first-of-type,
  • ul li ol:first-of-type,
  • ol li ul:first-of-type {
  • margin-top: 0px;
  • }
  • ul ul, ul ol, ol ol, ol ul {
  • margin-bottom: 0;
  • }
  • dl {
  • padding: 0;
  • }
  • dl dt {
  • font-size: 14px;
  • font-weight: bold;
  • font-style: italic;
  • padding: 0;
  • margin: 15px 0 5px;
  • }
  • dl dt:first-child {
  • padding: 0;
  • }
  • dl dt>:first-child {
  • margin-top: 0px;
  • }
  • dl dt>:last-child {
  • margin-bottom: 0px;
  • }
  • dl dd {
  • margin: 0 0 15px;
  • padding: 0 15px;
  • }
  • dl dd>:first-child {
  • margin-top: 0px;
  • }
  • dl dd>:last-child {
  • margin-bottom: 0px;
  • }
  • /* CODE
  • =============================================================================*/
  • pre, code, tt {
  • font-size: 12px;
  • font-family: Consolas, "Liberation Mono", Courier, monospace;
  • }
  • code, tt {
  • margin: 0 0px;
  • padding: 0px 0px;
  • white-space: nowrap;
  • border: 1px solid #eaeaea;
  • background-color: #f8f8f8;
  • border-radius: 3px;
  • }
  • pre>code {
  • margin: 0;
  • padding: 0;
  • white-space: pre;
  • border: none;
  • background: transparent;
  • }
  • pre {
  • background-color: #f8f8f8;
  • border: 1px solid #ccc;
  • font-size: 13px;
  • line-height: 19px;
  • overflow: auto;
  • padding: 6px 10px;
  • border-radius: 3px;
  • }
  • pre code, pre tt {
  • background-color: transparent;
  • border: none;
  • }
  • kbd {
  • -moz-border-bottom-colors: none;
  • -moz-border-left-colors: none;
  • -moz-border-right-colors: none;
  • -moz-border-top-colors: none;
  • background-color: #DDDDDD;
  • background-image: linear-gradient(#F1F1F1, #DDDDDD);
  • background-repeat: repeat-x;
  • border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
  • border-image: none;
  • border-radius: 2px 2px 2px 2px;
  • border-style: solid;
  • border-width: 1px;
  • font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
  • line-height: 10px;
  • padding: 1px 4px;
  • }
  • /* QUOTES
  • =============================================================================*/
  • blockquote {
  • border-left: 4px solid #DDD;
  • padding: 0 15px;
  • color: #777;
  • }
  • blockquote>:first-child {
  • margin-top: 0px;
  • }
  • blockquote>:last-child {
  • margin-bottom: 0px;
  • }
  • /* HORIZONTAL RULES
  • =============================================================================*/
  • hr {
  • clear: both;
  • margin: 15px 0;
  • height: 0px;
  • overflow: hidden;
  • border: none;
  • background: transparent;
  • border-bottom: 4px solid #ddd;
  • padding: 0;
  • }
  • /* TABLES
  • =============================================================================*/
  • table th {
  • font-weight: bold;
  • }
  • table th, table td {
  • border: 1px solid #ccc;
  • padding: 6px 13px;
  • }
  • table tr {
  • border-top: 1px solid #ccc;
  • background-color: #fff;
  • }
  • table tr:nth-child(2n) {
  • background-color: #f8f8f8;
  • }
  • /* IMAGES
  • =============================================================================*/
  • img {
  • max-width: 100%
  • }

markdownhere.css

Markdownhere 是李笑来制作的一套 CSS 主题,已开源在 GitHub 上,对于中文的显示效果比较友好,字距、行距比直接套用英文模板更加自然,是为数不多的优质中文 CSS 主题。

  • .markdown-here-wrapper {
  • font-size: 16px;
  • line-height: 1.8em;
  • letter-spacing: 0.1em;
  • }
  • pre, code {
  • font-size: 14px;
  • font-family: Roboto, 'Courier New', Consolas, Inconsolata, Courier, monospace;
  • margin: auto 5px;
  • }
  • code {
  • white-space: pre-wrap;
  • border-radius: 2px;
  • display: inline;
  • }
  • pre {
  • font-size: 15px;
  • line-height: 1.4em;
  • display: block; !important;
  • }
  • pre code {
  • white-space: pre;
  • overflow: auto;
  • border-radius: 3px;
  • padding: 1px 1px;
  • display: block !important;
  • }
  • strong, b{
  • color: #BF360C;
  • }
  • em, i {
  • color: #009688;
  • }
  • hr {
  • border: 1px solid #BF360C;
  • margin: 1.5em auto;
  • }
  • p {
  • margin: 1.5em 5px !important;
  • }
  • table, pre, dl, blockquote, q, ul, ol {
  • margin: 10px 5px;
  • }
  • ul, ol {
  • padding-left: 15px;
  • }
  • li {
  • margin: 10px;
  • }
  • li p {
  • margin: 10px 0 !important;
  • }
  • ul ul, ul ol, ol ul, ol ol {
  • margin: 0;
  • padding-left: 10px;
  • }
  • ul {
  • list-style-type: circle;
  • }
  • dl {
  • padding: 0;
  • }
  • dl dt {
  • font-size: 1em;
  • font-weight: bold;
  • font-style: italic;
  • }
  • dl dd {
  • margin: 0 0 10px;
  • padding: 0 10px;
  • }
  • blockquote, q {
  • border-left: 2px solid #009688;
  • padding: 0 10px;
  • color: #777;
  • quotes: none;
  • margin-left: 1em;
  • }
  • blockquote::before, blockquote::after, q::before, q::after {
  • content: none;
  • }
  • h1, h2, h3, h4, h5, h6 {
  • margin: 20px 0 10px;
  • padding: 0;
  • font-style: bold !important;
  • color: #009688 !important;
  • text-align: center !important;
  • margin: 1.5em 5px !important;
  • padding: 0.5em 1em !important;
  • }
  • h1 {
  • font-size: 24px !important;
  • border-bottom: 1px solid #ddd !important;
  • }
  • h2 {
  • font-size: 20px !important;
  • border-bottom: 1px solid #eee !important;
  • }
  • h3 {
  • font-size: 18px;
  • }
  • h4 {
  • font-size: 16px;
  • }
  • table {
  • padding: 0;
  • border-collapse: collapse;
  • border-spacing: 0;
  • font-size: 1em;
  • font: inherit;
  • border: 0;
  • margin: 0 auto;
  • }
  • tbody {
  • margin: 0;
  • padding: 0;
  • border: 0;
  • }
  • table tr {
  • border: 0;
  • border-top: 1px solid #CCC;
  • background-color: white;
  • margin: 0;
  • padding: 0;
  • }
  • table tr:nth-child(2n) {
  • background-color: #F8F8F8;
  • }
  • table tr th, table tr td {
  • font-size: 16px;
  • border: 1px solid #CCC;
  • margin: 0;
  • padding: 5px 10px;
  • }
  • table tr th {
  • font-weight: bold;
  • color: #eee;
  • border: 1px solid #009688;
  • background-color: #009688;
  • }

少数派经典主题

  • sspai.cssDroplr
  • /* Sspai Web Theme A theme to [sspai](ssp.ai) default theme. Developed by Codegass(wchweichenhao@gmial.com) & Yves(yves@sspai.com) Download Cuto on the App Store and Google Play! */
  • body {
  • font-size: 15px;
  • color:#333;
  • background:#fff;
  • font-family: Helvetica, Arial, "PingFang SC", "Microsoft YaHei", "WenQuanYi Micro Hei", "tohoma,sans-serif";
  • margin: 0;
  • padding: 10%;
  • }
  • h1 {
  • font-size: 2.2em;
  • font-weight: 700;
  • line-height: 1.1;
  • padding-top: 16px;
  • margin-bottom: 4px;
  • }
  • h2, h3, h4, h5, h6 {
  • line-height: 1.5em;
  • margin-top: 2.2em;
  • margin-bottom: 4px;
  • }
  • h2 {
  • font-size: 1.4em;
  • margin: 40px 10px 20px 0;
  • padding-left: 9px;
  • border-left: 6px solid #ff7e79;
  • font-weight: 700;
  • line-height: 1.4;
  • }
  • h3 {
  • font-weight: 700;
  • font-size: 1.2em;
  • line-height: 1.4;
  • margin: 10px 0 5px;
  • padding-top: 10px;
  • }
  • h4 {
  • font-weight: 700;
  • text-transform: uppercase;
  • font-size: 1.1em;
  • line-height: 1.4;
  • margin: 10px 0 5px;
  • padding-top: 10px
  • }
  • h5, h6 {
  • font-size: .9em;
  • }
  • h5 {
  • font-weight: bold;
  • text-transform: uppercase;
  • }
  • h6 {
  • font-weight: normal;
  • color: #AAA;
  • }
  • img {
  • width: 100%;
  • border-radius: 5px;
  • display: block;
  • margin-bottom: 15px;
  • height: auto;
  • }
  • dl,ol,ul {
  • margin-top: 12px;
  • margin-bottom: 20px;
  • padding-left: 5%;
  • line-height: 1.8;
  • }
  • p {
  • margin: 0 0 20px;
  • padding: 0;
  • line-height: 1.8;
  • }
  • a {
  • color: #f22f27;
  • text-decoration: none;
  • }
  • a:hover {
  • color: #f55852;
  • text-decoration: underline;
  • }
  • a:focus {
  • outline-offset: -2px;
  • }
  • blockquote {
  • font-size: 1em;
  • font-style: normal;
  • padding: 30px 38px;
  • margin: 0 0 15px;
  • position: relative;
  • line-height: 1.8;
  • text-indent: 0;
  • border: none;
  • color: #888;
  • }
  • blockquote:before {
  • content: "“";
  • left: 12px;
  • top: 0;
  • color: #E0E0E0;
  • font-size: 4em;
  • font-family: Arial, serif;
  • line-height: 1em;
  • font-weight: 700;
  • position: absolute;
  • }
  • blockquote:after {
  • content: "”";
  • right: 12px;
  • bottom: -26px;
  • color: #E0E0E0;
  • font-size: 4em;
  • font-family: Arial, serif;
  • line-height: 1em;
  • font-weight: 700;
  • position: absolute;
  • bottom: -31px;
  • }
  • strong, dfn {
  • font-weight: 700;
  • }
  • em, dfn {
  • font-style: italic;
  • font-weight: 400;
  • }
  • del {
  • text-decoration: line-through;
  • }
  • /*code {font-size:90%;}*/
  • /*pre {text-align:left; overflow-x: scroll; color: #257fa0; background: #f6f6f6; padding: 10pt 15pt; border-radius: 3px; border: solid 1px #e2e2e2;}*/
  • pre {
  • margin: 0 0 10px;
  • font-size: 13px;
  • line-height: 1.42857;
  • word-break: break-all;
  • word-wrap: break-word;
  • border-radius: 4px;
  • white-space: pre-wrap;
  • display: block;
  • background: #f8f8f8;
  • padding: 10px 20px;
  • border: none;
  • margin-bottom: 25px;
  • color: #666;
  • font-family: Courier, sans-serif;
  • }
  • code {
  • color: #c7254e;
  • background-color: #f9f2f4;
  • border-radius: 4px;
  • font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
  • padding: 2px 4px;
  • font-size: 90%;
  • }
  • p > code {
  • color: #c7264e;
  • background-color: #f9f2f4;
  • font-size: .95em;
  • border-radius: 3px;
  • -moz-border-radius: 3px;
  • -webkit-border-radius: 3px;
  • }
  • figure {
  • margin: 1em 0;
  • }
  • figcaption {
  • font-size: 0.75em;
  • padding:0.5em 2em;
  • margin-bottom: 2em;
  • }
  • figure img {
  • margin-bottom: 0px;
  • }
  • hr {
  • margin-top: 20px;
  • margin-bottom: 20px;
  • border: 0;
  • border-top: 1px solid #eee;
  • }
  • ol p, ul p {
  • margin-bottom: 0px;
  • }
  • li {
  • margin-bottom: 0.75em;
  • margin-top: 0.75em;
  • }
  • ol#footnotes {
  • font-size: 0.95em;
  • padding-top: 1em;
  • margin-top: 1em;
  • margin-left: 0;
  • border-top: 1px solid #eaeaea;
  • counter-reset: footer-counter;
  • list-style: none;
  • color: #555;
  • padding-left: 5%;
  • margin: 20px 0;
  • }
  • ol#footnotes li {
  • margin-bottom: 10px;
  • margin-left: 16px;
  • font-weight: 400;
  • line-height: 2;
  • list-style-type: none;
  • }
  • ol#footnotes li:before {
  • content: counter(footer-counter) ". ";
  • counter-increment: footer-counter;
  • font-weight: 800;
  • font-size: .95em;
  • }
  • @keyframes highfade {
  • 0% {background-color: none;}
  • 20% {background-color: yellow;}
  • 100% {background-color: none;}
  • }
  • @-webkit-keyframes highfade {
  • 0% {background-color: none;}
  • 20% {background-color: yellow;}
  • 100% {background-color: none;}
  • }
  • a:target, ol#footnotes li:target, sup a:target {
  • animation-name: highfade;
  • animation-duration: 2s;
  • animation-iteration-count: 1;
  • animation-timing-function: ease-in-out;
  • -webkit-animation-name: highfade;
  • -webkit-animation-duration: 2s;
  • -webkit-animation-iteration-count: 1;
  • -webkit-animation-timing-function: ease-in-out;
  • }
  • a:target {
  • border:0;
  • outline: 0;
  • animation-iteration-count: 1;
  • -webkit-animation-timing-function: ease-in-out;
  • }
  • a:target {
  • border:0;
  • outline: 0;
  • tion-iteration-count: 1;
  • -webkit-animation-timing-function: ease-in-out;
  • }
  • a:target {
  • border:0;outline: 0;
  • }

备注:

在个性化定制自己的CSS样式文件时,打开输出的HTML格式文件查看HTML文档(F12),可查看HTML结构。

2、模板

2.1 highlight.js插件

官网:https://highlightjs.org/

官方文档:http://www.ghostchina.com/adding-syntax-highlighting-to-ghost-using-highlight-js/

highlight.js,轻量级的Web代码语法高亮库,建议下载到本地进行本地化转换代码高亮,在线转换需要选择合适的CDN(可能耗时长)

使用方法:

  • 本地引用 highlight.js

    下载后的 highlight.js 为 highlight.pack.js;假设路径为:当前md文档的assets/highlight

    • <script type="text/javascript" src="assets/highlight/highlight.pack.js"></script>
  • 本地引用highlight.js的css文件

    在路径 /highlight/styles 中选择一个CSS文件,可在 官网的演示 中查看不同CSS文件的代码高亮显示效果

    • <link rel="stylesheet" href="assets/highlight/styles/a11y-light.css" type="text/css"></link>
  • 调用initHighlightingOnLoad方法

    • <script>hljs.initHighlightingOnLoad();</script>

只需要上述3行代码,就能对HTML文档中 pre 和 code 标签内的源代码自动识别语言,并执行代码高亮。

在线引用的,参考:Markdown文章添加代码高亮

2.2 添加目录

侧边栏目录

  • <!--在线https://www.bootcdn.cn/jquery/)引用($("")符号)jquery.min.js-->
  • <!-- <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script> -->
  • <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  • <!--侧栏目录生成代码-->
  • <script>
  • //标题序号计数器
  • var hCount = [0, 0, 0, 0, 0, 0];
  • //设置计数器
  • function setHCount(number) {
  • //当前计数器加一
  • hCount[number - 1]++;
  • for (var i = number, length = hCount.length; i < length; i++) {
  • //子目录计数器全部置零
  • hCount[i] = 0;
  • }
  • }
  • //重命名目录名称
  • function setHTagValue(item, number) {
  • //获取标题名
  • var text = $(item).get(0).innerHTML;
  • //初始化空字符串
  • var before = "";
  • //生成序号
  • for (var i = 0, length = hCount.length; i < number; i++) {
  • if (i < number - 1)
  • before += hCount[i] + ".";
  • else
  • before += hCount[i] + " ";
  • }
  • //在标题前面若需要添加序号,在text前面加上序号参数(before)即可
  • $(item).get(0).innerHTML = before + text;
  • }
  • function renameHTag(item) {
  • var tag = $(item).get(0).localName;
  • if (tag === "h1") {
  • setHCount(1);
  • //console\.log("捕获到标签:%s", tag);
  • setHTagValue(item, 1);
  • }
  • if (tag === "h2") {
  • setHCount(2);
  • //console.log("捕获到标签:%s", tag);
  • setHTagValue(item, 2);
  • }
  • if (tag === "h3") {
  • setHCount(3);
  • //console.log("捕获到标签:%s", tag);
  • setHTagValue(item, 3);
  • }
  • if (tag === "h4") {
  • setHCount(4);
  • //console.log("捕获到标签:%s", tag);
  • setHTagValue(item, 4);
  • }
  • if (tag === "h5") {
  • setHCount(5);
  • //console.log("捕获到标签:%s", tag);
  • setHTagValue(item, 5);
  • }
  • if (tag === "h6") {
  • setHCount(6);
  • //console.log("捕获到标签:%s", tag);
  • setHTagValue(item, 6)
  • }
  • }
  • $(document).ready(function () {
  • $("h1,h2,h3,h4,h5,h6").each(function (i, item) {
  • //给<H>类标签编号
  • renameHTag(item);
  • //获取标签的名字,h1,还是h2
  • var tag = $(item).get(0).localName;
  • //为该标签设置id属性
  • $(item).attr("id", "wow" + i);
  • //添加一个页内超链接,并设置class选择器
  • // $("#category").append('<a class="new'+tag+'" href="#wow'+i+'">'+$(this).text()+'</a></br>');
  • $("#category").append('<a class="new' + tag + '" href="#wow' + i + '">' + $(item).text() + '</a></br>');
  • //为每一个标题超链接的class属性设置左边距
  • $(".newh1").css("margin-left", 0);
  • $(".newh2").css("margin-left", 20);
  • $(".newh3").css("margin-left", 40);
  • $(".newh4").css("margin-left", 60);
  • $(".newh5").css("margin-left", 80);
  • $(".newh6").css("margin-left", 100);
  • });
  • //设置class选择器为.book-body的html内容
  • $(".book-body").html($(".book-body").nextAll())
  • });
  • </script>
  • <style type="text/css">
  • @media (max-width: 1600px) {
  • .book-body {
  • /* padding-left: 200px; */
  • padding-right: 0px;
  • }
  • }
  • @media (max-width: 1400px) {
  • .book-body {
  • /* padding-left: 200px; */
  • padding-right: 0px;
  • }
  • }
  • @media (max-width: 1200px) {
  • .book-body {
  • /* padding-left: 300px; */
  • padding-left: 0px;
  • }
  • }
  • @media (max-width: 700px) {
  • .book-body {
  • padding-left: 0px;
  • }
  • }
  • @media (min-width: 600px) {
  • #category {
  • /* 绝对定位 */
  • position: fixed;
  • /* left: 20px; */
  • /* 目录显示的位置 */
  • right: 0px;
  • top: 6%;
  • /* 目录栏的高度,这里设置为60%主要是为了不挡住返回顶部和折叠按钮 */
  • max-height: 60%;
  • /* 目录显示的底色 */
  • background: #E1FFFF;
  • /* 目录添加边框 */
  • border: 1px solid #aaaaaa;
  • overflow: auto;
  • }
  • }
  • @media (-webkit-max-device-pixel-ratio: 1) {
  • ::-webkit-scrollbar-track-piece {
  • background-color: #FFF
  • }
  • ::-webkit-scrollbar {
  • width: 6px;
  • height: 6px
  • }
  • ::-webkit-scrollbar-thumb {
  • background-color: #c2c2c2;
  • background-clip: padding-box;
  • min-height: 28px
  • }
  • ::-webkit-scrollbar-thumb:hover {
  • background-color: #A0A0A0
  • }
  • }
  • </style>
  • <script>
  • // id="category" onclick="showOrCloseCategory()"
  • function showOrCloseCategory() {
  • var id = document.getElementById("category");
  • var book_body=document.getElementById("book_body");
  • //如果展开了
  • if (id.style.display == 'block') {
  • //console.log("开始展开");
  • id.style.display='none';
  • id.style.width="0%";
  • book_body.style.width="80%";
  • book_body.style.paddingleft=0;
  • }
  • //如果被折叠了
  • else if (id.style.display =='none') {
  • //console.log("开始折叠");
  • id.style.display = 'block';
  • book_body.style.width="80%";
  • id.style.width="auto";
  • }
  • }
  • </script>
  • <!--返回顶部-->
  • <a href="javascript:scroll(0,0)" style="position:fixed;float:right;right:40px;top:68%"> Top</a>
  • <!--返回底部-->
  • <a href="javascript:scroll(0,document.body.scrollHeight)" style="position:fixed;float:right;right:23px;top:76%"> Buttom</a>
  • <!--目录-->
  • <button onclick="showOrCloseCategory()" style="position:fixed;float:right;right:40px;top:71%;height:36px;;background-color:#7FFFAA">目录</button>
  • <!--文章主体部分-->
  • <div class="book-body" id="book_body" style="width:80%;display:block"> </div>
  • <!--目录栏设置占用宽度为20%可以根据实际情况设置-->
  • <div class="book-summary" id="category" style="width:auto;display:none" ></div>

使用i5ting_toc生成左侧可折叠目录

四、应用

1、输出为html

  • pandoc -s -f gfm -t html5 --css=css/github.css test.md -o test.html
  • -s :表示使用标准模板输出,为pdf、epub、epub3、fb2、docx和odt自动设置适当的页眉和页脚
  • -f gfm :表示使用 gfm(Github Flavored MarkDown) 引擎解析文件
    • Markdown文档采用的语法来源
    • 不推荐使用不太准确的markdown_github,只有在gfm不支持扩展的情况下才使用markdown_github
  • -t html5:表示输出格式为html5
  • --css=css/github.css :表示输出的HTML文件使用github.css样式表(指定路径)
    • css/表示github.css文件的路径(相对路径)
    • 若不指定css样式文件,则使用默认模板
  • test.md -o test.html :表示将MarkDown文件“test.md”输出为.html文件(建议不同名字)
    • -o FILE命令表示将输出写入指定文件而不是stdout,若FILE-,输出将输出到stdout

pandoc模板

对于不同的输出文档而言,使用pandoc -D <format> 可以输出该格式的模板。其中可以看到模板中使用了哪些变量。对于其中使用的变量一般可以使用YAML元数据块来设定。也可以在命令行中使用-M参数来指定。其中有一个重要的变量body,它是整个markdown的内容。这个是无法通过YAML或者命令行来设置的。

例如:pandoc使用html模板生成html页面,通过命令pandoc -D html查看缺省的模板,:

  • <!DOCTYPE html>
  • <html xmlns="http://www.w3.org/1999/xhtml" lang="$lang$" xml:lang="$lang$"$if(dir)$ dir="$dir$"$endif$>
  • <head>
  • <meta charset="utf-8" />
  • <meta name="generator" content="pandoc" />
  • <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  • $for(author-meta)$
  • <meta name="author" content="$author-meta$" />
  • $endfor$
  • $if(date-meta)$
  • <meta name="dcterms.date" content="$date-meta$" />
  • $endif$
  • $if(keywords)$
  • <meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$" />
  • $endif$
  • <title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
  • <style type="text/css">
  • code{white-space: pre-wrap;}
  • span.smallcaps{font-variant: small-caps;}
  • span.underline{text-decoration: underline;}
  • div.column{display: inline-block; vertical-align: top; width: 50%;}
  • $if(quotes)$
  • q { quotes: "“" "”" "‘" "’"; }
  • $endif$
  • </style>
  • $if(highlighting-css)$
  • <style type="text/css">
  • $highlighting-css$
  • </style>
  • $endif$
  • $for(css)$
  • <link rel="stylesheet" href="$css$" />
  • $endfor$
  • $if(math)$
  • $math$
  • $endif$
  • <!--[if lt IE 9]>
  • <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  • <![endif]-->
  • $for(header-includes)$
  • $header-includes$
  • $endfor$
  • </head>
  • <body>
  • $for(include-before)$
  • $include-before$
  • $endfor$
  • $if(title)$
  • <header>
  • <h1 class="title">$title$</h1>
  • $if(subtitle)$
  • <p class="subtitle">$subtitle$</p>
  • $endif$
  • $for(author)$
  • <p class="author">$author$</p>
  • $endfor$
  • $if(date)$
  • <p class="date">$date$</p>
  • $endif$
  • </header>
  • $endif$
  • $if(toc)$
  • <nav id="$idprefix$TOC">
  • $table-of-contents$
  • </nav>
  • $endif$
  • $body$
  • $for(include-after)$
  • $include-after$
  • $endfor$
  • </body>
  • </html>

在进行模板处理时,pandoc中会自动生成一些变量,某些变量是由用户指定。在模板中使用$变量名$引用一个变量,模板中可以使用条件判断。,形式如下:

  • $if(title)$
  • <title>$title$</title>
  • $else$
  • <title>缺省的标题</title>
  • $endif$

上面的意思是,如果定义了title变量,那么就输出title的内容,否则就输出缺省的标题。

明白默认模板中的内容后,可以定义自己的模板。使用--template=FILENAME来指定模板文件。

2、md转docx

  • pandoc test.md -o test.docx

这个转换比较简单,不用多做配置。

3、md转pdf

  • pandoc --pdf-engine=xelatex --template=D:\tools\Pandoc\pm-template.latex test.md -o test.pdf

pandoc 不能直接生成 pdf 文档,需要借助 LaTeX 引擎。其基本转换流程如下:

1553690880531

3.1 只输出英文

  • pandoc -f gfm -t latex --pdf-engine=xelatex test.md -o test.pdf

可以生成一个pdf,但是其中只有英文,没有中文!

3.2 指定字体输出中文

查看本地中文字体的命令:fc-list :lang=zh

  • D:/Tex Live/texmf-dist/fonts/opentype/public/fandol/FandolFang-Regular.otf: FandolFang,FandolFang R:style=Regular
  • C:/WINDOWS/fonts/msyhl.ttc: Microsoft YaHei,Microsoft YaHei Light:style=Light,Regular
  • C:/WINDOWS/fonts/Dengb.ttf: DengXian:style=Bold
  • D:/Tex Live/texmf-dist/fonts/truetype/public/arphic-ttf/bkai00mp.ttf: AR PL KaitiM Big5,文鼎PL中楷:style=Regular
  • D:/Tex Live/texmf-dist/fonts/opentype/public/fandol/FandolKai-Regular.otf: FandolKai:style=Regular
  • C:/WINDOWS/fonts/STZHONGS.TTF: STZhongsong:style=Regular
  • C:/WINDOWS/fonts/simsun.ttc: NSimSun,新宋体:style=Regular,常规
  • D:/Tex Live/texmf-dist/fonts/truetype/public/arphic-ttf/gbsn00lp.ttf: AR PL SungtiL GB:style=Regular
  • C:/WINDOWS/fonts/AdobeFanHeitiStd-Bold.otf: Adobe Fan Heiti Std,Adobe 繁黑體 Std B,Adobe Fan Heiti Std B:style=B,Bold
  • C:/WINDOWS/fonts/AdobeHeitiStd-Regular.otf: Adobe Heiti Std,Adobe Heiti Std R:style=R,Regular
  • C:/WINDOWS/fonts/AdobeSongStd-Light.otf: Adobe Song Std,Adobe Song Std L:style=L,Regular
  • C:/WINDOWS/fonts/Dengl.ttf: DengXian,DengXian Light:style=Light,Regular
  • C:/WINDOWS/fonts/AdobeMingStd-Light.otf: Adobe Ming Std,Adobe 明體 Std L,Adobe Ming Std L:style=L,Regular
  • C:/WINDOWS/fonts/AdobeFangsongStd-Regular.otf: Adobe Fangsong Std,Adobe Fangsong Std R:style=R,Regular
  • C:/WINDOWS/fonts/simfang.ttf: FangSong:style=Regular,Normaali
  • C:/WINDOWS/fonts/simkai.ttf: KaiTi:style=Regular,Normaali
  • C:/WINDOWS/fonts/msyh.ttc: Microsoft YaHei UI:style=Normal
  • C:/WINDOWS/fonts/STCAIYUN.TTF: STCaiyun:style=Regular
  • C:/WINDOWS/fonts/Deng.ttf: DengXian:style=Regular
  • C:/WINDOWS/fonts/STXINGKA.TTF: STXingkai:style=Regular
  • C:/WINDOWS/fonts/msyhl.ttc: Microsoft YaHei UI,Microsoft YaHei UI Light:style=Light,Regular
  • C:/WINDOWS/fonts/STXINWEI.TTF: STXinwei:style=Regular
  • C:/WINDOWS/fonts/msyhbd.ttc: Microsoft YaHei UI:style=Έντονα
  • D:/Tex Live/texmf-dist/fonts/opentype/public/fandol/FandolSong-Bold.otf: FandolSong:style=Bold
  • C:/WINDOWS/fonts/msjhl.ttc: Microsoft JhengHei,微軟正黑體 Light:style=Light,Regular
  • C:/WINDOWS/fonts/msjhl.ttc: Microsoft JhengHei UI,Microsoft JhengHei UI Light:style=Light,Regular
  • C:/WINDOWS/fonts/msyh.ttc: Microsoft YaHei:style=Normal
  • C:/WINDOWS/fonts/SIMYOU.TTF: YouYuan:style=Regular
  • D:/Tex Live/texmf-dist/fonts/truetype/public/arphic-ttf/bsmi00lp.ttf: AR PL Mingti2L Big5,文鼎PL細上海宋:style=Reguler,Regular
  • D:/Tex Live/texmf-dist/fonts/opentype/public/fandol/FandolHei-Regular.otf: FandolHei:style=Regular
  • C:/WINDOWS/fonts/STXIHEI.TTF: STXihei:style=Regular
  • D:/Tex Live/texmf-dist/fonts/truetype/public/arphic-ttf/gkai00mp.ttf: AR PL KaitiM GB:style=Regular
  • C:/WINDOWS/fonts/STKAITI.TTF: STKaiti:style=Regular
  • C:/WINDOWS/fonts/STLITI.TTF: STLiti:style=Regular
  • C:/WINDOWS/fonts/msyhbd.ttc: Microsoft YaHei:style=Έντονα
  • D:/Tex Live/texmf-dist/fonts/opentype/public/fandol/FandolHei-Bold.otf: FandolHei:style=Bold
  • C:/WINDOWS/fonts/simsun.ttc: SimSun,宋体:style=Regular,常规
  • C:/WINDOWS/fonts/STHUPO.TTF: STHupo:style=Regular
  • C:/WINDOWS/fonts/AdobeKaitiStd-Regular.otf: Adobe Kaiti Std,Adobe Kaiti Std R:style=R,Regular
  • C:/WINDOWS/fonts/STFANGSO.TTF: STFangsong:style=Regular
  • C:/WINDOWS/fonts/msjh.ttc: Microsoft JhengHei:style=Regular
  • C:/WINDOWS/fonts/FZYTK.TTF: FZYaoTi:style=Regular
  • D:/Tex Live/texmf-dist/fonts/opentype/public/fandol/FandolSong-Regular.otf: FandolSong:style=Regular
  • C:/WINDOWS/fonts/SIMLI.TTF: LiSu:style=Regular
  • C:/WINDOWS/fonts/msjhbd.ttc: Microsoft JhengHei UI:style=Félkövér
  • C:/WINDOWS/fonts/STSONG.TTF: STSong:style=Regular
  • C:/WINDOWS/fonts/msjh.ttc: Microsoft JhengHei UI:style=Regular
  • C:/WINDOWS/fonts/msjhbd.ttc: Microsoft JhengHei:style=Félkövér
  • C:/WINDOWS/fonts/simhei.ttf: SimHei:style=Normal
  • C:/WINDOWS/fonts/FZSTK.TTF: FZShuTi:style=Regular

XeLaTeX可以直接使用系统中的字体,无需自己生成字体文件。

  • pandoc -f gfm -t latex --pdf-engine=xelatex -V mainfont="Microsoft YaHei" test.md -o test.pdf

可以生成一个pdf,可以输出中文,但中文输出过长不会换行!

中文的换行 通过\XeTeXlinebreaklocale "zh"实现。pandoc的缺省模板中是没有这个设置的。

pandoc的默认latex模板:pandoc -D latex

因此考虑修改缺省的latex模板。方法如下:

  • 导出缺省的模板 pandoc -D latex > template.latex

  • 在模板的这部分下面加上这一行\XeTeXlinebreaklocale "zh"

    • $if(mathfont)$
    • $if(mathspec)$
    • \ifxetex
    • \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
    • \else
    • \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
    • \fi
    • $else$
    • \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
    • $endif$
    • $endif$
  • 在上面的命令行中指定使用新的模板。

安装TexLive 2018

这是个比较暴力的方法。该包有3G,安装需要较长的时间(估计1个小时左右)。

使用指定字体(系统字体或下载字体)时,导出pdf时可成功显示中文

  • pandoc --pdf-engine=xelatex -V mainfont="Microsoft YaHei" test.md -o test.pdf

中文正常显示后,发现中文不换行。原因是 Pandoc 使用的latex模板文件需要修改。

参考资料

官网:

个人博客:

感谢您的赞赏支持:

Gitalking ...

Copyright © 2020 komantao. All Rights Reserved.