diff --git a/plexpl3.dtx b/plexpl3.dtx index 0c8d1ba..0317b6f 100644 --- a/plexpl3.dtx +++ b/plexpl3.dtx @@ -116,656 +116,6 @@ { \tex_ifdbox:D #1 \prg_return_true: \else: \prg_return_false: \fi: } % \end{macrocode} % -% \section{expl3の和文文字トークン対応} -% -% \subsection{Additional functions for jachar support} -% -% \subsubsection{Tests jachar token} -% \url{https://gist.github.com/zr-tex8r/248ff347172ce16d005897656687a901} -% -% \begin{macro}{\token_if_jachar:NTF} -% \meta{token} \marg{true code} \marg{false code} -% -% Tests if \meta{token} is a jachar token or not. -% -% \begin{macrocode} -\bool_lazy_or:nnTF - { \sys_if_engine_ptex_p: } - { \sys_if_engine_uptex_p: } - { - \use:x - { - \prg_new_conditional:Npnn \exp_not:N \token_if_jachar:N ##1 - { p , T , F , TF } - { -% \end{macrocode} -% A token is a jachar token if and only if -% its meaning string starts with ``\verb*|kanji |''. -% \begin{macrocode} - \exp_not:N \str_if_eq:eeTF - { - \exp_not:N \exp_after:wN - \exp_not:N \__token_delimit_by_kanji:w - \exp_not:N \token_to_meaning:N ##1 - ? \tl_to_str:n { kanji } ~ \s__token_stop - } - { } - { \exp_not:N \prg_return_true: } - { \exp_not:N \prg_return_false: } - } - \cs_new:Npn \exp_not:N \__token_delimit_by_kanji:w ##1 - \tl_to_str:n { kanji } ~ ##2 \s__token_stop - {##1} - } - } - { - \prg_new_conditional:Npnn \token_if_jachar:N #1 - { p , T , F , TF } - { \prg_return_false: } - } -% \end{macrocode} -% \end{macro} -% -% \subsection{Fix for l3str} -% -% \subsubsection{Fix for the case-change funcrtions} -% -% \begin{macrocode} -%<@@=str> -% \end{macrocode} -% -% Handle jachar in \pTeX{} and \upTeX{}. -% \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_ptex_p: } - { \sys_if_engine_uptex_p: } - { - \cs_new_eq:NN \@@_change_case_codepoint_non_jachar:nN - \@@_change_case_codepoint:nN - \cs_gset:Npn \@@_change_case_codepoint:nN #1#2 - { - \token_if_jachar:NTF #2 - { \@@_change_case_codepoint_jachar:nN } - { \@@_change_case_codepoint_non_jachar:nN } - {#1} #2 - } - \cs_new:Npn \@@_change_case_codepoint_jachar:nN #1#2 - { - \@@_change_case_output:nw {#2} - \@@_change_case_loop:nw {#1} - } - } -% \end{macrocode} -% -% \subsection{Fix for l3text} -% -% \begin{macrocode} -%<@@=text> -% \end{macrocode} -% -% \subsubsection{Fix for the codepoints funcrtions} -% -% Reverts the \pTeX{} implementation to the same as \pdfTeX{}. -% \begin{macrocode} -\sys_if_engine_ptex:T - { - \cs_gset:Npn \@@_codepoint_process:nN #1#2 - { - \int_compare:nNnTF { `#2 } > { "80 } - { - \int_compare:nNnTF { `#2 } < { "E0 } - { \@@_codepoint_process:nNN } - { - \int_compare:nNnTF { `#2 } < { "F0 } - { \@@_codepoint_process:nNNN } - { \@@_codepoint_process:nNNNN } - } - } - { \use:n } - {#1} #2 - } - \cs_new:Npn \@@_codepoint_process:nNNN #1#2#3#4 - { #1 {#2#3#4} } - \cs_new:Npn \@@_codepoint_process:nNNNN #1#2#3#4#5 - { #1 {#2#3#4#5} } - } -% \end{macrocode} -% Handle jachar in \pTeX{} and \upTeX{}. -% \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_ptex_p: } - { \sys_if_engine_uptex_p: } - { - \cs_new_eq:NN \@@_codepoint_process_non_jachar:nN - \@@_codepoint_process:nN - \cs_gset:Npn \@@_codepoint_process:nN #1#2 - { - \token_if_jachar:NTF #2 - { \@@_codepoint_process_jachar:nN } - { \@@_codepoint_process_non_jachar:nN } - {#1} #2 - } - \cs_new:Npn \@@_codepoint_process_jachar:nN #1#2 - { #1 {#2} } - } -% \end{macrocode} -% -% Reverts the \pTeX{} implementation to the same as \pdfTeX{}. -% \begin{macrocode} -\sys_if_engine_ptex:T - { - \cs_gset:Npn \@@_codepoint_from_chars:Nw #1 - { - \if_int_compare:w `#1 > "80 \exp_stop_f: - \if_int_compare:w `#1 < "E0 \exp_stop_f: - \exp_after:wN \exp_after:wN \exp_after:wN - \@@_codepoint_from_chars:NN - \else: - \if_int_compare:w `#1 < "F0 \exp_stop_f: - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_after:wN \@@_codepoint_from_chars:NNN - \else: - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_after:wN \@@_codepoint_from_chars:NNNN - \fi: - \fi: - \else: - \exp_after:wN \@@_codepoint_from_chars:N - \fi: - #1 - } - \cs_new:Npn \@@_codepoint_from_chars:NNN #1#2#3 - { (`#1 - "E0) * "1000 + (`#2 - "80) * "40 + `#3 - "80 } - \cs_new:Npn \@@_codepoint_from_chars:NNNN #1#2#3#4 - { - (`#1 - "F0) * "40000 - + (`#2 - "80) * "1000 - + (`#3 - "80) * "40 - + `#4 - "80 - } - } -% \end{macrocode} -% Handle jachar in \pTeX{} and \upTeX{}. -% \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_ptex_p: } - { \sys_if_engine_uptex_p: } - { - \cs_new_eq:NN \@@_codepoint_from_chars_non_jachar:Nw - \@@_codepoint_from_chars:Nw - \cs_gset:Npn \@@_codepoint_from_chars:Nw #1 - { - \token_if_jachar:NTF #1 - { \@@_codepoint_from_chars_jachar:N } - { \@@_codepoint_from_chars_non_jachar:Nw } - #1 - } - \cs_new:Npn \@@_codepoint_from_chars_jachar:N #1 - { \tex_toucs:D `#1 ~ } - } -% \end{macrocode} -% -% \subsubsection{Fix for the case-change funcrtions} -% -% Do not change case of jachar. -% \begin{macrocode} -\bool_lazy_or:nnT - { \sys_if_engine_ptex_p: } - { \sys_if_engine_uptex_p: } - { - \cs_new_eq:NN \@@_change_case_codepoint_lower_non_jachar:nnn - \@@_change_case_codepoint_lower:nnn - \cs_new_eq:NN \@@_change_case_codepoint_upper_non_jachar:nnn - \@@_change_case_codepoint_upper:nnn - \cs_new_eq:NN \@@_change_case_codepoint_title_non_jachar:nnn - \@@_change_case_codepoint_title:nnn - \cs_new_eq:NN \@@_change_case_codepoint_titleonly_non_jachar:nnn - \@@_change_case_codepoint_titleonly:nnn - \cs_gset:Npn \@@_change_case_codepoint_lower:nnn #1#2#3 - { \@@_change_case_codepoint_jachar:nnnn {#1} {#1} {#2} {#3} } - \cs_gset:Npn \@@_change_case_codepoint_upper:nnn #1#2#3 - { \@@_change_case_codepoint_jachar:nnnn {#1} {#1} {#2} {#3} } - \cs_gset:Npn \@@_change_case_codepoint_title:nnn #1#2#3 - { \@@_change_case_codepoint_jachar:nnnn {#1} { lower } {#2} {#3} } - \cs_gset:Npn \@@_change_case_codepoint_titleonly:nnn #1#2#3 - { \@@_change_case_codepoint_jachar:nnnn {#1} { end } {#2} {#3} } - \cs_new:Npn \@@_change_case_codepoint_jachar:nnnn #1#2#3#4 - { - \bool_lazy_and:nnTF - { \tl_if_single_p:n {#4} } - { \token_if_jachar_p:N #4 } - { - \@@_change_case_store:n {#4} - \use:c { @@_change_case_next_ #2 :nn } {#2} {#3} - } - { \use:c { @@_change_case_codepoint_ #1 _non_jachar:nnn } {#1} {#3} {#4} } - } - } -% \end{macrocode} -% -% \begin{macrocode} -%<@@=> -% \end{macrocode} -% -% \subsection{文字コード変換関数の修正} -% \url{https://gist.github.com/h20y6m/6449d1d5d29a71620d19f29f881a0549} -% -% \begin{macro}{\__str_encode_if_extended_char_p:n} -% \begin{macro}{\__str_encode_extended_char:n} -% \begin{macrocode} -\cs_new:Npn \__str_encode_if_extended_char_p:n #1 { \c_false_bool } -\cs_new:Npn \__str_encode_extended_char:n #1 { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% Patch for UTF-8 encoding function in \file{l3str-convert}. -% \begin{macrocode} -\cs_gset:Npn \__str_encode_utf_viii_char:n #1 - { - \if_predicate:w \__str_encode_if_extended_char_p:n {#1} - \__str_encode_extended_char:n {#1} - \else: - \__str_encode_utf_viii_loop:wwnnw #1 ; - 1 + 0 * ; - { 128 } { 0 } - { 32 } { 192 } - { 16 } { 224 } - { 8 } { 240 } - \s__str_stop - \fi: - } -% \end{macrocode} -% -% \begin{macro}{\__str_decode_if_extended_char_p:N} -% \begin{macro}{\__str_decode_extended_char:N} -% \begin{macrocode} -\cs_new:Npn \__str_decode_if_extended_char_p:N #1 { \c_false_bool } -\cs_new:Npn \__str_decode_extended_char:N #1 { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% Patch for UTF-8 decoding function in \file{l3str-convert}. -% \begin{macrocode} -\cs_gset:Npn \__str_decode_utf_viii_start:N #1 - { - #1 - \if_predicate:w \__str_decode_if_extended_char_p:N #1 - \s__str - \__str_decode_extended_char:N #1 - \else: - \if_int_compare:w `#1 < "C0 \exp_stop_f: - \s__str - \if_int_compare:w `#1 < "80 \exp_stop_f: - \int_value:w `#1 - \else: - \flag_raise:n { str_extra } - \flag_raise:n { str_error } - \int_use:N \c__str_replacement_char_int - \fi: - \else: - \exp_after:wN \__str_decode_utf_viii_continuation:wwN - \int_value:w \int_eval:n { `#1 - "C0 } \exp_after:wN - \fi: - \exp_after:wN % ??? - \fi: - \s__str - \__str_use_none_delimit_by_s_stop:w {"80} {"800} {"10000} {"110000} \s__str_stop - \__str_decode_utf_viii_start:N - } -% \end{macrocode} -% -% \begin{macrocode} -\cs_new_protected:Npn \__ptex_tmp:w { } -% \end{macrocode} -% -% (up\TeX{} only) declare kanji token which has specific kcatcode. -% \begin{macrocode} -\sys_if_engine_uptex:T - { - \group_begin: - \cs_set:Npn \__ptex_tmp:w #1#2 - { - \exp_after:wN \cs_new_eq:NN \exp_after:wN #1 - \tex_Ucharcat:D - \int_eval:n { \tex_jis:D "2121 } ~ - \int_eval:n {#2} \scan_stop: - } - \__ptex_tmp:w \c_kcatcode_kanji_token { 16 } - \__ptex_tmp:w \c_kcatcode_kana_token { 17 } - \__ptex_tmp:w \c_kcatcode_symbol_token { 18 } - \__ptex_tmp:w \c_kcatcode_hangul_token { 19 } - \group_end: - } -% \end{macrocode} -% -% (up\TeX{} only) get kcatcode of token. -% \begin{macrocode} -\sys_if_engine_uptex:T - { - \cs_new:Npn \__ptex_char_kcatcode:N #1 - { - \if_catcode:w \exp_not:N #1 \c_kcatcode_kanji_token - 16 - \else: - \if_catcode:w \exp_not:N #1 \c_kcatcode_kana_token - 17 - \else: - \if_catcode:w \exp_not:N #1 \c_kcatcode_symbol_token - 18 - \else: - \if_catcode:w \exp_not:N #1 \c_kcatcode_hangul_token - 19 - \else: - 15 - \fi: - \fi: - \fi: - \fi: - } - } -% \end{macrocode} -% -% define ptex+utf8 encoding. -% -% ptex+utf8 encode function. -% \begin{macrocode} -\cs_new_protected:cpn { __str_convert_encode_ptex+utf8: } - { - \group_begin: - \cs_set_eq:NN \__str_encode_if_extended_char_p:n - \__str_encode_if_kanji_char_p:n - \cs_set_eq:NN \__str_encode_extended_char:n - \__str_encode_kanji_char:n - \use:c { __str_convert_encode_utf8: } - \group_end: - } -% \end{macrocode} -% -% Tests whether the Unicode code point \#1 is Japanese character -% \begin{macrocode} -\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } - { -% \end{macrocode} -% up\TeX{} with unicode -% \begin{macrocode} - \prg_new_conditional:Npnn \__str_encode_if_kanji_char:n #1 { p } - { -% \end{macrocode} -% NOTE: -% \verb|\kcatcode0|--\verb|\kcatcode127| may not be 15, -% but ASCII ($0$--$127$) never be Japanese character. -% \begin{macrocode} - \if_int_compare:w #1 < "80 \exp_stop_f: - \prg_return_false: - \else: - \if_int_compare:w \tex_kcatcode:D #1 = 15 \exp_stop_f: - \prg_return_false: - \else: - \prg_return_true: - \fi: - \fi: - } - } - { -% \end{macrocode} -% p\TeX{} or up\TeX{} with euc/sjis -% \begin{macrocode} - \prg_new_conditional:Npnn \__str_encode_if_kanji_char:n #1 { p } - { -% \end{macrocode} -% If specified Unicode code point cannot convert to internal Kanji code, -% \cs{ucs} returns $-1$. -% \begin{macrocode} - \if_int_compare:w \tex_ucs:D #1 < 0 \exp_stop_f: - \prg_return_false: - \else: -% \end{macrocode} -% up\TeX{} only. p\TeX{} always false. -% \begin{macrocode} - \if_int_compare:w - \tex_kcatcode:D \tex_ucs:D #1 = 15 \exp_stop_f: - \prg_return_false: - \else: - \prg_return_true: - \fi: - \fi: - } - } -% \end{macrocode} -% -% Generate Japanese character token which has Unicode code point \#1. -% \begin{macrocode} -\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } - { -% \end{macrocode} -% up\TeX{} with unicode -% \begin{macrocode} - \cs_new:Npn \__str_encode_kanji_char:n #1 - { -% \end{macrocode} -% \cs{Uchar} always generates Latin character token for character -% code $128$--$255$, but Japanese character token are needed, -% so use \cs{Ucharcat} instead. -% \begin{macrocode} - \if_int_compare:w \tex_kcatcode:D #1 > 15 \exp_stop_f: - \tex_Ucharcat:D - #1 \exp_stop_f: \tex_kcatcode:D #1 \exp_stop_f: - \else: - \tex_Ucharcat:D #1 \exp_stop_f: 18 \exp_stop_f: - \fi: - } - } - { -% \end{macrocode} -% p\TeX{} or up\TeX{} with euc/sjis -% \begin{macrocode} - \cs_new:Npn \__str_encode_kanji_char:n #1 - { \tex_Uchar:D \tex_ucs:D #1 \exp_stop_f: \exp_stop_f: } - } -% \end{macrocode} -% -% ptex+utf8 decode function. -% \begin{macrocode} -\cs_new_protected:cpn { __str_convert_decode_ptex+utf8: } - { - \group_begin: - \cs_set_eq:NN \__str_decode_if_extended_char_p:N - \__str_decode_if_kanji_char_p:N - \cs_set_eq:NN \__str_decode_extended_char:N - \__str_decode_kanji_char:N - \use:c { __str_convert_decode_utf8: } - \group_end: - } -% \end{macrocode} -% -% Tests whether the token \#1 is Japanese character. -% \begin{macrocode} -\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } - { -% \end{macrocode} -% up\TeX{} with unicode -% \begin{macrocode} - \prg_new_conditional:Npnn \__str_decode_if_kanji_char:N #1 { p } - { - \if_int_compare:w - \__ptex_char_kcatcode:N #1 > 15 \exp_stop_f: - \prg_return_true: - \else: - \prg_return_false: - \fi: - } - } - { -% \end{macrocode} -% p\TeX{} or up\TeX{} with euc/sjis -% \begin{macrocode} - \prg_new_conditional:Npnn \__str_decode_if_kanji_char:N #1 { p } - { - \if_int_compare:w `#1 < "100 \exp_stop_f: - \prg_return_false: - \else: - \prg_return_true: - \fi: - } - } -% \end{macrocode} -% Convert Japanese character \#1 to Unicode code point. -% \begin{macrocode} -\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } - { -% \end{macrocode} -% up\TeX{} with unicode -% \begin{macrocode} - \cs_new:Npn \__str_decode_kanji_char:N #1 - { \int_value:w `#1 } - } - { -% \end{macrocode} -% p\TeX{} or up\TeX{} with euc/sjis -% \begin{macrocode} - \cs_new:Npn \__str_decode_kanji_char:N #1 - { \tex_toucs:D `#1 } - } -% \end{macrocode} -% -% alternative encoding name -% \begin{macrocode} -\prop_gput:Nnn \g__str_alias_prop { ptex } { ptex+utf8 } -% \end{macrocode} -% set default encoding to ptex+utf8 -% \begin{macrocode} -\prop_gput:Nnn \g__str_alias_prop { default } { ptex+utf8 } -% \end{macrocode} -% -% \subsection{正規表現関数の修正} -% -% Fix for replacement functions in \file{l3regrex}. -% \begin{macrocode} -\cs_gset_protected:Npn \__regex_replacement_normal_aux:N #1 - { - \token_if_eq_charcode:NNTF #1 \c_space_token - { \__regex_replacement_c_S:w } - { -% \end{macrocode} -% Check if the given character token is a jachar. -% \begin{macrocode} - \token_if_jachar:NTF #1 - { \__regex_replacement_jachar:NN } - { - \exp_after:wN \exp_after:wN - \if_case:w \tex_catcode:D `#1 \exp_stop_f: - \__regex_replacement_c_O:w - \or: \__regex_replacement_c_B:w - \or: \__regex_replacement_c_E:w - \or: \__regex_replacement_c_M:w - \or: \__regex_replacement_c_T:w - \or: \__regex_replacement_c_O:w - \or: \__regex_replacement_c_P:w - \or: \__regex_replacement_c_U:w - \or: \__regex_replacement_c_D:w - \or: \__regex_replacement_c_O:w - \or: \__regex_replacement_c_S:w - \or: \__regex_replacement_c_L:w - \or: \__regex_replacement_c_O:w - \or: \__regex_replacement_c_A:w - \else: \__regex_replacement_c_O:w - \fi: - } - } - ? #1 - } -% \end{macrocode} -% 和文文字はとりあえずそのまま出力します。 -% \begin{macrocode} -\cs_new_protected:Npn \__regex_replacement_jachar:NN #1#2 - { \__regex_replacement_put:n {#2} } -% \end{macrocode} -% -% \subsection{コードポイント関数の修正} -% -% Fix for codepoint functions in \file{l3text}. -% \begin{macrocode} -%<@@=text> -% \end{macrocode} -% \begin{macrocode} -\cs_gset:Npn \@@_codepoint_process:nN #1#2 - { -% \end{macrocode} -% Check if the given character token is a jachar. -% One jachar token is one codepoint. -% \begin{macrocode} - \token_if_jachar:NTF #2 - { \use:n } - { - \int_compare:nNnTF { `#2 } > { "80 } - { - \int_compare:nNnTF { `#2 } < { "E0 } - { \@@_codepoint_process:nNN } - { - \int_compare:nNnTF { `#2 } < { "F0 } - { \@@_codepoint_process:nNNN } - { \@@_codepoint_process:nNNNN } - } - } - } - { \use:n } - {#1} #2 - } -% \end{macrocode} -% \begin{macrocode} -\cs_gset:Npn \@@_codepoint_compare:N #1 - { -% \end{macrocode} -% Check if the given character token is a jachar. -% \begin{macrocode} - \token_if_jachar:NTF #1 - { \@@_codepoint_compare_jachar:N } - { - \if_int_compare:w `#1 > "80 \exp_stop_f: - \if_int_compare:w `#1 < "E0 \exp_stop_f: - \exp_after:wN \exp_after:wN \exp_after:wN - \@@_codepoint_compare:NN - \else: - \if_int_compare:w `#1 < "F0 \exp_stop_f: - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_after:wN \@@_codepoint_compare:NNN - \else: - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_after:wN \exp_after:wN \exp_after:wN - \exp_after:wN \@@_codepoint_compare:NNNN - \fi: - \fi: - \else: - \exp_after:wN \@@_codepoint_compare_aux:N - \fi: - } - #1 - } -% \end{macrocode} -% \begin{macrocode} -\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } - { -% \end{macrocode} -% up\TeX{} with unicode. -% \begin{macrocode} - \cs_new:Npn \@@_codepoint_compare_jachar:N #1 { `#1 } - } - { -% \end{macrocode} -% p\TeX{} or up\TeX{} with euc/sjis. -% \begin{macrocode} - \cs_new:Npn \@@_codepoint_compare_jachar:N #1 - { \tex_toucs:D `#1 \exp_stop_f: } - } -% \end{macrocode} -% \begin{macrocode} -%<@@=> -% \end{macrocode} -% % 以上です。 % \begin{macrocode} % diff --git a/plexpl3.ins b/plexpl3.ins index 51fbc18..4632723 100644 --- a/plexpl3.ins +++ b/plexpl3.ins @@ -10,7 +10,7 @@ This file is part of the pLaTeX2e system (community edition). \fi \let\jobname\relax -\input docstrip % +\input l3docstrip % \askforoverwritefalse \preamble @@ -27,7 +27,15 @@ This file is part of the pLaTeX2e system (community edition). \keepsilent -\generate{\file{plexpl3.sty}{\from{plexpl3.dtx}{package}}} -\generate{\file{plexpl3.ltx}{\from{plexpl3.dtx}{code}}} +\generate + { + \file{plexpl3.ltx} + { + \from{plexpl3.dtx} {code} + \from{plpatch3.dtx}{package} + } + } + +\generate{\file{plexpl3.sty} {\from{plexpl3.dtx} {package}}} \endbatchfile diff --git a/plpatch3.dtx b/plpatch3.dtx new file mode 100644 index 0000000..4eee533 --- /dev/null +++ b/plpatch3.dtx @@ -0,0 +1,639 @@ +% \iffalse meta-comment +%% File: plpatch3.dtx +% +% Copyright (c) 2023 Yukimasa Morimi (h20y6m) +% +% ------------------------------------------------------------- +% +% +%<*driver> +\RequirePackage{plautopatch} +\documentclass[dvipdfmx,a4paper,full]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +% +% \fi +% +% +% \title{^^A +% The \pkg{plpatch3} package: pTeX/upTeX-specific patches to expl3 ^^A +% } +% +% \author{^^A +% Yukimasa Morimi (h20y6m)\thanks +% {^^A +% GitHub: +% \url{https://github.com/h20y6m}^^A +% }^^A +% } +% +% \date{Released 2023-02-11} +% +% \maketitle +% +% \begin{documentation} +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{plpatch3} implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% +% \subsection{Additional functions for jachar support} +% +% \subsubsection{Tests jachar token} +% \url{https://gist.github.com/zr-tex8r/248ff347172ce16d005897656687a901} +% +% \begin{macrocode} +%<@@=token> +% \end{macrocode} +% +% \begin{macro}{\token_if_jachar:NTF} +% \meta{token} \marg{true code} \marg{false code} +% +% Tests if \meta{token} is a jachar token or not. +% +% \begin{macrocode} +\bool_lazy_or:nnTF + { \sys_if_engine_ptex_p: } + { \sys_if_engine_uptex_p: } + { + \use:x + { + \prg_new_conditional:Npnn \exp_not:N \token_if_jachar:N ##1 + { p , T , F , TF } + { +% \end{macrocode} +% A token is a jachar token if and only if +% its meaning string starts with ``\verb*|kanji |''. +% \begin{macrocode} + \exp_not:N \str_if_eq:eeTF + { + \exp_not:N \exp_after:wN + \exp_not:N \@@_delimit_by_kanji:w + \exp_not:N \token_to_meaning:N ##1 + ? \tl_to_str:n { kanji } ~ \s_@@_stop + } + { } + { \exp_not:N \prg_return_true: } + { \exp_not:N \prg_return_false: } + } + \cs_new:Npn \exp_not:N \@@_delimit_by_kanji:w ##1 + \tl_to_str:n { kanji } ~ ##2 \s_@@_stop + {##1} + } + } + { + \prg_new_conditional:Npnn \token_if_jachar:N #1 + { p , T , F , TF } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Fix for l3regex} +% +% \begin{macrocode} +%<@@=regex> +% \end{macrocode} +% +% \subsubsection{Fix for the regex funcrtions} +% +% Fix for replacement functions in \file{l3regrex}. +% \begin{macrocode} +\cs_gset_protected:Npn \__regex_replacement_normal_aux:N #1 + { + \token_if_eq_charcode:NNTF #1 \c_space_token + { \__regex_replacement_c_S:w } + { +% \end{macrocode} +% Check if the given character token is a jachar. +% \begin{macrocode} + \token_if_jachar:NTF #1 + { \__regex_replacement_jachar:NN } + { + \exp_after:wN \exp_after:wN + \if_case:w \tex_catcode:D `#1 \exp_stop_f: + \__regex_replacement_c_O:w + \or: \__regex_replacement_c_B:w + \or: \__regex_replacement_c_E:w + \or: \__regex_replacement_c_M:w + \or: \__regex_replacement_c_T:w + \or: \__regex_replacement_c_O:w + \or: \__regex_replacement_c_P:w + \or: \__regex_replacement_c_U:w + \or: \__regex_replacement_c_D:w + \or: \__regex_replacement_c_O:w + \or: \__regex_replacement_c_S:w + \or: \__regex_replacement_c_L:w + \or: \__regex_replacement_c_O:w + \or: \__regex_replacement_c_A:w + \else: \__regex_replacement_c_O:w + \fi: + } + } + ? #1 + } +% \end{macrocode} +% FIXME: jachar as is. +% \begin{macrocode} +\cs_new_protected:Npn \__regex_replacement_jachar:NN #1#2 + { \__regex_replacement_put:n {#2} } +% \end{macrocode} +% +% +% \subsection{Fix for l3str} +% +% \begin{macrocode} +%<@@=str> +% \end{macrocode} +% +% \subsubsection{Fix for the case-change funcrtions} +% +% Handle jachar in \pTeX{} and \upTeX{}. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_ptex_p: } + { \sys_if_engine_uptex_p: } + { + \cs_new_eq:NN \@@_change_case_codepoint_non_jachar:nN + \@@_change_case_codepoint:nN + \cs_gset:Npn \@@_change_case_codepoint:nN #1#2 + { + \token_if_jachar:NTF #2 + { \@@_change_case_codepoint_jachar:nN } + { \@@_change_case_codepoint_non_jachar:nN } + {#1} #2 + } + \cs_new:Npn \@@_change_case_codepoint_jachar:nN #1#2 + { + \@@_change_case_output:nw {#2} + \@@_change_case_loop:nw {#1} + } + } +% \end{macrocode} +% +% +% \subsection{Fix for l3str-convert} +% +% \begin{macrocode} +%<@@=str> +% \end{macrocode} +% +% \subsubsection{Fix for the encoding convertion funcrtions} +% \url{https://gist.github.com/h20y6m/6449d1d5d29a71620d19f29f881a0549} +% +% \begin{macro}{\__str_encode_if_extended_char_p:n} +% \begin{macro}{\__str_encode_extended_char:n} +% \begin{macrocode} +\cs_new:Npn \__str_encode_if_extended_char_p:n #1 { \c_false_bool } +\cs_new:Npn \__str_encode_extended_char:n #1 { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Patch for UTF-8 encoding function in \file{l3str-convert}. +% \begin{macrocode} +\cs_gset:Npn \__str_encode_utf_viii_char:n #1 + { + \if_predicate:w \__str_encode_if_extended_char_p:n {#1} + \__str_encode_extended_char:n {#1} + \else: + \__str_encode_utf_viii_loop:wwnnw #1 ; - 1 + 0 * ; + { 128 } { 0 } + { 32 } { 192 } + { 16 } { 224 } + { 8 } { 240 } + \s__str_stop + \fi: + } +% \end{macrocode} +% +% \begin{macro}{\__str_decode_if_extended_char_p:N} +% \begin{macro}{\__str_decode_extended_char:N} +% \begin{macrocode} +\cs_new:Npn \__str_decode_if_extended_char_p:N #1 { \c_false_bool } +\cs_new:Npn \__str_decode_extended_char:N #1 { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Patch for UTF-8 decoding function in \file{l3str-convert}. +% \begin{macrocode} +\cs_gset:Npn \__str_decode_utf_viii_start:N #1 + { + #1 + \if_predicate:w \__str_decode_if_extended_char_p:N #1 + \s__str + \__str_decode_extended_char:N #1 + \else: + \if_int_compare:w `#1 < "C0 \exp_stop_f: + \s__str + \if_int_compare:w `#1 < "80 \exp_stop_f: + \int_value:w `#1 + \else: + \flag_raise:n { str_extra } + \flag_raise:n { str_error } + \int_use:N \c__str_replacement_char_int + \fi: + \else: + \exp_after:wN \__str_decode_utf_viii_continuation:wwN + \int_value:w \int_eval:n { `#1 - "C0 } \exp_after:wN + \fi: + \exp_after:wN % ??? + \fi: + \s__str + \__str_use_none_delimit_by_s_stop:w {"80} {"800} {"10000} {"110000} \s__str_stop + \__str_decode_utf_viii_start:N + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \__ptex_tmp:w { } +% \end{macrocode} +% +% (up\TeX{} only) declare kanji token which has specific kcatcode. +% \begin{macrocode} +\sys_if_engine_uptex:T + { + \group_begin: + \cs_set:Npn \__ptex_tmp:w #1#2 + { + \exp_after:wN \cs_new_eq:NN \exp_after:wN #1 + \tex_Ucharcat:D + \int_eval:n { \tex_jis:D "2121 } ~ + \int_eval:n {#2} \scan_stop: + } + \__ptex_tmp:w \c_kcatcode_kanji_token { 16 } + \__ptex_tmp:w \c_kcatcode_kana_token { 17 } + \__ptex_tmp:w \c_kcatcode_symbol_token { 18 } + \__ptex_tmp:w \c_kcatcode_hangul_token { 19 } + \group_end: + } +% \end{macrocode} +% +% (up\TeX{} only) get kcatcode of token. +% \begin{macrocode} +\sys_if_engine_uptex:T + { + \cs_new:Npn \__ptex_char_kcatcode:N #1 + { + \if_catcode:w \exp_not:N #1 \c_kcatcode_kanji_token + 16 + \else: + \if_catcode:w \exp_not:N #1 \c_kcatcode_kana_token + 17 + \else: + \if_catcode:w \exp_not:N #1 \c_kcatcode_symbol_token + 18 + \else: + \if_catcode:w \exp_not:N #1 \c_kcatcode_hangul_token + 19 + \else: + 15 + \fi: + \fi: + \fi: + \fi: + } + } +% \end{macrocode} +% +% define ptex+utf8 encoding. +% +% ptex+utf8 encode function. +% \begin{macrocode} +\cs_new_protected:cpn { __str_convert_encode_ptex+utf8: } + { + \group_begin: + \cs_set_eq:NN \__str_encode_if_extended_char_p:n + \__str_encode_if_kanji_char_p:n + \cs_set_eq:NN \__str_encode_extended_char:n + \__str_encode_kanji_char:n + \use:c { __str_convert_encode_utf8: } + \group_end: + } +% \end{macrocode} +% +% Tests whether the Unicode code point \#1 is Japanese character +% \begin{macrocode} +\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } + { +% \end{macrocode} +% up\TeX{} with unicode +% \begin{macrocode} + \prg_new_conditional:Npnn \__str_encode_if_kanji_char:n #1 { p } + { +% \end{macrocode} +% NOTE: +% \verb|\kcatcode0|--\verb|\kcatcode127| may not be 15, +% but ASCII ($0$--$127$) never be Japanese character. +% \begin{macrocode} + \if_int_compare:w #1 < "80 \exp_stop_f: + \prg_return_false: + \else: + \if_int_compare:w \tex_kcatcode:D #1 = 15 \exp_stop_f: + \prg_return_false: + \else: + \prg_return_true: + \fi: + \fi: + } + } + { +% \end{macrocode} +% p\TeX{} or up\TeX{} with euc/sjis +% \begin{macrocode} + \prg_new_conditional:Npnn \__str_encode_if_kanji_char:n #1 { p } + { +% \end{macrocode} +% If specified Unicode code point cannot convert to internal Kanji code, +% \cs{ucs} returns $-1$. +% \begin{macrocode} + \if_int_compare:w \tex_ucs:D #1 < 0 \exp_stop_f: + \prg_return_false: + \else: +% \end{macrocode} +% up\TeX{} only. p\TeX{} always false. +% \begin{macrocode} + \if_int_compare:w + \tex_kcatcode:D \tex_ucs:D #1 = 15 \exp_stop_f: + \prg_return_false: + \else: + \prg_return_true: + \fi: + \fi: + } + } +% \end{macrocode} +% +% Generate Japanese character token which has Unicode code point \#1. +% \begin{macrocode} +\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } + { +% \end{macrocode} +% up\TeX{} with unicode +% \begin{macrocode} + \cs_new:Npn \__str_encode_kanji_char:n #1 + { +% \end{macrocode} +% \cs{Uchar} always generates Latin character token for character +% code $128$--$255$, but Japanese character token are needed, +% so use \cs{Ucharcat} instead. +% \begin{macrocode} + \if_int_compare:w \tex_kcatcode:D #1 > 15 \exp_stop_f: + \tex_Ucharcat:D + #1 \exp_stop_f: \tex_kcatcode:D #1 \exp_stop_f: + \else: + \tex_Ucharcat:D #1 \exp_stop_f: 18 \exp_stop_f: + \fi: + } + } + { +% \end{macrocode} +% p\TeX{} or up\TeX{} with euc/sjis +% \begin{macrocode} + \cs_new:Npn \__str_encode_kanji_char:n #1 + { \tex_Uchar:D \tex_ucs:D #1 \exp_stop_f: \exp_stop_f: } + } +% \end{macrocode} +% +% ptex+utf8 decode function. +% \begin{macrocode} +\cs_new_protected:cpn { __str_convert_decode_ptex+utf8: } + { + \group_begin: + \cs_set_eq:NN \__str_decode_if_extended_char_p:N + \__str_decode_if_kanji_char_p:N + \cs_set_eq:NN \__str_decode_extended_char:N + \__str_decode_kanji_char:N + \use:c { __str_convert_decode_utf8: } + \group_end: + } +% \end{macrocode} +% +% Tests whether the token \#1 is Japanese character. +% \begin{macrocode} +\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } + { +% \end{macrocode} +% up\TeX{} with unicode +% \begin{macrocode} + \prg_new_conditional:Npnn \__str_decode_if_kanji_char:N #1 { p } + { + \if_int_compare:w + \__ptex_char_kcatcode:N #1 > 15 \exp_stop_f: + \prg_return_true: + \else: + \prg_return_false: + \fi: + } + } + { +% \end{macrocode} +% p\TeX{} or up\TeX{} with euc/sjis +% \begin{macrocode} + \prg_new_conditional:Npnn \__str_decode_if_kanji_char:N #1 { p } + { + \if_int_compare:w `#1 < "100 \exp_stop_f: + \prg_return_false: + \else: + \prg_return_true: + \fi: + } + } +% \end{macrocode} +% Convert Japanese character \#1 to Unicode code point. +% \begin{macrocode} +\int_compare:nNnTF { \tex_jis:D "2121 } = { "3000 } + { +% \end{macrocode} +% up\TeX{} with unicode +% \begin{macrocode} + \cs_new:Npn \__str_decode_kanji_char:N #1 + { \int_value:w `#1 } + } + { +% \end{macrocode} +% p\TeX{} or up\TeX{} with euc/sjis +% \begin{macrocode} + \cs_new:Npn \__str_decode_kanji_char:N #1 + { \tex_toucs:D `#1 } + } +% \end{macrocode} +% +% alternative encoding name +% \begin{macrocode} +\prop_gput:Nnn \g__str_alias_prop { ptex } { ptex+utf8 } +% \end{macrocode} +% set default encoding to ptex+utf8 +% \begin{macrocode} +\prop_gput:Nnn \g__str_alias_prop { default } { ptex+utf8 } +% \end{macrocode} +% +% +% \subsection{Fix for l3text} +% +% \begin{macrocode} +%<@@=text> +% \end{macrocode} +% +% \subsubsection{Fix for the codepoints funcrtions} +% +% Reverts the \pTeX{} implementation to the same as \pdfTeX{}. +% \begin{macrocode} +\sys_if_engine_ptex:T + { + \cs_gset:Npn \@@_codepoint_process:nN #1#2 + { + \int_compare:nNnTF { `#2 } > { "80 } + { + \int_compare:nNnTF { `#2 } < { "E0 } + { \@@_codepoint_process:nNN } + { + \int_compare:nNnTF { `#2 } < { "F0 } + { \@@_codepoint_process:nNNN } + { \@@_codepoint_process:nNNNN } + } + } + { \use:n } + {#1} #2 + } + \cs_new:Npn \@@_codepoint_process:nNNN #1#2#3#4 + { #1 {#2#3#4} } + \cs_new:Npn \@@_codepoint_process:nNNNN #1#2#3#4#5 + { #1 {#2#3#4#5} } + } +% \end{macrocode} +% Handle jachar in \pTeX{} and \upTeX{}. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_ptex_p: } + { \sys_if_engine_uptex_p: } + { + \cs_new_eq:NN \@@_codepoint_process_non_jachar:nN + \@@_codepoint_process:nN + \cs_gset:Npn \@@_codepoint_process:nN #1#2 + { + \token_if_jachar:NTF #2 + { \@@_codepoint_process_jachar:nN } + { \@@_codepoint_process_non_jachar:nN } + {#1} #2 + } + \cs_new:Npn \@@_codepoint_process_jachar:nN #1#2 + { #1 {#2} } + } +% \end{macrocode} +% +% Reverts the \pTeX{} implementation to the same as \pdfTeX{}. +% \begin{macrocode} +\sys_if_engine_ptex:T + { + \cs_gset:Npn \@@_codepoint_from_chars:Nw #1 + { + \if_int_compare:w `#1 > "80 \exp_stop_f: + \if_int_compare:w `#1 < "E0 \exp_stop_f: + \exp_after:wN \exp_after:wN \exp_after:wN + \@@_codepoint_from_chars:NN + \else: + \if_int_compare:w `#1 < "F0 \exp_stop_f: + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_after:wN \@@_codepoint_from_chars:NNN + \else: + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_after:wN \exp_after:wN \exp_after:wN + \exp_after:wN \@@_codepoint_from_chars:NNNN + \fi: + \fi: + \else: + \exp_after:wN \@@_codepoint_from_chars:N + \fi: + #1 + } + \cs_new:Npn \@@_codepoint_from_chars:NNN #1#2#3 + { (`#1 - "E0) * "1000 + (`#2 - "80) * "40 + `#3 - "80 } + \cs_new:Npn \@@_codepoint_from_chars:NNNN #1#2#3#4 + { + (`#1 - "F0) * "40000 + + (`#2 - "80) * "1000 + + (`#3 - "80) * "40 + + `#4 - "80 + } + } +% \end{macrocode} +% Handle jachar in \pTeX{} and \upTeX{}. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_ptex_p: } + { \sys_if_engine_uptex_p: } + { + \cs_new_eq:NN \@@_codepoint_from_chars_non_jachar:Nw + \@@_codepoint_from_chars:Nw + \cs_gset:Npn \@@_codepoint_from_chars:Nw #1 + { + \token_if_jachar:NTF #1 + { \@@_codepoint_from_chars_jachar:N } + { \@@_codepoint_from_chars_non_jachar:Nw } + #1 + } + \cs_new:Npn \@@_codepoint_from_chars_jachar:N #1 + { \tex_toucs:D `#1 ~ } + } +% \end{macrocode} +% +% \subsubsection{Fix for the case-change funcrtions} +% +% Do not change case of jachar. +% \begin{macrocode} +\bool_lazy_or:nnT + { \sys_if_engine_ptex_p: } + { \sys_if_engine_uptex_p: } + { + \cs_new_eq:NN \@@_change_case_codepoint_lower_non_jachar:nnn + \@@_change_case_codepoint_lower:nnn + \cs_new_eq:NN \@@_change_case_codepoint_upper_non_jachar:nnn + \@@_change_case_codepoint_upper:nnn + \cs_new_eq:NN \@@_change_case_codepoint_title_non_jachar:nnn + \@@_change_case_codepoint_title:nnn + \cs_new_eq:NN \@@_change_case_codepoint_titleonly_non_jachar:nnn + \@@_change_case_codepoint_titleonly:nnn + \cs_gset:Npn \@@_change_case_codepoint_lower:nnn #1#2#3 + { \@@_change_case_codepoint_jachar:nnnn {#1} {#1} {#2} {#3} } + \cs_gset:Npn \@@_change_case_codepoint_upper:nnn #1#2#3 + { \@@_change_case_codepoint_jachar:nnnn {#1} {#1} {#2} {#3} } + \cs_gset:Npn \@@_change_case_codepoint_title:nnn #1#2#3 + { \@@_change_case_codepoint_jachar:nnnn {#1} { lower } {#2} {#3} } + \cs_gset:Npn \@@_change_case_codepoint_titleonly:nnn #1#2#3 + { \@@_change_case_codepoint_jachar:nnnn {#1} { end } {#2} {#3} } + \cs_new:Npn \@@_change_case_codepoint_jachar:nnnn #1#2#3#4 + { + \bool_lazy_and:nnTF + { \tl_if_single_p:n {#4} } + { \token_if_jachar_p:N #4 } + { + \@@_change_case_store:n {#4} + \use:c { @@_change_case_next_ #2 :nn } {#2} {#3} + } + { \use:c { @@_change_case_codepoint_ #1 _non_jachar:nnn } {#1} {#3} {#4} } + } + } +% \end{macrocode} +% +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex