\documentclass[full]{l3doc}
\usepackage[scheme=chinese]{ctex}
\usepackage{geometry}
\usepackage{fancyvrb-ex}
\usepackage{ninecolors}
\usepackage{suanpan-l3}

\IndexPrologue
  {
    % \section*{索引}
    % \markboth{索引}{索引}
    % \addcontentsline{toc}{section}{索引}
    % 斜体数字说明了对应索引内容出现的页码，
    % 带有下划线的数据给出了索引内容的定义，
    % 其它的数字给出了索引内容引用的位置。
    \section*{Index}
    \markboth{Index}{Index}
    \addcontentsline{toc}{section}{Index}
    The~italic~numbers~denote~the~pages~where~the~
    corresponding~entry~is~described,~
    numbers~underlined~point~to~the~definition,~
    all~others~indicate~the~places~where~it~is~used.
  }

\newcommand\tikzmark[1]{\tikz \coordinate[overlay, remember picture] (#1);}

\geometry{
  left=4.5cm,
  right=2cm,
  top=2cm,
  bottom=2cm,
}
\hypersetup {
  CJKbookmarks,
  bookmarksopen,
  bookmarksopenlevel=3,
  pdfstartview=FitH,
  pdfinfo = {
   Title = 中国传统7珠圆珠算盘排版宏包 ,
   Subject = A LaTeX3 package ,
   Author = 耿楠
 }
}

\DoNotIndex{\begin, \end}
\setlength{\parskip}{\medskipamount}
\DeclareDocumentEnvironment { noteen } { +b } {
  \par\textbf{\textsf{NOTE:~}}#1\par
} {}
\DeclareDocumentEnvironment { notezh } { +b } {
  \par\textbf{\textsf{注意:~}}#1\par
} {}

\AtEndDocument{
  \newgeometry{
    left=2cm,
    right=2cm,
    top=2cm,
    bottom=2cm
  }
  \PrintChanges
  \PrintIndex
}

\ExplSyntaxOn
\dim_new:N \l__my_syntax_dim
\box_new:N \g__my_syntax_box
\NewDocumentEnvironment { Syntax } { s }
  {
    \dim_set:Nn \l__my_syntax_dim
      { \textwidth }
    \hbox_gset:Nw \g__my_syntax_box
      \small \ttfamily
      \begin{minipage}[t]{\l__my_syntax_dim}
        \raggedright\obeyspaces\obeylines
  }
  {
      \end{minipage}
    \hbox_gset_end:
    \IfValueF { #1 } { \smallskip }
    \box_use_drop:N \g__my_syntax_box
    \smallskip
  }

\DeclareDocumentEnvironment { Description } { o +b } {
  \hbox_set:Nn \l_tmpa_box { #1 }
  \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box }
  \begin{itemize}[labelwidth=\l_tmpa_dim, align=left]
    #2
  \end{itemize}
} {  }

\keys_define:nn { suanpan/doc } {
  opt .tl_set:N = \l_opt_tl,
  desc .tl_set:N = \l_desc_tl,
  init .tl_set:N = \l_init_tl,
  init .initial:n = init-none,
}

\box_new:N \l__option_box
\NewDocumentEnvironment { option } { m +b } {
  \keys_set:nn { suanpan/doc } { #1 }
  \hbox_set:Nw \l__option_box
    \small \ttfamily
    \begin{minipage}[t]{\textwidth}
      \obeyspaces\obeylines
      \textcolor{red}{
        \l_opt_tl
        \exp_args:Nx\SpecialOptionIndex{\l_opt_tl}
      }
      {~}\l_desc_tl
      \hfill(
      \tl_if_eq:NnTF \l_init_tl { init-none } { no~value }
        { init: ~\texttt{\l_init_tl} }
      )
    \end{minipage}
  \hbox_gset_end:
  \box_use_drop:N \l__option_box
  #2
  \medskip
} {  }

\DeclareDocumentCommand \opt { O{} m }
  { \__codedoc_cmd:no {#1} { #2 } }
\ExplSyntaxOff

\def\vers{\texttt{v1.1.1} }

\changes{v1.0.0}{2024/08/20}{first version.}

\begin{document}
\title{
  \pkg{suanpan-l3}---算盘(Abacus)排版宏包
  \rlap{\makebox[4cm][r]{
    \normalsize $\Longrightarrow$ \color{red}
    \protect\hyperlink{en}{English Version}
    \protect\hypertarget{zh}{}
  }}
}
\author{\textit{耿楠} \texttt{<nangeng@nwafu.edu.cn>}}
\date{\the\year 年\the\month 月\the\day 日\qquad \vers
\thanks{\url{https://gitee.com/nwafu_nan/suan-pan}}
}

\maketitle

\begin{abstract}
  \pkg{suanpan-l3}是一个基于\pkg{l3draw}绘图宏包，用\pkg{Expl3}%
  开发的中国传统7珠圆珠算盘排版宏包，它能够实现使用普通上珠、下珠
  和底珠、顶珠及悬珠的算盘排版。该宏包提供了唯一的一个
  \env{suanpan}算盘排版环境及仅在该环境中使用的 \tn{rod}、
  \tn{rods}、\tn{bid}、\tn{bids}和\tn{lrframe}档杆、算珠着色和
  边框排版命令。同时，该宏包还提供了\tn{suanpanset}命令用于对算盘
  外观进行设置。
  \begin{center}
    \begin{suanpan}[framedraw = brown2, scale = 0.45, bidsep=1.5pt,
                    roddraw = brown3, rodfill = brown4]
      % 各档位数字列表
      \rods{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
      % 定位点
      \rod*{4}{3}
      \rod*{18}{17}
      % 使用顶珠
      \bid{12}{9}{azure7}
      \bid{13}{9}{azure7}
      \bid{14}{9}{azure7}
      \bid{15}{9}{azure7}
      \bid{16}{9}{azure7}
      % 使用悬珠
      \bid{17}{11}{red8}
      \bid{18}{11}{red8}
      \bid{19}{11}{red8}
      \bid{20}{11}{red8}
      \bid{21}{11}{red8}
      % 使用底珠
      \bid{11}{3}{olive7}
      \bid{16}{3}{olive7}
      \bid{21}{3}{olive7}
      \lrframe{1}{21}
    \end{suanpan}
  \end{center}
\end{abstract}

{\small
\tableofcontents
}
\newpage

\begin{documentation}

\section{引言}

\pkg{suanpan-l3}宏包是一个基于\pkg{l3draw}绘图宏包，用\pkg{Expl3}%
开发的中国传统7珠圆珠算盘排版宏包，它利用\pkg{l3draw}的绘图功能，
利用简单线条实现了算盘的排版。

由于圆珠是通过圆角矩形实现的，因此当算珠数量较多时，绘制耗时较长，
其编译速度较慢。

\section{用户接口}

\subsection{\env{suanpan}算盘排版环境}

\begin{function}{suanpan}
  \begin{syntax}
    \tn{begin}|{suanpan}|\oarg{外观选项}
    .....
    \tn{end}|{suanpan}|
  \end{syntax}
\end{function}

  按可选项设置的\oarg{外观选项}实现算盘排版。

  在\env{suanpan}环境中，可以通过专用命令\tn{rod}%
  (排版算盘的一个档位)，\tn{rods}(排版一组档位)，
  \tn{bid}(指定算珠颜色)，\tn{lrframe}(排版左右边框)
  按需实现算盘排版。

  在\oarg{外观选项}中可以通过key-value的方式设置线宽、颜色、
  缩放比例等外观属性。

  通过\oarg{外观选项}设置的外观参数仅对\env{suanpan}环境局部有效。

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  % 为便排版，进行缩放
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rod{1}{0}
    \rod{2}{3}
    \rod{3}{0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{\env{suanpan}环境中的专用命令}

\subsubsection{\tn{rod}单一档位排版命令}

\begin{function}{\rod}
  \begin{syntax}
    \cs{rod} \marg{档位编号} \marg{档位数字}
  \end{syntax}
\end{function}

  用于排版\marg{档位编号}(基于1，从左向右进行编号)参数指定的算盘
  档位，本档的计数值由\marg{档位数字}参数指定。

  \marg{档位数字}支持[0, 20]内的数字，其中[0, 9]内的
  数字采用常规4个下珠结合1个上珠的方法进行表示，[10, 15]
  内的数字则需要额外使用\enquote{底珠}和\enquote{顶珠}进行表示，
  [16, 20]内的数字则需要再额外使用\enquote{悬珠}进行表示。

  宏包还为\tn{rod}命令同时提供了\tn{rod*}星号命令用于排版在
  横梁上带有计位点(圆点)的档位。

  \begin{notezh}
    该命令只能用于\env{suanpan}环境中。
  \end{notezh}

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rod{1}{1}   % 常规档位
    \rod{2}{6}
    \rod*{3}{10} % 计位点，使用底珠
    \rod{4}{12}  % 使用顶珠
    \rod{5}{18}  % 使用悬珠
  \end{suanpan}
\end{SideBySideExample}

\subsubsection{\tn{rods}一组档位排版命令}

\begin{function}{\rods}
  \begin{syntax}
    \cs{rods} \marg{数字列表}
  \end{syntax}
\end{function}

  用于排版在\marg{数字列表}中用逗号分隔的一组数字指定的档位，
  各档位编号基于1，从左向右进行自动编号。

  \marg{数字列表}中的各档位数字支持[0, 20]内的数字，其中[0, 9]内的
  数字采用常规4个下珠结合1个上珠的方法进行表示，[10, 15]
  内的数字则需要额外使用\enquote{底珠}和\enquote{顶珠}进行表示，
  [16, 20]内的数字则需要再额外使用\enquote{悬珠}进行表示。

  \begin{notezh}
    宏包并没有为\tn{rods}命令提供在横梁排版计位点的档位的
    操作。如果需要，则可以使用\tn{rod*}命令对指定档位进行覆盖绘制。

    同样，该命令只能用于\env{suanpan}环境中。
  \end{notezh}

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rods{0, 6, 12, 18, 0}
    \rod*{3}{12}
  \end{suanpan}
\end{SideBySideExample}

\changes{v1.0.1}{2024/08/26}{rename \tn{bidclr} to \tn{bid}.}
\subsubsection{\tn{bid}算珠着色命令}

\begin{function}{\bid}
  \begin{syntax}
    \cs{bid} \marg{档位编号}\marg{算珠位置}\marg{算珠颜色}
  \end{syntax}
\end{function}

  用于将\marg{档位编号}指定的档位中，用\marg{算珠位置}指定的算珠
  设置为\marg{算珠颜色}指定的颜色。同时，该命令还将\marg{算珠颜色}%
  融合40\%黑色后用于算珠绘制颜色。

  一个档位中的\marg{算珠位置}自下向上，按\enquote{$1, 2, \cdots, 11$}%
  的顺序进行编号。其中下珠占\enquote{$1, 2, \cdots, 7$}的位置，上珠占
  \enquote{$8, 9, 10$}的位置，悬珠占\enquote{$11$}的位置。

  \begin{notezh}
    同样，该命令只能用于\env{suanpan}环境中。
  \end{notezh}

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rods{0, 0, 7, 11, 8, 19}
    \bid{1}{1}{gray7}
    \bid{2}{5}{gray7}
    \bid{3}{6}{red8}
    \bid{4}{7}{red8}
    \bid{4}{8}{azure6}
    \bid{4}{9}{yellow9}
    \bid{5}{10}{violet5}
    \bid{6}{11}{teal4}
  \end{suanpan}
\end{SideBySideExample}

\changes{v1.1.0}{2024/08/28}{adde \tn{bids} macro.}
\subsubsection{\tn{bids}内珠或外珠着色命令}

\begin{function}{\bids}
  \begin{syntax}
    \cs{bids} \marg{档位编号}\marg{档位数字}\marg{算珠颜色}
  \end{syntax}
\end{function}

  用于将\marg{档位编号}指定的档位中，所有\marg{档位数字}的内珠
  设置为\marg{算珠颜色}指定的颜色。同时，该命令还将\marg{算珠颜色}%
  融合40\%黑色后用于算珠绘制颜色。

  宏包还为\tn{bids}命令同时提供了\tn{bids*}星号命令用于设置该档
  所有外珠的颜色。

  \begin{notezh}
    同样，该命令只能用于\env{suanpan}环境中。该命令只能选择
    内珠或外珠进行着色，不能同时选择内珠和外珠。
  \end{notezh}

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rods{0, 0, 7, 11, 8, 19}
    \bids{3}{7}{teal4}
    \bids*{5}{8}{azure6}
  \end{suanpan}
\end{SideBySideExample}

\subsubsection{\tn{lrframe}左右边框排版命令}

\begin{function}{\lrframe}
  \begin{syntax}
    \cs{lrframe} \marg{首档编号}\marg{末档编号}
  \end{syntax}
\end{function}

  用于在\marg{首档编号}指定的档位左边和\marg{末档编号}指定的档位
  右边排版算盘的左右边框。

  \begin{notezh}
    同样，该命令只能用于\env{suanpan}环境中。另外，其左右边框应该
    同时按正确第一档和最后一档档位编号绘制，否则会造成结果容器(盒子)
    尺寸异常的问题。
  \end{notezh}

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rods{0, 6, 12, 18, 0}
    \lrframe{1}{5}
  \end{suanpan}
\end{SideBySideExample}

\subsection{\tn{suanpanset}选项设置命令}

\begin{function}{\suanpanset}
  \begin{syntax}
    \cs{suanpanset} \marg{外观选项}
  \end{syntax}
\end{function}

  通过\marg{外观选项}的key-value选项设置算盘的算珠、边框等元素的
  绘制颜色、填充颜色、线条宽度；各档位之间的间距、算珠之间的间距；
  算盘整体的缩放比例等外观属性。

  通过\cs{suanpan}\marg{外观选项}设置的外观属性对后续所有算盘排版
  操作有效。

  \begin{notezh}
    由于\pkg{suanpan-l3}宏包涉及大量绘图操作，因此建议尽量减少在每个
    \env{suanpan}排版环境的可选项中使用\oarg{外观选项}设置，以
    节约编译时间。如需要更改算盘外观，可以在引用宏包时，通过为宏包
    添加选项实现，也可以执行\tn{suanpanset}命令进行必要的
    全局设置或在一定范围内进行统一设置。
  \end{notezh}

\section{宏包选项}

在\pkg{suanpan-l3}宏包中，算盘颜色、线条宽度、档位及算珠间距等
算盘外观属性可以在引入宏包时通过\oarg{宏包选项}进行设置，
也可以在\env{suanpan}环境的\oarg{外观选项}中进行局部设置，
还可以通过\cs{suanpanset}命令进行全局或局部设置。

强烈建议在引用宏包时通过\oarg{宏包选项}为一个文档统一全局设置
算盘外观属性，以节约编译时间。应避免频繁\env{suanpan}环境中使用
\oarg{宏包选项}或使用\cs{suanpanset}命令设置算盘外观属性。

\pkg{suanpan-l3}宏包选项是一个英文逗号分隔的选项列表，其
选项是\marg{key}|=|\marg{value}形式。部分选项的\marg{value}可以省略。
对于同一选项，后续设置会覆盖以前设置。

\pkg{suanpan-l3}宏包采用\LaTeX3风格的键值设置，支持不同类型以及多种层次的
选项设定。键值列表中，``|=|''左右的空格不影响设置。但需注意，参数列表中%
\textsf{不可以出现空行}。

布尔型的参数\marg{选项}|=true|中的``|=true|''可以省略。

\subsection{草稿选项}

\begin{option}{ opt = draft, desc = {= \meta{草稿选项}}, init=false }
  设置草稿选项。
\end{option}

  \oarg{draft}选项会将算珠用矩形表示，取消其圆角效果，从而加快编译速度。

  \begin{notezh}
    在草稿模式下算盘排版会与期望的排版结果有出入。
  \end{notezh}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.53\linewidth,gobble=2]
  % \usepackage[draft]{suanpan}
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}[draft]
    \rods{0, 6, 12, 18, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{线宽选项}

\begin{option}{ opt = linewd, desc = {= \meta{线宽选项}}, init=2pt }
  设置算盘绘制中的线宽。
\end{option}

  \oarg{linewd}选项用于设置算盘边框内线线宽，同时会将
  边框外线设置为linewd的7.00倍，将档杆和算珠线宽
  设置为linewd的1.00倍。

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.40\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, linewd = 3pt}
  \begin{suanpan}
    \rods{0, 6, 12, 18, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{档位间距}

\begin{option}{ opt = rodsep, desc = {= \meta{档位间距}}, init=3.0pt }
  设置算盘各档间的间距。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.40\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, rodsep = 15pt}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

  \begin{notezh}
    修改档位间距会改变算盘排版的宽度。
  \end{notezh}

\subsection{算珠间距}

\begin{option}{ opt = bidsep, desc = {= \meta{算珠间距}}, init=1.8pt }
  设置算珠间的间距。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.40\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, bidsep = 4pt}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

  \begin{notezh}
    修改算珠间距不会改变算盘的尺寸，但算珠高度会发生变化。
    另外，过小的算珠高度会造成算珠圆角的畸变。
  \end{notezh}

\subsection{缩放比例}

\begin{option}{ opt = scale, desc = {= \meta{缩放比例}}, init=1.0 }
  设置算盘输出结果的整体缩放比例。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.40\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 1.20}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{边框颜色}

\begin{option}{ opt = framedraw, desc = {= \meta{边框颜色}}, init=black }
  设置算盘边框颜色。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, framedraw = brown3}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

  \begin{notezh}
    边框颜色包括内外边框和横梁颜色。
  \end{notezh}

\subsection{档杆绘制颜色}

\begin{option}{ opt = roddraw, desc = {= \meta{档杆绘制颜色}}, init=black }
  设置档杆绘制颜色。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, roddraw = brown4}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{档杆填充颜色}

\begin{option}{ opt = rodfill, desc = {= \meta{档杆填充颜色}}, init=white }
  设置档杆填充颜色。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, rodfill = brown6}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{外珠绘制颜色}

\begin{option}{ opt = outerdraw, desc = {= \meta{外珠绘制颜色}}, init=black }
  设置档杆上外珠\footnote{外珠是指离梁不记数的算珠。}绘制颜色。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, outerdraw = yellow4}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{外珠填充颜色}

\begin{option}{ opt = outerfill, desc = {= \meta{外珠填充颜色}}, init=white }
  设置外珠填充颜色。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, outerfill = yellow9}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{内珠绘制颜色}

\begin{option}{ opt = innerdraw, desc = {= \meta{内珠绘制颜色}}, init=black }
  设置档杆上内珠\footnote{内珠是指靠梁记数的算珠。}绘制颜色。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, innerdraw = red8}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{内珠填充颜色}

\begin{option}{ opt = innerfill, desc = {= \meta{内珠填充颜色}}, init=black}
  设置内珠填充颜色。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, innerfill = red9}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\bigskip

\changes{v1.1.1}{2024/08/30}{add English documentation.}

\title{
  \pkg{suanpan-l3} package for traditional Chinese 7-bids suanpan(abacus)
  \rlap{\makebox[4cm][r]{
    \normalsize $\Longrightarrow$ \color{red}
    \protect\hyperlink{zh}{中文版本}
    \protect\hypertarget{en}{}
  }}
}
\author{Nan Geng \texttt{<nangeng@nwafu.edu.cn>}}
\date{\today\qquad \vers}

\maketitle

\section{Introduction}

\pkg{suanpan-l3} is a traditional Chinese 7-bids suanpan drawing package
utilizes \pkg{l3draw} and is developed with \pkg{Expl3}. It can
effectively manage both upper and lower bids, while also considering
bottom bid, top bid, and hanging bid.

This package offers a unique environment for drawing suanpan,
denoted as \env{suanpan}. Within this environment, 7 specialized macros
are available for the creation of suanpan. The \tn{rod} macro is used
to lay out a single rod, while the \tn{rod*} macro draws a counting point
on this rod’s beam. The \tn{rods} macro is capable of laying out a set of rods.
The \tn{bid} macro colors the specified bid. The \tn{bids} macro colors
all inner bids that are near the beam, while the \tn{bids*} macro colors
all outer bids that are far from the beam. Lastly, the \tn{lrframe} macro
is used to lay out the left and right frames of an abacus.

At the same time, the package offers customization options for suanpan,
including line width, draw color, fill color, bid space, rod space, etc.
These can be configured through package options, \env{suanpan} environment
options, or the \tn{suanpanset} macro.

\begin{center}
  \begin{suanpan}[framedraw = brown2, scale = 0.45, bidsep=1.5pt,
                  roddraw = brown3, rodfill = brown4]
    % rod's val list
    \rods{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
    % counting point
    \rod*{4}{3}
    \rod*{18}{17}
    % top bid
    \bid{12}{9}{azure7}
    \bid{13}{9}{azure7}
    \bid{14}{9}{azure7}
    \bid{15}{9}{azure7}
    \bid{16}{9}{azure7}
    % hanging bid
    \bid{17}{11}{red8}
    \bid{18}{11}{red8}
    \bid{19}{11}{red8}
    \bid{20}{11}{red8}
    \bid{21}{11}{red8}
    % bottom bid
    \bid{11}{3}{olive7}
    \bid{16}{3}{olive7}
    \bid{21}{3}{olive7}
    \lrframe{1}{21}
  \end{suanpan}
\end{center}

\section{Interface}

\subsection{\env{suanpan} environment}

\begin{function}{suanpan}
  \begin{syntax}
    \tn{begin}|{suanpan}|\oarg{options}
    .....
    \tn{end}|{suanpan}|
  \end{syntax}
\end{function}

  Typesetting 7-bids Chinese suanpan with \oarg{options}.

  Within the \env{suanpan} environment, \tn{rod}, \tn{rod*}, \tn{rods}, \tn{bid},
  \tn{bids}, \tn{bids*} and \tn{lrframe} 7 specialized macros
  are available for the creation of suanpan.

  \oarg{options} is a key-value list for line width, draw color, fill color,
  bid space, rod space, etc.

  \oarg{options} is environment's local setting.

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rod{1}{0}
    \rod{2}{3}
    \rod{3}{0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{\env{suanpan}'s specialized macros}

\subsubsection{\tn{rod}---single rod}

\begin{function}{\rod}
  \begin{syntax}
    \cs{rod} \marg{num} \marg{val}
  \end{syntax}
\end{function}

  The \tn{rod} macro is used to lay out a single rod.

  The \marg{num} argument numbers the rods from left to right.
  The \marg{val} is the number to be represented on the rod from
  0 to 20. For number within [0, 9], it is represented using 4 lower deck
  bids and 1 upper deck bid. Numbers within [10, 15] are represented additionally
  using bottom bid and top bid. For numbers within [16, 20], hanging bid is also
  required for representation.

  The starred version \tn{rod*} will draw a counting point on this rod's beam.

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rod{1}{1}   % normal rod
    \rod{2}{6}
    \rod*{3}{10} % counting point and
                 % bottom bid
    \rod{4}{12}  % top bid
    \rod{5}{18}  % hanging bid
  \end{suanpan}
\end{SideBySideExample}

\subsubsection{\tn{rods}---a set of rods}

\begin{function}{\rods}
  \begin{syntax}
    \cs{rods} \marg{val list}
  \end{syntax}
\end{function}

  The \tn{rods} macro is used to lay out a set of rods.

  The \marg{val list} is a value list of each rod seperated by commas.
  Each rod number is automatically numbered from left to right.

  Each value in \marg{val list} is the number to be represented on the rod from
  0 to 20. For number within [0, 9], it is represented using 4 lower deck
  bids and 1 upper deck bid. Numbers within [10, 15] are represented additionally
  using bottom bid and top bid. For numbers within [16, 20], hanging bid is also
  required for representation.

  \begin{noteen}
    The starred version \tn{rods*} for counting point is not provided.
    Use the \tn{rod*} macro to overlay the specified rod for drawing.
  \end{noteen}

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rods{0, 6, 12, 18, 0}
    \rod*{3}{12}
  \end{suanpan}
\end{SideBySideExample}

\subsubsection{\tn{bid}---color bid}

\begin{function}{\bid}
  \begin{syntax}
    \cs{bid} \marg{num}\marg{pos}\marg{color}
  \end{syntax}
\end{function}

  The \tn{bid} macro fills the specified bid.

  The \marg{num} is the same as for \tn{rod}; the \marg{color} argument
  defines the fill color and the \marg{pos} argument tells which bid has to
  be colored in \marg{num} rod.

  This macro also blends \marg{color} by 40\% black to be used for bid
  drawing color.

  The \marg{pos} in a rod is numbered from the bottom up in the order
  $1, 2, \cdots, 11$. The lower deck bids occupies position
  $1, 2, \cdots, 7$, the upper deck bids occupies position $8, 9, 10$,
  and the hanging bead occupies position $11$ between $9$ and $10$ .

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rods{0, 0, 7, 11, 8, 19}
    \bid{1}{1}{gray7}
    \bid{2}{5}{gray7}
    \bid{3}{6}{red8}
    \bid{4}{7}{red8}
    \bid{4}{8}{azure6}
    \bid{4}{9}{yellow9}
    \bid{5}{10}{violet5}
    \bid{6}{11}{teal4}
  \end{suanpan}
\end{SideBySideExample}

\subsubsection{\tn{bids}---color inner/outer bids}

\begin{function}{\bids}
  \begin{syntax}
    \cs{bids} \marg{num}\marg{val}\marg{color}
  \end{syntax}
\end{function}

  The \tn{bids} macro fills all inner bids that are near the beam.

  \marg{num} and \marg{color} are the same as for \tn{bid};
  the \marg{val} argument is the same as for \tn{rod}.

  The \marg{color} is fill color for inner bids. it also blends
  \marg{color} by 40\% black to be used for inner bids drawing color.

  The starred version \tn{bids*} is used to color outer bids of \marg{num} rod.

  \begin{noteen}
    This macro can only select the inner bids or the outer bids for coloring,
    you can't select both the inner and outer bids at the same time.
  \end{noteen}

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rods{0, 0, 7, 11, 8, 19}
    \bids{3}{7}{teal4}
    \bids*{5}{8}{azure6}
  \end{suanpan}
\end{SideBySideExample}

\subsubsection{\tn{lrframe}---left and right frame}

\begin{function}{\lrframe}
  \begin{syntax}
    \cs{lrframe} \marg{first num}\marg{last num}
  \end{syntax}
\end{function}

  The \tn{lrframe} macro is used to lay out the left and right frames of
  a suanpan.

  The \marg{first num} argument tells which rod is the first rod and
  the \marg{last num} argument tells which rod is the last rod.

\begin{SideBySideExample}[frame=single,numbers=left,%
    xrightmargin=.48\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}
    \rods{0, 6, 12, 18, 0}
    \lrframe{1}{5}
  \end{suanpan}
\end{SideBySideExample}

\subsection{\tn{suanpanset}}

\begin{function}{\suanpanset}
  \begin{syntax}
    \cs{suanpanset} \marg{options}
  \end{syntax}
\end{function}

  The \tn{suanpanset} macro offers customization options for suanpan,
  including line width, draw color, fill color, bid space, rod space, etc.

  The \marg{options} is a key-value list.

  The \marg{options} seted by the \cs{suanpanset} are valid for
  all subsequent \env{suanpan} environments.

\section{options}

The \pkg{suanpan-l3} package offers customization options for abacus,
including line width, draw color, fill color, bid space, rod space, etc.
These can be configured through package \oarg{options}, \env{suanpan}
environment \oarg{options}, or the \tn{suanpanset} macro.

It is strongly recommended that suanpan options be set globally
for a document uniformly via \oarg{options} of packages to save compilation time.
Frequent use of \oarg{options} in \env{suanpan} environments or
use of the \tn{suanpanset} command to set suanpan options should be avoided.

The \oarg{options} is a comma-seperated list of options in the form
\marg{key}|=|\marg{value}. The \marg{value} can be omitted for some options.
For the same option, subsequent settings will override the previous one.

The \pkg{suanpan-l3} package uses \LaTeX3 style key settings,
supporting different types and levels of options. In the key list,
spaces around ``='' do not affect the settings.
However, it is important to note that blank lines are not allowed in the list.

The ``|=true|'' in the \marg{option}|=true| for Boolean types can be omitted.

\subsection{draft}

\begin{option}{ opt = draft, desc = {= \meta{draft}}, init=false }
  Draft mode.
\end{option}

The \oarg{draft} option speeds up compilation by canceling
  bids rounded corner effect.

  \begin{noteen}
    Suanpan layout in draft mode may differ from the desired layout.
  \end{noteen}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.53\linewidth,gobble=2]
  % \usepackage[draft]{suanpan}
  \centering
  \suanpanset{scale = 0.65}
  \begin{suanpan}[draft]
    \rods{0, 6, 12, 18, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{line width}

\begin{option}{ opt = linewd, desc = {= \meta{linewd}}, init=2pt }
  Drawing line width.
\end{option}

  The \oarg{linewd} is used to set the line width of the frame inner,
  and will also set the line width the frame outer to 7.00 times linewd,
  and the rod and bid line widths to 1.00 times linewd.

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.40\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, linewd = 3pt}
  \begin{suanpan}
    \rods{0, 6, 12, 18, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{rod spacing}

\begin{option}{ opt = rodsep, desc = {= \meta{rodsep}}, init=3.0pt }
  The spacing between suanpan rods.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.40\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, rodsep = 15pt}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

  \begin{noteen}
    The \oarg{rodsep} will change the width of the suanpan.
  \end{noteen}

\subsection{bid spacing}

\begin{option}{ opt = bidsep, desc = {= \meta{bidsep}}, init=1.8pt }
  The spacing between suanpan bids.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.40\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, bidsep = 4pt}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

  \begin{noteen}
    The \oarg{bidsep} does not change the size of the suanpan.
    But the height of each bid will be changed.
    In addition, too small an bid height will cause distortion
    of the rounded corners of the bid.
  \end{noteen}

\subsection{scale}

\begin{option}{ opt = scale, desc = {= \meta{scale}}, init=1.0 }
  Scaling factor of whole suanpan.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.40\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 1.20}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{frame color}

\begin{option}{ opt = framedraw, desc = {= \meta{framedraw}}, init=black }
  Frame drawing color.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, framedraw = brown3}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

  \begin{noteen}
    Frame colors include inner and outer of frame and beam colors.
  \end{noteen}

\subsection{rod drawing color}

\begin{option}{ opt = roddraw, desc = {= \meta{roddraw}}, init=black }
  Rod drawing color.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, roddraw = brown4}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{rod filling color}

\begin{option}{ opt = rodfill, desc = {= \meta{rodfill}}, init=white }
  Rod filling color.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, rodfill = brown6}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{outer bids drawing color}

\begin{option}{ opt = outerdraw, desc = {= \meta{outerdraw}}, init=black }
  The outer bids\footnote{The outer bid is that is not counted away from the beam.}drawing color.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, outerdraw = yellow4}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{outer bids filling color}

\begin{option}{ opt = outerfill, desc = {= \meta{outerfill}}, init=white }
  The outer bids filling color。
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, outerfill = yellow9}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{inner bids drawing color}

\begin{option}{ opt = innerdraw, desc = {= \meta{innerdraw}}, init=black }
  The inner bids\footnote{The inner bid is that is counted near to the beam.}drawing color.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, innerdraw = red8}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\subsection{inner bids filling color}

\begin{option}{ opt = innerfill, desc = {= \meta{innerfill}}, init=black}
  The inner bids filling color.
\end{option}

\begin{SideBySideExample}[frame=single,numbers=left,%
                xrightmargin=.37\linewidth,gobble=2]
  \centering
  \suanpanset{scale = 0.65, innerfill = red9}
  \begin{suanpan}
    \rods{0, 6, 0}
  \end{suanpan}
\end{SideBySideExample}

\end{documentation}

\end{document}
