如何使用循环检查字体中某些字符的存在?

如何使用循环检查字体中某些字符的存在?

我正在尝试修改 xepersian 包的当前版本以满足我的需求。以下代码从 xepersian-mathsdigitspec.sty 应该检查要加载的字体中是否存在某些字符。我的问题是关于函数的\__xepersian_mathsdigitspec_char_not_exist_error。有没有办法用遍历字符列表的 (while, till, ...) LOOP 替换函数参数中那些重复的代码行[06F0, ..., 066B]

\cs_new:Npn \__xepersian_mathsdigitspec_error:nxx    { \msg_error:nnxx    {xepersian-mathsdigitspec} }
\cs_new:Nn \__xepersian_mathsdigitspec_msg_new:nnnn
  { \msg_new:nnxx {#1} {#2} { \tl_trim_spaces:n {#3} } { \tl_trim_spaces:n {#4} } }
\char_set_catcode_space:n {32}
\__xepersian_mathsdigitspec_msg_new:nnnn {xepersian-mathsdigitspec} {char-not-exist}
 {
  The font "#1" does not contain U+#2.
 }
 {
  Select another font and rerun xelatex.
 }
\char_set_catcode_ignore:n {32}

\prg_new_conditional:Nnn \__xepersian_mathsdigitspec_primitive_font_char_if_exist:n {p,TF,T,F}
  {
    \etex_iffontchar:D \l_fontspec_font `#1 \scan_stop:
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }

\cs_new:Nn \__xepersian_mathsdigitspec_char_not_exist_error:n
 {
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۰ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F0 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۱ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F1 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۲ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F2 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۳ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F3 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۴ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F4 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۵ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F5 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۶ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F6 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۷ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F7 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۸ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F8 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۹ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F9 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ٫ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 066B } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ٪ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 066A } }
 }

答案1

在再次阅读了文档“expl3 包和 LaTeX3 编程”和“LaTeX3 接口”之后(但这次读得很彻底),我想我找到了我的问题的解决方案。我将以下代码替换为xepersian-mathsdigitspec.sty

\prg_new_conditional:Nnn \__xepersian_mathsdigitspec_primitive_font_char_if_exist:n {p,TF,T,F}
  {
    \etex_iffontchar:D \l_fontspec_font `#1 \scan_stop:
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }

\cs_new:Nn \__xepersian_mathsdigitspec_char_not_exist_error:n
 {
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۰ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F0 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۱ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F1 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۲ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F2 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۳ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F3 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۴ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F4 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۵ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F5 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۶ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F6 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۷ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F7 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۸ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F8 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ۹ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 06F9 } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ٫ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 066B } }
    \__xepersian_mathsdigitspec_primitive_font_char_if_exist:nF ٪ { \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #1 } { 066A } }
 }

\seq_new:N \l_my_xepersian_digits_seq 
\seq_set_split:Nnn \l_my_xepersian_digits_seq { , } { 06F0 , 06F1 , 06F2 , 06F3 , 06F4 , 06F5 , 06F6 , 06F7 , 06F8 , 06F9 , 066A , 066B }

并将该函数的所有实例替换 \__xepersian_mathsdigitspec_char_not_exist_error为:

\seq_map_inline:Nn \l_my_xepersian_digits_seq
  {
    \etex_iffontchar:D \l_fontspec_font "##1 \scan_stop:
    \else:
      \__xepersian_mathsdigitspec_error:nxx {char-not-exist} { #2 } { ##1 }
    \fi:
  }

当然,我们可以用它\seq_map_function来定义一个新函数,并用它替换所有出现的该函数\__xepersian_mathsdigitspec_char_not_exist_error

相关内容