% \iffalse meta-comment % !TEX program = XeLaTeX %<*internal> \iffalse % %<*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.ins and README.txt (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). % %<*internal> \fi \ifnum\strcmp{\fmtname}{plain}=0 \else \expandafter\begingroup \fi % %<*batchfile> \input docstrip.tex \keepsilent \askforoverwritefalse \preamble Copyright (C) 2012 by Qing Lee -------------------------------------------------------------------------- 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.ins and README.txt. \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-gbk.cfg}{\from{\jobname.dtx}{config-gbk}}} \immediate\write18{iconv -f utf-8 -t gbk \jobname-gbk.cfg > \jobname-gbk.temp} \immediate\write18{mv -f \jobname-gbk.temp \jobname-gbk.cfg} % %\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 % % %<*driver|package> \NeedsTeXFormat{LaTeX2e} %\ProvidesFile{zhnumber.dtx} \RequirePackage{expl3} % %\ExplSyntaxOff %\ProvidesExplPackage {zhnumber} %\ProvidesExplFile {zhnumber-gbk.cfg} %\ProvidesExplFile {zhnumber-utf8.cfg} % {2012/05/21} {1.4} % {package for typesetting numbers with Chinese glyphs} % {Chinese numerals with GBK encoding} % {Chinese numerals with UTF8 encoding} % %<*driver> \documentclass{l3doc} \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} \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 \begin{document} \DocInput{\jobname.dtx} \end{document} % % \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| 和 |UTF8| 编码,依赖 \LaTeX~3 项目的 \pkg{expl3}, % \pkg{xparse} 和 \pkg{l3keys2e} 宏包。 % % 目前 |\zhnumber| 能正确处理的最大整数是 $10^{48}-1$,|\zhditits| 不受这个大小的限制。 % % \section{使用方法} % % \begin{function}{encoding} % \begin{syntax} % encoding = \meta{GBK\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}{\zhnumsetup} % \begin{syntax} % \cs{zhnumsetup} \argbrace{\meta{key1}=\meta{var1}, \meta{key2}=\meta{var2}, ...} % \end{syntax} % 用于在导言区或文档中,设置中文数字的输出格式。目前可以设置的 \meta{key} 如下介绍。 % \end{function} % % \begin{function}{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] 以简体中文输出数字; % \item[Traditional] 以繁体中文输出数字; % \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 映射 % 成〇,可以使用这个选项。 % \end{function} % % \smallskip % % \pkg{zhnumber} 提供下列选项来控制阿拉伯数字的中文映射。 % \begin{verbatim}[frame=single] % - -0 0 1 2 3 4 5 6 7 8 9 10 20 30 40 200 dot and parts % E2 E3 E4 E8 E12 E16 E20 E24 E28 E32 E36 E40 E44 % \end{verbatim} % 其中 |-| 设置负,|-0| 设置〇,|dot| 设置小数的点,|and| 和 |parts| 分别设置分数 % 的“又”和“分之”,而 |E|$n$ 设置 $10^n$。例如 % \begin{verbatim}[frame=single] % \zhnumsetup{2={两}} % \end{verbatim} % 可以将 2 映射成两。需要说明的是,\pkg{zhnumber} 将优先使用这里的设置,所以将会影响 % 到 |style| 选项。如果要恢复 |style| 的功能,可以使用 |reset| 选项。 % % \begin{function}{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/02/19 } { } { \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_over_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_over_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} { \zhnum_digit_map:n \c_zero } { \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 { \zhnum_integer_aux:f { \zhnum_erase_separator:n {#1} } } \cs_new_nopar:Nn \zhnum_integer_aux:n { \int_compare:nNnT { \int_get_sign:n {#1} \c_one } < \c_zero { \zhnum_digit_map:n \c_minus_one } \zhnum_parse_number:f { \zhnum_trim_zeros:f { \int_get_digits:n {#1} } } } \cs_generate_variant:Nn \zhnum_integer:n { f , v } \cs_generate_variant:Nn \zhnum_integer_aux:n { f } % \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 { \str_if_eq:xxF {#1} \c_zhnum_separator_tl {#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} } } \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,\zhnum_parse_number:nnn} % \begin{macrocode} \cs_new_nopar:Nn \zhnum_parse_number:n { \zhnum_parse_number:nf {#1} { \tl_length:n {#1} } } \cs_new_nopar:Nn \zhnum_parse_number:nn { \int_compare:nNnTF {#2} < \c_five { \int_compare:nNnTF {#1} = \c_zero { \zhnum_digit_map:n \c_zero } { \zhnum_process_number:NNn \c_true_bool \c_true_bool {#1} } } { \int_compare:nNnTF { \int_mod:nn {#2} \c_four } = \c_zero { \zhnum_split_number:nNNnfn {#1} \c_true_bool \c_true_bool { \c_zero } { \int_div_truncate:nn { #2 - \c_one } \c_four } { \c_zero } } { \zhnum_parse_number:nnf {#1} {#2} { \use:c { zhnum_use_ \int_to_roman:n { \int_mod:nn {#2} \c_four } _delimit_by_q_stop:w } #1 \q_stop } } } } \cs_new_nopar:Nn \zhnum_parse_number:nnn { \zhnum_process_number:NNn \c_true_bool \c_true_bool {#3} \zhnum_scale_map:n { \int_div_truncate:nn { #2 - \c_one } \c_four } \int_compare:nNnTF { \int_mod:nn {#3} \c_ten } = \c_zero { \zhnum_split_number:nNNffn {#1} \c_false_bool \c_true_bool } { \zhnum_split_number:nNNffn {#1} \c_true_bool \c_false_bool } { \int_mod:nn {#2} \c_four } { \int_eval:n { \int_div_truncate:nn { #2 - \c_one } \c_four - \c_one } } { \c_zero } } \cs_generate_variant:Nn \zhnum_parse_number:n { f } \cs_generate_variant:Nn \zhnum_parse_number:nn { nf } \cs_generate_variant:Nn \zhnum_parse_number:nnn { nnf } \cs_new_nopar:Npn \zhnum_use_i_delimit_by_q_stop:w #1#2 \q_stop {#1} \cs_new_nopar:Npn \zhnum_use_ii_delimit_by_q_stop:w #1#2#3 \q_stop {#1#2} \cs_new_nopar:Npn \zhnum_use_iii_delimit_by_q_stop:w #1#2#3#4 \q_stop {#1#2#3} % \end{macrocode} % \end{macro} % % \begin{macro}[internal]{\zhnum_split_number:nNNnnn} % 将输入的整数由低位到高位,以四位为一段进行处理。 % \begin{macrocode} \cs_new_nopar:Nn \zhnum_split_number:nNNnnn { \exp_args:Nf \zhnum_split_number_aux:nnnnnnn { \zhnum_number_item:nn {#1} { \c_one + #4 + #6 * \c_four } } {#1} {#2} {#3} {#4} {#5} {#6} } \cs_new_nopar:Nn \zhnum_split_number_aux:nnnnnnn { \int_compare:nNnTF {#1} = \c_zero { \use_i_ii:nnn } { \bool_if:NF #3 { \zhnum_digit_map:n \c_zero } \zhnum_process_number:NNn {#3} {#4} {#1} \zhnum_scale_map:n { #6 - #7 } \int_compare:nNnTF { \int_mod:nn {#1} \c_ten } = \c_zero { \use_i_ii:nnn } { \zhnum_use_i_iii:nnn } } { \int_compare:nNnF { #6 - #7 } = \c_zero } { { \zhnum_split_number:nNNnnf {#2} \c_false_bool \c_true_bool {#5} {#6} { \int_eval:n { #7 + \c_one } } } } { { \zhnum_split_number:nNNnnf {#2} \c_true_bool \c_false_bool {#5} {#6} { \int_eval:n { #7 + \c_one } } } } } \cs_new_nopar:Nn \zhnum_use_i_iii:nnn {#1#3} \cs_generate_variant:Nn \zhnum_split_number:nNNnnn { nNNnf , nNNff , nNNnnf } % \end{macrocode} % \end{macro} % % \begin{macro}[internal]{\zhnum_number_item:nn,\zhnum_number_item_aux:nN} % 截取整数的其中四位数。 % \begin{macrocode} \cs_new_nopar:Nn \zhnum_number_item:nn { \zhnum_number_item_aux:nN {#2} #1 \q_recursion_tail \prg_break_point:n { } } \cs_new_nopar:Nn \zhnum_number_item_aux:nN { \quark_if_recursion_tail_break:n {#2} \int_compare:nNnTF {#1} = \c_one { \zhnum_recursion_break:NNNNw #2 } { \zhnum_number_item_aux:fN { \int_eval:n { #1 - \c_one } } } } \cs_generate_variant:Nn \zhnum_number_item_aux:nN { f } \cs_new_nopar:Npn \zhnum_recursion_break:NNNNw #1#2#3#4#5 \prg_break_point:n #6 {#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:ffffNN { \int_mod:nn {#3} \c_ten } { \int_mod:nn { \int_div_truncate:nn {#3} \c_ten } \c_ten } { \int_mod:nn { \int_div_truncate:nn {#3} \c_one_hundred } \c_ten } { \int_div_truncate:nn {#3} \c_one_thousand } {#1} {#2} } \cs_new_nopar:Nn \zhnum_process_number:NNNNNN { \int_compare:nNnTF {#4} = \c_zero { \bool_if:NF #6 { \zhnum_digit_map:n \c_zero } } { \zhnum_digit_map:n {#4} \zhnum_digit_map:n \c_one_thousand } \int_compare:nNnTF {#3} = \c_zero { \int_compare:nNnT { #4 * (#2#1) } > \c_zero { \zhnum_digit_map:n \c_zero } } { \bool_if:nTF { \l_zhnum_ancient_bool && \int_compare_p:nNn {#3} = \c_two } { \zhnum_digit_map:n { #3 * \c_one_hundred } } { \zhnum_digit_map:n {#3} \zhnum_digit_map:n \c_one_hundred } } \int_compare:nNnTF {#2} = \c_zero { \int_compare:nNnT { #3 * #1 } > \c_zero { \zhnum_digit_map:n \c_zero } } { \bool_if:nF { \int_compare_p:nNn {#2} = \c_one && \int_compare_p:nNn {#4#3} = \c_zero && #6 && #5 } { \bool_if:nTF { \l_zhnum_ancient_bool && ( \int_compare_p:nNn {#2} = \c_two || \int_compare_p:nNn {#2} = \c_three || \int_compare_p:nNn {#2} = \c_four ) } { \zhnum_digit_map:n { #2 * \c_ten } \use_none:nn } { \zhnum_digit_map:n {#2} } } \zhnum_digit_map:n \c_ten } \int_compare:nNnF {#1} = \c_zero { \zhnum_digit_map:n {#1} } } \cs_generate_variant:Nn \zhnum_process_number:NNn { NNf } \cs_generate_variant:Nn \zhnum_process_number:NNNNNN { ffff } % \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_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_zhnum_null_int {#1} } \cs_new_nopar:Nn \zhnum_digits_zero_aux:N { \zhnum_digits_aux:nn \c_zero {#1} } \cs_new_nopar:Nn \zhnum_digits_aux:nn { \str_if_eq:xxF {#2} \c_zhnum_separator_tl { \str_if_eq:xxTF {#2} . \c_zhnum_dot_tl { \zhnum_digit_map:n { \str_if_eq:xxTF {#2} - \c_minus_one { \bool_if:nTF { \int_compare_p:nNn {#2} = \c_zero && \int_compare_p:nNn {#1} = \c_zhnum_null_int } { \c_zhnum_null_int } {#2} } } } } } % \end{macrocode} % \end{macro} % % \begin{macro}[internal]{\c_zhnum_null_int} % 设置“〇”对应的阿拉伯数字。 % \begin{macrocode} \int_const:Nn \c_zhnum_null_int { -10 } % \end{macrocode} % \end{macro} % % \begin{macro}[internal]{\zhnum_digit_map:n} % 阿拉伯数字与中文数字的映射。 % \begin{macrocode} \cs_new_nopar:Nn \zhnum_digit_map:n { \prg_case_int:nnn {#1} { { \c_minus_one } { \c_zhnum_minus_tl } { \c_zero } { \c_zhnum_zero_tl } { \c_one } { \c_zhnum_one_tl } { \c_two } { \c_zhnum_two_tl } { \c_three } { \c_zhnum_three_tl } { \c_four } { \c_zhnum_four_tl } { \c_five } { \c_zhnum_five_tl } { \c_six } { \c_zhnum_six_tl } { \c_seven } { \c_zhnum_seven_tl } { \c_eight } { \c_zhnum_eight_tl } { \c_nine } { \c_zhnum_nine_tl } { \c_ten } { \c_zhnum_ten_tl } { \c_one_hundred } { \c_zhnum_hundred_tl } { \c_one_thousand } { \c_zhnum_thousand_tl } { \c_zhnum_null_int } { \c_zhnum_null_tl } { 20 } { \c_zhnum_twenty_tl } { 30 } { \c_zhnum_thirty_tl } { 40 } { \c_zhnum_forty_tl } { 200 } { \c_zhnum_two_hundred_tl } } { \prg_do_nothing: } } % \end{macrocode} % \end{macro} % % \begin{macro}[internal]{\zhnum_scale_map:n} % 大数系统的映射。 % \begin{macrocode} \cs_new_nopar:Nn \zhnum_scale_map:n { \prg_case_int:nnn {#1} { { \c_zero } { \c_zhnum_scale_zero_tl } { \c_one } { \c_zhnum_scale_one_tl } { \c_two } { \c_zhnum_scale_two_tl } { \c_three } { \c_zhnum_scale_three_tl } { \c_four } { \c_zhnum_scale_four_tl } { \c_five } { \c_zhnum_scale_five_tl } { \c_six } { \c_zhnum_scale_six_tl } { \c_seven } { \c_zhnum_scale_seven_tl } { \c_eight } { \c_zhnum_scale_eight_tl } { \c_nine } { \c_zhnum_scale_nine_tl } { \c_ten } { \c_zhnum_scale_ten_tl } { \c_eleven } { \c_zhnum_scale_eleven_tl } } { \zhnum_scale_map_hook:n {#1} } } \cs_new_nopar:Nn \zhnum_scale_map_hook:n { \zhnum_scale_map:n { \int_mod:nn {#1} \c_eleven } } % \end{macrocode} % \end{macro} % 根据需要设置中文阿拉伯数字。 % \begin{macrocode} \keys_define:nn { zhnum / options } { - .tl_set:N = \c_zhnum_minus_tl , -0 .tl_set:N = \c_zhnum_null_tl , 0 .tl_set:N = \c_zhnum_zero_tl , 1 .tl_set:N = \c_zhnum_one_tl , 2 .tl_set:N = \c_zhnum_two_tl , 3 .tl_set:N = \c_zhnum_three_tl , 4 .tl_set:N = \c_zhnum_four_tl , 5 .tl_set:N = \c_zhnum_five_tl , 6 .tl_set:N = \c_zhnum_six_tl , 7 .tl_set:N = \c_zhnum_seven_tl , 8 .tl_set:N = \c_zhnum_eight_tl , 9 .tl_set:N = \c_zhnum_nine_tl , 10 .tl_set:N = \c_zhnum_ten_tl , 20 .tl_set:N = \c_zhnum_twenty_tl , 30 .tl_set:N = \c_zhnum_thirty_tl , 40 .tl_set:N = \c_zhnum_forty_tl , 200 .tl_set:N = \c_zhnum_two_hundred_tl , E2 .tl_set:N = \c_zhnum_hundred_tl , E3 .tl_set:N = \c_zhnum_thousand_tl , E4 .tl_set:N = \c_zhnum_scale_one_tl , E8 .tl_set:N = \c_zhnum_scale_two_tl , E12 .tl_set:N = \c_zhnum_scale_three_tl , E16 .tl_set:N = \c_zhnum_scale_four_tl , E20 .tl_set:N = \c_zhnum_scale_five_tl , E24 .tl_set:N = \c_zhnum_scale_six_tl , E28 .tl_set:N = \c_zhnum_scale_seven_tl , E32 .tl_set:N = \c_zhnum_scale_eight_tl , E36 .tl_set:N = \c_zhnum_scale_nine_tl , E40 .tl_set:N = \c_zhnum_scale_ten_tl , E44 .tl_set:N = \c_zhnum_scale_eleven_tl , } % \end{macrocode} % % \begin{macro}[internal]{\zhnum_load_cfg:} % 根据选定编码载入配置文件。 % \begin{macrocode} \cs_new:Nn \zhnum_load_cfg: { \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 } } \file_input:n { zhnumber - \bool_if:NTF \g_zhnum_gbk_bool { gbk } { utf8 } .cfg } \bool_if:nT { \cs_if_exist_p:N \CJK@makeInactive && \l_zhnum_set_CJK_active_bool } { \CJK@makeInactive } } % \end{macrocode} % \end{macro} % % \begin{macro}{encoding,style,null,reset} % 宏包设置选项。 % \begin{macrocode} \keys_define:nn { zhnum / options } { encoding .choice: , encoding / UTF8 .code:n = { \bool_gset_false:N \g_zhnum_gbk_bool \zhnum_load_cfg: } , encoding / GBK .code:n = { \bool_gset_true:N \g_zhnum_gbk_bool \zhnum_load_cfg: } , encoding .default:n = { GBK } , 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 , reset .code:n = \zhnum_load_cfg: , dot .tl_set:N = \c_zhnum_dot_tl , and .tl_set:N = \c_zhnum_and_tl , parts .tl_set:N = \c_zhnum_over_tl , separator .tl_set:N = \c_zhnum_separator_tl , } % \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 , null = false , separator = {,} } \ProcessKeysOptions { zhnum / options } % \end{macrocode} % % 如果没有选定编码,则根据引擎自动设置编码。 % \begin{macrocode} \ExplSyntaxOn \bool_if_exist:NF \g_zhnum_gbk_bool { \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} % % \end{macrocode} % % \section{中文数字设置} % \label{sec:zhnum-map} % % \begin{macrocode} %<*config-gbk|config-utf8> % \end{macrocode} % % \begin{macrocode} \tl_set:Nn \c_zhnum_minus_tl { \bool_if:NTF \l_zhnum_simp_bool { 负 } { 負 } } \tl_set:Nn \c_zhnum_zero_tl { \bool_if:nTF \l_zhnum_null_bool \c_zhnum_null_tl { 零 } } \tl_set:Nn \c_zhnum_null_tl { \bool_if:NTF \l_zhnum_normal_bool { 〇 } { 零 } } \tl_set:Nn \c_zhnum_one_tl { \bool_if:NTF \l_zhnum_normal_bool { 一 } { 壹 } } \tl_set:Nn \c_zhnum_two_tl { \bool_if:NTF \l_zhnum_normal_bool { 二 } { \bool_if:NTF \l_zhnum_simp_bool { 贰 } { 貳 } } } \tl_set:Nn \c_zhnum_three_tl { \bool_if:NTF \l_zhnum_normal_bool { 三 } { \bool_if:NTF \l_zhnum_simp_bool { 叁 } { 叄 } } } \tl_set:Nn \c_zhnum_four_tl { \bool_if:NTF \l_zhnum_normal_bool { 四 } { 肆 } } \tl_set:Nn \c_zhnum_five_tl { \bool_if:NTF \l_zhnum_normal_bool { 五 } { 伍 } } \tl_set:Nn \c_zhnum_six_tl { \bool_if:NTF \l_zhnum_normal_bool { 六 } { \bool_if:NTF \l_zhnum_simp_bool { 陆 } { 陸 } } } \tl_set:Nn \c_zhnum_seven_tl { \bool_if:NTF \l_zhnum_normal_bool { 七 } { 柒 } } \tl_set:Nn \c_zhnum_eight_tl { \bool_if:NTF \l_zhnum_normal_bool { 八 } { 捌 } } \tl_set:Nn \c_zhnum_nine_tl { \bool_if:NTF \l_zhnum_normal_bool { 九 } { 玖 } } \tl_set:Nn \c_zhnum_ten_tl { \bool_if:NTF \l_zhnum_normal_bool { 十 } { 拾 } } \tl_set:Nn \c_zhnum_hundred_tl { \bool_if:NTF \l_zhnum_normal_bool { 百 } { 佰 } } \tl_set:Nn \c_zhnum_thousand_tl { \bool_if:NTF \l_zhnum_normal_bool { 千 } { 仟 } } \tl_set:Nn \c_zhnum_twenty_tl { 廿 } \tl_set:Nn \c_zhnum_thirty_tl { 卅 } \tl_set:Nn \c_zhnum_forty_tl { 卌 } \tl_set:Nn \c_zhnum_two_hundred_tl { 皕 } \tl_set:Nn \c_zhnum_dot_tl { \bool_if:NTF \l_zhnum_simp_bool { 点 } { 點 } } \tl_set:Nn \c_zhnum_and_tl { 又 } \tl_set:Nn \c_zhnum_over_tl { 分之 } \tl_set:Nn \c_zhnum_scale_zero_tl { } \tl_set:Nn \c_zhnum_scale_one_tl { \bool_if:NTF \l_zhnum_simp_bool { 万 } { 萬 } } \tl_set:Nn \c_zhnum_scale_two_tl { \bool_if:NTF \l_zhnum_simp_bool { 亿 } { 億 } } \tl_set:Nn \c_zhnum_scale_three_tl { 兆 } \tl_set:Nn \c_zhnum_scale_four_tl { 京 } \tl_set:Nn \c_zhnum_scale_five_tl { 垓 } \tl_set:Nn \c_zhnum_scale_six_tl { 秭 } \tl_set:Nn \c_zhnum_scale_seven_tl { 穰 } \tl_set:Nn \c_zhnum_scale_eight_tl { \bool_if:NTF \l_zhnum_simp_bool { 沟 } { 溝 } } \tl_set:Nn \c_zhnum_scale_nine_tl { \bool_if:NTF \l_zhnum_simp_bool { 涧 } { 澗 } } \tl_set:Nn \c_zhnum_scale_ten_tl { 正 } \tl_set:Nn \c_zhnum_scale_eleven_tl { \bool_if:NTF \l_zhnum_simp_bool { 载 } { 載 } } % \end{macrocode} % % \begin{macrocode} \ExplSyntaxOff % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \Finale % \endinput