%% %% This is file `xpinyin.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% xpinyin.dtx (with options: `package') %% %% 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. %% \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} \GetIdInfo$Id: xpinyin.dtx 367 2012-11-23 04:45:50Z sobenlee $ {Automatically add pinyin to Chinese characters} \ProvidesExplPackage{\ExplFileName}{\ExplFileDate}{1.2}{\ExplFileDescription} \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 } } \RequirePackage{xparse} \RequirePackage{l3keys2e} \box_new:N \l_xpinyin_tmpa_box \box_new:N \l_xpinyin_tmpb_box \cs_new_nopar:Nn \xpinyin_make_box:nn { \xpinyin_save_CJKsymbol:n {#1} \xpinyin_make_pinyin_box:nn {#1} {#2} } \cs_new_nopar:Nn \xpinyin_make_pinyin_box:nn { \hbox_overlap_left:n { \hbox_set:Nn \l_xpinyin_tmpa_box { \xpinyin_CJKsymbol_hook: \xpinyin_save_CJKsymbol:n {#1} } \hbox_set:Nn \l_xpinyin_tmpb_box { \color_group_begin: \color_ensure_current: \xpinyin_select_font: \l_xpinyin_format_tl \clist_if_exist:cT { c_xpinyin_multiple_ \xpinyin_CJKsymbol_to_unicode:n {#1} _clist } { \l_xpinyin_multiple_tl } {#2} \color_group_end: } \dim_compare:nNnT { \box_wd:N \l_xpinyin_tmpb_box } > { \box_wd:N \l_xpinyin_tmpa_box + \l_xpinyin_CJKglue_dim } { \box_resize:Nnn \l_xpinyin_tmpb_box { \box_wd:N \l_xpinyin_tmpa_box + \l_xpinyin_CJKglue_dim } { \box_ht:N \l_xpinyin_tmpb_box + \box_dp:N \l_xpinyin_tmpb_box } } \box_move_up:nn { \l_xpinyin_vsep_tl } { \hbox_to_wd:nn { \box_wd:N \l_xpinyin_tmpa_box } { \tex_hss:D \box_use_clear:N \l_xpinyin_tmpb_box \tex_hss:D } } } { \xpinyin_CJK_node: } \xpinyin_CJK_ignorespaces: } \cs_new_nopar:Nn \xpinyin_CJKsymbol:n { \xpinyin_make_box:nn {#1} { \xpinyin_to_pinyin:n {#1} } } \cs_new_nopar:Nn \xpinyin_to_pinyin:n { \use:c { c_xpinyin_ \xpinyin_CJKsymbol_to_unicode:n {#1} _tl } } \NewDocumentEnvironment { pinyinscope } { O{} } { \keys_set:nn { xpinyin } {#1} \tl_if_empty:NF \l_xpinyin_hsep_tl { \cs_set_nopar:Npn \CJKglue { \skip_horizontal:n { \l_xpinyin_hsep_tl } } } \settowidth \l_xpinyin_CJKglue_dim { \CJKglue } \xpinyin_replace_CJKsymbol: } { \cs_gset_eq:NN \CJKsymbol \xpinyin_save_CJKsymbol:n } \NewDocumentCommand \xpinyin { s O{} m } { \IfBooleanTF {#1} { \group_begin: \keys_set:nn { xpinyin } {#2} \tl_if_empty:NF \l_xpinyin_hsep_tl { \cs_set_nopar:Npn \CJKglue { \skip_horizontal:n { \l_xpinyin_hsep_tl } } } \settowidth \l_xpinyin_CJKglue_dim { \CJKglue } \xpinyin_replace_CJKsymbol: #3 \group_end: } { \group_begin: \keys_set:nn { xpinyin } {#2} \settowidth \l_xpinyin_CJKglue_dim { \CJKglue } \xpinyin_xpinyin_single_aux:nn {#3} } } \dim_new:N \l_xpinyin_CJKglue_dim \cs_new_nopar:Nn \xpinyin_xpinyin_single_aux:nn { \xpinyin_xpinyin_single_hook:n { \cs_set_eq:NN \xpinyin_save_CJKsymbol:n \use:n } \cs_set_eq:NN \xpinyin_CJKsymbol_to_unicode:n \xpinyin_CJKchar_to_unicode:n \xpinyin_make_box:nn {#1} { \xpinyin_pinyin:n {#2} } \group_end: } \cs_new_nopar:Nn \xpinyin_replace_CJKsymbol_aux: { \cs_if_eq:NNF \CJKsymbol \xpinyin_CJKsymbol:n { \cs_set_eq:NN \xpinyin_save_CJKsymbol:n \CJKsymbol \cs_set_eq:NN \CJKsymbol \xpinyin_CJKsymbol:n } } \cs_new_nopar:Npn \xpinyin_xpinyin_single_hook_aux:n { \cs_if_eq:NNTF \CJKsymbol \xpinyin_CJKsymbol:n { \cs_set_eq:NN \CJKsymbol \xpinyin_save_CJKsymbol:n \cs_set_eq:NN \xpinyin_save_CJKsymbol:n \use:n } } \cs_new_nopar:Nn \xpinyin_select_font_xetex: { \cs_if_exist_use:cF { \l_xpinyin_coor_tl } { \tl_set:Nx \l_xpinyin_current_coor_tl { \l_xpinyin_coor_tl } \xpinyin_select_font_aux: \int_compare:nNnT { \XeTeXfonttype \tex_font:D } > \c_zero { \exp_last_unbraced:NNV \cs_gset_eq:cN \l_xpinyin_current_coor_tl \tex_font:D } } } \cs_new_nopar:Nn \xpinyin_select_font_aux: { \fontsize { \l_xpinyin_ratio_tl \etex_dimexpr:D \f@size pt \scan_stop: } { \c_zero_skip } \l_xpinyin_font_tl \selectfont } \cs_new_nopar:Nn \xpinyin_CJKsymbol_to_unicode_xetex:n { \int_to_hexadecimal:n {`#1} } \cs_new_nopar:Nn \xpinyin_CJKsymbol_to_unicode_pdftex:n { \int_to_hexadecimal:n { \int_from_hexadecimal:V \CJK@plane * "100 + #1 } } \cs_new_nopar:Nn \xpinyin_CJKchar_to_unicode_pdftex:n { \int_to_hexadecimal:n { \xpinyin_UTF_viii_to_unicode:NNNw #1 \q_stop } } \cs_new_nopar:Npn \xpinyin_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 ) } } \cs_generate_variant:Nn \int_from_hexadecimal:n { V } \cs_new_nopar:Nn \xpinyin_adjust_xeCJK_hook: { \cs_new_eq:NN \xpinyin_select_font: \xpinyin_select_font_xetex: \cs_new_eq:NN \xpinyin_CJKsymbol_to_unicode:n \xpinyin_CJKsymbol_to_unicode_xetex:n \cs_new_eq:NN \xpinyin_CJKchar_to_unicode:n \xpinyin_CJKsymbol_to_unicode:n \cs_new_eq:NN \xpinyin_replace_CJKsymbol: \xpinyin_replace_CJKsymbol_aux: \cs_new_eq:NN \xpinyin_CJK_node: \xeCJK_CJK_kern: \cs_new_eq:NN \xpinyin_CJK_ignorespaces: \xeCJK_ignore_spaces:w \cs_new_protected_nopar:Npn \xpinyin_CJK_node: { \xeCJK_make_node:n { CJK } } \tl_gset:Nn \l_xpinyin_coor_tl { (\cs_meaning:N \l_xpinyin_font_tl)/\l_xeCJK_current_font_tl/\l_xpinyin_ratio_tl } \cs_new_nopar:Nn \xpinyin_CJKsymbol_hook: { \makexeCJKinactive \xeCJK_select_font: } \cs_new_nopar:Npn \xpinyin_xpinyin_single_hook:n { \cs_if_eq:NNTF \CJKsymbol \xpinyin_CJKsymbol:n { \cs_set_eq:NN \CJKsymbol \use:n } } } \cs_new_nopar:Nn \xpinyin_adjust_CJK_hook: { \cs_new_eq:NN \xpinyin_select_font: \xpinyin_select_font_aux: \cs_new_eq:NN \xpinyin_CJKsymbol_to_unicode:n \xpinyin_CJKsymbol_to_unicode_pdftex:n \cs_new_eq:NN \xpinyin_CJKchar_to_unicode:n \xpinyin_CJKchar_to_unicode_pdftex:n \cs_new_eq:NN \xpinyin_CJKsymbol_hook: \prg_do_nothing: \cs_new_eq:NN \xpinyin_CJK_node: \CJK@CJK \cs_new_eq:NN \xpinyin_CJK_ignorespaces: \prg_do_nothing: \@ifpackageloaded { CJKpunct } { \xpinyin_adjust_CJKpunct_hook: } { \cs_new_eq:NN \xpinyin_replace_CJKsymbol: \xpinyin_replace_CJKsymbol_aux: \cs_new_eq:NN \xpinyin_xpinyin_single_hook:n \xpinyin_xpinyin_single_hook_aux:n } \prop_map_function:NN \g_xpinyin_tone_prop \DeclareUnicodeCharacter } \cs_new_nopar:Nn \xpinyin_adjust_CJKpunct_hook: { \cs_new_nopar:Nn \xpinyin_replace_CJKsymbol: { \int_compare:nNnTF { \CJKpunct@punctstyle } = { \CJKpunct@ps@plain } { \xpinyin_replace_CJKsymbol_aux: } { \cs_if_eq:NNF \CJKosymbol \xpinyin_CJKsymbol:n { \cs_set_eq:NN \xpinyin_save_CJKsymbol:n \CJKosymbol \cs_set_eq:NN \CJKosymbol \xpinyin_CJKsymbol:n } } } \cs_new_nopar:Npn \xpinyin_xpinyin_single_hook:n { \int_compare:nNnTF { \CJKpunct@punctstyle } = { \CJKpunct@ps@plain } { \xpinyin_xpinyin_single_hook_aux:n } { \cs_if_eq:NNTF \CJKosymbol \xpinyin_CJKsymbol:n { \cs_set_eq:NN \CJKosymbol \xpinyin_save_CJKsymbol:n \cs_set_eq:NN \xpinyin_save_CJKsymbol:n \use:n } } } } \AtBeginDocument { \@ifpackageloaded { xeCJK } { \xpinyin_adjust_xeCJK_hook: } { \@ifpackageloaded { CJKutf8 } { \xpinyin_adjust_CJK_hook: } { \msg_warning:nn { xpinyin } { invalid } } } } \msg_new:nnn { xpinyin } { invalid } { If~you~want~to~use~xpinyin~in~the~right~way,~you\\ should~load~the~\xetex_if_engine:TF { xeCJK } { CJKutf8 }~ package~in~the~preamble.\\ } \NewDocumentCommand \pinyin { O{} m } { \group_begin: \keys_set:nn { xpinyin } {#1} \l_xpinyin_font_tl \l_xpinyin_format_tl \selectfont \xpinyin_pinyin:n {#2} \group_end: } \cs_new_nopar:Nn \xpinyin_pinyin:n { \xpinyin_xpinyin_init: \bool_set_true:N \l_xpinyin_first_bool \tl_set:Nn \l_xpinyin_save_tl {#1} \xpinyin_xpinyin_aux:N #1 \q_recursion_tail \q_recursion_stop } \cs_new_nopar:Nn \xpinyin_xpinyin_aux:N { \quark_if_recursion_tail_stop_do:Nn #1 { \bool_if:NTF \l_xpinyin_first_bool { \l_xpinyin_save_tl } { \tl_if_empty:NF \l_xpinyin_item_tl { \l_xpinyin_pysep_tl \l_xpinyin_item_tl } } } \xpinyin_if_number:NTF {#1} { \bool_if:NTF \l_xpinyin_first_bool { \bool_set_false:N \l_xpinyin_first_bool } { \l_xpinyin_pysep_tl } \l_xpinyin_pre_tl \xpinyin_tone:Vn \l_xpinyin_tone_tl {#1} \l_xpinyin_post_tl \xpinyin_xpinyin_init: } { \int_compare:nNnTF { 0 \cs_if_exist_use:c { c_xpinyin_ \tl_to_str:V \l_xpinyin_tone_tl _tl } } > { 0 \cs_if_exist_use:c { c_xpinyin_ \tl_to_str:n {#1} _tl } } { \tl_put_right:Nn \l_xpinyin_post_tl {#1} } { \tl_set:Nn \l_xpinyin_tone_tl {#1} \tl_set_eq:NN \l_xpinyin_pre_tl \l_xpinyin_item_tl \tl_clear:N \l_xpinyin_post_tl } \tl_put_right:Nx \l_xpinyin_item_tl { \xpinyin_replace_v:N {#1} } } \xpinyin_xpinyin_aux:N } \cs_generate_variant:Nn \tl_to_str:n { V } \cs_new_nopar:Nn \xpinyin_tone:Nn { \use:c { xpinyin_num_to_tone_ #1 :Nn } {#1} {#2} } \cs_generate_variant:Nn \xpinyin_tone:Nn { V } \cs_new_nopar:Nn \xpinyin_replace_v:N { \str_if_eq:nnTF {#1} { v } { \bool_if:nTF { \str_if_eq_p:Vn \l_xpinyin_item_tl { l } || \str_if_eq_p:Vn \l_xpinyin_item_tl { n } } { \exp_not:n { ü} } { u } } { \exp_not:n {#1} } } \cs_new_nopar:Nn \xpinyin_xpinyin_init: { \tl_clear:N \l_xpinyin_pre_tl \tl_clear:N \l_xpinyin_post_tl \tl_clear:N \l_xpinyin_item_tl \tl_clear:N \l_xpinyin_tone_tl } \prg_new_conditional:Nnn \xpinyin_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: } \bool_new:N \l_xpinyin_first_bool \tl_const:Nn \c_xpinyin_a_tl { 3 } \tl_const:Nn \c_xpinyin_o_tl { 2 } \tl_const:Nn \c_xpinyin_e_tl { 2 } \tl_const:Nn \c_xpinyin_i_tl { 1 } \tl_const:Nn \c_xpinyin_u_tl { 1 } \tl_const:Nn \c_xpinyin_v_tl { 1 } \cs_new_nopar:Nn \xpinyin_num_to_tone:Nn { \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 { xpinyin_num_to_tone_ #1 :Nn } \xpinyin_num_to_tone:Nn } \cs_new_nopar:Nn \xpinyin_num_to_tone_i:Nn { \if_case:w \int_eval:n { #2 - \c_one } \exp_stop_f: ī \or: í \or: ǐ \or: ì \else: i \fi: } \cs_new_nopar:Nn \xpinyin_num_to_tone_v:Nn { \bool_if:nTF { \str_if_eq_p:Vn \l_tmpa_tl { l } || \str_if_eq_p:Vn \l_tmpa_tl { n } } { \if_case:w \int_eval:n { #2 - \c_one } \exp_stop_f: ǖ \or: ǘ \or: ǚ \or: ǜ \else: ü \fi: } { \xpinyin_num_to_tone:Nn u {#2} } } \prop_new:N \g_xpinyin_tone_prop \clist_map_inline:nn { {0101}{\=a} , {00E1}{\'a} , {01CE}{\v{a}} , {00E0}{\`a} , {014D}{\=o} , {00F3}{\'o} , {01D2}{\v{o}} , {00F2}{\`o} , {0113}{\=e} , {00E9}{\'e} , {011B}{\v{e}} , {00E8}{\`e} , {012B}{\={\i}} , {00ED}{\'{\i}} , {01D0}{\v{\i}} , {00EC}{\`{\i}} , {016B}{\=u} , {00FA}{\'u} , {01D4}{\v{u}} , {00F9}{\`u} , {00FC}{\"u} , {01D6}{\={\"u}} , {01D8}{\'{\"u}} , {01DA}{\v{\"u}} , {01DC}{\`{\"u}} } { \prop_gput:Nnn \g_xpinyin_tone_prop #1 } \NewDocumentCommand \xpinyinsetup { m } { \keys_set:nn { xpinyin } {#1} } \clist_map_inline:nn { ratio , vsep , hsep , pysep , font , format , multiple } { \keys_define:nn { xpinyin } { #1 .tl_set:c = { l_xpinyin_ #1 _tl } } } \keys_set:nn { xpinyin } { ratio = .4 , vsep = 1 em , pysep = \c_space_tl , font = \normalfont , } \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_xpinyin_ #1 _tl } {#2} } \cs_set_nopar:Npn V+ #1 ~ #2 ~ { \clist_gset:cn { c_xpinyin_multiple_ #1 _clist } {#2} } \char_set_catcode_space:N \ \file_input:n {xpinyin-map.cfg} \group_end: \NewDocumentCommand \setpinyin { m m } { \tl_set:cn { c_xpinyin_ \xpinyin_CJKchar_to_unicode:n {#1} _tl } { \xpinyin_pinyin:n {#2} } } \ProcessKeysOptions { xpinyin } %% %% This package consists of the file xpinyin.dtx, %% xpinyin-map.cfg, %% and the derived files xpinyin.sty, %% xpinyin.pdf, %% xpinyin.ins and %% README. %% %% End of file `xpinyin.sty'.