texlive[63249] Master/texmf-dist: chinesechess (7may22)

commits+karl at tug.org commits+karl at tug.org
Sat May 7 22:38:01 CEST 2022


Revision: 63249
          http://tug.org/svn/texlive?view=revision&revision=63249
Author:   karl
Date:     2022-05-07 22:38:01 +0200 (Sat, 07 May 2022)
Log Message:
-----------
chinesechess (7may22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/chinesechess/chinesechess.pdf
    trunk/Master/texmf-dist/doc/latex/chinesechess/chinesechess.tex
    trunk/Master/texmf-dist/tex/latex/chinesechess/chinesechess.sty

Modified: trunk/Master/texmf-dist/doc/latex/chinesechess/chinesechess.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/chinesechess/chinesechess.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/chinesechess/chinesechess.tex	2022-05-07 20:37:47 UTC (rev 63248)
+++ trunk/Master/texmf-dist/doc/latex/chinesechess/chinesechess.tex	2022-05-07 20:38:01 UTC (rev 63249)
@@ -123,7 +123,7 @@
   { \__codedoc_cmd:no {#1} { #2 } }
 \ExplSyntaxOff
 
-\def\vers{\texttt{v1.0.0} }
+\def\vers{\texttt{v1.1.0} }
 
 \begin{document}
 \title{
@@ -150,15 +150,14 @@
 
 \section{引言}
 
-\pkg{chinesechess}是一个基于\pkg{l3draw}用\pkg{Expl3}开发的
-中国象棋排版宏包。它提供了\tn{cchessboard} 全棋盘、
-\tn{cchessbord*}空白棋盘和\tn{cchessman}棋谱排版命令。同时,
+\pkg{chinesechess}是一个基于\pkg{l3draw}绘图宏包,用\pkg{Expl3}%
+开发的中国象棋排版宏包。它提供了\tn{cchessboard}(全棋盘)、%
+\tn{cchessbord*}(空棋盘)和\tn{cchessman}(棋谱)排版命令。同时,
 该宏包还提供了用于打谱的排版环境\env{setcchessman},在该环境
-中,可以通过环境专用命令\tn{init}初始化棋谱状态,\tn{set}在
-指定位置布置棋子,\tn{del}删除指定位置的棋子,\tn{mov}实现
-棋子的移动,从而实现打谱操作,并在环境结束后以最终状态排版棋谱。
-另外,也可以通过星号环境\env{setcchessman*}实现棋谱的文本描述
-输出。
+中,可以通过环境专用命令\tn{init}(初始化棋谱状态),\tn{set}(在
+指定位置布置棋子),\tn{del}(删除指定位置的棋子),\tn{mov}(实现
+棋子的移动),从而实现打谱操作,并在环境结束后以最终状态排版棋谱。
+另外,也可以通过星号环境\env{setcchessman*}实现棋谱文本输出。
 
 棋子、棋盘、背景等外观可以通过命令、环境选项或\tn{cchessset}%
 命令进行设置。
@@ -226,8 +225,8 @@
       编码 & 红棋 & 编码 & 黑棋\\\hline
       K    & 帥   & k    & 將  \\
       A    & 仕   & a    & 士  \\
-      E    & 相   & e    & 象  \\
-      H    & 马   & h    & 馬  \\
+      B(E) & 相   & b(e) & 象  \\
+      N(H) & 马   & n(h) & 馬  \\
       R    & 车   & r    & 車  \\
       C    & 炮   & c    & 炮  \\
       P    & 兵   & p    & 卒  \\\hline
@@ -274,7 +273,9 @@
   指定位置的棋子,\tn{mov}实现棋子的移动,从而实现打谱操作。
   在环境结束后以最终打谱状态排版棋谱。
 
-  星号环境\env{setcchessman*}会同时排版棋谱的文本描述(如:车一进二等)。
+  星号环境\env{setcchessman*}用于记录排版棋谱的文本描述(如:车一进二等)。
+  可在在\env{setcchessman*}环境中用label选项进行标记,然后用\tn{printman}%
+  输出该棋谱。
 
   在\oarg{外观选项}中可以通过key-value的方式设置棋子、棋盘的颜色、
   字体、字号、线宽等外观。
@@ -302,27 +303,6 @@
   \end{setcchessman}
 \end{SideBySideExample}
 
-\begin{SideBySideExample}[frame=single,numbers=left,
-                xrightmargin=.45\linewidth,gobble=2]
-  \centering
-  % 为便排版,进行缩放
-  \cchessset{resize=real,
-             width=.30\linewidth}
-  \begin{setcchessman*}
-    % 残局初始化
-    \init{ {{4,0}{K}}, {{2,2}{p}},
-           {{1,7}{C}}, {{4,9}{k}} }
-    % 添加棋子
-    \set{e,d}{P} \set{8,g}{h}
-    % 删除棋子
-    \del{4,3}
-    % 移动棋子
-    \mov{C}{b,h}{b,b} \mov{p}{2,2}{3,2}
-    \mov{K}{4,0}{4,1} \mov{h}{8,6}{6,7}
-    \mov{K}{4,1}{3,1} \mov{h}{6,7}{5,5}
-  \end{setcchessman*}
-\end{SideBySideExample}
-
 \subsection{打谱专用命令}
 
 \subsubsection{\tn{init}棋谱初始化命令}
@@ -386,6 +366,52 @@
 
   \textbf{\textsf{注意: }}该命令只能用于\env{setcchessman}环境中。
 
+\subsection{\tn{printman}输出打谱结果命令}
+
+\begin{function}{\printman}
+  \begin{syntax}
+    \cs{printman} \marg{\env{setcchessman*}环境的label标签}
+  \end{syntax}
+\end{function}
+
+  输出由label标签指定的\env{setcchessman*}打谱环境生成的棋谱。
+
+\subsection{\tn{getpiece}输出棋子命令}
+
+\begin{function}{\getpiece}
+  \begin{syntax}
+    \cs{getpiece} \oarg{棋子字号} \marg{棋子编码}
+  \end{syntax}
+\end{function}
+
+  按\oarg{棋子字号}指定的字号将用\marg{棋子编码}指定的棋子在当前位置输出。
+
+  \marg{棋子编码}中的编码详见表表\ref{tab-piececode}。
+
+\begin{SideBySideExample}[frame=single,numbers=left,
+                xrightmargin=.28\linewidth,gobble=2]
+  \centering
+  \getpiece{K}\getpiece{A}\getpiece{B}\getpiece{R}%
+  \getpiece{N}\getpiece{C}\getpiece{P}
+
+  \getpiece{k}\getpiece{a}\getpiece{b}\getpiece{r}%
+  \getpiece{n}\getpiece{c}\getpiece{p}
+\end{SideBySideExample}
+
+\subsection{\tn{piecechar}棋子字符设置命令}
+
+\begin{function}{\piecechar}
+  \begin{syntax}
+    \cs{piecechar} \marg{棋子编码} \marg{棋子字符}
+  \end{syntax}
+\end{function}
+
+  用于将\marg{棋子编码}指定的棋子字符设置为指定的\marg{棋子字符}。
+
+  \marg{棋子编码}中的编码详见表表\ref{tab-piececode}。
+
+  \textbf{\textsf{说明: }}该功能也可以通过|piecechar|外观选项实现。
+
 \subsection{\tn{resetpiece}棋子字符复位命令}
 
 \begin{function}{\resetpiece}
@@ -624,7 +650,7 @@
     piecechar={E}{\faChessBishop},
     piecechar={H}{\faChessKnight},
     piecechar={R}{\faChessRook},
-    piecechar={C}{\faBomb},
+    piecechar={C}{\faMeteor},
     piecechar={P}{\faChessPawn},
     piecechar={k}{\faChessQueen},
     piecechar={a}{\faShield*},
@@ -631,7 +657,7 @@
     piecechar={e}{\faChessBishop},
     piecechar={h}{\faChessKnight},
     piecechar={r}{\faChessRook},
-    piecechar={c}{\faBomb},
+    piecechar={c}{\faMeteor},
     piecechar={p}{\faChessPawn},
     boardlinecolor=red]
 \end{SideBySideExample}
@@ -862,6 +888,47 @@
     redupper=red,blkupper=black]
 \end{SideBySideExample}
 
+\bigskip
+
+\subsection{打谱}
+
+\subsubsection{label标签}
+
+\begin{option}{ opt = label, desc = {= \meta{棋谱标签}}, init=init-none }
+  设置\env{setcchessman*}打谱环境交叉引用标签。
+\end{option}
+
+\subsubsection{每行棋谱步数}
+
+\begin{option}{ opt = mansperline, desc = {= \meta{每行棋谱步数}}, init=2 }
+  设置\tn{printman}输出棋谱时,每行输出棋谱的步数。
+\end{option}
+
+\begin{SideBySideExample}[frame=single,numbers=left,
+                xrightmargin=.45\linewidth,gobble=2]
+  \centering
+    \printman{test}
+
+    \bigskip
+
+    % 为便排版,进行缩放
+    \cchessset{resize=real,
+               width=0.90\linewidth}
+    \begin{setcchessman*}[label=test]
+      % 残局初始化
+      \init{ {{4,0}{K}}, {{2,2}{p}},
+             {{1,7}{C}}, {{4,9}{k}} }
+      % 添加棋子
+      \set{e,d}{P} \set{8,g}{h}
+      % 删除棋子
+      \del{4,3}
+      % 移动棋子
+      \mov{C}{b,h}{b,b} \mov{p}{2,2}{3,2}
+      \mov{K}{4,0}{4,1} \mov{h}{8,6}{6,7}
+      \mov{K}{4,1}{3,1} \mov{h}{6,7}{5,5}
+    \end{setcchessman*}
+\end{SideBySideExample}
+
 % \bigskip
 
 % \title{

Modified: trunk/Master/texmf-dist/tex/latex/chinesechess/chinesechess.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/chinesechess/chinesechess.sty	2022-05-07 20:37:47 UTC (rev 63248)
+++ trunk/Master/texmf-dist/tex/latex/chinesechess/chinesechess.sty	2022-05-07 20:38:01 UTC (rev 63249)
@@ -19,12 +19,12 @@
 %%
 \NeedsTeXFormat{LaTeX2e}[2020/10/01]
 \RequirePackage{expl3}
-\ProvidesExplPackage{chinesechess}{2022-04-29}{v1.0.0}
+\ProvidesExplPackage{chinesechess}{2022-05-06}{v1.1.0}
   {Typeset Chinese chess with l3draw}
 
 \RequirePackage { l3keys2e, l3draw, xparse }
 
-% 保证TeXLive的向下兼容
+% 测量盒子总高度(保证TeXLive的向下兼容)
 \cs_if_free:NT \box_ht_plus_dp:N
   {
     \cs_new_protected:Npn \box_ht_plus_dp:N #1
@@ -31,9 +31,6 @@
       { \tex_dimexpr:D \box_ht:N #1 + \box_dp:N #1 \scan_stop: }
   }
 
-% 可以使用>{\SplitArgument{1}{~}}分割参数,如:
-% \NewDocumentCommand{\cchessboard}{ s >{\SplitArgument{1}{,}}O{10mm,10mm} }
-%
 % 棋盘排版命令用户接口
 % #1 星号命令,是否输出棋子
 % #2 棋盘类型、棋子类型等外观选项
@@ -56,10 +53,10 @@
 % 棋谱排版命令用户接口
 % #1 棋盘类型、棋子类型等外观选项
 % #2 棋子位置列表
-% 棋子字母汉字对照表(取xq.sty中的定义)
-% K=帅,A=仕,E=相,R=车,C=砲,H=马,P=兵, k=将,a=士,e=象,r=車,c=炮,h=馬,p=卒
-% 水平定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
-% 垂直定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
+%    红棋:K=帅,A=仕,E/B=相,R=车,C=砲,N/H=马,P=兵,
+%    黑棋:k=将,a=士,e/b=象,r=車,c=炮,n/h=馬,p=卒
+%    横向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
+%    纵向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
 \NewDocumentCommand{\cchessman}{ O{} m }
   {
     \group_begin:
@@ -75,29 +72,43 @@
       % 定义棋子字符常量
       \clist_map_inline:nn
         {
-          { K } {\__cchess_symbol:n {"5E25} }, % 帥
-          { A } {\__cchess_symbol:n {"4ED5} }, % 仕
-          { E } {\__cchess_symbol:n {"76F8} }, % 相
-          { H } {\__cchess_symbol:n {"9A6C} }, % 马
-          { R } {\__cchess_symbol:n {"8F66} }, % 车
-          { C } {\__cchess_symbol:n {"7832} }, % 砲
-          { P } {\__cchess_symbol:n {"5175} }, % 兵
-          { k } {\__cchess_symbol:n {"5C07} }, % 將
-          { a } {\__cchess_symbol:n {"58EB} }, % 士
-          { e } {\__cchess_symbol:n {"8C61} }, % 象
-          { h } {\__cchess_symbol:n {"99AC} }, % 馬
-          { r } {\__cchess_symbol:n {"8ECA} }, % 車
-          { c } {\__cchess_symbol:n {"70AE} }, % 炮
-          { p } {\__cchess_symbol:n {"5352} }, % 卒
+          { K } { 帥 }, % 帥\__cchess_symbol:n {"5E25}
+          { A } { 仕 }, % 仕\__cchess_symbol:n {"4ED5}
+          { E } { 相 }, % 相\__cchess_symbol:n {"76F8}
+          { B } { 相 }, % 相\__cchess_symbol:n {"76F8}
+          { H } { 马 }, % 马\__cchess_symbol:n {"9A6C}
+          { N } { 马 }, % 马\__cchess_symbol:n {"9A6C}
+          { R } { 车 }, % 车\__cchess_symbol:n {"8F66}
+          { C } { 砲 }, % 砲\__cchess_symbol:n {"7832}
+          { P } { 兵 }, % 兵\__cchess_symbol:n {"5175}
+          { k } { 將 }, % 將\__cchess_symbol:n {"5C07}
+          { a } { 士 }, % 士\__cchess_symbol:n {"58EB}
+          { e } { 象 }, % 象\__cchess_symbol:n {"8C61}
+          { b } { 象 }, % 象\__cchess_symbol:n {"8C61}
+          { h } { 馬 }, % 馬\__cchess_symbol:n {"99AC}
+          { n } { 馬 }, % 馬\__cchess_symbol:n {"99AC}
+          { r } { 車 }, % 車\__cchess_symbol:n {"8ECA}
+          { c } { 炮 }, % 炮\__cchess_symbol:n {"70AE}
+          { p } { 卒 }, % 卒\__cchess_symbol:n {"5352}
         }
         { \__cchess_piece_char_setup:nn ##1 }
   }
+
+% 棋子字符设置命令
+% #1 棋子编号及字符
+% K=帅,A=仕,B/E=相,R=车,C=砲,N/H=马,P=兵
+% k=将,a=士,b/e=象,r=車,c=炮,n/h=馬,p=卒
+\NewDocumentCommand{\piecechar}{ m m }
+  {
+    \__cchess_piece_char_setup:nn { #1 } { #2 }
+  }
+
 % 打谱环境初始化(仅用于setcchessman环境中)
 % #1 棋子位置列表
-% 棋子字母汉字对照表(取xq.sty中的定义)
-% K=帅,A=仕,E=相,R=车,C=砲,H=马,P=兵, k=将,a=士,e=象,r=車,c=炮,h=馬,p=卒
-% 水平定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
-% 垂直定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
+%    红棋:K=帅,A=仕,E/B=相,R=车,C=砲,N/H=马,P=兵,
+%    黑棋:k=将,a=士,e/b=象,r=車,c=炮,n/h=馬,p=卒
+%    横向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
+%    纵向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
 \NewDocumentCommand{\init}{ m }
   {
     % 临时clist
@@ -110,11 +121,11 @@
 
 % 打谱环境中的棋子布置命令(仅用于setcchessman环境中)
 % #1 棋子位置
-% #2 棋子名称(单个英文字母)
-% 棋子字母汉字对照表(取xq.sty中的定义)
-% K=帅,A=仕,E=相,R=车,C=砲,H=马,P=兵, k=将,a=士,e=象,r=車,c=炮,h=馬,p=卒
-% 水平定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
-% 垂直定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
+% #2 棋子位置列表
+%    红棋:K=帅,A=仕,E/B=相,R=车,C=砲,N/H=马,P=兵,
+%    黑棋:k=将,a=士,e/b=象,r=車,c=炮,n/h=馬,p=卒
+%    横向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
+%    纵向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
 \NewDocumentCommand{\set}{ m m }
   {
     \__cchess_piece_replace_handle:nn { #1 } { #2 }
@@ -121,9 +132,9 @@
   }
 
 % 删除打谱环境中的棋子(仅用于setcchessman环境中)
-% #1 棋子位置
-% 水平定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
-% 垂直定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
+% #1 棋子位置列表
+%    横向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
+%    纵向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
 \NewDocumentCommand{\del}{ m }
   {
     \__cchess_piece_remove_handle:n { #1 }
@@ -133,9 +144,10 @@
 % #1 棋子名称(单个英文字母)
 % #2 棋子当前位置
 % #3 棋子目的位置
-% K=帅,A=仕,E=相,R=车,C=砲,H=马,P=兵, k=将,a=士,e=象,r=車,c=炮,h=馬,p=卒
-% 水平定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
-% 垂直定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
+%    红棋:K=帅,A=仕,E/B=相,R=车,C=砲,N/H=马,P=兵,
+%    黑棋:k=将,a=士,e/b=象,r=車,c=炮,n/h=馬,p=卒
+%    横向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8)
+%    纵向定位: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9)
 \NewDocumentCommand{\mov}{ m m m }
   {
     \__cchess_piece_move_handle:nnn { #1 } { #2 } { #3 }
@@ -167,13 +179,37 @@
     \group_end:
   }
 
+% 打谱棋谱输出用户接口
+% #1 每行输出步数
+% #2 棋谱交叉引用label
+% 参考雾月的回复:https://ask.latexstudio.net/ask/question/7430.html
+\NewDocumentCommand{\printman}{ O{} >{\TrimSpaces} m } % 去掉两侧空格
+  {
+    \group_begin:
+      \keys_set:nn { cchess } { #1 }
+      \__cchess_setman_print:n { #2 }
+    \group_end:
+  }
 
-% ==========棋子字符定义=====================
+% 棋子输出用户接口
+% #1 棋子字体字号
+% #2 棋子编码
+%    红棋:K=帅,A=仕,E/B=相,R=车,C=砲,N/H=马,P=兵,
+%    黑棋:k=将,a=士,e/b=象,r=車,c=炮,n/h=馬,p=卒
+\NewDocumentCommand{\getpiece}{ O{\normalsize} m }
+  {
+    \group_begin:
+      \__cchess_getpiece_handle:nn {#1} { #2 }
+    \group_end:
+  }
+
+% ==========棋子字符常量定义=====================
 % 读取符号
 \cs_new:Npn \__cchess_symbol:n #1
   {
-    \tex_char:D #1
-    \scan_stop:
+    #1
+    % \tex_char:D #1
+    % \scan_stop:
   }
 
 % 棋子符号定义
@@ -233,30 +269,39 @@
 % 出于对国际象棋棋手意识习惯的兼容性设计
 % 相 B ,也可兼容使用 E,
 % 马N, 也可兼容使用 H 代替
+% 在此,为兼容性考虑使用B/E同时表示相,使用H/N同时表示马
+% 在使用时,可以任意选择习惯的名称
+
 % 判断红黑棋子英文单字母名称的正则表达式
 \regex_new:N \l__capital_regex
-\regex_set:Nn \l__capital_regex { [KAERCHP] }
-% 判断棋子英文单字母名称的正则表达式
-\clist_const:Nn \c__cchess_pieces_name_clist { K,A,E,R,C,H,P,k,a,e,r,c,h,p }
+\regex_set:Nn \l__capital_regex { [KAEBRCHNP] }
+
+% 棋子英文单字母名称列表
+\clist_const:Nn \c__cchess_pieces_name_clist { K,A,E,B,R,C,H,N,P,k,a,e,b,r,c,h,n,p }
 \msg_new:nnn { cchess } { piecename-exists } { The~ piece~ name~ `#1~ not~ exists. }
 
 % 定义棋子字符常量
+% 注意相和马分别用两个符号以适配不同习惯
 \clist_map_inline:nn
   {
-    { K } { "5E25 }, % 帥
-    { A } { "4ED5 }, % 仕
-    { E } { "76F8 }, % 相
-    { H } { "9A6C }, % 马
-    { R } { "8F66 }, % 车
-    { C } { "7832 }, % 砲
-    { P } { "5175 }, % 兵
-    { k } { "5C07 }, % 將
-    { a } { "58EB }, % 士
-    { e } { "8C61 }, % 象
-    { h } { "99AC }, % 馬
-    { r } { "8ECA }, % 車
-    { c } { "70AE }, % 炮
-    { p } { "5352 }, % 卒
+    { K } { 帥 }, % 帥"5E25
+    { A } { 仕 }, % 仕"4ED5
+    { E } { 相 }, % 相"76F8
+    { B } { 相 }, % 相"76F8
+    { H } { 马 }, % 马"9A6C
+    { N } { 马 }, % 马"9A6C
+    { R } { 车 }, % 车"8F66
+    { C } { 砲 }, % 砲"7832
+    { P } { 兵 }, % 兵"5175
+    { k } { 將 }, % 將"5C07
+    { a } { 士 }, % 士"58EB
+    { e } { 象 }, % 象"8C61
+    { b } { 象 }, % 象"8C61
+    { h } { 馬 }, % 馬"99AC
+    { n } { 馬 }, % 馬"99AC
+    { r } { 車 }, % 車"8ECA
+    { c } { 炮 }, % 炮"70AE
+    { p } { 卒 }, % 卒"5352
   }
   { \__cchess_piece_define:nn #1 }
 
@@ -268,8 +313,8 @@
       { #1 } { \use:c { c__cchess_ #1 _tl } }
   }
 
-% 在棋子编码列表中添加n表示空(null)棋子
-\clist_push:Nn \c__cchess_pieces_name_clist { n }
+% 在棋子编码列表中添加z表示空棋子
+\clist_push:Nn \c__cchess_pieces_name_clist { z }
 
 % 定义棋子盒子容器
 \clist_map_inline:Nn \c__cchess_pieces_name_clist
@@ -277,7 +322,7 @@
     \coffin_new:c { l__cchess_piece_ #1 _coffin }
   }
 % 将空棋子盒子容器置空
-\hcoffin_gset:Nn \l__cchess_piece_n_coffin { \phantom{空} }
+\hcoffin_gset:Nn \l__cchess_piece_z_coffin { \phantom{a} }
 
 % 棋盘盒子容器
 \coffin_new:N \l__cchess_board_coffin
@@ -311,11 +356,11 @@
     5 = f, 6 = g, 7 = h, 8 = i, 9 = j
   }
 
-% 判断是水平方向位置合法性的正则表达式
+% 判断是横向位置合法性的列表
 \clist_const:Nn \c__cchess_pos_x_index_clist
   { a,b,c,d,e,f,g,h,i,0,1,2,3,4,5,6,7,8 }
 \msg_new:nnn { cchess } { posx-exists } { The~ x~ index~ `#1~ not~ exists. }
-% 判断是垂直方向位置合法性的正则表达式
+% 判断是纵向位置合法性的列表
 \clist_const:Nn \c__cchess_pos_y_index_clist
   { a,b,c,d,e,f,g,h,i,j,0,1,2,3,4,5,6,7,8,9 }
 \msg_new:nnn { cchess } { posy-exists } { The~ y~ index~ `#1~ not~ exists. }
@@ -331,13 +376,13 @@
       {
         \coffin_new:c { l__cchess_board_piece_ #1 _ ##1 _coffin }
         \hcoffin_gset:cn { l__cchess_board_piece_ #1 _ ##1 _coffin }
-          { \phantom{空} }
+          { \phantom{a} }
       }
   }
-\coffin_new:N \l__cchess_board_piece_n_coffin
-\hcoffin_gset:Nn \l__cchess_board_piece_n_coffin { \phantom{空} }
+\coffin_new:N \l__cchess_board_piece_z_coffin
+\hcoffin_gset:Nn \l__cchess_board_piece_z_coffin { \phantom{a} }
 
-% 红方棋盘坐标字母与竖线标位对应关系
+% 红方棋盘坐标字母与红棋竖线标位对应关系
 \prop_const_from_keyval:Nn \c__cchess_board_red_x_idx_prop
   {
     a = 九, b = 八, c = 七 , d = 六, e = 五,
@@ -344,7 +389,7 @@
     f = 四, g = 三, h = 二, i = 一
   }
 
-% 黑方棋盘坐标字母与竖线标位对应关系
+% 黑方棋盘坐标字母与黑棋竖线标位对应关系
 \prop_const_from_keyval:Nn \c__cchess_board_black_x_idx_prop
   {
     a = 1, b = 2, c = 3 , d = 4, e = 5,
@@ -358,7 +403,7 @@
     5 = 五, 6 = 六, 7 = 七, 8 = 八, 9 = 九
   }
 
-% 棋谱文字说明列表(如车一进二等)
+% 棋谱记录列表(如车一进二等)
 \clist_new:N \l__cchess_manual_clist
 
 % 棋子外框盒子容器
@@ -393,16 +438,21 @@
 % 棋子缩放比例
 \tl_new:N    \l__cchess_piece_scale_tl
 % 待处理棋子字符
-\tl_new:N     \l__cchess_pieces_tl
+\tl_new:N    \l__cchess_pieces_tl
 % 棋子字符格式
-\tl_new:N     \l__cchess_piece_char_format_tl
+\tl_new:N    \l__cchess_piece_char_format_tl
 % 棋盘背景图片名称
-\tl_new:N     \l__cchess_board_background_tl
+\tl_new:N    \l__cchess_board_background_tl
 % 棋子字符字形类型(实线、虚线等)
-\int_new:N    \l__cchess_charstroke_type_int
+\int_new:N   \l__cchess_charstroke_type_int
 
+% 打谱环境棋谱标签
+\tl_new:N    \l__cchess_setman_label_tl
+% 打谱结果每行棋谱步数
+\int_new:N   \l__cchess_mans_per_line_int
+
 % 打谱环境用计数器
-% \int_new:N \c at cchessman
+\newcounter{setman}
 
 % 增加两个临时int变量
 \int_new:N \l_tmpc_int
@@ -415,7 +465,8 @@
 
 
 % 棋子盒子由l3draw实现,
-% 棋子外围盒子及缩放设计思路来自zitie宏包(\url{https://www.ctan.org/pkg/zitie})。
+% 棋子外围盒子及缩放设计思路来自zitie宏包
+% (\url{https://www.ctan.org/pkg/zitie})。
 
 % =============颜色处理函数=============
 % 填充色辅助函数
@@ -448,11 +499,11 @@
     \coffin_ht:N #1 + \coffin_dp:N #1
   }
 
-% 计算基字符外框大小(外接正方形边长和外接圆半径)
+% 计算外框大小(外接正方形边长和外接圆半径)
 \cs_new:Npn \__cchess_calc_piece_box_size:
   {
-    % 设置基字符格式的基字符盒子
-    \hbox_set:Nn \l_tmpa_box { 将 }
+    % 设置计算基础盒子
+    \hbox_set:Nn \l_tmpa_box { xx }
 
     % 盒子宽度
     \dim_set:Nn \l_tmpa_dim
@@ -491,31 +542,16 @@
 
 % =============构造棋子函数=============
 % 字符盒子构造类型函数名称生成函数
-% 名称中6个参数分别表示:
-% #1 左下角x坐标
-% #2 左下角y坐标
-% #3 右上角x坐标
-% #4 右上角y坐标
-% #5 x方向缩放比例(扩展保留参数)
-% #6 y方向缩放比例(扩展保留参数)
+% #1 缩放比例
 \cs_new_nopar:Npn \__cchess_piece_box_type:n #1
   {
     __cchess_piece_box_construct_type_ #1 :n
   }
 % 字符盒子构造类型函数名称命令生成函数
-% 名称命令中6个参数分别表示:
-% #1 左下角x坐标
-% #2 左下角y坐标
-% #3 右上角x坐标
-% #4 右上角y坐标
-% #5 x方向缩放比例(扩展保留参数)
-% #6 y方向缩放比例(扩展保留参数)
+% #1 缩放比例
 \cs_new_nopar:Npn \__cchess_piece_box_type_c:n #1
   {
-    \use:c
-      {
-        __cchess_piece_box_construct_type_ #1 :n
-      }
+    \use:c { __cchess_piece_box_construct_type_ #1 :n }
   }
 
 % 字符盒子构造类型函数内部生成器函数
@@ -647,25 +683,21 @@
 % =============构造棋盘函数=============
 % 棋盘部件构造函数函数名称生成函数
 % 名称中2个参数分别表示:
-% #1 x方向缩放比例(暂未使用保留参数)
-% #2 y方向缩放比例(暂未使用保留参数)
+% #1 x方向缩放比例(暂未使用, 保留参数)
+% #2 y方向缩放比例(暂未使用, 保留参数)
 \cs_new_nopar:Npn \__cchess_board_type:n #1
   {
     __cchess_board_construct_type_ #1 :nn
   }
-% 字符盒子构造类型函数名称命令生成函数
 % 名称命令中2个参数分别表示:
-% #1 x方向缩放比例(暂未使用保留参数)
-% #2 y方向缩放比例(暂未使用保留参数)
+% #1 x方向缩放比例(暂未使用, 保留参数)
+% #2 y方向缩放比例(暂未使用, 保留参数)
 \cs_new_nopar:Npn \__cchess_board_type_c:n #1
   {
-    \use:c
-      {
-        __cchess_board_construct_type_ #1 :nn
-      }
+    \use:c { __cchess_board_construct_type_ #1 :nn }
   }
 
-% 字符盒子构造类型函数生成器内部函数
+% 棋盘类型函数生成器内部函数
 % #1 类型名称
 \cs_new:Npn \__cchess_new_board_private_construct:nn #1
   {
@@ -675,7 +707,7 @@
 \cs_generate_variant:Nn \__cchess_new_board_private_construct:nn { V }
 \cs_generate_variant:Nn \__cchess_new_board_private_construct:nn { x }
 
-% 字符盒子构造类型函数生成器函数
+% 棋盘类型函数生成器函数
 % #1 类型名称
 \cs_new:Npn \__cchess_new_board_construct:nn #1
   {
@@ -687,10 +719,10 @@
 \cs_generate_variant:Nn \__cchess_new_board_construct:nn { V }
 \cs_generate_variant:Nn \__cchess_new_board_construct:nn { x }
 
-% 无棋盘
+% 空棋盘
 \__cchess_new_board_construct:nn { none } { }
 
-% 半部棋盘
+% 仅格子线半部棋盘
 \__cchess_new_board_private_construct:nn { __semiboard }
   {
     \draw_scope_begin:
@@ -787,7 +819,7 @@
     \draw_scope_end:
   }
 
-% 兵、炮标志
+% 兵、炮标志(半棋盘)
 \__cchess_new_board_private_construct:nn { __semipos }
   {
     \hcoffin_set:Nn \l_tmpa_coffin
@@ -867,7 +899,7 @@
     \draw_scope_end:
   }
 
-% 象位线
+% 象位虚线
 \__cchess_new_board_private_construct:nn { __elephantcross }
   {
     \draw_scope_begin:
@@ -910,8 +942,8 @@
 
     \color_select:n { cchessboardlinecolor }
 
-    \hcoffin_set:Nn \l_char_tmpa_coffin { 河 }
-    \hcoffin_set:Nn \l_char_tmpb_coffin { 楚 }
+    \hcoffin_set:Nn \l_char_tmpa_coffin { 楚 }
+    \hcoffin_set:Nn \l_char_tmpb_coffin { 河 }
     \hcoffin_set:Nn \l_char_tmpc_coffin { 漢 }
     \hcoffin_set:Nn \l_char_tmpd_coffin { 界 }
 
@@ -924,7 +956,7 @@
         \coffin_rotate:cn { l_char_tmp ##1 _coffin } { 90 }
       }
 
-    % 测量盒子容器总高度(用内切圆则不需要)
+    % 测量盒子容器总高度
     \dim_set:Nn \l_tmpa_dim
       { \__cchess_coffin_ht_plus_dp:N \l_char_tmpa_coffin }
 
@@ -933,7 +965,8 @@
         \fp_to_dim:n { \fp_eval:n { \gridsize * 0.45 } }
       }
 
-    \clist_map_inline:Nn \l_tmpa_clist
+    % 缩放盒子容器
+    \clist_map_inline:nn { a, b, c, d }
       {
         \coffin_scale:cnn { l_char_tmp ##1 _coffin }
           {
@@ -945,17 +978,26 @@
 
     % 排版文字
     \draw_scope_begin:
-      \int_set:Nn \l_tmpa_int { 1 }
-      \clist_map_inline:Nn \l_tmpa_clist
-        {
-          \draw_path_scope_begin:
-            \draw_transform_shift:n
-              { \gridsize * \l_tmpa_int, \gridsize * 4.5 }
-            \draw_coffin_use:cnn { l_char_tmp ##1 _coffin } { hc } { vc }
-          \draw_path_scope_end:
-          \int_incr:N \l_tmpa_int
-          \int_incr:N \l_tmpa_int
-        }
+      \draw_path_scope_begin:
+        \draw_transform_shift:n { \gridsize * 2, \gridsize * 4.5 }
+        \draw_transform_shift:n { -\gridsize / 2, 0pt }
+        \draw_coffin_use:cnn { l_char_tmpb_coffin } { hc } { vc }
+      \draw_path_scope_end:
+      \draw_path_scope_begin:
+        \draw_transform_shift:n { \gridsize * 2, \gridsize * 4.5 }
+        \draw_transform_shift:n { \gridsize / 2, 0pt }
+        \draw_coffin_use:cnn { l_char_tmpa_coffin } { hc } { vc }
+      \draw_path_scope_end:
+      \draw_path_scope_begin:
+        \draw_transform_shift:n { \gridsize * 6, \gridsize * 4.5 }
+        \draw_transform_shift:n { -\gridsize / 2, 0pt }
+        \draw_coffin_use:cnn { l_char_tmpc_coffin } { hc } { vc }
+      \draw_path_scope_end:
+      \draw_path_scope_begin:
+        \draw_transform_shift:n { \gridsize * 6, \gridsize * 4.5 }
+        \draw_transform_shift:n { \gridsize / 2, 0pt }
+        \draw_coffin_use:cnn { l_char_tmpd_coffin } { hc } { vc }
+      \draw_path_scope_end:
     \draw_scope_end:
   }
 
@@ -1255,13 +1297,18 @@
 % =============棋子文字设置函数=============
 % 设置棋子的文字
 % 红棋编码用大写字母,默认:
-% K=帅,A=仕,E=相,R=车,C=砲,H=马,P=兵
+% K=帅,A=仕,E/B=相,R=车,C=砲,H/N=马,P=兵
 % 黑棋编码用小字字母,默认:
-% k=将,a=士,e=象,r=車,c=炮,h=馬,p=卒
+% k=将,a=士,e/b=象,r=車,c=炮,h/n=馬,p=卒
 % #1 棋子编码
 % #2 棋子字符
 \cs_new_nopar:Npn \__cchess_piece_char_setup:nn #1#2
   {
+    \clist_if_in:NnF \c__cchess_pieces_name_clist { #1 }
+      {
+        \msg_error:nnx { cchess } { piecename-exists } { #1 }
+      }
+
     \prop_gput:Nnn \c__cchess_board_pieces_alph_name_prop
         { #1 } { #2 }
   }
@@ -1310,21 +1357,10 @@
     boardlinecolor  .initial:n = black ,
     boardlinecolor* .code:n = { \__cchess_color_select:nnn { cchessboardlinecolor } #1 } ,
 
-    % 设置棋子字符
-    piecechar .code:n    = { \__cchess_piece_char_setup:nn #1 },
-    piecechar .initial:n = {K}{\c__cchess_K_tl} ,
+    % 棋盘背景图片
+    boardbg .tl_set:N  = \l__cchess_board_background_tl ,
+    boardbg .initial:n = {} ,
 
-    % 字符格式
-    piecefont .code:n = { \tl_set:Nn \l__cchess_piece_char_format_tl {#1}
-                        \__cchess_calc_piece_box_size:
-                     },
-
-    % 边框类型
-    piecetype .code:n = { \exp_args:NNx \clist_if_in:NnTF
-                            \g__cchess_piece_box_list_clist {#1}
-                            { \tl_set:Nx \l__cchess_piece_box_type_tl {#1} }
-                            { \msg_error:nnx { cchess } { box-exists } {#1} }
-                        },
     % 缩放方式
     resize    .code:n = { \exp_args:NNx \clist_if_in:NnTF
                             \g__cchess_resize_method_clist {#1}
@@ -1340,6 +1376,22 @@
     width  .dim_set:N = \l__cchess_manual_width_dim ,
     height .dim_set:N = \l__cchess_manual_height_dim ,
 
+    % 设置棋子字符
+    piecechar .code:n    = { \__cchess_piece_char_setup:nn #1 },
+    piecechar .initial:n = {K}{\c__cchess_K_tl} ,
+
+    % 字符格式
+    piecefont .code:n = { \tl_set:Nn \l__cchess_piece_char_format_tl {#1}
+                        \__cchess_calc_piece_box_size:
+                     },
+
+    % 边框类型
+    piecetype .code:n = { \exp_args:NNx \clist_if_in:NnTF
+                            \g__cchess_piece_box_list_clist {#1}
+                            { \tl_set:Nx \l__cchess_piece_box_type_tl {#1} }
+                            { \msg_error:nnx { cchess } { box-exists } {#1} }
+                        },
+
     % 字符边框线宽
     boxlinewd .dim_set:N = \l__cchess_box_linewidth_dim ,
     boxlinewd .initial:n = 0.4pt ,
@@ -1434,10 +1486,14 @@
       { \int_set_eq:NN \l__cchess_charstroke_type_int \l_keys_choice_int },
     charstroke .initial:n = bold,
 
-    % 棋盘背景图片
-    boardbg .tl_set:N  = \l__cchess_board_background_tl ,
-    boardbg .initial:n = {} ,
+    % 打谱环境交叉引用标签
+    label .tl_gset:N  = \l__cchess_setman_label_tl ,
+    label .initial:n = {} ,
 
+    % 每行棋谱步数
+    mansperline .tl_gset:N  = \l__cchess_mans_per_line_int ,
+    mansperline .initial:n = 2 ,
+
     unknown .code:n = { \msg_error:nn { cchess } { unknown-option } }
   }
 \msg_new:nnn { cchess } { unknown-option }
@@ -1448,7 +1504,7 @@
     piecefont = \kaishu,
     piecetype = ooo,
     boardtype = x+tn,
-    resize   = none,
+    resize    = none,
   }
 
 % 选项设置用户接口
@@ -1491,7 +1547,7 @@
           % 缩放棋子盒子容器
           \coffin_resize:Nnn \l__cchess_piece_coffin { \piecesize }{ \piecesize }
 
-          % 复制结果以备后续使用
+          % 保存结果
           \coffin_gset_eq:cN
             { l__cchess_piece_ ##1 _coffin } \l__cchess_piece_coffin
         }
@@ -1531,17 +1587,17 @@
   }
 
 % =============创建棋子占位coffins=============
-  % 缩放空白棋子(n---null)
-\cs_new:Nn \__cchess_board_piece_n_resize:
+  % 缩放空白棋子
+\cs_new:Nn \__cchess_board_piece_z_resize:
   {
-    \coffin_resize:Nnn \l__cchess_piece_n_coffin { \piecesize } { \piecesize }
+    \coffin_resize:Nnn \l__cchess_piece_z_coffin { \piecesize } { \piecesize }
   }
-% 执行缩放
-\__cchess_board_piece_n_resize:
+% 缩放空白棋子
+\__cchess_board_piece_z_resize:
 
 % 将棋子盒子容器布置到棋盘指定位置(用于棋谱和棋盘排版)
 % #1 棋子参数
-% 棋子参数的形式为{0,0}{k},{0,1}{K},注意需要包含大括号,
+% 棋子参数的形式为{{0,0}{k},{0,1}{K}},注意需要包含大括号,
 % 不同棋子之间用英文逗号分隔
 \cs_new:Npn \__cchess_board_piece_pos_construct:n #1
   {
@@ -1550,7 +1606,7 @@
         \draw_begin:
           % 在四个角布置空白棋子实现占位(用于撑满棋子画布)
           \clist_set:Nn \l_tmpa_clist
-            { {0, 0}{n}, {8, 0}{n}, {0, 9}{n}, {8, 9}{n}}
+            { {0, 0}{z}, {8, 0}{z}, {0, 9}{z}, {8, 9}{z}}
           \clist_map_inline:Nn \l_tmpa_clist
             {
               \__cchess_piece_set_handle:nn ##1
@@ -1575,7 +1631,7 @@
         % 如果文件名不为空则载入图片,否则创建一个空盒子容器
         \tl_if_empty:NTF \l__cchess_board_background_tl
           {
-            \phantom{将}
+            \phantom{a}
           }{
             \includegraphics{\l__cchess_board_background_tl}
           }
@@ -1670,6 +1726,43 @@
       }
   }
 
+% 在正文中排版棋子
+\cs_new:Npn \__cchess_getpiece_handle:nn #1#2
+  {
+    % 构建红黑各7个棋子
+    \__cchess_pieces_construct:
+
+    % 设置指定格式的基字符盒子
+    \hbox_set:Nn \l_tmpa_box { #1 将 }
+
+    % 盒子高度
+    \dim_set:Nn \l_tmpa_dim
+      {
+        \box_ht_plus_dp:N \l_tmpa_box
+      }
+
+    % 棋子高度
+    \dim_set:Nn \l_tmpb_dim
+      {
+        \__cchess_coffin_ht_plus_dp:N \l__cchess_piece_K_coffin
+      }
+
+    % 缩放棋子
+    \coffin_scale:cnn { l__cchess_piece_ #2 _coffin }
+      {
+        \dim_ratio:nn { \l_tmpa_dim } { \l_tmpb_dim }
+      }{
+        \dim_ratio:nn { \l_tmpa_dim } { \l_tmpb_dim }
+      }
+
+    % 盒子深度
+    \dim_set:Nn \l_tmpb_dim { \box_dp:N \l_tmpa_box }
+
+    % 输出盒子(下沉深度距离)
+    \coffin_typeset:cnnnn { l__cchess_piece_ #2 _coffin }
+        { l } { b } { 0pt } { -\l_tmpb_dim }
+  }
+
 % =============排版棋谱=============
 % 棋谱排版
 \cs_new:Npn \__cchess_manual_output:n #1
@@ -1820,12 +1913,14 @@
   }
 \cs_generate_variant:Nn \__cchess_piece_set:nnn {VV}
 
+% ======================================================
 % ===采用棋子替换方式创建棋子画布coffin(用于打谱排版)===
-% 缩放棋子盒子容器
+% ======================================================
+% 缩放占棋子盒子容器
 \cs_new:Nn \__cchess_board_pieces_resize:
   {
     % 空白棋子
-    \coffin_resize:Nnn \l__cchess_board_piece_n_coffin
+    \coffin_resize:Nnn \l__cchess_board_piece_z_coffin
        { \piecesize } { \piecesize }
 
     % 其它棋子,按行(a-i)列(a-j)编号命名。
@@ -1912,8 +2007,8 @@
   }
 
 % 棋子占位替换函数
-% #1 x方向数字型坐标值(a-i)
-% #2 y方向数字型坐标值(a-j)
+% #1 横向字符型坐标值(a-i)
+% #2 纵向字符型坐标值(a-j)
 % #3 棋子名称(单英文字母)
 \cs_new:Npn \__cchess_piece_replace:nnn #1#2#3
   {
@@ -1958,14 +2053,14 @@
   }
 
 % 棋子删除函数
-% #1 x方向数字型坐标值(a-i)
-% #2 y方向数字型坐标值(a-j)
+% #1 横向字符型坐标值(a-i)
+% #2 纵方向字符型坐标值(a-j)
 % #3 棋子名称(单英文字母)
 \cs_new:Npn \__cchess_piece_remove:nn #1#2
   {
     \coffin_gset_eq:cN
       { l__cchess_board_piece_ #1 _ #2 _coffin }
-      \l__cchess_board_piece_n_coffin
+      \l__cchess_board_piece_z_coffin
   }
 \cs_generate_variant:Nn \__cchess_piece_remove:nn {VV}
 
@@ -2028,10 +2123,10 @@
   }
 
 % 棋子移动函数
-% #1 原位置x方向数字型坐标值(a-i)
-% #2 原位置y方向数字型坐标值(a-j)
-% #3 新位置x方向数字型坐标值(a-i)
-% #4 新位置y方向数字型坐标值(a-j)
+% #1 原位置横向字符型坐标值(a-i)
+% #2 原位置纵向字符型坐标值(a-j)
+% #3 新位置横向字符型坐标值(a-i)
+% #4 新位置纵向字符型坐标值(a-j)
 % #5 棋子名称(单英文字母)
 \cs_new:Npn \__cchess_piece_move:nnnnn #1#2#3#4#5
   {
@@ -2050,14 +2145,14 @@
 
 % 生成打谱棋谱记录
 % TODO:暂未实现纵向同类棋子前后判断
-% #1 原位置x方向数字型坐标值(a-i)
-% #2 原位置y方向数字型坐标值(a-j)
-% #3 新位置x方向数字型坐标值(a-i)
-% #4 新位置y方向数字型坐标值(a-j)
+% #1 原位置横向字符型坐标值(a-i)
+% #2 原位置纵向字符型坐标值(a-j)
+% #3 新位置横向字符型坐标值(a-i)
+% #4 新位置纵向字符型坐标值(a-j)
 % #5 棋子名称(单英文字母)
 \cs_new:Npn \__cchess_piece_manual_str_construct:nnnnn #1#2#3#4#5
   {
-    % 将字母坐标数据转换为整数坐标
+    % 将字符坐标数据转换为整数坐标
     \prop_get:NnN \c__cchess_board_pos_alph_num_prop { #1 } \l_tmpa_tl
     \prop_get:NnN \c__cchess_board_pos_alph_num_prop { #2 } \l_tmpb_tl
     \prop_get:NnN \c__cchess_board_pos_alph_num_prop { #3 } \l_tmpc_tl
@@ -2226,6 +2321,11 @@
     \tl_use:N \l_tmpa_tl
   }
 
+% 定义\label命令的变体函数
+%\label { #1 }
+\cs_set_eq:NN \__cchess_setman_label:n \label
+\cs_generate_variant:Nn \__cchess_setman_label:n { x }
+
 % 打谱环境后处理函数
 \cs_new:Nn \__cchess_setcchessman_post_setup:
   {
@@ -2257,36 +2357,27 @@
     % 星号环境需要输出打谱记录
     \bool_if:NT \l__cchess_with_setman_bool
       {
-        % 测量打谱记录盒子水平尺寸
-        \hcoffin_set:Nn \l_tmpa_coffin { 车九平八\quad 车九平八}
-        \dim_set:Nn \l_tmpa_dim { \coffin_wd:N \l_tmpa_coffin }
+        % 递增计数器
+        \refstepcounter{setman}
+        % 设置label标签
+        \__cchess_setman_label:x { \l__cchess_setman_label_tl }
 
-        % 构建打谱记录垂直盒子容器
-        \vcoffin_set:Nnn \l_tmpa_coffin { \l_tmpa_dim }
+        % 构造临时文件
+        \iow_open:Nn \g_tmpa_iow
           {
-            % 遍历打谱记录列表,输出打谱记录
-            \bool_until_do:nn { \clist_if_empty_p:N \l__cchess_manual_clist }
-              {
-                % 取消首行缩进
-                \noindent
-                \clist_pop:NN \l__cchess_manual_clist \l_tmpa_tl
+            \c_sys_jobname_str\l__cchess_setman_label_tl\thesetman .man
+          }
 
-                \clist_if_empty:NTF \l__cchess_manual_clist
-                  {
-                    \l_tmpa_tl
-                  }{
-                    \clist_pop:NN \l__cchess_manual_clist \l_tmpb_tl
-                    \l_tmpa_tl
-                    \quad
-                    \l_tmpb_tl
-                    \par
-                  }
-              }
+        % 遍历打谱记录列表,输出打谱记录到临时文件
+        \bool_until_do:nn { \clist_if_empty_p:N \l__cchess_manual_clist }
+          {
+            \clist_pop:NN \l__cchess_manual_clist \l_tmpa_tl
+            \tl_set:Nx \l_tmpb_tl {\l_tmpa_tl}
+            \iow_now:Nx \g_tmpa_iow { \l_tmpb_tl }
           }
 
-        % 拼装打谱记录盒子容器到结果容器
-        \coffin_join:NnnNnnnn \l__cchess_manual_coffin
-          { l } { t } \l_tmpa_coffin { r } { t } { -10pt } { -\piecesize }
+        % 关闭文件
+        \iow_close:N \g_tmpa_iow
       }
 
     % 输出结果盒子容器
@@ -2294,4 +2385,60 @@
       { l }{ b } { 0pt } { 0pt }
   }
 
+% 参考雾月的回复:https://ask.latexstudio.net/ask/question/7430.html
+% LaTeX3 并未定义 \use_i:nnnnn
+\cs_set:Npn \use_i:nnnnn #1#2#3#4#5 {#1}
+
+% 打谱棋谱排版描述处理
+\cs_new:Npn \__cchess_setman_print:n #1
+  {
+    % 根据棋谱label构建文件名
+    \cs_if_exist:cTF { r@#1 }
+      {
+        % 这一步是得到 ref,它保存在 \r@#1 中。
+        % \r@#1 有两项,当使用 hyperref 时,
+        % \r@#1 有 5 项,这里使用 \empty 统一解决
+        \tl_set:Nx \l_tmpa_tl
+          {
+            \c_sys_jobname_str
+            #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 }
+          {
+            % 循环计数
+            \int_set:Nn \l_tmpa_int { 1 }
+            % 循环读取一行棋谱
+            \ior_str_map_variable:NNn \g_tmpb_ior \l_tmpb_str
+              {
+                % 转换为token
+                \tl_set_rescan:Nno \l_tmpb_tl
+                  {
+                    \char_set_catcode_letter:N \_
+                    \char_set_catcode_letter:N :
+                  }{ \l_tmpb_str }
+
+                % 输出结果
+                \tl_use:N \l_tmpb_tl
+
+                % 根据每行步数确定输出\quad或是\par
+                \int_set:Nn \l_tmpb_int
+                  {
+                    \int_mod:nn { \l_tmpa_int } { \l__cchess_mans_per_line_int }
+                  }
+                \int_compare:nNnTF { \l_tmpb_int } = { 0 }
+                  { \par } { \quad }
+
+                \int_incr:N \l_tmpa_int
+              }
+          }
+          { \msg_error:nnx { cchess } { file-not-found } { \l_tmpa_tl } }
+
+        % 关闭文件
+        \iow_close:N \g_tmpa_ior
+      }{ \G at refundefinedtrue }% 引用未定义
+  }
+
 \endinput



More information about the tex-live-commits mailing list.