diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx | 2407 |
1 files changed, 699 insertions, 1708 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx index caaf003bcbe..1767bc97e16 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2022-11-02} +% \date{Released 2022-12-17} % % \maketitle % @@ -138,7 +138,8 @@ % \@@_change_case_group_titleonly:nnn % } % \begin{macro}[EXP]{\@@_change_case_space:nnw} -% \begin{macro}[EXP]{\@@_change_case_N_type:nnN, \@@_change_case_N_type_aux:nnN} +% \begin{macro}[EXP] +% {\@@_change_case_N_type:nnN, \@@_change_case_N_type_aux:nnN} % \begin{macro}[EXP]{\@@_change_case_N_type:nnnN} % \begin{macro}[EXP]{\@@_change_case_math_search:nnNNN} % \begin{macro}[EXP]{\@@_change_case_math_loop:nnNw} @@ -170,36 +171,38 @@ % } % \begin{macro}[EXP]{\@@_change_case_letterlike:nnnnN} % \begin{macro}[EXP] -% {\@@_change_case_char_lower:nnN, \@@_change_case_char_upper:nnN} +% { +% \@@_change_case_codepoint_lower:nnn , +% \@@_change_case_codepoint_upper:nnn , +% \@@_change_case_codepoint_title:nnn , +% \@@_change_case_codepoint_titleonly:nnn +% } +% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnn} +% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnw} % \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnN} -% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnNw} -% \begin{macro}[EXP]{\@@_change_case_lower_sigma:NnnN} -% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnnNN} -% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnw} -% \begin{macro}[EXP]{\@@_change_case_lower_sigma:nnN} % \begin{macro}[EXP] -% {\@@_change_case_char_title:nnN, \@@_change_case_char_titleonly:nnN} +% { +% \@@_change_case_codepoint_title:nn , +% \@@_change_case_codepoint_titleonly:nn +% } +% \begin{macro}[EXP]{\@@_change_case_codepoint_title:nnnn} % \begin{macro}[EXP] -% {\@@_change_case_char_title:nN, \@@_change_case_char_titleonly:nN} -% \begin{macro}[EXP]{\@@_change_case_char_title:nnnN} +% {\@@_change_case_codepoint:nnnn, \@@_change_case_codepoint_aux:nnnn} +% \begin{macro}[EXP]{\@@_change_case_codepoint:nn} % \begin{macro}[EXP] % { -% \@@_change_case_char:nnnN , -% \@@_change_case_char_auxi:nnnN , -% \@@_change_case_char_auxii:nnnN +% \@@_change_case_codepoint:nnn , +% \@@_change_case_codepoint:fnn , +% \@@_change_case_codepoint_aux:nnn % } -% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nnnNN} -% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nnnNNN} -% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nnnNNNN} -% \begin{macro}[EXP]{\@@_change_case_char_UTFviii:nnnn} % \begin{macro}[EXP] % { -% \@@_change_case_char_next_lower:nn , -% \@@_change_case_char_next_upper:nn , -% \@@_change_case_char_next_title:nn , -% \@@_change_case_char_next_titleonly:nn +% \@@_change_case_next_lower:nn , +% \@@_change_case_next_upper:nn , +% \@@_change_case_next_title:nn , +% \@@_change_case_next_titleonly:nn , +% \@@_change_case_next_end:nn % } -% \begin{macro}[EXP]{\@@_change_case_char_next_end:nn} % As for the expansion code, the business end of case changing is the % handling of \texttt{N}-type tokens. First, we expand the input fully % (so the loops here don't need to worry about awkward look-aheads and the @@ -246,7 +249,7 @@ { \@@_change_case_BCP:nnnnw {#1} {#2} {#4} {#3} #3 - - \q_@@_stop } \cs_new:Npn \@@_change_case_BCP:nnnnw #1#2#3#4#5 - #6 - #7 \q_@@_stop { - \cs_if_exist:cTF { @@_change_case_ #2 _ #5 -x- #3 :nnnN } + \cs_if_exist:cTF { @@_change_case_ #2 _ #5 -x- #3 :nnnn } { \@@_change_case_auxii:nnn {#1} {#2} { #5 -x- #3 } } { \@@_change_case_auxii:nnn {#1} {#2} {#4} } } @@ -429,9 +432,12 @@ \cs_new:Npn \@@_change_case_cs_check:nnN #1#2#3 { \token_if_cs:NTF #3 - { \@@_change_case_exclude:nnN } - { \use:c { @@_change_case_char_ #1 :nnN } } - {#1} {#2} #3 + { \@@_change_case_exclude:nnN {#1} {#2} } + { + \@@_codepoint_process:nN + { \use:c { @@_change_case_codepoint_ #1 :nnn } {#1} {#2} } + } + #3 } % \end{macrocode} % To deal with a control sequence there is first a need to test if it is @@ -545,7 +551,7 @@ { \@@_change_case_store:v { c_@@_ #1 case_ \token_to_str:N #5 _tl } - \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#4} + \use:c { @@_change_case_next_ #2 :nn } {#2} {#4} } { \@@_change_case_store:n {#5} @@ -555,7 +561,7 @@ \str_if_eq:nnTF {#1} { lower } { upper } { lower } case_ \token_to_str:N #5 _tl } - { \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#4} } + { \use:c { @@_change_case_next_ #2 :nn } {#2} {#4} } { \@@_change_case_loop:nnw {#3} {#4} } } } @@ -563,222 +569,196 @@ % For upper- and lowercase changes, once we get to this stage there are only % a couple of questions remaining: is there a language-specific mapping and % is there the special case of a terminal sigma. If not, then we pass to -% a simple character mapping. +% a simple codepoint mapping. % \begin{macrocode} -\cs_new:Npn \@@_change_case_char_lower:nnN #1#2#3 +\cs_new:Npn \@@_change_case_codepoint_lower:nnn #1#2#3 { - \cs_if_exist_use:cF { @@_change_case_lower_ #2 :nnnN } - { \@@_change_case_lower_sigma:nnnN } - {#1} {#1} {#2} #3 + \cs_if_exist_use:cF { @@_change_case_lower_ #2 :nnnn } + { \@@_change_case_lower_sigma:nnnn } + {#1} {#1} {#2} {#3} } -\cs_new:Npn \@@_change_case_char_upper:nnN #1#2#3 +\cs_new:Npn \@@_change_case_codepoint_upper:nnn #1#2#3 { - \cs_if_exist_use:cF { @@_change_case_upper_ #2 :nnnN } - { \@@_change_case_char:nnnN } - {#1} {#1} {#2} #3 + \cs_if_exist_use:cF { @@_change_case_upper_ #2 :nnnn } + { \@@_change_case_codepoint:nnnn } + {#1} {#1} {#2} {#3} } % \end{macrocode} % If the current character is an uppercase sigma, the a check is made on the % next item in the input. If it is \texttt{N}-type and not a control sequence -% then there is a look-ahead phase: the logic here is simply based on letters. -% The one exception is Dutch: see below. +% then there is a look-ahead phase: the logic here is simply based on letters +% or actives (to cover $8$-bit engines). % \begin{macrocode} -\bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } +\cs_new:Npn \@@_change_case_lower_sigma:nnnn #1#2#3#4 { - \cs_new:Npn \@@_change_case_lower_sigma:nnnN #1#2#3#4 - { - \int_compare:nNnTF { `#4 } = { "03A3 } - { \@@_change_case_lower_sigma:nnNw {#2} {#3} #4 } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } - } - \cs_new:Npn \@@_change_case_lower_sigma:nnNw #1#2#3#4 \q_@@_recursion_stop - { - \tl_if_head_is_N_type:nTF {#4} - { \@@_change_case_lower_sigma:NnnN #3 } - { - \@@_change_case_store:e - { \char_generate:nn { "03C2 } { \@@_char_catcode:N #3 } } - \@@_change_case_loop:nnw - } - {#1} {#2} #4 \q_@@_recursion_stop - } - \cs_new:Npn \@@_change_case_lower_sigma:NnnN #1#2#3#4 + \@@_codepoint_compare:nNnTF {#4} = { "03A3 } + { \@@_change_case_lower_sigma:nnnw {#2} } + { \@@_change_case_codepoint:nnnn {#1} {#2} } + {#3} {#4} + } +\cs_new:Npn \@@_change_case_lower_sigma:nnnw #1#2#3#4 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_lower_sigma:nnnN {#3} } { \@@_change_case_store:e - { - \token_if_letter:NTF #4 - { \char_generate:nn { "03C3 } { \@@_char_catcode:N #1 } } - { \char_generate:nn { "03C2 } { \@@_char_catcode:N #1 } } - } - \@@_change_case_loop:nnw {#2} {#3} #4 + { \codepoint_generate:nn { "03C2 } { \@@_char_catcode:N #3 } } + \@@_change_case_loop:nnw } + {#1} {#2} #4 \q_@@_recursion_stop } -% \end{macrocode} -% In the $8$-bit engines, we have to look ahead once we find the first byte of the -% possible hit. -% \begin{macrocode} +\cs_new:Npn \@@_change_case_lower_sigma:nnnN #1#2#3#4 { - \cs_new:Npn \@@_change_case_lower_sigma:nnnN #1#2#3#4 - { - \int_compare:nNnTF { `#4 } = { "CE } - { \@@_change_case_lower_sigma:nnnNN } - { \@@_change_case_char:nnnN } - {#1} {#2} {#3} #4 - } - \cs_new:Npn \@@_change_case_lower_sigma:nnnNN #1#2#3#4#5 - { - \int_compare:nNnTF { `#5 } = { "A3 } - { \@@_change_case_lower_sigma:nnw {#2} {#3} } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4#5 } - } - \cs_new:Npn \@@_change_case_lower_sigma:nnw #1#2#3 \q_@@_recursion_stop - { - \tl_if_head_is_N_type:nTF {#3} - { \@@_change_case_lower_sigma:nnN } - { - \@@_change_case_store:V \c_@@_final_sigma_tl - \@@_change_case_loop:nnw - } - {#1} {#2} #3 \q_@@_recursion_stop - } - \cs_new:Npn \@@_change_case_lower_sigma:nnN #1#2#3 + \@@_change_case_store:e { \bool_lazy_or:nnTF - { \token_if_letter_p:N #3 } + { \token_if_letter_p:N #4 } { \bool_lazy_and_p:nn - { \token_if_active_p:N #3 } - { \int_compare_p:nNn { `#3 } > { "80 } } + { \token_if_active_p:N #4 } + { \int_compare_p:nNn {`#4} > { "80 } } } - { \@@_change_case_store:V \c_@@_sigma_tl } - { \@@_change_case_store:V \c_@@_final_sigma_tl } - \@@_change_case_loop:nnw {#1} {#2} #3 + { \codepoint_generate:nn { "03C3 } { \@@_char_catcode:N #1 } } + { \codepoint_generate:nn { "03C2 } { \@@_char_catcode:N #1 } } } + \@@_change_case_loop:nnw {#2} {#3} #4 } % \end{macrocode} % For titlecasing, we need to fully expand the new character to see if it -% is a letter (or active) But that means looking ahead in the $8$-bit case, so -% we have to grab the required tokens up-front. Life is a lot easier for Unicode -% \TeX{}'s, where we just have one token to worry about. The one wrinkle here -% is that for look-ahead we'd get into trouble: luckily, only Dutch has that -% issue. +% is a letter (or active). % \begin{macrocode} -\cs_new:Npx \@@_change_case_char_title:nnN #1#2#3 +\cs_new:Npn \@@_change_case_codepoint_title:nnn #1#2#3 { - \exp_not:N \bool_if:NTF \l_text_titlecase_check_letter_bool + \bool_if:NTF \l_text_titlecase_check_letter_bool { - \bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { \exp_not:N \token_if_letter:NTF #3 } + \tl_if_single:nTF {#3} { - \exp_not:N \bool_lazy_or:nnTF - { \exp_not:N \token_if_letter_p:N #3 } - { \exp_not:N \token_if_active_p:N #3 } + \bool_lazy_or:nnTF + { \token_if_letter_p:N #3 } + { + \bool_lazy_and_p:nn + { \token_if_active_p:N #3 } + { ! \int_compare_p:nNn {`#3} < { "80 } } + } + { \use:c { @@_change_case_codepoint_ #1 :nn } } + { \@@_change_case_codepoint_title:nnnn { title } {#1} } } - { \exp_not:N \use:c { @@_change_case_char_ #1 :nN } } - { \exp_not:N \@@_change_case_char_title:nnnN { title } {#1} } + { \use:c { @@_change_case_codepoint_ #1 :nn } } } - { \exp_not:N \use:c { @@_change_case_char_ #1 :nN } } - {#2} #3 + { \use:c { @@_change_case_codepoint_ #1 :nn } } + {#2} {#3} } -\cs_new_eq:NN \@@_change_case_char_titleonly:nnN - \@@_change_case_char_title:nnN -\cs_new:Npn \@@_change_case_char_title:nN #1#2 - { \@@_change_case_char_title:nnnN { title } { lower } {#1} #2 } -\cs_new:Npn \@@_change_case_char_titleonly:nN #1#2 - { \@@_change_case_char_title:nnnN { title } { end } {#1} #2 } -\cs_new:Npn \@@_change_case_char_title:nnnN #1#2#3#4 +\cs_new_eq:NN \@@_change_case_codepoint_titleonly:nnn + \@@_change_case_codepoint_title:nnn +\cs_new:Npn \@@_change_case_codepoint_title:nn #1#2 + { \@@_change_case_codepoint_title:nnnn { title } { lower } {#1} {#2} } +\cs_new:Npn \@@_change_case_codepoint_titleonly:nn #1#2 + { \@@_change_case_codepoint_title:nnnn { title } { end } {#1} {#2} } +\cs_new:Npn \@@_change_case_codepoint_title:nnnn #1#2#3#4 { - \cs_if_exist_use:cF { @@_change_case_title_ #3 :nnnN } + \cs_if_exist_use:cF { @@_change_case_title_ #3 :nnnn } { - \cs_if_exist_use:cF { @@_change_case_upper_ #3 :nnnN } - { \@@_change_case_char:nnnN } + \cs_if_exist_use:cF { @@_change_case_upper_ #3 :nnnn } + { \@@_change_case_codepoint:nnnn } } - {#1} {#2} {#3} #4 + {#1} {#2} {#3} {#4} } -% \end{macrocode} -% For Unicode engines we can handle all characters directly. However, for -% the $8$-bit engines the aim is to deal with (a subset of) Unicode (UTF-8) -% input. They deal with that by making the upper half of the range active, -% so we look for that and if found work out how many UTF-8 octets there -% are to deal with. Those can then be grabbed to reconstruct the full -% Unicode character, which is then used in a lookup. (As will become -% obvious below, there is no intention here of covering all of Unicode.) -% For (u)p-\TeX{} there are a limited number of tokens we can touch. -% \begin{macrocode} -\cs_new:Npn \@@_change_case_char:nnnN #1#2#3#4 +\cs_new:Npn \@@_change_case_codepoint:nnnn #1#2#3#4 { - \token_if_active:NTF #4 + \bool_lazy_and:nnTF + { \tl_if_single_p:n {#4} } + { \token_if_active_p:N #4 } { \@@_change_case_store:n {#4} } { \@@_change_case_store:e - { \use:c { char_ #1 case :N } #4 } + { \@@_change_case_codepoint:nn {#1} {#4} } } - \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} + \use:c { @@_change_case_next_ #2 :nn } {#2} {#3} } -\bool_lazy_or:nnF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } +\cs_new:Npn \@@_change_case_codepoint:nn #1#2 { - \cs_new_eq:NN \@@_change_case_char_auxi:nnnN - \@@_change_case_char:nnnN - \cs_gset:Npn \@@_change_case_char:nnnN #1#2#3#4 - { - \int_compare:nNnTF { `#4 } > { "80 } - { - \int_compare:nNnTF { `#4 } < { "E0 } - { \@@_change_case_char_UTFviii:nnnNN } - { \@@_change_case_char_auxii:nnnN } - } - { \@@_change_case_char_auxi:nnnN } - {#1} {#2} {#3} #4 - } - \sys_if_engine_pdftex:TF + \@@_change_case_codepoint:fnn + { \int_eval:n { \@@_codepoint_from_chars:Nw #2 } } {#1} {#2} + } +\cs_new:Npn \@@_change_case_codepoint:nnn #1#2#3 + { + \exp_args:Ne \@@_change_case_codepoint_aux:nn + { \__kernel_codepoint_case:nn { #2 case } {#1} } {#3} + } +\cs_generate_variant:Nn \@@_change_case_codepoint:nnn { f } +% \end{macrocode} +% Avoid high chars with p\TeX{}. +% \begin{macrocode} +\sys_if_engine_ptex:T + { + \cs_new_eq:NN \@@_change_case_codepoint_aux:nnn + \@@_change_case_codepoint:nnn + \cs_gset:Npn \@@_change_case_codepoint:nnn #1#2#3 { - \cs_new:Npn \@@_change_case_char_auxii:nnnN #1#2#3#4 - { - \int_compare:nNnTF { `#4 } < { "F0 } - { \@@_change_case_char_UTFviii:nnnNNN } - { \@@_change_case_char_UTFviii:nnnNNNN } - {#1} {#2} {#3} #4 - } + \int_compare:nNnTF {#1} = { -1 } + { \exp_not:n {#3} } + { \@@_change_case_codepoint_aux:nnn {#1} {#2} {#3} } } + } +\cs_new:Npn \@@_change_case_codepoint_aux:nn #1#2 + { + \use:e { \@@_change_case_codepoint_aux:nnnn #1 {#2} } + } +\cs_new:Npn \@@_change_case_codepoint_aux:nnnn #1#2#3#4 + { + \@@_codepoint_compare:nNnTF {#4} = {#1} + { \exp_not:n {#4} } { - \cs_new:Npn \@@_change_case_char_auxii:nnnN #1#2#3#4 + \codepoint_generate:nn {#1} + { \@@_change_case_catcode:nn {#4} {#1} } + \tl_if_blank:nF {#2} { - \@@_change_case_store:n {#4} - \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} + \codepoint_generate:nn {#2} + { \char_value_catcode:n {#2} } + \tl_if_blank:nF {#3} + { + \codepoint_generate:nn {#3} + { \char_value_catcode:n {#3} } + } } } - \cs_new:Npn \@@_change_case_char_UTFviii:nnnNN #1#2#3#4#5 - { \@@_change_case_char_UTFviii:nnnn {#1} {#2} {#3} {#4#5} } - \cs_new:Npn \@@_change_case_char_UTFviii:nnnNNN #1#2#3#4#5#6 - { \@@_change_case_char_UTFviii:nnnn {#1} {#2} {#3} {#4#5#6} } - \cs_new:Npn \@@_change_case_char_UTFviii:nnnNNNN #1#2#3#4#5#6#7 - { \@@_change_case_char_UTFviii:nnnn {#1} {#2} {#3} {#4#5#6#7} } - \cs_new:Npn \@@_change_case_char_UTFviii:nnnn #1#2#3#4 + } +% \end{macrocode} +% We need to ensure that only valid catcode-extraction is attempted. That's +% fine with Unicode engines but needs a bit of work with 8-bit ones. The +% logic is that if the original codepoint was in the ASCII range, we keep +% the catcode. Otherwise, if the target is in the ASCII range, we use +% the standard catcode. If neither are true, we set as 13 on the grounds that +% this will be what is used anyway! +% \begin{macrocode} +\bool_lazy_or:nnTF + { \sys_if_engine_luatex_p: } + { \sys_if_engine_xetex_p: } + { + \cs_new:Npn \@@_change_case_catcode:nn #1#2 + { \@@_char_catcode:N #1 } + } + { + \cs_new:Npn \@@_change_case_catcode:nn #1#2 { - \cs_if_exist:cTF { c__kernel_ #1 case_ \tl_to_str:n {#4} _tl } + \@@_codepoint_compare:nNnTF {#1} < { "80 } + { \@@_char_catcode:N #1 } { - \@@_change_case_store:v - { c__kernel_ #1 case_ \tl_to_str:n {#4} _tl } + \int_compare:nNnTF {#2} < { "80 } + { \char_value_catcode:n {#2} } + { 13 } } - { \@@_change_case_store:n {#4} } - \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} } } -\cs_new:Npn \@@_change_case_char_next_lower:nn #1#2 +\cs_new:Npn \@@_change_case_next_lower:nn #1#2 { \@@_change_case_loop:nnw {#1} {#2} } -\cs_new_eq:NN \@@_change_case_char_next_upper:nn - \@@_change_case_char_next_lower:nn -\cs_new_eq:NN \@@_change_case_char_next_title:nn - \@@_change_case_char_next_lower:nn -\cs_new_eq:NN \@@_change_case_char_next_titleonly:nn - \@@_change_case_char_next_lower:nn -\cs_new:Npn \@@_change_case_char_next_end:nn #1#2 +\cs_new_eq:NN \@@_change_case_next_upper:nn + \@@_change_case_next_lower:nn +\cs_new_eq:NN \@@_change_case_next_title:nn + \@@_change_case_next_lower:nn +\cs_new_eq:NN \@@_change_case_next_titleonly:nn + \@@_change_case_next_lower:nn +\cs_new:Npn \@@_change_case_next_end:nn #1#2 { \@@_change_case_break:w } % \end{macrocode} % \end{macro} @@ -822,13 +802,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}{\text_declare_case_equivalent:Nn} % Create equivalents to allow replacement. @@ -855,76 +828,63 @@ % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_change_case_upper_de-x-eszett:nnnN, \@@_change_case_upper_de-alt:nnnN} -% \begin{macro}[EXP]{\@@_change_case_upper_de-x-eszett:nnnNN} +% \begin{macro}[EXP] +% {\@@_change_case_upper_de-x-eszett:nnnn, \@@_change_case_upper_de-alt:nnnn} % A simple alternative version for German. % \begin{macrocode} -\bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_new:cpn { @@_change_case_upper_de-x-eszett:nnnN } #1#2#3#4 - { - \int_compare:nNnTF { `#4 } = { "00DF } - { - \@@_change_case_store:e - { \char_generate:nn { "1E9E } { \@@_char_catcode:N #4 } } - \use:c { @@_change_case_char_next_ #2 :nn } - {#2} {#3} - } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } - } - } +\cs_new:cpn { @@_change_case_upper_de-x-eszett:nnnn } #1#2#3#4 { - \cs_new:cpx { @@_change_case_upper_de-x-eszett:nnnN } #1#2#3#4 + \@@_codepoint_compare:nNnTF {#4} = { "00DF } { - \exp_not:N \int_compare:nNnTF { `#4 } = { "00C3 } - { - \exp_not:c { @@_change_case_upper_de-x-eszett:nnnNN } - {#1} {#2} {#3} #4 - } - { \exp_not:N \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } - } - \cs_new:cpn { @@_change_case_upper_de-x-eszett:nnnNN } #1#2#3#4#5 - { - \int_compare:nNnTF { `#5 } = { "009F } - { - \@@_change_case_store:V \c_@@_grosses_Eszett_tl - \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} - } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4#5 } + \@@_change_case_store:e + { + \codepoint_generate:nn { "1E9E } + { \@@_change_case_catcode:nn {#4} { "1E9E } } + } + \use:c { @@_change_case_next_ #2 :nn } + {#2} {#3} } + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } } -\cs_new_eq:cc { @@_change_case_upper_de-alt:nnnN } - { @@_change_case_upper_de-x-eszett:nnnN } +\cs_new_eq:cc { @@_change_case_upper_de-alt:nnnn } + { @@_change_case_upper_de-x-eszett:nnnn } % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}[EXP] -% {\@@_change_case_upper_el:nnnN, \@@_change_case_upper_el-x-iota:nnnN} +% { +% \@@_change_case_upper_el:nnnn , +% \@@_change_case_upper_el_aux:nnnn , +% \@@_change_case_upper_el-x-iota:nnnn +% } % \begin{macro}[EXP] -% {\@@_change_case_upper_el:N, \@@_change_case_upper_el-x-iota:N} +% {\@@_change_case_upper_el:n, \@@_change_case_upper_el-x-iota:n} % \begin{macro}[EXP]{\@@_change_case_upper_el:nnn} -% \begin{macro}[EXP]{\@@_change_case_upper_el:nnNw} -% \begin{macro}[EXP]{\@@_change_case_upper_el:NnnN} -% \begin{macro}[EXP]{\@@_change_case_upper_el_ypogegrammeni:Nnnnnw} -% \begin{macro}[EXP]{\@@_change_case_upper_el_ypogegrammeni:NnnnnN} -% \begin{macro}[EXP]{\@@_change_case_upper_el_dialytika:nnN} -% \begin{macro}[EXP]{\@@_change_case_upper_el_dialytika:N} -% \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnNw} +% \begin{macro}[EXP]{\@@_change_case_upper_el:nnnw} +% \begin{macro}[EXP] +% {\@@_change_case_upper_el:nnnN, \@@_change_case_upper_el_aux:nnnN} +% \begin{macro}[EXP]{\@@_change_case_upper_el_ypogegrammeni:nnnnnw} +% \begin{macro}[EXP]{\@@_change_case_upper_el_ypogegrammeni:nnnnnN} +% \begin{macro}[EXP]{\@@_change_case_upper_el_ypogegrammeni:nnnnnn} +% \begin{macro}[EXP]{\@@_change_case_upper_el_dialytika:nnn} +% \begin{macro}[EXP]{\@@_change_case_upper_el_dialytika:n} +% \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnnw} % \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnN} +% \begin{macro}[EXP]{\@@_change_case_upper_el_hiatus:nnn} % \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnw} % \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnN} -% \begin{macro}[EXP]{\@@_change_case_upper_el:nnnNN} -% \begin{macro}[EXP]{\@@_change_case_upper_el:nnnNNN} -% \begin{macro}[EXP]{\@@_change_case_upper_el:nnnn} +% \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnn} % \begin{macro}[EXP,TF]{\@@_change_case_if_greek:n} +% \begin{macro}[EXP]{\@@_change_case_if_greek:n} % \begin{macro}[EXP,pTF]{\@@_change_case_if_greek:n} % \begin{macro}[EXP,pTF]{\@@_change_case_if_greek_accent:n} +% \begin{macro}[EXP]{\@@_change_case_if_greek_accent:n} % \begin{macro}[EXP,pTF]{\@@_change_case_if_greek_diacritic:n} +% \begin{macro}[EXP]{\@@_change_case_if_greek_diacritic:n} % \begin{macro}[EXP,TF]{\@@_change_case_if_takes_dialytika:n} +% \begin{macro}[EXP]{\@@_change_case_if_takes_dialytika:n} % \begin{macro}[EXP,TF]{\@@_change_case_if_takes_ypogegrammeni:n} +% \begin{macro}[EXP]{\@@_change_case_if_takes_ypogegrammeni:n} % For Greek uppercasing, we need to know if characters \emph{in the Greek % range} have accents. That means doing a \textsc{nfd} conversion first, then % starting a search. As described by the Unicode \textsc{cldr}, Greek accents @@ -936,55 +896,58 @@ % \emph{ypogegrammeni} is filtered out here as it is not actually in the % Greek range, so gets lost if we leave until later. % \begin{macrocode} -\bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } +\cs_new:Npn \@@_change_case_upper_el:nnnn #1#2#3#4 { - \cs_new:Npn \@@_change_case_upper_el:nnnN #1#2#3#4 + \@@_change_case_if_greek:nTF {#4} { - \@@_change_case_if_greek:nTF { `#4 } + \exp_args:Ne \@@_change_case_upper_el:nnn { - \exp_args:Ne \@@_change_case_upper_el:nnn - { \char_to_nfd:N #4 } {#2} {#3} + \codepoint_to_nfd:n { \@@_codepoint_from_chars:Nw #4 } } + {#2} {#3} + } + { + \@@_codepoint_compare:nNnTF {#4} = { "0345 } { - \int_compare:nNnTF { `#4 } = { "0345 } + \@@_change_case_store:e { - \@@_change_case_store:e - { - \use:c { @@_change_case_upper_ #3 :N } #4 - } - \@@_change_case_loop:nnw {#2} {#3} + \use:c { @@_change_case_upper_ #3 :n } {#4} } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + \@@_change_case_loop:nnw {#2} {#3} } + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } } - \cs_new_eq:cN { @@_change_case_upper_el-x-iota:nnnN } - \@@_change_case_upper_el:nnnN - \cs_new:Npn \@@_change_case_upper_el:N #1 - { - \char_generate:nn { "0399 } - { \char_value_catcode:n { "0399 } } - } - \cs_new:cpn { @@_change_case_upper_el-x-iota:N } #1 - { \exp_not:n {#1} } - \cs_new:Npn \@@_change_case_upper_el:nnn #1#2#3 - { \@@_change_case_upper_el:nnNw {#2} {#3} #1 } + } +\cs_new_eq:cN { @@_change_case_upper_el-x-iota:nnnn } + \@@_change_case_upper_el:nnnn +\cs_new:Npn \@@_change_case_upper_el:n #1 + { + \codepoint_generate:nn { "0399 } + { \char_value_catcode:n { "0399 } } + } +\cs_new:cpn { @@_change_case_upper_el-x-iota:n } #1 + { \exp_not:n {#1} } +\cs_new:Npn \@@_change_case_upper_el:nnn #1#2#3 + { + \@@_codepoint_process:nN + { \@@_change_case_upper_el:nnnw {#2} {#3} } #1 + } % \end{macrocode} % At this stage we have the first NFD codepoint as |#3|. What we need to know -% is whether after that we have another character token, either from the NFD or +% is whether after that we have another character, either from the NFD or % directly in the input. If not, we store the changed character at this stage. % \begin{macrocode} - \cs_new:Npn \@@_change_case_upper_el:nnNw #1#2#3#4 \q_@@_recursion_stop +\cs_new:Npn \@@_change_case_upper_el:nnnw #1#2#3#4 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_upper_el:nnnN {#3} } { - \tl_if_head_is_N_type:nTF {#4} - { \@@_change_case_upper_el:NnnN #3 } - { - \@@_change_case_store:e { \char_uppercase:N #3 } - \@@_change_case_loop:nnw - } - {#1} {#2} #4 \q_@@_recursion_stop + \@@_change_case_store:e + { \@@_change_case_codepoint:nn { upper } {#3} } + \@@_change_case_loop:nnw } + {#1} {#2} #4 \q_@@_recursion_stop + } % \end{macrocode} % Now, we check the detail of the next codepoint: again we filter out the % not-a-char cases, before checking if it's an dialytika, accent or diacritic. @@ -993,193 +956,200 @@ % to move any ypogegrammeni to after accents (in case the input is not % normalised). The ypogegrammeni itself is handled separately. % \begin{macrocode} - \cs_new:Npn \@@_change_case_upper_el:NnnN #1#2#3#4 +\cs_new:Npn \@@_change_case_upper_el:nnnN #1#2#3#4 + { + \token_if_cs:NTF #4 { - \token_if_cs:NTF #4 - { - \@@_change_case_store:e { \char_uppercase:N #1 } - \@@_change_case_loop:nnw {#2} {#3} #4 - } + \@@_change_case_store:e + { \@@_change_case_codepoint:nn { upper } {#1} } + \@@_change_case_loop:nnw {#2} {#3} #4 + } + { + \@@_change_case_if_takes_ypogegrammeni:nTF {#1} { - \@@_change_case_if_takes_ypogegrammeni:nTF { `#1 } - { - \@@_change_case_upper_el_ypogegrammeni:Nnnnnw - #1 {#2} {#3} { } { } #4 - } - { \@@_change_case_upper_el_aux:NnnN #1 {#2} {#3} #4 } + \@@_change_case_upper_el_ypogegrammeni:nnnnnw + {#1} {#2} {#3} { } { } #4 } + { \@@_change_case_upper_el_aux:nnnN {#1} {#2} {#3} #4 } } - \cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:Nnnnnw - #1#2#3#4#5#6 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:nnnnnw + #1#2#3#4#5#6 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#6} { - \tl_if_head_is_N_type:nTF {#6} + \@@_change_case_upper_el_ypogegrammeni:nnnnnN + {#1} {#2} {#3} {#4} {#5} + } + { \@@_change_case_upper_el_aux:nnnN {#1} {#2} {#3} #4#5 } + #6 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:nnnnnN #1#2#3#4#5#6 + { + \token_if_cs:NTF #6 + { \@@_change_case_upper_el_aux:nnnN {#1} {#2} {#3} #4#5 #6 } + { + \@@_codepoint_process:nN { - \@@_change_case_upper_el_ypogegrammeni:NnnnnN - #1 {#2} {#3} {#4} {#5} + \@@_change_case_upper_el_ypogegrammeni:nnnnnn + {#1} {#2} {#3} {#4} {#5} } - { \@@_change_case_upper_el_aux:NnnN #1 {#2} {#3} #4#5 } - #6 \q_@@_recursion_stop + #6 + } + } +\cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:nnnnnn #1#2#3#4#5#6 + { + \@@_codepoint_compare:nNnTF {#6} = { "0345 } + { + \@@_change_case_upper_el_ypogegrammeni:nnnnnw + {#1} {#2} {#3} {#4} {#6} } - \cs_new:Npn \@@_change_case_upper_el_ypogegrammeni:NnnnnN #1#2#3#4#5#6 { - \token_if_cs:NTF #6 - { \@@_change_case_upper_el_aux:NnnN #1 {#2} {#3} #4#5 #6 } + \bool_lazy_or:nnTF + { \@@_change_case_if_greek_accent_p:n {#6} } + { \@@_change_case_if_greek_diacritic_p:n {#6} } { - \int_compare:nNnTF { `#6 } = { "0345 } - { - \@@_change_case_upper_el_ypogegrammeni:Nnnnnw - #1 {#2} {#3} {#4} {#6} - } - { - \bool_lazy_or:nnTF - { \@@_change_case_if_greek_accent_p:n { `#6 } } - { \@@_change_case_if_greek_diacritic_p:n { `#6 } } - { - \@@_change_case_upper_el_ypogegrammeni:Nnnnnw - #1 {#2} {#3} {#4#6} {#5} - } - { \@@_change_case_upper_el_aux:NnnN #1 {#2} {#3} #4#5 #6 } - } + \@@_change_case_upper_el_ypogegrammeni:nnnnnw + {#1} {#2} {#3} {#4#6} {#5} } + { \@@_change_case_upper_el_aux:nnnN {#1} {#2} {#3} #4#5 #6 } } - \cs_new:Npn \@@_change_case_upper_el_aux:NnnN #1#2#3#4 + } +\cs_new:Npn \@@_change_case_upper_el_aux:nnnN #1#2#3#4 + { + \@@_codepoint_process:nN + { \@@_change_case_upper_el_aux:nnnn {#1} {#2} {#3} } #4 + } +\cs_new:Npn \@@_change_case_upper_el_aux:nnnn #1#2#3#4 + { + \@@_codepoint_compare:nNnTF {#4} = { "0308 } + { \@@_change_case_upper_el_dialytika:nnn {#2} {#3} {#1} } { - \int_compare:nNnTF { `#4 } = { "0308 } - { \@@_change_case_upper_el_dialytika:nnN {#2} {#3} #1 } + \@@_change_case_if_greek_accent:nTF {#4} + { \@@_change_case_upper_el_hiatus:nnnw {#2} {#3} {#1} } { - \@@_change_case_if_greek_accent:nTF { `#4 } - { \@@_change_case_upper_el_hiatus:nnNw {#2} {#3} #1 } + \@@_change_case_if_greek_diacritic:nTF {#4} { - \@@_change_case_if_greek_diacritic:nTF { `#4 } - { - \@@_change_case_store:e { \char_uppercase:N #1 } - \@@_change_case_loop:nnw {#2} {#3} - } + \@@_change_case_store:e + { \@@_change_case_codepoint:nn { upper } {#1} } + \@@_change_case_loop:nnw {#2} {#3} + } + { + \@@_codepoint_compare:nNnTF {#4} = { "0345 } + { \@@_change_case_store:e { [XXX] } } { - \int_compare:nNnTF { `#4 } = { "0345 } - { \@@_change_case_store:e { [XXX] } } - { \@@_change_case_store:e { \char_uppercase:N #1 } } - \@@_change_case_loop:nnw {#2} {#3} #4 + \@@_change_case_store:e + { \@@_change_case_codepoint:nn { upper } {#1} } } + \@@_change_case_loop:nnw {#2} {#3} #4 } } } -% \end{macrocode} + } +% \end{macrocode} % We handle \emph{dialytika} in parts as it's also needed for the hiatus. % We know only two letters take it, so we can shortcut here on the second % part of the tests. % \begin{macrocode} - \cs_new:Npn \@@_change_case_upper_el_dialytika:nnN #1#2#3 +\cs_new:Npn \@@_change_case_upper_el_dialytika:nnn #1#2#3 + { + \@@_change_case_if_takes_dialytika:nTF {#3} + { \@@_change_case_upper_el_dialytika:n {#3} } { - \@@_change_case_if_takes_dialytika:nTF { `#3 } - { \@@_change_case_upper_el_dialytika:N #3 } - { \@@_change_case_store:e { \char_uppercase:N #3 } } - \@@_change_case_upper_el_gobble:nnw {#1} {#2} + \@@_change_case_store:e + { \@@_change_case_codepoint:nn { upper } {#3} } } - \cs_new:Npn \@@_change_case_upper_el_dialytika:N #1 + \@@_change_case_upper_el_gobble:nnw {#1} {#2} + } +\cs_new:Npn \@@_change_case_upper_el_dialytika:n #1 + { + \@@_change_case_store:e { - \@@_change_case_store:e + \bool_lazy_or:nnTF + { \@@_codepoint_compare_p:nNn {#1} = { "0399 } } + { \@@_codepoint_compare_p:nNn {#1} = { "03B9 } } { - \bool_lazy_or:nnTF - { \int_compare_p:nNn { `#1 } = { "0399 } } - { \int_compare_p:nNn { `#1 } = { "03B9 } } - { \char_generate:nn { "03AA } { \@@_char_catcode:N #1 } } - { \char_generate:nn { "03AB } { \@@_char_catcode:N #1 } } + \codepoint_generate:nn { "03AA } + { \@@_change_case_catcode:nn {#1} { "03AA } } + } + { + \codepoint_generate:nn { "03AB } + { \@@_change_case_catcode:nn {#1} { "03AB } } } } + } % \end{macrocode} % Adding a hiatus needs some of the same ideas, but if there is not one we % skip this code point, hence needing a separate function. % \begin{macrocode} - \cs_new:Npn \@@_change_case_upper_el_hiatus:nnNw - #1#2#3#4 \q_@@_recursion_stop +\cs_new:Npn \@@_change_case_upper_el_hiatus:nnnw + #1#2#3#4 \q_@@_recursion_stop + { + \@@_change_case_store:e + { \@@_change_case_codepoint:nn { upper } {#3} } + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_upper_el_hiatus:nnN } + { \@@_change_case_loop:nnw } + {#1} {#2} #4 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_upper_el_hiatus:nnN #1#2#3 + { + \token_if_cs:NTF #3 + { \@@_change_case_loop:nnw {#1} {#2} #3 } { - \@@_change_case_store:e { \char_uppercase:N #3 } - \tl_if_head_is_N_type:nTF {#4} - { \@@_change_case_upper_el_hiatus:nnN } - { \@@_change_case_loop:nnw } - {#1} {#2} #4 \q_@@_recursion_stop + \@@_codepoint_process:nN + { \@@_change_case_upper_el_hiatus:nnn {#1} {#2} } #3 } - \cs_new:Npn \@@_change_case_upper_el_hiatus:nnN #1#2#3 + } +\cs_new:Npn \@@_change_case_upper_el_hiatus:nnn #1#2#3 + { + \@@_change_case_if_takes_dialytika:nTF {#3} { - \token_if_cs:NTF #3 - { \@@_change_case_loop:nnw {#1} {#2} #3 } - { - \@@_change_case_if_takes_dialytika:nTF { `#3 } - { - \@@_change_case_upper_el_dialytika:N #3 - \@@_change_case_upper_el_gobble:nnw {#1} {#2} - } - { \@@_change_case_loop:nnw {#1} {#2} #3 } - } + \@@_change_case_upper_el_dialytika:n {#3} + \@@_change_case_upper_el_gobble:nnw {#1} {#2} } + { \@@_change_case_loop:nnw {#1} {#2} #3 } + } % \end{macrocode} % For clearing out trailing combining marks after we have dealt with % the first one. % \begin{macrocode} - \cs_new:Npn \@@_change_case_upper_el_gobble:nnw - #1#2#3 \q_@@_recursion_stop - { - \tl_if_head_is_N_type:nTF {#3} - { \@@_change_case_upper_el_gobble:nnN } - { \@@_change_case_loop:nnw } - {#1} {#2} #3 \q_@@_recursion_stop - } - \cs_new:Npn \@@_change_case_upper_el_gobble:nnN #1#2#3 - { - \bool_lazy_or:nnTF - { \token_if_cs_p:N #3 } - { - ! \bool_lazy_or_p:nn - { \@@_change_case_if_greek_accent_p:n { `#3 } } - { \@@_change_case_if_greek_diacritic_p:n { `#3 } } - } - { \@@_change_case_loop:nnw {#1} {#2} #3 } - { \@@_change_case_upper_el_gobble:nnw {#1} {#2} } - } +\cs_new:Npn \@@_change_case_upper_el_gobble:nnw + #1#2#3 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_upper_el_gobble:nnN } + { \@@_change_case_loop:nnw } + {#1} {#2} #3 \q_@@_recursion_stop } -% \end{macrocode} -% For $8$-bit engines we use a simplified approach: covers the common -% requirements. This is basically how \pkg{xgreek} works but done by -% expansion: use fixed mappings from accented to accent-free letters. -% Only the two- and three-byte ranges can be involved. -% \begin{macrocode} +\cs_new:Npn \@@_change_case_upper_el_gobble:nnN #1#2#3 { - \cs_new:Npn \@@_change_case_upper_el:nnnN #1#2#3#4 - { - \int_compare:nNnTF { `#4 } > { "80 } - { - \int_compare:nNnTF { `#4 } < { "E0 } - { \@@_change_case_upper_el:nnnNN } - { - \int_compare:nNnTF { `#4 } < { "F0 } - { \@@_change_case_upper_el:nnnNNN } - { \@@_change_case_char:nnnN } - } - } - { \@@_change_case_char:nnnN } - {#1} {#2} {#3} #4 - } - \cs_new:Npn \@@_change_case_upper_el:nnnNN #1#2#3#4#5 - { \@@_change_case_upper_el:nnnn {#1} {#2} {#3} {#4#5} } - \cs_new:Npn \@@_change_case_upper_el:nnnNNN #1#2#3#4#5#6 - { \@@_change_case_upper_el:nnnn {#1} {#2} {#3} {#4#5#6} } - \cs_new:Npn \@@_change_case_upper_el:nnnn #1#2#3#4 + \token_if_cs:NTF #3 + { \@@_change_case_loop:nnw {#1} {#2} } { - \cs_if_exist:cTF { c_@@_uppercase_el_ \tl_to_str:n {#4} _tl } - { - \@@_change_case_store:v - { c_@@_uppercase_el_ \tl_to_str:n {#4} _tl } - \@@_change_case_loop:nnw {#1} {#3} - } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + \@@_codepoint_process:nN + { \@@_change_case_upper_el_gobble:nnn {#1} {#2} } } + #3 + } +\cs_new:Npn \@@_change_case_upper_el_gobble:nnn #1#2#3 + { + \bool_lazy_or:nnTF + { \@@_change_case_if_greek_accent_p:n {#3} } + { \@@_change_case_if_greek_diacritic_p:n {#3} } + { \@@_change_case_upper_el_gobble:nnw {#1} {#2} } + { \@@_change_case_loop:nnw {#1} {#2} #3 } } % \end{macrocode} % Luckily the Greek range is limited and clear. % \begin{macrocode} \prg_new_conditional:Npnn \@@_change_case_if_greek:n #1 { TF } { + \exp_args:Nf \@@_change_case_if_greek:n + { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } } + } +\cs_new:Npn \@@_change_case_if_greek:n #1 + { \if_int_compare:w #1 < "0370 \exp_stop_f: \prg_return_false: \else: @@ -1207,6 +1177,11 @@ % \begin{macrocode} \prg_new_conditional:Npnn \@@_change_case_if_greek_accent:n #1 { TF , p } { + \exp_args:Nf \@@_change_case_if_greek_accent:n + { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } } + } +\cs_new:Npn \@@_change_case_if_greek_accent:n #1 + { \if_int_compare:w #1 = "0300 \exp_stop_f: \prg_return_true: \else: @@ -1236,6 +1211,11 @@ \prg_new_conditional:Npnn \@@_change_case_if_greek_diacritic:n #1 { TF , p } { + \exp_args:Nf \@@_change_case_if_greek_diacritic:n + { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } } + } +\cs_new:Npn \@@_change_case_if_greek_diacritic:n #1 + { \if_int_compare:w #1 = "0304 \exp_stop_f: \prg_return_true: \else: @@ -1260,6 +1240,11 @@ } \prg_new_conditional:Npnn \@@_change_case_if_takes_dialytika:n #1 { TF } { + \exp_args:Nf \@@_change_case_if_takes_dialytika:n + { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } } + } +\cs_new:Npn \@@_change_case_if_takes_dialytika:n #1 + { \if_int_compare:w #1 = "0399 \exp_stop_f: \prg_return_true: \else: @@ -1280,6 +1265,11 @@ } \prg_new_conditional:Npnn \@@_change_case_if_takes_ypogegrammeni:n #1 { TF } { + \exp_args:Nf \@@_change_case_if_takes_ypogegrammeni:n + { \int_eval:n { \@@_codepoint_from_chars:Nw #1 } } + } +\cs_new:Npn \@@_change_case_if_takes_ypogegrammeni:n #1 + { \if_int_compare:w #1 = "03B1 \exp_stop_f: \prg_return_true: \else: @@ -1317,60 +1307,79 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:Nnnw} % \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnN} -% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnNw} -% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:NnnN} +% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnn} +% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnnw} +% \begin{macro}[EXP]{\@@_change_case_boundary_upper_el:nnnN} % There is one special case in Greek that needs to be picked up based on % being an isolated letter. We do that using a test similar to final sigma, % but it has to fire off from the space grabber. % \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } +\cs_new:Npn \@@_change_case_boundary_upper_el:Nnnw + #1#2#3#4 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_boundary_upper_el:nnN } + { \@@_change_case_loop:nnw } + {#2} {#3} #4 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_boundary_upper_el:nnN #1#2#3 { - \cs_new:Npn \@@_change_case_boundary_upper_el:Nnnw - #1#2#3#4 \q_@@_recursion_stop + \token_if_cs:NTF #3 + { \@@_change_case_loop:nnw {#1} {#2} } { - \tl_if_head_is_N_type:nTF {#4} - { \@@_change_case_boundary_upper_el:nnN } - { \@@_change_case_loop:nnw } - {#2} {#3} #4 \q_@@_recursion_stop + \@@_codepoint_process:nN + { \@@_change_case_boundary_upper_el:nnn {#1} {#2} } } - \cs_new:Npn \@@_change_case_boundary_upper_el:nnN #1#2#3 + #3 + } +\cs_new:Npn \@@_change_case_boundary_upper_el:nnn #1#2#3 + { + \bool_lazy_or:nnTF + { \@@_codepoint_compare_p:nNn {#3} = { "03AE } } + { \@@_codepoint_compare_p:nNn {#3} = { "1F22 } } + { \@@_change_case_boundary_upper_el:nnnw {#1} {#2} {#3} } + { \@@_change_case_loop:nnw {#1} {#2} #3 } + } +\cs_new:Npn \@@_change_case_boundary_upper_el:nnnw + #1#2#3#4 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_boundary_upper_el:nnnN {#3} } { - \bool_lazy_or:nnTF - { \token_if_cs_p:N #3 } + \@@_change_case_store:e { - ! \bool_lazy_or_p:nn - { \int_compare_p:nNn { `#3 } = { "03AE } } - { \int_compare_p:nNn { `#3 } = { "1F22 } } + \codepoint_generate:nn { "0389 } + { \@@_change_case_catcode:nn {#3} { "0389 } } } - { \@@_change_case_loop:nnw } - { \@@_change_case_boundary_upper_el:nnNw } - {#1} {#2} #3 + \@@_change_case_loop:nnw } - \cs_new:Npn \@@_change_case_boundary_upper_el:nnNw - #1#2#3#4 \q_@@_recursion_stop - { - \tl_if_head_is_N_type:nTF {#4} - { \@@_change_case_boundary_upper_el:NnnN #3 } - { - \@@_change_case_store:e - { \char_generate:nn { "0389 } { \@@_char_catcode:N #3 } } - \@@_change_case_loop:nnw - } - {#1} {#2} #4 \q_@@_recursion_stop + {#1} {#2} #4 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_boundary_upper_el:nnnN #1#2#3#4 + { + \MARJ + \bool_lazy_or:nnTF + { \token_if_letter_p:N #4 } + { + \bool_lazy_and_p:nn + { \token_if_active_p:N #4 } + { ! \int_compare_p:nNn {`#4} < { "80 } } } - \cs_new:Npn \@@_change_case_boundary_upper_el:NnnN #1#2#3#4 + { \@@_change_case_loop:nnw {#2} {#3} #1#4 } { - \token_if_letter:NTF #4 - { \@@_change_case_loop:nnw {#2} {#3} #1#4 } + \@@_change_case_store:e { - \@@_change_case_store:e - { \char_generate:nn { "0389 } { \@@_char_catcode:N #1 } } - \@@_change_case_loop:nnw {#2} {#3} #4 + \codepoint_generate:nn { "0389 } + { \@@_change_case_catcode:nn {#1} { "0389 } } } + \@@_change_case_loop:nnw {#2} {#3} #4 } } % \end{macrocode} @@ -1378,98 +1387,89 @@ % \end{macro} % \end{macro} % \end{macro} -% \begin{macro}[EXP]{\@@_change_case_title_el:nnnN} +% \end{macro} +% \begin{macro}[EXP]{\@@_change_case_title_el:nnnn} % Titlecasing retains accents, but to prevent the uppercasing code % from kicking in, there has to be an explicit function here. % \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_new:Npn \@@_change_case_title_el:nnnN #1#2#3#4 - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } - } +\cs_new:Npn \@@_change_case_title_el:nnnn #1#2#3#4 + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } % \end{macrocode} % \end{macro} % % \begin{macro}[EXP] % { -% \@@_change_case_upper_hy:nnnN , -% \@@_change_case_title_hy:nnNN , -% \@@_change_case_upper_hy-x-yiwn:nnnN , -% \@@_change_case_title_hy-x-yiwn:nnNN +% \@@_change_case_upper_hy:nnnn , +% \@@_change_case_title_hy:nnnn , +% \@@_change_case_upper_hy-x-yiwn:nnnn , +% \@@_change_case_title_hy-x-yiwn:nnnn % } % See \url{https://www.unicode.org/L2/L2020/20143-armenian-ech-yiwn.pdf}. % \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } +\cs_new:Npn \@@_change_case_upper_hy:nnnn #1#2#3#4 { - \cs_new:cpn { @@_change_case_upper_hy:nnnN } #1#2#3#4 + \@@_codepoint_compare:nNnTF {#4} = { "0587 } { - \int_compare:nNnTF { `#4 } = { "0587 } + \@@_change_case_store:e { - \@@_change_case_store:e - { - \char_generate:nn { "0535 } { \@@_char_catcode:N #4 } - \char_generate:nn { "054E } { \@@_char_catcode:N #4 } - } - \use:c { @@_change_case_char_next_ #2 :nn } - {#2} {#3} + \codepoint_generate:nn { "0535 } + { \@@_change_case_catcode:nn {#4} { "0535 } } + \codepoint_generate:nn { "054E } + { \@@_change_case_catcode:nn {#4} { "054E } } } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + \use:c { @@_change_case_next_ #2 :nn } + {#2} {#3} } - \cs_new:cpn { @@_change_case_title_hy:nnnN } #1#2#3#4 + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } + } +\cs_new:Npn \@@_change_case_title_hy:nnnn #1#2#3#4 + { + \@@_codepoint_compare:nNnTF {#4} = { "0587 } { - \int_compare:nNnTF { `#4 } = { "0587 } + \@@_change_case_store:e { - \@@_change_case_store:e - { - \char_generate:nn { "0535 } { \@@_char_catcode:N #4 } - \char_generate:nn { "057E } { \@@_char_catcode:N #4 } - } - \use:c { @@_change_case_char_next_ #2 :nn } - {#2} {#3} + \codepoint_generate:nn { "0535 } + { \@@_change_case_catcode:nn {#4} { "0535 } } + \codepoint_generate:nn { "057E } + { \@@_change_case_catcode:nn {#4} { "057E } } } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + \use:c { @@_change_case_next_ #2 :nn } + {#2} {#3} } - \cs_new:cpn { @@_change_case_upper_hy-x-yiwn:nnnN } #1#2#3#4 - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } - \cs_new_eq:cc { @@_change_case_title_hy-x-yiwn:nnnN } - { @@_change_case_upper_hy-x-yiwn:nnnN } + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } } +\cs_new:cpn { @@_change_case_upper_hy-x-yiwn:nnnn } #1#2#3#4 + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } +\cs_new_eq:cc { @@_change_case_title_hy-x-yiwn:nnnn } + { @@_change_case_upper_hy-x-yiwn:nnnn } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\@@_change_case_lower_la-x-medieval:nnnN} -% \begin{macro}[EXP]{\@@_change_case_upper_la-x-medieval:nnnN} +% \begin{macro}[EXP]{\@@_change_case_lower_la-x-medieval:nnnn} +% \begin{macro}[EXP]{\@@_change_case_upper_la-x-medieval:nnnn} % Simply swaps of characters. % \begin{macrocode} -\cs_new:cpn { @@_change_case_lower_la-x-medieval:nnnN } #1#2#3#4 +\cs_new:cpn { @@_change_case_lower_la-x-medieval:nnnn } #1#2#3#4 { - \int_compare:nNnTF { `#4 } = { `V } + \@@_codepoint_compare:nNnTF {#4} = { "0056 } { \@@_change_case_store:e - { - \char_generate:nn { `u } { \@@_char_catcode:N #4 } - } - \use:c { @@_change_case_char_next_ #2 :nn } + { \char_generate:nn { "0075 } { \@@_char_catcode:N #4 } } + \use:c { @@_change_case_next_ #2 :nn } {#2} {#3} } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } } -\cs_new:cpn { @@_change_case_upper_la-x-medieval:nnnN } #1#2#3#4 +\cs_new:cpn { @@_change_case_upper_la-x-medieval:nnnn } #1#2#3#4 { - \int_compare:nNnTF { `#4 } = { `u } + \@@_codepoint_compare:nNnTF {#4} = { "0075 } { \@@_change_case_store:e - { - \char_generate:nn { `V } { \@@_char_catcode:N #4 } - } - \use:c { @@_change_case_char_next_ #2 :nn } + { \char_generate:nn { "0056 } { \@@_char_catcode:N #4 } } + \use:c { @@_change_case_next_ #2 :nn } {#2} {#3} } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } } % \end{macrocode} % \end{macro} @@ -1477,191 +1477,223 @@ % % \begin{macro}[EXP] % { -% \@@_change_cases_lower_lt:nnnN , -% \@@_change_cases_lower_lt_auxi:nnnN , -% \@@_change_cases_lower_lt_auxii:nnnN +% \@@_change_cases_lower_lt:nnnn , +% \@@_change_cases_lower_lt_auxi:nnnn , +% \@@_change_cases_lower_lt_auxii:nnnn % } % \begin{macro}[rEXP]{\@@_change_case_lower_lt:nnw} % \begin{macro}[rEXP]{\@@_change_case_lower_lt:nnN} +% \begin{macro}[rEXP]{\@@_change_case_lower_lt:nnn} % For Lithuanian, the issue to be dealt with is dots over lower case % letters: these should be present if there is another accent. The first step % is a simple match attempt: look for the three uppercase accented letters % which should gain a dot-above char in their lowercase form. % \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } +\cs_new:Npn \@@_change_case_lower_lt:nnnn #1#2#3#4 { - \cs_new:Npn \@@_change_case_lower_lt:nnnN #1#2#3#4 - { - \exp_args:Ne \@@_change_case_lower_lt_auxi:nnnN + \exp_args:Ne \@@_change_case_lower_lt_auxi:nnnn + { + \int_case:nn { \@@_codepoint_from_chars:Nw #4 } { - \int_case:nn { `#4 } - { - { "00CC } { "0300 } - { "00CD } { "0301 } - { "0128 } { "0303 } - } - } - {#2} {#3} #4 + { "00CC } { "0300 } + { "00CD } { "0301 } + { "0128 } { "0303 } + } } + {#2} {#3} {#4} + } % \end{macrocode} % If there was a hit, output the result with the dot-above and move on. % Otherwise, look for one of the three letters that can take a combining % accent: I, J and I-ogonek. % \begin{macrocode} - \cs_new:Npn \@@_change_case_lower_lt_auxi:nnnN #1#2#3#4 +\cs_new:Npn \@@_change_case_lower_lt_auxi:nnnn #1#2#3#4 + { + \tl_if_blank:nTF {#1} { - \tl_if_blank:nTF {#1} + \exp_args:Ne \@@_change_case_lower_lt_auxii:nnnn { - \exp_args:Ne \@@_change_case_lower_lt_auxii:nnnN + \int_case:nn { \@@_codepoint_from_chars:Nw #4 } { - \int_case:nn { `#4 } - { - { "0049 } { "0069 } - { "004A } { "006A } - { "012E } { "012F } - } - } - {#2} {#3} #4 + { "0049 } { "0069 } + { "004A } { "006A } + { "012E } { "012F } + } } + {#2} {#3} {#4} + } + { + \@@_change_case_store:e { - \@@_change_case_store:e - { - \char_generate:nn { "0069 } { \@@_char_catcode:N #4 } - \char_generate:nn { "0307 } { \@@_char_catcode:N #4 } - \char_generate:nn {#1} { \@@_char_catcode:N #4 } - } - \@@_change_case_loop:nnw {#2} {#3} + \codepoint_generate:nn { "0069 } + { \@@_change_case_catcode:nn {#4} { "0069 } } + \codepoint_generate:nn { "0307 } + { \@@_change_case_catcode:nn {#4} { "0307 } } + \codepoint_generate:nn {#1} + { \@@_change_case_catcode:nn {#4} {#1} } } + \@@_change_case_loop:nnw {#2} {#3} } + } % \end{macrocode} % Again, branch depending on a hit. If there is one, we output the character % then need to look for a combining accent: as usual, we need to be aware of % the loop situation. % \begin{macrocode} - \cs_new:Npn \@@_change_case_lower_lt_auxii:nnnN #1#2#3#4 +\cs_new:Npn \@@_change_case_lower_lt_auxii:nnnn #1#2#3#4 + { + \tl_if_blank:nTF {#1} + { \@@_change_case_codepoint:nnnn {#2} {#2} {#3} {#4} } { - \tl_if_blank:nTF {#1} - { \@@_change_case_lower_sigma:nnnN {#2} {#2} {#3} #4 } + \@@_change_case_store:e { - \@@_change_case_store:e - { \char_generate:nn {#1} { \@@_char_catcode:N #4 } } - \@@_change_case_lower_lt:nnw {#2} {#3} + \codepoint_generate:nn {#1} + { \@@_change_case_catcode:nn {#4} {#1} } } + \@@_change_case_lower_lt:nnw {#2} {#3} } - \cs_new:Npn \@@_change_case_lower_lt:nnw #1#2#3 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_lower_lt:nnw #1#2#3 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_lower_lt:nnN } + { \@@_change_case_loop:nnw } + {#1} {#2} #3 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_lower_lt:nnN #1#2#3 + { + \@@_codepoint_process:nN + { \@@_change_case_lower_lt:nnn {#1} {#2} } #3 + } +\cs_new:Npn \@@_change_case_lower_lt:nnn #1#2#3 + { + \bool_lazy_and:nnT { - \tl_if_head_is_N_type:nTF {#3} - { \@@_change_case_lower_lt:nnN } - { \@@_change_case_loop:nnw } - {#1} {#2} #3 \q_@@_recursion_stop + \bool_lazy_or_p:nn + { ! \tl_if_single_p:n {#3} } + { ! \token_if_cs_p:N #3 } } - \cs_new:Npn \@@_change_case_lower_lt:nnN #1#2#3 { - \bool_lazy_and:nnT - { ! \token_if_cs_p:N #3 } + \bool_lazy_any_p:n { - \bool_lazy_any_p:n - { - { \int_compare_p:nNn { `#3 } = { "0300 } } - { \int_compare_p:nNn { `#3 } = { "0301 } } - { \int_compare_p:nNn { `#3 } = { "0303 } } - } + { \@@_codepoint_compare_p:nNn {#3} = { "0300 } } + { \@@_codepoint_compare_p:nNn {#3} = { "0301 } } + { \@@_codepoint_compare_p:nNn {#3} = { "0303 } } } + } + { + \@@_change_case_store:e { - \@@_change_case_store:e - { \char_generate:nn { "0307 } { \@@_char_catcode:N #3 } } + \codepoint_generate:nn { "0307 } + { \@@_change_case_catcode:nn {#3} { "0307 } } } - \@@_change_case_loop:nnw {#1} {#2} #3 } + \@@_change_case_loop:nnw {#1} {#2} #3 } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % \begin{macro}[EXP] % { -% \@@_change_cases_upper_lt:nnnN , -% \@@_change_cases_upper_lt_aux:nnnN +% \@@_change_cases_upper_lt:nnnn , +% \@@_change_cases_upper_lt_aux:nnnn % } % \begin{macro}[rEXP]{\@@_change_case_upper_lt:nnw} % \begin{macro}[rEXP]{\@@_change_case_upper_lt:nnN} +% \begin{macro}[rEXP]{\@@_change_case_upper_lt:nnn} % The uppercasing version: first find i/j/i-ogonek, then look for the % combining char: drop it if present. % \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_new:Npn \@@_change_case_upper_lt:nnnN #1#2#3#4 - { - \exp_args:Ne \@@_change_case_upper_lt_aux:nnnN +\cs_new:Npn \@@_change_case_upper_lt:nnnn #1#2#3#4 + { + \exp_args:Ne \@@_change_case_upper_lt_aux:nnnn + { + \int_case:nn { \@@_codepoint_from_chars:Nw #4 } { - \int_case:nn { `#4 } - { - { "0069 } { "0049 } - { "006A } { "004A } - { "012F } { "012E } - } - } - {#2} {#3} #4 + { "0069 } { "0049 } + { "006A } { "004A } + { "012F } { "012E } + } } - \cs_new:Npn \@@_change_case_upper_lt_aux:nnnN #1#2#3#4 - { - \tl_if_blank:nTF {#1} - { \@@_change_case_char:nnnN { upper } {#2} {#3} #4 } - { - \@@_change_case_store:e - { \char_generate:nn {#1} { \@@_char_catcode:N #4 } } - \@@_change_case_upper_lt:nnw {#2} {#3} - } - } - \cs_new:Npn \@@_change_case_upper_lt:nnw #1#2#3 \q_@@_recursion_stop + {#2} {#3} {#4} + } +\cs_new:Npn \@@_change_case_upper_lt_aux:nnnn #1#2#3#4 + { + \tl_if_blank:nTF {#1} + { \@@_change_case_codepoint:nnnn { upper } {#2} {#3} {#4} } { - \tl_if_head_is_N_type:nTF {#3} - { \@@_change_case_upper_lt:nnN } - { \use:c { @@_change_case_char_next_ #1 :nn } } - {#1} {#2} #3 \q_@@_recursion_stop + \@@_change_case_store:e + { + \codepoint_generate:nn {#1} + { \@@_change_case_catcode:nn {#4} {#1} } + } + \@@_change_case_upper_lt:nnw {#2} {#3} } - \cs_new:Npn \@@_change_case_upper_lt:nnN #1#2#3 + } +\cs_new:Npn \@@_change_case_upper_lt:nnw #1#2#3 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#3} + { \@@_change_case_upper_lt:nnN } + { \use:c { @@_change_case_next_ #1 :nn } } + {#1} {#2} #3 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_upper_lt:nnN #1#2#3 + { + \@@_codepoint_process:nN + { \@@_change_case_upper_lt:nnn {#1} {#2} } #3 + } +\cs_new:Npn \@@_change_case_upper_lt:nnn #1#2#3 + { + \bool_lazy_and:nnTF { - \bool_lazy_and:nnTF + \bool_lazy_or_p:nn + { ! \tl_if_single_p:n {#3} } { ! \token_if_cs_p:N #3 } - { \int_compare_p:nNn { `#3 } = { "0307 } } - { \use:c { @@_change_case_char_next_ #1 :nn } {#1} {#2} } - { \use:c { @@_change_case_char_next_ #1 :nn } {#1} {#2} #3 } } + { \@@_codepoint_compare_p:nNn {#3} = { "0307 } } + { \use:c { @@_change_case_next_ #1 :nn } {#1} {#2} } + { \use:c { @@_change_case_next_ #1 :nn } {#1} {#2} #3 } } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % -% \begin{macro}[EXP]{\@@_change_case_title_nl:nnnN} +% \begin{macro}[EXP] +% {\@@_change_case_title_nl:nnnn, \@@_change_case_title_nl_aux:nnnn} % \begin{macro}[EXP]{\@@_change_case_title_nl:nnw} % \begin{macro}[EXP]{\@@_change_case_title_nl:nnN} % For Dutch, there is a single look-ahead test for \texttt{ij} when % title casing. If the appropriate letters are found, produce \texttt{IJ} % and gobble the \texttt{j}/\texttt{J}. % \begin{macrocode} -\cs_new:Npn \@@_change_case_title_nl:nnnN #1#2#3#4 +\cs_new:Npn \@@_change_case_title_nl:nnnn #1#2#3#4 + { + \tl_if_single:nTF {#4} + { \@@_change_case_title_nl_aux:nnnn } + { \@@_change_case_codepoint:nnnn } + {#1} {#2} {#3} {#4} + } +\cs_new:Npn \@@_change_case_title_nl_aux:nnnn #1#2#3#4 { \bool_lazy_or:nnTF - { \int_compare_p:nNn { `#4 } = { "0049 } } - { \int_compare_p:nNn { `#4 } = { "0069 } } + { \int_compare_p:nNn {`#4} = { "0049 } } + { \int_compare_p:nNn {`#4} = { "0069 } } { \@@_change_case_store:e { \char_generate:nn { "0049 } { \@@_char_catcode:N #4 } } \@@_change_case_title_nl:nnw {#2} {#3} } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } } \cs_new:Npn \@@_change_case_title_nl:nnw #1#2#3 \q_@@_recursion_stop { \tl_if_head_is_N_type:nTF {#3} { \@@_change_case_title_nl:nnN } - { \use:c { @@_change_case_char_next_ #1 :nn } } + { \use:c { @@_change_case_next_ #1 :nn } } {#1} {#2} #3 \q_@@_recursion_stop } \cs_new:Npn \@@_change_case_title_nl:nnN #1#2#3 @@ -1670,118 +1702,96 @@ { ! \token_if_cs_p:N #3 } { \bool_lazy_or_p:nn - { \int_compare_p:nNn { `#3 } = { "004A } } - { \int_compare_p:nNn { `#3 } = { "006A } } + { \int_compare_p:nNn {`#3} = { "004A } } + { \int_compare_p:nNn {`#3} = { "006A } } } { \@@_change_case_store:e { \char_generate:nn { "004A } { \@@_char_catcode:N #3 } } - \use:c { @@_change_case_char_next_ #1 :nn } {#1} {#2} + \use:c { @@_change_case_next_ #1 :nn } {#1} {#2} } - { \use:c { @@_change_case_char_next_ #1 :nn } {#1} {#2} #3 } + { \use:c { @@_change_case_next_ #1 :nn } {#1} {#2} #3 } } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnnN} +% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnnn} % \begin{macro}[EXP]{\@@_change_case_lower_tr:nnNw} % \begin{macro}[EXP]{\@@_change_case_lower_tr:NnnN} -% \begin{macro}[EXP]{\@@_change_case_lower_tr:nnnNN} +% \begin{macro}[EXP]{\@@_change_case_lower_tr:Nnnn} % The Turkic languages need special treatment for dotted-i and dotless-i. % The lower casing rule can be expressed in terms of searching first for % either a dotless-I or a dotted-I. In the latter case the mapping is % easy, but in the former there is a second stage search. % \begin{macrocode} -\bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } +\cs_new:Npn \@@_change_case_lower_tr:nnnn #1#2#3#4 { - \cs_new:Npn \@@_change_case_lower_tr:nnnN #1#2#3#4 + \@@_codepoint_compare:nNnTF {#4} = { "0049 } + { \@@_change_case_lower_tr:nnNw {#1} {#3} #4 } { - \int_compare:nNnTF { `#4 } = { "0049 } - { \@@_change_case_lower_tr:nnNw {#1} {#3} #4 } + \@@_codepoint_compare:nNnTF {#4} = { "0130 } { - \int_compare:nNnTF { `#4 } = { "0130 } + \@@_change_case_store:e { - \@@_change_case_store:e - { \char_generate:nn { "0069 } { \@@_char_catcode:N #4 } } - \@@_change_case_loop:nnw {#1} {#3} + \codepoint_generate:nn { "0069 } + { \@@_change_case_catcode:nn {#4} { "0069 } } } - { \@@_change_case_lower_sigma:nnnN {#1} {#2} {#3} #4 } + \@@_change_case_loop:nnw {#1} {#3} } + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } } + } % \end{macrocode} % After a dotless-I there may be a dot-above character. If there is then % a dotted-i should be produced, otherwise output a dotless-i. When the % combination is found both the dotless-I and the dot-above char have to % be removed from the input. % \begin{macrocode} - \cs_new:Npn \@@_change_case_lower_tr:nnNw #1#2#3#4 \q_@@_recursion_stop +\cs_new:Npn \@@_change_case_lower_tr:nnNw #1#2#3#4 \q_@@_recursion_stop + { + \tl_if_head_is_N_type:nTF {#4} + { \@@_change_case_lower_tr:NnnN #3 {#1} {#2} } { - \tl_if_head_is_N_type:nTF {#4} - { \@@_change_case_lower_tr:NnnN #3 } + \@@_change_case_store:e { - \@@_change_case_store:e - { \char_generate:nn { "0131 } { \@@_char_catcode:N #3 } } - \@@_change_case_loop:nnw + \codepoint_generate:nn { "0131 } + { \@@_change_case_catcode:nn {#3} { "0131 } } } - {#1} {#2} #4 \q_@@_recursion_stop + \@@_change_case_loop:nnw {#1} {#2} } - \cs_new:Npn \@@_change_case_lower_tr:NnnN #1#2#3#4 + #4 \q_@@_recursion_stop + } +\cs_new:Npn \@@_change_case_lower_tr:NnnN #1#2#3#4 + { + \@@_codepoint_process:nN + { \@@_change_case_lower_tr:Nnnn #1 {#2} {#3} } #4 + } +\cs_new:Npn \@@_change_case_lower_tr:Nnnn #1#2#3#4 + { + \bool_lazy_or:nnTF { - \bool_lazy_or:nnTF + \bool_lazy_and_p:nn + { \tl_if_single_p:n {#4} } { \token_if_cs_p:N #4 } - { ! \int_compare_p:nNn { `#4 } = { "0307 } } - { - \@@_change_case_store:e - { \char_generate:nn { "0131 } { \@@_char_catcode:N #1 } } - \@@_change_case_loop:nnw {#2} {#3} #4 - } - { - \@@_change_case_store:e - { \char_generate:nn { "0069 } { \@@_char_catcode:N #1 } } - \@@_change_case_loop:nnw {#2} {#3} - } } - } -% \end{macrocode} -% For $8$-bit engines, dot-above is not available so there is a simple -% test for an upper-case I. Then we can look for the UTF-8 representation of -% an upper case dotted-I without the combining char. If it's not there, -% preserve the UTF-8 sequence as-is. With $8$bit engines, we cannot -% completely preserve category codes, so we have to make some assumptions: -% output a \enquote{normal} \texttt{i} for the dotted case. As the original -% character here is catcode-$13$, we have to make a choice about handling -% of |i|: generate a \enquote{normal} one. -% \begin{macrocode} - { - \cs_new:Npn \@@_change_case_lower_tr:nnnN #1#2#3#4 + { ! \@@_codepoint_compare_p:nNn {#4} = { "0307 } } { - \int_compare:nNnTF { `#4 } = { "0049 } - { - \@@_change_case_store:V \c_@@_dotless_i_tl - \@@_change_case_loop:nnw {#1} {#3} - } + \@@_change_case_store:e { - \int_compare:nNnTF { `#4 } = { "00C4 } - { \@@_change_case_lower_tr:nnnNN {#1} {#2} {#3} #4 } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + \codepoint_generate:nn { "0131 } + { \@@_change_case_catcode:nn {#1} { "0131 } } } + \@@_change_case_loop:nnw {#2} {#3} #4 } - \cs_new:Npn \@@_change_case_lower_tr:nnnNN #1#2#3#4#5 { - \int_compare:nNnTF { `#5 } = { "00B0 } + \@@_change_case_store:e { - \@@_change_case_store:e - { - \char_generate:nn { "0069 } - { \char_value_catcode:n { "0069 } } - } - \@@_change_case_loop:nnw {#1} {#3} + \codepoint_generate:nn { "0069 } + { \@@_change_case_catcode:nn {#1} { "0069 } } } - { \@@_change_case_char:nnnN {#1} {#2} {#3} #4#5 } + \@@_change_case_loop:nnw {#2} {#3} } } % \end{macrocode} @@ -1789,1055 +1799,36 @@ % \end{macro} % \end{macro} % \end{macro} -% \begin{macro}[EXP]{\@@_change_case_upper_tr:nnnN} +% \begin{macro}[EXP]{\@@_change_case_upper_tr:nnnn} % Uppercasing is easier: just one exception with no context. % \begin{macrocode} -\cs_new:Npx \@@_change_case_upper_tr:nnnN #1#2#3#4 +\cs_new:Npn \@@_change_case_upper_tr:nnnn #1#2#3#4 { - \exp_not:N \int_compare:nNnTF { `#4 } = { "0069 } + \@@_codepoint_compare:nNnTF {#4} = { "0069 } { - \bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \exp_not:N \@@_change_case_store:e - { - \exp_not:N \char_generate:nn { "0130 } - { \exp_not:N \@@_char_catcode:N #4 } - } - } + \@@_change_case_store:e { - \exp_not:N \@@_change_case_store:V - \exp_not:N \c_@@_dotted_I_tl + \codepoint_generate:nn { "0130 } + { \@@_change_case_catcode:nn {#4} { "0130 } } } - \exp_not:N \use:c { @@_change_case_char_next_ #2 :nn } {#2} {#3} + \use:c { @@_change_case_next_ #2 :nn } {#2} {#3} } - { \exp_not:N \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } + { \@@_change_case_codepoint:nnnn {#1} {#2} {#3} {#4} } } % \end{macrocode} % \end{macro} % % \begin{macro}[EXP] -% {\@@_change_case_lower_az:nnnN, \@@_change_case_upper_az:nnnN} +% {\@@_change_case_lower_az:nnnn, \@@_change_case_upper_az:nnnn} % Straight copies. % \begin{macrocode} -\cs_new_eq:NN \@@_change_case_lower_az:nnnN - \@@_change_case_lower_tr:nnnN -\cs_new_eq:NN \@@_change_case_upper_az:nnnN - \@@_change_case_upper_tr:nnnN +\cs_new_eq:NN \@@_change_case_lower_az:nnnn + \@@_change_case_lower_tr:nnnn +\cs_new_eq:NN \@@_change_case_upper_az:nnnn + \@@_change_case_upper_tr:nnnn % \end{macrocode} % \end{macro} % -% \subsection{Case changing data for $8$-bit engines} -% -% \begin{variable} -% { -% \c_@@_dotless_i_tl , -% \c_@@_dotted_I_tl , -% \c_@@_i_ogonek_tl , -% \c_@@_I_ogonek_tl , -% \c_@@_final_sigma_tl , -% \c_@@_sigma_tl , -% \c_@@_grosses_Eszett_tl -% } -% For cases where there is an $8$-bit option in the |T1| font set up, -% a variant is provided in both cases. There are also a few extras for -% |LGR|. -% \begin{macrocode} -\group_begin: - \bool_lazy_or:nnF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_set_protected:Npn \@@_tmp:w #1#2 - { - \group_begin: - \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4 - { - \tl_const:Nx #1 - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##1} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##2} { 13 } - \tl_if_blank:nF {##3} - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##3} { 13 } - } - } - } - \use:x - { \@@_tmp:w \char_to_utfviii_bytes:n { "#2 } } - \group_end: - } - \@@_tmp:w \c_@@_dotless_i_tl { 0131 } - \@@_tmp:w \c_@@_dotted_I_tl { 0130 } - \@@_tmp:w \c_@@_i_ogonek_tl { 012F } - \@@_tmp:w \c_@@_I_ogonek_tl { 012E } - \@@_tmp:w \c_@@_final_sigma_tl { 03C2 } - \@@_tmp:w \c_@@_sigma_tl { 03C3 } - \@@_tmp:w \c_@@_grosses_Eszett_tl { 1E9E } - } -\group_end: -% \end{macrocode} -% \end{variable} -% -% For $8$-bit engines we now need to define the case-change data for -% the multi-octet mappings. This data is here not in the \pkg{char} module -% as the multi-byte nature means they are never |N|-type. As this data is -% needed both for text and string work, it is stored as |kernel|: it remains -% internal as it is not really suitable for wider exposure. -% -% The first set of codepoints are those in |T1|: all of these are two bytes. -% \begin{macrocode} -\group_begin: - \bool_lazy_or:nnF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { - \cs_set_protected:Npn \@@_loop:nn #1#2 - { - \quark_if_recursion_tail_stop:n {#1} - \use:x - { - \@@_tmp:w - \char_to_utfviii_bytes:n { "#1 } - \char_to_utfviii_bytes:n { "#2 } - } - \@@_loop:nn - } - \cs_set_protected:Npn \@@_tmp:nnnn #1#2#3#4#5 - { - \tl_const:cx - { - c__kernel_ #1 case_ - \char_generate:nn {#2} { 12 } - \char_generate:nn {#3} { 12 } - _tl - } - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#4} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#5} { 13 } - } - } - \cs_set_protected:Npn \@@_tmp:w #1#2#3#4#5#6#7#8 - { - \tl_const:cx - { - c__kernel_lowercase_ - \char_generate:nn {#1} { 12 } - \char_generate:nn {#2} { 12 } - _tl - } - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#5} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#6} { 13 } - } - \@@_tmp:nnnn { upper } {#5} {#6} {#1} {#2} - \@@_tmp:nnnn { title } {#5} {#6} {#1} {#2} - } - \@@_loop:nn - { 00C0 } { 00E0 } - { 00C1 } { 00E1 } - { 00C2 } { 00E2 } - { 00C3 } { 00E3 } - { 00C4 } { 00E4 } - { 00C5 } { 00E5 } - { 00C6 } { 00E6 } - { 00C7 } { 00E7 } - { 00C8 } { 00E8 } - { 00C9 } { 00E9 } - { 00CA } { 00EA } - { 00CB } { 00EB } - { 00CC } { 00EC } - { 00CD } { 00ED } - { 00CE } { 00EE } - { 00CF } { 00EF } - { 00D0 } { 00F0 } - { 00D1 } { 00F1 } - { 00D2 } { 00F2 } - { 00D3 } { 00F3 } - { 00D4 } { 00F4 } - { 00D5 } { 00F5 } - { 00D6 } { 00F6 } - { 00D8 } { 00F8 } - { 00D9 } { 00F9 } - { 00DA } { 00FA } - { 00DB } { 00FB } - { 00DC } { 00FC } - { 00DD } { 00FD } - { 00DE } { 00FE } - { 0100 } { 0101 } - { 0102 } { 0103 } - { 0104 } { 0105 } - { 0106 } { 0107 } - { 0108 } { 0109 } - { 010A } { 010B } - { 010C } { 010D } - { 010E } { 010F } - { 0110 } { 0111 } - { 0112 } { 0113 } - { 0114 } { 0115 } - { 0116 } { 0117 } - { 0118 } { 0119 } - { 011A } { 011B } - { 011C } { 011D } - { 011E } { 011F } - { 0120 } { 0121 } - { 0122 } { 0123 } - { 0124 } { 0125 } - { 0128 } { 0129 } - { 012A } { 012B } - { 012C } { 012D } - { 012E } { 012F } - { 0132 } { 0133 } - { 0134 } { 0135 } - { 0136 } { 0137 } - { 0139 } { 013A } - { 013B } { 013C } - { 013E } { 013F } - { 0141 } { 0142 } - { 0143 } { 0144 } - { 0145 } { 0146 } - { 0147 } { 0148 } - { 014A } { 014B } - { 014C } { 014D } - { 014E } { 014F } - { 0150 } { 0151 } - { 0152 } { 0153 } - { 0154 } { 0155 } - { 0156 } { 0157 } - { 0158 } { 0159 } - { 015A } { 015B } - { 015C } { 015D } - { 015E } { 015F } - { 0160 } { 0161 } - { 0162 } { 0163 } - { 0164 } { 0165 } - { 0168 } { 0169 } - { 016A } { 016B } - { 016C } { 016D } - { 016E } { 016F } - { 0170 } { 0171 } - { 0172 } { 0173 } - { 0174 } { 0175 } - { 0176 } { 0177 } - { 0178 } { 00FF } - { 0179 } { 017A } - { 017B } { 017C } - { 017D } { 017E } - { 01A0 } { 01A1 } - { 01AF } { 01B0 } - { 01CD } { 01CE } - { 01CF } { 01D0 } - { 01D1 } { 01D2 } - { 01D3 } { 01D4 } - { 01E2 } { 01E3 } - { 01E6 } { 01E7 } - { 01E8 } { 01E9 } - { 01EA } { 01EB } - { 01F4 } { 01F5 } - { 0218 } { 0219 } - { 021A } { 021B } -% \end{macrocode} -% Add |T2| (Cyrillic) : again two bytes. -% \begin{macrocode} - { 0400 } { 0450 } - { 0401 } { 0451 } - { 0402 } { 0452 } - { 0403 } { 0453 } - { 0404 } { 0454 } - { 0405 } { 0455 } - { 0406 } { 0456 } - { 0407 } { 0457 } - { 0408 } { 0458 } - { 0409 } { 0459 } - { 040A } { 045A } - { 040B } { 045B } - { 040C } { 045C } - { 040D } { 045D } - { 040E } { 045E } - { 040F } { 045F } - { 0410 } { 0430 } - { 0411 } { 0431 } - { 0412 } { 0432 } - { 0413 } { 0433 } - { 0414 } { 0434 } - { 0415 } { 0435 } - { 0416 } { 0436 } - { 0417 } { 0437 } - { 0418 } { 0438 } - { 0419 } { 0439 } - { 041A } { 043A } - { 041B } { 043B } - { 041C } { 043C } - { 041D } { 043D } - { 041E } { 043E } - { 041F } { 043F } - { 0420 } { 0440 } - { 0421 } { 0441 } - { 0422 } { 0442 } - { 0423 } { 0443 } - { 0424 } { 0444 } - { 0425 } { 0445 } - { 0426 } { 0446 } - { 0427 } { 0447 } - { 0428 } { 0448 } - { 0429 } { 0449 } - { 042A } { 044A } - { 042B } { 044B } - { 042C } { 044C } - { 042D } { 044D } - { 042E } { 044E } - { 042F } { 044F } -% \end{macrocode} -% Greek support: everything in the two-octet range. -% \begin{macrocode} - { 0370 } { 0371 } - { 0372 } { 0373 } - { 0376 } { 0377 } - { 03FD } { 037B } - { 03FE } { 037C } - { 03FF } { 037D } - { 0386 } { 03AC } - { 0388 } { 03AD } - { 0389 } { 03AE } - { 038A } { 03AF } - { 0391 } { 03B1 } - { 0392 } { 03B2 } - { 0393 } { 03B3 } - { 0394 } { 03B4 } - { 0395 } { 03B5 } - { 0396 } { 03B6 } - { 0397 } { 03B7 } - { 0398 } { 03B8 } - { 0399 } { 03B9 } - { 039A } { 03BA } - { 039B } { 03BB } - { 039C } { 03BC } - { 039D } { 03BD } - { 039E } { 03BE } - { 039F } { 03BF } - { 03A0 } { 03C0 } - { 03A1 } { 03C1 } - { 03A3 } { 03C3 } - { 03A4 } { 03C4 } - { 03A5 } { 03C5 } - { 03A6 } { 03C6 } - { 03A7 } { 03C7 } - { 03A8 } { 03C8 } - { 03A9 } { 03C9 } - { 03AA } { 03CA } - { 03AB } { 03CB } - { 038C } { 03CC } - { 038E } { 03CD } - { 038F } { 03CE } - { 03CF } { 03D7 } - { 03D8 } { 03D9 } - { 03DA } { 03DB } - { 03DC } { 03DD } - { 03DE } { 03DF } - { 03E0 } { 03E1 } - { 03E2 } { 03E3 } - { 03E4 } { 03E5 } - { 03E6 } { 03E7 } - { 03E8 } { 03E9 } - { 03EA } { 03EB } - { 03EC } { 03ED } - { 03EE } { 03EF } - { 03F9 } { 03F2 } - { 037F } { 03F3 } - { 03F7 } { 03F8 } - { 03FA } { 03FB } - \q_recursion_tail ? - \q_recursion_stop -% \end{macrocode} -% Odds and ends for Greek; mainly symbols that are for compatibility, -% but also things like the terminal sigma. Almost all are uppercase -% mappings, but there is one that is not! -% \begin{macrocode} - \cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \group_begin: - \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4##5##6##7##8 - { - \tl_const:cx - { - c__kernel_ #3 case_ - \char_generate:nn {##1} { 12 } - \char_generate:nn {##2} { 12 } - _tl - } - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##5} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##6} { 13 } - } - } - \use:x - { - \@@_tmp:w - \char_to_utfviii_bytes:n { "#1 } - \char_to_utfviii_bytes:n { "#2 } - } - \group_end: - } - \@@_tmp:w { 0345 } { 0399 } { upper } - \@@_tmp:w { 03C2 } { 03A3 } { upper } - \@@_tmp:w { 03D0 } { 0392 } { upper } - \@@_tmp:w { 03D1 } { 0398 } { upper } - \@@_tmp:w { 03D5 } { 03A6 } { upper } - \@@_tmp:w { 03D6 } { 03A0 } { upper } - \@@_tmp:w { 03F0 } { 039A } { upper } - \@@_tmp:w { 03F1 } { 03A1 } { upper } - \@@_tmp:w { 03F4 } { 03B8 } { lower } - \@@_tmp:w { 03F5 } { 0395 } { upper } -% \end{macrocode} -% Croatian digraph letters: these have a titlecase variant. -% \begin{macrocode} - \@@_tmp:w { 01C4 } { 01C5 } { title } - \@@_tmp:w { 01C4 } { 01C6 } { lower } - \@@_tmp:w { 01C5 } { 01C4 } { upper } - \@@_tmp:w { 01C5 } { 01C6 } { lower } - \@@_tmp:w { 01C6 } { 01C4 } { upper } - \@@_tmp:w { 01C6 } { 01C5 } { title } - \@@_tmp:w { 01C7 } { 01C8 } { title } - \@@_tmp:w { 01C7 } { 01C9 } { lower } - \@@_tmp:w { 01C8 } { 01C7 } { upper } - \@@_tmp:w { 01C8 } { 01C9 } { lower } - \@@_tmp:w { 01C9 } { 01C7 } { upper } - \@@_tmp:w { 01C9 } { 01C8 } { title } - \@@_tmp:w { 01CA } { 01CB } { title } - \@@_tmp:w { 01CA } { 01CC } { lower } - \@@_tmp:w { 01CB } { 01CA } { upper } - \@@_tmp:w { 01CB } { 01CC } { lower } - \@@_tmp:w { 01CC } { 01CA } { upper } - \@@_tmp:w { 01CC } { 01CB } { title } -% \end{macrocode} -% Odds and ends that are not simple one-to-one mappings. These -% are still two-octet code points. -% \begin{macrocode} - \cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \group_begin: - \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4 - { - \tl_const:cn - { - c__kernel_ #3 case_ - \char_generate:nn {##1} { 12 } - \char_generate:nn {##2} { 12 } - _tl - } - {#2} - } - \use:x - { \@@_tmp:w \char_to_utfviii_bytes:n { "#1 } } - \group_end: - } - \@@_tmp:w { 00DF } { SS } { upper } - \@@_tmp:w { 00DF } { Ss } { title } - \@@_tmp:w { 0131 } { I } { upper } -% \end{macrocode} -% Coverage for Vietnamese (\texttt{T5}) -% \begin{macrocode} - \cs_set_protected:Npn \@@_tmp:nnnnnn #1#2#3#4#5#6#7 - { - \tl_const:cx - { - c__kernel_ #1 case_ - \char_generate:nn {#2} { 12 } - \char_generate:nn {#3} { 12 } - \char_generate:nn {#4} { 12 } - _tl - } - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#5} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#6} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#7} { 13 } - } - } - \cs_set_protected:Npn \@@_tmp:w #1#2#3#4#5#6#7#8 - { - \tl_const:cx - { - c__kernel_lowercase_ - \char_generate:nn {#1} { 12 } - \char_generate:nn {#2} { 12 } - \char_generate:nn {#3} { 12 } - _tl - } - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#5} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#6} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#7} { 13 } - } - \@@_tmp:nnnnnn { upper } {#5} {#6} {#7} {#1} {#2} {#3} - \@@_tmp:nnnnnn { title } {#5} {#6} {#7} {#1} {#2} {#3} - } - \@@_loop:nn - { 1EA0 } { 1EA1 } - { 1EA2 } { 1EA3 } - { 1EA4 } { 1EA5 } - { 1EA6 } { 1EA7 } - { 1EA8 } { 1EA9 } - { 1EAA } { 1EAB } - { 1EAC } { 1EAD } - { 1EAE } { 1EAF } - { 1EB0 } { 1EB1 } - { 1EB2 } { 1EB3 } - { 1EB4 } { 1EB5 } - { 1EB6 } { 1EB7 } - { 1EB8 } { 1EB9 } - { 1EBA } { 1EBB } - { 1EBC } { 1EBD } - { 1EBE } { 1EBF } - { 1EC0 } { 1EC1 } - { 1EC2 } { 1EC3 } - { 1EC4 } { 1EC5 } - { 1EC6 } { 1EC7 } - { 1EC8 } { 1EC9 } - { 1ECA } { 1ECB } - { 1ECC } { 1ECD } - { 1ECE } { 1ECF } - { 1ED0 } { 1ED1 } - { 1ED2 } { 1ED3 } - { 1ED4 } { 1ED5 } - { 1ED6 } { 1ED7 } - { 1ED8 } { 1ED9 } - { 1EDA } { 1EDB } - { 1EDC } { 1EDD } - { 1EDE } { 1EDF } - { 1EE0 } { 1EE1 } - { 1EE2 } { 1EE3 } - { 1EE4 } { 1EE5 } - { 1EE6 } { 1EE7 } - { 1EE8 } { 1EE9 } - { 1EEA } { 1EEB } - { 1EEC } { 1EED } - { 1EEE } { 1EEF } - { 1EF0 } { 1EF1 } - { 1EF2 } { 1EF3 } - { 1EF4 } { 1EF5 } - { 1EF6 } { 1EF7 } - { 1EF8 } { 1EF9 } - \q_recursion_tail ? - \q_recursion_stop -% \end{macrocode} -% Greek support: the three-octet code points. -% \begin{macrocode} - \@@_loop:nn - { 1F08 } { 1F00 } - { 1F09 } { 1F01 } - { 1F0A } { 1F02 } - { 1F0B } { 1F03 } - { 1F0C } { 1F04 } - { 1F0D } { 1F05 } - { 1F0E } { 1F06 } - { 1F0F } { 1F07 } - { 1F18 } { 1F10 } - { 1F19 } { 1F11 } - { 1F1A } { 1F12 } - { 1F1B } { 1F13 } - { 1F1C } { 1F14 } - { 1F1D } { 1F15 } - { 1F28 } { 1F20 } - { 1F29 } { 1F21 } - { 1F2A } { 1F22 } - { 1F2B } { 1F23 } - { 1F2C } { 1F24 } - { 1F2D } { 1F25 } - { 1F2E } { 1F26 } - { 1F2F } { 1F27 } - { 1F38 } { 1F30 } - { 1F39 } { 1F31 } - { 1F3A } { 1F32 } - { 1F3B } { 1F33 } - { 1F3C } { 1F34 } - { 1F3D } { 1F35 } - { 1F3E } { 1F36 } - { 1F3F } { 1F37 } - { 1F48 } { 1F40 } - { 1F49 } { 1F41 } - { 1F4A } { 1F42 } - { 1F4B } { 1F43 } - { 1F4C } { 1F44 } - { 1F4D } { 1F45 } - { 1F59 } { 1F51 } - { 1F5B } { 1F53 } - { 1F5D } { 1F55 } - { 1F5F } { 1F57 } - { 1F68 } { 1F60 } - { 1F69 } { 1F61 } - { 1F6A } { 1F62 } - { 1F6B } { 1F63 } - { 1F6C } { 1F64 } - { 1F6D } { 1F65 } - { 1F6E } { 1F66 } - { 1F6F } { 1F67 } - { 1FBA } { 1F70 } - { 1FBB } { 1F71 } - { 1FC8 } { 1F72 } - { 1FC9 } { 1F73 } - { 1FCA } { 1F74 } - { 1FCB } { 1F75 } - { 1FDA } { 1F76 } - { 1FDB } { 1F77 } - { 1FF8 } { 1F78 } - { 1FF9 } { 1F79 } - { 1FEA } { 1F7A } - { 1FEB } { 1F7B } - { 1FFA } { 1F7C } - { 1FFB } { 1F7D } - { 1F88 } { 1F80 } - { 1F89 } { 1F81 } - { 1F8A } { 1F82 } - { 1F8B } { 1F83 } - { 1F8C } { 1F84 } - { 1F8D } { 1F85 } - { 1F8E } { 1F86 } - { 1F8F } { 1F87 } - { 1F98 } { 1F90 } - { 1F99 } { 1F91 } - { 1F9A } { 1F92 } - { 1F9B } { 1F93 } - { 1F9C } { 1F94 } - { 1F9D } { 1F95 } - { 1F9E } { 1F96 } - { 1F9F } { 1F97 } - { 1FA8 } { 1FA0 } - { 1FA9 } { 1FA1 } - { 1FAA } { 1FA2 } - { 1FAB } { 1FA3 } - { 1FAC } { 1FA4 } - { 1FAD } { 1FA5 } - { 1FAE } { 1FA6 } - { 1FAF } { 1FA7 } - { 1FB8 } { 1FB0 } - { 1FB9 } { 1FB1 } - { 1FBC } { 1FB3 } - { 1FCC } { 1FC3 } - { 1FD8 } { 1FD0 } - { 1FD9 } { 1FD1 } - { 1FE8 } { 1FE0 } - { 1FE9 } { 1FE1 } - { 1FEC } { 1FE5 } - { 1FFC } { 1FF3 } - \q_recursion_tail ? - \q_recursion_stop -% \end{macrocode} -% One three-octet special case for Greek: it also moves to two-octets! -% \begin{macrocode} - \cs_set_protected:Npn \@@_tmp:w #1#2#3 - { - \group_begin: - \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4##5##6##7##8 - { - \tl_const:cx - { - c__kernel_ #3 case_ - \char_generate:nn {##1} { 12 } - \char_generate:nn {##2} { 12 } - \char_generate:nn {##3} { 12 } - _tl - } - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##5} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {##6} { 13 } - } - } - \use:x - { - \@@_tmp:w - \char_to_utfviii_bytes:n { "#1 } - \char_to_utfviii_bytes:n { "#2 } - } - \group_end: - } - \@@_tmp:w { 1FBE } { 0399 } { upper } -% \end{macrocode} -% Greek accent suppression for uppercasing. -% \begin{macrocode} - \cs_set_protected:Npn \@@_tmp:w #1#2#3#4#5#6#7#8 - { - \tl_const:cx - { - c_@@_uppercase_el_ - \char_generate:nn {#1} { 12 } - \char_generate:nn {#2} { 12 } - _tl - } - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#5} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#6} { 13 } - } - } - \@@_loop:nn - { 0370 } { 0370 } - { 0371 } { 0370 } - { 0372 } { 0372 } - { 0373 } { 0372 } - { 0376 } { 0376 } - { 0377 } { 0376 } - { 03FD } { 03FD } - { 037B } { 03FD } - { 03FE } { 03FE } - { 037C } { 03FE } - { 03FF } { 03FF } - { 037D } { 03FF } - { 0386 } { 0391 } - { 0388 } { 0395 } - { 0389 } { 0397 } - { 038A } { 0399 } - { 038C } { 039F } - { 038E } { 03A5 } - { 038F } { 03A9 } - { 0390 } { 03AA } - { 0391 } { 0391 } - { 0392 } { 0392 } - { 0393 } { 0393 } - { 0394 } { 0394 } - { 0395 } { 0395 } - { 0396 } { 0396 } - { 0397 } { 0397 } - { 0398 } { 0398 } - { 0399 } { 0399 } - { 039A } { 039A } - { 039B } { 039B } - { 039C } { 039C } - { 039D } { 039D } - { 039E } { 039E } - { 039F } { 039F } - { 03A0 } { 03A0 } - { 03A1 } { 03A1 } - { 03A3 } { 03A3 } - { 03A4 } { 03A4 } - { 03A5 } { 03A5 } - { 03A6 } { 03A6 } - { 03A7 } { 03A7 } - { 03A8 } { 03A8 } - { 03A9 } { 03A9 } - { 03AA } { 03AA } - { 03AB } { 03AB } - { 03AC } { 0391 } - { 03AD } { 0395 } - { 03AE } { 0397 } - { 03AF } { 0399 } - { 03B0 } { 03AB } - { 03B1 } { 0391 } - { 03B2 } { 0392 } - { 03B3 } { 0393 } - { 03B4 } { 0394 } - { 03B5 } { 0395 } - { 03B6 } { 0396 } - { 03B7 } { 0397 } - { 03B8 } { 0398 } - { 03B9 } { 0399 } - { 03BA } { 039A } - { 03BB } { 039B } - { 03BC } { 039C } - { 03BD } { 039D } - { 03BE } { 039E } - { 03BF } { 039F } - { 03C0 } { 03A0 } - { 03C1 } { 03A1 } - { 03C2 } { 03A3 } - { 03C3 } { 03A3 } - { 03C4 } { 03A4 } - { 03C5 } { 03A5 } - { 03C6 } { 03A6 } - { 03C7 } { 03A7 } - { 03C8 } { 03A8 } - { 03C9 } { 03A9 } - { 03CA } { 03AA } - { 03CB } { 03AB } - { 03CC } { 039F } - { 03CD } { 03A5 } - { 03CE } { 03A9 } - { 03D0 } { 0392 } - { 03D1 } { 0398 } - { 03D2 } { 03A5 } - { 03D3 } { 03A5 } - { 03D4 } { 03AB } - { 03D5 } { 03A6 } - { 03D6 } { 03A0 } - { 03DA } { 03DA } - { 03DB } { 03DA } - { 03DC } { 03DC } - { 03DD } { 03DC } - { 03DE } { 03DE } - { 03DF } { 03DE } - { 03E0 } { 03E0 } - { 03E1 } { 03E0 } - { 03F0 } { 039A } - { 03F1 } { 03A1 } - { 03F2 } { 03F9 } - { 03F9 } { 03F9 } - \q_recursion_tail ? - \q_recursion_stop - \cs_set_protected:Npn \@@_tmp:w #1#2#3#4#5#6#7#8 - { - \tl_const:cx - { - c_@@_uppercase_el_ - \char_generate:nn {#1} { 12 } - \char_generate:nn {#2} { 12 } - \char_generate:nn {#3} { 12 } - _tl - } - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#5} { 13 } - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#6} { 13 } - \tl_if_blank:nF {#7} - { - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_not:N \char_generate:nn {#7} { 13 } - } - } - } - \@@_loop:nn - { 1F00 } { 0391 } - { 1F01 } { 0391 } - { 1F02 } { 0391 } - { 1F03 } { 0391 } - { 1F04 } { 0391 } - { 1F05 } { 0391 } - { 1F06 } { 0391 } - { 1F07 } { 0391 } - { 1F08 } { 0391 } - { 1F09 } { 0391 } - { 1F0A } { 0391 } - { 1F0B } { 0391 } - { 1F0C } { 0391 } - { 1F0D } { 0391 } - { 1F0E } { 0391 } - { 1F0F } { 0391 } - { 1F10 } { 0395 } - { 1F11 } { 0395 } - { 1F12 } { 0395 } - { 1F13 } { 0395 } - { 1F14 } { 0395 } - { 1F15 } { 0395 } - { 1F18 } { 0395 } - { 1F19 } { 0395 } - { 1F1A } { 0395 } - { 1F1B } { 0395 } - { 1F1C } { 0395 } - { 1F1D } { 0395 } - { 1F20 } { 0397 } - { 1F21 } { 0397 } - { 1F22 } { 0397 } - { 1F23 } { 0397 } - { 1F24 } { 0397 } - { 1F25 } { 0397 } - { 1F26 } { 0397 } - { 1F27 } { 0397 } - { 1F28 } { 0397 } - { 1F29 } { 0397 } - { 1F2A } { 0397 } - { 1F2B } { 0397 } - { 1F2C } { 0397 } - { 1F2D } { 0397 } - { 1F2E } { 0397 } - { 1F2F } { 0397 } - { 1F30 } { 0399 } - { 1F31 } { 0399 } - { 1F32 } { 0399 } - { 1F33 } { 0399 } - { 1F34 } { 0399 } - { 1F35 } { 0399 } - { 1F36 } { 0399 } - { 1F37 } { 0399 } - { 1F38 } { 0399 } - { 1F39 } { 0399 } - { 1F3A } { 0399 } - { 1F3B } { 0399 } - { 1F3C } { 0399 } - { 1F3D } { 0399 } - { 1F3E } { 0399 } - { 1F3F } { 0399 } - { 1F40 } { 039F } - { 1F41 } { 039F } - { 1F42 } { 039F } - { 1F43 } { 039F } - { 1F44 } { 039F } - { 1F45 } { 039F } - { 1F48 } { 039F } - { 1F49 } { 039F } - { 1F4A } { 039F } - { 1F4B } { 039F } - { 1F4C } { 039F } - { 1F4D } { 039F } - { 1F50 } { 03A5 } - { 1F51 } { 03A5 } - { 1F52 } { 03A5 } - { 1F53 } { 03A5 } - { 1F54 } { 03A5 } - { 1F55 } { 03A5 } - { 1F56 } { 03A5 } - { 1F57 } { 03A5 } - { 1F59 } { 03A5 } - { 1F5B } { 03A5 } - { 1F5D } { 03A5 } - { 1F5F } { 03A5 } - { 1F60 } { 03A9 } - { 1F61 } { 03A9 } - { 1F62 } { 03A9 } - { 1F63 } { 03A9 } - { 1F64 } { 03A9 } - { 1F65 } { 03A9 } - { 1F66 } { 03A9 } - { 1F67 } { 03A9 } - { 1F68 } { 03A9 } - { 1F69 } { 03A9 } - { 1F6A } { 03A9 } - { 1F6B } { 03A9 } - { 1F6C } { 03A9 } - { 1F6D } { 03A9 } - { 1F6E } { 03A9 } - { 1F6F } { 03A9 } - { 1F70 } { 0391 } - { 1F71 } { 0391 } - { 1F72 } { 0395 } - { 1F73 } { 0395 } - { 1F74 } { 0397 } - { 1F75 } { 0397 } - { 1F76 } { 0399 } - { 1F77 } { 0399 } - { 1F78 } { 039F } - { 1F79 } { 039F } - { 1F7A } { 03A5 } - { 1F7B } { 03A5 } - { 1F7C } { 03A9 } - { 1F7D } { 03A9 } - { 1F80 } { 1FBC } - { 1F81 } { 1FBC } - { 1F82 } { 1FBC } - { 1F83 } { 1FBC } - { 1F84 } { 1FBC } - { 1F85 } { 1FBC } - { 1F86 } { 1FBC } - { 1F87 } { 1FBC } - { 1F88 } { 1FBC } - { 1F89 } { 1FBC } - { 1F8A } { 1FBC } - { 1F8B } { 1FBC } - { 1F8C } { 1FBC } - { 1F8D } { 1FBC } - { 1F8E } { 1FBC } - { 1F8F } { 1FBC } - { 1F90 } { 1FCC } - { 1F91 } { 1FCC } - { 1F92 } { 1FCC } - { 1F93 } { 1FCC } - { 1F94 } { 1FCC } - { 1F95 } { 1FCC } - { 1F96 } { 1FCC } - { 1F97 } { 1FCC } - { 1F98 } { 1FCC } - { 1F99 } { 1FCC } - { 1F9A } { 1FCC } - { 1F9B } { 1FCC } - { 1F9C } { 1FCC } - { 1F9D } { 1FCC } - { 1F9E } { 1FCC } - { 1F9F } { 1FCC } - { 1FA0 } { 1FFC } - { 1FA1 } { 1FFC } - { 1FA2 } { 1FFC } - { 1FA3 } { 1FFC } - { 1FA4 } { 1FFC } - { 1FA5 } { 1FFC } - { 1FA6 } { 1FFC } - { 1FA7 } { 1FFC } - { 1FA8 } { 1FFC } - { 1FA9 } { 1FFC } - { 1FAA } { 1FFC } - { 1FAB } { 1FFC } - { 1FAC } { 1FFC } - { 1FAD } { 1FFC } - { 1FAE } { 1FFC } - { 1FAF } { 1FFC } - { 1FB0 } { 1FB8 } - { 1FB1 } { 1FB9 } - { 1FB2 } { 1FBC } - { 1FB3 } { 1FBC } - { 1FB4 } { 1FBC } - { 1FB6 } { 0391 } - { 1FB7 } { 1FBC } - { 1FB8 } { 1FB8 } - { 1FB9 } { 1FB9 } - { 1FBA } { 0391 } - { 1FBB } { 0391 } - { 1FBC } { 1FBC } - { 1FBD } { 1FBD } - { 1FC2 } { 1FCC } - { 1FC3 } { 1FCC } - { 1FC4 } { 1FCC } - { 1FC6 } { 0397 } - { 1FC7 } { 1FCC } - { 1FC8 } { 0395 } - { 1FC9 } { 0395 } - { 1FCA } { 0397 } - { 1FCB } { 0397 } - { 1FCC } { 1FCC } - { 1FD0 } { 1FD8 } - { 1FD1 } { 1FD9 } - { 1FD2 } { 03AA } - { 1FD3 } { 03AA } - { 1FD6 } { 0399 } - { 1FD7 } { 03AA } - { 1FD8 } { 1FD8 } - { 1FD9 } { 1FD9 } - { 1FDA } { 0399 } - { 1FDB } { 0399 } - { 1FE0 } { 1FE8 } - { 1FE1 } { 1FE9 } - { 1FE2 } { 03AB } - { 1FE3 } { 03AB } - { 1FE4 } { 03A1 } - { 1FE5 } { 03A1 } - { 1FE6 } { 03A5 } - { 1FE7 } { 03AB } - { 1FE8 } { 1FE8 } - { 1FE9 } { 1FE9 } - { 1FEA } { 03A5 } - { 1FEB } { 03A5 } - { 1FEC } { 1FEC } - { 1FF2 } { 1FFC } - { 1FF3 } { 1FFC } - { 1FF4 } { 1FFC } - { 1FF6 } { 03A9 } - { 1FF7 } { 1FFC } - { 1FF8 } { 039F } - { 1FF9 } { 039F } - { 1FFA } { 03A9 } - { 1FFB } { 03A9 } - { 1FFC } { 1FFC } - \q_recursion_tail ? - \q_recursion_stop - } -\group_end: -% \end{macrocode} -% % The (fixed) look-up mappings for letter-like control sequences. % \begin{macrocode} \group_begin: |