Pandoc

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


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.css • Droplr™
/* 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模板文件需要修改。

参考资料

官网:

个人博客:

感谢您的赞赏支持:

Copyright © 2020 komantao. All Rights Reserved.