基础概念

LaTeX WorkShop 插件的编译逻辑分为两层:第一层为recipe,第二层为tool,具有如下特点:

  • 一个recipe由若干个tool组成;
  • 在配置文件中可以提供多个recipe和多个tool;
  • 直接点击编译按钮会自动选择第一个(或上一次使用的)recipe来执行编译;
  • 一个tool通常包括一个单独的编译命令加上若干参数,例如xelatex,lualatex和pdflatex等,还可能是处理参考文献需要的bibtex或biber;
  • 一个recipe会依次执行它所包含的tool,例如:
    1
    xelatex -> bibtex -> xelatex -> xelatex

下文中编译命令及其选项可以参考其它几篇关于LaTeX的笔记,LaTeX WorkShop 插件只是对这些编译命令进行了封装。 此外,LaTeX WorkShop 插件会在命令中传递特殊变量%DOC%%DOCFILE%代表当前文件,第一个是文件名(含完整路径,不含后缀),第二个则是文件名(不含后缀),略有区别。

由于插件也只是调用了pdflatexlatexmk等编译命令,如果环境中存在.latexmkrc等配置文件,可能会对插件的编译行为造成影响。 但是因为插件的选项是通过命令行参数传递的,优先级更高,影响应该不大。

LaTeX WorkShop 插件并不推荐使用例如% !TEX program = xelatex的魔法命令来指定编译命令,但是考虑到向后兼容性会为其提供有限的支持,需要在设置中开启相关选项。

编译配置(一)

第一种配置是使用latexmk分别调用xelatex,lualatex和pdflatex,配置如下

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// latex基本工具链 latex-workshop.latex.tools
"latex-workshop.latex.tools": [
{
"name": "xelatexmk",
"command": "latexmk",
"args": [
"-file-line-error",
"-halt-on-error",
"-interaction=nonstopmode",
"-synctex=1",
"-xelatex",
"-auxdir=%DIR%/.aux",
"-outdir=%OUTDIR%",
"%DOC%"
],
"env": {}
},
{
"name": "lualatexmk",
"command": "latexmk",
"args": [
"-file-line-error",
"-halt-on-error",
"-interaction=nonstopmode",
"-synctex=1",
"-lualatex",
"-outdir=%OUTDIR%",
"-auxdir=%DIR%/.aux",
"%DOC%"
],
"env": {}
},
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-file-line-error",
"-halt-on-error",
"-interaction=nonstopmode",
"-synctex=1",
"-pdf",
"-outdir=%OUTDIR%",
"-auxdir=%DIR%/.aux",
"%DOC%"
]
}
],
// latex组合工具链 latex-workshop.latex.recipes
"latex-workshop.latex.recipes": [
{
"name": "XeLaTeXmk",
"tools": [
"xelatexmk"
]
},
{
"name": "LuaLaTeXmk",
"tools": [
"lualatexmk"
]
},
{
"name": "LaTeXmk",
"tools": [
"latexmk"
]
}
],

在某些情况下的编译可能需要加上 "-shell-escape" 选项。

编译配置(二)

第二种配置是不使用 latexmk,直接使用xelatex等编译命令, 此时由于参考文献(bibtex或biber)和双向引用等原因,需要配置recipe进行多次编译,配置如下

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
"latex-workshop.latex.tools": [
{
"name": "xelatex",
"command": "xelatex",
"args": [
"-file-line-error",
"-halt-on-error",
"-interaction=nonstopmode",
"-synctex=1",
"%DOC%"
]
},
{
"name": "pdflatex",
"command": "pdflatex",
"args": [
"-file-line-error",
"-halt-on-error",
"-interaction=nonstopmode",
"-synctex=1",
"%DOC%"
]
},
{
"name": "bibtex",
"command": "bibtex",
"args": [
"%DOCFILE%"
]
}
],
"latex-workshop.latex.recipes": [
{
"name": "xelatex->xelatex",
"tools": [
"xelatex",
"xelatex"
]
},
{
"name": "xelatex",
"tools": [
"xelatex"
]
},
{
"name": "pdflatex",
"tools": [
"pdflatex"
]
},
{
"name": "BibTeX",
"tools": [
"bibtex"
]
},
{
"name": "xe->bib->xe*2",
"tools": [
"xelatex",
"bibtex",
"xelatex",
"xelatex"
]
},
{
"name": "pdf->bib->pdf*2",
"tools": [
"pdflatex",
"bibtex",
"pdflatex",
"pdflatex"
]
}
],

这组配置并没有使用.aux/子目录存放辅助文件,因为这些编译命令虽然支持指定输出目录,但是无法自动创建目录。

VSCode与SumatraPDF双向跳转

除了 tools 和 recipes 这两个主要的配置,还有一个重要的功能是双向跳转, 通过VSCode内部预览PDF时,可以直接进行双向跳转,无需任何配置。 默认的双向跳转操作是:

  • ctrl + 单击PDF相应位置,从PDF跳转到源文件对应位置
  • ctrl+alt+j,从源文件跳转到PDF对应位置

由于内部预览无法拆分窗口,在外部使用SumatraPDF进行PDF预览可能更加方便,下面考虑配置支持VSCode和SumatraPDF之间的双向跳转。

参考 LaTeX-Workshop的wiki 以及 SumatraPDF的相关讨论

对于VSCode的配置如下:

1
2
3
4
5
6
7
8
9
10
11
"latex-workshop.view.pdf.viewer": "external",
"latex-workshop.view.pdf.external.synctex.command": "<path-to-SumatraPDF>/SumatraPDF.exe",
"latex-workshop.view.pdf.external.synctex.args": [
"-forward-search",
"%TEX%",
"%LINE%",
"-reuse-instance",
"-inverse-search",
"\"<path-to-vscode>/Code.exe\" \"<path-to-vscode>/resources/app/out/cli.js\" --ms-enable-electron-run-as-node -r -g \"%f:%l\"",
"%PDF%"
],

对于SumatraPDF的高级选项配置为:

1
2
InverseSearchCmdLine = "<path-to-vscode>/Code.exe" "<path-to-vscode>/resources/app/out/cli.js" --ms-enable-electron-run-as-node  -r -g "%f:%l"
EnableTeXEnhancements = true

如果打开SumatraPDF的设置面板找不到Set inverse command-line这个项, 需要在高级选项中首先打开Tex增强选项:EnableTeXEnhancements = trueSet inverse command-line在配置文件中实际上是 InverseSearchCmdLine = ... 这一项。

注意配置中的参数顺序,如果跳转中断在cli.js文件,可以尝试将 --ms-enable-electron-run-as-node 移动到cli.js之前。 如果VS Code始终无法打开SumatraPDF,可以试着把SumatraPDF.exe的路径添加到环境变量PATH。

测试发现,上面的这个配置仍然只能在受限的条件下正常工作, 如果在 VSCode 中通过源文件跳转的方式启动 SumatraPDF,很可能对于PDF文件无法进行跳转回到源文件, 这个问题可能和 SumatraPDF 的启动方式有关,通过VSCode启动时继承了 VSCode 的某些上下文,使得双向跳转失败。

最好的使用方式是:单独使用vscode打开tex文件(或者对应的文件夹),使用SumatraPDF打开PDF文件,然后在两者之间可以进行双向跳转。

VSCode 补充配置

除了最主要的编译部分和双向跳转,还有一些可能有用的,与LaTeX相关的辅助性配置

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
"[latex]": {
"editor.defaultFormatter": "James-Yu.latex-workshop",
"editor.wordWrap": "on",
"editor.unicodeHighlight.allowedLocales": {
"zh-hans": true,
"zh-hant": true
},
"editor.formatOnSave": false,
},
"latex-workshop.showContextMenu": true,
"latex-workshop.view.pdf.internal.synctex.keybinding": "double-click",
"latex-workshop.latex.autoBuild.cleanAndRetry.enabled": false,
"latex-workshop.latex.recipe.default": "lastUsed",
"latex-workshop.latex.clean.args": [
"-outdir=%OUTDIR%",
"-c",
"%TEX%",
"-auxdir=%DIR%/.aux"
],
"latex-workshop.message.error.show": false,
"latex-workshop.message.warning.show": false,
"latex-workshop.latex.build.rootfileInStatus": true,
"latex-workshop.latex.build.clearLog.everyRecipeStep.enabled": false,
"latex-workshop.bibtex-fields.sort.enabled": true,
"latex-workshop.bibtex-fields.order": [
"author",
"title",
"journal",
"year"
],
"latex-workshop.formatting.latex": "latexindent",

这里有几个是值得注意的:

  • latex-workshop.latex.recipe.default:使用上一次的recipe,插件默认会使用第一个recipe;
  • latex-workshop.latex.clean.args:如果使用.aux/辅助目录,这里也需要加上参数,否则插件无法进行清理。

智能补全

对于LaTeX来说,智能补全还是非常有必要的,LaTeX workshop插件在这方面提供了很多支持,可以查看对应的官方文档

首先,对于一些最常见的公式环境,可以使用BXY(或BSXY代表加星号版本,不区分大小写)的prefix来自动补全完整的环境,这里的XY取自公式环境名称的缩写,如下表:

prefix name
BEQ, BSEQ equation, equation*
BAL, BSAL align, align*
BGA, BSGA gather, gather*

除了公式,常见的列表环境和浮动体环境也是支持的:

prefix name
BIT itemize
BEN enumerate

对于数学公式中的常用字体也有支持(可以选中需要改变字体的片段后再输入),如下表

prefix command
MRM \mathrm{${1}}
MSF \mathsf{${1}}
MBF \mathbf{${1}}
MBB \mathbb{${1}}
MCA \mathcal{${1}}
MIT \mathit{${1}}
MTT \mathtt{${1}}

插件还对一些常见的数学元素进行了自动替换,例如

prefix command
__ _{$1}
** ^{$1}
... \dots

对于很多的数学符号,插件还提供了@X方式的快捷输入方式,其中X与数学符号的对应关系很有意思,例如

prefix command
@%,@/ \frac{}{}
@2 \sqrt{}
@6 \partial
@8 \infty
@( \left( \right)
@[ \left[ \right]
@{ \left\{ \right\}
@\| \left\| \right\|
@a \alpha
@b \beta
@d \delta
@D \Delta
@ve \varepsilon
@vf \varphi
@vq \vartheta

这些智能补全只会在编辑LaTeX文档时触发,对于其它文档的编辑不会造成干扰。

补充

当前LaTeX项目使用的.gitignore如下

1
2
3
4
5
6
.aux/

*.pdf
*.synctex.gz
*.synctex.gz.sum.synctex
indent.log

含义为忽略.aux/文件夹、PDF文件以及相关的辅助文件。注意如果需要插入PDF格式的图片,这里还需要加上其它规则,例如

1
!figure/*.pdf