% \iffalse meta-comment
% !TEX program  = XeLaTeX
%<*internal>
\iffalse
%</internal>
%<*readme>
Introduction
------------
xpinyin is a LaTeX package written to simplify the input of Hanyu Pinyin.
The package provides macros to automatically add pinyin to Chinese characters.
It can only be used in conjunction with xeCJK or CJK/CJKutf8 package.

Given that the implementation of pinyin package of CJK bundle is not very
well, it seems that xpinyin is a good replacement of it.

You can read the package manual (in Chinese) for more detailed explanations.

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 package consists of the file  xpinyin.dtx,
                                   xpinyin-map.cfg,
             and the derived files xpinyin.sty,
                                   xpinyin.pdf,
                                   xpinyin.ins and
                                   README (this file).

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,
xpinyin.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,
running "xetex xpinyin.dtx" will extract the package whereas
"xelatex xpinyin.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.
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
\begingroup
  \edef\tempa{\fmtname}
  \edef\tempb{plain}
\expandafter\endgroup
\ifx\tempa\tempb
\csname fi\endcsname
%</internal>
%<*install>

\input l3docstrip.tex
\keepsilent
\askforoverwritefalse
\preamble

   Copyright (C) 2012--2013 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  xpinyin.dtx,
                                      xpinyin-map.cfg,
                and the derived files xpinyin.sty,
                                      xpinyin.pdf,
                                      xpinyin.ins and
                                      README.
\endpostamble

\generate{
  \usedir{source/latex/xpinyin}
  \file{\jobname.ins}{\from{\jobname.dtx}{install}}
  \usedir{tex/latex/xpinyin}
  \file{\jobname.sty}{\from{\jobname.dtx}{package}}
  \nopreamble\nopostamble
  \usedir{doc/latex/xpinyin}
  \file{README.txt}{\from{\jobname.dtx}{readme}}
}

\endbatchfile
%</install>
%<*internal>
\fi
%</internal>
%
%<*driver|package>
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3}
\GetIdInfo$Id: xpinyin.dtx 526 2013-11-12 00:16:04Z sobenlee $
  {Automatically add pinyin to Chinese characters}
%<*driver>
\ProvidesExplFile{\ExplFileName.\ExplFileExtension}
%</driver>
%<package>\ProvidesExplPackage{\ExplFileName}
  {\ExplFileDate}{1.5}{\ExplFileDescription}
%<*driver>
\ExplSyntaxOff
%</driver>
%</driver|package>
%
%<*driver>
\documentclass[full,a4paper]{l3doc}
\usepackage{xeCJK}
\usepackage{xpinyin}
\usepackage{fvrb-ex}
\usepackage{geometry}
\hypersetup{pdfstartview=FitH}
\geometry{includemp,hmargin={0mm,15mm},vmargin=15mm,footskip=7mm}
\BeforeBeginEnvironment{SideBySideExample}{\vskip1ex\relax}
\fvset{formatcom=\xeCJKVerbAddon}
\linespread{1.1}
\setmainfont[Ligatures=TeX]{TeX Gyre Pagella}
\setmonofont{CMU Typewriter Text}
\setCJKmainfont[BoldFont=Adobe Heiti Std,ItalicFont=Adobe Kaiti Std]{Adobe Song Std}
\setCJKmonofont{Adobe Kaiti Std}
\xeCJKsetup{PunctStyle=kaiming}
\newfontfamily\PinYinFont{TeX Gyre Adventor}
\xpinyinsetup{font=\PinYinFont,multiple=\color{red}}
\def\MacroFont{\linespread{1}\small\normalfont\ttfamily}
\ExplSyntaxOn
\DeclareDocumentCommand \package { o m }
  {
    \href
      {
        http://mirrors.ctan.org/help/Catalogue/entries/
        \IfNoValueTF {#1} { \tl_expandable_lowercase:n {#2} } {#1} .html
      }
      { \pkg {#2} }
  }
\ExplSyntaxOff
\makeatletter
\def\LaTeX{\hologo{LaTeX}}
\def\pdfLaTeX{\hologo{pdfLaTeX}}
\def\XeLaTeX{\hologo{XeLaTeX}}
\def\TF{true\orvar{}false}
\def\TTF{\defaultvar{true}\orvar{}false}
\def\TFF{true\orvar\defaultvar{false}}
\def\orvar{\textup{\textbar}}
\def\defaultvar#1{\textbf{\textup{#1}}}
\def\argbrace#1{\{#1\}}
\makeatother
\def\indexname{代码索引}
\IndexPrologue{%
  \section*{\indexname}
  \markboth{\indexname}{\indexname}
  斜体的数字表示对应项说明所在的页码，下划线的数字表示定义所在的代码行号，而直立体的
  数字表示对应项使用时所在的行号。}
\begin{document}
  \DocInput{\jobname.dtx}
  \newgeometry{margin=15mm,footskip=7mm}
  \PrintIndex
\end{document}
%</driver>
% \fi
%
% \CheckSum{616}
% \GetFileInfo{\jobname.dtx}
%
% \title{\bfseries\pkg{xpinyin} 宏包}
% \author{李清\\ \path{sobenlee@gmail.com}}
% \date{\filedate\qquad\fileversion}
% \maketitle
%
% \begin{documentation}
%
% \section{简介}
%
% \pkg{xpinyin} 是一个 \LaTeX 宏包，提供了为汉字自动注音的功能。
%
% \section{基本用法}
%
% \pkg{xpinyin} 支持采用 \texttt{GBK} 和 \texttt{UTF-8} 编码的 \TeX 源文件，建议
% 总是使用 \texttt{UTF-8}。如果使用 \LaTeX 或 \pdfLaTeX\ 的编译方式，则根据编码的
% 情况，\pkg{xpinyin} 依赖 \package{CJK} 或者 \package[cjk]{CJKutf8} 宏包。
% 如果使用 \XeLaTeX，则依赖 \package{xeCJK} 宏包。如果它们没有在 \pkg{xpinyin}
% 之前被载入，\pkg{xpinyin} 将根据编译方式自动选择，\LaTeX 或 \pdfLaTeX\ 将使用
% \pkg{CJKutf8}。
%
% \pkg{xpinyin} 还依赖 \package{l3kernel} 和 \package{l3packages}，使用 (pdf)\LaTeX
% 下的 \texttt{GBK} 编码时，还将依赖 \package{xCJK2uni}。
%
% 需要注意的是，\pkg{xpinyin} 缺省将拼音的字体设置为与文档的主字体（\cs{normalfont}）相同，
% 所以为了保证声调字母的正确输出，应该选用合适的西文主字体。也可以通过将在下一节介绍的
% \meta{font} 选项来单独设置拼音的字体。
%
% \begin{minipage}[t]{\dimexpr(\linewidth-\parindent-2em)/2\relax}
% \XeLaTeX 下的简单示例：
% \begin{verbatim}[frame=single,gobble=3]
%   \documentclass{article}
%   \usepackage{xeCJK}
%   \usepackage{xpinyin}
%   \setmainfont{CMU Serif}
%   \setCJKmainfont{SimSun}
%
%   \begin{document}
%   \xpinyin*{汉语拼音示例}
%   \end{document}
% \end{verbatim}
% \end{minipage}\qquad
% \begin{minipage}[t]{\dimexpr(\linewidth-\parindent-2em)/2\relax}
% (pdf)\LaTeX 下的简单示例：
% \begin{verbatim}[frame=single,gobble=3]
%   \documentclass{article}
%   \usepackage{CJKutf8}
%   \usepackage{xpinyin}
%   \usepackage[T1]{fontenc}
%   \usepackage{lmodern}
%
%   \begin{document}
%   \begin{CJK}{UTF8}{gbsn}
%   \xpinyin*{汉语拼音示例}
%   \end{CJK}
%   \end{document}
% \end{verbatim}
% \hrule height \dp\strutbox width 0pt \relax
% \end{minipage}
%
% 运行上述示例要求系统安装了设置的字体，源文件用 |UTF-8| 编码保存，使用相应的编译方式。
%
% \pkg{xpinyin} 可以与 \package{ctex} 宏包或文档类共同使用，使用方式与上面类似。
%
% \section{用户手册}
%
% \begin{function}{pinyinscope}
%   \begin{syntax}
%     \cs{begin}\argbrace{pinyinscope}\oarg{options}
%     .....
%     \cs{end}\argbrace{pinyinscope}
%   \end{syntax}
%   为 \env{pinyinscope} 环境中的汉字自动注音。例如
%   \begin{Example}[frame=single,numbers=left,gobble=5]
%     \begin{pinyinscope}
%     列位看官：你道此书从何而来？说起根由，虽近荒唐，细按则深有趣味。
%     待在下将此来历注明，方使阅者\xpinyin{了}{liao3}然不惑。
%     \end{pinyinscope}
%   \end{Example}
% \end{function}
%
%   可选项 \meta{options} 用于局部设置拼音的格式，将在下面说明。
%
% \begin{function}{\xpinyin}
%   \begin{syntax}
%     \cs{xpinyin} \oarg{options} \Arg{单个汉字} \Arg{拼音}
%     \cs{xpinyin*} \oarg{options} \Arg{文字}
%   \end{syntax}
%   对于多音字，可以使用 \cs{xpinyin} 为其设置拼音；而 \cs{xpinyin*} 相当于
%   \env{pinyinscope} 环境的命令形式。\cs{xpinyin} 可以在 \env{pinyinscope} 环境和
%   \cs{xpinyin*} 中使用。例如，
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.5\linewidth,gobble=5]
%     \xpinyin{长}{chang2}\\
%     \xpinyin*{甄士隐梦幻识通灵}\\
%     \xpinyin*{\xpinyin{重}{zhong4}要}
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}{\pinyin}
%   \begin{syntax}
%     \cs{pinyin} \oarg{options} \Arg{拼音}
%   \end{syntax}
%   用于输出拼音，为了输入的方便 \texttt{\"u} 可以用 |v| 代替。例如，
%   \begin{SideBySideExample}[frame=single,numbers=left,xrightmargin=.5\linewidth,gobble=5]
%     \pinyin{lv2zi}\\
%     \pinyin{nv3hai2zi}
%   \end{SideBySideExample}
% \end{function}
%
% \begin{function}{\setpinyin}
%   \begin{syntax}
%     \cs{setpinyin} \Arg{汉字} \Arg{拼音}
%   \end{syntax}
%   \pkg{xpinyin} 宏包的拼音数据（\file{xpinyin-map.cfg}）来源于 \texttt{Unicode 6.1.0}
%   的 \texttt{Unihan} 数据库\footnotemark 中的 \file{Unihan_Readings.txt} 文件。对于多
%   音字，一般来说这个文件选用的是常用读音。可以使用 \cs{setpinyin} 来设置多音字的首选读音。
% \end{function}
%
% \footnotetext{\url{http://www.unicode.org/Public/UNIDATA/Unihan.zip}}
%
% \begin{function}{\xpinyinsetup}
%   \begin{syntax}
%     \cs{xpinyinsetup} \argbrace{\meta{key_1}=\meta{var_1}, \meta{key_2}=\meta{var_2}, ...}
%   \end{syntax}
%   用于在导言区或文档中，设置拼音的格式。目前可以设置的 \meta{key} 如下介绍。
% \end{function}
%
% \begin{function}{ratio}
%   \begin{syntax}
%     ratio = \marg{number}
%   \end{syntax}
%   设置拼音字体大小与当前正文字体大小的比例，缺省值是 |0.4|。
% \end{function}
%
% \begin{function}{vsep}
%   \begin{syntax}
%     vsep = \marg{dimen}
%   \end{syntax}
%   设置拼音的基线与汉字基线的间距，缺省值是 |1 em|。
% \end{function}
%
% \begin{function}{hsep}
%   \begin{syntax}
%     hsep = \marg{skip}
%   \end{syntax}
%   设置注音汉字之间的间距，缺省值与 \cs{CJKglue} 的值相同。为了断行时行末的对齐，设置
%   的 \meta{skip} 最后有一定的弹性。例如
%   \begin{Example}[frame=single,numbers=left,gobble=5]
%     \xpinyin*[ratio={.7},hsep={.5em plus .1em},vsep={1.1em}]{贾雨村风尘怀闺秀}
%   \end{Example}
% \end{function}
%
% \begin{function}{pysep}
%   \begin{syntax}
%     pysep = \marg{glue}
%   \end{syntax}
%   设置 \cs{pinyin} 输出的相邻两个汉语拼音的空白，缺省值是一个空格。
% \end{function}
%
% \begin{function}{font}
%   \begin{syntax}
%     font = \marg{font}
%   \end{syntax}
%   设置拼音的字体，缺省值是 \cs{normalfont}，即以正文西文字体相同。为了保证拼音能正确
%   输出，最好选用收字量较大的西文字体。
% \end{function}
%
% \begin{function}{format}
%   \begin{syntax}
%     format = \marg{format}
%   \end{syntax}
%   设置拼音的其它格式，例如颜色等，缺省值为空。
% \end{function}
%
% \begin{function}{multiple}
%   \begin{syntax}
%     multiple = \marg{format}
%   \end{syntax}
%   设置多音字拼音的其它格式，缺省值为空。可以通过这个选项来提醒校正多音字的拼音。例如
%   本文档设置多音字拼音的颜色是红色（需要载入 \pkg{color} 宏包）：
%   \begin{verbatim}[frame=single,gobble=5]
%     \xpinyinsetup{multiple={\color{red}}}
%   \end{verbatim}
% \end{function}
%
% \end{documentation}
%
% \StopEventually{}
%
% \begin{implementation}
%
% \section{代码实现}
%
%    \begin{macrocode}
%<*package>
%<@@=xpinyin>
%    \end{macrocode}
%
%    \begin{macrocode}
\msg_new:nnn  { xpinyin } { no-LuaTeX }
  {
    The~xpinyin~package~is~not~supported~in~LuaTeX.\\\\
    You~must~change~your~typesetting~engine~to\\
    "xelatex"~or~"pdflatex"~or~"latex"~instead~of~"lualatex".
  }
\luatex_if_engine:T { \msg_critical:nn { xpinyin } { no-LuaTeX } }
%    \end{macrocode}
%
%    \begin{macrocode}
\RequirePackage{xparse}
\RequirePackage{l3keys2e}
%    \end{macrocode}
%
% \begin{macro}[internal]{\c_@@_tone_prop}
%    \begin{macrocode}
\prop_new:N \c_@@_tone_prop
\clist_map_inline:nn
  {
    { ā }{ \= a } , { á }{ \' a } , { ǎ }{ \v a } , { à }{ \` a } ,
    { ō }{ \= o } , { ó }{ \' o } , { ǒ }{ \v o } , { ò }{ \` o } ,
    { ē }{ \= e } , { é }{ \' e } , { ě }{ \v e } , { è }{ \` e } ,
    { ī }{ \=\i } , { í }{ \'\i } , { ǐ }{ \v\i } , { ì }{ \`\i } ,
    { ū }{ \= u } , { ú }{ \' u } , { ǔ }{ \v u } , { ù }{ \` u } ,
    { ḿ }{ \' m } , { ń }{ \' n } , { ň }{ \v n } , { ǹ }{ \` n } ,
    { ü }{ \" u } ,
    { ǖ }{ \= { \" u } } , { ǘ }{ \' { \" u } } ,
    { ǚ }{ \v { \" u } } , { ǜ }{ \` { \" u } }
  }
  { \prop_gput:Nnn \c_@@_tone_prop #1 }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}[internal]{\@@_UTF_char:nn}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_UTF_char:nn #1#2
  {
    \cs_if_exist:cF { u8:#1 }
      { \cs_new_protected_nopar:cpn { u8:#1 } {#2} }
  }
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}[internal]{\@@_GBK_char:nn}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_GBK_char:nn #1#2
  {
    \@@_UTF_char:nn {#1} {#2}
    \exp_args:Nx \@@_GBK_char_aux:nn { \tl_head:n {#1} } {#1}
  }
\cs_new_protected_nopar:Npn \@@_GBK_char_aux:nn #1#2
  { \exp_args:Nf \@@_GBK_char_aux:nnn { \int_eval:n { `#1 } } {#1} {#2} }
\cs_new_protected_nopar:Npn \@@_GBK_char_aux:nnn #1#2#3
  {
    \cs_if_exist:cF { @@_UTF_ #1 :w }
      {
        \exp_args:Nf \@@_GBK_char_def:nnn
          {
            \int_case:nn { \tl_count:n {#3} }
              {
                { \c_two   } { ##1 }
                { \c_three } { ##1##2 }
                { \c_four  } { ##1##2##3 }
              }
          }
          {#1} {#2}
        \exp_args:Nc \@@_save_UTF_cs:Nn { @@_UTF_ #1 :w } {#1}
        \tl_gput_right:Nx \c_@@_reset_UTF_catcode_tl
          { \char_set_catcode:nn {#1} { \char_value_catcode:n {#1} } }
        \char_set_catcode_active:n {#1}
      }
  }
\cs_new_protected_nopar:Npn \@@_GBK_char_def:nnn #1#2#3
  {
    \cs_new_protected_nopar:cpn { @@_UTF_ #2 :w } #1
      { \use:c { u8: \tl_to_str:n { #3#1 } } }
  }
\tl_new:N \c_@@_reset_UTF_catcode_tl
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_save_UTF_cs:Nn}
%    \begin{macrocode}
\group_begin:
\char_set_catcode_active:n { \c_zero }
\cs_new_protected_nopar:Npn \@@_save_UTF_cs:Nn #1#2
  {
    \group_begin:
    \char_set_lccode:nn { \c_zero } {#2}
    \tl_to_lowercase:n
      {
        \group_end:
        \tl_gput_right:Nn \c_@@_reset_UTF_cs_tl { \cs_set_eq:NN ^^00 #1 }
      }
  }
\group_end:
\tl_new:N \c_@@_reset_UTF_cs_tl
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\bool_new:N \g_@@_GBK_bool
\@ifpackageloaded { xeCJK }
  { \AtEndOfPackage { \@@_adjust_xeCJK_hook: } }
  {
    \@ifpackageloaded { CJKutf8 }
      {
        \prop_map_function:NN \c_@@_tone_prop \@@_UTF_char:nn
        \AtEndOfPackage { \@@_adjust_CJK_hook: }
      }
      {
        \@ifpackageloaded { CJK }
          {
            \RequirePackage { xCJK2uni }
            \prop_map_function:NN \c_@@_tone_prop \@@_GBK_char:nn
            \AtEndOfPackage
              {
                \tl_put_right:Nn \l_@@_pinyin_box_hook_tl
                  { \c_@@_reset_UTF_cs_tl }
                \@@_adjust_CJK_hook:
                \tl_use:N \c_@@_reset_UTF_catcode_tl
              }
            \bool_gset_true:N \g_@@_GBK_bool
          }
          {
            \xetex_if_engine:TF
              {
                \RequirePackage { xeCJK }
                \AtEndOfPackage { \@@_adjust_xeCJK_hook: }
              }
              {
                \RequirePackage { CJKutf8 }
                \prop_map_function:NN \c_@@_tone_prop \@@_UTF_char:nn
                \AtEndOfPackage { \@@_adjust_CJK_hook: }
              }
          }
      }
  }
%    \end{macrocode}
%
% \begin{macro}[internal,var]{\l_@@_tmpa_box,\l_@@_tmpb_box}
%    \begin{macrocode}
\box_new:N \l_@@_tmpa_box
\box_new:N \l_@@_tmpb_box
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_make_box:nn}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_make_box:nn #1#2
  {
    \@@_make_pinyin_box:xnn { \@@_to_unicode:n {#1} } {#1} {#2}
    \@@_save_CJKsymbol:n {#1}
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_make_pinyin_box:nnn}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_make_pinyin_box:nnn #1#2#3
  {
    \@@_leavevmode:
    \hbox_overlap_right:n
      {
        \hbox_set:Nn \l_@@_tmpa_box
          { \@@_CJKsymbol_hook: \@@_save_CJKsymbol:n {#2} }
        \hbox_set:Nn \l_@@_tmpb_box
          {
            \l_@@_pinyin_box_hook_tl
            \color_group_begin: \color_ensure_current:
            \@@_select_font:
            \clist_if_exist:cTF { c_@@_multiple_ #1 _clist }
              { \l_@@_multiple_tl \l_@@_format_tl }
              { \l_@@_format_tl }
            {#3}
            \color_group_end:
          }
        \dim_compare:nNnT
          { \box_wd:N \l_@@_tmpb_box } >
          { \box_wd:N \l_@@_tmpa_box + \l_@@_CJKglue_dim }
          {
            \box_resize:Nnn \l_@@_tmpb_box
              { \box_wd:N \l_@@_tmpa_box + \l_@@_CJKglue_dim }
              { \box_ht:N \l_@@_tmpb_box + \box_dp:N \l_@@_tmpb_box }
          }
        \box_move_up:nn { \l_@@_vsep_tl }
          {
            \hbox_to_wd:nn { \box_wd:N \l_@@_tmpa_box }
              { \tex_hss:D  \box_use_clear:N \l_@@_tmpb_box \tex_hss:D }
          }
      }
  }
\tl_new:N \l_@@_pinyin_box_hook_tl
\cs_generate_variant:Nn \@@_make_pinyin_box:nnn { x }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_CJKsymbol:n}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_CJKsymbol:n #1
  { \@@_CJKsymbol:xn { \@@_to_unicode:n {#1} } {#1} }
\cs_new_protected_nopar:Npn \@@_CJKsymbol:nn #1#2
  {
    \@@_make_pinyin_box:nnn {#1} {#2} { \use:c { c_@@_ #1 _tl } }
    \@@_save_CJKsymbol:n {#2}
  }
\cs_generate_variant:Nn \@@_CJKsymbol:nn { x }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{pinyinscope}
%    \begin{macrocode}
\NewDocumentEnvironment { pinyinscope } { O { } }
  {
    \keys_set:nn { xpinyin } {#1}
    \tl_if_empty:NF \l_@@_hsep_tl
      { \cs_set_nopar:Npn \CJKglue { \skip_horizontal:n { \l_@@_hsep_tl } } }
    \settowidth \l_@@_CJKglue_dim { \CJKglue }
    \@@_replace_CJKsymbol:
  }
  { }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xpinyin}
%    \begin{macrocode}
\NewDocumentCommand \xpinyin { s O { } m }
  {
    \IfBooleanTF {#1}
      {
        \group_begin:
        \keys_set:nn { xpinyin } {#2}
        \tl_if_empty:NF \l_@@_hsep_tl
          { \cs_set_nopar:Npn \CJKglue { \skip_horizontal:n { \l_@@_hsep_tl } } }
        \settowidth \l_@@_CJKglue_dim { \CJKglue }
        \@@_replace_CJKsymbol:
        #3
        \group_end:
      }
      {
        \group_begin:
        \keys_set:nn { xpinyin } {#2}
        \settowidth \l_@@_CJKglue_dim { \CJKglue }
        \leavevmode
        \@@_single_aux:nn {#3}
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal,var]{\l_@@_CJKglue_dim}
%    \begin{macrocode}
\dim_new:N \l_@@_CJKglue_dim
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_single_aux:nn}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_single_aux:nn #1#2
  {
    \@@_single_hook:n
      { \cs_set_eq:NN \@@_save_CJKsymbol:n \use:n }
    \cs_set_eq:NN \@@_to_unicode:n \@@_char_to_unicode:n
    \@@_make_box:nn {#1} { \@@_pinyin:n {#2} }
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_replace_CJKsymbol_aux:}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_replace_CJKsymbol_aux:
  {
    \cs_if_eq:NNF \CJKsymbol \@@_CJKsymbol:n
      {
        \cs_set_eq:NN \@@_save_CJKsymbol:n \CJKsymbol
        \cs_set_eq:NN \CJKsymbol \@@_CJKsymbol:n
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_single_hook_aux:n}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_single_hook_aux:n
  {
    \cs_if_eq:NNTF \CJKsymbol \@@_CJKsymbol:n
      {
        \cs_set_eq:NN \CJKsymbol \@@_save_CJKsymbol:n
        \cs_set_eq:NN \@@_save_CJKsymbol:n \use:n
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_select_font_xetex:}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_select_font_xetex:
  {
    \cs_if_exist_use:cF { \l_@@_coor_tl }
      {
        \tl_set:Nx \l_@@_current_coor_tl { \l_@@_coor_tl }
        \@@_select_font_aux:
        \int_compare:nNnF { \XeTeXfonttype \tex_font:D } = \c_zero
          {
            \exp_last_unbraced:NNV
            \cs_gset_eq:cN \l_@@_current_coor_tl \tex_font:D
          }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_select_font_aux:}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_select_font_aux:
  {
    \fontsize
      { \l_@@_ratio_tl \etex_dimexpr:D \f@size pt \scan_stop: }
      { \f@baselineskip }
    \l_@@_font_tl
    \selectfont
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_to_unicode_xetex:n}
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_to_unicode_xetex:n #1
  { \int_to_hexadecimal:n { `#1 } }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_UTF_to_unicode:n,\@@_UTFchar_to_unicode:n}
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_UTF_to_unicode:n #1
  {
    \int_to_hexadecimal:n
      { \exp_args:No \int_from_hexadecimal:n { \CJK@plane } * "100 + #1 }
  }
\cs_new_nopar:Npn \@@_UTFchar_to_unicode:n #1
  { \int_to_hexadecimal:n { \@@_UTF_viii_to_unicode:NNNw #1 \q_stop } }
\cs_new_nopar:Npn \@@_UTF_viii_to_unicode:NNNw #1#2#3#4 \q_stop
  {
    \tl_if_empty:nTF {#4}
      { ( `#1 - "E0 ) * "1000 + ( `#2 - "80 ) * "40 + ( `#3 - "80 ) }
      { ( `#1 - "F0 ) * "4000 + ( `#2 - "80 ) * "1000 + ( `#3 - "80 ) * "40 + ( `#4 - "80 ) }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_GBK_to_unicode:n,\@@_GBKchar_to_unicode:n}
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_GBK_to_unicode:n #1
  { \CJKtu_sfd_map:nn { \CJK@plane } {#1} }
\cs_new_nopar:Npn \@@_GBKchar_to_unicode:n #1
  { \CJKchartouni {#1} }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_adjust_xeCJK_hook:}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_adjust_xeCJK_hook:
  {
    \cs_new_eq:NN \@@_select_font:       \@@_select_font_xetex:
    \cs_new_eq:NN \@@_to_unicode:n       \@@_to_unicode_xetex:n
    \cs_new_eq:NN \@@_char_to_unicode:n  \@@_to_unicode:n
    \cs_new_eq:NN \@@_replace_CJKsymbol: \@@_replace_CJKsymbol_aux:
    \tl_gset:Nn \l_@@_coor_tl
      { (\cs_meaning:N \l_@@_font_tl)/\l_xeCJK_current_font_tl/\l_@@_ratio_tl }
    \cs_new_eq:NN \@@_leavevmode: \prg_do_nothing:
    \cs_new_protected_nopar:Npn \@@_CJKsymbol_hook:
      { \makexeCJKinactive \xeCJK_select_font: }
    \cs_new_protected_nopar:Npn \@@_single_hook:n
      { \cs_if_eq:NNTF \CJKsymbol \@@_CJKsymbol:n { \cs_set_eq:NN \CJKsymbol \use:n } }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_adjust_CJK_hook:}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_adjust_CJK_hook:
  {
    \bool_if:NTF \g_@@_GBK_bool
      {
        \cs_new_eq:NN \@@_to_unicode:n      \@@_GBK_to_unicode:n
        \cs_new_eq:NN \@@_char_to_unicode:n \@@_GBKchar_to_unicode:n
      }
      {
        \cs_new_eq:NN \@@_to_unicode:n      \@@_UTF_to_unicode:n
        \cs_new_eq:NN \@@_char_to_unicode:n \@@_UTFchar_to_unicode:n
      }
    \cs_new_eq:NN \@@_select_font:    \@@_select_font_aux:
    \cs_new_eq:NN \@@_leavevmode:     \leavevmode
    \cs_new_eq:NN \@@_CJKsymbol_hook: \prg_do_nothing:
    \@ifpackageloaded { CJKpunct }
      { \@@_adjust_CJKpunct_hook: }
      {
        \cs_new_eq:NN \@@_single_hook:n \@@_single_hook_aux:n
        \cs_new_eq:NN \@@_replace_CJKsymbol: \@@_replace_CJKsymbol_aux:
        \AtBeginDocument
          {
            \@ifpackageloaded { CJKpunct }
              {
                \cs_undefine:N \@@_single_hook:n
                \cs_undefine:N \@@_replace_CJKsymbol:
                \@@_adjust_CJKpunct_hook:
              } { }
          }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_adjust_CJKpunct_hook:}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_adjust_CJKpunct_hook:
  {
    \cs_new_protected_nopar:Npn \@@_replace_CJKsymbol:
      {
        \int_compare:nNnTF { \CJKpunct@punctstyle } = { \CJKpunct@ps@plain }
          { \@@_replace_CJKsymbol_aux: }
          {
            \cs_if_eq:NNF \CJKosymbol \@@_CJKsymbol:n
              {
                \cs_set_eq:NN \@@_save_CJKsymbol:n \CJKosymbol
                \cs_set_eq:NN \CJKosymbol \@@_CJKsymbol:n
              }
          }
      }
    \cs_new_protected_nopar:Npn \@@_single_hook:n
      {
        \int_compare:nNnTF { \CJKpunct@punctstyle } = { \CJKpunct@ps@plain }
          { \@@_single_hook_aux:n }
          {
            \cs_if_eq:NNTF \CJKosymbol \@@_CJKsymbol:n
              {
                \cs_set_eq:NN \CJKosymbol \@@_save_CJKsymbol:n
                \cs_set_eq:NN \@@_save_CJKsymbol:n \use:n
              }
          }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pinyin}
%    \begin{macrocode}
\NewDocumentCommand \pinyin { O { } m }
  {
    \group_begin:
    \keys_set:nn { xpinyin } {#1}
    \l_@@_font_tl
    \l_@@_format_tl
    \selectfont
    \c_@@_reset_UTF_cs_tl
    \@@_pinyin:n {#2}
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_pinyin:n}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_pinyin:n #1
  {
    \@@_pinyin_init:
    \bool_set_true:N \l_@@_first_bool
    \tl_set:Nn \l_@@_save_tl {#1}
    \@@_pinyin_aux:n #1 \q_recursion_tail \q_recursion_stop
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_pinyin_aux:n}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_pinyin_aux:n #1
  {
    \quark_if_recursion_tail_stop_do:nn {#1}
      {
        \bool_if:NTF \l_@@_first_bool { \l_@@_save_tl }
          { \tl_if_empty:NF \l_@@_item_tl { \l_@@_pysep_tl \l_@@_item_tl } }
      }
    \@@_if_number:nTF {#1}
      {
        \bool_if:NTF \l_@@_first_bool
          { \bool_set_false:N \l_@@_first_bool }
          { \l_@@_pysep_tl }
        \l_@@_pre_tl
        \@@_tone:Vn \l_@@_tone_tl {#1}
        \l_@@_post_tl
        \@@_pinyin_init:
      }
      {
        \int_compare:nNnTF
          { 0 \cs_if_exist_use:c { c_@@_ \tl_to_str:N \l_@@_tone_tl _tl } } >
          { 0 \cs_if_exist_use:c { c_@@_ \tl_to_str:n {#1} _tl } }
          { \tl_put_right:Nn \l_@@_post_tl {#1} }
          {
            \tl_set:Nn \l_@@_tone_tl {#1}
            \tl_set_eq:NN \l_@@_pre_tl \l_@@_item_tl
            \tl_clear:N \l_@@_post_tl
          }
        \tl_put_right:Nx \l_@@_item_tl { \@@_replace_v:n {#1} }
      }
    \@@_pinyin_aux:n
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_tone:Nn}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_tone:Nn #1#2
  { \use:c { @@_num_to_tone_ #1 :Nn } {#1} {#2} }
\cs_generate_variant:Nn \@@_tone:Nn { V }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_replace_v:n}
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_replace_v:n #1
  {
    \str_if_eq:nnTF {#1} { v }
      {
        \str_case:onTF { \l_@@_item_tl }
          { { l } { } { n } { } { L } { } { N } { } }
          { \exp_not:n { ü } } { u }
      }
      { \exp_not:n {#1} }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_pinyin_init:}
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_pinyin_init:
  {
    \tl_clear:N \l_@@_pre_tl   \tl_clear:N \l_@@_post_tl
    \tl_clear:N \l_@@_item_tl  \tl_clear:N \l_@@_tone_tl
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_if_number:nTF}
%    \begin{macrocode}
\prg_new_conditional:Npnn \@@_if_number:n #1 { TF }
  {
    \if_int_compare:w \c_one < 1 \tl_to_str:n {#1} \exp_stop_f:
      \prg_return_true: \else: \prg_return_false: \fi:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal,var]{\l_@@_first_bool}
%    \begin{macrocode}
\bool_new:N \l_@@_first_bool
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal,var]
% {\c_@@_a_tl,\c_@@_o_tl,\c_@@_e_tl,\c_@@_i_tl,\c_@@_u_tl,\c_@@_v_tl}
%    \begin{macrocode}
\tl_const:Nn \c_@@_a_tl { 3 }
\tl_const:Nn \c_@@_o_tl { 2 }
\tl_const:Nn \c_@@_e_tl { 2 }
\tl_const:Nn \c_@@_i_tl { 1 }
\tl_const:Nn \c_@@_u_tl { 1 }
\tl_const:Nn \c_@@_v_tl { 1 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{\@@_num_to_tone:Nn}
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_num_to_tone:Nn #1#2
  {
    \if_case:w \int_eval:n { #2 - \c_one } \exp_stop_f:
      \= {#1}  \or: \'{#1}  \or: \v {#1}  \or: \` {#1}  \else: #1 \fi:
  }
\tl_map_inline:nn { a o e u }
  { \cs_new_eq:cN { @@_num_to_tone_ #1 :Nn } \@@_num_to_tone:Nn }
\cs_new_nopar:Npn \@@_num_to_tone_i:Nn #1#2
  {
    \if_case:w \int_eval:n { #2 - \c_one } \exp_stop_f:
      ī  \or: í  \or: ǐ  \or: ì \else: i \fi:
  }
\cs_new_protected_nopar:Npn \@@_num_to_tone_v:Nn #1#2
  {
    \str_case:onTF { \l_@@_pre_tl }
      { { l } { }  { n } { }  { L } { } { N } { } }
      {
        \if_case:w \int_eval:n { #2 - \c_one } \exp_stop_f:
          ǖ  \or: ǘ  \or: ǚ  \or: ǜ \else: ü \fi:
      }
      { \@@_num_to_tone:Nn u {#2} }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\xpinyinsetup}
%    \begin{macrocode}
\NewDocumentCommand \xpinyinsetup { m } { \keys_set:nn { xpinyin } {#1} }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{ratio,vsep,hsep,pysep,font,format,multiple}
%    \begin{macrocode}
\clist_map_inline:nn
  { ratio , vsep , hsep , pysep , font , format , multiple }
  { \keys_define:nn { xpinyin } { #1 .tl_set:c = { l_@@_ #1 _tl } } }
\keys_set:nn { xpinyin }
  {
    ratio   = .4 ,
    vsep    = 1 em ,
    pysep   = \c_space_tl ,
    font    = \normalfont ,
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[internal]{xpinyin-map.cfg}
%    \begin{macrocode}
\group_begin:
\char_set_catcode_active:N \U
\char_set_catcode_active:N \V
\cs_set_nopar:Npn U+ #1 ~ #2 ~
  { \tl_gset:cn { c_@@_ #1 _tl } {#2} }
\cs_set_nopar:Npn V+ #1 ~ #2 ~
  { \clist_gset:cn { c_@@_multiple_ #1 _clist } {#2} }
\use:n
  {
    \char_set_catcode_space:N \
    \file_input:n { xpinyin-map.cfg }
  }
\group_end:
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\setpinyin}
%    \begin{macrocode}
\NewDocumentCommand \setpinyin { m m }
  {
    \tl_set:cn
      { c_@@_ \@@_char_to_unicode:n {#1} _tl }
      { \@@_pinyin:n {#2} }
  }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\ProcessKeysOptions { xpinyin }
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \end{implementation}
%
% \Finale
%
\endinput
