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 | 693 |
1 files changed, 604 insertions, 89 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx index 3f8f381063f..fd41c6bdd31 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 2020-10-05} +% \date{Released 2020-10-27} % % \maketitle % @@ -155,6 +155,9 @@ % \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} % \begin{macro}[EXP] @@ -206,6 +209,7 @@ \cs_new:Npn \@@_change_case_aux:nnn #1#2#3 { \group_align_safe_begin: + \cs_if_exist_use:c { @@_change_case_boundary_ #2 _ #3 :Nnnw } \@@_change_case_loop:nnw {#2} {#3} #1 \q_@@_recursion_tail \q_@@_recursion_stop \@@_change_case_result:n { } @@ -296,6 +300,7 @@ } { \@@_change_case_store:n { ~ } + \cs_if_exist_use:c { @@_change_case_boundary_ #1 _ #2 :Nnnw } \@@_change_case_loop:nnw {#1} {#2} } % \end{macrocode} @@ -461,16 +466,10 @@ % is there the special case of a terminal sigma. If not, then we pass to % a simple character mapping. % \begin{macrocode} -\cs_new:Npx \@@_change_case_char_lower:nnN #1#2#3 +\cs_new:Npn \@@_change_case_char_lower:nnN #1#2#3 { - \exp_not:N \cs_if_exist_use:cF { @@_change_case_lower_ #2 :nnnN } - { - \bool_lazy_or:nnTF - { \sys_if_engine_luatex_p: } - { \sys_if_engine_xetex_p: } - { \exp_not:N \@@_change_case_lower_sigma:nnnN } - { \exp_not:N \@@_change_case_char:nnnN } - } + \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 @@ -485,7 +484,7 @@ % then there is a look-ahead phase: the logic here is simply based on letters. % The one exception is Dutch: see below. % \begin{macrocode} -\bool_lazy_or:nnT +\bool_lazy_or:nnTF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } { @@ -518,6 +517,48 @@ } } % \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 + { + \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 + { + \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 } } + } + { \@@_change_case_store:V \c_@@_sigma_tl } + { \@@_change_case_store:V \c_@@_final_sigma_tl } + \@@_change_case_loop:nnw {#1} {#2} #3 + } + } +% \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 @@ -664,6 +705,9 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}[EXP]{\@@_change_case_upper_de-alt:nnnN} % \begin{macro}[EXP]{\@@_change_case_upper_de-alt:nnnNN} @@ -710,16 +754,28 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_change_case_upper_el:nnnN} -% \begin{macro}[EXP]{\@@_change_case_upper_el:nnnn} -% \begin{macro}[EXP]{\@@_change_case_upper_el_aux:nnnN} -% \begin{macro}[EXP]{\@@_change_case_upper_el_loop:nnw} -% \begin{macro}[EXP]{\@@_change_case_upper_el:nnN} -% \begin{macro}[EXP]{\@@_change_case_if_greek:nTF} +% \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_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_gobble:nnw} +% \begin{macro}[EXP]{\@@_change_case_upper_el_gobble:nnN} +% \begin{macro}[EXP,TF]{\@@_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,pTF]{\@@_change_case_if_greek_diacritic:n} +% \begin{macro}[EXP,TF]{\@@_change_case_if_takes_dialytika: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 % need to be found \emph{after} any U+0308 (diaeresis) and are done in two -% groups to allow for the canonical ordering. +% groups to allow for the canonical ordering. The implementation here follows +% the data and examples from ICU +% (\url{https://sites.google.com/site/icusite/design/case/greek-upper}), +% although necessarily the implementation is somewhat different. % \begin{macrocode} \bool_lazy_or:nnT { \sys_if_engine_luatex_p: } @@ -729,97 +785,233 @@ { \@@_change_case_if_greek:nTF { `#4 } { - \exp_args:Ne \@@_change_case_upper_el:nnnn - { \char_to_nfd:N #4 } {#1} {#2} {#3} + \exp_args:Ne \@@_change_case_upper_el:nnn + { \char_to_nfd:N #4 } {#2} {#3} } { \@@_change_case_char:nnnN {#1} {#2} {#3} #4 } } - \cs_new:Npn \@@_change_case_upper_el:nnnn #1#2#3#4 - { \@@_change_case_upper_el_aux:nnnN {#2} {#3} {#4} #1 } - \cs_new:Npn \@@_change_case_upper_el_aux:nnnN #1#2#3#4 - { - \@@_change_case_store:e { \use:c { char_ #1 case:N } #4 } - \@@_change_case_upper_el_loop:nnw {#2} {#3} - } - \cs_new:Npn \@@_change_case_upper_el_loop:nnw - #1#2#3 \q_@@_recursion_stop + \cs_new:Npn \@@_change_case_upper_el:nnn #1#2#3 + { \@@_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 +% 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 { - \tl_if_head_is_N_type:nTF {#3} - { \@@_change_case_upper_el:nnN } - { \@@_change_case_loop:nnw } - {#1} {#2} #3 \q_@@_recursion_stop + \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 } % \end{macrocode} -% In addition to the Greek accents, we list three cases here where an -% accent outside the Greek range has a \text{nfd} that would make it -% equivalent. That includes U+0344, which has to insert U+0308. +% 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. +% (The latter do not have the same hiatus behavior as accents.) % \begin{macrocode} - \cs_new:Npn \@@_change_case_upper_el:nnN #1#2#3 + \cs_new:Npn \@@_change_case_upper_el:NnnN #1#2#3#4 { - \token_if_cs:NTF #3 - { \@@_change_case_loop:nnw {#1} {#2} #3 } + \token_if_cs:NTF #4 { - \int_compare:nNnTF { `#3 } = { "0308 } - { - \@@_change_case_store:n {#3} - \@@_change_case_upper_el_loop:nnw {#1} {#2} - } + \@@_change_case_store:e { \char_uppercase:N #1 } + \@@_change_case_loop:nnw {#2} {#3} #4 + } + { + \int_compare:nNnTF { `#4 } = { "0308 } + { \@@_change_case_upper_el_dialytika:nnN {#2} {#3} #1 } { - \bool_lazy_any:nTF + \@@_change_case_if_greek_accent:nTF { `#4 } + { \@@_change_case_upper_el_hiatus:nnNw {#2} {#3} #1 } { - { \int_compare_p:nNn { `#3 } = { "0300 } } - { \int_compare_p:nNn { `#3 } = { "0301 } } - { \int_compare_p:nNn { `#3 } = { "0304 } } - { \int_compare_p:nNn { `#3 } = { "0306 } } - { \int_compare_p:nNn { `#3 } = { "0308 } } - { \int_compare_p:nNn { `#3 } = { "0313 } } - { \int_compare_p:nNn { `#3 } = { "0314 } } - { \int_compare_p:nNn { `#3 } = { "0342 } } - { \int_compare_p:nNn { `#3 } = { "0340 } } - { \int_compare_p:nNn { `#3 } = { "0341 } } - { \int_compare_p:nNn { `#3 } = { "0343 } } - } - { \@@_change_case_upper_el_loop:nnw {#1} {#2} } - { - \int_compare:nNnTF { `#3 } = { "0344 } + \@@_change_case_if_greek_diacritic:nTF { `#4 } { - \@@_change_case_store:e - { - \char_generate:nn { "0308 } - { \@@_char_catcode:N #3 } - } - \@@_change_case_upper_el_loop:nnw {#1} {#2} + \@@_change_case_store:e { \char_uppercase:N #1 } + \@@_change_case_loop:nnw {#2} {#3} } { - \int_compare:nNnTF { `#3 } = { "0345 } - { \@@_change_case_loop:nnw {#1} {#2} } - { \@@_change_case_loop:nnw {#1} {#2} #3 } + \@@_change_case_store:e { \char_uppercase:N #1 } + \@@_change_case_loop:nnw {#2} {#3} #4 } } } } } - \prg_new_conditional:Npnn \@@_change_case_if_greek:n #1 { TF } +% \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 + { + \@@_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} + } + \cs_new:Npn \@@_change_case_upper_el_dialytika:N #1 + { + \@@_change_case_store:e + { + \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 } } + } + } +% \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 + { + \@@_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 + } + \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_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 } + } + } +% \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 { - \if_int_compare:w #1 < "0370 \exp_stop_f: + \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} } + } + } +% \end{macrocode} +% Luckily the Greek range is limited and clear. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_change_case_if_greek:n #1 { TF } + { + \if_int_compare:w #1 < "0370 \exp_stop_f: + \prg_return_false: + \else: + \if_int_compare:w #1 > "03FF \exp_stop_f: + \if_int_compare:w #1 < "1F00 \exp_stop_f: \prg_return_false: \else: - \if_int_compare:w #1 > "03FF \exp_stop_f: - \if_int_compare:w #1 < "1F00 \exp_stop_f: - \prg_return_false: + \if_int_compare:w #1 > "1FFF \exp_stop_f: + \prg_return_false: + \else: + \prg_return_true: + \fi: + \fi: + \else: + \prg_return_true: + \fi: + \fi: + } +% \end{macrocode} +% We follow ICU in adding a few extras to the accent list here. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_change_case_if_greek_accent:n #1 { TF , p } + { + \if_int_compare:w #1 = "0300 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0301 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0342 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0302 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0303 \exp_stop_f: + \prg_return_true: \else: - \if_int_compare:w #1 > "1FFF \exp_stop_f: - \prg_return_false: - \else: + \if_int_compare:w #1 = "0311 \exp_stop_f: \prg_return_true: + \else: + \prg_return_false: \fi: \fi: - \else: + \fi: + \fi: + \fi: + \fi: + } +\prg_new_conditional:Npnn \@@_change_case_if_greek_diacritic:n + #1 { TF , p } + { + \if_int_compare:w #1 = "0304 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0306 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0313 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "0314 \exp_stop_f: \prg_return_true: + \else: + \if_int_compare:w #1 = "0343 \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: \fi: \fi: - } + \fi: + \fi: } +\prg_new_conditional:Npnn \@@_change_case_if_takes_dialytika:n #1 { TF } + { + \if_int_compare:w #1 = "0399 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "03B9 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "03A5 \exp_stop_f: + \prg_return_true: + \else: + \if_int_compare:w #1 = "03C5 \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: + \fi: + \fi: + \fi: + } % \end{macrocode} % \end{macro} % \end{macro} @@ -827,6 +1019,76 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \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} +% 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 + { + \bool_lazy_or:nnTF + { \token_if_cs_p:N #3 } + { + ! \bool_lazy_or_p:nn + { \int_compare_p:nNn { `#3 } = { "03AE } } + { \int_compare_p:nNn { `#3 } = { "1F22 } } + } + { \@@_change_case_loop:nnw } + { \@@_change_case_boundary_upper_el:nnNw } + {#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 } + { + \@@_change_case_store:e + { \char_generate:nn { "0389 } { \@@_char_catcode:N #3 } } + \@@_change_case_loop:nnw + } + {#1} {#2} #4 \q_@@_recursion_stop + } + \cs_new:Npn \@@_change_case_boundary_upper_el:NnnN #1#2#3#4 + { + \token_if_letter:NTF #4 + { \@@_change_case_loop:nnw {#2} {#3} #1#4 } + { + \@@_change_case_store:e + { \char_generate:nn { "0389 } { \@@_char_catcode:N #1 } } + \@@_change_case_loop:nnw {#2} {#3} #4 + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \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. @@ -1198,14 +1460,17 @@ % % \begin{variable} % { -% \c_@@_dotless_i_tl , -% \c_@@_dotted_I_tl , -% \c_@@_i_ogonek_tl , -% \c_@@_I_ogonek_tl , +% \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. +% a variant is provided in both cases. There are also a few extras for +% |LGR|. % \begin{macrocode} \group_begin: \bool_lazy_or:nnF @@ -1238,6 +1503,8 @@ \@@_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: @@ -1245,7 +1512,9 @@ % \end{variable} % % For $8$-bit engines we now need to define the case-change data for -% the multi-octet mappings. These need a list of what code points are +% 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. +% These need a list of what code points are % doable in |T1| so the list is hard coded (there's no saving in loading % the mappings dynamically). All of the straight-forward ones have two % octets, so that is taken as read. @@ -1454,9 +1723,18 @@ { 042E } { 044E } { 042F } { 044F } % \end{macrocode} -% Core Greek support: there may need to be a little more work here to -% deal completely with accents. +% 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 } @@ -1481,17 +1759,39 @@ { 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 + \cs_set_protected:Npn \@@_tmp:w ##1##2##3##4##5##6##7##8 { \tl_const:cx { @@ -1500,6 +1800,47 @@ \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} +% 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_@@_ #3 case_ + \char_generate:nn {##1} { 12 } + \char_generate:nn {##2} { 12 } + _tl + } {#2} } \use:x @@ -1509,8 +1850,182 @@ \@@_tmp:w { 00DF } { SS } { upper } \@@_tmp:w { 00DF } { Ss } { title } \@@_tmp:w { 0131 } { I } { upper } - } - \group_end: +% \end{macrocode} +% Greek support: the three-octet code points. +% \begin{macrocode} + \cs_set_protected:Npn \@@_tmp:nnnnnn #1#2#3#4#5#6#7 + { + \tl_const:cx + { + c_@@_ #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_@@_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 + { 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_@@_ #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 } + } +\group_end: % \end{macrocode} % % The (fixed) look-up mappings for letter-like control sequences. |