雾月
雾月

注册于 2 years ago

回答
88
文章
0
关注者
6

image.png

\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 绘制复杂表格(不能跨页)。

image.png

\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 不可用。

解决方法建议问宏包作者:issuediscussion

\chinese{section}\chinese {section},不是 \chinese { section }

套一个 \tikz\node[]{\parbox{}{...}};。或者用 tcolorbox,可以设置 frame code 和 interior code。

image.png

\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 绘图命令。

image.png

\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

有两个问题,

  1. \ref 不能被完全展开,因此不能用于 fxe 等展开类型中,否则会出错,必须使用底层的宏来得到 ref;
  2. 使用 \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)与其它主文件的辅助文件区分开来。

使用 ctex 宏包或其文档类以后,不要再使用 titlesec 宏包,直接使用 heading 选项或者 ctexheading 宏包。ctexheading 宏包基本有与 titlesec 宏包等价的设置方式,并且接口更加友好。

  1. \addcontentsline 前需使用 \phantomsection 以正确设置超链接位置。
  2. 使用 heading 选项后,可以直接设置 \ctex{.../numbering=false} 不对标题编号,但仍输出至目录,并正确设置超链接和书签。
\documentclass[12pt,a4paper]{article}
\usepackage[UTF8,heading]{ctex}
\usepackage{geometry}
\geometry{a4paper,left=3.18cm,right=3.18cm,top=2.54cm,bottom=2.54cm}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage[numbers,sort&compress]{natbib}
\usepackage{tabularx}
\usepackage{hyperref}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{setspace}
\ctexset{section/format=\centering\fontsize{16pt}{19.2pt}\bfseries,section/aftername=\quad}
%\usepackage{titlesec}
%\titleformat{\section}{\centering\fontsize{16pt}{19.2pt} \bfseries}{\thesection}{1em}{}
\numberwithin{equation}{section}
\linespread{1.5}



\begin{document}

    \newpage
    \tableofcontents
    \newpage

    \section{背景介绍与研究现状}
    \newpage
    \section{平衡点的线性稳定性}
    \newpage
    \section{数值模拟}\label{sec6}
    \newpage
    \section{总结与讨论}\label{sec7}

    \newpage
    \phantomsection
    \addcontentsline{toc}{section}{参考文献}
    \begin{thebibliography}{99}
    \end{thebibliography}
    
    \clearpage
    %\setcounter{secnumdepth}{0}
    \ctexset{section/numbering=false}
    \section{致谢}
    %\addcontentsline{toc}{section}{致谢}
 谢谢谢谢谢
\end{document}

这可能是 XeLaTeX 下特有的 bug。
使用其它引擎编译即可,需修改代码。这里提供 LuaLaTeX 和 upLaTeX 的方法。另外在 upLaTeX 下需自行修改 jfm,否则标点符号仍然使用全宽标点。
image.png

%%--- LuaLaTeX
%%--- lualatex main.tex
\documentclass[12pt,tate]{ltjarticle}
\usepackage{luatexja-fontspec}
\setmainjfont[TateFeatures = {JFM={zh_CN/{kaiming,vert}}}]{SimSun}
\newjfontface\fangsong[TateFeatures = {JFM={zh_CN/{kaiming,vert}}}]{SimFang}
\linespread{1.3}\selectfont % 适配 ctex 的行间距
\Large\parindent=2\zw % 缩进
%%---

%%--- upLaTeX
%%--- ptex2pdf -u -l main.tex
%\documentclass[12pt]{utarticle}
%\usepackage{ctex}
%%---

\usepackage{lltjp-geometry} % 在 LuaLaTeX 和 upLaTeX 下,直排需使用这个宏包以适配 geometry
\usepackage[a4paper,margin=1in]{geometry}
\usepackage{jiazhu}
\jiazhuset{
format =\fangsong,
beforeskip =0.5em plus 0.2em minus 0.2em,
afterskip =0.5em plus 0.2em minus 0.2em}

\begin{document}
\Large

世祖光武皇帝讳秀,字文叔,\jiazhu{测礼“祖有功而宗有德”,光武中兴,故庙称世祖。谥法:“能绍前业曰光,克定祸乱曰武。”伏侯古今注曰:“秀之字曰茂。伯、仲、叔、季,兄弟之次。长兄伯升,次仲,故字文叔焉。”}南阳蔡阳人,\jiazhu{南阳,郡,今邓州县也。蔡阳,县,故城在今随州枣阳县西南。}高祖九世之孙也,出自景帝生长沙定王发。\jiazhu{长沙,郡,今潭州县也。}发生舂陵节侯买,\jiazhu{舂陵,乡名,本属零陵泠道县,在今永州唐兴县北,元帝时徙南阳,仍号舂陵,故城在今随州枣阳县东。事具宗室四王传。}买生郁林太守外,\jiazhu{郁林,郡,今贵州县。前书曰:“郡守,秦官。秩二千石。景帝更名太守。”}外生钜鹿都尉回,\jiazhu{钜鹿,郡,今邢州县也。前书曰:“都尉,本{郡尉},秦官也。掌佐守,典武职,秩比二千石。景帝更名都尉。”}回生南顿令钦,\jiazhu{南顿,县,属汝南郡,故城在今陈州项城县西。前书曰:“令、长,皆秦官也。万户以上为令,秩千石至六百石;不满万户为长,秩五百石至三百石。”}钦生光武。光武年九岁而孤,养于叔父良。

身长七尺三寸,美须眉,大口,隆准,日角。\jiazhu{隆,高也。许负云:“鼻头为准。”郑玄尚书中候注云:“日角谓庭中骨起,状如日。”}性勤于稼穑,\jiazhu{种曰稼,敛曰穑。}而兄伯升好侠养士,常非笑光武事田业,比之高祖兄仲。\jiazhu{仲,合阳侯喜也,能为产业。见前书。}王莽天凤中,\jiazhu{王莽始建国六年改为天凤。}乃之长安,受尚书,略通大义。\jiazhu{东观记曰:“受尚书于中大夫庐江许子威。资用乏,与同舍生韩子合钱买驴,令从者僦,以给诸公费。”}

莽末,天下连岁灾蝗,寇盗锋起。\jiazhu{言贼锋锐竞起。字或作“蜂”,谕多也。}地皇三年,\jiazhu{天凤六年改为地皇。}南阳荒饥,\jiazhu{《韩诗外传》曰:“一谷不升曰歉,二谷不升曰饥,三谷不升曰馑,四谷不升曰荒,五谷不升曰大侵。”}诸家宾客多为小盗。光武避吏新野,\jiazhu{新野属南阳郡,今邓州县。《续汉书》曰:“伯升宾客劫人,上避吏于新野邓晨家。”}因卖谷于宛。\jiazhu{《东观记》曰:“时南阳旱饥,而上田独收。”宛,县,属南阳郡,故城今邓州南阳县也。}宛人李通等以图谶说光武云:“刘氏复起,李氏为辅。”\jiazhu{图,《河图》也。谶,符命之书。谶,验也。言为王者受命之征验也。《易·坤灵图》曰:“汉之臣李阳也。”}光武初不敢当,然独念兄伯升素结轻客,必举大事,且王莽败亡已兆,天下方乱,遂与定谋,于是乃市兵弩。十月,与李通从弟轶等起于宛,时年二十八。
\end{document}

jiazhu 宏包版本太旧。
使用这一个版本:jiazhu.sty

使用 upLaTeX 或 pLaTeX-ng 编译,不能使用其它引擎
image.png

\documentclass[tikz,border=5pt,dvipdfmx]{standalone}
\usepackage{ctex}
\newcommand\nodebox[2][5\ccwd]{\hbox{\vbox{\parindent=0pt \linespread{1}\selectfont
  \setlength\hsize{#1}\tate #2}}}
\usetikzlibrary{arrows.meta,calc,positioning}
\tikzstyle{every node}=[font=\small]
\tikzset{>={Stealth[scale=1.1]}}
\tikzset{NR/.style={rectangle,draw,minimum height=0.5cm,inner ysep
=2pt,inner xsep=5pt,text=black,align=center,font=\linespread{1}\small}}
\begin{document}
\begin{tikzpicture}[node distance=1cm,cyan]
\node[NR,text width=5em](a){导数的概念及其意义};
\node[NR,below=of a,xshift=-0.7cm,align=left](a1){\tate 导数的概念};
\node[NR,below=of a,xshift=0.7cm,align=left](a2){\nodebox[6\ccwd]{基本初等函数的导数公式}};
\path(a.south)--++(0,-0.5cm)coordinate(x);
\draw(a.south)--(x)-|(a1.north);
\draw(a.south)--(x)-|(a2.north);
\end{tikzpicture}

\end{document}

upLaTeX 编译:

uplatex main.tex % 生成 dvi(main.dvi)
dvipdfmx main.dvi % 生成 pdf(main.pdf)

pLaTeX-ng 编译:

platex-ng main.tex % 生成 dvi(main.dvi)
dvipdfmx main.dvi % 生成 pdf(main.pdf),这一步必须使用 dvipdfmx,默认生成的 pdf 仍保留空白边距

(1)插入垂直间距 -1em。(2)这是使用垂直字体导致的,不能正确计算盒子的宽度,根本原因是目前 xetex 没有垂直排版的能力,只能靠旋转来实现。要使用垂直排版,最好使用 upLaTeX、pLaTeX-ng,或 ConTeXt MKXL(LuaMetaTeX)。(3)修改 \lineskiplimit\lineskip

\documentclass{ctexart}
\usepackage{graphicx}
\setCJKmainfont{SimSun}
\setCJKfamilyfont{songvert}[RawFeature={vertical:+vert}]{SimSun}
\newcommand*\CJKmovesymbol[1]{\raise.7em\hbox{#1}}
\newcommand*\CJKmove{
\let\CJKsymbol\CJKmovesymbol
\let\CJKpunctsymbol\CJKsymbol}
\usepackage{varwidth}
\newcommand{\shupai}[1]{\rotatebox{-90}{%
\begin{varwidth}{\textwidth}
\CJKfamily{songvert}
\lineskip=-3pt
\lineskiplimit=1pt
\CJKmove
#1\end{varwidth}}}
\newcommand{\SHUPAI}[1]{\rotatebox{-90}{%
\CJKfamily{songvert}%
\CJKmove
#1}}

\begin{document}
上文上文上文上文上文上文上文上文上文上文

\vspace*{-1em}\fbox{\shupai{文本框框\\测试}}

下文下文下文下文下文下文下文下文

\vspace*{-1em}\fbox{\SHUPAI{文本框框}}

测试测试测试测试测试测试测试测试测试测试测试测试
\end{document}

image.png

发布
问题