From 1f050a1e138e1969a2ad80bc2e1f1fced6729c35 Mon Sep 17 00:00:00 2001 From: Joseph Wright Date: Mon, 17 Oct 2022 14:44:19 +0100 Subject: [PATCH] Add \text_declare_case_mapping:nnn --- l3kernel/CHANGELOG.md | 1 + l3kernel/l3text-case.dtx | 74 +++++++++++++++++++++---- l3kernel/l3text.dtx | 12 ++++ l3kernel/testfiles/m3text002.luatex.tlg | 27 +++++++++ l3kernel/testfiles/m3text002.lvt | 15 +++++ l3kernel/testfiles/m3text002.tlg | 27 +++++++++ l3kernel/testfiles/m3text002.xetex.tlg | 27 +++++++++ 7 files changed, 172 insertions(+), 11 deletions(-) diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md index 50ba0a32c5..3f7512c85b 100644 --- a/l3kernel/CHANGELOG.md +++ b/l3kernel/CHANGELOG.md @@ -12,6 +12,7 @@ this project uses date-based 'snapshot' version identifiers. - `\codepoint_to_nfd:n` - `\codepoint_str_generate:n` - `\str_casefold:n` +- `\text_declare_case_mapping:nnn` ### Changed - Usage of `\exp_not:n`/`\exp_not:N` in `\peek_analysis_map_inline:n` output diff --git a/l3kernel/l3text-case.dtx b/l3kernel/l3text-case.dtx index d7e816aeaa..9b447dcc95 100644 --- a/l3kernel/l3text-case.dtx +++ b/l3kernel/l3text-case.dtx @@ -170,6 +170,7 @@ % \@@_change_case_letterlike_titleonly:nnN % } % \begin{macro}[EXP]{\@@_change_case_letterlike:nnnnN} +% \begin{macro}[EXP]{\@@_change_case_codepoint:nnn} % \begin{macro}[EXP] % { % \@@_change_case_codepoint_lower:nnn , @@ -191,9 +192,9 @@ % \begin{macro}[EXP]{\@@_change_case_codepoint:nn} % \begin{macro}[EXP] % { -% \@@_change_case_codepoint:nnn , -% \@@_change_case_codepoint:fnn , -% \@@_change_case_codepoint_aux:nnn +% \@@_change_case_codepoint_auxi:nnn , +% \@@_change_case_codepoint_auxi:fnn , +% \@@_change_case_codepoint_auxii:nnn % } % \begin{macro}[EXP] % { @@ -435,7 +436,7 @@ { \@@_change_case_exclude:nnN {#1} {#2} } { \@@_codepoint_process:nN - { \use:c { @@_change_case_codepoint_ #1 :nnn } {#1} {#2} } + { \@@_change_case_codepoint:nnn {#1} {#2} } } #3 } @@ -565,6 +566,22 @@ { \@@_change_case_loop:nnw {#3} {#4} } } } +\cs_new:Npn \@@_change_case_codepoint:nnn #1#2#3 + { + \cs_if_exist:cTF { l_@@_ #1 _ \tl_to_str:n {#3} _tl } + { + \@@_change_case_store:e + { + \use:e + { + \exp_not:N \@@_change_case_codepoint_aux:nnnn + \use:c { l_@@_ #1 _ \tl_to_str:n {#3} _tl } {#3} + } + } + \use:c { @@_change_case_next_ #1 :nn } {#1} {#2} + } + { \use:c { @@_change_case_codepoint_ #1 :nnn } {#1} {#2} {#3} } + } % \end{macrocode} % 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 @@ -677,27 +694,27 @@ } \cs_new:Npn \@@_change_case_codepoint:nn #1#2 { - \@@_change_case_codepoint:fnn + \@@_change_case_codepoint_auxi:fnn { \int_eval:n { \@@_codepoint_from_chars:Nw #2 } } {#1} {#2} } -\cs_new:Npn \@@_change_case_codepoint:nnn #1#2#3 +\cs_new:Npn \@@_change_case_codepoint_auxi: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 } +\cs_generate_variant:Nn \@@_change_case_codepoint_auxi: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_eq:NN \@@_change_case_codepoint_auxii:nnn + \@@_change_case_codepoint_auxi:nnn + \cs_gset:Npn \@@_change_case_codepoint_auxi:nnn #1#2#3 { \int_compare:nNnTF {#1} = { -1 } { \exp_not:n {#3} } - { \@@_change_case_codepoint_aux:nnn {#1} {#2} {#3} } + { \@@_change_case_codepoint_auxii:nnn {#1} {#2} {#3} } } } \cs_new:Npn \@@_change_case_codepoint_aux:nn #1#2 @@ -775,6 +792,7 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\text_declare_case_equivalent:Nn} % Create equivalents to allow replacement. @@ -787,6 +805,40 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\text_declare_case_mapping:nnn} +% \begin{macro}{\@@_declare_case_mapping:nnnn} +% \begin{macro}[EXP]\@@_declare_case_mapping:n} +% \begin{macrocode} +\cs_new_protected:Npn \text_declare_case_mapping:nnn #1#2#3 + { + \exp_args:Ne \@@_declare_case_mapping:nnnn { \clist_count:n {#3} } + {#1} {#2} {#3} + } +\cs_new_protected:Npn \@@_declare_case_mapping:nnnn #1#2#3#4 + { + \int_compare:nTF { 0 < #1 < 4 } + { + \tl_clear_new:c { l_@@_ #3 _ \tl_to_str:n {#2} _tl } + \tl_set:cx { l_@@_ #3 _ \tl_to_str:n {#2} _tl } + { + \clist_map_function:nN {#4} \@@_declare_case_mapping:n + \prg_replicate:nn { 3 - #1 } { { } } + } + } + { \msg_error:nnnn { text } { invalid-case-mapping } {#2} {#1} } + } +\cs_new:Npn \@@_declare_case_mapping:n #1 { {#1} } +\msg_new:nnnn { text } { invalid-case-mapping } + { Invalid~number~of~entries~for~case~mapping~of~"#1". } + { + LaTeX~has~been~asked~to~specify~a~custom~case~mapping~for~"#1".~ + This~must~be~given~as~1~to~3~output~codepoints,~but~#2~codepoints~ + were~given. + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}{\text_case_switch:nnnn} % \begin{macro}{\@@_case_switch_marker:} % Set up the mechanism for manual case switching. diff --git a/l3kernel/l3text.dtx b/l3kernel/l3text.dtx index 0c3ea223ee..35b0bb35c5 100644 --- a/l3kernel/l3text.dtx +++ b/l3kernel/l3text.dtx @@ -212,6 +212,18 @@ % \meta{cmd} (a single token) is encountered during case changing. % \end{function} % +% \begin{function}[added = 2022-10-17]{\text_declare_case_mapping:nnn} +% \begin{syntax} +% \cs{text_declare_case_mapping:nnn} \meta{letter} \Arg{case} \Args{codepoints} +% \end{syntax} +% Declares that when the \meta{letter} is encountered during conversion to the +% \meta{case}, the \meta{codepoints} should be generated as a replacement. This +% over-rides the standard value(s). The \meta{letter} will be given as written +% by the user, thus in $8$-bit engines will potentially be multiple bytes. +% Between one and three \meta{codepoints} should be given as replacements in +% a comma list. +% \end{function} +% % \begin{function}[EXP, added = 2022-07-04]{\text_case_switch:nnnn} % \begin{syntax} % \cs{text_case_switch:nnnn} \Arg{normal} \Arg{upper} \Arg{lower} \Arg{title} diff --git a/l3kernel/testfiles/m3text002.luatex.tlg b/l3kernel/testfiles/m3text002.luatex.tlg index 96bbeee9ab..7a90414c2b 100644 --- a/l3kernel/testfiles/m3text002.luatex.tlg +++ b/l3kernel/testfiles/m3text002.luatex.tlg @@ -366,3 +366,30 @@ Defining \l__text_case_\foo_tl on line ... } l. ... } ============================================================ +============================================================ +TEST 32: Case change mappings +============================================================ +> lupus. + } +l. ... } +Defining \l__text_lower_U_tl on line ... +> lvpvs. + } +l. ... } +============================================================ +============================================================ +TEST 33: Case change mapping errors +============================================================ +! Package text Error: Invalid number of entries for case mapping of "U". +For immediate help type H . + ... +l. ... } +LaTeX has been asked to specify a custom case mapping for "U". This must be +given as 1 to 3 output codepoints, but 0 codepoints were given. +! Package text Error: Invalid number of entries for case mapping of "U". +For immediate help type H . + ... +l. ... } +LaTeX has been asked to specify a custom case mapping for "U". This must be +given as 1 to 3 output codepoints, but 4 codepoints were given. +============================================================ diff --git a/l3kernel/testfiles/m3text002.lvt b/l3kernel/testfiles/m3text002.lvt index bf379eb9da..b82b60eaed 100644 --- a/l3kernel/testfiles/m3text002.lvt +++ b/l3kernel/testfiles/m3text002.lvt @@ -382,4 +382,19 @@ { \text_lowercase:n { \use:n { FOO } \foo } } } +\TEST { Case~change~mappings } + { + \tl_show:x + { \text_lowercase:n { LUPUS } } + \text_declare_case_mapping:nnn { U } { lower } { `v } + \tl_show:x + { \text_lowercase:n { LUPUS } } + } + +\TEST { Case~change~mapping~errors } + { + \text_declare_case_mapping:nnn { U } { lower } { } + \text_declare_case_mapping:nnn { U } { lower } { a , b , c , d } + } + \END diff --git a/l3kernel/testfiles/m3text002.tlg b/l3kernel/testfiles/m3text002.tlg index e48c1f0e70..d07492b381 100644 --- a/l3kernel/testfiles/m3text002.tlg +++ b/l3kernel/testfiles/m3text002.tlg @@ -366,3 +366,30 @@ Defining \l__text_case_\foo_tl on line ... } l. ... } ============================================================ +============================================================ +TEST 32: Case change mappings +============================================================ +> lupus. + } +l. ... } +Defining \l__text_lower_U_tl on line ... +> lvpvs. + } +l. ... } +============================================================ +============================================================ +TEST 33: Case change mapping errors +============================================================ +! Package text Error: Invalid number of entries for case mapping of "U". +For immediate help type H . + ... +l. ... } +LaTeX has been asked to specify a custom case mapping for "U". This must be +given as 1 to 3 output codepoints, but 0 codepoints were given. +! Package text Error: Invalid number of entries for case mapping of "U". +For immediate help type H . + ... +l. ... } +LaTeX has been asked to specify a custom case mapping for "U". This must be +given as 1 to 3 output codepoints, but 4 codepoints were given. +============================================================ diff --git a/l3kernel/testfiles/m3text002.xetex.tlg b/l3kernel/testfiles/m3text002.xetex.tlg index 96bbeee9ab..7a90414c2b 100644 --- a/l3kernel/testfiles/m3text002.xetex.tlg +++ b/l3kernel/testfiles/m3text002.xetex.tlg @@ -366,3 +366,30 @@ Defining \l__text_case_\foo_tl on line ... } l. ... } ============================================================ +============================================================ +TEST 32: Case change mappings +============================================================ +> lupus. + } +l. ... } +Defining \l__text_lower_U_tl on line ... +> lvpvs. + } +l. ... } +============================================================ +============================================================ +TEST 33: Case change mapping errors +============================================================ +! Package text Error: Invalid number of entries for case mapping of "U". +For immediate help type H . + ... +l. ... } +LaTeX has been asked to specify a custom case mapping for "U". This must be +given as 1 to 3 output codepoints, but 0 codepoints were given. +! Package text Error: Invalid number of entries for case mapping of "U". +For immediate help type H . + ... +l. ... } +LaTeX has been asked to specify a custom case mapping for "U". This must be +given as 1 to 3 output codepoints, but 4 codepoints were given. +============================================================