[latex3-commits] [git/LaTeX3-latex3-latex3] tex-interaction: Implement \sys_interact: to mimick TeX's interactive mode [WIP] (1bb3757f9)
PhelypeOleinik
tex.phelype at gmail.com
Sun Aug 23 20:58:46 CEST 2020
Repository : https://github.com/latex3/latex3
On branch : tex-interaction
Link : https://github.com/latex3/latex3/commit/1bb3757f96be075b260ae4ce04578a96a588d3ee
>---------------------------------------------------------------
commit 1bb3757f96be075b260ae4ce04578a96a588d3ee
Author: PhelypeOleinik <tex.phelype at gmail.com>
Date: Sun Aug 23 15:58:46 2020 -0300
Implement \sys_interact: to mimick TeX's interactive mode [WIP]
>---------------------------------------------------------------
1bb3757f96be075b260ae4ce04578a96a588d3ee
l3kernel/l3sys.dtx | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
diff --git a/l3kernel/l3sys.dtx b/l3kernel/l3sys.dtx
index 61083db17..f5d5df1a8 100644
--- a/l3kernel/l3sys.dtx
+++ b/l3kernel/l3sys.dtx
@@ -955,6 +955,155 @@
% \end{macrocode}
% \end{variable}
%
+% \subsection{Emulating \TeX's interactive mode}
+%
+% \begin{macro}{\sys_interact:}
+% This starts interaction but only in \cs{errorstopmode}.
+% A |?| prompt is printed and it waits for user input, then calls
+% \cs{@@_interact:n} on the first token.
+% \begin{macrocode}
+\cs_new_protected:Npn \sys_interact:
+ {
+ \int_compare:nNnT { \tex_interactionmode:D } = { 3 }
+ {
+ \tex_message:D { \iow_newline: ?!?! ~ }
+ \ior_str_get_term:nN { } \l_@@_internal_tl
+ \exp_args:Nx \@@_interact:n { \tl_head:N \l_@@_internal_tl }
+ }
+ }
+% \cs{@@_interact:n} checks if the requested action exists; if not,
+% the action may be a number of tokens to delete, or invalid.
+\cs_new_protected:Npn \@@_interact:n #1
+ {
+ \cs_if_exist_use:cF { _@@_action_ \char_uppercase:N #1 : }
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+ \exp_after:wN \use_ii:nnn
+ \fi:
+ \use_ii:nn
+ { \@@_action_delete_tokens:n {#1} }
+ {
+ \@@_help_print:
+ \sys_interact:
+ }
+ }
+ }
+% No action:
+\cs_new_protected:Npn \@@_action_: { }
+% Enter scrollmode:
+\cs_new_protected:Npn \@@_action_S: { \tex_scrollmode:D }
+% Enter nonstopmode:
+\cs_new_protected:Npn \@@_action_R: { \tex_nonstopmode:D }
+% Enter batchmode:
+\cs_new_protected:Npn \@@_action_Q: { \tex_batchmode:D }
+% Insert tokens.
+% The token list was read as a string, so we need to rescan.
+% TODO: maybe everyhting has to be read with normal catcodes then
+% stringified to detect the action; no need to rescanning here
+% in that case...
+\cs_new_protected:Npn \@@_action_I:
+ {
+ \tl_set_rescan:Nnx \l_@@_internal_tl { }
+ { \tl_tail:N \l_@@_internal_tl }
+ \tl_use:N \l_@@_internal_tl
+ }
+% Edit the file.
+% Currently this uses \CurrentFile or \jobname, both of which are not
+% always true. I think primitive support is required to print the
+% correct file name here. Besides this doesn't open an editor as
+% TeX does. Is there even a way to do that?
+\cs_new_protected:Npn \@@_action_E:
+ {
+ \tex_message:D { You~want~to~edit~file }
+ \tex_message:D
+ {
+ \tl_if_empty:NTF \CurrentFile
+ { \c_sys_jobname_str }
+ { \CurrentFile }
+ }
+ \tex_message:D { at~line~\int_use:N \tex_inputlineno:D }
+ \@@_action_X:
+ }
+% Print \errhelp. I think this doesn't work exactly like TeX yet.
+\cs_new_protected:Npn \@@_action_H:
+ {
+ \tl_if_empty:oT { \tex_the:D \tex_errhelp:D }
+ {
+ \exp_args:Nx \tex_errhelp:D
+ {
+ Sorry,~I~already~gave~what~help~I~could... \iow_newline:
+ Maybe~you~should~try~asking~a~human? \iow_newline:
+ An~error~might~have~occurred~
+ before~I~noticed~any~problems. \iow_newline:
+ ``If~all~else~fails,~read~the~instructions.''
+ }
+ }
+ \tex_message:D { \tex_the:D \tex_errhelp:D }
+ \tex_errhelp:D = { }
+ \sys_interact:
+ }
+% Exit. At least this one works... kinda
+\cs_new_protected:Npn \@@_action_X:
+ { \tex_batchmode:D \tex_read:D -1~to~\l_@@_internal_tl }
+% Delete up to 99 tokens
+\int_new:N \l_@@_internal_int
+\cs_new_protected:Npn \@@_action_delete_tokens:n #1
+ {
+ \exp_args:Nx \@@_action_delete_tokens:nn
+ { \tl_item:Nn \l_@@_internal_tl { 2 } } {#1}
+ }
+% TeX ignores the second input token if not a number
+\cs_new_protected:Npn \@@_action_delete_tokens:nn #1 #2
+ {
+ \if_int_compare:w 9 < 1 \token_to_str:N #1 \exp_stop_f:
+ \int_set:Nn \l_@@_internal_int {#2#1}
+ \else:
+ \int_set:Nn \l_@@_internal_int {#2}
+ \fi:
+ \@@_action_delete_tokens_loop:w
+ }
+% Recursively delete tokens using \verb*|\let\tmp= |. Needs checking
+% how well this performs with different types of tokens and inside
+% alignments.
+\cs_new_protected:Npn \@@_action_delete_tokens_loop:w
+ {
+ \tex_message:D { >~\token_to_meaning:N \l_@@_internal_tl ^^J }
+ \int_compare:nNnTF \l_@@_internal_int = 0
+ { \@@_action_delete_tokens_end:w }
+ { \int_decr:N \l_@@_internal_int }
+ \tex_afterassignment:D \@@_action_delete_tokens_loop:w
+ \tex_let:D \l_@@_internal_tl = ~
+ }
+% At the end set the error help and call for interaction again.
+% After deleting a bunch of tokens TeX does |show_context|. Is it
+% possible to do that without raising another error?
+\cs_new_protected:Npn \@@_action_delete_tokens_end:w #1 = ~
+ {
+ \exp_args:Nx \tex_errhelp:D
+ {
+ I~have~just~deleted~some~text,~as~you~asked. \iow_newline:
+ You~can~now~delete~more,~or~insert,~or~whatever.
+ }
+ \sys_interact:
+ }
+% Help message
+\cs_new_protected:Npn \@@_help_print:
+ {
+ \tex_message:D
+ {
+ Type~<return>~to~proceed,~
+ S~to~scroll~future~error~messages, \iow_newline:
+ R~to~run~without~stopping,~
+ Q~to~run~quietly, \iow_newline:
+ I~to~insert~something,~
+ E~to~edit~your~file, \iow_newline:
+ 1~or~...~or~9~to~ignore~the~next~1~to~9~tokens~of~input, \iow_newline:
+ H~for~help,~
+ X~to~quit.
+ }
+ }
+% \end{macrocode}
+%
% \begin{macrocode}
%</package>
% \end{macrocode}
More information about the latex3-commits
mailing list.