给出 MWE 以及 log 文件。
是否正确安装了 mtpro2 字体库?
给出 MWE 以及 log 文件。
是否正确安装了 mtpro2 字体库?
\part
的结构为:
\clearpage (\cleardoublepage)
...
\thispagestyle{<pagestyle>}
...
\newpage
...
由于使用了 \clearpage
和 \newpage
,使用 \thispagestyle
无法修改 part 页的 pagestyle。\chapter
则没有尾部的 \newpage
,thispagestyle` 可以生效。
如果使用 titlesec
宏包,它提供了 \assignpagestyle
来修改页面样式。如:
\assignpagestyle{\part}{empty}
\assignpagestyle{\chapter}{empty}
将修改 \part
和 \chapter
的 pagestyle 为 empty。此命令应在 \titleformat{<command>}...
后使用。它可以在任意位置使用,将影响其后的 pagestyle。
当使用 ctex 文档类时,可使用 \ctexset{part/pagestyle=..., chapter/pagestyle=...}
直接设置 pagestyle。但当加载 titlesec
后无效。
对于本例,若要全局修改,只需在导言区使用:
%\usepackage{titlesec}
\titleformat{\part}[display]{\Huge\bf}{第\thepart 部分}{1em}{}
\assignpagestyle{\part}{empty}
若只修改个别,则
\assignpagestyle{\part}{empty}
\part{...}
\assignpagestyle{\part}{plain} % 改回来,默认为 plain
tcolorbox
的每个块默认是单独放在一个 minipage 中的,如果要实现这样的需求,必须使用 \footnotemark
和 \footnotetext
单独设置。
...[title={title\footnotemark}]...
\footnotetext{foot1}
但这样的话标题中的脚注标记与 upper 部分中的标记不同,为此,可以使用 nccfoots
宏包提供的\Footnotemark
和 \Footnotetext
来设置脚注标记符号。
\documentclass[11pt,twocolumn]{ctexart}
\usepackage{tcolorbox}
\usepackage{nccfoots}
\begin{document}
\begin{tcolorbox}[%colbacktitle=black!10!white,
title=title\Footnotemark{a}]
\footnotetext[1]{foot1}
content\footnote[2]{foot2}
\end{tcolorbox}
\end{document}
使用 caption
宏包提供的 \captionof
命令,可在非浮动体中生成相应的 caption。
\documentclass{article}
\usepackage{caption}
\usepackage{tcolorbox}
\usepackage{hyperref}
\begin{document}
\begin{tcolorbox}
\begin{center}
\includegraphics[width=3cm]{example-image-golden}
\captionof{figure}{test}\label{fig:1}
\end{center}
\end{tcolorbox}
\ref{fig:1}
\end{document}
tl、str、clist、seq、prop 等类型都有对应的 map 函数,
\..._map_function:NN <data> <func>
\..._map_tokens:Nn <data> <tokens>
\..._map_inline:Nn <data> <code>
它们将 <func>
、<tokens>
作用于 <data>
的每一项,也即,在 <data>
的每一项前添加 <func>
、<tokens>
,变成:
<func> <item1> <func> <item2> <func> <item3> ...
<tokens> <item1> <tokens> <item2> <tokens> <item3> ...
对于 \..._map_inline:Nn
则是先将一个 <temp func>
定义为 <code>
,它可使用一个参数,代表当前的 item
。再对 <temp func>
使用 \..._map_function:NN
。
你这个可以用 \tl_map_inline:nn
,或者 \clist_map_inline:nn
,前者速度更快:
\tl_map_inline:nn { ABCD }
{
\exp_args:Nc \NewDocumentCommand { xxColor #1 } { }
{
\bool_lazy_and:nnTF
{ \bool_not_p:n \l_choice_隐藏答案_bool }
{ \use:c { l_choice_ #1 _bool } }
{ { \color{red} \bfseries #1 . } }
{ #1 . }
}
}
\documentclass{ctexart}
\usepackage{zhlipsum}
\usepackage{niceframe}
\usepackage{dingbat}
\usepackage{bbding}
\usepackage{tikz}
\usepackage[margin=2cm]{geometry}
\makeatletter
\newlength\this@pgf@bop@width
\newlength\this@pgf@bop@height
\def\this@pgf@bop@color{black}
\def\this@pgf@bop@opacity{1}
\def\this@pgf@bop@xscale{1}
\def\this@pgf@bop@yscale{1}
\ExplSyntaxOn
\cs_new_protected:Npn \this@pgf@bop@setscale #1
{
\box_scale:cnn { this@pgf@box@pattern #1 }
{ \this@pgf@bop@xscale } { \this@pgf@bop@yscale }
\tl_set:cx { this@pgf@bop@#1@width } { \box_wd:c { this@pgf@box@pattern#1 } }
\tl_set:cx { this@pgf@bop@#1@height } { \box_ht_plus_dp:c { this@pgf@box@pattern#1 } }
}
\ExplSyntaxOff
\def\setboxaspattern#1#2{\expandafter\newbox\csname this@pgf@box@pattern#1\endcsname
\expandafter\setbox\csname this@pgf@box@pattern#1\endcsname\hbox{#2}%
\expandafter\edef\csname this@pgf@bop@#1@width\endcsname{\the\wd\csname this@pgf@box@pattern#1\endcsname}%
\expandafter\edef\csname this@pgf@bop@#1@height\endcsname{\the\dimexpr\ht\csname this@pgf@box@pattern#1\endcsname+\dp\csname this@pgf@box@pattern#1\endcsname}%
}
\tikzset{
box pattern xscale/.code={\def\this@pgf@bop@xscale{#1}},
box pattern yscale/.code={\def\this@pgf@bop@yscale{#1}},
box pattern scale/.code={\def\this@pgf@bop@xscale{#1}\def\this@pgf@bop@yscale{#1}},
box pattern color/.code={\def\this@pgf@bop@color{#1}},
box pattern opacity/.code={\def\this@pgf@bop@opacity{#1}},
box as pattern/.code 2 args={%
\this@pgf@bop@setscale{#2}%
\expandafter\this@pgf@bop@width\csname this@pgf@bop@#2@width\endcsname
\expandafter\this@pgf@bop@height\csname this@pgf@bop@#2@height\endcsname
\pgfkeysalso{/tikz/path picture={%
\pgf@process{\pgfpointanchor{path picture bounding box}{north east}}%
\pgf@xa\pgf@x \pgf@ya\pgf@y
\pgf@process{\pgfpointanchor{path picture bounding box}{south west}}%
\pgf@xb\pgf@x \pgf@yb\pgf@y \pgf@yc\pgf@yb
\pgfutil@loop
{%
\pgfutil@loop
\expandafter\pgftext\expandafter[#1,at=\pgfqpoint{\pgf@xb}{\pgf@yb}]{%
\pgfsetfillcolor{\this@pgf@bop@color}%
\pgfsetfillopacity{\this@pgf@bop@opacity}%
\copy\csname this@pgf@box@pattern#2\endcsname}%
\ifdim\pgf@yb<\pgf@ya
\advance\pgf@yb\this@pgf@bop@height
\pgfutil@repeat
}%
\ifdim\pgf@xb<\pgf@xa
\advance\pgf@xb\this@pgf@bop@width
\pgf@yb\pgf@yc
\pgfutil@repeat
}}%
}
}
\makeatother
\setboxaspattern{hua}{\FourClowerOpen}
\usepackage[many]{tcolorbox}
\usetikzlibrary{decorations,decorations.markings}
\begin{document}
\font\border=karta15
\generalframe
{\border\char'307}{\border\char'324}{\border\char'322}
{\border\char'310} {\border\char'323}
{\border\char'174}{\border\char'325}{\border\char'175}
{\noindent\tikz\node[box pattern opacity=0.4, box as pattern={}{hua}]
{\parbox{\dimexpr\textwidth-40pt-4\fboxsep}{\parindent=2\ccwd \zhlipsum[1][name=zhufu]}};}
{\setlength\fboxsep{0pt}
\generalframe
{\border\char'307}{\border\char'324}{\border\char'322}
{\border\char'310} {\border\char'323}
{\border\char'174}{\border\char'325}{\border\char'175}
{\parindent=0pt
\begin{tcolorbox}[width=\textwidth-3.28em-4\fboxsep,left=2mm,right=2mm,enhanced,nobeforeafter,
frame empty,
interior code={\path[draw=white,fill=white,box pattern opacity=0.3, box as pattern={}{hua}]
(interior.south west) rectangle (interior.north east);},
]
\parindent=2\ccwd
\zhlipsum[1][name=zhufu]
\end{tcolorbox}}}
\makeatletter
\tcbset{arrow frame decoration/.style={
frame empty,
before skip=1em plus 5pt, after skip=1em plus 5pt,
overlay={%
\draw[decorate,decoration={
markings, mark=between positions 0.07 and 0.97 step 1.2em with
{\pgftext{\border\char'325}}}](frame.north west)--(frame.south west);
\draw[decorate,decoration={
markings, mark=between positions 0.07 and 0.97 step 1.2em with
{\pgftext{\border\char'324}}}](frame.north east)--(frame.south east);
\draw[decorate,decoration={
markings, mark=between positions 0.03 and 0.97 step {\dimexpr\kvtcb@width/(\numexpr\linewidth/\dimexpr1.5em\relax)} with
{\pgftext{\border\char'324}}}](frame.north west)--(frame.north east);
\draw[decorate,decoration={
markings, mark=between positions 0.03 and 0.97 step {\dimexpr\kvtcb@width/(\numexpr\linewidth/\dimexpr1.5em\relax)} with
{\pgftext{\border\char'325}}}](frame.south west)--(frame.south east);
\path node at([yshift=-.2ex]frame.south west) {\border\char'174}
node at([yshift=-.2ex]frame.south east) {\border\char'175}
node at([yshift=-.2ex]frame.north west) {\border\char'307}
node at([yshift=-.2ex]frame.north east) {\border\char'322};
},
},}
\makeatother
\newtcolorbox{arrowframe}[2][]{left=2mm,right=2mm,enhanced,arrow frame decoration,
interior code={\path[draw=white,fill=white,
box pattern opacity=.5,box pattern color=red,box pattern scale=1.5,
box as pattern={}{#2}]
([xshift=1ex,yshift=1ex]interior.south west) rectangle
([xshift=-1ex,yshift=-1ex]interior.north east);},#1}
\begin{arrowframe}{hua}
\parindent=2\ccwd
\zhlipsum[1]
\end{arrowframe}
\end{document}
你可以用 nicematrix
,它能够使用 tikz 绘制复杂表格(不能跨页)。
\documentclass{ctexart}
\usepackage{xcolor}
\usepackage{tikz}
\usepackage{nicematrix}
\usetikzlibrary{intersections,patterns,decorations.pathmorphing}
\begin{document}
\begin{NiceTabular}{>{\centering}p{2cm}p{2cm}p{2cm}c}[hvlines,
create-large-nodes,left-margin,right-margin]
\Block{2-3}{~} & & & 什么?\\
~ &~ &~ & \Block{1-1}{wh\\at?} \\
1 & 2 & 3 & 4
\CodeAfter
\begin{tikzpicture}
\draw[pattern=north west lines] ([xshift=-1em,yshift=1em]3-4-large.north west) rectangle ([xshift=1pt,yshift=-.5pt]3-4-large.south east);
\path[fill=red!30] ([xshift=1em-1pt]1-1-large.north west) arc (0:-90:1em) --([xshift=-1pt]1-1-large.north west) --cycle;
\draw (1-1-large.north west)-- node[midway,below left=-2pt]{看看} (2-2-large.south west);
\draw[decorate,decoration={snake}] (1-1-large.north west)-- node[pos=0.6,below left=-2.5pt]{第二} (2-3-large.south west);
\draw (1-1-large.north west)-- node[near end,below left]{上下} (1-4-large.south west);
\path[name path=a] (1-1-large.north west)--(2-4-large.south west);
\draw[name path=b] (3-3-large.north west)--(1-4-large.south west);
\draw[name intersections={of=a and b, name=itr}] (itr-1)-- node[pos=.4,above right=-2pt]{what} (3-4-large.north west);
\draw[dashed] (1-1-large.north west)--(itr-1);
\draw (itr-1)--(3-1-large.north west);
\end{tikzpicture}
\end{NiceTabular}
\end{document}
tabularray 并不自动展开表格内容,因此,\multicolumn
并未生效。理论上,只要展开 \notableentry
即可,但 \vadjust
不可用。
解决方法建议问宏包作者:issue、discussion。
\chinese{section}
或 \chinese {section}
,不是 \chinese { section }
。
套一个 \tikz\node[]{\parbox{}{...}};
。或者用 tcolorbox,可以设置 frame code 和 interior code。
\documentclass{ctexart}
\usepackage{zhlipsum}
\usepackage{niceframe}
\usepackage{dingbat}
\usepackage{bbding}
\usepackage{tikz}
\makeatletter
\newlength\this@pgf@bop@width
\newlength\this@pgf@bop@height
\def\this@pgf@bop@opacity{1}
\def\setboxaspattern#1#2{\expandafter\newbox\csname this@pgf@box@pattern#1\endcsname
\expandafter\setbox\csname this@pgf@box@pattern#1\endcsname\hbox{#2}%
\expandafter\edef\csname this@pgf@bop@#1@width\endcsname{\the\wd\csname this@pgf@box@pattern#1\endcsname}%
\expandafter\edef\csname this@pgf@bop@#1@height\endcsname{\the\ht\csname this@pgf@box@pattern#1\endcsname}%
}
\tikzset{
box pattern opacity/.code={\def\this@pgf@bop@opacity{#1}},
box as pattern/.code 2 args={%
\expandafter\this@pgf@bop@width\csname this@pgf@bop@#2@width\endcsname
\expandafter\this@pgf@bop@height\csname this@pgf@bop@#2@height\endcsname
\pgfkeysalso{/tikz/path picture={%
\pgfsetfillopacity{\this@pgf@bop@opacity}%
\pgf@process{\pgfpointanchor{path picture bounding box}{north east}}%
\pgf@xa\pgf@x \pgf@ya\pgf@y
\pgf@process{\pgfpointanchor{path picture bounding box}{south west}}%
\pgf@xb\pgf@x \pgf@yb\pgf@y \pgf@yc\pgf@yb
\pgfutil@loop
{%
\pgfutil@loop
\expandafter\pgftext\expandafter[#1,at=\pgfqpoint{\pgf@xb}{\pgf@yb}]{\copy\csname this@pgf@box@pattern#2\endcsname}%
\ifdim\pgf@yb<\pgf@ya
\advance\pgf@yb\this@pgf@bop@height
\pgfutil@repeat
}%
\ifdim\pgf@xb<\pgf@xa
\advance\pgf@xb\this@pgf@bop@width
\pgf@yb\pgf@yc
\pgfutil@repeat
}}%
}
}
\makeatother
\setboxaspattern{hua}{\FourClowerOpen}
\usepackage[many]{tcolorbox}
\begin{document}
\font\border=karta15
\generalframe
{\border\char'307}{\border\char'324}{\border\char'322}
{\border\char'310} {\border\char'323}
{\border\char'174}{\border\char'325}{\border\char'175}
{\noindent\tikz\node[box pattern opacity=0.4, box as pattern={}{hua}]
{\parbox{\dimexpr\textwidth-40pt-4\fboxsep}{\parindent=2\ccwd \zhlipsum[1]}};}
{\setlength\fboxsep{0pt}
\generalframe
{\border\char'307}{\border\char'324}{\border\char'322}
{\border\char'310} {\border\char'323}
{\border\char'174}{\border\char'325}{\border\char'175}
{\parindent=0pt
\begin{tcolorbox}[width=\textwidth-3.28em-4\fboxsep,left=2mm,right=2mm,enhanced,
frame empty,nobeforeafter,
interior code={\path[draw=white,fill=white,box pattern opacity=0.3, box as pattern={}{hua}]
(interior.south west) rectangle (interior.north east);},
]
\parindent=2\ccwd
\zhlipsum[1]
\end{tcolorbox}}}
\end{document}
你的这种写法确实会带来一点性能提升。这是由于 TeX 进行了更少的展开和内部操作。哪怕是在 \else
、\expandafter
前增加一个 \relax
都会增加编译时间。
\documentclass{article}
\begin{document}
\long\def\loop#1\repeat{\def\iterate{#1\relax\expandafter\iterate\fi}\iterate \let\iterate\relax}
\long\def\xunhuan#1\repeat{\def\iterate{#1\else\let\iterate\relax \fi\iterate}\iterate}
%\long\def\xunhuan#1\repeat{\def\iterate{#1\relax\else\let\iterate\relax \fi\iterate}\iterate \let\iterate\relax}
\count5656=0
\count5657=300000000
%\xunhuan \advance\count5656by1 \ifnum \count5656<\count5657 \relax \repeat
%\the\count5656
\count5656=0
\loop \advance\count5656by1 \ifnum \count5656<\count5657 \relax \repeat
\the\count5656
\end{document}
(谨慎运行!)
这种最简单的循环,在我的电脑上,使用 \loop
大概 61.7s,使用 \xunhuan
大概 57.4s,\loop
大致慢了 6%-8% 左右,但是当需要大量的计算时,用在 \loop
中的时间几乎可以忽略不计,实际区别很小。
但是你的代码与原来的 loop 并不是完全等价的,这里暂时先不说。
只要循环中不保存内容(不修改内部的 hash 表)、不留下 typeset material、不输出信息(log 等),仅包含(有效的)单纯的计算(比如 \advance
),(可能所列并不完整,)TeX 不会在循环中消耗一丁点内存,因此理论上这样的“循环”的循环次数是无限的。这与其它编程语言是不同的。
诸如 C 之类的语言,在函数执行时会为其开辟新的内存空间,因此如果在循环时内存不回收,则可能会溢出,
然而在递归时,想要回收这些内存是很难的。
但是 TeX 不一样,TeX 在执行时,只是展开这些宏,
\loop \advance\count5656by1 \ifnum \count5656<\count5657 \repeat
展开,变成了
\def\iterate{\advance\count5656by1 \ifnum \count5656<\count5657
\relax\expandafter\iterate\fi}\iterate
\let \iterate \relax
定义 \iterate
,再展开 \iterate
,此时 \let\iterate\relax
还未执行:
\advance\count5656by1 \ifnum \count5656<\count5657 \relax\expandafter\iterate\fi
\let\iterate\relax
count 寄存器 5656 加 1,即使是 \ifnum
也是执行展开,假设判断为真,则要么向后找到一个 \else
(并不必须是 \else,任何一个被 \let
为 primitive \else
的都可以,要么向后找到一个 \fi
(同样不必是 \fi),这一点必须要注意,与 \def
中的参数定界符不同。
这里没有发现 \else
,TeX 先展开 \fi
,然后将 \iterate
放在即将执行的输出流中。继续递归。
如果判断为假,TeX 不展开 \relax\expandafter\iterate\fi
,而是直接找 \else
或 \fi
(不必是 \else、\fi)。而此时 \relax\expandafter\iterate\fi
四者完全可能是 \else
、\fi
二者之一。如果 \relax\expandafter\iterate
均不是 \else\fi
二者之一,且 \fi
是 primitive \fi
,那么 TeX 正确的结束此次循环,并
\let\iterate\relax
否则,在预想情况下,应该出错(报错)。因为重定义 \iterate
是不被允许的。
可以看到,在此循环中并不涉及内存分配,因此并不会出现爆栈或 overflow。
而若包含 typeset material 等内容,当一个段落的内容过多,或待输出的 typeset material 过多,或在循环过程中在 hash 表中增加了巨量的内容,则会出现内存用光的情况。这是这两种循环都会出现的。
考虑如下代码:
\documentclass{article}
\begin{document}
\long\def\xunhuan#1\repeat{\def\iterate{#1\else\let\iterate\relax \fi\iterate}\iterate}
\count5656=0
\count5657=3 %00000000
\loop \advance\count5656by1 \let\iterate\fi \ifnum \count5656>\count5657 \repeat
\end{document}
编译报错了,原因正是如上所说的 TeX 并不需要 \fi
是 \fi,任何被 \let
为 primitive \fi
的都可以。但是换成你的 \xunhuan
则不会报错。
至于哪个更好,可能因人而异。
xpinyin
宏包手册中的拼音使用 TeX Gyre Adventor(texgyreadventor-regular.otf)字体。
\newfontfamily\PinYinFont{TeX Gyre Adventor}
\xpinyinsetup{font=\PinYinFont}
patterns 无法做到这一点。可以使用 /tikz/path picture
。这样可以使用任意内容填充,包括 tikz
绘图命令。
\documentclass{ctexart}
\usepackage{tikz}
\usepackage{bbding}
\makeatletter
\newlength\this@pgf@bop@width
\newlength\this@pgf@bop@height
\def\setboxaspattern#1#2{\expandafter\newbox\csname this@pgf@box@pattern#1\endcsname
\expandafter\setbox\csname this@pgf@box@pattern#1\endcsname\hbox{#2}%
\expandafter\edef\csname this@pgf@bop@#1@width\endcsname{\the\wd\csname this@pgf@box@pattern#1\endcsname}%
\expandafter\edef\csname this@pgf@bop@#1@height\endcsname{\the\ht\csname this@pgf@box@pattern#1\endcsname}%
}
\tikzset{
box as pattern/.code 2 args={%
\expandafter\this@pgf@bop@width\csname this@pgf@bop@#2@width\endcsname
\expandafter\this@pgf@bop@height\csname this@pgf@bop@#2@height\endcsname
\pgfkeysalso{/tikz/path picture={%
\pgf@process{\pgfpointanchor{path picture bounding box}{north east}}%
\pgf@xa\pgf@x \pgf@ya\pgf@y
\pgf@process{\pgfpointanchor{path picture bounding box}{south west}}%
\pgf@xb\pgf@x \pgf@yb\pgf@y \pgf@yc\pgf@yb
\pgfutil@loop
{%
\pgfutil@loop
\expandafter\pgftext\expandafter[#1,at=\pgfqpoint{\pgf@xb}{\pgf@yb}]{\copy\csname this@pgf@box@pattern#2\endcsname}%
\ifdim\pgf@yb<\pgf@ya
\advance\pgf@yb\this@pgf@bop@height
\pgfutil@repeat
}%
\ifdim\pgf@xb<\pgf@xa
\advance\pgf@xb\this@pgf@bop@width
\pgf@yb\pgf@yc
\pgfutil@repeat
}}%
}
}
\makeatother
\setboxaspattern{hua}{\FourClowerOpen}
\setboxaspattern{huarotate}{\rotatebox{22.5}{\FourClowerOpen}}
\setboxaspattern{image}{\includegraphics[width=2cm,height=2cm]{example-image}}
\usetikzlibrary{graphs,graphs.standard}
\setboxaspattern{tikzfancy}{\tikz
\graph [nodes={draw, circle, rotate=25}, clockwise, radius=.5cm,
empty nodes, n=5] {
subgraph I_n [name=inner] --[complete bipartite]
subgraph I_n [name=outer]
};}
\begin{document}
\begin{tikzpicture}
\draw[box as pattern={left,base}{hua}](0,0)rectangle(4,4);
\end{tikzpicture}
\tikz\draw[box as pattern={left,top}{huarotate}](0,0)rectangle(4,4);
\tikz\draw[box as pattern={}{tikzfancy}](0,0)rectangle(10,10);
\tikz\draw[box as pattern={left,bottom}{image}](0,0)rectangle(10,4);
\end{document}
\setboxaspattern
第一个参数是 box pattern 名,第二个参数是内容。box as pattern
的第一个参数是 \pgftext
可用的选项,第二个参数为预先定义的 box pattern 名。
可以做成在使用时声明,但为了一致性(pattern 均是先声明再使用),仍然做成声明和使用分离的。
参考:https://tex.stackexchange.com/questions/103980
实际上,这样使用会重复使用这些盒子,造成一定的浪费。理想情况下,对于这种重复的内容,应该仅存储一个,之后的内容引用这一个即可。但目前只有 pdftex(和 luatex 的 pdf 模式)能做到这一点,xetex 无法做到。
而 xetex 要支持这一点,则要等到 LaTeX 2022-06-01 这一版(也就是目前的 LaTeX-dev)或者使用 pdfmanagement-testphase
。
有两个问题,
\ref
不能被完全展开,因此不能用于 f
、x
、e
等展开类型中,否则会出错,必须使用底层的宏来得到 ref;\printman{ test01 }
,时,一般两侧的空格是不需要的,使用 \NewDocumentCommand { >{\TrimSpaces} m }
在传参时将其去除。改动的地方只有两个:
\makeatletter
% 棋谱输出用户接口
% #1 棋谱label
\NewDocumentCommand{\printman}{ >{\TrimSpaces} m } % 去掉两侧空格
{
\__cchess_setman_print:n { #1 }
}
\cs_set:Npn \use_i:nnnnn #1#2#3#4#5 {#1} % LaTeX3 并未定义 \use_i:nnnnn
% 棋谱输出
\cs_new:Npn \__cchess_setman_print:n #1
{
\cs_if_exist:cTF { r@#1 }
{
% 这一步是得到 ref,它保存在 \r@#1 中。\r@#1 有两项,当使用 hyperref 时,
% \r@#1 有 5 项,这里使用 \empty 统一解决
\tl_set:Nx \l_tmpa_tl
{ #1 \exp_args:NNc \exp_after:wN \use_i:nnnnn { r@ #1 } \c_empty_tl \c_empty_tl \c_empty_tl .man }
\ior_open:NnTF \g_tmpb_ior { \l_tmpa_tl }
{
\ior_str_map_inline:Nn
% \ior_map_inline:Nn
\g_tmpb_ior
{ ##1\par }
}
{ \msg_error:nnx { csv } { file-not-found } { \l_tmpa_tl } }
\iow_close:N \g_tmpa_ior
}
{ \G@refundefinedtrue }% 引用未定义
}
完整代码:
\documentclass{ctexart}
\usepackage{xparse}
%\usepackage{hyperref}
%\usepackage{nameref,cleveref}
\makeatletter
\ExplSyntaxOn
% \label命令变体
\cs_new_protected_nopar:Npn \__cchess_setman_label:n { \label }
\cs_generate_variant:Nn \__cchess_setman_label:n { x }
\cs_set:Npn \use_i:nnnnn #1#2#3#4#5 {#1}
% 是否输出棋谱
\bool_new:N \l__cchess_with_setman_bool
% 棋谱文字说明列表(如车一进二等)
\clist_new:N \l__cchess_manual_clist
% 打谱环境棋谱标签
\tl_new:N \l__cchess_setman_label_tl
\tl_new:N \l__cchess_setman_label_num_tl
% 打谱环境用计数器
\newcounter{setman}
\coffin_new:N \l__cchess_manual_coffin
% key_value选项设计
\keys_define:nn { cchess }
{
% 棋盘背景图片
label .tl_gset:N = \l__cchess_setman_label_tl ,
label .initial:n = {} ,
}
% 打谱排版环境用户接口
\NewDocumentEnvironment{ setcchessman* }{ O{} +b }
{
\group_begin:
\bool_set_true:N \l__cchess_with_setman_bool
\keys_set:nn { cchess } { #1 }
\__cchess_setcchessman_pre_setup:n { #2 }
}{
\__cchess_setcchessman_post_setup:
\group_end:
}
% 棋谱输出用户接口
% #1 棋谱label
\NewDocumentCommand{\printman}{ >{\TrimSpaces} m }
{
\__cchess_setman_print:n { #1 }
}
% 打谱环境前处理函数
% #1 打谱命令
\cs_new:Npn \__cchess_setcchessman_pre_setup:n #1
{
\hcoffin_set:Nn \l__cchess_manual_coffin
{ 这是一个棋盘 }
\clist_put_right:Nn \l__cchess_manual_clist { 车九进一 }
\clist_put_right:Nn \l__cchess_manual_clist { 马3退2 }
}
% 打谱环境后处理函数
\cs_new:Nn \__cchess_setcchessman_post_setup:
{
% 输出结果盒子容器
\coffin_typeset:Nnnnn \l__cchess_manual_coffin
{ l }{ b } { 0pt } { 0pt }
% 星号环境需要输出打谱记录
\bool_if:NT \l__cchess_with_setman_bool
{
% 递增计数器
\refstepcounter{setman}
% 设置label标签
\__cchess_setman_label:x { \l__cchess_setman_label_tl }
% 构造文件名
\iow_open:Nn \g_tmpa_iow { \l__cchess_setman_label_tl\thesetman .man }
% 遍历打谱记录列表,输出打谱记录
\bool_until_do:nn { \clist_if_empty_p:N \l__cchess_manual_clist }
{
\clist_pop:NN \l__cchess_manual_clist \l_tmpa_tl
\iow_now:Nx \g_tmpa_iow { \l_tmpa_tl }
}
\iow_close:N \g_tmpa_iow
}
}
% 棋谱输出
\cs_new:Npn \__cchess_setman_print:n #1
{
% 根据棋谱label构建文件名
% 此处无法构建文件名
\cs_if_exist:cTF { r@#1 }
{
\tl_set:Nx \l_tmpa_tl
{ #1 \exp_args:NNc \exp_after:wN \use_i:nnnnn { r@ #1 } \c_empty_tl \c_empty_tl \c_empty_tl .man }
\ior_open:NnTF \g_tmpb_ior { \l_tmpa_tl }
{
\ior_str_map_inline:Nn
% \ior_map_inline:Nn
\g_tmpb_ior
{ ##1\par }
}
{ \msg_error:nnx { csv } { file-not-found } { \l_tmpa_tl } }
\iow_close:N \g_tmpa_ior
}
{ \G@refundefinedtrue }% 引用未定义
}
% 文件不存在错误提示
\msg_new:nnn { cchess } { file-not-found } { File~`#1'~not~found. }
\ExplSyntaxOff
\begin{document}
天圆地方大战的棋谱如棋谱 \ref{test01} 所示。
\begin{setcchessman*}[label=test01]
% 打谱命令
\end{setcchessman*}
\bigskip
这是一个棋谱
\printman{ test01 }
\bigskip
\bigskip
昏天黑地大战的棋谱如棋谱 \ref{test02} 所示。
\begin{setcchessman*}[label=test02]
% 打谱命令
\end{setcchessman*}
\end{document}
写入临时文件时,可以在文件名前加上 \jobname
(\c_sys_jobname_str
)与其它主文件的辅助文件区分开来。
问 texlive2022不能用mtpro2字体了