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
    2020.11.30 初始
    2021.04.11 开始填坑...
    2021.04.16 第一阶段填坑完成

导语

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

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

至于为什么拖了这么长时间直接安装 latex 环境太大,而且对重装非常不友好,必须 docker 才行….给自己找事…

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

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

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.

预备

目标:

  • latex 使用 docker,跨平台同步.
  • vscode 可以一键编译 tex 文件
  • tex 和 pdf 双向链接
  • 文献引用的支持

方案

  • docker 运行的 TeX Live
  • vscode + LaTeX Workshop 插件支持 LaTex 编译
  • SumatraPDF 双向搜索
  • Zotero,文献管理.
  • 所有文件在同一个文件夹下,git 管理同步.

结果 :

  • 因为 SumatraPDF 只有 windows 版本,因此双向搜索只有在 win 平台了.
  • 正向搜索可能配置有小问题,无法跳转到 pdf 的字段,不排除是版本问题.
  • 其他功能可以跟随 vsc 同步,跨平台.

方案

因为使用 docker 的方式可以细分成两种.

方案 1

  • LaTeX Workshop 编译时直接 docker run xxx,几乎和本地安装 TeX Live相同.
  • 几乎和本地安装 TeX Live 配置相同.

结果 1:

  • 需要修改 LaTeX Workshop 的一点 js 代码.
  • 正向搜索无法跳转到 pdf 具体行,提示 未知文件,这可能是版本问题,也可能是系统问题.

方案 2(remote-containers):

  • 相当于运行一个 latex 环境,vsc 远程上去.
  • 可能 win 下无法实现双向搜索.
  • 最好是自行定制 docker 镜像.

结果 2:

  • 预期上,win / linux 体验几乎会完全相同

这篇文章大概会说到以上步骤的安装 && 配置.(大概最近会填坑)

方案 1

安装

说到底只是需要 XeLaTeX 的支持就好,因此直接用 LaTeX Workshop docker 模式默认的 tianon/latex

后端

  • tianon/latex
  • docker pull tianon/latex

编辑器

  • Vscode 主力编辑器
  • LaTeX Workshop 插件
  • SumatraPDF pdf 预览

文献管理

  • Zotero 文献管理
  • Zotero-better-bibtex 导出 bib 文件并更新
  • asminum 识别中文文献信息.

配置

LaTeX Workshop

配置分成两个部分

  • 编译,可以跨平台.
  • 双向搜索,只有 win (因为依赖于 smartpdf )

修改 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 %\*

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

ps: tianon/latex 不支持 pdflatex 命令.

编译

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

找到的最详细的图文见 科研利器—— 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 的中间步骤很多,中间文件也略多..配置一下清理.清理一般只需要全文完成后进行一次,双向搜索依赖于中间文件

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", // 自动换行

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

测试文件

下面是个简单的中文测试文件.包括几种常见中文字体.出处忘了….

上面的两种编译方式都能正常编译.

1
2
3
4
5
6
7
8
9
10
11
12
\documentclass[UTF8]{ctexart}

\begin{document}

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

推荐使用XeLaTeX或LuaLaTeX编译。对高级用户\cite{lozanoGlobalRegionalMortality2012}, 我们也推荐使用upLaTeX编译。\cite{tangDynamicallyAdaptiveCooperation2020}
{\kaishu 这里是楷体显示}
{\songti 这里是宋体显示}
{\heiti 我是黑体}
{\fangsong 这里是仿宋显示}
\end{document}

双向搜索

双向搜索指的是,在 tex 源文件,快捷键 Ctrl+Alt+J 可以跳转到 pdf 对应位置.pdf 双击可以返回 tex 文件对应位置,非常实用.

同样的最详细的图文见 科研利器—— 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

文献管理

待续

方案2

待续