Vscode + Latex 环境踩坑

  • Vscode + Latex 环境配置 (应该不是踩坑,直接埋了) ≡(▔﹏▔)≡.

  • 资料来源:

    https://colainlibrary.com/archives/f7fcf26c.html
    https://zhuanlan.zhihu.com/p/136931926
    https://liam.page/2014/09/08/latex-introduction/
    http://ctan.math.utah.edu/ctan/tex-archive/language/chinese/ctex/ctex.pdf

  • 更新

    1
    2
    3
    4
    5
    2020.11.30 初始
    2021.04.11 开始填坑...
    2021.04.16 第一阶段填坑完成
    2021.05.14 第二阶段开始填坑
    2021.05.21 填坑0.8

导语

之后的日子里,每当想起赶论文被 word 支配的恐惧…应该会庆幸入了 LaTex 的坑.

word 巨复杂的功能,搞得烦上加烦,并最终空出了一个周末来熟悉 LaTex.环境是初步能运行了,就是语法的坑还在后面😂.

  • (20.12.05)至于为什么拖了这么长时间,texlive 环境太乱了
  • (21.4.11)对重装非常不友好,必须 docker 才行..可能在给自己找事…
  • (21.05.21)真的是再给自己找事…

大量参考了下面的几篇文章/库

科研利器—— VS Code + LaTeX
macOS下配置VSCode+Latex Workshop+Docker中文LaTeX环境
如何利用docker与vscode写latex
https://github.com/alexpovel/latex-extras-docker
https://github.com/nelsond/docker-texlive

LaTex 简史

Tex

  • 高德纳教授嫌弃出版社的排版系统,为了自己的著作-电脑程序设计艺术排版,毅然决然决定编写一套排版系统.
  • Tex 算是一种轻量级标记语言,类似的还有 Markdown.
  • Tex 的版本号自从第 3 版后,就越来越接近 $\pi$.高教授说自己过世后版本号就改成 $\pi$.之后的程序 bug 就当成程序功能.😂.
  • 每一个 bug 的奖励金额从 2.56 美元开始翻倍,目前是327.68美元封顶.牛人的自豪..

LaTex

  • 高教授的 Tex 对普通用户来说还是太难上手了,于是 LaTex 出现了.
  • LaTex 是莱斯利·兰波特上世纪 80 年代开发的基于 Tex 的排版系统,普通用户无需排版的知识也能短时间生成高质量印刷品-
  • LaTex 算是 TeX描述的宏软件,有很多预设的模版.
  • 但是 LaTex 开始时只为英文设计,对其他语言支持度很低..

XeLaTeX

  • 为了支持 Unicode 和现代字体,特别是可以从系统之间调用字体,大大降低了安装难度.(字体问题一言难尽,可能需要另外一个篇幅来说了)
  • 算是 Tex 家族又一干将.

CTeX 套装与 CTex 宏集

  • CTeX 套装是在 XeLaTeX 之前被广泛使用的中文 Tex 排版系统,属于 XeLaTeX LaTex 的同类系统,但是 12 年以后已经停止更新了.
  • CTex 宏集是 LaTeX 的宏包和文档类集合,目前中文排版常用这个.
  • CTex宏集手册
  • 千万不要搞混了…

还有其他 N 多 Tex 和渲染引擎,有时间再一一说吧.

总之后端渲染中文需要安装 TeX Live.

目标

  • 跨平台同步 win/linux
  • 一键编译 tex 文件
  • tex 和 pdf 双向跳转
  • 文献引用支持
  • vsc 同步,跨平台

总结参考文献有

  • 后端毫无疑问是 TeX Live
  • 前端是 vscode 搭配 LaTeX Workshop
  • Zotero,文献管理.
  • 双向搜索,可以是 SumatraPDF 或 vsc 内 tab,SumatraPDF 只有 windows,因此暂定使用用 vsc tab.
  • 最后 git 管理同步.

结果 :

  • 有 3 种方案,目前主力在用方案 3,vsc 的 remote containers.
  • 方案 2 双向跳转较复杂,其他基本完工.

LaTeX Workshop

  • 除了上面提到的功能,还提供了诸如 tex 目录,math 公式快捷输入等等,简直是居家旅行,杀人越货必备良药.
  • 方便的话,一定点个 star -> LaTeX-Workshop

双向跳转

  • 在 tex 源文件,快捷键 Ctrl+Alt+J 可以跳转到 pdf 对应位置.pdf 双击 可以返回 tex 文件对应位置,非常实用.
  • vsc 内 tab 跳到 pdf 也是 Ctrl+Alt+J,跳回 tex 是 ctrl + 双击

方案

按照 texlive 安装在那,可以分成 3 种方案.

方案 1

  • 宿主机直接安装 texlive

结果1

  • 需求都可以满足
  • 不方便重装和跨平台

方案 2

  • LaTeX Workshop 编译时直接 docker run xxx,下载个能用 texlive 镜像就行.
  • 但是只支持 latexmk,常用的 xelatex 需要修改 js.
  • 配置几乎和本地安装 TeX Live相同.

结果 2:

  • 双向跳转实现麻烦,其他正常
    • 正向搜索依赖 synctex ,TeXLive 直接带了.这里需要自行安装(未尝试).

方案 3 (remote-containers):

  • 相当于 docker 运行一个完备 latex 环境,vsc 远程上去.
  • linux 需要处理一些文件权限问题
  • 最好是自行定制 docker 镜像.

结果 3:

  • win / linux 体验几乎完全相同

这篇文章大概会说到以上步骤的安装 && 配置.

(大概最近会填坑)

下面是各个方案的详细配置,文献管理/测试文件 放在最后说了.

方案 1

宿主机直接安装 texlive 相关文章很多了,重点看下面这 3 篇.

科研利器—— VS Code + LaTeX
macOS下配置VSCode+Latex Workshop+Docker中文LaTeX环境
如何利用docker与vscode写latex

方案 2

说到底只是需要 XeLaTeX 的支持就好,LaTeX Workshop 支持 docker 模式.唯一的问题是双向跳转..

安装

这里镜像直接用默认的 tianon/latex, 理论上命令行能运行编译命令的都行.

1
docker pull tianon/latex

双向跳转依赖 synctex 需要自行安装.

双向跳转这里选择 SumatraPDF.

修改 js 增加 xelatex/pdflatex/bibtex 调用

参考 macOS下配置VSCode+Latex Workshop+Docker中文LaTeX环境, LaTeX Workshop docker 模式下似乎只有 latexmk 命令..

对应代码在 这里,本地文件对应 user\.vscode\extensions\james-yu.latex-workshop-8.16.1\out\src\components\builder.js

虽然没学过 js,不过大意还看懂了,docker 模式下只有 latexmk 才能正常调用,且win 下调用的是 /scripts/ 文件夹下的 bat 文件.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (docker) {
switch (step.command) {
case 'latexmk':
if (process.platform === 'win32') {
step.command = path.resolve(this.extension.extensionRoot, './scripts/latexmk.bat')
} else {
step.command = path.resolve(this.extension.extensionRoot, './scripts/latexmk')
fs.chmodSync(step.command, 0o755)
}
break
default:
break
}
}

依葫芦画瓢,修改如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

if (docker) {
switch (step.command) {
case 'latexmk':
this.extension.logger.addLogMessage('Use Docker to invoke the command latexmk.');
if (process.platform === 'win32') {
step.command = path.resolve(this.extension.extensionRoot, './scripts/latexmk.bat');
}
else {
step.command = path.resolve(this.extension.extensionRoot, './scripts/latexmk');
fs.chmodSync(step.command, 0o755);
}
break;
case 'xelatex':
this.extension.logger.addLogMessage('Use Docker to invoke the command xelatex.');
if (process.platform === 'win32') {
step.command = path.resolve(this.extension.extensionRoot, './scripts/latexmk.bat');
}
step.command = path.resolve(this.extension.extensionRoot, './scripts/xelatex');
fs.chmodSync(step.command, 0o755);
break;
case 'pdflatex':
this.extension.logger.addLogMessage('Use Docker to invoke the command pdflatex.');
if (process.platform === 'win32') {
step.command = path.resolve(this.extension.extensionRoot, './scripts/latexmk.bat');
}
step.command = path.resolve(this.extension.extensionRoot, './scripts/pdflatex');
fs.chmodSync(step.command, 0o755);
break;
case 'bibtex':
this.extension.logger.addLogMessage('Use Docker to invoke the command bibtex.');
if (process.platform === 'win32') {
step.command = path.resolve(this.extension.extensionRoot, './scripts/latexmk.bat');
}
step.command = path.resolve(this.extension.extensionRoot, './scripts/bibtex');
fs.chmodSync(step.command, 0o755);
break;
default:
break;
}
}

另外在 user\.vscode\extensions\james-yu.latex-workshop-8.16.1\scripts 下添加 bibtex bibtex.bat pdflatex pdflatex.bat xelatexxelatex.bat

bibtex

1
2
3
#!/bin/sh

docker run -i --rm -w "$(pwd)" -v "$(pwd):$(pwd)" $LATEXWORKSHOP\_DOCKER\_LATEX bibtex "$@"

bibtex.bat

1
@docker run -i --rm -w /data -v "%cd%:/data" %LATEXWORKSHOP\_DOCKER\_LATEX% bibtex %\*

pdflatex

1
2
3
#!/bin/sh

docker run -i --rm -w "$(pwd)" -v "$(pwd):$(pwd)" $LATEXWORKSHOP\_DOCKER\_LATEX pdflatex "$@"

pdflatex.bat

1
@docker run -i --rm -w /data -v "%cd%:/data" %LATEXWORKSHOP\_DOCKER\_LATEX% pdflatex %\*

xelatex

1
2
3
#!/bin/sh

docker run -i --rm -w "$(pwd)" -v "$(pwd):$(pwd)" $LATEXWORKSHOP\_DOCKER\_LATEX xelatex "$@"

xelatex.bat

1
@docker run -i --rm -w /data -v "%cd%:/data" %LATEXWORKSHOP\_DOCKER\_LATEX% xelatex %\*

接下来就能正常添加编译的命令了.


  • tianon/latex 不支持 pdflatex 命令.
  • Latex Workshop 主线支持以前, 每次插件更新后都需要进行一次设置.

配置

LaTeX Workshop

配置分成两个部分

  • 编译,可以跨平台.
  • SumatraPDF 双向搜索,只有 win.
  • 如果是 vsc tab 的双向跳转,不需要复杂配置,只需要配置 "latex-workshop.view.pdf.viewer": "tab" 从 vsc 打开 pdf 即可.

编译

编译这一块的命令是可以跨平台同步的.

找到的最详细的图文见 科研利器—— VS Code + LaTeX

这里只给具体配置了.在 vsc 的 setting.json 文件.

首先是启用 docker 和配置使用的 docker 镜像.

1
2
"latex-workshop.docker.enabled": true, //使用docker
"latex-workshop.docker.image.latex": "tianon/latex", //docker镜像,这里是默认镜像

接下来是编译用到的具体命令 latexmk / xelatex / bibtex,对应 latex-workshop.latex.tools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"latex-workshop.latex.tools": [
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-xelatex",
"-outdir=%OUTDIR%",
"%DOCFILE%" //相对路径
],
"env": {}
},
{
"name": "xelatex",
"command": "xelatex",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"%DOCFILE%"
],
"env": {}
},
{
"name": "bibtex",//参考文献
"command": "bibtex",
"args": [
"%DOCFILE%"
],
"env": {}
}
],

latex-workshop.latex.tools 配置的命令可以在 latex-workshop.latex.recipes 自由组合成最终编译执行的步骤.这里只保留两个示例,其他请自行添加.

  • latexmk: LaTeX Workshop 默认支持的,简单测试下支持文献和一些常见中文字体,而且一次编译后,以后的编译时间都会大幅度缩短,还没查详细资料,待补充.
  • xelatex ➞ bibtex ➞ xelatex: 上面查到的文献都提到了这样编译中文 latex,bibtex 是文献索引,xelatex 是其他内容,编译两边防止一次编译遗漏?..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"latex-workshop.latex.recipes": [
{
"name": "latexmk",
"tools": [
"latexmk"
]
},
{
"name": "xelatex ➞ bibtex ➞ xelatex`×2",
"tools": [
"xelatex",
"bibtex",
"xelatex",
"xelatex"
]
}
],

因为从编译到最终 pdf 的中间步骤很多,中间文件也略多..配置一下清理.双向跳转依赖 synctex,因此不要清理.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
"latex-workshop.latex.clean.fileTypes": [  //设定清理文件的类型  
"*.aux",
"*.bbl",
"*.blg",
"*.idx",
"*.ind",
"*.lof",
"*.lot",
"*.out",
"*.toc",
"*.acn",
"*.acr",
"*.alg",
"*.glg",
"*.glo",
"*.gls",
"*.ist",
"*.fls",
"*.log",
"*.fdb_latexmk",
"*.nav",
"*.snm",
//"*.synctex.gz"
]

其他

  • 不需要自动编译,占 cpu.
  • 启用自动完成,聊胜于无.
1
2
3
4
"latex-workshop.latex.autoBuild.run": "never", // 不自动编译
"latex-workshop.intellisense.package.enabled": true,//自动完成
"latex-workshop.showContextMenu": true, //右键菜单
"editor.wordWrap": "on", // 自动换行

以上配置完成后,就可以正常编译了.

SumatraPDF 双向搜索

最详细的图文见 科研利器—— VS Code + LaTeX

SumatraPDF,一个非常精简的 pdf/epub/mobi…阅读器,有时间会再写一点 SumatraPDF 的配置,现在常用软件.

正向 tex -> pdf

首先需要启用外部阅读器,到 SumatraPDF 预览 pdf

1
2
3
"latex-workshop.view.pdf.viewer": "external", //使用外部pdf阅读器
"latex-workshop.view.pdf.ref.viewer":"external",
"latex-workshop.view.pdf.external.viewer.command": "xxxx/SumatraPDF-3.2-64.exe",

正向搜索,直接复制,把 vsc 路径修改一下.

1
2
3
4
5
6
7
8
9
10
11
12
// 正向搜索
"latex-workshop.view.pdf.external.synctex.command": "D:\\Users\\stati\\OneDrive\\PortableApps\\SumatraPDF\\SumatraPDF-3.2-64.exe",
// "latex-workshop.view.pdf.external.synctex.command": "D:/Users/stati/AppData/Local/SumatraPDF/SumatraPDF.exe",
"latex-workshop.view.pdf.external.synctex.args": [
"-forward-search",
"%TEX%",
"%LINE%",
"-reuse-instance",
"-inverse-search",
"\"C:/Program Files/Microsoft VS Code/Code.exe\" \"C:/Program Files/Microsoft VS Code/resources/app/out/cli.js\" -r -g \"%f:%l\"",
"%PDF%",
],
反向 pdf -> tex

可以直接在 vsc 的 setting 中修改:

反向搜索,直接复制,把 vsc 路径修改一下.

1
2
3
4
5
6
7
8
9
"latex-workshop.view.pdf.external.viewer.args": [
"-forward-search",
"%TEX%",
"%LINE%",
"-reuse-instance",
"-inverse-search",
"\"C:/Program Files/Microsoft VS Code/Code.exe\" \"D:/Program Files/Microsoft VS Code/resources/app/out/cli.js\" -r -g \"%f:%l\"",
"%PDF%",
],

或者在 SumatraPDF 设置->选项->设置反向搜索命令行,同样的效果.

1
"C:\Program Files\Microsoft VS Code\Code.exe" "C:\Program Files\Microsoft VS Code\resources\app\out\cli.js" -g "%f":%l

方案 3

详情见 Latex + Vscode Remote containers

文献管理

参考 Zotero:科研小白的第一款文献管理软件

文献管理最终目的

  • 记录所有阅读过文献
  • 支持同步和备份
  • 支持多种路径文献导入,甚至 pdf 拖拽直接识别.
  • 跨平台

Zotero 完全满足.基本的安装配置等均见上文,这里只提几个细节.

  • 与 latex 配合依赖于插件 Zotero-better-bibtex 导出 bib 文件并更新
  • asminum 中文文献必不可少,直接识别中文 pdf,支持浏览器插件导入知网.这两点太方便了.

测试文件

下面是个简单的中文测试文件.包括 CTex 内置的 4 种中文字体.原始出处忘了,又加上了引用测试.

上面的 xelatexlatexmk 都能正常编译.需要把 test.texREF.bib 放到相同路径下.

test.tex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
\documentclass[UTF8]{ctexart}

\begin{document}

中文文档类测试。你需要将所有源文件保存为 UTF-8编码。

引用测试 \cite{lozanoGlobalRegionalMortality2012}.

CTEX 默认 4 种字体

\begin{itemize}
\item {\songti 这里是宋体显示}
\item {\heiti 这里是黑体显示}
\item {\fangsong 这里是仿宋显示}
\item {\kaishu 这里是楷体显示}
\end{itemize}

\bibliography{REF} % 导入lib,ref为“ref.lib"的文件名
\bibliographystyle{ieeetr} % 参考文献排版风格,这个是IEEE transaction的,其他可以自查

\end{document}

REF.bib: 太长了,参见: REF.bib