summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/zhnumber
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/zhnumber
Initial commit
Diffstat (limited to 'macros/latex/contrib/zhnumber')
-rw-r--r--macros/latex/contrib/zhnumber/README.md65
-rw-r--r--macros/latex/contrib/zhnumber/zhnumber.dtx1955
-rw-r--r--macros/latex/contrib/zhnumber/zhnumber.ins89
-rw-r--r--macros/latex/contrib/zhnumber/zhnumber.pdfbin0 -> 270690 bytes
4 files changed, 2109 insertions, 0 deletions
diff --git a/macros/latex/contrib/zhnumber/README.md b/macros/latex/contrib/zhnumber/README.md
new file mode 100644
index 0000000000..a8ac1b7a7c
--- /dev/null
+++ b/macros/latex/contrib/zhnumber/README.md
@@ -0,0 +1,65 @@
+zhnumber
+========
+
+The `zhnumber` package provides commands to typeset Chinese representations of
+numbers. The main difference between this package and `CJKnumb` is that commands
+provided by this package is expandable in the proper way. So, it seems that
+zhnumber is a good alternative to `CJKnumb` package.
+
+Basic Usage
+-----------
+The package provides the following macros:
+
+ \zhnumber{<number>}
+
+Convert `<number>` to a full Chinese representation.
+
+ \zhnum{<counter>}
+
+Similar to `\arabic{<counter>}`, but representation of `<counter>`
+as Chinese numerals.
+
+ \zhdigits{<number>}
+ \zhdigits*{<number>}
+
+Handle `<number>` as a string of digits and convert each of them into the
+corresponding Chinese digit. The starred version uses the Chinese circle glyph
+for digit zero; the unstarred version uses the traditional glyph.
+
+You can read the package manual (in Chinese) for more detailed explanations.
+
+Contributing
+------------
+
+This package is a part of the [ctex-kit](https://github.com/CTeX-org/ctex-kit) project.
+
+Issues and pull requests are welcome.
+
+Copyright and Licence
+---------------------
+
+ Copyright (C) 2012, 2014-2019 by Qing Lee <sobenlee@gmail.com>
+ ----------------------------------------------------------------------
+
+ This work may be distributed and/or modified under the
+ conditions of the LaTeX Project Public License, either
+ version 1.3c of this license or (at your option) any later
+ version. This version of this license is in
+ http://www.latex-project.org/lppl/lppl-1-3c.txt
+ and the latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+ and version 1.3 or later is part of all distributions of
+ LaTeX version 2005/12/01 or later.
+
+ This work has the LPPL maintenance status `maintained'.
+
+ The Current Maintainer of this work is Qing Lee.
+
+ This package consists of the file zhnumber.dtx,
+ and the derived files zhnumber.pdf,
+ zhnumber.sty,
+ zhnumber-utf8.cfg,
+ zhnumber-gbk.cfg,
+ zhnumber-big5.cfg,
+ zhnumber.ins and
+ README.md (this file).
diff --git a/macros/latex/contrib/zhnumber/zhnumber.dtx b/macros/latex/contrib/zhnumber/zhnumber.dtx
new file mode 100644
index 0000000000..05472f8fd1
--- /dev/null
+++ b/macros/latex/contrib/zhnumber/zhnumber.dtx
@@ -0,0 +1,1955 @@
+% \iffalse meta-comment
+% !TEX program = XeLaTeX
+%<*internal>
+\iffalse
+%</internal>
+%<*readme>
+zhnumber
+========
+
+The `zhnumber` package provides commands to typeset Chinese representations of
+numbers. The main difference between this package and `CJKnumb` is that commands
+provided by this package is expandable in the proper way. So, it seems that
+zhnumber is a good alternative to `CJKnumb` package.
+
+Basic Usage
+-----------
+The package provides the following macros:
+
+ \zhnumber{<number>}
+
+Convert `<number>` to a full Chinese representation.
+
+ \zhnum{<counter>}
+
+Similar to `\arabic{<counter>}`, but representation of `<counter>`
+as Chinese numerals.
+
+ \zhdigits{<number>}
+ \zhdigits*{<number>}
+
+Handle `<number>` as a string of digits and convert each of them into the
+corresponding Chinese digit. The starred version uses the Chinese circle glyph
+for digit zero; the unstarred version uses the traditional glyph.
+
+You can read the package manual (in Chinese) for more detailed explanations.
+
+Contributing
+------------
+
+This package is a part of the [ctex-kit](https://github.com/CTeX-org/ctex-kit) project.
+
+Issues and pull requests are welcome.
+
+Copyright and Licence
+---------------------
+
+ Copyright (C) 2012, 2014-2019 by Qing Lee <sobenlee@gmail.com>
+ ----------------------------------------------------------------------
+
+ This work may be distributed and/or modified under the
+ conditions of the LaTeX Project Public License, either
+ version 1.3c of this license or (at your option) any later
+ version. This version of this license is in
+ http://www.latex-project.org/lppl/lppl-1-3c.txt
+ and the latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+ and version 1.3 or later is part of all distributions of
+ LaTeX version 2005/12/01 or later.
+
+ This work has the LPPL maintenance status `maintained'.
+
+ The Current Maintainer of this work is Qing Lee.
+
+ This package consists of the file zhnumber.dtx,
+ and the derived files zhnumber.pdf,
+ zhnumber.sty,
+ zhnumber-utf8.cfg,
+ zhnumber-gbk.cfg,
+ zhnumber-big5.cfg,
+ zhnumber.ins and
+ README.md (this file).
+%</readme>
+%<*internal>
+\fi
+\begingroup
+ \def\temp{LaTeX2e}
+\expandafter\endgroup\ifx\temp\fmtname\else
+\csname fi\endcsname
+%</internal>
+%<*install>
+
+\input ctxdocstrip %
+
+\preamble
+
+ Copyright (C) 2012, 2014-2019 by Qing Lee <sobenlee@gmail.com>
+--------------------------------------------------------------------------
+
+ This work may be distributed and/or modified under the
+ conditions of the LaTeX Project Public License, either
+ version 1.3c of this license or (at your option) any later
+ version. This version of this license is in
+ http://www.latex-project.org/lppl/lppl-1-3c.txt
+ and the latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+ and version 1.3 or later is part of all distributions of
+ LaTeX version 2005/12/01 or later.
+
+ This work has the LPPL maintenance status `maintained'.
+
+ The Current Maintainer of this work is Qing Lee.
+
+--------------------------------------------------------------------------
+
+\endpreamble
+\postamble
+
+ This package consists of the file zhnumber.dtx,
+ and the derived files zhnumber.pdf,
+ zhnumber.sty,
+ zhnumber-utf8.cfg,
+ zhnumber-gbk.cfg,
+ zhnumber-big5.cfg,
+ zhnumber.ins and
+ README.md.
+\endpostamble
+
+\generate
+ {
+%</install>
+%<*internal>
+ \usedir{source/latex/zhnumber}
+ \file{zhnumber.ins} {\from{\jobname.dtx}{install}}
+%</internal>
+%<*install>
+ \usedir{tex/latex/zhnumber}
+ \file{zhnumber.sty} {\from{\jobname.dtx}{package}}
+ \usedir{tex/latex/zhnumber/config}
+ \file{zhnumber-utf8.cfg} {\from{\jobname.dtx}{config,utf8}}
+ \file{zhnumber-big5.cfg} {\from{\jobname.dtx}{config,big5}}
+ \file{zhnumber-gbk.cfg} {\from{\jobname.dtx}{config,gbk}}
+ \nopreamble\nopostamble
+ \usedir{doc/latex/zhnumber}
+ \file{README.md} {\from{\jobname.dtx}{readme}}
+ }
+
+\endbatchfile
+%</install>
+%<*internal>
+\fi
+%</internal>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\RequirePackage{expl3}
+%<+package|config>\GetIdInfo$Id: zhnumber.dtx 311c61d 2019-04-07 23:29:51 +0800 Qing Lee <sobenlee@gmail.com> $
+%<package> {Typesetting numbers with Chinese glyphs}
+%<config&utf8> {Chinese numerals with UTF8 encoding}
+%<config&big5> {Chinese numerals with Big5 encoding}
+%<config&gbk> {Chinese numerals with GBK encoding}
+%<package>\ProvidesExplPackage{\ExplFileName}
+%<config&utf8>\ProvidesExplFile{\ExplFileName-utf8.cfg}
+%<config&big5>\ProvidesExplFile{\ExplFileName-big5.cfg}
+%<config&gbk>\ProvidesExplFile{\ExplFileName-gbk.cfg}
+%<package|config> {\ExplFileDate}{2.7}{\ExplFileDescription}
+%<*driver>
+\documentclass{ctxdoc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+ \IndexLayout
+ \PrintIndex
+\end{document}
+%</driver>
+% \fi
+%
+% \CheckSum{1186}
+% \GetFileId{zhnumber.sty}
+%
+% \title{\bfseries\pkg{zhnumber} 宏包}
+% \author{李清\\ \path{sobenlee@gmail.com}}
+% \date{\filedate\qquad\fileversion\thanks{\ctexkitrev{\ExplFileVersion}.}}
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{简介}
+% \pkg{zhnumber} 宏包用于将阿拉伯数字按照中文格式输出。相比于 \pkg{CJKnumb},它提供
+% 的四个格式转换命令 \tn{zhnumber},\tn{zhdigits}、\tn{zhnum} 和 \tn{zhdig}
+% 都是可以适当展开的,可以正常使用于 |PDF| 书签和交叉引用。
+%
+% \pkg{zhnumber} 支持 |GBK|,|Big5| 和 |UTF8| 编码,依赖 \LaTeXiii{} 项目的
+% \pkg{expl3},\pkg{xparse} 和 \pkg{l3keys2e} 宏包。
+%
+% \section{使用方法}
+%
+% \begin{function}[updated=2014-09-09]{encoding}
+% \begin{syntax}
+% encoding = <GBK|Big5|UTF8>
+% \end{syntax}
+% 用于指定编码的宏包选项,可以在调用宏包的时候设定,也可以用 \tn{zhnumsetup}
+% 在导言区内设定。对于 \upLaTeX、\XeLaTeX{} 和 \LuaLaTeX,不用指定编码,宏包将
+% 自动使用 |UTF8| 编码。只有 \LaTeX{} 和 \pdfLaTeX{} 需要指定编码,如果没有指定,
+% 默认将使用 |GBK|。
+% \end{function}
+%
+% \begin{function}[rEXP, updated=2014-09-12]{\zhnumber}
+% \begin{syntax}
+% \tn{zhnumber} \Arg{number}
+% \end{syntax}
+% 以中文格式输出数字。这里的数字可以是整数、小数和分数。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhnumber{2012020120}\\
+% \zhnumber{2 012 020 120}\\
+% \zhnumber{2,012,020,120}\\
+% \zhnumber{2012.020120}\\
+% \zhnumber{2012.}\\
+% \zhnumber{.2012}\\
+% \zhnumber{20120/20120}\\
+% \zhnumber{/2012}\\
+% \zhnumber{2012/}\\
+% \zhnumber{201;2020/120}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, updated=2014-09-09]{\zhdigits}
+% \begin{syntax}
+% \tn{zhdigits} \Arg{number}
+% \tn{zhdigits} * \Arg{number}
+% \end{syntax}
+% 将阿拉伯数字转换为中文数字串。缺省状态下,\tn{zhdigits} 将 0 映射为〇,如果需要
+% 将其映射为零,可以使用带星号的形式。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhdigits{2012020120}\\
+% \zhdigits*{2012020120}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, updated=2016-05-01]{\zhnum}
+% \begin{syntax}
+% \tn{zhnum} \Arg{counter}
+% \tn{pagenumbering} \{zhnum\}
+% \end{syntax}
+% 与 |\roman| 等类似,用于将 \LaTeX 计数器的值转换为中文数字。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhnum{section}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2016-05-01]{\zhdig}
+% \begin{syntax}
+% \tn{zhdig} \Arg{counter}
+% \tn{pagenumbering} \{zhdig\}
+% \end{syntax}
+% 与 |\roman| 等类似,用于将 \LaTeX 计数器的值转换为中文数字串。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhdig{section}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2012-05-25]{\zhweekday}
+% \begin{syntax}
+% \tn{zhweekday} \Arg{yyyy/mm/dd}
+% \end{syntax}
+% 输出日期当天的星期。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhweekday{2012/5/20}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2012-05-25]{\zhdate}
+% \begin{syntax}
+% \tn{zhdate} \Arg{yyyy/mm/dd}
+% \tn{zhdate} * \Arg{yyyy/mm/dd}
+% \end{syntax}
+% 以中文格式输出日期,其中带 |*| 的命令还输出星期。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhdate{2012/5/21}\\
+% \zhdate*{2012/5/21}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2012-05-25]{\zhtoday}
+% 与 |\today| 类似,以中文输出当天的日期。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhtoday
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2012-05-25]{\zhtime}
+% \begin{syntax}
+% \tn{zhtime} \Arg{hh:mm}
+% \end{syntax}
+% 以中文格式输出时间。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhtime{23:56}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2012-05-25]{\zhcurrtime}
+% 输出当前的时间。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhcurrtime
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2015-05-20]{\zhtiangan}
+% \begin{syntax}
+% \tn{zhtiangan} \Arg{number}
+% \end{syntax}
+% 输出对应的天干计数。\meta{number} 的正常范围是 1--10,超出范围的数字将输出空值。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.4\linewidth,gobble=5]
+% \zhtiangan{1} \zhtiangan{2} \zhtiangan{3}
+% \zhtiangan{4} \zhtiangan{5} \zhtiangan{10}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2015-05-20]{\zhdizhi}
+% \begin{syntax}
+% \tn{zhdizhi} \Arg{number}
+% \end{syntax}
+% 输出对应的地支计数。\meta{number} 的正常范围是 1--12,超出范围的数字将输出空值。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.4\linewidth,gobble=5]
+% \zhdizhi{1} \zhdizhi{2} \zhdizhi{3}
+% \zhdizhi{4} \zhdizhi{5} \zhdizhi{12}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2015-05-20]{\zhganzhi}
+% \begin{syntax}
+% \tn{zhganzhi} \Arg{number}
+% \end{syntax}
+% 输出对应的干支计数。\meta{number} 的正常范围是 1--60,超出范围的数字将输出空值。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.4\linewidth,gobble=5]
+% \zhganzhi{1} \zhganzhi{2} \zhganzhi{3} \\
+% \zhganzhi{4} \zhganzhi{5} \zhganzhi{60}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[rEXP, added=2015-05-20]{\zhganzhinian}
+% \begin{syntax}
+% \tn{zhganzhinian} \Arg{year}
+% \end{syntax}
+% 输出公元纪年 \meta{year} 对应的干支纪年。公元前的年份用负数表示。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.4\linewidth,gobble=5]
+% \zhganzhinian{1898} \zhganzhinian{-246} \\
+% \zhganzhinian{-2697} \zhganzhinian{\year}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[added=2012-05-25]{\zhnumExtendScaleMap}
+% \begin{syntax}
+% \tn{zhnumExtendScaleMap} \oarg{character} \{<character_1>, <character_2>, ..., <character_n>\}
+% \end{syntax}
+% 缺省状态下 \tn{zhnumber} 能正确中文格式化的最大整数是 $10^{48}-1$,\tn{zhdigits} 不受
+% 这个大小的限制。可以通过 \tn{zhnumExtendScaleMap} 来扩展 \tn{zhnumber}。
+% \meta{character_i} 设置 $10^{4(i+11)}$。若给出可选项 \meta{character},则当
+% 数字大于 $10^{4(n+12)}-1$ 时,统一用 \meta{character} 设置输出数字的进位。
+% \end{function}
+%
+% \begin{function}{\zhnumsetup}
+% \begin{syntax}
+% \tn{zhnumsetup} \{<key_1>=<val_1>, <key_2>=<val_2>, ...\}
+% \end{syntax}
+% 用于在导言区或文档中,设置中文数字的输出格式。目前可以设置的 \meta{key} 如下介绍。
+% 以\textbf{粗体}表示选项的默认值。
+% \end{function}
+%
+% \begin{function}[added=2012-05-25]{time}
+% \begin{syntax}
+% time = <(Arabic)|Chinese>
+% \end{syntax}
+% 设置日期和时间的数字格式,\meta{Arabic} 为阿拉伯数字,而 \meta{Chinese} 为中文数字。
+% 例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
+% \zhnumsetup{time=Chinese}
+% \zhtoday\zhcurrtime
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}[added=2016-05-01]{arabicsep}
+% \begin{syntax}
+% arabicsep = \Arg{sep}
+% \end{syntax}
+% 设置日期和时间的数字格式为阿拉伯数字时,阿拉伯数字与汉字的间隔内容。默认为一个空格。
+% \end{function}
+%
+% \begin{function}[updated=2012-05-25]{style}
+% \begin{syntax}
+% style = <(Simplified)|Traditional|(Normal)|Financial|Ancient>
+% \end{syntax}
+% 意义分别为
+%
+% \begin{description}[font=\mdseries\ttfamily\small,align=right,leftmargin=*,
+% labelsep=\marginparsep,labelindent=-\marginparsep]
+% \item[Simplified] 以简体中文输出数字(对 |Big5| 编码无效);
+% \item[Traditional] 以繁体中文输出数字(对 |Big5| 编码无效);
+% \item[Normal] 以小写形式输出中文数字;
+% \item[Financial] 以大写形式输出中文数字;
+% \item[Ancient] 以廿输出 20,以卅输出 30,以卌输出 40,以皕输出 200。
+% \end{description}
+%
+% 可以设置 |style| 为其中一个,也可以是前三个与后两个的适当组合,默认是简体小写。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.4\linewidth,gobble=5]
+% \zhnumsetup{style={Traditional,Financial}}
+% \zhnumber{62012.3}\\
+% \zhnumsetup{style=Ancient}
+% \zhnumber{21}
+% \end{SideBySideExample}
+% \end{function}
+%
+% \begin{function}{null}
+% \begin{syntax}
+% null = <\TFF>
+% \end{syntax}
+% 缺省状态下,除了 \tn{zhdigits} 外,其它的格式转换命令,将 0 映射成零,如果需要将 0 映射
+% 成〇,可以使用这个选项。
+% \end{function}
+%
+% \begin{function}[added=2015-05-20]{ganzhi-cyclic}
+% \begin{syntax}
+% ganzhi-cyclic = <\TFF>
+% \end{syntax}
+% 天干、地支和干支的数字都有一定范围。若参数大于这个范围,\tn{tiangan} 等将输出空值。
+% 可以将本选项设置为 |true|,对超出范围的数字取相应的模。
+% 请注意,数字 |0| 的结果总是为空值。例如
+% \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.3\linewidth,gobble=5]
+% \zhnumsetup{ganzhi-cyclic}
+% \zhtiangan{11} \zhtiangan{12} \zhtiangan{209}
+% \zhtiangan{-1} \zhtiangan{-2} \zhtiangan{-683} \\
+% \zhdizhi{13} \zhdizhi{24} \zhdizhi{1211}
+% \zhdizhi{-1} \zhdizhi{-2} \zhdizhi{-8199} \\
+% \zhganzhi{61} \zhganzhi{72} \zhganzhi{2158} \\
+% \zhganzhi{-1} \zhganzhi{-2} \zhganzhi{-789}
+% \end{SideBySideExample}
+% \end{function}
+%
+%\bigskip
+% \pkg{zhnumber} 提供下列选项来控制阿拉伯数字的中文映射。
+% \begin{verbatim}[frame=single]
+% - -0 0 1 2 3 4 5 6 7 8 9 10 20 30 40 100 200 1000
+% E2 E3 E4 E8 E12 E16 E20 E24 E28 E32 E36 E40 E44
+% F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F100 F1000 FE2 FE3
+% T1 T2 T3 T4 T5 T6 T7 T8 T9 T10
+% D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12
+% GZ1 GZ2 GZ3 GZ4 GZ5 GZ6 GZ7 GZ8 GZ9 GZ10 ... GZ60
+% dot and parts
+% year month day hour minute weekday mon tue wed thu fri sat sun
+% \end{verbatim}
+% 其中 |-| 设置负,|-0| 设置〇,|dot| 设置小数的点,|and| 和 |parts| 分别设置分数
+% 的“又”和“分之”,|E|$n$ 设置 $10^n$,|F|$n$ 设置数字 $n$ 的大写,|T|$n$ 设置
+% 数字 $n$ 的天干,|D|$n$ 设置数字 $n$ 的地支,而 |GZ|$n$ 设置数字 $n$ 的干支。
+% 其它的选项同字面意思,不再赘述。例如
+% \begin{verbatim}[frame=single]
+% \zhnumsetup{2={两}}
+% \end{verbatim}
+% 可以将 2 映射成两。需要说明的是,\pkg{zhnumber} 将优先使用这里的设置,所以可能会影响
+% 到 |style| 选项。如果要恢复 |style| 的功能,可以使用 |reset| 选项。
+%
+% \begin{function}[updated=2014-09-12]{reset}
+% \begin{syntax}
+% reset
+% \end{syntax}
+% 用于恢复 \pkg{zhnumber} 对阿拉伯数字的初始化映射。\pkg{zhnumber} 的中文数字初始化
+% 设置见源代码(第 \ref{sec:zhnum-map} 节)。
+% \end{function}
+%
+% \begin{function}[added=2014-09-09]{activechar}
+% \begin{syntax}
+% activechar = <\TTF>
+% \end{syntax}
+% 在 \LaTeX{} 或者 \pdfLaTeX{} 下面输出汉字,传统的办法需要将汉字的首字节设置为
+% 活动字符,然后再通过特殊的宏技巧来实现。因此,\pkg{zhnumber} 在载入配置文件的
+% 时候,默认会将汉字的首字节设置为活动字符。禁用本选项将不会改变汉字首字节的
+% 类代码。需要在本选项之后,使用 \texttt{encoding} 或者 \texttt{reset} 选项
+% 才会有效果。
+% \end{function}
+%
+% \begin{function}[updated=2016-05-01]{\zhnumber,\zhdigits,\zhnum,\zhdig}
+% \begin{syntax}
+% \tn{zhnumber} \oarg{options} \Arg{number}
+% \tn{zhdigits} * \oarg{options} \Arg{number}
+% \tn{zhnum} \oarg{options} \Arg{counter}
+% \tn{zhdig} \oarg{options} \Arg{counter}
+% \end{syntax}
+% 如果只改变当前数字的中文输出格式,可以使用带选项的格式转换命令,其中 \meta{options}
+% 与 \tn{zhnumsetup} 的参数相同,如上所介绍。这些带了选项的命令是不可展开的,在某些场合使
+% 用时要小心。
+% \end{function}
+%
+% \end{documentation}
+%
+% \StopEventually{}
+%
+% \begin{implementation}
+%
+% \section{\pkg{zhnumber} 宏包代码实现}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=zhnum>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnn { zhnumber } { l3-too-old }
+ {
+ Support~package~'expl3'~too~old. \\\\
+ Please~update~an~up~to~date~version~of~the~bundles\\\\
+ 'l3kernel'~and~'l3packages'\\\\
+ using~your~TeX~package~manager~or~from~CTAN.
+ }
+\@ifpackagelater { expl3 } { 2019/03/05 } { }
+ { \msg_error:nn { zhnumber } { l3-too-old } }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\RequirePackage { xparse , l3keys2e }
+% \end{macrocode}
+%
+% \begin{macro}{\zhnumber}
+% 用于将输入的数字按照中文格式输出。
+% \begin{macrocode}
+\DeclareExpandableDocumentCommand \zhnumber { +o +m }
+ {
+ \IfNoValueTF {#1}
+ { \zhnum_number:f }
+ { \zhnumberwithoptions {#1} }
+ {#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnumberwithoptions}
+% 带选项的用户函数。
+% \begin{macrocode}
+ \NewDocumentCommand \zhnumberwithoptions { +m +m }
+ {
+ \group_begin:
+ \keys_set:nn { zhnum / options } {#1}
+ \zhnum_number:f {#2}
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_number:n}
+% \begin{macro}{\@@_number:www}
+% 先判断输入的是小数还是分数。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_number:n #1
+ { \@@_number:www #1 . \q_nil . \q_stop }
+\cs_new:Npn \@@_number:www #1 . #2 . #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \@@_integer_or_fraction:www #1 / \q_nil / \q_stop }
+ { \zhnum_decimal:nn {#1} {#2} }
+ }
+\cs_generate_variant:Nn \zhnum_number:n { f }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_integer_or_fraction:www}
+% 判断是否输入的是分数。
+% \begin{macrocode}
+\cs_new:Npn \@@_integer_or_fraction:www #1 / #2 / #3 \q_stop
+ {
+ \quark_if_nil:nTF {#2}
+ { \zhnum_integer:n {#1} }
+ { \@@_fraction:wwww #2 \q_mark #1 ; \q_nil ; \q_stop }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_fraction:wwww}
+% 对分数进行预处理。
+% \begin{macrocode}
+\cs_new:Npn \@@_fraction:wwww #1 \q_mark #2 ; #3 ; #4 \q_stop
+ {
+ \quark_if_nil:nTF {#3}
+ {
+ \zhnum_blank_to_zero:n {#1}
+ \c_@@_parts_tl
+ \zhnum_blank_to_zero:n {#2}
+ }
+ {
+ \tl_if_blank:nF {#2}
+ {
+ \zhnum_number:n {#2}
+ \c_@@_and_tl
+ }
+ \zhnum_blank_to_zero:n {#1}
+ \c_@@_parts_tl
+ \zhnum_blank_to_zero:n {#3}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_decimal:nn}
+% 对小数进行预处理。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_decimal:nn #1#2
+ {
+ \zhnum_blank_to_zero:n {#1} \c_@@_dot_tl
+ \tl_if_blank:nTF {#2}
+ { \c_@@_zero_tl }
+ { \zhnum_digits_zero:n {#2} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_blank_to_zero:n}
+% 输出小数的整数位。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_blank_to_zero:n #1
+ {
+ \tl_if_blank:nTF {#1}
+ { \c_@@_zero_tl }
+ { \zhnum_number:n {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhnum,\zhnumberwithoptions}
+% 用于将 \LaTeX{} 计数器按中文格式输出。
+% \begin{macrocode}
+\DeclareExpandableDocumentCommand \zhnum { +o +m }
+ {
+ \IfNoValueTF {#1}
+ { \zhnum_counter:n }
+ { \zhnumwithoptions {#1} }
+ {#2}
+ }
+\NewDocumentCommand \zhnumwithoptions { +m +m }
+ {
+ \group_begin:
+ \keys_set:nn { zhnum / options } {#1}
+ \zhnum_counter:n {#2}
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_counter:n, \zhnum_int:n}
+% 可以直接通过比较 \LaTeX{} 计数器的值来得到符号和绝对值。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_counter:n #1
+ {
+ \int_if_exist:cTF { c@#1 }
+ { \exp_args:Nc \zhnum_int:n { c@#1 } }
+ { \@@_counter_error:n {#1} }
+ }
+\cs_new:Npn \@@_counter_error:n #1
+ { \msg_expandable_error:nnn { zhnumber } { not-counter } {#1} }
+\msg_new:nnn { zhnumber } { not-counter }
+ { `#1'~is~not~a~LaTeX~counter. }
+\cs_new:Npn \zhnum_int:n #1
+ {
+ \int_compare:nNnTF {#1} > \c_zero_int
+ { \zhnum_parse_number:f { \int_eval:n {#1} } }
+ {
+ \int_compare:nNnTF {#1} < \c_zero_int
+ {
+ \c_@@_minus_tl
+ \zhnum_parse_number:f { \int_eval:n { - #1 } }
+ }
+ { \c_@@_zero_tl }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@zhnum}
+% 用于支持 |\pagenumbering{zhnum}|。
+% \begin{macrocode}
+\cs_new_nopar:Npn \@zhnum { \zhnum_int:n }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_integer:n}
+% 对整数的处理。这个函数基本抄录自 \pkg{l3bigint} 的 \cs{__bingint_read_do:nn}。它可以
+% 正确取得符号,去掉多余的零,还可以循环展开数字。但它在遇到非数字的时候就停止了
+% 循环,我们可能需要非数字(例如逗号)来作为分隔符号。因此对它略作修改,跳过非数字。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_integer:n #1
+ {
+ \exp_after:wN \@@_read_integer:www
+ \int_value:w
+ \exp_after:wN \@@_read_sign_loop:N
+ \exp:w \exp_end_continue_f:w \use:n
+ #1 \exp_stop_f: \q_recursion_tail \q_recursion_stop
+ \@@_result:nn { \c_zero_int } { } ;
+ }
+\cs_new:Npn \@@_read_sign_loop:N #1
+ {
+ \if:w + \if:w - \exp_not:N #1 + \fi: \exp_not:N #1
+ \exp_after:wN \@@_read_sign_loop:N
+ \exp:w \exp_end_continue_f:w \exp_after:wN \use:n
+ \else:
+ 1 \exp_after:wN ;
+ \exp:w \exp_end_continue_f:w
+ \exp_after:wN \@@_read_zeros_loop:N
+ \exp_after:wN #1
+ \fi:
+ }
+\cs_new:Npn \@@_read_zeros_loop:N #1
+ {
+ \if:w 0 \exp_not:N #1
+ \exp_after:wN \@@_read_zeros_loop:N
+ \exp:w \exp_end_continue_f:w \exp_after:wN \use:n
+ \else:
+ \exp_after:wN \@@_read_abs_loop:Nw
+ \exp_after:wN #1
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_read_abs_loop:Nw}
+% 当数字很大时,\pkg{l3bigint} 的实现会造成 \TeX{} 内存溢出:
+% \begin{verbatim}
+% ! TeX capacity exceeded, sorry [expansion depth=10000].
+% \end{verbatim}
+% 我们在这里参考 \cs{__tl_act:NNNnn} 的实现对它进行了改进。
+% \begin{macrocode}
+\cs_new:Npn \@@_read_abs_loop:Nw #1#2 \q_recursion_stop
+ {
+ \zhnum_if_digit:NTF #1
+ { \@@_output:nnwnn { + 1 } #1 }
+ { \quark_if_recursion_tail_stop_do:Nn #1 { \@@_loop_end:wnn } }
+ \exp_after:wN \@@_read_abs_loop:Nw
+ \exp:w \exp_end_continue_f:w \use:n #2 \q_recursion_stop
+ }
+\cs_new:Npn \@@_output:nnwnn #1#2#3 \@@_result:nn #4#5
+ { #3 \@@_result:nn { #4#1 } { #5#2 } }
+\cs_new:Npn \@@_loop_end:wnn #1 \@@_result:nn #2#3
+ { \int_eval:n {#2} ; #3 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_read_integer:www}
+% |#1| 符号,|#3| 是绝对值,|#2| 是绝对值的长度。
+% \begin{macrocode}
+\cs_new:Npn \@@_read_integer:www #1 ; #2 ; #3 ;
+ {
+ \int_compare:nNnTF {#2} = \c_zero_int
+ { \c_@@_zero_tl }
+ {
+ \int_compare:nNnF {#1} = \c_one_int
+ { \c_@@_minus_tl }
+ \zhnum_parse_number:nn {#2} {#3}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_if_digit:NTF}
+% 判断 |#1| 是否为数字位。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_if_digit:NTF #1
+ {
+ \if_int_compare:w 9 < 1 \exp_not:N #1 \exp_stop_f:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% \zhnum_parse_number:n,
+% \zhnum_parse_number:nn
+% }
+% \begin{macrocode}
+\cs_new:Npn \zhnum_parse_number:n #1
+ { \exp_args:Nf \zhnum_parse_number:nn { \tl_count:n {#1} } {#1} }
+\cs_new:Npn \zhnum_parse_number:nn #1
+ { \exp_args:Nf \@@_parse_number:nnn { \int_mod:nn {#1} { 4 } } {#1} }
+\cs_new:Npn \@@_parse_number:nnn #1#2
+ {
+ \int_compare:nNnTF {#2} < 2
+ { \zhnum_digit_map:n }
+ {
+ \int_compare:nNnTF {#1} = \c_zero_int
+ { \zhnum_split_number:fn { \int_eval:n { #2 / 4 - 1 } } }
+ { \@@_split_number_aux:nnn {#1} {#2} }
+ }
+ }
+\cs_generate_variant:Nn \zhnum_parse_number:n { f }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_split_number_aux:nnn}
+% 为了处理的方便,在整数前面补上适当的 $0$,使其位数可以被 $4$ 整除。
+% \begin{macrocode}
+\cs_new:Npn \@@_split_number_aux:nnn #1#2
+ {
+ \exp_after:wN \@@_split_number_aux:wwn
+ \int_value:w \int_div_truncate:nn {#2} { 4 }
+ \if_case:w #1 \exp_stop_f:
+ \or: \exp_after:wN \use:n
+ \or: \exp_after:wN \use_i_ii:nnn
+ \or: \exp_after:wN \use_i:nnn
+ \fi:
+ { \exp_stop_f: ; 0 } 0 0 ;
+ }
+\cs_new:Npn \@@_split_number_aux:wwn #1 ; #2 ; #3
+ { \zhnum_split_number:nn {#1} { #2#3 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_split_number:nn}
+% 最后加入的 \cs{q_recursion_tail} 是停止递归的标志,而 \cs{q_nil} 用于占位。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_split_number:nn #1#2
+ {
+ \zhnum_split_number:NNnNNNNw \c_true_bool \c_true_bool {#1}
+ #2 \q_recursion_tail \q_nil \q_nil \q_nil \q_recursion_stop
+ }
+\cs_generate_variant:Nn \zhnum_split_number:nn { f }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_split_number:NNnNNNNw}
+% 将输入的整数由高位到低位,以四位为一段进行处理。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_split_number:NNnNNNNw #1#2#3#4#5#6#7
+ {
+ \quark_if_recursion_tail_stop:N #4
+ \int_compare:nNnTF { #4#5#6#7 } = \c_zero_int
+ { \use_i:nn }
+ {
+ \bool_if:NF #1 { \c_@@_zero_tl }
+ \zhnum_process_number:NNNNNN #4#5#6#7#1#2
+ \zhnum_scale_map:n {#3}
+ \int_compare:nNnTF {#7} = \c_zero_int
+ }
+ { \zhnum_split_number:NNfNNNNw \c_false_bool \c_true_bool }
+ { \zhnum_split_number:NNfNNNNw \c_true_bool \c_false_bool }
+ { \int_eval:n { #3 - 1 } }
+ }
+\cs_generate_variant:Nn \zhnum_split_number:NNnNNNNw { NNf }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_process_number:NNNNNN}
+% 对四位数字按情况进行处理。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_process_number:NNNNNN #1#2#3#4#5#6
+ {
+ \int_compare:nNnTF {#1} = \c_zero_int
+ { \bool_if:NF #6 { \c_@@_zero_tl } }
+ { \zhnum_digit_map:n {#1} \c_@@_thousand_tl }
+ \int_compare:nNnTF {#2} = \c_zero_int
+ { \int_compare:nNnF { #1 * (#3#4) } = \c_zero_int { \c_@@_zero_tl } }
+ {
+ \bool_lazy_and:nnTF
+ { \l_@@_ancient_bool }
+ { \int_compare_p:nNn {#2} = 2 }
+ { \zhnum_digit_map:n { #2 00 } }
+ { \zhnum_digit_map:n {#2} \c_@@_hundred_tl }
+ }
+ \int_compare:nNnTF {#3} = \c_zero_int
+ { \int_compare:nNnF { #2 * #4 } = \c_zero_int { \c_@@_zero_tl } }
+ {
+ \bool_lazy_all:nF
+ {
+ { \int_compare_p:nNn {#3} = \c_one_int }
+ { \int_compare_p:nNn {#1#2} = \c_zero_int }
+ {#6}
+ {#5}
+ }
+ {
+ \bool_lazy_and:nnTF
+ { \l_@@_ancient_bool }
+ { \int_compare_p:n { 1 < #3 < 5 } }
+ { \zhnum_digit_map:n { #3 0 } \use_none:n }
+ { \zhnum_digit_map:n {#3} }
+ }
+ \c_@@_ten_tl
+ }
+ \int_compare:nNnF {#4} = \c_zero_int { \zhnum_digit_map:n {#4} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhdig}
+% 用于将 \LaTeX{} 计数器按中文数字串输出。
+% \begin{macrocode}
+\DeclareExpandableDocumentCommand \zhdig { +o +m }
+ {
+ \IfNoValueTF {#1}
+ { \zhnum_digits_counter:n }
+ { \zhdigwithoptions {#1} }
+ {#2}
+ }
+\NewDocumentCommand \zhdigwithoptions { +m +m }
+ {
+ \group_begin:
+ \keys_set:nn { zhnum / options } {#1}
+ \zhnum_digits_counter:n #1 {#2}
+ \group_end:
+ }
+\cs_new:Npn \zhnum_digits_counter:n #1
+ {
+ \int_if_exist:cTF { c@#1 }
+ { \zhnum_digits_null:v { c@#1 } }
+ { \@@_counter_error:n {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@zhdig}
+% 用于支持 |\pagenumbering{zhdig}|。
+% \begin{macrocode}
+\cs_new_nopar:Npn \@zhdig #1 { \zhnum_digits_null:f { \int_eval:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhdigits,\zhdigitswithoptions}
+% 将输入的数字输出为中文数字串输出。
+% \begin{macrocode}
+\DeclareExpandableDocumentCommand \zhdigits { +s +o +m }
+ {
+ \IfNoValueTF {#2}
+ { \zhnum_digits:Nn #1 }
+ { \zhdigitswithoptions {#1} {#2} }
+ {#3}
+ }
+\NewDocumentCommand \zhdigitswithoptions { +m +m +m }
+ {
+ \group_begin:
+ \keys_set:nn { zhnum / options } {#2}
+ \zhnum_digits:Nn #1 {#3}
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_digits_zero:n,\zhnum_digits_null:n}
+% 快捷方式。
+% \begin{macrocode}
+\cs_new_nopar:Npn \zhnum_digits_zero:n
+ { \zhnum_digits:Nn \BooleanTrue }
+\cs_new_nopar:Npn \zhnum_digits_null:n
+ { \zhnum_digits:Nn \BooleanFalse }
+\cs_generate_variant:Nn \zhnum_digits_null:n { V , v , f }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_digits:Nn}
+% 与 \cs{zhnum_integer:n} 类似,但不用去掉多余的零。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_digits:Nn #1#2
+ {
+ \exp_after:wN \@@_read_digits:w
+ \int_value:w
+ \exp_after:wN \@@_read_sign_loop:NN \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w \use:n
+ #2 \exp_stop_f: \q_recursion_tail \q_recursion_stop
+ }
+\cs_new:Npn \@@_read_sign_loop:NN #1#2
+ {
+ \if:w + \if:w - \exp_not:N #2 + \fi: \exp_not:N #2
+ \exp_after:wN \@@_read_sign_loop:NN \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w \exp_after:wN \use:n
+ \else:
+ 1 \exp_after:wN ;
+ \exp_after:wN \@@_read_digits_loop:NN
+ \exp_after:wN #1
+ \exp_after:wN #2
+ \fi:
+ }
+\cs_new:Npn \@@_read_digits_loop:NN #1#2
+ {
+ \zhnum_if_digit:NTF #2
+ { \@@_output_digits:NN #1#2 }
+ {
+ \quark_if_recursion_tail_stop:N #2
+ \if:w .\exp_not:N #2 \exp_after:wN \c_@@_dot_tl \fi:
+ }
+ \exp_after:wN \@@_read_digits_loop:NN \exp_after:wN #1
+ \exp:w \exp_end_continue_f:w \use:n
+ }
+\cs_new:Npn \@@_read_digits:w #1 ;
+ {
+ \int_compare:nNnF {#1} = \c_one_int
+ { \c_@@_minus_tl }
+ }
+\cs_new:Npn \@@_output_digits:NN #1#2
+ {
+ \cs:w
+ c_@@_
+ \if_int_compare:w #2 = \c_zero_int
+ \IfBooleanTF #1 { zero } { null }
+ \else:
+ #2
+ \fi:
+ _tl
+ \cs_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhdate}
+% 输出中文日期。
+% \begin{macrocode}
+\DeclareExpandableDocumentCommand \zhdate { +s +m }
+ {
+ \@@_date:www #2 \q_stop
+ \IfBooleanT #1
+ { \@@_week_day:www #2 \q_stop }
+ }
+\cs_new:Npn \@@_date:www #1/#2/#3 \q_stop
+ { \@@_date_aux:nnn {#1} {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhtoday}
+% 输出当天日期。
+% \begin{macrocode}
+\cs_new_nopar:Npn \zhtoday
+ { \@@_date_aux:Vnn \tex_year:D \tex_month:D \tex_day:D }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_date_aux:nnn}
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_date_aux:nnn
+ {
+ \bool_if:NTF \l_@@_time_bool
+ { \@@_date_aux:NNnnnn \zhnum_digits_null:n \zhnum_int:n { } }
+ { \@@_date_aux:Nnnnn \int_to_arabic:n { \l_@@_arabic_sep_tl } }
+ }
+\cs_new:Npn \@@_date_aux:Nnnnn #1
+ { \@@_date_aux:NNnnnn #1#1 }
+\cs_new:Npn \@@_date_aux:NNnnnn #1#2#3#4#5#6
+ {
+ #1 {#4} #3 \c_@@_year_tl #3
+ #2 {#5} #3 \c_@@_month_tl #3
+ #2 {#6} #3 \c_@@_day_tl
+ }
+\cs_generate_variant:Nn \@@_date_aux:nnn { V }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhweekday}
+% 输出星期
+% \begin{macrocode}
+\cs_new:Npn \zhweekday #1
+ { \@@_week_day:www #1 \q_stop }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_week_day:www}
+% 用 Zeller 公式计算的结果 $h$ 与实际星期的关系是 $d=h+5\pmod7+1$。
+% \begin{macrocode}
+\cs_new:Npn \@@_week_day:www #1/#2/#3 \q_stop
+ {
+ \if_case:w \zhnum_Zeller:nnn {#1} {#2} {#3} \exp_stop_f:
+ \c_@@_sat_tl
+ \or: \c_@@_sun_tl
+ \or: \c_@@_mon_tl
+ \or: \c_@@_tue_tl
+ \or: \c_@@_wed_tl
+ \or: \c_@@_thu_tl
+ \or: \c_@@_fri_tl
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_Zeller:nnn,\zhnum_Zeller_aux:Nnnn,\zhnum_two_digits:n}
+% 用 Zeller 公式\footnote{\url{http://en.wikipedia.org/wiki/Zeller's_congruence}}
+% 计算星期几。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_Zeller:nnn #1#2#3
+ {
+ \int_compare:nNnTF
+ { #1 \zhnum_two_digits:n {#2} \zhnum_two_digits:n {#3} } > { 1582 10 04 }
+ { \@@_Zeller_aux:Nnnn \zhnum_Zeller_Gregorian:nnn }
+ { \@@_Zeller_aux:Nnnn \zhnum_Zeller_Julian:nnn }
+ {#1} {#2} {#3}
+ }
+\cs_new:Npn \@@_Zeller_aux:Nnnn #1#2#3#4
+ {
+ \int_compare:nNnTF {#3} < 3
+ { #1 { #2 - 1 } { #3 + 12 } {#4} }
+ { #1 {#2} {#3} {#4} }
+ }
+\cs_new:Npn \zhnum_two_digits:n #1
+ {
+ \int_compare:nNnT {#1} < { 10 } { 0 }
+ \int_eval:n {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_Zeller_Gregorian:nnn}
+% 格里历(\zhdate{1582/10/15}及以后)的计算公式
+% \[
+% h = \biggl(q + \biggl\lfloor\frac{26(m+1)}{10}\biggr\rfloor + Y +
+% \biggl\lfloor\frac Y4\biggr\rfloor + 6\biggl\lfloor\frac Y{100}\biggr\rfloor
+% + \biggl\lfloor\frac Y{400}\biggr\rfloor\biggr) \pmod 7
+% \]
+% 其中 $Y$ 为年,$m$ 为月,$q$ 为日;若 $m=1,2$,则令 $m\mathbin{{+}{=}}12$,同时 $Y\mathop{--}{}$。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_Zeller_Gregorian:nnn #1#2#3
+ {
+ \int_mod:nn
+ {
+ (#3)
+ + \int_div_truncate:nn { 26 * ( #2 + 1 ) } { 10 }
+ + (#1)
+ + \int_div_truncate:nn {#1} { 4 }
+ + 6 * \int_div_truncate:nn {#1} { 100 }
+ + \int_div_truncate:nn {#1} { 400 }
+ }
+ { 7 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_Zeller_Julian:nnn}
+% 儒略历(\zhdate{1582/10/04}及以前)的计算公式
+% \[
+% h = \biggl(q + \biggl\lfloor\frac{26(m+1)}{10}\biggr\rfloor + Y +
+% \biggl\lfloor\frac Y4\biggr\rfloor + 5\biggr) \pmod 7
+% \]
+% \begin{macrocode}
+\cs_new:Npn \zhnum_Zeller_Julian:nnn #1#2#3
+ {
+ \int_mod:nn
+ {
+ (#3)
+ + \int_div_truncate:nn { 26 * ( #2 + 1 ) } { 10 }
+ + (#1)
+ + \int_div_truncate:nn {#1} { 4 }
+ + 5
+ }
+ { 7 }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhtime}
+% 输出时间。
+% \begin{macrocode}
+\cs_new:Npn \zhtime #1
+ { \@@_time:ww #1 \q_stop }
+\use:x
+ {
+ \cs_new:Npn \exp_not:N \@@_time:ww ##1 \c_colon_str ##2 \exp_not:N \q_stop
+ }
+ { \@@_time_aux:nn {#1} {#2} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhcurrtime}
+% 输出当前时间。
+% \begin{macrocode}
+\cs_new_nopar:Npn \zhcurrtime
+ {
+ \@@_time_aux:nn
+ { \int_div_truncate:nn \tex_time:D { 60 } }
+ { \int_mod:nn \tex_time:D { 60 } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_time_aux:nn,\@@_time_aux:Nnnn}
+% \begin{macrocode}
+\cs_new_nopar:Npn \@@_time_aux:nn
+ {
+ \bool_if:NTF \l_@@_time_bool
+ { \@@_time_aux:Nnnn \zhnum_int:n { } }
+ { \@@_time_aux:Nnnn \int_to_arabic:n { \l_@@_arabic_sep_tl } }
+ }
+\cs_new:Npn \@@_time_aux:Nnnn #1#2#3#4
+ {
+ #1 {#3} #2 \c_@@_hour_tl #2
+ #1 {#4} #2 \c_@@_minute_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_digit_map:n}
+% 阿拉伯数字与中文数字的映射。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_digit_map:n #1
+ { \use:c { c_@@_ #1 _tl } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_scale_map:n,\zhnum_scale_map_loop:n}
+% 大数系统的映射。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_scale_map:n #1
+ {
+ \cs_if_exist_use:cF { c_@@_s #1 _tl }
+ { \zhnum_scale_map_hook:n {#1} }
+ }
+\cs_new:Npn \zhnum_scale_map_loop:n #1
+ { \zhnum_scale_map:n { \int_mod:nn {#1} \l_@@_scale_int } }
+\cs_generate_variant:Nn \zhnum_scale_map:n { f }
+\int_new:N \l_@@_scale_int
+\int_set:Nn \l_@@_scale_int { 11 }
+\cs_new_eq:NN \zhnum_scale_map_hook:n \zhnum_scale_map_loop:n
+\tl_const:cn { c_@@_s0_tl } { }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhnumExtendScaleMap}
+% 扩展进位系统。
+% \begin{macrocode}
+\NewDocumentCommand \zhnumExtendScaleMap { > { \TrimSpaces } +o +m }
+ {
+ \int_zero:N \l_tmpa_int
+ \clist_map_function:nN {#2} \zhnum_set_scale:n
+ \IfNoValueF {#1}
+ { \cs_set:Npn \zhnum_scale_map_hook:n ##1 {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_set_scale:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \zhnum_set_scale:n #1
+ {
+ \int_incr:N \l_tmpa_int
+ \tl_set:Nx \l_tmpa_tl
+ { c_@@_s \int_eval:n { \l_tmpa_int + 11 } _tl }
+ \tl_if_exist:cF { \l_tmpa_tl }
+ { \int_incr:N \l_@@_scale_int }
+ \tl_set:cn { \l_tmpa_tl } {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_ganzhi_normal:nnn}
+% 保证干支的参数为正数。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_ganzhi_normal:nnn #1#2#3
+ {
+ \int_compare:nNnF {#1} < \c_one_int
+ { \cs_if_exist_use:c { c_@@_ #2 _ #1 _tl } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_ganzhi_cyclic:nnn}
+% \begin{macro}{\@@_ganzhi_cyclic_mod:nnnn}
+% 对超出范围的数字取模,参数 |0| 的结果是空值。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_ganzhi_cyclic:nnn #1#2#3
+ {
+ \int_compare:nNnF {#1} = \c_zero_int
+ {
+ \cs_if_exist_use:cF { c_@@_ #2 _ #1 _tl }
+ {
+ \@@_ganzhi_cyclic_mod:fnnn
+ { \int_mod:nn {#1} {#3} } {#1} {#2} {#3}
+ }
+ }
+ }
+\cs_new:Npn \@@_ganzhi_cyclic_mod:nnnn #1#2#3#4
+ {
+ \int_compare:nNnTF {#2} > \c_zero_int
+ { \use:c { c_@@_ #3 _ #1 _tl } }
+ {
+ \int_compare:nNnTF {#1} = \c_zero_int
+ { \use:c { c_@@_ #3 _ 1 _tl } }
+ { \use:c { c_@@_ #3 _ \int_eval:n { #1 + #4 + 1 } _tl } }
+ }
+ }
+\cs_generate_variant:Nn \@@_ganzhi_cyclic_mod:nnnn { f }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_ganzhi:nnn}
+% 默认不对超出范围的数字取模。
+% \begin{macrocode}
+\cs_new_eq:NN \zhnum_ganzhi:nnn \zhnum_ganzhi_normal:nnn
+\cs_generate_variant:Nn \zhnum_ganzhi:nnn { f }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhtiangan}
+% 天干。
+% \begin{macrocode}
+\cs_new:Npn \zhtiangan #1
+ { \zhnum_ganzhi:fnn { \int_eval:n {#1} } { tiangan } { 10 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhdizhi}
+% 地支。
+% \begin{macrocode}
+\cs_new:Npn \zhdizhi #1
+ { \zhnum_ganzhi:fnn { \int_eval:n {#1} } { dizhi } { 12 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhganzhi}
+% 干支。
+% \begin{macrocode}
+\cs_new:Npn \zhganzhi #1
+ { \zhnum_ganzhi:fnn { \int_eval:n {#1} } { ganzhi } { 60 } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhganzhinian}
+% 干支纪年。
+% \begin{macrocode}
+\cs_new:Npn \zhganzhinian #1
+ { \zhnum_ganzhi_nian:f { \int_eval:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_ganzhi_nian:n}
+% 干支纪年。公元元年是 |\zhganzhi{58}|。
+% \begin{macrocode}
+\cs_new:Npn \zhnum_ganzhi_nian:n #1
+ {
+ \int_compare:nNnTF {#1} > \c_zero_int
+ { \use:c { c_@@_ganzhi_ \int_mod:nn { #1 + 57 } { 60 } _tl } }
+ {
+ \int_compare:nNnF {#1} = \c_zero_int
+ {
+ \use:c
+ {
+ c_@@_ganzhi_
+ \int_eval:n { \int_mod:nn { #1 - 2 } { 60 } + 60 }
+ _tl
+ }
+ }
+ }
+ }
+\cs_generate_variant:Nn \zhnum_ganzhi_nian:n { f }
+% \end{macrocode}
+% \end{macro}
+%
+% 根据需要设置中文阿拉伯数字。
+% \begin{macrocode}
+\group_begin:
+ \tl_set:Nn \l_tmpa_tl
+ {
+ - .tl_set:N = \l_@@_minus_tl ,
+ -0 .tl_set:N = \l_@@_null_tl ,
+ }
+ \tl_put_right:Nx \l_tmpa_tl
+ {
+ E2 .tl_set:N = \exp_not:c { l_@@_ 100 _tl } ,
+ E3 .tl_set:N = \exp_not:c { l_@@_ 1000 _tl } ,
+ FE2 .tl_set:N = \exp_not:c { l_@@_financial_ 100 _tl } ,
+ FE3 .tl_set:N = \exp_not:c { l_@@_financial_ 1000 _tl } ,
+ D11 .tl_set:N = \exp_not:c { l_@@_dizhi_ 11 _tl } ,
+ D12 .tl_set:N = \exp_not:c { l_@@_dizhi_ 12 _tl } ,
+ E44 .tl_set:N = \exp_not:c { l_@@_ s11 _tl } ,
+ }
+ \int_step_inline:nn { 10 }
+ {
+ \tl_put_right:Nx \l_tmpa_tl
+ {
+ #1 .tl_set:N = \exp_not:c { l_@@_ #1 _tl } ,
+ F#1 .tl_set:N = \exp_not:c { l_@@_financial_ #1 _tl } ,
+ T#1 .tl_set:N = \exp_not:c { l_@@_tiangan_ #1 _tl } ,
+ D#1 .tl_set:N = \exp_not:c { l_@@_dizhi_ #1 _tl } ,
+ GZ#1 .tl_set:N = \exp_not:c { l_@@_ganzhi_ #1 _tl } ,
+ E \int_eval:n { #1 * 4 }
+ .tl_set:N = \exp_not:c { l_@@_ s#1 _tl } ,
+ }
+ }
+ \int_step_inline:nnn { 11 } { 60 }
+ {
+ \tl_put_right:Nx \l_tmpa_tl
+ { GZ#1 .tl_set:N = \exp_not:c { l_@@_ganzhi_ #1 _tl } , }
+ }
+ \clist_map_inline:nn { 0 , 100 , 1000 }
+ {
+ \tl_put_right:Nx \l_tmpa_tl
+ {
+ #1 .tl_set:N = \exp_not:c { l_@@_ #1 _tl } ,
+ F#1 .tl_set:N = \exp_not:c { l_@@_financial_ #1 _tl } ,
+ }
+ }
+ \clist_map_inline:nn { 20 , 30 , 40 , 200 }
+ {
+ \tl_put_right:Nx \l_tmpa_tl
+ { #1 .tl_set:N = \exp_not:c { l_@@_ #1 _tl } , }
+ }
+ \clist_map_inline:nn
+ {
+ dot , and , parts , year , month , day , weekday , hour , minute
+ mon , tue , wed , thu , fri , sat , sun
+ }
+ {
+ \tl_put_right:Nx \l_tmpa_tl
+ { #1 .tl_set:N = \exp_not:c { l_@@_ #1 _tl } , }
+ }
+\use:x
+ {
+ \group_end:
+ \keys_define:nn { zhnum / options } { \exp_not:o \l_tmpa_tl }
+ }
+% \end{macrocode}
+%
+% \begin{macro}[int]
+% {
+% \zhnum_set_digits_map:nn,
+% \zhnum_set_digits_map:nnn,
+% \zhnum_set_financial_map:nn,
+% \zhnum_set_financial_map:nnn,
+% \zhnum_set_tiangan_map:nn,
+% \zhnum_set_dizhi_map:nn
+% }
+% \begin{variable}
+% {
+% \l_@@_cfg_map_prop,
+% \l_@@_cfg_map_var_prop,
+% \l_@@_cfg_map_finan_prop,
+% \l_@@_cfg_map_ganzhi_prop
+% }
+% 将配置文件中的中文数字保存到 \texttt{prop} 变量中。
+% \begin{macrocode}
+\cs_new_protected:Npn \zhnum_set_digits_map:nn #1#2
+ { \prop_put:Nnn \l_@@_cfg_map_prop {#1} {#2} }
+\cs_new_protected:Npn \zhnum_set_digits_map:nnn #1#2#3
+ {
+ \prop_put_if_new:Nnn \l_@@_cfg_map_prop {#1} {#3}
+ \prop_put:Nnn \l_@@_cfg_map_var_prop {#1_#2} {#3}
+ }
+\cs_new_protected:Npn \zhnum_set_financial_map:nn #1#2
+ { \prop_put:Nnn \l_@@_cfg_map_finan_prop {#1} {#2} }
+\cs_new_protected:Npn \zhnum_set_financial_map:nnn #1#2#3
+ {
+ \prop_put_if_new:Nnn \l_@@_cfg_map_finan_prop {#1} {#3}
+ \prop_put:Nnn \l_@@_cfg_map_var_prop { financial_#1_#2 } {#3}
+ }
+\cs_new_protected:Npn \zhnum_set_tiangan_map:nn #1#2
+ { \prop_put:Nnn \l_@@_cfg_map_ganzhi_prop { tiangan_#1 } {#2} }
+\cs_new_protected:Npn \zhnum_set_dizhi_map:nn #1#2
+ { \prop_put:Nnn \l_@@_cfg_map_ganzhi_prop { dizhi_#1 } {#2} }
+\prop_new:N \l_@@_cfg_map_prop
+\prop_new:N \l_@@_cfg_map_var_prop
+\prop_new:N \l_@@_cfg_map_finan_prop
+\prop_new:N \l_@@_cfg_map_ganzhi_prop
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% \zhnum_parse_config:,
+% \zhnum_check_simp:nn,
+% \zhnum_check_financial:nn,
+% \zhnum_set_zero:,
+% \zhnum_set_week_day:
+% }
+% 将 \texttt{prop} 表转化到单独的 \texttt{tl} 变量。
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \zhnum_parse_config:
+ {
+ \prop_map_function:NN \l_@@_cfg_map_prop \zhnum_check_simp:nn
+ \prop_map_function:NN \l_@@_cfg_map_ganzhi_prop \zhnum_assgin_ganzhi:nn
+ \zhnum_set_zero:
+ \zhnum_set_week_day:
+ \bool_if:NF \l_@@_reset_bool
+ {
+ \zhnum_assgin_const:
+ \bool_set_true:N \l_@@_reset_bool
+ }
+ }
+\cs_new_protected:Npn \zhnum_check_simp:nn #1#2
+ {
+ \@@_check_simp_aux:nn {#2} {#1}
+ \prop_get:NnNT \l_@@_cfg_map_finan_prop {#1} \l_tmpa_tl
+ { \exp_args:No \@@_check_simp_aux:nn { \l_tmpa_tl } { financial_ #1 } }
+ }
+\cs_new_protected:Npn \@@_check_simp_aux:nn #1#2
+ {
+ \prop_get:NnNTF \l_@@_cfg_map_var_prop { #2 _trad } \l_tmpa_tl
+ {
+ \prop_get:NnNF \l_@@_cfg_map_var_prop { #2 _simp } \l_tmpb_tl
+ { \tl_set:Nn \l_tmpb_tl {#1} }
+ \tl_set:cx { l_@@_ #2 _tl }
+ {
+ \exp_not:n { \bool_if:NTF \l_@@_simp_bool }
+ { \exp_not:o \l_tmpb_tl } { \exp_not:o \l_tmpa_tl }
+ }
+ }
+ { \tl_set:cn { l_@@_ #2 _tl } {#1} }
+ }
+\cs_new_protected_nopar:Npn \zhnum_assgin_const:
+ {
+ \prop_map_function:NN \l_@@_cfg_map_prop \zhnum_check_financial:nn
+ \zhnum_set_alias:
+ }
+\cs_new_protected:Npn \zhnum_check_financial:nn #1#2
+ {
+ \prop_get:NnNTF \l_@@_cfg_map_finan_prop {#1} \l_tmpa_tl
+ {
+ \zhnum_assgin_const_tl:cx { c_@@_ #1 _tl }
+ {
+ \exp_not:n { \bool_if:NTF \l_@@_normal_bool }
+ { \exp_not:c { l_@@_ #1 _tl } }
+ { \exp_not:c { l_@@_financial_ #1 _tl } }
+ }
+ }
+ {
+ \zhnum_assgin_const_tl:cx
+ { c_@@_ #1 _tl } { \exp_not:c { l_@@_ #1 _tl } }
+ }
+ }
+\cs_new_protected_nopar:Npn \zhnum_set_zero:
+ {
+ \tl_set:cx { l_@@_0_tl }
+ {
+ \exp_not:n { \bool_if:NTF \l_@@_null_bool }
+ { \exp_not:o \l_@@_null_tl } { \exp_not:v { l_@@_0_tl } }
+ }
+ }
+\cs_new_protected_nopar:Npn \zhnum_set_week_day:
+ {
+ \tl_set:Nx \l_@@_mon_tl
+ { \exp_not:N \c_@@_weekday_tl \exp_not:v { l_@@_1_tl } }
+ \tl_set:Nx \l_@@_tue_tl
+ { \exp_not:N \c_@@_weekday_tl \exp_not:v { l_@@_2_tl } }
+ \tl_set:Nx \l_@@_wed_tl
+ { \exp_not:N \c_@@_weekday_tl \exp_not:v { l_@@_3_tl } }
+ \tl_set:Nx \l_@@_thu_tl
+ { \exp_not:N \c_@@_weekday_tl \exp_not:v { l_@@_4_tl } }
+ \tl_set:Nx \l_@@_fri_tl
+ { \exp_not:N \c_@@_weekday_tl \exp_not:v { l_@@_5_tl } }
+ \tl_set:Nx \l_@@_sat_tl
+ { \exp_not:N \c_@@_weekday_tl \exp_not:v { l_@@_6_tl } }
+ \tl_set:Nx \l_@@_sun_tl
+ { \exp_not:N \c_@@_weekday_tl \exp_not:o \l_@@_day_tl }
+ }
+\clist_map_inline:nn { mon , tue , wed , thu , fri , sat , sun }
+ { \tl_const:cx { c_@@_ #1 _tl } { \exp_not:c { l_@@_ #1 _tl } } }
+\cs_new_protected:Npn \zhnum_assgin_ganzhi:nn #1#2
+ { \tl_set:cn { l_@@_ #1 _tl } {#2} }
+\cs_new:Npn \zhnum_zero_mod:nn #1#2
+ { \exp_args:Nf \@@_zero_mod_aux:nn { \int_mod:nn {#1} {#2} } {#2} }
+\cs_new:Npn \@@_zero_mod_aux:nn #1#2
+ { \int_compare:nNnTF {#1} = \c_zero_int {#2} {#1} }
+\int_step_inline:nn { 60 }
+ {
+ \tl_const:cx { c_@@_ganzhi_ #1 _tl } { \exp_not:c { l_@@_ganzhi_ #1 _tl } }
+ \tl_set:cx { l_@@_ganzhi_ #1 _tl }
+ {
+ \exp_not:c { l_@@_tiangan_ \zhnum_zero_mod:nn {#1} { 10 } _tl }
+ \exp_not:c { l_@@_dizhi_ \zhnum_zero_mod:nn {#1} { 12 } _tl }
+ }
+ }
+\cs_new_eq:cc { c_@@_ganzhi_ 0 _tl } { c_@@_ganzhi_ 60 _tl }
+\cs_new_eq:NN \zhnum_assgin_const_tl:cx \tl_const:cx
+\AtEndOfPackage
+ {
+ \prop_map_inline:Nn \l_@@_cfg_map_ganzhi_prop
+ { \tl_const:cx { c_@@_ #1 _tl } { \exp_not:c { l_@@_ #1 _tl } } }
+ \cs_new_eq:cc { c_@@_tiangan_ 0 _tl } { c_@@_tiangan_ 10 _tl }
+ \cs_new_eq:cc { c_@@_dizhi_ 0 _tl } { c_@@_dizhi_ 12 _tl }
+ \cs_set_eq:NN \zhnum_assgin_const_tl:cx \tl_set:cx
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_set_alias:}
+% 一些易于使用的别名。
+% \begin{macrocode}
+\cs_new_eq:NN \zhnum_set_alias:NN \cs_new_eq:NN
+\cs_new_protected_nopar:Npx \zhnum_set_alias:
+ {
+ \zhnum_set_alias:NN \exp_not:N \c_@@_zero_tl
+ \exp_not:c { c_@@_ 0 _tl }
+ \zhnum_set_alias:NN \exp_not:N \c_@@_ten_tl
+ \exp_not:c { c_@@_ 10 _tl }
+ \zhnum_set_alias:NN \exp_not:N \c_@@_hundred_tl
+ \exp_not:c { c_@@_ 100 _tl }
+ \zhnum_set_alias:NN \exp_not:N \c_@@_thousand_tl
+ \exp_not:c { c_@@_ 1000 _tl }
+ }
+\AtEndOfPackage
+ { \cs_set_eq:NN \zhnum_set_alias:NN \tl_set_eq:NN }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\zhnum_load_cfg:n}
+% 根据选定编码载入配置文件。
+% \begin{macrocode}
+\cs_new_protected:Npn \zhnum_load_cfg:n #1
+ {
+ \zhnum_set_cfg_name:Nn \l_@@_cfg_str {#1}
+ \str_if_eq:NNF \l_@@_cfg_str \l_@@_last_cfg_str
+ { \zhnum_update_cfg:n {#1} }
+ \zhnum_parse_config:
+ }
+\cs_generate_variant:Nn \zhnum_load_cfg:n { o }
+\cs_new_protected:Npn \zhnum_update_cfg:n #1
+ {
+ \prop_if_exist:cTF { g_@@_cfg_ \l_@@_cfg_str _prop }
+ { \str_set_eq:NN \l_@@_last_cfg_str \l_@@_cfg_str }
+ { \zhnum_input_cfg:n {#1} }
+ \@@_update_cfg_prop:N \prop_set_eq:Nc
+ }
+\cs_new_protected:Npn \zhnum_input_cfg:n #1
+ {
+ \file_if_exist:nTF { zhnumber - #1 .cfg }
+ {
+ \bool_set_false:N \l_@@_reset_bool
+ \@@_update_cfg_prop:N \@@_prop_initial:Nn
+ \group_begin:
+ \zhnum_set_catcode:
+ \file_input:n { zhnumber - #1 .cfg }
+ \@@_update_cfg_prop:N \@@_prop_gset_eq:Nn
+ \group_end:
+ }
+ { \msg_error:nnx { zhnumber } { file-not-found } {#1} }
+ }
+\cs_new_protected:Npn \@@_update_cfg_prop:N #1
+ {
+ #1 \l_@@_cfg_map_prop { g_@@_cfg_ \l_@@_cfg_str _prop }
+ #1 \l_@@_cfg_map_var_prop { g_@@_cfg_var_ \l_@@_cfg_str _prop }
+ #1 \l_@@_cfg_map_finan_prop { g_@@_cfg_finan_ \l_@@_cfg_str _prop }
+ #1 \l_@@_cfg_map_ganzhi_prop { g_@@_cfg_ganzhi_ \l_@@_cfg_str _prop }
+ }
+\cs_new_protected:Npn \@@_prop_initial:Nn #1#2
+ {
+ \prop_clear:N #1
+ \prop_new:c {#2}
+ }
+\cs_new_protected:Npn \@@_prop_gset_eq:Nn #1#2
+ { \prop_gset_eq:cN {#2} #1 }
+\str_new:N \l_@@_cfg_str
+\str_new:N \l_@@_last_cfg_str
+\bool_new:N \l_@@_reset_bool
+\msg_new:nnnn { zhnumber } { file-not-found }
+ { File~`#1'~not~found. }
+ {
+ The~requested~file~could~not~be~found~in~the~current~directory,~
+ in~the~TeX~search~path~or~in~the~LaTeX~search~path.
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int,pTF]{\zhnum_if_unicode_engine:}
+% 使用 \upTeX{} 的时候,也不必将汉字的首字符设置为活动字符。判断 |^^^^0021| 是否为
+% 单个记号的办法对 \upTeX{} 不适用。
+% \begin{macrocode}
+\bool_lazy_any:nTF
+ {
+ { \sys_if_engine_xetex_p: }
+ { \sys_if_engine_luatex_p: }
+ { \sys_if_engine_uptex_p: }
+ }
+ {
+ \cs_new_eq:NN \zhnum_if_unicode_engine_p: \c_true_bool
+ \cs_new_eq:NN \zhnum_if_unicode_engine:TF \use_i:nn
+ }
+ {
+ \cs_new_eq:NN \zhnum_if_unicode_engine_p: \c_false_bool
+ \cs_new_eq:NN \zhnum_if_unicode_engine:TF \use_ii:nn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% \zhnum_set_catcode:,
+% \zhnum_set_cfg_name:Nn,
+% \zhnum_reset_config:
+% }
+% 设置与恢复配置文件前后的 catcode。\pdfLaTeX{} 需要将汉字的首字节设置为活动字符。
+% \begin{macrocode}
+\if_predicate:w \zhnum_if_unicode_engine_p:
+ \cs_new_eq:NN \zhnum_set_catcode: \prg_do_nothing:
+ \cs_new_protected:Npn \zhnum_set_cfg_name:Nn #1#2
+ {
+ \str_set:Nx \l_@@_encoding_str {#2}
+ \str_set_eq:NN #1 \l_@@_encoding_str
+ }
+ \cs_new_eq:NN \zhnum_reset_config: \zhnum_parse_config:
+\else:
+ \cs_new_protected_nopar:Npn \zhnum_set_catcode:
+ { \bool_if:NT \l_@@_active_char_bool { \zhnum_set_active: } }
+ \cs_new_protected_nopar:Npn \zhnum_set_active:
+ {
+ \str_case:onTF { \l_@@_encoding_str }
+ {
+ { gbk } { \int_set:Nn \l_@@_byte_min_int { "81 } }
+ { big5 } { \int_set:Nn \l_@@_byte_min_int { "A1 } }
+ }
+ { \int_set:Nn \l_@@_byte_max_int { "FE } }
+ {
+ \int_set:Nn \l_@@_byte_min_int { "E0 }
+ \int_set:Nn \l_@@_byte_max_int { "EF }
+ }
+ \int_step_function:nnN
+ { \l_@@_byte_min_int }
+ { \l_@@_byte_max_int } \char_set_catcode_active:n
+ }
+ \int_new:N \l_@@_byte_min_int
+ \int_new:N \l_@@_byte_max_int
+ \cs_new_protected:Npn \zhnum_set_cfg_name:Nn #1#2
+ {
+ \str_set:Nx \l_@@_encoding_str {#2}
+ \str_set:Nx #1
+ {
+ \l_@@_encoding_str
+ \bool_if:NT \l_@@_active_char_bool { _active }
+ }
+ }
+ \cs_new_protected_nopar:Npn \zhnum_reset_config:
+ { \zhnum_load_cfg:o { \l_@@_encoding_str } }
+ \bool_new:N \l_@@_active_char_bool
+ \bool_set_true:N \l_@@_active_char_bool
+\fi:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{encoding,style,null,reset}
+% 宏包设置选项。
+% \begin{macrocode}
+\keys_define:nn { zhnum / options }
+ {
+ encoding .choices:nn =
+ { UTF8 , GBK , Big5 }
+ {
+ \str_set:Nx \l_@@_encoding_str
+ { \str_fold_case:V \l_keys_choice_tl }
+ \zhnum_load_cfg:o { \l_@@_encoding_str }
+ } ,
+ encoding .default:n = { GBK } ,
+ encoding / Bg5 .meta:n = { encoding = Big5 } ,
+ encoding / unknown .code:n =
+ { \msg_error:nnn { zhnumber } { encoding-invalid } {#1} } ,
+ style .multichoice: ,
+ style / Normal .code:n =
+ {
+ \bool_set_false:N \l_@@_ancient_bool
+ \bool_set_true:N \l_@@_normal_bool
+ } ,
+ style / Financial .code:n =
+ {
+ \bool_set_false:N \l_@@_ancient_bool
+ \bool_set_false:N \l_@@_normal_bool
+ } ,
+ style / Ancient .code:n =
+ {
+ \bool_set_true:N \l_@@_ancient_bool
+ \bool_set_true:N \l_@@_normal_bool
+ } ,
+ style / Simplified .code:n = { \bool_set_true:N \l_@@_simp_bool } ,
+ style / Traditional .code:n = { \bool_set_false:N \l_@@_simp_bool } ,
+ style .default:n = { Normal , Simplified } ,
+ null .bool_set:N = \l_@@_null_bool ,
+ time .choice: ,
+ time / Chinese .code:n = { \bool_set_true:N \l_@@_time_bool } ,
+ time / Arabic .code:n = { \bool_set_false:N \l_@@_time_bool } ,
+ time .default:n = { Arabic } ,
+ reset .code:n = { \zhnum_reset_config: } ,
+ activechar .bool_set:N = \l_@@_active_char_bool ,
+ ganzhi-cyclic .choice: ,
+ ganzhi-cyclic / true .code:n =
+ { \cs_set_eq:NN \zhnum_ganzhi:nnn \zhnum_ganzhi_cyclic:nnn } ,
+ ganzhi-cyclic / false.code:n =
+ { \cs_set_eq:NN \zhnum_ganzhi:nnn \zhnum_ganzhi_normal:nnn } ,
+ ganzhi-cyclic .default:n = { true } ,
+ arabicsep .tl_set:N = \l_@@_arabic_sep_tl
+ }
+\str_new:N \l_@@_encoding_str
+\msg_new:nnnn { zhnumber } { encoding-invalid }
+ { The~encoding~`#1'~is~invalid. }
+ { Available~encodings~are~`UTF8',~`GBK'~and~`Big5'. }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zhnumsetup}
+% 在文档中设置 \pkg{zhnumber} 的接口。
+% \begin{macrocode}
+\NewDocumentCommand \zhnumsetup { +m }
+ {
+ \keys_set:nn { zhnum / options } {#1}
+ \tex_ignorespaces:D
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% 初始化设置和执行宏包选项。
+% \begin{macrocode}
+\keys_set:nn { zhnum / options } { style , time , arabicsep = { ~ } }
+\ProcessKeysOptions { zhnum / options }
+% \end{macrocode}
+%
+% 如果没有选定编码,则根据引擎自动设置编码。
+% \begin{macrocode}
+\str_if_empty:NT \l_@@_encoding_str
+ {
+ \zhnum_if_unicode_engine:TF
+ { \keys_set:nn { zhnum / options } { encoding = UTF8 } }
+ { \keys_set:nn { zhnum / options } { encoding = GBK } }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \section{中文数字配置文件}
+% \label{sec:zhnum-map}
+%
+% \begin{macrocode}
+%<*config>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*!big5>
+\zhnum_set_digits_map:nnn { minus } { simp } { 负 }
+\zhnum_set_digits_map:nnn { minus } { trad } { 負 }
+%</!big5>
+%<*big5>
+\zhnum_set_digits_map:nn { minus } { 負 }
+%</big5>
+\zhnum_set_digits_map:nn { 0 } { 零 }
+%<*!big5>
+\zhnum_set_digits_map:nn { null } { 〇 }
+%</!big5>
+%<*big5>
+\zhnum_set_digits_map:nn { null } { ○ }
+%</big5>
+\zhnum_set_digits_map:nn { 1 } { 一 }
+\zhnum_set_digits_map:nn { 2 } { 二 }
+\zhnum_set_digits_map:nn { 3 } { 三 }
+\zhnum_set_digits_map:nn { 4 } { 四 }
+\zhnum_set_digits_map:nn { 5 } { 五 }
+\zhnum_set_digits_map:nn { 6 } { 六 }
+\zhnum_set_digits_map:nn { 7 } { 七 }
+\zhnum_set_digits_map:nn { 8 } { 八 }
+\zhnum_set_digits_map:nn { 9 } { 九 }
+\zhnum_set_digits_map:nn { 10 } { 十 }
+\zhnum_set_digits_map:nn { 100 } { 百 }
+\zhnum_set_digits_map:nn { 1000 } { 千 }
+\zhnum_set_digits_map:nn { 20 } { 廿 }
+\zhnum_set_digits_map:nn { 30 } { 卅 }
+\zhnum_set_digits_map:nn { 40 } { 卌 }
+\zhnum_set_digits_map:nn { 200 } { 皕 }
+%<*!big5>
+\zhnum_set_digits_map:nnn { dot } { simp } { 点 }
+\zhnum_set_digits_map:nnn { dot } { trad } { 點 }
+%</!big5>
+%<*big5>
+\zhnum_set_digits_map:nn { dot } { 點 }
+%</big5>
+\zhnum_set_digits_map:nn { and } { 又 }
+\zhnum_set_digits_map:nn { parts } { 分之 }
+%<*!big5>
+\zhnum_set_digits_map:nnn { s1 } { simp } { 万 }
+\zhnum_set_digits_map:nnn { s1 } { trad } { 萬 }
+\zhnum_set_digits_map:nnn { s2 } { simp } { 亿 }
+\zhnum_set_digits_map:nnn { s2 } { trad } { 億 }
+%</!big5>
+%<*big5>
+\zhnum_set_digits_map:nn { s1 } { 萬 }
+\zhnum_set_digits_map:nn { s2 } { 億 }
+%</big5>
+\zhnum_set_digits_map:nn { s3 } { 兆 }
+\zhnum_set_digits_map:nn { s4 } { 京 }
+\zhnum_set_digits_map:nn { s5 } { 垓 }
+\zhnum_set_digits_map:nn { s6 } { 秭 }
+\zhnum_set_digits_map:nn { s7 } { 穰 }
+%<*!big5>
+\zhnum_set_digits_map:nnn { s8 } { simp } { 沟 }
+\zhnum_set_digits_map:nnn { s8 } { trad } { 溝 }
+\zhnum_set_digits_map:nnn { s9 } { simp } { 涧 }
+\zhnum_set_digits_map:nnn { s9 } { trad } { 澗 }
+%</!big5>
+%<*big5>
+\zhnum_set_digits_map:nn { s8 } { 溝 }
+\zhnum_set_digits_map:nn { s9 } { 澗 }
+%</big5>
+\zhnum_set_digits_map:nn { s10 } { 正 }
+%<*!big5>
+\zhnum_set_digits_map:nnn { s11 } { simp } { 载 }
+\zhnum_set_digits_map:nnn { s11 } { trad } { 載 }
+%</!big5>
+%<*big5>
+\zhnum_set_digits_map:nn { s11 } { 載 }
+%</big5>
+\zhnum_set_digits_map:nn { year } { 年 }
+\zhnum_set_digits_map:nn { month } { 月 }
+\zhnum_set_digits_map:nn { day } { 日 }
+%<*!big5>
+\zhnum_set_digits_map:nnn { hour } { simp } { 时 }
+\zhnum_set_digits_map:nnn { hour } { trad } { 時 }
+%</!big5>
+%<*big5>
+\zhnum_set_digits_map:nn { hour } { 時 }
+%</big5>
+\zhnum_set_digits_map:nn { minute } { 分 }
+\zhnum_set_digits_map:nn { weekday } { 星期 }
+\zhnum_set_financial_map:nn { null } { 零 }
+\zhnum_set_financial_map:nn { 0 } { 零 }
+\zhnum_set_financial_map:nn { 1 } { 壹 }
+\zhnum_set_financial_map:nn { 2 } { 貳 }
+%<*!big5>
+\zhnum_set_financial_map:nnn { 3 } { simp } { 叁 }
+\zhnum_set_financial_map:nnn { 3 } { trad } { 叄 }
+%</!big5>
+%<*big5>
+\zhnum_set_financial_map:nn { 3 } { 參 }
+%</big5>
+\zhnum_set_financial_map:nn { 4 } { 肆 }
+\zhnum_set_financial_map:nn { 5 } { 伍 }
+%<*!big5>
+\zhnum_set_financial_map:nnn { 6 } { simp } { 陆 }
+\zhnum_set_financial_map:nnn { 6 } { trad } { 陸 }
+%</!big5>
+%<*big5>
+\zhnum_set_financial_map:nn { 6 } { 陸 }
+%</big5>
+\zhnum_set_financial_map:nn { 7 } { 柒 }
+\zhnum_set_financial_map:nn { 8 } { 捌 }
+\zhnum_set_financial_map:nn { 9 } { 玖 }
+\zhnum_set_financial_map:nn { 10 } { 拾 }
+\zhnum_set_financial_map:nn { 100 } { 佰 }
+\zhnum_set_financial_map:nn { 1000 } { 仟 }
+\zhnum_set_tiangan_map:nn { 1 } { 甲 }
+\zhnum_set_tiangan_map:nn { 2 } { 乙 }
+\zhnum_set_tiangan_map:nn { 3 } { 丙 }
+\zhnum_set_tiangan_map:nn { 4 } { 丁 }
+\zhnum_set_tiangan_map:nn { 5 } { 戊 }
+\zhnum_set_tiangan_map:nn { 6 } { 己 }
+\zhnum_set_tiangan_map:nn { 7 } { 庚 }
+\zhnum_set_tiangan_map:nn { 8 } { 辛 }
+\zhnum_set_tiangan_map:nn { 9 } { 壬 }
+\zhnum_set_tiangan_map:nn { 10 } { 癸 }
+\zhnum_set_dizhi_map:nn { 1 } { 子 }
+\zhnum_set_dizhi_map:nn { 2 } { 丑 }
+\zhnum_set_dizhi_map:nn { 3 } { 寅 }
+\zhnum_set_dizhi_map:nn { 4 } { 卯 }
+\zhnum_set_dizhi_map:nn { 5 } { 辰 }
+\zhnum_set_dizhi_map:nn { 6 } { 巳 }
+\zhnum_set_dizhi_map:nn { 7 } { 午 }
+\zhnum_set_dizhi_map:nn { 8 } { 未 }
+\zhnum_set_dizhi_map:nn { 9 } { 申 }
+\zhnum_set_dizhi_map:nn { 10 } { 酉 }
+\zhnum_set_dizhi_map:nn { 11 } { 戌 }
+\zhnum_set_dizhi_map:nn { 12 } { 亥 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</config>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \Finale
+%
+\endinput
diff --git a/macros/latex/contrib/zhnumber/zhnumber.ins b/macros/latex/contrib/zhnumber/zhnumber.ins
new file mode 100644
index 0000000000..d403166319
--- /dev/null
+++ b/macros/latex/contrib/zhnumber/zhnumber.ins
@@ -0,0 +1,89 @@
+%%
+%% This is file `zhnumber.ins',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% zhnumber.dtx (with options: `install')
+%%
+%% Copyright (C) 2012, 2014-2019 by Qing Lee <sobenlee@gmail.com>
+%% --------------------------------------------------------------------------
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version. This version of this license is in
+%% http://www.latex-project.org/lppl/lppl-1-3c.txt
+%% and the latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of
+%% LaTeX version 2005/12/01 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%%
+%% The Current Maintainer of this work is Qing Lee.
+%%
+%% --------------------------------------------------------------------------
+%%
+
+\input ctxdocstrip %
+
+\preamble
+
+ Copyright (C) 2012, 2014-2019 by Qing Lee <sobenlee@gmail.com>
+--------------------------------------------------------------------------
+
+ This work may be distributed and/or modified under the
+ conditions of the LaTeX Project Public License, either
+ version 1.3c of this license or (at your option) any later
+ version. This version of this license is in
+ http://www.latex-project.org/lppl/lppl-1-3c.txt
+ and the latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+ and version 1.3 or later is part of all distributions of
+ LaTeX version 2005/12/01 or later.
+
+ This work has the LPPL maintenance status `maintained'.
+
+ The Current Maintainer of this work is Qing Lee.
+
+--------------------------------------------------------------------------
+
+\endpreamble
+\postamble
+
+ This package consists of the file zhnumber.dtx,
+ and the derived files zhnumber.pdf,
+ zhnumber.sty,
+ zhnumber-utf8.cfg,
+ zhnumber-gbk.cfg,
+ zhnumber-big5.cfg,
+ zhnumber.ins and
+ README.md.
+\endpostamble
+
+\generate
+ {
+ \usedir{tex/latex/zhnumber}
+ \file{zhnumber.sty} {\from{\jobname.dtx}{package}}
+ \usedir{tex/latex/zhnumber/config}
+ \file{zhnumber-utf8.cfg} {\from{\jobname.dtx}{config,utf8}}
+ \file{zhnumber-big5.cfg} {\from{\jobname.dtx}{config,big5}}
+ \file{zhnumber-gbk.cfg} {\from{\jobname.dtx}{config,gbk}}
+ \nopreamble\nopostamble
+ \usedir{doc/latex/zhnumber}
+ \file{README.md} {\from{\jobname.dtx}{readme}}
+ }
+
+\endbatchfile
+%%
+%% This package consists of the file zhnumber.dtx,
+%% and the derived files zhnumber.pdf,
+%% zhnumber.sty,
+%% zhnumber-utf8.cfg,
+%% zhnumber-gbk.cfg,
+%% zhnumber-big5.cfg,
+%% zhnumber.ins and
+%% README.md.
+%%
+%% End of file `zhnumber.ins'.
diff --git a/macros/latex/contrib/zhnumber/zhnumber.pdf b/macros/latex/contrib/zhnumber/zhnumber.pdf
new file mode 100644
index 0000000000..7a3936c5ff
--- /dev/null
+++ b/macros/latex/contrib/zhnumber/zhnumber.pdf
Binary files differ