% \iffalse meta-comment
% !TEX program  = XeLaTeX
%<*internal>
\iffalse
%</internal>
%<*readme>
Introduction
------------
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.

It may be distributed and/or modified under the conditions of the
LaTeX Project Public License (LPPL), either version 1.3c of this license or
(at your option) any later version. 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 work 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 (this file).

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.

Author
------
Qing Lee
Email: sobenlee@gmail.com

If you are interested in the process of development you may observe

    http://code.google.com/p/ctex-kit/

Installation
------------
The package is supplied in dtx format and as a pre-extracted zip file,
zhnumber.tds.zip. The later is most convenient for most users: simply
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.

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.
Suitable versions are available in the latest version of MiKTeX and TeX Live
(updating the relevant packages online may be necessary).

To compile the documentation without error, you will need the xeCJK package
and some specific Chinese Simplified fonts (TrueType or OpenType).
%</readme>
%<*internal>
\fi
\ifnum\strcmp{\fmtname}{plain}=0 \else
  \expandafter\begingroup
\fi
%</internal>
%<*batchfile>
\input docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble

   Copyright (C) 2012 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
   of this license or (at your option) any later version.
   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.
\endpostamble
\ifnum\shellescape=1 \else
  \errmessage{
    Shell escape is disabled. Please use ^^J^^J
    xe(la)tex -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
%<*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>
\NeedsTeXFormat{LaTeX2e}
%<*driver>
\ProvidesFile{zhnumber.dtx}
%</driver>
\RequirePackage{expl3}
%</driver|package>
%<package|config>\GetIdInfo$Id: zhnumber.dtx 351 2012-07-20 05:30:58Z sobenlee $
%<package>          {package for 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>\ProvidesExplFile
%<config&utf8>  {\ExplFileName-utf8.cfg}
%<config&big5>  {\ExplFileName-big5.cfg}
%<config&gbk>  {\ExplFileName-gbk.cfg}
%<config>  {\ExplFileDate} {1.6} {\ExplFileDescription}
%
%<*driver>
\documentclass{l3doc}
\usepackage{amsmath}
\usepackage{xeCJK}
\usepackage{zhnumber}
\usepackage{fvrb-ex}
\usepackage{metalogo}
\hypersetup{pdfstartview=FitH}
\setlist{nosep}
\linespread{1.1}
\addtolength{\voffset}{-5\baselineskip}
\addtolength\textheight{8\baselineskip}
\setmainfont{TeX Gyre Pagella}
\setmonofont{Inconsolata}
\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}
\makeatletter
\let\orig@meta\meta
\def\meta#1{\orig@meta{\normalfont\itshape#1}}
\def\TF{true\orvar{}false}
\def\TTF{\defaultvar{true}\orvar{}false}
\def\TFF{true\orvar\defaultvar{false}}
\def\orvar{\char`\|}
\let\defaultvar\textbf
\def\argbrace#1{\char`\{#1\char`\}}
\@addtoreset{CodelineNo}{section}
\makeatother
\def\indexname{代码索引}
\IndexPrologue{%
  \section*{\indexname}
  \markboth{\indexname}{\indexname}
  斜体的数字表示对应项说明所在的页码，下划线的数字表示定义所在的代码行号，而直立体的
  数字表示对应项使用时所在的行号。}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \GetFileInfo{\jobname.sty}
%
% \title{\bfseries\pkg{zhnumber} 宏包}
% \author{李清\\ \path{sobenlee@gmail.com}}
% \date{\filedate\qquad\fileversion}
% \maketitle
%
% \begin{documentation}
%
% \section{简介}
% \pkg{zhnumber} 宏包用于将阿拉伯数字按照中文格式输出。相比于 \pkg{CJKnumb}，它提供
% 的三个格式转换命令 |\zhnumber|，|\zhdigits| 和 |\zhnum| 都是可以适当展开的，可以
% 正常使用于 |PDF| 书签和交叉引用。
%
% \pkg{zhnumber} 支持 |GBK|，|Big5| 和 |UTF8| 编码，依赖 \LaTeX~3 项目的 \pkg{expl3}，
% \pkg{xparse} 和 \pkg{l3keys2e} 宏包。
%
% \section{使用方法}
%
% \begin{function}[updated=2012-5-25]{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} 宏包之后载入。
% \end{function}
%
% \begin{function}{\zhnumber}
%   \begin{syntax}
%     \cs{zhnumber} \marg{number}
%   \end{syntax}
%   以中文格式输出数字。这里的数字可以是整数、小数和分数。例如\\[1ex]
%   \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}{\zhdigits}
%   \begin{syntax}
%     \cs{zhdigits} \marg{number}
%   \end{syntax}
%   将阿拉伯数字转换为中文数字串。缺省状态下，|\zhdigits| 将 0 映射为〇，如果需要
%   将其映射为零，可以使用 |\zhdigits*|。例如\\[1ex]
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
%     \zhdigits{2012020120}\\
%     \zhdigits*{2012020120}
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}{\zhnum}
%   \begin{syntax}
%     \cs{zhnum} \marg{counter}
%   \end{syntax}
%   与 |\roman| 等类似，用于将 \LaTeX 计数器的值转换为中文数字。例如\\[1ex]
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
%     \zhnum{section}
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}[added=2012-5-25]{\zhweekday}
%   \begin{syntax}
%     \cs{zhweekday} \Arg{yyyy/mm/dd}
%   \end{syntax}
%   输出日期当天的星期。例如\\[1ex]
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
%     \zhweekday{2012/5/20}
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}[added=2012-5-25]{\zhdate}
%   \begin{syntax}
%     \cs{zhdate}  \Arg{yyyy/mm/dd}
%     \cs{zhdate*} \Arg{yyyy/mm/dd}
%   \end{syntax}
%   以中文格式输出日期，其中带 |*| 的命令还输出星期。例如\\[1ex]
%   \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}[added=2012-5-25]{\zhtoday}
%   与 |\today| 类似，以中文输出当天的日期。例如\\[1ex]
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
%     \zhtoday
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}[added=2012-5-25]{\zhtime}
%   \begin{syntax}
%     \cs{zhtime} \Arg{hh:mm}
%   \end{syntax}
%   以中文格式输出时间。例如\\[1ex]
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
%     \zhtime{23:56}
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}[added=2012-5-25]{\zhcurrtime}
%   输出当前的时间。例如\\[1ex]
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
%     \zhcurrtime
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}[added=2012-5-25]{\zhnumExtendScaleMap}
%   \begin{syntax}
%     \cs{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}，则当
%   数字大于 $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}, ...}
%   \end{syntax}
%   用于在导言区或文档中，设置中文数字的输出格式。目前可以设置的 \meta{key} 如下介绍。
% \end{function}
%
% \begin{function}[added=2012-5-25]{time}
%   \begin{syntax}
%     time =  \argbrace{\meta{Arabic}\orvar\meta{Chinese}}
%   \end{syntax}
%   设置日期和时间的数字格式，\meta{Arabic} 为阿拉伯数字，而 \meta{Chinese} 为中文数字。
%   默认使用阿拉伯数字。例如\\[1ex]
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.6\linewidth,gobble=5]
%     \zhnumsetup{time=Chinese}
%     \zhtoday\zhcurrtime
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}[updated=2012-5-25]{style}
%   \begin{syntax}
%     style = \argbrace{\meta{Simplified}\orvar\meta{Traditional}\orvar\meta{Normal}\orvar\meta{Financial}\orvar\meta{Ancient}}
%   \end{syntax}
%   意义分别为
%   \begin{itemize}[font=\ttfamily,labelsep=1em]
%     \item[Simplified]  以简体中文输出数字（对 |Big5| 编码无效）；
%     \item[Traditional] 以繁体中文输出数字（对 |Big5| 编码无效）；
%     \item[Normal] 以小写形式输出中文数字；
%     \item[Financial]  以大写形式输出中文数字；
%     \item[Ancient] 以廿输出 20，以卅输出 30，以卌输出 40，以皕输出 200。
%   \end{itemize}
%   可以设置 |style| 为其中一个，也可以是前三个与后两个的适当组合，默认是简体小写。例如\\[1ex]
%   \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 = \meta{\TFF}
%   \end{syntax}
%   缺省状态下，除了 |\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
%   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
%   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$ 的大写。其它的选项同
% 字面意思，不再赘述。例如
% \begin{verbatim}[frame=single]
%   \zhnumsetup{2={两}}
% \end{verbatim}
% 可以将 2 映射成两。需要说明的是，\pkg{zhnumber} 将优先使用这里的设置，所以可能会影响
% 到 |style| 选项。如果要恢复 |style| 的功能，可以使用 |reset| 选项。
%
% \begin{function}[updated=2012-5-25]{reset}
%   \begin{syntax}
%     reset
%   \end{syntax}
%   用于恢复 \pkg{zhnumber} 对阿拉伯数字的初始化映射。\pkg{zhnumber} 的中文数字初始化
%   设置见源代码（第 \ref{sec:zhnum-map} 节）。
% \end{function}
%
% \begin{function}{\zhnumber,\zhdigits,\zhnum}
%   \begin{syntax}
%     \cs{zhnumber} \oarg{options} \marg{number}
%     \cs{zhdigits} \oarg{options} \marg{number}
%     \cs{zhnum} \oarg{options} \marg{counter}
%   \end{syntax}
%   如果只改变当前数字的中文输出格式，可以使用带选项的格式转换命令，其中 \meta{options}
%   与 |\zhnumsetup| 的参数相同，如上所介绍。这些带了选项的命令是不可展开的，在某些场合使
%   用时要小心。
% \end{function}
%
% \end{documentation}
%
%
% \begin{implementation}
%
% \section{\pkg{zhnumber} 宏包代码实现}
%
%    \begin{macrocode}
%<*package>
%    \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 } { 2012/07/16 } { }
  { \msg_error:nn  { zhnumber }  { l3-too-old } }
%    \end{macrocode}
%
%    \begin{macrocode}
\RequirePackage{xparse}
\RequirePackage{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 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_number_aux:nNn}
%    \begin{macrocode}
\cs_new_nopar:Nn \zhnum_number_aux:nNn
  {
    \IfNoValueTF {#1} { #2 {#3} }
      { \group_begin: \zhnumsetup {#1} #2 {#3} \group_end: }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_number:w}
% 先判断输入的是小数还是分数。
%    \begin{macrocode}
\cs_new_nopar:Npn \zhnum_number:w #1.#2.#3 \q_stop
  {
    \quark_if_nil:nTF {#2}
      { \zhnum_integer_or_fraction:w #1 / \q_nil / \q_stop }
      { \zhnum_decimal:nn {#1} {#2} }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_integer_or_fraction:w}
% 判断是否输入的是分数。
%    \begin{macrocode}
\cs_new_nopar:Npn \zhnum_integer_or_fraction:w #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 }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_fraction:w}
% 对分数进行预处理。
%    \begin{macrocode}
\cs_new_nopar:Npn \zhnum_fraction:w #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 {#2}
      }
      {
        \tl_if_blank:fF {#2} { \zhnumber {#2} \c_zhnum_and_tl }
        \zhnum_blank_to_zero:f {#1} \c_zhnum_parts_tl
        \zhnum_blank_to_zero:f {#3}
      }
  }
\cs_generate_variant:Nn \tl_if_blank:nF { f }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_decimal:nn}
% 对小数进行预处理。
%    \begin{macrocode}
\cs_new_nopar:Nn \zhnum_decimal:nn
  {
    \zhnum_blank_to_zero:f {#1} \c_zhnum_dot_tl
    \tl_if_blank:fTF {#2} { \c_zhnum_zero_tl } { \zhdigits * {#2} }
  }
\cs_generate_variant:Nn \tl_if_blank:nTF { f }
%    \end{macrocode}
% \end{macro}
%
% \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_generate_variant:Nn \zhnum_blank_to_zero:n { f }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\zhnum}
% 用于将 \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} }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_integer:n}
% 对整数的处理。
%    \begin{macrocode}
\cs_new_nopar:Nn \zhnum_integer:n
  {
    \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} } }
  }
\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{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
  {
    \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}
      }
  }
\prg_new_conditional:Nnn \zhnum_if_number:N { p , T , F , TF }
  {
    \if_int_compare:w \c_one < 1 #1 \exp_stop_f:
      \prg_return_true: \else: \prg_return_false: \fi:
  }
\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{macrocode}
\cs_new_nopar:Nn \zhnum_parse_number:n
  {
    \zhnum_parse_number:nff {#1}
      { \tl_count:n {#1} }
      { \int_mod:nn { \tl_count:n {#1} } \c_four }
  }
\cs_new_nopar:Nn \zhnum_parse_number:nnn
  {
    \int_compare:nNnTF {#2} < \c_two
      { \zhnum_digit_map:n {#1} }
      {
        \zhnum_split_number:fNNfn { \zhnum_insert_zeros:n {#3} #1 }
          \c_true_bool \c_true_bool
          {
            \int_compare:nNnTF {#3} = \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 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_insert_zeros:n}
% 为了处理的方便，在整数前面补上适当的 $0$，使其位数可以被 $4$ 整除。
%    \begin{macrocode}
\cs_new_nopar:Nn \zhnum_insert_zeros:n
  {
    \if_case:w \int_eval:n { #1 - \c_one } \exp_stop_f:
      \or: \exp_after:wN \use_none:n
      \or: \exp_after:wN \use_none:nn
    \else: \exp_after:wN \use_none:nnn
    \fi:
    000
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_split_number:nNNnn}
% 将输入的整数由高位到低位，以四位为一段进行处理。
%    \begin{macrocode}
\cs_new_nopar:Nn \zhnum_split_number:nNNnn
  {
    \zhnum_split_number_aux:fnNNnn { \zhnum_number_item:nn {#1} {#5} }
      {#1} #2#3 {#4} {#5}
  }
\cs_new_nopar:Nn \zhnum_split_number_aux:nnNNnn
  {
    \int_compare:nNnTF {#1} = \c_zero { \use_i_ii:nnn }
      {
        \bool_if:NF #3 { \c_zhnum_zero_tl }
        \zhnum_process_number:NNn #3#4 {#1}
        \zhnum_scale_map:n { #5 - #6 }
        \int_compare:nNnTF { \int_mod:nn {#1} \c_ten } = \c_zero
          { \use_i_ii:nnn } { \zhnum_use_i_iii:nnn }
      }
    { \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 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_number_item:nn,\zhnum_number_item_aux:nNNNN}
% 截取整数的其中四位数。
%    \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
  {
    \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 } } }
  }
\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}
%    \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
  { \zhnum_process_number:NNNNNN #3#1#2 }
\cs_new_nopar:Nn \zhnum_process_number:NNNNNN
  {
    \int_compare:nNnTF {#1} = \c_zero
      { \bool_if:NF #6 { \c_zhnum_zero_tl } }
      { \zhnum_digit_map:n {#1} \c_zhnum_thousand_tl }
    \int_compare:nNnTF {#2} = \c_zero
      { \int_compare:nNnT { #1 * (#3#4) } > \c_zero { \c_zhnum_zero_tl } }
      {
        \bool_if:nTF
          { \l_zhnum_ancient_bool && \int_compare_p:nNn {#2} = \c_two }
          { \zhnum_digit_map:n { #2 00 } }
          { \zhnum_digit_map:n {#2} \c_zhnum_hundred_tl }
      }
    \int_compare:nNnTF {#3} = \c_zero
      { \int_compare:nNnT { #2 * #4 } > \c_zero { \c_zhnum_zero_tl } }
      {
        \bool_if:nF
          {
            \int_compare_p:nNn {#3}   = \c_one  &&
            \int_compare_p:nNn {#1#2} = \c_zero && #6 && #5
          }
          {
            \bool_if:nTF
              {
                \l_zhnum_ancient_bool                   &&
                ( \int_compare_p:nNn {#3} = \c_two   ||
                  \int_compare_p:nNn {#3} = \c_three ||
                  \int_compare_p:nNn {#3} = \c_four )
              }
              { \zhnum_digit_map:n { #3 0 } \use_none:n }
              { \zhnum_digit_map:n {#3} }
          }
        \c_zhnum_ten_tl
      }
    \int_compare:nNnF {#4} = \c_zero { \zhnum_digit_map:n {#4} }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\zhdigits}
% 将输入的数字输出为中文数字串输出。
%    \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 }
  }
\cs_new_nopar:Nn \zhnum_digits_aux:nnN
  {
    \IfNoValueTF {#1} { \tl_map_function:fN {#2} #3 }
      { \group_begin: \zhnumsetup {#1} \tl_map_function:fN {#2} #3 \group_end: }
  }
\cs_new_nopar:Nn \zhnum_digits_null:n { \tl_map_function:fN {#1} \zhnum_digits_null_aux:N }
\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{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
  {
    \str_if_eq_x:nnTF {#2} . \c_zhnum_dot_tl
      {
        \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} }
              }
          }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\zhdate}
% 输出中文日期。
%    \begin{macrocode}
\DeclareExpandableDocumentCommand \zhdate { s m }
  {
    \zhnum_date:w #2 \q_stop
    \IfBooleanT {#1} { \zhweekday {#2} }
  }
\cs_new_nopar:Npn \zhnum_date:w #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
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\zhtoday}
% 输出当天日期。
%    \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
  }
%    \end{macrocode}
% \end{macro}
%
% \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} }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\zhweekday}
% 输出星期
%    \begin{macrocode}
\cs_new_nopar:Npn \zhweekday #1 { \zhnum_week_day:w #1 \q_stop }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\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_nopar:Nn \zhnum_Zeller:nnn
  {
    \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 }
    {#1} {#2} {#3}
  }
\cs_new_nopar:Nn \zhnum_Zeller_aux:Nnnn
  {
    \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
  {
    \int_compare:nNnT {#1} < \c_ten { 0 }
    \int_eval:n {#1}
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\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_nopar:Nn \zhnum_Zeller_Gregorian:nnn
  {
    \int_mod:nn
      {
          \int_eval:n {#3}
        + \int_div_truncate:nn { 26 * ( \int_eval:n {#2} + \c_one ) } \c_ten
        + \int_eval:n {#1}
        + \int_div_truncate:nn {#1} \c_four
        + \c_six * \int_div_truncate:nn {#1} \c_one_hundred
        + \int_div_truncate:nn {#1} { 400 }
      }
      { \c_seven }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\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_nopar:Nn \zhnum_Zeller_Julian:nnn
  {
    \int_mod:nn
      {
          \int_eval:n {#3}
        + \int_div_truncate:nn { 26 * ( \int_eval:n {#2} + \c_one ) } \c_ten
        + \int_eval:n {#1}
        + \int_div_truncate:nn {#1} \c_four
        + \c_five
      }
      { \c_seven }
  }
%    \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 }
\group_begin:
\char_set_lccode:nn { `\; } { `\: }
\tl_to_lowercase:n
  {
    \group_end:
    \cs_new_nopar:Npn \zhnum_time:w #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
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\zhcurrtime}
% 输出当前时间。
%    \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
  }
%    \end{macrocode}
% \end{macro}
%
% \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 } }
%    \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_if_exist_use:cF { c_zhnum_scale_ \zhnum_int_to_word:n {#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_eq:NN \zhnum_scale_map_hook:n \zhnum_scale_map_loop:n
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\zhnumExtendScaleMap}
%    \begin{macrocode}
\NewDocumentCommand \zhnumExtendScaleMap { > { \TrimSpaces } o m }
  {
   \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 }
        \tl_set:cn { \l_tmpa_tl } {##1}
      }
    \IfValueT {#1} { \cs_set:Nn \zhnum_scale_map_hook:n {#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}
        {
          { 20 } { twenty }  { 30  } { thirty }
          { 40 } { forty }   { 200 } { two_hundred }
        }
        { \int_to_roman:n {#1} }
    \fi:
  }
%    \end{macrocode}
% \end{macro}

% 根据需要设置中文阿拉伯数字。
%    \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 }
  {
    \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 } }
  }
\clist_map_inline:nn
  {
    dot , and , parts , year , month , day , weekday , hour , minute
    mon , tue , wed , thu , fri , sat , sun
  }
  { \keys_define:nn { zhnum / options } { #1 .tl_set:c = { l_zhnum_ #1 _tl } } }
%    \end{macrocode}
%
% \begin{macro}[internal]
% {\zhnum_parse_config:,\zhnum_check_simp:nn,\zhnum_check_financial:nn,
%  \zhnum_set_zero:,\zhnum_set_week_day:}
% 将配置文件中的中文数字保存起来。
%    \begin{macrocode}
\cs_new_nopar:Nn \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
    \zhnum_set_zero:
    \zhnum_set_week_day:
  }
\cs_new_nopar:Nn \zhnum_check_simp:nn
  {
    \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 }
  }
\cs_new_nopar:Nn \zhnum_check_simp_aux:nn
  {
    \prop_get:NnNTF \g_zhnum_cfg_map_var_prop { #1 _trad } \l_tmpa_tl
      {
        \prop_get:NnNTF \g_zhnum_cfg_map_var_prop { #1 _simp } \l_tmpb_tl
          {
            \tl_set:cx { l_zhnum_ #1 _tl }
              {
                \exp_not:n { \bool_if:NTF \l_zhnum_simp_bool }
                  { \exp_not:V \l_tmpb_tl } { \exp_not:V \l_tmpa_tl }
              }
          }
          {
            \tl_set:cx { l_zhnum_ #1 _tl }
              {
                \exp_not:n { \bool_if:NTF \l_zhnum_simp_bool }
                  { \exp_not:n {#2} } { \exp_not:V \l_tmpa_tl }
              }
          }
      }
      { \tl_set:cn { l_zhnum_ #1 _tl } {#2} }
  }
\cs_new_nopar:Nn \zhnum_check_financial:nn
  {
    \prop_get:NnNTF \g_zhnum_cfg_map_finan_prop {#1} \l_tmpa_tl
      {
        \tl_set:cx { c_zhnum_ #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 } }
          }
      }
      { \tl_set:cx { c_zhnum_ #1 _tl } { \exp_not:c { l_zhnum_ #1 _tl } } }
  }
\cs_new_nopar:Nn \zhnum_set_zero:
  {
    \tl_set:Nx \l_zhnum_zero_tl
      {
        \exp_not:n { \bool_if:nTF \l_zhnum_null_bool }
          { \exp_not:V \l_zhnum_null_tl } { \exp_not:V \l_zhnum_zero_tl }
      }
  }
\cs_new_nopar:Nn \zhnum_set_week_day:
  {
    \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 } } }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\zhnum_load_cfg:}
% 根据选定编码载入配置文件。
%    \begin{macrocode}
\cs_new:Nn \zhnum_load_cfg:n
  {
    \cs_if_exist:NT \CJK@makeActive
      {
        \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 }
      }
    \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 }
  }
%    \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{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
  {
    \prop_put_if_new:Nnn \g_zhnum_cfg_map_prop {#1} {#3}
    \prop_put:Nnn \g_zhnum_cfg_map_var_prop {#1_#2} {#3}
  }
\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
  {
    \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}
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]
% {\g_zhnum_cfg_map_prop,\g_zhnum_cfg_map_var_prop,\g_zhnum_cfg_map_finan_prop}
%    \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
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{encoding,style,null,reset}
% 宏包设置选项。
%    \begin{macrocode}
\keys_define:nn { zhnum / options }
  {
    encoding      .choice_code:n =
      {
        \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 }
      } ,
    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 } } ,
    style .multichoice: ,
    style / Normal       .code:n =
      {
        \bool_set_false:N \l_zhnum_ancient_bool
        \bool_set_true:N  \l_zhnum_normal_bool
      } ,
    style / Financial    .code:n =
      {
        \bool_set_false:N \l_zhnum_ancient_bool
        \bool_set_false:N \l_zhnum_normal_bool
      } ,
    style / Ancient      .code:n =
      {
        \bool_set_true:N \l_zhnum_ancient_bool
        \bool_set_true:N \l_zhnum_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             .default:n = { Normal , Simplified } ,
    null             .bool_set:N = \l_zhnum_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              .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'.\\
  }
%    \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 }
\ProcessKeysOptions { zhnum / options }
%    \end{macrocode}
%
% 如果没有选定编码，则根据引擎自动设置编码。
%    \begin{macrocode}
\ExplSyntaxOn
\tl_if_exist:NF \c_zhnum_encoding_tl
  {
    \exp_args:Nnx \keys_set:nn { zhnum / options }
      {
        encoding =
          {
            \bool_if:nTF { \xetex_if_engine_p: || \luatex_if_engine_p: }
              { UTF8 } { GBK }
          }
      }
  }
\ExplSyntaxOff
%    \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 { zero }        { 零 }
%<*!big5>
\zhnum_set_digits_map:nn { null }        { 〇 }
%</!big5>
%<*big5>
\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 } { 皕 }
%<*!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 } { 分之 }
\zhnum_set_digits_map:nn { scale_zero }   { }
%<*!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 } { 億 }
%</!big5>
%<*big5>
\zhnum_set_digits_map:nn { scale_one }    { 萬 }
\zhnum_set_digits_map:nn { scale_two }    { 億 }
%</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 }  { 穰 }
%<*!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 }  { 澗 }
%</!big5>
%<*big5>
\zhnum_set_digits_map:nn { scale_eight }  { 澗 }
%</big5>
\zhnum_set_digits_map:nn { scale_ten }    { 正 }
%<*!big5>
\zhnum_set_digits_map:nnn { scale_eleven } { simp } { 载 }
\zhnum_set_digits_map:nnn { scale_eleven } { trad } { 載 }
%</!big5>
%<*big5>
\zhnum_set_digits_map:nn { scale_eleven } { 載 }
%</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 { zero }     { 零 }
\zhnum_set_financial_map:nn { one }      { 壹 }
\zhnum_set_financial_map:nn { two }      { 貳 }
%<*!big5>
\zhnum_set_financial_map:nnn { three } { simp } { 叁 }
\zhnum_set_financial_map:nnn { three } { trad } { 叄 }
%</!big5>
%<*big5>
\zhnum_set_financial_map:nn { three }    { 參 }
%</big5>
\zhnum_set_financial_map:nn { four }     { 肆 }
\zhnum_set_financial_map:nn { five }     { 伍 }
%<*!big5>
\zhnum_set_financial_map:nnn { six }   { simp } { 陆 }
\zhnum_set_financial_map:nnn { six }   { trad } { 陸 }
%</!big5>
%<*big5>
\zhnum_set_financial_map:nn { six }      { 陸 }
%</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
%    \end{macrocode}
%
%    \begin{macrocode}
%</config>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
% \Finale
%
\endinput
