xeCJKfntef 基于 ulem 实现,ulem 限制很多,不能随便加组,\zhlipsum 就有:
\NewDocumentCommand \zhlipsum { s o +o }
{
\group_begin:
\IfBooleanF {#1}
...
}保存在宏里的文字一般也无法换行,见 ulem.pdf 第 5 页。
xeCJKfntef 基于 ulem 实现,ulem 限制很多,不能随便加组,\zhlipsum 就有:
\NewDocumentCommand \zhlipsum { s o +o }
{
\group_begin:
\IfBooleanF {#1}
...
}保存在宏里的文字一般也无法换行,见 ulem.pdf 第 5 页。
不是已经实现了吗,没懂哪里有问题,除了 label 单独一行外,也没懂一二种列表有什么区别。
纯 enumitem 的实现,需要用 verb 的地方,在合适的地方用 \scantokens 重新扫描一下就行了(\sitem 的实现方式):
\NewDocumentCommand\sitem{+v}{\item[\scantokens{#1}]}
\newlist{mydesc}{description}{2}
\setlist[mydesc,1]{}
\setlist[mydesc,2]{style=nextline}
\begin{mydesc}
\sitem{\Verb|something|} 劳仑
\sitem{\mintinline{asy}|Rotate(pair z)|} 普桑
\begin{mydesc}
\sitem{wa hh} 劳仑\\ 衣
% \item[wa hh] 也可以用
\sitem=\Verb|\{}|= 普桑
\end{mydesc}
\end{mydesc}label 宽度可以自己改改。
\documentclass[fontset=fandol]{ctexart}
\ctexset{section/format+={\raggedright}}
\parindent=0pt
\begin{document}
\begingroup\ctexset{section/format+=\centering}
\tableofcontents
\endgroup
\section{aaaa}
\section{bbbb}
\section{cccc}
\section*{ddd}
\end{document}一般情况下 \section 等命令不建议放在组中(因为它们可能为了实现某些效果会重定义 \par),但只在目录里这么做还是问题不大的,目录条目一般都会使用自定义的格式,而不像普通段落那样。
listing 环境就是一个浮动体,tcolorbox 自己就有对应的功能,没必要再套一个浮动环境,tcolorbox 也不能用 before 和 after 随便套一个环境。\label 也有对应的选项。
如果只要给代码添加目录,无需使用浮动体。要改目录条目的样式只要重定义 \l@tcolorbox 即可(\renewcommand\l@tcolorbox[2]{\@dottedtocline{1}{1.5em}{2.3em}{#1}{#2}}),见 tcolorbox 文档 5.2 节 /tcb/new/list type 选项的说明。
\documentclass[UTF8]{ctexbook}
%代码排版
\usepackage{tcolorbox}
\tcbuselibrary{minted,breakable,hooks}
\newtcblisting[auto counter,list inside=abMATLABlist]{abMATLAB}[3][]{%
coltitle=black,
colbacktitle=white,
colupper=black,
colback=white,
boxrule=0pt,
toprule=0.08em,
titlerule=0.05em,
bottomrule=0.08em,
fonttitle=\bfseries,
title={\heiti 代码列表 \thetcbcounter: #2},
listing only,
sharp corners=all,
minted language=matlab,
label={#3}, % \label %% <--
float=htbp!, % 浮动环境 %% <--,如果代码不要浮动,删掉这行
#1,
}
\begin{document}
\tableofcontents
\tcblistof[\chapter*]{abMATLABlist}{MATLAB 代码}
%\tcblistof[\section*]{abMATLABlist}{MATLAB 代码}
%\begin{abMATLAB}{拉普拉斯展开计算行列式}{abMATLABlist:DetLaplace}
%\end{abMATLAB}
\chapter{AAA}
\begin{abMATLAB}{拉普拉斯展开计算行列式}{abMATLABlist:DetLaplace}
function d=DetLaplace(A)
% DETLAPLACE 使用 Lapace 展开计算行列式
% d = DetLaplace(A); 计算矩阵 A 的行列式 (determinant)
% 对第一行 (row) 使用 Laplace 展开 (expansion)
n = length(A);
if n==1
d=A(1,1);
else
d=0; v=1;
for j=1:n
M1j = [A(2:n,1:j-1) A(2:n,j+1:n)];
d = d + v*A(1,j)*DetLaplace(M1j);
v = -v;
end
end
\end{abMATLAB}
\end{document}至于 \chapter 前面那个例子可以编译,可能是某个奇怪的 bug,不去管就行了。
\documentclass{article}
\usepackage{ctex,lipsum}
\usepackage[most]{tcolorbox}
\usepackage{geometry}
\geometry{a4paper,left=2.5cm,right=2.5cm,top=2.5cm,bottom=2.5cm}
\makeatletter
\ExplSyntaxOn
\cs_new_protected:Npn \@Line@check@last
{
\int_case:nnTF { \tex_lastnodetype:D }
{
{ 11 } { \tl_put_left:Ne \@Line@save { \vskip\the\lastskip\relax } \unskip }
{ 12 } { \tl_put_left:Ne \@Line@save { \kern\the\lastkern\relax } \unkern }
{ 13 } { \tl_put_left:Ne \@Line@save { \penalty\the\lastpenalty\relax } \unpenalty }
}
{ \@Line@check@last }
{ \tl_set:Ne \@Line@last@type { \int_value:w \tex_lastnodetype:D } }
}
\cs_new:Npn \@Line@is@print@number
{
\int_case:nnTF { \@Line@last@type }
{
{ -1 } {}
{ 0 } {}
{ 1 } {}
{ 9 } {}
}
{ 1~ } { 0~ }
}
\ExplSyntaxOff
\newsavebox\linebox
\newcommand{\@Line@Number}{%
\def\@line@no{0}
\def\@Line@save{\nointerlineskip}%
\def\@Line@last@type{-1}%
\setbox\linebox\lastbox%
\ifvoid\linebox%如果行文字盒子为空则什么都不执行
\relax%
\else%
\@Line@check@last
{\@Line@Number}%
\@Line@save
\ifcase\@Line@is@print@number\else
\xdef\@line@no{\number\numexpr\@line@no+1\relax}%
\ifnum\numexpr(\@line@no/5)*5=\@line@no\relax%判断行号能否被5整除
\noindent\llap{\mbox{\@line@no\hskip7.5mm\relax}}%
\else%
\ifnum\@line@no=1%判断行号是否等于1
\noindent\llap{\mbox{\@line@no\hskip7.5mm\relax}}%
\fi\fi\fi
\box\linebox\par
\fi}
\makeatother
\begin{document}
\makeatletter
\noindent 不含行间公式
\begin{tcolorbox}[breakable]
\lipsum
\par\@Line@Number
\end{tcolorbox}
\clearpage
\noindent 含行间公式
\begin{tcolorbox}[breakable]
\lipsum[1]
\begin{align}% 不能用 equation 和 $$
\int_\Omega x^2{\rm d}V=\frac{1}{5}
\end{align}
\lipsum[2-8]
\par\@Line@Number
\end{tcolorbox}
\makeatother
\end{document}\pgfmathsetseed{42}默认就是不打印显式空格,不过某些字体下,LaTeX 会把字符码为 32,类别码为 12 的字符显示为非空白。
新版本里,我修改了实现,可以更新一下(只需更新 texhigh.sty 这个文件)。但是这个问题始终是和字体有关的。
提到的 texhigh 已经设置 \THSetCharReplacement{\ }{\textvisiablespace} 就是字面意思,这是设置字符要被替换为哪些代码,它只设置而不启用,要靠 char-replacements 键来启用。
texhigh 还额外设置了 \raggedright,所以一般是靠左而不是默认分散的,可以设置 font=\ttfamily 移除这个,也可使用 ragged2e 宏包的 \justifying:font+=\justifying。
其它问题可以参考 Sagittarius Rover 的回答。
texhigh 是高亮 TeX 代码的宏包,也可以用来输出颜文字等(实验性质的)。
需要首先安装 texhigh 命令行工具到指定位置:
执行 kpsewhich --var-value SELFAUTOLOC,得到一个路径,然后在 https://github.com/Sophanatprime/texhigh-rs/releases 下载以 texhigh-x86... 开头的对应操作系统的压缩文件(比如 Windows 是 texhigh-x86_64-pc-windows-msvc.zip),将其解压缩后复制到刚才得到的路径中(比如把 texhigh.exe 复制到 D:/texlive/2025/bin/windows)。然后执行 texhigh -V 可以得到版本信息(比如 texhigh 0.4.0),否则就是安装出错了。
然后执行 kpsewhich --var-value TEXMFLOCAL 得到一个路径,再将 https://github.com/Sophanatprime/texhigh 仓库里的 texhigh.sty 和 texhigh.prelude.ths 复制到这个路径中:$TEXMFLOCAL/tex/latex/texhigh($TEXMFLOCAL 就是刚才执行 kpsewhich --var-value TEXMFLOCAL 得到的路径,如何没有对应的路径可以直接创建,比如创建 D:/texlive/texmf-local/tex/latex/texhigh,把这两个文件复制到这个路径即可)。然后再执行 texhash 刷新缓存即可。
总之,安装就是复制文件到指定的路径中,比较简单,不过需要确保命令行工具的版本和宏包版本一致,一般情况下,只要仓库不是刚刚更新,同一时间下载到的版本都是一致的。
然后就和使用其它宏包,比如 minted 是一样的了。
\documentclass{article}
\usepackage[tikz]{texhigh}
\begin{document}
\texhighverb|\hello, \LaTeX|.
\texhighverb[use-ctab=latex3]|\latex_hello:|.
\texhighverb[style=tikz.gradient]|\relax|.
\end{document}执行 xelatex --shell-escape main.tex(其它引擎也可以,--shell-escape 是必要的)。
更详细的用法可以参考文档和例子以及我写的一个显示TikZ图形和代码的例子。
\documentclass{article}
\usepackage{showframe}
\newenvironment{abc}{\par}{\par}
\newcommand\NoindentNextPara{\AddToHookNext{para/begin}{\OmitIndent}}
\begin{document}
text1\par
text2\NoindentNextPara
\begin{abc}
abc
\end{abc}
text4\par
text5
\end{document}
https://bithesis.bitnp.net/faq/biber-perl-cache.html

LaTeX Workshop 可以设置环境变量。修改用户设置,biber 命令的环境变量改为:
"latex-workshop.latex.tools": [
{
"name": "biber",
"command": "biber",
"env": {
"TEMP": "%WORKSPACE_FOLDER%",
},
"args": [
"%DOCFILE%"
]
},
....
]最简单的办法是加上这行
\pgfkeys{...
/mycmd/.search also={/tikz}, % <- 自动找 /tikz/...
}\documentclass{article}
\usepackage{tikz}
\pgfkeys{%
/mycmd/.is family,
/mycmd/.cd,
/mycmd/.search also={/tikz},
default/.style={color=black},
color/.store in = \mycmdcolor,
}
\pgfkeys{%
/tikz/mycmd/.code args={#1}{%
\pgfkeys{/mycmd, default, #1}
\pgfkeysalso{color=\mycmdcolor,}
}
}
\newcommand{\mydraw}[1][]{%
\draw[mycmd={#1}] (0,0) -- (4,0); }
\begin{document}
\begin{tikzpicture}
\mydraw[color=blue, line width=1mm]
\end{tikzpicture}
\end{document}\documentclass[tikz,border=5pt]{standalone}
\usepackage{tkz-euclide}
\ExplSyntaxOn\makeatletter
\pgfmathdeclarefunction{pointveclen}{3}{
\begingroup
\tikz@scan@one@point\pgfutil@firstofone(#1)\relax
\pgf@xx\pgf@x \pgf@xy\pgf@y
\tikz@scan@one@point\pgfutil@firstofone(#2)\relax
\pgf@yx\pgf@x \pgf@yy\pgf@y
\pgfmathparse{veclen(\the\pgf@xx+#3\the\pgf@yx,\the\pgf@xy+#3\the\pgf@yy)}
\pgfmath@smuggleone\pgfmathresult
\endgroup
}
\NewDocumentCommand\tkzAutoLabelPolygons{O{} r()} {
\group_begin:
\seq_gclear:N \g_tmpa_seq
\foreach \x in {#2} { \seq_gput_right:Ne \g_tmpa_seq { \x } }
\seq_get_left:NN \g_tmpa_seq \l_tmpa_tl
\seq_get_right:NN \g_tmpa_seq \l_tmpb_tl
\seq_gput_left:NV \g_tmpa_seq \l_tmpb_tl
\seq_gput_right:NV \g_tmpa_seq \l_tmpa_tl
\int_step_inline:nnn { 2 } { \seq_count:N \g_tmpa_seq - 1 }
{
\seq_gpop_left:NN \g_tmpa_seq \l_tmpa_tl
\tl_set:Ne \l_tmpb_tl { \seq_item:Nn \g_tmpa_seq { 1 } }
\tl_set:Ne \l_tmpc_tl { \seq_item:Nn \g_tmpa_seq { 2 } }
\pgfinterruptboundingbox
\coordinate (tempa) at ($1cm/pointveclen("\l_tmpa_tl","\l_tmpb_tl","-")
*($(\l_tmpa_tl)-(\l_tmpb_tl)$)$);
\coordinate (tempb) at ($1cm/pointveclen("\l_tmpc_tl","\l_tmpb_tl","-")
*($(\l_tmpc_tl)-(\l_tmpb_tl)$)$);
\coordinate (tempc) at ($0.3*1cm/pointveclen("tempa","tempb","+")
*($(tempa)+(tempb)$)$);
\endpgfinterruptboundingbox
\path (\l_tmpb_tl) -- ($(\l_tmpb_tl)-(tempc)$)
node[label~style,anchor=center,#1] {$\l_tmpb_tl$};
}
\group_end:
}
\ExplSyntaxOff\makeatother
\begin{document}
\begin{tikzpicture}
\tkzDefPoints{-1/-1/A, 1/-2/B, 3/0/C, 2/4/D, 0/5/E,-3/2/F}
\tkzDrawPolygons[thick](A,...,F)
\tkzAutoLabelPolygons(A,...,F)
\end{tikzpicture}
\begin{tikzpicture}
\tkzDefPoints{-1/-1/A, 1/-2/B, 0.5/0/C, 2/4/D, 0/5/E,-3/2/F}
\tkzDrawPolygons[thick](A,...,F)
\tkzAutoLabelPolygons(A,...,F)
\end{tikzpicture}
\end{document}
见 The TeXBook 第 258 页(2021 年版),The LaTeX Companion 第三版 5.3.4、5.3.5 节。
TeX 遇到某些内容和输出这些内容所在的页码并不一定相同,比如,TeX 在准备第 5 页所需的内容时遇到太多文字,直到第 5 页输出完成后才能知道哪些文字是多余的,然而它们是在第 5 页中发现的,却并不是在第 5 页输出的,这就存在某些问题,比如假如这些多出来的文字中获取了 page 计数器的值,由于它在第 5 页中执行,得到的结果是 5,而不是 6。TeX 为了解决这个问题提供了几个方案,一个是把要获取的这些值延迟到页面输出完成之后再获取,另一个就是 mark 机制。
firstmark 就是输出的那一页最开始遇到的 mark,botmark 就是最后遇到的 mark,topmark 就是上一页的 botmark。最开始的 TeX 只有一个 mark 类,e-TeX 扩展为了 32767 个。
如果你用 LaTeX 2022-06-01 及之后的版本,那么 LaTeX 提供了 \FirstMark \LastMark \TopMark,并且不但能获得当前页的,还能获得上一页、当前栏、上一栏的。建议使用这些命令。如果用的是 2025-06-01 的版本,还能获得 multicols 每一栏的 marks。
不过,如果 marks 出现在其它盒子中,那么 TeX 无法正确更新,可以用我写的 updatemarks 宏包。
\changetext 的修改是局部的,而 shipout 钩子总是放在一个组中执行,必须要全局修改。
\AddToHookNext{shipout}{\global\advance\textheight2cm\relax}不过,如果修改 \textheight 正好发生在 paracol 环境中间,是无效的,原因未知。
设置 TEXINPUTS 环境变量,.tex .sty 这类文件都在 $TEXMF/tex// 目录里查找,而 TeX 文档的位置在 $TEXDOCS ($TEXMF/doc//) 这个变量里(texmf.cnf 的变量,不是环境变量)。
cmd:
set TEXINPUTS=;$TEXDOCS
powershell:
$env:TEXINPUTS=';$TEXDOCS'不过最好不要设置 $TEXDOCS 来编译文档,因为这里的目录包含许多配置文件(比如 hyperref.cfg,你设置上面的环境变量再用 xelatex 编译就会发现报错),会出现什么完全不能预测。
可以先修改 TEXINPUTS 然后用 kpsewhich 找到所需的文件,只用特定目录一般问题不大:
set TEXINPUTS=;$TEXDOCS
kpsewhich lshort-zh-cn-style.sty
% 注意要先清除
set TEXINPUTS=
set TEXINPUTS=;$TEXMFDIST/doc/latex/lshort-chinese//
xelatex main.tex可以查看 texdoc kpathsea 文档了解更多内容。
问 无法在 xeCJKfntef 宏包的 \CJKunderanyline* 命令中使用\zhlipsum 以及 \lisum 命令?