原因
一直比较喜欢用markdown写东西,毕竟对写作十分友好,但是写论文,排版和引用文献又几乎离不开word,平时用markdown写东西想引用文献,图片交叉引用等等也不是很方便,偶然发现vsc插件markdown preview enhanced 功能强大可以配合pandoc获得不错的写作体验,于是我就搞了一些,花了两天时间。
最终也不是特别满意,虽然写起来没有问题,但是感觉配置比较复杂,可能会遇到bug。不过至少实现了用md写文献的想法。md原生支持的或者tex支持的比如数学公式,表格,图片,代码块之类的没有问题,但是像我用chemdraw画的化学结构就只能转成图片插件去,这点不如word。
用我的这个方法不但可以使得引用的文献(reference)格式统一,自动编号,自动对引用位置(cite)格式编号进行设置,还可以自动对图片,表格进行编号,格式统一,交叉引用生成的文件内部添加链接,点击直达。
需要的软件
- vscode
- markdown preview enhanced
- markdown all in one
- markdownlint
- paste Image
- citation picker for zotero
- zotero LaTeX
主要是前面5个,其他的可选,只要不冲突装几个都行
- pandoc:开源的强大的文件转换软件,没有GUI只有命令行
- pandoc-crossref (版本要与pandoc匹配,版本不对不能用):图,表格等交叉引用,算是pandoc的一个插件
- miktex:tex的发行版,在这里是pandoc用来把md转换成pdf的,也可以安装texlive,只是觉得texlive是全安装,好几个G的东西只拿来转换pdf比较浪费,miktex是用的时候才会安装相应的引擎,比较小
上面这几个我都用scoop安装的,如果不用scoop,安装好之后要写入环境变量,保证命令行可以直接调用就行。 - zotero:文献管理软件,类似endnote,开源的,被誉为文献管理软件中的”瑞士军刀“,十分好用。如果用其他文献管理器,把文献导入进去就行,主要是为了生成bib,以及引用文献,可以 只把它作为一个在论文中插文献引用的软件也是可以的。
配置
zotero
可以参考别的地方
知乎文章——插件安装,其中最重要的是Better BibTex,其他插件可选
导入文献,不同文献管理器导入方法不同,可以上网查一下,方法很多,都很方便,如果不想把它作为主力文献管理器,可以不用导入文件,也不用分类。
导出bib:文件——》导出文献库》better BibLatex(勾选keep updated,随时更新导出的文件)最好保存到你写的文章的位置,不保存到那里也行。
MikTex
基本不用设置
双击miktex-portable,可以打开miktex配置窗口,可以更新一下,也可以不更新,主要要用它的pdflatex和xelatex,但是不需要手动安装,会在第一次运行的时候自动安装。
vscode
这个方法的核心就是markdown preview enhanced(MPE)这个插件。但是在这之前,先配置好其他的部分。
首先是配置文件:
"markdown-preview-enhanced.pandocMarkdownFlavor": "markdown+raw_tex+tex_math_dollars",
"markdown-preview-enhanced.usePandocParser": true,
"markdown-preview-enhanced.mathRenderingOption": "MathJax",
"[markdown]": {
"editor.defaultFormatter": "DavidAnson.vscode-markdownlint"
},
"markdown-preview-enhanced.pandocPath": "pandoc",
"markdown-preview-enhanced.pandocArguments": [
"--filter=pandoc-crossref",
"--number-sections",
],
"markdown-preview-enhanced.enableExtendedTableSyntax": true,
"markdown-preview-enhanced.enableHTML5Embed": true,
"markdown-preview-enhanced.latexEngine": "xelatex",
这里一定记得勾选上,不然会使用默认的markdown-it渲染,无法渲染出引用文献和交叉引用来
勾选了这个,默认的数学公式处理器(mathRenderingOption)KaTeX
就失效了,选用MathJax
就好了
latexEngine要选xelatex,pdflatex对中文支持不好,配置麻烦
pandocArguments配置中--filter=pandoc-crossref
可以理解成添加pandoc-crossref插件,用于交叉引用,--number-sections
是对章节目录添加序号,注意这两个参数只在预览中起作用
其他插件可以根据需要自行配置,有些插件是对内部预览器进行更改,对MPE无影响,所以没必要下载。
使用
文件头
---
title: xxx
bibliography: "../../bib/我的文库.bib"
pandoc_args:
- "--csl=../../bib/chinese-gb7714-2005-numeric.csl"
figureTemplate: $$figureTitle$$ $$i$$ $$t$$
figureTitle: 图
output:
pdf_document:
latex_engine: xelatex
pandoc_args: [
"--csl=../../bib/chinese-gb7714-2005-numeric.csl",
"--filter=pandoc-crossref",
"--number-sections"
]
template: "mydir\\template.latex"
---
两个
---
中间的部分叫front matter,用于定义一些marddown信息,具体可以查看MPE文档
其中:
- bibliography :表示zotero生成的bib文件所在的位置,可以是相对路径也可以是绝对路径,比较推荐绝对路径。打开bib文件里面大概是下面的样子,其中citekey是唯一的并且可以自行定义的,用于引用这一篇文章,在生成pdf的时候,pandoc会根据citekey去bib文件中查找文章信息,并根据csl格式将需要的信息拿出来生成reference(结尾的一长串文献)。因此要告诉pandoc这个bib在哪里
@article{citekey,
title = {},
author = {},
date = {},
journaltitle = {},
shortjournal = {},
volume = {},
number = {},
eprint = {},
eprinttype = {},
pages = {},
issn = {},
doi = {},
abstract = {},
...
}
- csl: 就是结尾的reference所用的格式,用于告诉pandoc,作者放前面还是文章名放前面,作者写几个,姓名格式用不用缩写,后面先写年份还是先期刊名,大写小写,字体,大小等等信息。可以在zotero中下载(编辑——》首选项),也可以自己编辑:
- output:表示输出文件的一些参数,不影响在右侧的显示,这一部分作用是:右侧预览窗口中,右键——》Pandc输出想要的格式的文件的
- pdf_doucment:表示输出成pdf
- latex_engine:xelate输出成pdf的时候用的引擎
- csl:与上面不同的是,上面影响的预览窗口的格式,下面影响的输出文件的格式,两者互不影响
- filter:也是只在输出的时候起作用,另外在MPE设置中设置的两个参数则不再起作用
- number-sections:对文章标题编号
- tempalte:latex模板,需要进行一些设置
在这里还可以通过设置
pandoc_args:
设置很多pandoc的参数,pandoc有着复杂的参数,可以查看pandoc文档 另外除了title,还可以设置,abstract,author等等各种文档信息,参考MPE文档
注意pandoc转换成pdf的方法其实是先转换成tex文件,然后在通过tex引擎转换成pdf,所以需要向tex一样需要一个模板,pandoc是自带一个默认模板的。pandoc -D latex > template.latex
可以获取默认模板,默认模板不支持中文,因此需要做一些更改,如果你生成的模板跟我的差不多的话,可以在90行-117行之间添加比下面少的部分,设置中文字体,主要要设置你电脑上有的字体,不然也会报错,另外我尝试中文设置微软雅黑:Micorsoft YaHei
发现是不行的,不知道为啥。这里可以参考tex排版知识,只不过语法复杂,学习起来困难,不如直接模仿。
$if(linestretch)$
\usepackage{setspace}
$endif$
\usepackage{iftex}
\ifPDFTeX
\usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp} % provide euro and other symbols
\else % if luatex or xetex
\usepackage{fontspec} % 允許設定字體
\usepackage{xeCJK} % 分開設置中英文字型
\setCJKmainfont{SimHei} % 設定中文字型
\setmainfont{Times New Roman} % 設定英文字型
\setromanfont{Times New Roman} % 字型
\setmonofont{Courier New}
\linespread{1.2}\selectfont % 行距
\XeTeXlinebreaklocale "zh" % 針對中文自動換行
\XeTeXlinebreakskip = 0pt plus 1pt % 字與字之間加入0pt至1pt的間距,確保左右對整齊
$if(mathspec)$
\ifXeTeX
\usepackage{mathspec}
\else
\usepackage{unicode-math}
\fi
$else$
\usepackage{unicode-math}
$endif$
文件内容
交叉引用
图片添加标题
![imgname](imgpath){#fig:imgcitekey}
与一般md中插入图片不同的是,imgname是必填的,因为会作为图片的标题,
{}
中内容可以理解为添加一个锚点,#fig
表示是图片,冒号后面是引用的key,要保证是唯一的,一般可以用图片的题目,这样自己写起来也不容易混乱,另外,cite可以中是不能有空格的,也不能有冒号,括号等等。
注意这里{}
要紧跟前面,不能有空格
引用图片:
引用图片[@fig:imgcitekey]
[]
中@表示引用,引用图片的citekey
图表等等内容方法类似,只不过相应标志换成了tbl
,可以查看pandoc-crossref文档
实例:
引用文献
首先要保证zotero打开
在vscode中alt+shift+z
或者ctrl+shift+p
——》Zotero Citation Picker,打开下面的窗口(可能不会跳出来,需要到zotero界面去找)
可以直接输入要插入的文章名称或者其他信息,下面会直接出搜索结果,也可以选择经典视图去直接找要插入的文章。然后输入enter
插入即可。
实例:
引用文献[@mycitekey]
注意这里要手动加
[]
导出
MPE可以用pandoc导出各种格式文件,包括docx。
在配置好pandoc路径之后,在预览窗口,右击——》Pandoc即可自动导出成pdf
一开始我总是遇到找不到xelatex
引擎的问题,虽然设置了--pdf-latex=xelate
,但是在powershell使用pandoc可以,最后把xelatex手动添加到了系统环境变量,然后重启电脑,才正常的。
中间好多次出现下面的问题:
命令行导出
template 配置文件有问题,pandoc我所用版本默认配置文件没问题,从网上下载的别人的template有问题,我手动将默认的导出并在默认基础上修改的,具体如上
字体设置问题,中文字体使用微软雅黑不行,使用宋体,黑体等等可以,可能是因为微软雅黑是多种字体在一起,无法识别或者说无法选择
也是字体问题,同样是因为微软雅黑不行
照片路径问题,pandoc转换时候,是根据当前路径转换,相对路径不好使,相对路径只能在md文件所在目录执行pandoc
成功生成pdf但是中文全是空白
字体问题,还是要在template中设置合适字体,微软雅黑不行
生成的文件没有参考文献
filter=pandoc-crossref必须在output部分定义,之前定义的只影响右侧显示,其他参数同理
md图片引用后面要有空行,不然就会识别不到citekey信息,图片标题也不显示
总结
能实现这两个功能确实不容易,但是也会牺牲md一些其他的扩展功能,比如mermaid思维导图流程图等等,另外也会让渲染变慢,对md格式要求更高一些(比如之前图片后面不用空行)。不过相比与能引用文献,这些都是小事情。
问题补充
中文首行缩进
可以按原来md方法进行首行缩进,但是每段都要设置比较麻烦。
在windows中,~/.mume
目录下,可以设置mpe预览的格式
使用如下代码,在style.less
中可以设置首行缩进:
/* Please visit the URL below for more information: */
/* https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */
.markdown-preview.markdown-preview {
// modify your style here
// eg: background-color: blue;
p {
text-indent: 2em;//首行缩进
}
}