From da237d93d205989f6e955beb7ac7ec52c092aecd Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Tue, 9 Sep 2014 21:48:38 +0000
Subject: zhnumber (8sep14)

git-svn-id: svn://tug.org/texlive/trunk@35138 c570f23f-e606-0410-a88d-b1316a301751
---
 .../texmf-dist/source/latex/zhnumber/zhnumber.dtx  | 1389 ++++++++++++--------
 1 file changed, 872 insertions(+), 517 deletions(-)

(limited to 'Master/texmf-dist/source/latex/zhnumber/zhnumber.dtx')

diff --git a/Master/texmf-dist/source/latex/zhnumber/zhnumber.dtx b/Master/texmf-dist/source/latex/zhnumber/zhnumber.dtx
index 8fd4b479293..59a56eb12e0 100644
--- a/Master/texmf-dist/source/latex/zhnumber/zhnumber.dtx
+++ b/Master/texmf-dist/source/latex/zhnumber/zhnumber.dtx
@@ -67,8 +67,7 @@ unzip this in your local texmf directory and run texhash to update the
 database of file locations. If you want to unpack the dtx yourself, please
 ensure that the "iconv" program is installed and working properly, then
 running "xetex -shell-escape zhnumber.dtx" will extract the package whereas
-"xelatex -shell-escape zhnumber.dtx" will extract it and also typeset the
-documentation.
+"xelatex zhnumber.dtx" will typeset the documentation.
 
 The package requires LaTeX3 support as provided in the l3kernel and l3packages
 bundles. Both of these are available on CTAN as ready-to-install zip files.
@@ -80,17 +79,21 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %</readme>
 %<*internal>
 \fi
-\ifnum\strcmp{\fmtname}{plain}=0 \else
-  \expandafter\begingroup
-\fi
+\begingroup
+  \edef\tempa{\fmtname}
+  \edef\tempb{plain}
+\expandafter\endgroup
+\ifx\tempa\tempb
+\csname fi\endcsname
 %</internal>
-%<*batchfile>
-\input docstrip.tex
+%<*install>
+
+\input l3docstrip.tex
 \keepsilent
 \askforoverwritefalse
 \preamble
 
-   Copyright (C) 2012 by Qing Lee <sobenlee@gmail.com>
+   Copyright (C) 2012, 2014 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.3
@@ -115,87 +118,130 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
                                       zhnumber.ins and
                                       README.
 \endpostamble
+
 \ifnum\shellescape=1 \else
   \errmessage{
     Shell escape is disabled. Please use ^^J^^J
-    xe(la)tex -shell-escape \jobname.ins(dtx)^^J}
+    xetex -shell-escape \jobname.ins(dtx)^^J}
   \expandafter\endbatchfile
 \fi
-\usedir{tex/latex/zhnumber}
-\generate{\file{\jobname.sty}{\from{\jobname.dtx}{package}}}
-\usedir{tex/latex/zhnumber/config}
-\generate{
-  \file{\jobname-utf8.cfg}{\from{\jobname.dtx}{config,utf8}}
-  \file{\jobname-big5.cfg}{\from{\jobname.dtx}{config,big5}}
-  \file{\jobname-gbk.cfg}{\from{\jobname.dtx}{config,gbk}}}
-\immediate\write18{iconv -f utf-8 -t big-5 \jobname-big5.cfg > \jobname-big5.temp}
-\immediate\write18{iconv -f utf-8 -t gbk \jobname-gbk.cfg > \jobname-gbk.temp}
-\immediate\write18{mv -f \jobname-big5.temp \jobname-big5.cfg}
-\immediate\write18{mv -f \jobname-gbk.temp \jobname-gbk.cfg}
-%</batchfile>
-%<batchfile>\endbatchfile
+
+\generate
+  {
+    \usedir{source/latex/zhnumber}
+    \file{zhnumber.ins}       {\from{\jobname.dtx}{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.txt}         {\from{\jobname.dtx}{readme}}
+  }
+
+\immediate\write18{iconv -f utf-8 -t big-5 zhnumber-big5.cfg > zhnumber-big5.temp}
+\immediate\write18{iconv -f utf-8 -t gbk zhnumber-gbk.cfg > zhnumber-gbk.temp}
+\immediate\write18{mv -f zhnumber-big5.temp zhnumber-big5.cfg}
+\immediate\write18{mv -f zhnumber-gbk.temp zhnumber-gbk.cfg}
+
+\endbatchfile
+%</install>
 %<*internal>
-\usedir{source/latex/zhnumber}
-\generate{\file{\jobname.ins}{\from{\jobname.dtx}{batchfile}}}
-\nopreamble\nopostamble
-\usedir{doc/latex/zhnumber}
-\generate{\file{README.txt}{\from{\jobname.dtx}{readme}}}
-\ifnum\strcmp{\fmtname}{plain}=0
-  \expandafter\endbatchfile
-\else
-  \expandafter\endgroup
 \fi
 %</internal>
 %
-%<*driver|package>
+%<*driver|package|config>
+%<*!config>
 \NeedsTeXFormat{LaTeX2e}
+\RequirePackage{expl3}
+%</!config>
+\GetIdInfo$Id: zhnumber.dtx 715 2014-09-09 14:11:20Z sobenlee $
 %<*driver>
-\ProvidesFile{zhnumber.dtx}
+  {zhnumber source file}
+\ProvidesExplFile{\ExplFileName.\ExplFileExtension}
 %</driver>
-\RequirePackage{expl3}
-%</driver|package>
-%<package|config>\GetIdInfo$Id: zhnumber.dtx 367 2012-11-23 04:45:50Z sobenlee $
 %<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 Big5 encoding}
-%<package>\ProvidesExplPackage{\ExplFileName}{\ExplFileDate}{1.6}{\ExplFileDescription}
+%<config&gbk>  {Chinese numerals with GBK encoding}
+%<package>\ProvidesExplPackage
 %<config>\ProvidesExplFile
+%<package>  {\ExplFileName}
 %<config&utf8>  {\ExplFileName-utf8.cfg}
 %<config&big5>  {\ExplFileName-big5.cfg}
 %<config&gbk>  {\ExplFileName-gbk.cfg}
-%<config>  {\ExplFileDate} {1.6} {\ExplFileDescription}
-%
+  {\ExplFileDate}{2.0}{\ExplFileDescription}
+%</driver|package|config>
 %<*driver>
-\documentclass[full,a4paper]{l3doc}
+\ExplSyntaxOff
+\let\ctexrevnum\ExplFileVersion
+\expandafter\let\csname ver@thumbpdf.sty\endcsname\fmtversion
+\documentclass[numbered,full,a4paper]{l3doc}
 \usepackage{amsmath}
 \usepackage{xeCJK}
 \usepackage{zhnumber}
 \usepackage{fvrb-ex}
-\usepackage{metalogo}
+\usepackage{indentfirst}
 \usepackage{geometry}
 \geometry{includemp,hmargin={0mm,15mm},vmargin=15mm,footskip=7mm}
 \BeforeBeginEnvironment{SideBySideExample}{\vskip1ex\relax}
 \hypersetup{pdfstartview=FitH}
-\setlist{nosep}
+\setlist{noitemsep,topsep=\smallskipamount}
 \linespread{1.1}
 \setmainfont{TeX Gyre Pagella}
-\setmonofont{Inconsolata}
+\setsansfont{CMU Sans Serif}
+\setmonofont[
+  UprightFont=* Light, BoldFont=* Bold,
+  SlantedFont=* Light Oblique]{CMU Typewriter Text}
 \xeCJKDeclareCharClass{CJK}{ "25CB }
 \setCJKmainfont[BoldFont=Adobe Heiti Std,ItalicFont=Adobe Kaiti Std]{Adobe Song Std}
 \setCJKmonofont{Adobe Kaiti Std}
 \xeCJKsetup{PunctStyle=kaiming}
-\def\MacroFont{\small\normalfont\ttfamily}
+\def\ctexkitrev#1{%
+  \href{http://code.google.com/p/ctex-kit/source/detail?r=#1}{\texttt{ctex-kit} rev#1}}
 \makeatletter
-\let\orig@meta\meta
-\def\meta#1{\orig@meta{\normalfont\itshape#1}}
+\def\LaTeX{\hologo{LaTeX}}
+\def\upTeX{up\!\hologo{TeX}}
+\def\upLaTeX{up\hologo{LaTeX}}
+\def\pdfLaTeX{\hologo{pdfLaTeX}}
+\def\LuaLaTeX{\hologo{LuaLaTeX}}
+\def\XeLaTeX{\hologo{XeLaTeX}}
 \def\TF{true\orvar{}false}
-\def\TTF{\defaultvar{true}\orvar{}false}
+\def\TTF{\defaultvar{true}\orvar false}
 \def\TFF{true\orvar\defaultvar{false}}
-\def\orvar{\char`\|}
-\let\defaultvar\textbf
+\def\orvar{\textup{\textbar}}
+\def\defaultvar{\textbf}
 \def\argbrace#1{\{#1\}}
-\@addtoreset{CodelineNo}{section}
+\preto\MacroFont{\linespread{1}}
+\appto\MacroFont{\hyphenchar\font\m@ne}
+\preto\AltMacroFont{\linespread{1}}
+\appto\AltMacroFont{\hyphenchar\font\m@ne}
+\ExplSyntaxOn
+\cs_set_protected:Npn \__codedoc_special_index_aux:nnnnn #1#2#3#4#5
+  {
+    \__codedoc_special_index_set:Nn \l__codedoc_index_escaped_macro_tl {#2}
+    \str_if_eq:onTF { \@currenvir } { macrocode }
+      { \codeline@wrindex }
+      {
+        \HD@target
+        \index
+      }
+      {
+        \tl_if_empty:nF { #3 #4 }
+          { #3 \actualchar #4 \levelchar }
+        #1
+        \actualchar
+        {
+          \token_to_str:N \verbatim@font \c_space_tl
+          \l__codedoc_index_escaped_macro_tl
+        }
+        \encapchar
+        hdclindex{\the\c@HD@hypercount}{#5}
+      }
+  }
+\ExplSyntaxOff
 \makeatother
 \def\indexname{代码索引}
 \IndexPrologue{%
@@ -211,39 +257,39 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %</driver>
 % \fi
 %
-% \CheckSum{844}
+% \CheckSum{1071}
 % \GetFileInfo{\jobname.sty}
 %
 % \title{\bfseries\pkg{zhnumber} 宏包}
 % \author{李清\\ \path{sobenlee@gmail.com}}
-% \date{\filedate\qquad\fileversion}
+% \date{\filedate\qquad\fileversion\thanks{\ctexkitrev{\ctexrevnum}.}}
 % \maketitle
 %
 % \begin{documentation}
 %
 % \section{简介}
 % \pkg{zhnumber} 宏包用于将阿拉伯数字按照中文格式输出。相比于 \pkg{CJKnumb}，它提供
-% 的三个格式转换命令 |\zhnumber|，|\zhdigits| 和 |\zhnum| 都是可以适当展开的，可以
-% 正常使用于 |PDF| 书签和交叉引用。
+% 的三个格式转换命令 \tn{zhnumber}，\tn{zhdigits} 和 \tn{zhnum} 都是可以适当展开的，
+% 可以正常使用于 |PDF| 书签和交叉引用。
 %
-% \pkg{zhnumber} 支持 |GBK|，|Big5| 和 |UTF8| 编码，依赖 \LaTeX~3 项目的 \pkg{expl3}，
-% \pkg{xparse} 和 \pkg{l3keys2e} 宏包。
+% \pkg{zhnumber} 支持 |GBK|，|Big5| 和 |UTF8| 编码，依赖 \hologo{LaTeX3} 项目的
+% \pkg{expl3}，\pkg{xparse} 和 \pkg{l3keys2e} 宏包。
 %
 % \section{使用方法}
 %
-% \begin{function}[updated=2012-5-25]{encoding}
+% \begin{function}[updated=2014-09-09]{encoding}
 %   \begin{syntax}
 %     encoding = \meta{GBK\orvar{}Big5\orvar{}UTF8}
 %   \end{syntax}
-%   用于指定编码的宏包选项，可以在调用宏包的时候设定，也可以用 |\zhnumsetup| 在导言区内设定。
-%   对于 \XeLaTeX 和 \LuaLaTeX ，不用指定编码，宏包将自动使用 |UTF8| 编码。只有 \LaTeX
-%   和 pdf\LaTeX 需要指定编码，如果没有指定，默认将使用 |GBK|，并且此时 \pkg{zhnumber}
-%   宏包应该在 \pkg{CJK} 或 \pkg{CJKutf8} 宏包之后载入。
+%   用于指定编码的宏包选项，可以在调用宏包的时候设定，也可以用 \tn{zhnumsetup}
+%   在导言区内设定。对于 \upLaTeX、\XeLaTeX{} 和 \LuaLaTeX，不用指定编码，宏包将
+%   自动使用 |UTF8| 编码。只有 \LaTeX{} 和 \pdfLaTeX{} 需要指定编码，如果没有指定，
+%   默认将使用 |GBK|。
 % \end{function}
 %
-% \begin{function}{\zhnumber}
+% \begin{function}[updated=2014-09-09]{\zhnumber}
 %   \begin{syntax}
-%     \cs{zhnumber} \marg{number}
+%     \tn{zhnumber} \Arg{number}
 %   \end{syntax}
 %   以中文格式输出数字。这里的数字可以是整数、小数和分数。例如
 %   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
@@ -260,21 +306,22 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %   \end{SideBySideExample}
 % \end{function}
 %
-% \begin{function}{\zhdigits}
+% \begin{function}[updated=2014-09-09]{\zhdigits}
 %   \begin{syntax}
-%     \cs{zhdigits} \marg{number}
+%     \tn{zhdigits}   \Arg{number}
+%     \tn{zhdigits} * \Arg{number}
 %   \end{syntax}
-%   将阿拉伯数字转换为中文数字串。缺省状态下，|\zhdigits| 将 0 映射为〇，如果需要
-%   将其映射为零，可以使用 |\zhdigits*|。例如
+%   将阿拉伯数字转换为中文数字串。缺省状态下，\tn{zhdigits} 将 0 映射为〇，如果需要
+%   将其映射为零，可以使用带星号的形式。例如
 %   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
 %     \zhdigits{2012020120}\\
 %     \zhdigits*{2012020120}
 %   \end{SideBySideExample}
 % \end{function}
 %
-% \begin{function}{\zhnum}
+% \begin{function}[updated=2014-09-09]{\zhnum}
 %   \begin{syntax}
-%     \cs{zhnum} \marg{counter}
+%     \tn{zhnum} \Arg{counter}
 %   \end{syntax}
 %   与 |\roman| 等类似，用于将 \LaTeX 计数器的值转换为中文数字。例如
 %   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
@@ -284,7 +331,7 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %
 % \begin{function}[added=2012-5-25]{\zhweekday}
 %   \begin{syntax}
-%     \cs{zhweekday} \Arg{yyyy/mm/dd}
+%     \tn{zhweekday} \Arg{yyyy/mm/dd}
 %   \end{syntax}
 %   输出日期当天的星期。例如
 %   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
@@ -294,8 +341,8 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %
 % \begin{function}[added=2012-5-25]{\zhdate}
 %   \begin{syntax}
-%     \cs{zhdate}  \Arg{yyyy/mm/dd}
-%     \cs{zhdate*} \Arg{yyyy/mm/dd}
+%     \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]
@@ -313,7 +360,7 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %
 % \begin{function}[added=2012-5-25]{\zhtime}
 %   \begin{syntax}
-%     \cs{zhtime} \Arg{hh:mm}
+%     \tn{zhtime} \Arg{hh:mm}
 %   \end{syntax}
 %   以中文格式输出时间。例如
 %   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
@@ -330,17 +377,17 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %
 % \begin{function}[added=2012-5-25]{\zhnumExtendScaleMap}
 %   \begin{syntax}
-%     \cs{zhnumExtendScaleMap} \oarg{character} \argbrace{\meta{character 1}, \meta{character 2}, ..., \meta{character n}}
+%     \tn{zhnumExtendScaleMap} \oarg{character} \argbrace{\meta{character_1}, \meta{character_2}, ..., \meta{character_n}}
 %   \end{syntax}
-%   缺省状态下 |\zhnumber| 能正确中文格式化的最大整数是 $10^{48}-1$，|\zhditits| 不受
-%   这个大小的限制。可以通过 |\zhnumExtendScaleMap| 来扩展 |\zhnumber|。
-%   \meta{character} $i$ 设置 $10^{4(i+11)}$。若给出可选项 \meta{character}，则当
+%   缺省状态下 \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}
-%     \cs{zhnumsetup} \argbrace{\meta{key1}=\meta{var1}, \meta{key2}=\meta{var2}, ...}
+%     \tn{zhnumsetup} \argbrace{\meta{key_1}=\meta{val_1}, \meta{key_2}=\meta{val_2}, ...}
 %   \end{syntax}
 %   用于在导言区或文档中，设置中文数字的输出格式。目前可以设置的 \meta{key} 如下介绍。
 % \end{function}
@@ -362,13 +409,15 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %     style = \argbrace{\meta{Simplified}\orvar\meta{Traditional}\orvar\meta{Normal}\orvar\meta{Financial}\orvar\meta{Ancient}}
 %   \end{syntax}
 %   意义分别为
-%   \begin{itemize}[font=\ttfamily,labelsep=1em]
+%
+%   \begin{description}[font=\mdseries\ttfamily,align=right,labelsep=1em,labelindent=-1em,leftmargin=*]
 %     \item[Simplified]  以简体中文输出数字（对 |Big5| 编码无效）；
 %     \item[Traditional] 以繁体中文输出数字（对 |Big5| 编码无效）；
 %     \item[Normal] 以小写形式输出中文数字；
 %     \item[Financial]  以大写形式输出中文数字；
 %     \item[Ancient] 以廿输出 20，以卅输出 30，以卌输出 40，以皕输出 200。
-%   \end{itemize}
+%   \end{description}
+%
 %   可以设置 |style| 为其中一个，也可以是前三个与后两个的适当组合，默认是简体小写。例如
 %   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.4\linewidth,gobble=5]
 %     \zhnumsetup{style={Traditional,Financial}}
@@ -382,15 +431,15 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %   \begin{syntax}
 %     null = \meta{\TFF}
 %   \end{syntax}
-%   缺省状态下，除了 |\zhdigits| 外，其它的格式转换命令，将 0 映射成零，如果需要将 0 映射
+%   缺省状态下，除了 \tn{zhdigits} 外，其它的格式转换命令，将 0 映射成零，如果需要将 0 映射
 %   成〇，可以使用这个选项。\strut
 % \end{function}
 %
 % \pkg{zhnumber} 提供下列选项来控制阿拉伯数字的中文映射。
 % \begin{verbatim}[frame=single]
-%   - -0 0 1 2 3 4 5 6 7 8 9 10 20 30 40 200
+%   - -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 FE2 FE3
+%   F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F100 F1000 FE2 FE3
 %   dot and parts
 %   year month day hour minute weekday mon tue wed thu fri sat sun
 % \end{verbatim}
@@ -403,7 +452,7 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 % 可以将 2 映射成两。需要说明的是，\pkg{zhnumber} 将优先使用这里的设置，所以可能会影响
 % 到 |style| 选项。如果要恢复 |style| 的功能，可以使用 |reset| 选项。
 %
-% \begin{function}[updated=2012-5-25]{reset}
+% \begin{function}[updated=2014-09-09]{reset}
 %   \begin{syntax}
 %     reset
 %   \end{syntax}
@@ -411,14 +460,25 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %   设置见源代码（第 \ref{sec:zhnum-map} 节）。
 % \end{function}
 %
-% \begin{function}{\zhnumber,\zhdigits,\zhnum}
+% \begin{function}[added=2014-09-09]{activechar}
+%   \begin{syntax}
+%     activechar = \meta{\TTF}
+%   \end{syntax}
+%   在 \LaTeX{} 或者 \pdfLaTeX{} 下面输出汉字，传统的办法需要将汉字的首字节设置为
+%   活动字符，然后再通过特殊的宏技巧来实现。因此，\pkg{zhnumber} 在载入配置文件的
+%   时候，默认会将汉字的首字节设置为活动字符。禁用本选项将不会改变汉字首字节的
+%   类代码。需要在本选项之后，使用 \texttt{encoding} 或者 \texttt{reset} 选项
+%   才会有效果。
+% \end{function}
+%
+% \begin{function}[updated=2014-09-09]{\zhnumber,\zhdigits,\zhnum}
 %   \begin{syntax}
-%     \cs{zhnumber} \oarg{options} \marg{number}
-%     \cs{zhdigits} \oarg{options} \marg{number}
-%     \cs{zhnum} \oarg{options} \marg{counter}
+%     \tn{zhnumber}   \oarg{options} \Arg{number}
+%     \tn{zhdigits} * \oarg{options} \Arg{number}
+%     \tn{zhnum}      \oarg{options} \Arg{counter}
 %   \end{syntax}
 %   如果只改变当前数字的中文输出格式，可以使用带选项的格式转换命令，其中 \meta{options}
-%   与 |\zhnumsetup| 的参数相同，如上所介绍。这些带了选项的命令是不可展开的，在某些场合使
+%   与 \tn{zhnumsetup} 的参数相同，如上所介绍。这些带了选项的命令是不可展开的，在某些场合使
 %   用时要小心。
 % \end{function}
 %
@@ -435,6 +495,10 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %    \end{macrocode}
 %
 %    \begin{macrocode}
+%<@@=zhnum>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \msg_new:nnn { zhnumber } { l3-too-old }
   {
     Support~package~'expl3'~too~old. \\\\
@@ -442,71 +506,86 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
     'l3kernel'~and~'l3packages'\\\\
     using~your~TeX~package~manager~or~from~CTAN.
   }
-\@ifpackagelater { expl3 } { 2012/07/16 } { }
+\@ifpackagelater { expl3 } { 2014/08/25 } { }
   { \msg_error:nn  { zhnumber }  { l3-too-old } }
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\RequirePackage{xparse}
-\RequirePackage{l3keys2e}
+\RequirePackage { xparse , l3keys2e }
 %    \end{macrocode}
 %
 % \begin{macro}{\zhnumber}
 % 用于将输入的数字按照中文格式输出。
 %    \begin{macrocode}
-\DeclareExpandableDocumentCommand \zhnumber { o m }
-  { \zhnum_number_aux:nNn {#1} \zhnum_number:n {#2} }
-\cs_new_nopar:Nn \zhnum_number:n { \zhnum_number:w #1 . \q_nil . \q_stop }
+\DeclareExpandableDocumentCommand \zhnumber { +o +m }
+  {
+    \IfNoValueTF {#1}
+      { \zhnum_number:n {#2} }
+      { \zhnumberwithoptions {#1} {#2} }
+  }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_number_aux:nNn}
+% \begin{macro}{\zhnumberwithoptions}
+% 带选项的用户函数。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_number_aux:nNn
+ \NewDocumentCommand \zhnumberwithoptions { +m +m }
   {
-    \IfNoValueTF {#1} { #2 {#3} }
-      { \group_begin: \zhnumsetup {#1} #2 {#3} \group_end: }
+    \group_begin:
+      \keys_set:nn { zhnum / options } {#1}
+      \zhnum_number:n {#2}
+    \group_end:
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_number:w}
+% \begin{macro}[internal]{\zhnum_number:n}
+% \begin{macro}[aux]{\@@_number:www}
 % 先判断输入的是小数还是分数。
 %    \begin{macrocode}
-\cs_new_nopar:Npn \zhnum_number:w #1.#2.#3 \q_stop
+\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}
-      { \zhnum_integer_or_fraction:w #1 / \q_nil / \q_stop }
+      { \@@_integer_or_fraction:www #1 / \q_nil / \q_stop }
       { \zhnum_decimal:nn {#1} {#2} }
   }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_integer_or_fraction:w}
+% \begin{macro}[aux]{\@@_integer_or_fraction:www}
 % 判断是否输入的是分数。
 %    \begin{macrocode}
-\cs_new_nopar:Npn \zhnum_integer_or_fraction:w #1/#2/#3 \q_stop
+\cs_new:Npn \@@_integer_or_fraction:www #1 / #2 / #3 \q_stop
   {
     \quark_if_nil:nTF {#2}
-      { \zhnum_integer:f {#1} }
-      { \zhnum_fraction:w #2 \q_mark #1 ; \q_nil ; \q_stop }
+      { \zhnum_integer:n {#1} }
+      { \@@_fraction:wwww #2 \q_mark #1 ; \q_nil ; \q_stop }
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_fraction:w}
+% \begin{macro}[aux]{\@@_fraction:wwww}
 % 对分数进行预处理。
 %    \begin{macrocode}
-\cs_new_nopar:Npn \zhnum_fraction:w #1 \q_mark #2;#3;#4 \q_stop
+\cs_new:Npn \@@_fraction:wwww #1 \q_mark #2 ; #3 ; #4 \q_stop
   {
     \quark_if_nil:nTF {#3}
       {
-        \zhnum_blank_to_zero:f {#1} \c_zhnum_parts_tl
+        \zhnum_blank_to_zero:f {#1}
+        \c_@@_parts_tl
         \zhnum_blank_to_zero:f {#2}
       }
       {
-        \tl_if_blank:fF {#2} { \zhnumber {#2} \c_zhnum_and_tl }
-        \zhnum_blank_to_zero:f {#1} \c_zhnum_parts_tl
+        \tl_if_blank:fF {#2}
+          {
+            \zhnum_number:n {#2}
+            \c_@@_and_tl
+          }
+        \zhnum_blank_to_zero:f {#1}
+        \c_@@_parts_tl
         \zhnum_blank_to_zero:f {#3}
       }
   }
@@ -517,10 +596,12 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 % \begin{macro}[internal]{\zhnum_decimal:nn}
 % 对小数进行预处理。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_decimal:nn
+\cs_new:Npn \zhnum_decimal:nn #1#2
   {
-    \zhnum_blank_to_zero:f {#1} \c_zhnum_dot_tl
-    \tl_if_blank:fTF {#2} { \c_zhnum_zero_tl } { \zhdigits * {#2} }
+    \zhnum_blank_to_zero:f {#1} \c_@@_dot_tl
+    \tl_if_blank:fTF {#2}
+      { \c_@@_zero_tl }
+      { \zhnum_digits_zero:n {#2} }
   }
 \cs_generate_variant:Nn \tl_if_blank:nTF { f }
 %    \end{macrocode}
@@ -529,101 +610,193 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 % \begin{macro}[internal]{\zhnum_blank_to_zero:n}
 % 输出小数的整数位。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_blank_to_zero:n
-  { \tl_if_blank:nTF {#1} { \zhnum_digit_map:n \c_zero } { \zhnumber {#1} } }
+\cs_new:Npn \zhnum_blank_to_zero:n #1
+  {
+    \tl_if_blank:nTF {#1}
+      { \c_@@_zero_tl }
+      { \zhnum_number:n {#1} }
+  }
 \cs_generate_variant:Nn \zhnum_blank_to_zero:n { f }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\zhnum}
-% 用于将 \LaTeX 计数器按中文格式输出。
+% \begin{macro}{\zhnum,\zhnumberwithoptions}
+% 用于将 \LaTeX{} 计数器按中文格式输出。
 %    \begin{macrocode}
 \DeclareExpandableDocumentCommand \zhnum { o m }
-  { \zhnum_number_aux:nNn {#1} \zhnum_counter:n {#2} }
-\cs_new_nopar:Nn \zhnum_counter:n
   {
-    \exp_args:Nc \token_if_int_register:NTF { c@#1 }
-      { \zhnum_integer:v { c@#1 } }
-      { \@nocounterr {#1} }
+    \IfNoValueTF {#1}
+      { \zhnum_counter:n {#2} }
+      { \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}[internal]{\zhnum_counter:n}
+% 可以直接通过比较 \LaTeX{} 计数器的值来得到符号和绝对值。
+%    \begin{macrocode}
+\cs_new_nopar:Npn \zhnum_counter:n #1
+  { \exp_args:Nc \zhnum_counter:Nn  { c@#1 } {#1} }
+\cs_new:Npn \zhnum_counter:Nn #1#2
+  {
+    \token_if_int_register:NTF #1
+      { \zhnum_int:n {#1} }
+      { \__msg_expandable_error:n { `#2' is not a LaTeX counter. } }
+  }
+\cs_new:Npn \zhnum_int:n #1
+  {
+    \int_compare:nNnTF {#1} > \c_zero
+      { \zhnum_parse_number:f { \int_eval:n {#1} } }
+      {
+        \int_compare:nNnTF {#1} < \c_zero
+          {
+            \c_@@_minus_tl
+            \zhnum_parse_number:f { \int_eval:n { - #1 } }
+          }
+          { \c_@@_zero_tl }
+      }
   }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}[internal]{\zhnum_integer:n}
-% 对整数的处理。
+% 对整数的处理。这个函数基本抄录自 \pkg{l3bigint} 的 \cs{__bingint_read_do:nn}。它可以
+% 正确取得符号，去掉多余的零，还可以循环展开数字。但它在遇到非数字的时候就停止了
+% 循环，我们可能需要非数字（例如逗号）来作为分隔符号。因此对它略作修改，跳过非数字。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_integer:n
+\cs_new:Npn \zhnum_integer:n #1
+  {
+    \exp_after:wN \@@_read_integer:www
+    \tex_number:D
+      \exp_after:wN \@@_read_sign_loop:N
+      \tex_romannumeral:D -`0 \use:n
+      #1 \exp_stop_f: \q_recursion_tail \q_recursion_stop
+         \@@_result:nn { \c_zero } { } ;
+  }
+\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
+      \tex_romannumeral:D -`0 \exp_after:wN \use:n
+    \else:
+      1 \exp_after:wN ;
+      \tex_romannumeral:D -`0
+        \exp_after:wN \@@_read_zeros_loop:N
+        \exp_after:wN #1
+    \fi:
+  }
+\cs_new:Npn \@@_read_zeros_loop:N #1
   {
-    \int_compare:nNnT { \__int_get_sign:n {#1} \c_one } < \c_zero { \c_zhnum_minus_tl }
-    \zhnum_parse_number:f { \zhnum_trim_zeros:f { \zhnum_erase_separator:n {#1} } }
+    \if:w 0 \exp_not:N #1
+      \exp_after:wN \@@_read_zeros_loop:N
+      \tex_romannumeral:D -`0 \exp_after:wN \use:n
+    \else:
+      \exp_after:wN \@@_read_abs_loop:Nw
+      \exp_after:wN #1
+    \fi:
   }
-\cs_generate_variant:Nn \zhnum_integer:n { f , v , V }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_erase_separator:n,\zhnum_trim_zeros:n}
-% 去掉分隔符和多余的 $0$。
+% \begin{macro}[aux]{\@@_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_nopar:Nn \zhnum_erase_separator:n
-  { \cs_to_str:c { \tl_map_function:nN {#1} \zhnum_erase_separator_aux:N } }
-\cs_new_nopar:Nn \zhnum_erase_separator_aux:N { \zhnum_if_number:NT {#1} {#1} }
-\cs_new_nopar:Nn \zhnum_trim_zeros:n
+\cs_new:Npn \@@_read_abs_loop:Nw #1#2 \q_recursion_stop
   {
-    \tl_if_empty:nTF {#1} \c_zero
-      {
-        \int_compare:nNnTF { \tl_head:n {#1} } = \c_zero
-          { \zhnum_trim_zeros:o { \use_none:n #1 } } {#1}
-      }
+    \zhnum_if_digit:NTF #1
+      { \@@_output:nnwnn { + \c_one } #1 }
+      { \quark_if_recursion_tail_stop_do:Nn #1 { \@@_loop_end:wnn } }
+    \exp_after:wN \@@_read_abs_loop:Nw
+      \tex_romannumeral:D -`0 \use:n #2 \q_recursion_stop
   }
-\prg_new_conditional:Nnn \zhnum_if_number:N { p , T , F , TF }
+\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}[aux]{\@@_read_integer:www}
+% |#1| 符号，|#3| 是绝对值，|#2| 是绝对值的长度。
+%    \begin{macrocode}
+\cs_new:Npn \@@_read_integer:www #1 ; #2 ; #3 ;
   {
-    \if_int_compare:w \c_one < 1 #1 \exp_stop_f:
-      \prg_return_true: \else: \prg_return_false: \fi:
+    \int_compare:nNnTF {#2} = \c_zero
+      { \c_@@_zero_tl }
+      {
+        \int_compare:nNnF {#1} = \c_one
+          { \c_@@_minus_tl }
+        \zhnum_parse_number:nn {#2} {#3}
+      }
   }
-\cs_generate_variant:Nn \zhnum_trim_zeros:n { f , o }
-\cs_generate_variant:Nn \cs_to_str:N        { c }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_parse_number:n,\zhnum_parse_number:nn}
+% \begin{macro}[internal]{\zhnum_if_digit:NTF}
+% 判断 |#1| 是否为数字位。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_parse_number:n
+\cs_new:Npn \zhnum_if_digit:NTF #1
   {
-    \zhnum_parse_number:nff {#1}
-      { \tl_count:n {#1} }
-      { \int_mod:nn { \tl_count:n {#1} } \c_four }
+    \if_int_compare:w \c_nine < 1 \exp_not:N #1 \exp_stop_f:
+      \exp_after:wN \use_i:nn
+    \else:
+      \exp_after:wN \use_ii:nn
+    \fi:
   }
-\cs_new_nopar:Nn \zhnum_parse_number:nnn
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]
+%   {
+%     \zhnum_parse_number:n,
+%     \zhnum_parse_number:nn
+%   }
+%    \begin{macrocode}
+\cs_new_nopar:Npn \zhnum_parse_number:n #1
+  { \exp_args:Nf \zhnum_parse_number:nn { \tl_count:n {#1} } {#1} }
+\cs_new_nopar:Npn \zhnum_parse_number:nn #1#2
+  { \exp_args:Nf \@@_parse_number:nnn { \int_mod:nn {#1} \c_four } {#1} {#2} }
+\cs_new_nopar:Npn \@@_parse_number:nnn #1#2#3
   {
     \int_compare:nNnTF {#2} < \c_two
-      { \zhnum_digit_map:n {#1} }
+      { \zhnum_digit_map:n {#3} }
       {
-        \zhnum_split_number:fNNfn { \zhnum_insert_zeros:n {#3} #1 }
+        \zhnum_split_number:fNNfn { \zhnum_insert_zeros:n {#1} #3 }
           \c_true_bool \c_true_bool
           {
-            \int_compare:nNnTF {#3} = \c_zero
+            \int_compare:nNnTF {#1} = \c_zero
               { \int_eval:n { (#2) / \c_four - \c_one } }
               { \int_div_truncate:nn {#2} \c_four }
           }
           { \c_zero }
       }
   }
-\cs_generate_variant:Nn \zhnum_parse_number:n   {   f }
-\cs_generate_variant:Nn \zhnum_parse_number:nnn { nff }
+\cs_generate_variant:Nn \zhnum_parse_number:n { f }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}[internal]{\zhnum_insert_zeros:n}
 % 为了处理的方便，在整数前面补上适当的 $0$，使其位数可以被 $4$ 整除。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_insert_zeros:n
+\cs_new_nopar:Npn \zhnum_insert_zeros:n #1
   {
-    \if_case:w \int_eval:n { #1 - \c_one } \exp_stop_f:
+    \if_case:w \etex_numexpr:D #1 - \c_one \scan_stop:
       \or: \exp_after:wN \use_none:n
       \or: \exp_after:wN \use_none:nn
     \else: \exp_after:wN \use_none:nnn
     \fi:
-    000
+    0 0 0
   }
 %    \end{macrocode}
 % \end{macro}
@@ -631,73 +804,73 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 % \begin{macro}[internal]{\zhnum_split_number:nNNnn}
 % 将输入的整数由高位到低位，以四位为一段进行处理。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_split_number:nNNnn
+\cs_new_nopar:Npn \zhnum_split_number:nNNnn #1#2#3#4#5
   {
-    \zhnum_split_number_aux:fnNNnn { \zhnum_number_item:nn {#1} {#5} }
+    \@@_split_number:fnNNnn { \zhnum_number_item:nn {#1} {#5} }
       {#1} #2#3 {#4} {#5}
   }
-\cs_new_nopar:Nn \zhnum_split_number_aux:nnNNnn
+\cs_new_nopar:Npn \@@_split_number:nnNNnn #1#2#3#4#5#6
   {
-    \int_compare:nNnTF {#1} = \c_zero { \use_i_ii:nnn }
+    \int_compare:nNnTF {#1} = \c_zero
+      { \@@_split_number_aux:NNfnnn \c_false_bool \c_true_bool }
       {
-        \bool_if:NF #3 { \c_zhnum_zero_tl }
+        \bool_if:NF #3 { \c_@@_zero_tl }
         \zhnum_process_number:NNn #3#4 {#1}
-        \zhnum_scale_map:n { #5 - #6 }
+        \exp_args:Nf \zhnum_scale_map:n { \int_eval:n { #5 - #6 } }
         \int_compare:nNnTF { \int_mod:nn {#1} \c_ten } = \c_zero
-          { \use_i_ii:nnn } { \zhnum_use_i_iii:nnn }
+          { \@@_split_number_aux:NNfnnn \c_false_bool \c_true_bool }
+          { \@@_split_number_aux:NNfnnn \c_true_bool \c_false_bool }
       }
-    { \int_compare:nNnF {#5} = {#6} }
-    { {
-        \zhnum_split_number:nNNnf
-          {#2} \c_false_bool \c_true_bool {#5} { \int_eval:n { #6 + \c_one } }
-    } }
-    { {
-        \zhnum_split_number:nNNnf
-          {#2} \c_true_bool \c_false_bool {#5} { \int_eval:n { #6 + \c_one } }
-    } }
-  }
-\cs_new_nopar:Nn \zhnum_use_i_iii:nnn {#1#3}
-\cs_generate_variant:Nn \zhnum_split_number:nNNnn { fNNf , nNNnf }
-\cs_generate_variant:Nn \zhnum_split_number_aux:nnNNnn { f }
+    { \int_eval:n { #6 + \c_one } } {#2} {#5} {#6}
+  }
+\cs_new_nopar:Npn \@@_split_number_aux:NNnnnn #1#2#3#4#5#6
+  {
+    \int_compare:nNnF {#5} = {#6}
+      { \zhnum_split_number:nNNnn {#4} #1#2 {#5} {#3} }
+  }
+\cs_generate_variant:Nn \zhnum_split_number:nNNnn { fNNf }
+\cs_generate_variant:Nn \@@_split_number:nnNNnn { f }
+\cs_generate_variant:Nn \@@_split_number_aux:NNnnnn { NNf }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_number_item:nn,\zhnum_number_item_aux:nNNNN}
+% \begin{macro}[internal]{\zhnum_number_item:nn}
 % 截取整数的其中四位数。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_number_item:nn
-  { \zhnum_number_item_aux:nNNNN {#2} #1 \q_recursion_stop }
-\cs_new_nopar:Nn \zhnum_number_item_aux:nNNNN
+\cs_new_nopar:Npn \zhnum_number_item:nn #1#2
+  { \@@_number_item:nNNNN {#2} #1 \q_recursion_stop }
+\cs_new_nopar:Npn \@@_number_item:nNNNN #1#2#3#4#5
   {
     \int_compare:nNnTF {#1} = \c_zero
-      { \zhnum_recursion_stop:NNNNw #2#3#4#5 }
-      { \zhnum_number_item_aux:fNNNN { \int_eval:n { #1 - \c_one } } }
+      { \@@_recursion_stop:NNNNw #2#3#4#5 }
+      { \@@_number_item:fNNNN { \int_eval:n { #1 - \c_one } } }
   }
-\cs_generate_variant:Nn \zhnum_number_item_aux:nNNNN { f }
-\cs_new_nopar:Npn \zhnum_recursion_stop:NNNNw #1#2#3#4#5 \q_recursion_stop {#1#2#3#4}
+\cs_generate_variant:Nn \@@_number_item:nNNNN { f }
+\cs_new_nopar:Npn \@@_recursion_stop:NNNNw #1#2#3#4#5 \q_recursion_stop
+  { #1#2#3#4 }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}[internal]{\zhnum_process_number:NNn,\zhnum_process_number:NNNNNN}
 % 对四位数字按情况进行处理。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_process_number:NNn
+\cs_new_nopar:Npn \zhnum_process_number:NNn #1#2#3
   { \zhnum_process_number:NNNNNN #3#1#2 }
-\cs_new_nopar:Nn \zhnum_process_number:NNNNNN
+\cs_new_nopar:Npn \zhnum_process_number:NNNNNN #1#2#3#4#5#6
   {
     \int_compare:nNnTF {#1} = \c_zero
-      { \bool_if:NF #6 { \c_zhnum_zero_tl } }
-      { \zhnum_digit_map:n {#1} \c_zhnum_thousand_tl }
+      { \bool_if:NF #6 { \c_@@_zero_tl } }
+      { \zhnum_digit_map:n {#1} \c_@@_thousand_tl }
     \int_compare:nNnTF {#2} = \c_zero
-      { \int_compare:nNnT { #1 * (#3#4) } > \c_zero { \c_zhnum_zero_tl } }
+      { \int_compare:nNnT { #1 * (#3#4) } > \c_zero { \c_@@_zero_tl } }
       {
         \bool_if:nTF
-          { \l_zhnum_ancient_bool && \int_compare_p:nNn {#2} = \c_two }
+          { \l_@@_ancient_bool && \int_compare_p:nNn {#2} = \c_two }
           { \zhnum_digit_map:n { #2 00 } }
-          { \zhnum_digit_map:n {#2} \c_zhnum_hundred_tl }
+          { \zhnum_digit_map:n {#2} \c_@@_hundred_tl }
       }
     \int_compare:nNnTF {#3} = \c_zero
-      { \int_compare:nNnT { #2 * #4 } > \c_zero { \c_zhnum_zero_tl } }
+      { \int_compare:nNnT { #2 * #4 } > \c_zero { \c_@@_zero_tl } }
       {
         \bool_if:nF
           {
@@ -707,7 +880,7 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
           {
             \bool_if:nTF
               {
-                \l_zhnum_ancient_bool                   &&
+                \l_@@_ancient_bool                   &&
                 ( \int_compare_p:nNn {#3} = \c_two   ||
                   \int_compare_p:nNn {#3} = \c_three ||
                   \int_compare_p:nNn {#3} = \c_four )
@@ -715,54 +888,98 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
               { \zhnum_digit_map:n { #3 0 } \use_none:n }
               { \zhnum_digit_map:n {#3} }
           }
-        \c_zhnum_ten_tl
+        \c_@@_ten_tl
       }
     \int_compare:nNnF {#4} = \c_zero { \zhnum_digit_map:n {#4} }
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\zhdigits}
+% \begin{macro}{\zhdigits,\zhdigitswithoptions}
 % 将输入的数字输出为中文数字串输出。
 %    \begin{macrocode}
 \DeclareExpandableDocumentCommand \zhdigits { s o m }
   {
-    \IfBooleanTF {#1}
-      { \zhnum_digits_aux:nnN {#2} {#3} \zhnum_digits_zero_aux:N }
-      { \zhnum_digits_aux:nnN {#2} {#3} \zhnum_digits_null_aux:N }
+    \IfNoValueTF {#2}
+      { \zhnum_digits:Nn #1 {#3} }
+      {
+        \IfBooleanTF #1
+          { \zhdigitswithoptions * }
+          { \zhdigitswithoptions }
+        {#2} {#3}
+      }
   }
-\cs_new_nopar:Nn \zhnum_digits_aux:nnN
+\NewDocumentCommand \zhdigitswithoptions { s m m }
   {
-    \IfNoValueTF {#1} { \tl_map_function:fN {#2} #3 }
-      { \group_begin: \zhnumsetup {#1} \tl_map_function:fN {#2} #3 \group_end: }
+    \group_begin:
+      \keys_set:nn { zhnum / options } {#2}
+      \zhnum_digits:Nn #1 {#3}
+    \group_end:
   }
-\cs_new_nopar:Nn \zhnum_digits_null:n { \tl_map_function:fN {#1} \zhnum_digits_null_aux:N }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\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 }
-\cs_generate_variant:Nn \tl_map_function:nN  { f }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]
-% {\zhnum_digits_null_aux:N,\zhnum_digits_zero_aux:N,\zhnum_digits_aux:NN}
-% 将输入的数字输出为中文数字串输出。
+% \begin{macro}[internal]{\zhnum_digits:Nn}
+% 与 \cs{zhnum_integer:n} 类似，但不用去掉多余的零。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_digits_null_aux:N { \zhnum_digits_aux:NN \c_true_bool  #1 }
-\cs_new_nopar:Nn \zhnum_digits_zero_aux:N { \zhnum_digits_aux:NN \c_false_bool #1 }
-\cs_new_nopar:Nn \zhnum_digits_aux:NN
+\cs_new:Npn \zhnum_digits:Nn #1#2
   {
-    \str_if_eq_x:nnTF {#2} . \c_zhnum_dot_tl
+    \exp_after:wN \@@_read_digits:w
+    \tex_number:D
+      \exp_after:wN \@@_read_sign_loop:NN \exp_after:wN #1
+      \tex_romannumeral:D -`0 \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
+      \tex_romannumeral:D -`0 \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 }
       {
-        \str_if_eq_x:nnTF {#2} -
-          { \c_zhnum_minus_tl }
-          {
-            \zhnum_if_number:NT {#2}
-              {
-                \bool_if:nTF { \int_compare_p:nNn {#2} = \c_zero }
-                  { \bool_if:NTF #1 \c_zhnum_null_tl \c_zhnum_zero_tl }
-                  { \zhnum_digit_map:n {#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
+        \tex_romannumeral:D -`0 \use:n
+  }
+\cs_new:Npn \@@_read_digits:w #1 ;
+  {
+    \int_compare:nNnF {#1} = \c_one
+      { \c_@@_minus_tl }
+  }
+\cs_new:Npn \@@_output_digits:NN #1#2
+  {
+    \cs:w
+      c_@@_
+        \if_int_compare:w #2 = \c_zero
+          \IfBooleanTF #1 { zero } { null }
+        \else:
+          #2
+        \fi:
+      _tl
+    \cs_end:
   }
 %    \end{macrocode}
 % \end{macro}
@@ -772,14 +989,15 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %    \begin{macrocode}
 \DeclareExpandableDocumentCommand \zhdate { s m }
   {
-    \zhnum_date:w #2 \q_stop
-    \IfBooleanT {#1} { \zhweekday {#2} }
+    \@@_date:www #2 \q_stop
+    \IfBooleanT {#1}
+      {  \@@_week_day:www #2 \q_stop }
   }
-\cs_new_nopar:Npn \zhnum_date:w #1/#2/#3 \q_stop
+\cs_new_nopar:Npn \@@_date:www #1/#2/#3 \q_stop
   {
-    \zhnum_check_time:Nn \zhnum_digits_null:n {#1} \c_zhnum_year_tl
-    \zhnum_check_time:Nn \zhnum_integer:f {#2} \c_zhnum_month_tl
-    \zhnum_check_time:Nn \zhnum_integer:f {#3} \c_zhnum_day_tl
+    \zhnum_check_time:Nn \zhnum_digits_null:n {#1} \c_@@_year_tl
+    \zhnum_check_time:Nn \zhnum_integer:n {#2} \c_@@_month_tl
+    \zhnum_check_time:Nn \zhnum_integer:n {#3} \c_@@_day_tl
   }
 %    \end{macrocode}
 % \end{macro}
@@ -789,9 +1007,9 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %    \begin{macrocode}
 \cs_new_nopar:Npn \zhtoday
   {
-    \zhnum_check_time:Nn \zhnum_digits_null:V \tex_year:D \c_zhnum_year_tl
-    \zhnum_check_time:Nn \zhnum_integer:V \tex_month:D \c_zhnum_month_tl
-    \zhnum_check_time:Nn \zhnum_integer:V \tex_day:D   \c_zhnum_day_tl
+    \zhnum_check_time:Nn \zhnum_digits_null:V \tex_year:D \c_@@_year_tl
+    \zhnum_check_time:Nn \zhnum_int:n \tex_month:D \c_@@_month_tl
+    \zhnum_check_time:Nn \zhnum_int:n \tex_day:D   \c_@@_day_tl
   }
 %    \end{macrocode}
 % \end{macro}
@@ -799,15 +1017,34 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 % \begin{macro}[internal]{\zhnum_check_time:Nn}
 % 判断是用中文数字还是用阿拉伯数组。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_check_time:Nn
-  { \bool_if:NTF \l_zhnum_time_bool {#1} { \int_eval:n } {#2} }
+\cs_new_nopar:Npn \zhnum_check_time:Nn #1
+  { \bool_if:NTF \l_@@_time_bool {#1} { \int_eval:n } }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}{\zhweekday}
 % 输出星期
 %    \begin{macrocode}
-\cs_new_nopar:Npn \zhweekday #1 { \zhnum_week_day:w #1 \q_stop }
+\cs_new_nopar:Npn \zhweekday #1
+  { \@@_week_day:www #1 \q_stop }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\@@_week_day:www}
+% 用 Zeller 公式计算的结果 $h$ 与实际星期的关系是 $d=h+5\pmod7+1$。
+%    \begin{macrocode}
+\cs_new_nopar:Npn \@@_week_day:www #1/#2/#3 \q_stop
+  {
+    \if_case:w \etex_numexpr:D \zhnum_Zeller:nnn {#1} {#2} {#3} \scan_stop:
+           \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}
 %
@@ -815,21 +1052,21 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 % 用 Zeller 公式\footnote{\url{http://en.wikipedia.org/wiki/Zeller's_congruence}}
 % 计算星期几。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_Zeller:nnn
+\cs_new_nopar:Npn \zhnum_Zeller:nnn #1#2#3
   {
     \int_compare:nNnTF
       { #1 \zhnum_two_digits:n {#2} \zhnum_two_digits:n {#3} } > { 1582 10 04 }
-      { \zhnum_Zeller_aux:Nnnn \zhnum_Zeller_Gregorian:nnn }
-      { \zhnum_Zeller_aux:Nnnn \zhnum_Zeller_Julian:nnn }
+      { \@@_Zeller_aux:Nnnn \zhnum_Zeller_Gregorian:nnn }
+      { \@@_Zeller_aux:Nnnn \zhnum_Zeller_Julian:nnn }
     {#1} {#2} {#3}
   }
-\cs_new_nopar:Nn \zhnum_Zeller_aux:Nnnn
+\cs_new_nopar:Npn \@@_Zeller_aux:Nnnn  #1#2#3#4
   {
     \int_compare:nNnTF {#3} < \c_three
       { #1 { #2 - \c_one } { #3 + \c_twelve } {#4} }
       { #1 {#2} {#3} {#4} }
   }
-\cs_new_nopar:Nn \zhnum_two_digits:n
+\cs_new_nopar:Npn \zhnum_two_digits:n #1
   {
     \int_compare:nNnT {#1} < \c_ten { 0 }
     \int_eval:n {#1}
@@ -846,13 +1083,13 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 % \]
 % 其中 $Y$ 为年，$m$ 为月，$q$ 为日；若 $m=1,2$，则令 $m\mathbin{{+}{=}}12$，同时 $Y\mathop{--}{}$。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_Zeller_Gregorian:nnn
+\cs_new_nopar:Npn \zhnum_Zeller_Gregorian:nnn #1#2#3
   {
     \int_mod:nn
       {
-          \int_eval:n {#3}
-        + \int_div_truncate:nn { 26 * ( \int_eval:n {#2} + \c_one ) } \c_ten
-        + \int_eval:n {#1}
+          (#3)
+        + \int_div_truncate:nn { 26 * ( #2 + \c_one ) } \c_ten
+        + (#1)
         + \int_div_truncate:nn {#1} \c_four
         + \c_six * \int_div_truncate:nn {#1} \c_one_hundred
         + \int_div_truncate:nn {#1} { 400 }
@@ -869,13 +1106,13 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %   \biggl\lfloor\frac Y4\biggr\rfloor + 5\biggr) \pmod 7
 % \]
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_Zeller_Julian:nnn
+\cs_new_nopar:Npn \zhnum_Zeller_Julian:nnn #1#2#3
   {
     \int_mod:nn
       {
-          \int_eval:n {#3}
-        + \int_div_truncate:nn { 26 * ( \int_eval:n {#2} + \c_one ) } \c_ten
-        + \int_eval:n {#1}
+          (#3)
+        + \int_div_truncate:nn { 26 * ( #2 + \c_one ) } \c_ten
+        + (#1)
         + \int_div_truncate:nn {#1} \c_four
         + \c_five
       }
@@ -884,37 +1121,20 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_week_day:w}
-% 用 Zeller 公式计算的结果 $h$ 与实际星期的关系是 $d=h+5\pmod7+1$。
-%    \begin{macrocode}
-\cs_new_nopar:Npn \zhnum_week_day:w #1/#2/#3 \q_stop
-  {
-    \if_case:w \int_eval:n { \zhnum_Zeller:nnn {#1} {#2} {#3} } \exp_stop_f:
-           \c_zhnum_sat_tl
-      \or: \c_zhnum_sun_tl
-      \or: \c_zhnum_mon_tl
-      \or: \c_zhnum_tue_tl
-      \or: \c_zhnum_wed_tl
-      \or: \c_zhnum_thu_tl
-      \or: \c_zhnum_fri_tl
-    \fi:
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\zhtime}
 % 输出时间。
 %    \begin{macrocode}
-\cs_new_nopar:Npn \zhtime #1 { \zhnum_time:w #1 \q_stop }
+\cs_new_nopar:Npn \zhtime #1
+  { \@@_time:ww #1 \q_stop }
 \group_begin:
 \char_set_lccode:nn { `\; } { `\: }
 \tl_to_lowercase:n
   {
     \group_end:
-    \cs_new_nopar:Npn \zhnum_time:w #1 ; #2 \q_stop
+    \cs_new_nopar:Npn \@@_time:ww #1 ; #2 \q_stop
       {
-        \zhnum_check_time:Nn \zhnum_integer:f {#1} \c_zhnum_hour_tl
-        \zhnum_check_time:Nn \zhnum_integer:f {#2} \c_zhnum_minute_tl
+        \zhnum_check_time:Nn \zhnum_integer:n {#1} \c_@@_hour_tl
+        \zhnum_check_time:Nn \zhnum_integer:n {#2} \c_@@_minute_tl
       }
   }
 %    \end{macrocode}
@@ -925,10 +1145,10 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %    \begin{macrocode}
 \cs_new_nopar:Npn \zhcurrtime
   {
-    \zhnum_check_time:Nn \zhnum_integer:f
-      { \int_div_truncate:nn \tex_time:D { 60 } } \c_zhnum_hour_tl
-    \zhnum_check_time:Nn \zhnum_integer:f
-      { \int_mod:nn \tex_time:D { 60 } } \c_zhnum_minute_tl
+    \zhnum_check_time:Nn \zhnum_int:n
+      { \int_div_truncate:nn \tex_time:D { 60 } } \c_@@_hour_tl
+    \zhnum_check_time:Nn \zhnum_int:n
+      { \int_mod:nn \tex_time:D { 60 } } \c_@@_minute_tl
   }
 %    \end{macrocode}
 % \end{macro}
@@ -936,23 +1156,23 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 % \begin{macro}[internal]{\zhnum_digit_map:n}
 % 阿拉伯数字与中文数字的映射。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_digit_map:n
-  { \tl_use:c { c_zhnum_ \zhnum_int_to_word:n {#1} _tl } }
+\cs_new_nopar:Npn \zhnum_digit_map:n #1
+  { \use:c { c_@@_ #1 _tl } }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}[internal]{\zhnum_scale_map:n,\zhnum_scale_map_loop:n}
 % 大数系统的映射。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_scale_map:n
+\cs_new_nopar:Npn \zhnum_scale_map:n #1
   {
-    \cs_if_exist_use:cF { c_zhnum_scale_ \zhnum_int_to_word:n {#1} _tl }
+    \cs_if_exist_use:cF { c_@@_s #1 _tl }
       { \zhnum_scale_map_hook:n {#1} }
   }
-\cs_new_nopar:Nn \zhnum_scale_map_loop:n
-  { \zhnum_scale_map:n { \int_mod:nn {#1} \g_zhnum_scale_int } }
-\int_new:N \g_zhnum_scale_int
-\int_set_eq:NN \g_zhnum_scale_int \c_eleven
+\cs_new_nopar:Npn \zhnum_scale_map_loop:n #1
+  { \zhnum_scale_map:n { \int_mod:nn {#1} \g_@@_scale_int } }
+\int_new:N \g_@@_scale_int
+\int_set_eq:NN \g_@@_scale_int \c_eleven
 \cs_new_eq:NN \zhnum_scale_map_hook:n \zhnum_scale_map_loop:n
 %    \end{macrocode}
 % \end{macro}
@@ -961,211 +1181,356 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %    \begin{macrocode}
 \NewDocumentCommand \zhnumExtendScaleMap { > { \TrimSpaces } o m }
   {
-   \int_zero:N \l_tmpa_int
+    \int_zero:N \l_tmpa_int
     \clist_map_inline:nn {#2}
       {
         \int_incr:N \l_tmpa_int
         \tl_set:Nx \l_tmpa_tl
-          { c_zhnum_scale_ \zhnum_int_to_word:n { \l_tmpa_int + \c_eleven } _tl }
-        \tl_if_exist:cF \l_tmpa_tl { \int_incr:N \g_zhnum_scale_int }
+          { c_@@_s \int_eval:n { \l_tmpa_int + \c_eleven } _tl }
+        \tl_if_exist:cF { \l_tmpa_tl }
+          { \int_incr:N \g_@@_scale_int }
         \tl_set:cn { \l_tmpa_tl } {##1}
       }
-    \IfValueT {#1} { \cs_set:Nn \zhnum_scale_map_hook:n {#1} }
+    \IfNoValueF {#1}
+      { \cs_set:Npn \zhnum_scale_map_hook:n ##1 {#1} }
   }
 %    \end{macrocode}
 % \end{macro}
-%
-% \begin{macro}[internal]{\zhnum_int_to_word:n}
-% 将整数转换成英文单词。
+
+% 根据需要设置中文阿拉伯数字。
 %    \begin{macrocode}
-\cs_new_nopar:Nn \zhnum_int_to_word:n
-  {
-    \if_case:w \int_eval:n {#1} \exp_stop_f:
-           zero
-      \or: one
-      \or: two
-      \or: three
-      \or: four
-      \or: five
-      \or: six
-      \or: seven
-      \or: eight
-      \or: nine
-      \or: ten
-      \or: eleven
-    \else:
-      \int_case:nnn {#1}
+\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 } ,
+    }
+  \clist_map_inline:nn
+    { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 100 , 1000 }
+    {
+      \tl_put_right:Nx \l_tmpa_tl
         {
-          { 20 } { twenty }  { 30  } { thirty }
-          { 40 } { forty }   { 200 } { two_hundred }
+           #1 .tl_set:N = \exp_not:c { l_@@_ #1 _tl } ,
+          F#1 .tl_set:N = \exp_not:c { l_@@_financial_ #1 _tl } ,
         }
-        { \int_to_roman:n {#1} }
-    \fi:
+    }
+  \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
+    { 4 , 8 , 12 , 16 , 20 , 24 , 28 , 32 , 36 , 40 , 44 }
+    {
+      \tl_put_right:Nx \l_tmpa_tl
+        { E#1 .tl_set:N = \exp_not:c { l_@@_ s \int_eval:n { #1 / 4 } _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}
-% \end{macro}
-
-% 根据需要设置中文阿拉伯数字。
+%
+% \begin{macro}[internal]
+%   {
+%     \zhnum_set_digits_map:nn,
+%     \zhnum_set_digits_map:nnn,
+%     \zhnum_set_financial_map:nn,
+%     \zhnum_set_financial_map:nnn,
+%     \l_@@_cfg_map_prop,
+%     \l_@@_cfg_map_var_prop,
+%     \l_@@_cfg_map_finan_prop
+%   }
+% 将配置文件中的中文数字保存到 \texttt{prop} 变量中。
 %    \begin{macrocode}
-\keys_define:nn { zhnum / options }
-  {
-    -   .tl_set:N = \l_zhnum_minus_tl        ,
-    -0  .tl_set:N = \l_zhnum_null_tl         ,
-    E2  .tl_set:N = \l_zhnum_hundred_tl      ,
-    E3  .tl_set:N = \l_zhnum_thousand_tl     ,
-    FE2 .tl_set:N = \l_zhnum_financial_hundred_tl ,
-    FE3 .tl_set:N = \l_zhnum_financial_thousand_tl ,
-  }
-\clist_map_inline:nn
-  { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 20 , 30 , 40 , 200 }
+\cs_new_protected_nopar:Npn \zhnum_set_digits_map:nn #1#2
+  { \prop_put:Nnn \l_@@_cfg_map_prop {#1} {#2} }
+\cs_new_protected_nopar:Npn \zhnum_set_digits_map:nnn #1#2#3
   {
-    \keys_define:nn { zhnum / options }
-      { #1 .tl_set:c = { l_zhnum_ \zhnum_int_to_word:n {#1} _tl } }
-    \int_compare:nNnF {#1} > \c_ten
-      {
-        \keys_define:nn { zhnum / options }
-          { F#1 .tl_set:c = { l_zhnum_financial_ \zhnum_int_to_word:n {#1} _tl } }
-      }
-  }
-\clist_map_inline:nn
-  { 4 , 8 , 12 , 16 , 20 , 24 , 28 , 32 , 36 , 40 , 44 }
-  {
-    \keys_define:nn { zhnum / options }
-      { E#1 .tl_set:c = { l_zhnum_scale_ \zhnum_int_to_word:n { #1 / 4 } _tl } }
+    \prop_put_if_new:Nnn \l_@@_cfg_map_prop {#1} {#3}
+    \prop_put:Nnn \l_@@_cfg_map_var_prop {#1_#2} {#3}
   }
-\clist_map_inline:nn
+\cs_new_protected_nopar:Npn \zhnum_set_financial_map:nn #1#2
+  { \prop_put:Nnn \l_@@_cfg_map_finan_prop {#1} {#2} }
+\cs_new_protected_nopar:Npn \zhnum_set_financial_map:nnn #1#2#3
   {
-    dot , and , parts , year , month , day , weekday , hour , minute
-    mon , tue , wed , thu , fri , sat , sun
+    \prop_put_if_new:Nnn \l_@@_cfg_map_finan_prop {#1} {#3}
+    \prop_put:Nnn \l_@@_cfg_map_var_prop { financial_#1_#2 } {#3}
   }
-  { \keys_define:nn { zhnum / options } { #1 .tl_set:c = { l_zhnum_ #1 _tl } } }
+\prop_new:N \l_@@_cfg_map_prop
+\prop_new:N \l_@@_cfg_map_var_prop
+\prop_new:N \l_@@_cfg_map_finan_prop
 %    \end{macrocode}
+% \end{macro}
 %
 % \begin{macro}[internal]
-% {\zhnum_parse_config:,\zhnum_check_simp:nn,\zhnum_check_financial:nn,
-%  \zhnum_set_zero:,\zhnum_set_week_day:}
-% 将配置文件中的中文数字保存起来。
+%   {
+%     \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_nopar:Nn \zhnum_parse_config:
+\cs_new_protected_nopar:Npn \zhnum_parse_config:
   {
-    \prop_map_function:NN \g_zhnum_cfg_map_prop \zhnum_check_simp:nn
-    \prop_map_function:NN \g_zhnum_cfg_map_prop \zhnum_check_financial:nn
+    \prop_map_function:NN \l_@@_cfg_map_prop \zhnum_check_simp:nn
+    \bool_if:NF \l_@@_reset_bool
+      { \prop_map_function:NN \l_@@_cfg_map_prop \zhnum_check_financial:nn }
     \zhnum_set_zero:
     \zhnum_set_week_day:
   }
-\cs_new_nopar:Nn \zhnum_check_simp:nn
+\cs_new_protected_nopar:Npn \zhnum_check_simp:nn #1#2
   {
-    \zhnum_check_simp_aux:nn {#1} {#2}
-    \prop_get:NnNT \g_zhnum_cfg_map_finan_prop {#1} \l_tmpa_tl
-      { \exp_args:NnV \zhnum_check_simp_aux:nn { financial_ #1 } \l_tmpa_tl }
+    \@@_check_simp_aux:nn {#1} {#2}
+    \prop_get:NnNT \l_@@_cfg_map_finan_prop {#1} \l_tmpa_tl
+      { \exp_args:Nno \@@_check_simp_aux:nn { financial_ #1 } \l_tmpa_tl }
   }
-\cs_new_nopar:Nn \zhnum_check_simp_aux:nn
+\cs_new_protected_nopar:Npn \@@_check_simp_aux:nn #1#2
   {
-    \prop_get:NnNTF \g_zhnum_cfg_map_var_prop { #1 _trad } \l_tmpa_tl
+    \prop_get:NnNTF \l_@@_cfg_map_var_prop { #1 _trad } \l_tmpa_tl
       {
-        \prop_get:NnNTF \g_zhnum_cfg_map_var_prop { #1 _simp } \l_tmpb_tl
+        \prop_get:NnNTF \l_@@_cfg_map_var_prop { #1 _simp } \l_tmpb_tl
           {
-            \tl_set:cx { l_zhnum_ #1 _tl }
+            \tl_set:cx { l_@@_ #1 _tl }
               {
-                \exp_not:n { \bool_if:NTF \l_zhnum_simp_bool }
-                  { \exp_not:V \l_tmpb_tl } { \exp_not:V \l_tmpa_tl }
+                \exp_not:n { \bool_if:NTF \l_@@_simp_bool }
+                  { \exp_not:o \l_tmpb_tl } { \exp_not:o \l_tmpa_tl }
               }
           }
           {
-            \tl_set:cx { l_zhnum_ #1 _tl }
+            \tl_set:cx { l_@@_ #1 _tl }
               {
-                \exp_not:n { \bool_if:NTF \l_zhnum_simp_bool }
-                  { \exp_not:n {#2} } { \exp_not:V \l_tmpa_tl }
+                \exp_not:n { \bool_if:NTF \l_@@_simp_bool }
+                  { \exp_not:n {#2} } { \exp_not:o \l_tmpa_tl }
               }
           }
       }
-      { \tl_set:cn { l_zhnum_ #1 _tl } {#2} }
+      { \tl_set:cn { l_@@_ #1 _tl } {#2} }
   }
-\cs_new_nopar:Nn \zhnum_check_financial:nn
+\cs_new_protected_nopar:Npn \zhnum_check_financial:nn #1#2
   {
-    \prop_get:NnNTF \g_zhnum_cfg_map_finan_prop {#1} \l_tmpa_tl
+    \prop_get:NnNTF \l_@@_cfg_map_finan_prop {#1} \l_tmpa_tl
       {
-        \tl_set:cx { c_zhnum_ #1 _tl }
+        \zhnum_assgin_const_tl:cx { c_@@_ #1 _tl }
           {
-            \exp_not:n { \bool_if:NTF \l_zhnum_normal_bool }
-              { \exp_not:c { l_zhnum_ #1 _tl } }
-              { \exp_not:c { l_zhnum_financial_ #1 _tl } }
+            \exp_not:n { \bool_if:NTF \l_@@_normal_bool }
+              { \exp_not:c { l_@@_ #1 _tl } }
+              { \exp_not:c { l_@@_financial_ #1 _tl } }
           }
       }
-      { \tl_set:cx { c_zhnum_ #1 _tl } { \exp_not:c { l_zhnum_ #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_nopar:Nn \zhnum_set_zero:
+\cs_new_protected_nopar:Npn \zhnum_set_week_day:
   {
-    \tl_set:Nx \l_zhnum_zero_tl
+    \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 }
+    \bool_if:NF \l_@@_reset_bool
       {
-        \exp_not:n { \bool_if:nTF \l_zhnum_null_bool }
-          { \exp_not:V \l_zhnum_null_tl } { \exp_not:V \l_zhnum_zero_tl }
+        \clist_map_inline:nn { mon , tue , wed , thu , fri , sat , sun }
+          {
+            \zhnum_assgin_const_tl:cx
+              { c_@@_ ##1 _tl } { \exp_not:c { l_@@_ ##1 _tl } }
+          }
+        \bool_set_true:N \l_@@_reset_bool
       }
   }
-\cs_new_nopar:Nn \zhnum_set_week_day:
+\cs_new_eq:NN \zhnum_assgin_const_tl:cx \tl_const:cx
+\AtEndOfPackage
+  { \cs_set_eq:NN \zhnum_assgin_const_tl:cx \tl_set:cx }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{\zhnum_set_alias:}
+% 一些易于使用的别名。
+%    \begin{macrocode}
+\cs_new_protected_nopar:Npn \zhnum_set_alias:
   {
-    \tl_set:Nx \l_zhnum_mon_tl { \exp_not:N \c_zhnum_weekday_tl \exp_not:V \l_zhnum_one_tl   }
-    \tl_set:Nx \l_zhnum_tue_tl { \exp_not:N \c_zhnum_weekday_tl \exp_not:V \l_zhnum_two_tl   }
-    \tl_set:Nx \l_zhnum_wed_tl { \exp_not:N \c_zhnum_weekday_tl \exp_not:V \l_zhnum_three_tl }
-    \tl_set:Nx \l_zhnum_thu_tl { \exp_not:N \c_zhnum_weekday_tl \exp_not:V \l_zhnum_four_tl  }
-    \tl_set:Nx \l_zhnum_fri_tl { \exp_not:N \c_zhnum_weekday_tl \exp_not:V \l_zhnum_five_tl  }
-    \tl_set:Nx \l_zhnum_sat_tl { \exp_not:N \c_zhnum_weekday_tl \exp_not:V \l_zhnum_six_tl   }
-    \tl_set:Nx \l_zhnum_sun_tl { \exp_not:N \c_zhnum_weekday_tl \exp_not:V \l_zhnum_day_tl   }
-    \clist_map_inline:nn { mon , tue , wed , thu , fri , sat , sun }
-      { \tl_set:cx { c_zhnum_ ##1 _tl } { \exp_not:c { l_zhnum_ ##1 _tl } } }
+    \tl_const:Nx \c_@@_zero_tl     { \exp_not:c { c_@@_ 0 _tl } }
+    \tl_const:Nx \c_@@_ten_tl      { \exp_not:c { c_@@_ 10 _tl } }
+    \tl_const:Nx \c_@@_hundred_tl  { \exp_not:c { c_@@_ 100 _tl } }
+    \tl_const:Nx \c_@@_thousand_tl { \exp_not:c { c_@@_ 1000 _tl } }
   }
+\AtEndOfPackage { \zhnum_set_alias: }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[internal]{\zhnum_load_cfg:}
+% \begin{macro}[internal]{\zhnum_load_cfg:n}
 % 根据选定编码载入配置文件。
 %    \begin{macrocode}
-\cs_new:Nn \zhnum_load_cfg:n
+\cs_new_protected_nopar:Npn \zhnum_load_cfg:n #1
+  {
+    \zhnum_set_cfg_name:Nn \l_@@_cfg_tl {#1}
+    \tl_if_eq:NNF \l_@@_cfg_tl \l_@@_last_cfg_tl
+      { \zhnum_update_cfg:n {#1} }
+    \zhnum_parse_config:
+  }
+\cs_generate_variant:Nn \zhnum_load_cfg:n { o }
+\cs_new_protected_nopar:Npn \zhnum_update_cfg:n #1
+  {
+    \prop_if_exist:cTF { g_@@_cfg_ \l_@@_cfg_tl _prop }
+      { \tl_set_eq:NN \l_@@_last_cfg_tl \l_@@_cfg_tl }
+      { \zhnum_input_cfg:n  {#1} }
+    \@@_update_cfg_prop:N \prop_set_eq:Nc
+  }
+\cs_new_protected_nopar:Npn \zhnum_input_cfg:n #1
   {
-    \cs_if_exist:NT \CJK@makeActive
+    \file_if_exist_input:nTF { zhnumber - #1 .cfg }
       {
-        \int_compare:nNnTF { \char_value_catcode:n {"080} } = \active
-          { \bool_set_false:N \l_zhnum_set_CJK_active_bool }
-          { \bool_set_true:N \l_zhnum_set_CJK_active_bool \CJK@makeActive }
+        \bool_set_false:N \l_@@_reset_bool
+        \@@_update_cfg_prop:N \@@_prop_initial:Nn
+        \group_begin:
+          \zhnum_set_catcode:
       }
-    \prop_clear:N \g_zhnum_cfg_map_prop
-    \prop_clear:N \g_zhnum_cfg_map_var_prop
-    \prop_clear:N \g_zhnum_cfg_map_finan_prop
-    \file_input:n { zhnumber - #1 .cfg }
-    \zhnum_parse_config:
-    \bool_if:nT { \cs_if_exist_p:N \CJK@makeInactive && \l_zhnum_set_CJK_active_bool }
-      { \CJK@makeInactive }
+      {
+        \msg_error:nnx { zhnumber } { file-not-found } {#1}
+        \use_none:nnn
+      }
+    \@@_update_cfg_prop:N \@@_prop_gset_eq:Nn
+    \group_end:
+  }
+\cs_new_protected_nopar:Npn \@@_update_cfg_prop:N #1
+  {
+    #1 \l_@@_cfg_map_prop       { g_@@_cfg_ \l_@@_cfg_tl _prop }
+    #1 \l_@@_cfg_map_var_prop   { g_@@_cfg_var_ \l_@@_cfg_tl _prop }
+    #1 \l_@@_cfg_map_finan_prop { g_@@_cfg_finan_ \l_@@_cfg_tl _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 }
+\tl_new:N \l_@@_cfg_tl
+\tl_new:N \l_@@_last_cfg_tl
+\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}[internal]
-% {\zhnum_set_digits_map:nn,\zhnum_set_digits_map:nnn,
-%  \zhnum_set_financial_map:nn,\zhnum_set_financial_map:nnn}
+% \begin{macro}[internal,pTF]{\zhnum_if_unicode_engine:}
+% 使用 \upTeX{} 的时候，也不必将汉字的首字符设置为活动字符。判断 |^^^^0021| 是否为
+% 单个记号的办法对 \upTeX{} 不适用。因此，参考 \pkg{ifuptex} 宏包，通过 \tn{kchar}
+% 是否为 primitive 来判断。
 %    \begin{macrocode}
-\cs_new_protected_nopar:Nn \zhnum_set_digits_map:nn
-  { \prop_put:Nnn \g_zhnum_cfg_map_prop {#1} {#2} }
-\cs_new_protected_nopar:Nn \zhnum_set_digits_map:nnn
+\pdftex_if_engine:TF
   {
-    \prop_put_if_new:Nnn \g_zhnum_cfg_map_prop {#1} {#3}
-    \prop_put:Nnn \g_zhnum_cfg_map_var_prop {#1_#2} {#3}
+    \str_if_eq_x:nnTF
+      { \token_to_str:N \kchar }
+      { \token_to_meaning:N \kchar }
   }
-\cs_new_protected_nopar:Nn \zhnum_set_financial_map:nn
-  { \prop_put:Nnn \g_zhnum_cfg_map_finan_prop {#1} {#2} }
-\cs_new_protected_nopar:Nn \zhnum_set_financial_map:nnn
+  { \use_i:nn }
   {
-    \prop_put_if_new:Nnn \g_zhnum_cfg_map_finan_prop {#1} {#3}
-    \prop_put:Nnn \g_zhnum_cfg_map_var_prop { financial_#1_#2 } {#3}
+    \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}[internal]
-% {\g_zhnum_cfg_map_prop,\g_zhnum_cfg_map_var_prop,\g_zhnum_cfg_map_finan_prop}
+%   {
+%     \zhnum_set_catcode:,
+%     \zhnum_set_cfg_name:Nn,
+%     \zhnum_reset_config:
+%   }
+% 设置与恢复配置文件前后的 catcode。\pdfLaTeX{} 需要将汉字的首字节设置为活动字符。
 %    \begin{macrocode}
-\prop_new:N \g_zhnum_cfg_map_prop
-\prop_new:N \g_zhnum_cfg_map_var_prop
-\prop_new:N \g_zhnum_cfg_map_finan_prop
+\if_predicate:w \zhnum_if_unicode_engine_p:
+  \cs_new_eq:NN \zhnum_set_catcode: \prg_do_nothing:
+  \cs_new_protected_nopar:Npn \zhnum_set_cfg_name:Nn #1#2
+    {
+      \tl_set:Nx \l_@@_encoding_tl {#2}
+      \tl_set:Nx #1 { \tl_to_str:N \l_@@_encoding_tl }
+    }
+  \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_tl }
+        {
+          { 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:nnnN
+        { \l_@@_byte_min_int } { \c_one }
+        { \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_nopar:Npn \zhnum_set_cfg_name:Nn #1#2
+    {
+      \tl_set:Nx \l_@@_encoding_tl {#2}
+      \tl_set:Nx #1
+        {
+          \tl_to_str:N \l_@@_encoding_tl
+          \bool_if:NT \l_@@_active_char_bool
+            { \tl_to_str:n { _active } }
+        }
+    }
+  \cs_new_protected_nopar:Npn \zhnum_reset_config:
+    { \zhnum_load_cfg:o { \l_@@_encoding_tl } }
+  \bool_new:N \l_@@_active_char_bool
+  \bool_set_true:N \l_@@_active_char_bool
+\fi:
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1174,48 +1539,48 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %    \begin{macrocode}
 \keys_define:nn { zhnum / options }
   {
-    encoding      .choice_code:n =
+    encoding         .choices:nn =
+      { UTF8 , GBK , Big5 }
       {
-        \tl_gset:Nx \c_zhnum_encoding_tl
-          { \exp_args:NV \tl_expandable_lowercase:n \l_keys_choice_tl }
-        \zhnum_load_cfg:n { \c_zhnum_encoding_tl }
+        \tl_set:Nx \l_@@_encoding_tl
+          { \exp_args:No \tl_expandable_lowercase:n { \l_keys_choice_tl } }
+        \zhnum_load_cfg:o { \l_@@_encoding_tl }
       } ,
-    encoding .generate_choices:n = { UTF8 , GBK , Big5 } ,
     encoding          .default:n = { GBK } ,
     encoding / Bg5       .meta:n = { encoding = Big5 } ,
     encoding / unknown   .code:n =
-      { \msg_error:nnx { zhnumber } { encoding-invalid } { \l_keys_value_tl } } ,
+      { \msg_error:nnn { zhnumber } { encoding-invalid } {#1} } ,
     style .multichoice: ,
     style / Normal       .code:n =
       {
-        \bool_set_false:N \l_zhnum_ancient_bool
-        \bool_set_true:N  \l_zhnum_normal_bool
+        \bool_set_false:N \l_@@_ancient_bool
+        \bool_set_true:N  \l_@@_normal_bool
       } ,
     style / Financial    .code:n =
       {
-        \bool_set_false:N \l_zhnum_ancient_bool
-        \bool_set_false:N \l_zhnum_normal_bool
+        \bool_set_false:N \l_@@_ancient_bool
+        \bool_set_false:N \l_@@_normal_bool
       } ,
     style / Ancient      .code:n =
       {
-        \bool_set_true:N \l_zhnum_ancient_bool
-        \bool_set_true:N \l_zhnum_normal_bool
+        \bool_set_true:N \l_@@_ancient_bool
+        \bool_set_true:N \l_@@_normal_bool
       } ,
-    style / Simplified   .code:n = { \bool_set_true:N  \l_zhnum_simp_bool } ,
-    style / Traditional  .code:n = { \bool_set_false:N \l_zhnum_simp_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_zhnum_null_bool ,
+    null             .bool_set:N = \l_@@_null_bool ,
     time .choice: ,
-    time / Chinese       .code:n = { \bool_set_true:N \l_zhnum_time_bool } ,
-    time / Arabic        .code:n = { \bool_set_false:N  \l_zhnum_time_bool } ,
+    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_load_cfg:n { \c_zhnum_encoding_tl } } ,
-  }
-\msg_new:nnn { zhnumber } { encoding-invalid }
-  {
-    The~encoding~'#1'~is~invalid,~please~check~it~over.\\\\
-    Available~encoding~are~'UTF8',~'GBK'~and~'Big5'.\\
+    reset                .code:n = { \zhnum_reset_config: } ,
+    activechar       .bool_set:N = \l_@@_active_char_bool ,
   }
+\tl_new:N \l_@@_encoding_tl
+\msg_new:nnnn { zhnumber } { encoding-invalid }
+  { The~encoding~`#1'~is~invalid. }
+  { Available~encoding~are~`UTF8',~`GBK'~and~`Big5'. }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1238,19 +1603,12 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %
 % 如果没有选定编码，则根据引擎自动设置编码。
 %    \begin{macrocode}
-\ExplSyntaxOn
-\tl_if_exist:NF \c_zhnum_encoding_tl
+\tl_if_empty:NT \l_@@_encoding_tl
   {
-    \exp_args:Nnx \keys_set:nn { zhnum / options }
-      {
-        encoding =
-          {
-            \bool_if:nTF { \xetex_if_engine_p: || \luatex_if_engine_p: }
-              { UTF8 } { GBK }
-          }
-      }
+    \zhnum_if_unicode_engine:TF
+      { \keys_set:nn { zhnum / options } { encoding = UTF8 } }
+      { \keys_set:nn { zhnum / options } { encoding = GBK } }
   }
-\ExplSyntaxOff
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -1266,35 +1624,35 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %
 %    \begin{macrocode}
 %<*!big5>
-\zhnum_set_digits_map:nnn { minus } { simp }  { 负 }
-\zhnum_set_digits_map:nnn { minus } { trad }  { 負 }
+\zhnum_set_digits_map:nnn { minus } { simp } { 负 }
+\zhnum_set_digits_map:nnn { minus } { trad } { 負 }
 %</!big5>
 %<*big5>
-\zhnum_set_digits_map:nn { minus }       { 負 }
+\zhnum_set_digits_map:nn { minus } { 負 }
 %</big5>
-\zhnum_set_digits_map:nn { zero }        { 零 }
+\zhnum_set_digits_map:nn { 0 }     { 零 }
 %<*!big5>
-\zhnum_set_digits_map:nn { null }        { 〇 }
+\zhnum_set_digits_map:nn { null }  { 〇 }
 %</!big5>
 %<*big5>
-\zhnum_set_digits_map:nn { null }        { ○ }
+\zhnum_set_digits_map:nn { null }  { ○ }
 %</big5>
-\zhnum_set_digits_map:nn { one }         { 一 }
-\zhnum_set_digits_map:nn { two }         { 二 }
-\zhnum_set_digits_map:nn { three }       { 三 }
-\zhnum_set_digits_map:nn { four }        { 四 }
-\zhnum_set_digits_map:nn { five }        { 五 }
-\zhnum_set_digits_map:nn { six }         { 六 }
-\zhnum_set_digits_map:nn { seven }       { 七 }
-\zhnum_set_digits_map:nn { eight }       { 八 }
-\zhnum_set_digits_map:nn { nine }        { 九 }
-\zhnum_set_digits_map:nn { ten }         { 十 }
-\zhnum_set_digits_map:nn { hundred }     { 百 }
-\zhnum_set_digits_map:nn { thousand }    { 千 }
-\zhnum_set_digits_map:nn { twenty }      { 廿 }
-\zhnum_set_digits_map:nn { thirty }      { 卅 }
-\zhnum_set_digits_map:nn { forty }       { 卌 }
-\zhnum_set_digits_map:nn { two_hundred } { 皕 }
+\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 } { 點 }
@@ -1304,81 +1662,78 @@ and some specific Chinese Simplified fonts (TrueType or OpenType).
 %</big5>
 \zhnum_set_digits_map:nn { and }   { 又 }
 \zhnum_set_digits_map:nn { parts } { 分之 }
-\zhnum_set_digits_map:nn { scale_zero }   { }
+\zhnum_set_digits_map:nn { s0 }    { }
 %<*!big5>
-\zhnum_set_digits_map:nnn { scale_one } { simp } { 万 }
-\zhnum_set_digits_map:nnn { scale_one } { trad } { 萬 }
-\zhnum_set_digits_map:nnn { scale_two } { simp } { 亿 }
-\zhnum_set_digits_map:nnn { scale_two } { trad } { 億 }
+\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 { scale_one }    { 萬 }
-\zhnum_set_digits_map:nn { scale_two }    { 億 }
+\zhnum_set_digits_map:nn { s1 }    { 萬 }
+\zhnum_set_digits_map:nn { s2 }    { 億 }
 %</big5>
-\zhnum_set_digits_map:nn { scale_three }  { 兆 }
-\zhnum_set_digits_map:nn { scale_four }   { 京 }
-\zhnum_set_digits_map:nn { scale_five }   { 垓 }
-\zhnum_set_digits_map:nn { scale_six }    { 秭 }
-\zhnum_set_digits_map:nn { scale_seven }  { 穰 }
+\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 { scale_eight } { simp }  { 沟 }
-\zhnum_set_digits_map:nnn { scale_eight } { trad }  { 溝 }
-\zhnum_set_digits_map:nnn { scale_nine  } { simp }  { 涧 }
-\zhnum_set_digits_map:nnn { scale_nine  } { trad }  { 澗 }
+\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 { scale_eight }  { 澗 }
+\zhnum_set_digits_map:nn { s8 }    { 溝 }
+\zhnum_set_digits_map:nn { s9 }    { 澗 }
 %</big5>
-\zhnum_set_digits_map:nn { scale_ten }    { 正 }
+\zhnum_set_digits_map:nn { s10 }   { 正 }
 %<*!big5>
-\zhnum_set_digits_map:nnn { scale_eleven } { simp } { 载 }
-\zhnum_set_digits_map:nnn { scale_eleven } { trad } { 載 }
+\zhnum_set_digits_map:nnn { s11 }   { simp } { 载 }
+\zhnum_set_digits_map:nnn { s11 }   { trad } { 載 }
 %</!big5>
 %<*big5>
-\zhnum_set_digits_map:nn { scale_eleven } { 載 }
+\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 }     { 日 }
+\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 } { 時 }
+\zhnum_set_digits_map:nnn { hour }  { simp } { 时 }
+\zhnum_set_digits_map:nnn { hour }  { trad } { 時 }
 %</!big5>
 %<*big5>
-\zhnum_set_digits_map:nn { hour }    { 時 }
+\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 { zero }     { 零 }
-\zhnum_set_financial_map:nn { one }      { 壹 }
-\zhnum_set_financial_map:nn { two }      { 貳 }
+\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 { three } { simp } { 叁 }
-\zhnum_set_financial_map:nnn { three } { trad } { 叄 }
+\zhnum_set_financial_map:nnn { 3 }  { simp } { 叁 }
+\zhnum_set_financial_map:nnn { 3 }  { trad } { 叄 }
 %</!big5>
 %<*big5>
-\zhnum_set_financial_map:nn { three }    { 參 }
+\zhnum_set_financial_map:nn { 3 }    { 參 }
 %</big5>
-\zhnum_set_financial_map:nn { four }     { 肆 }
-\zhnum_set_financial_map:nn { five }     { 伍 }
+\zhnum_set_financial_map:nn { 4 }    { 肆 }
+\zhnum_set_financial_map:nn { 5 }    { 伍 }
 %<*!big5>
-\zhnum_set_financial_map:nnn { six }   { simp } { 陆 }
-\zhnum_set_financial_map:nnn { six }   { trad } { 陸 }
+\zhnum_set_financial_map:nnn { 6 }  { simp } { 陆 }
+\zhnum_set_financial_map:nnn { 6 }  { trad } { 陸 }
 %</!big5>
 %<*big5>
-\zhnum_set_financial_map:nn { six }      { 陸 }
+\zhnum_set_financial_map:nn { 6 }    { 陸 }
 %</big5>
-\zhnum_set_financial_map:nn { seven }    { 柒 }
-\zhnum_set_financial_map:nn { eight }    { 捌 }
-\zhnum_set_financial_map:nn { nine }     { 玖 }
-\zhnum_set_financial_map:nn { ten }      { 拾 }
-\zhnum_set_financial_map:nn { hundred }  { 佰 }
-\zhnum_set_financial_map:nn { thousand } { 仟 }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\ExplSyntaxOff
+\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 } { 仟 }
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-- 
cgit v1.2.3

