summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/prettytok/prettytok.sty
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/prettytok/prettytok.sty')
-rw-r--r--macros/latex/contrib/prettytok/prettytok.sty729
1 files changed, 137 insertions, 592 deletions
diff --git a/macros/latex/contrib/prettytok/prettytok.sty b/macros/latex/contrib/prettytok/prettytok.sty
index e17eb204c6..3acea38c62 100644
--- a/macros/latex/contrib/prettytok/prettytok.sty
+++ b/macros/latex/contrib/prettytok/prettytok.sty
@@ -11,659 +11,204 @@
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is user202729.
-\RequirePackage{expl3}
-\ProvidesExplPackage{prettytok}{2022/05/28}{0.0.0}{Pretty-print token list}
-
-
-
-
-
-\@ifpackagelater{expl3}{2022/04/10} % https://github.com/latex3/latex3/blob/main/l3kernel/CHANGELOG.md#2022-04-10
- {
- }
-
- {
-
-\cs_set_protected:Npn \tl_analysis_map_inline:Nn #1
- { \exp_args:No \tl_analysis_map_inline:nn #1 }
-\cs_set_protected:Npn \tl_analysis_map_inline:nn #1
- {
- \__tl_analysis:n {#1}
- \int_gincr:N \g__kernel_prg_map_int
- \exp_args:Nc \__tl_analysis_map:Nn
- { _tl_analysis_map_inline_ \int_use:N \g__kernel_prg_map_int :wNw }
- }
-\cs_set_protected:Npn \__tl_analysis_map:Nn #1#2
- {
- \cs_gset_protected:Npn #1 ##1##2##3 {#2}
- \exp_after:wN \__tl_analysis_map:NwNw \exp_after:wN #1
- \g__tl_analysis_result_tl
- \s__tl { ? \tl_map_break: } \s__tl
- \prg_break_point:Nn \tl_map_break:
- { \int_gdecr:N \g__kernel_prg_map_int }
- }
-\cs_set_protected:Npn \__tl_analysis_map:NwNw #1 #2 \s__tl #3 #4 \s__tl
- {
- \use_none:n #3
- #1 {#2} {#4} {#3}
- \__tl_analysis_map:NwNw #1
- }
-
- }
-
-\cs_generate_variant:Nn \EI_append:n {x}
-\cs_generate_variant:Nn \int_compare:nNnTF {VNnTF}
-\cs_generate_variant:Nn \tl_set:Nn {Nx}
-\cs_generate_variant:Nn \int_compare:nNnT {VNnT}
-\cs_generate_variant:Nn \cs_if_exist_use:NT {cT}
-
-% ======== define handler functions.
-% a few things it can do:
-% • \tl_build_gput_right:Nn to \_EIresult (content being put there must be wrapped in \unexpanded i.e. x-expand to the desired result
-
-\cs_set_protected:Npn \EI_append_raw:n #1 {
- \tl_build_gput_right:Nn \_EIresult {#1}
-}
-
-\cs_set_protected:Npn \EI_append:n #1 {
- \EI_append_raw:n {\exp_not:n {#1}}
-}
-
-
-% handler can call this to collect following tokens in the input stream as argument.
-% #1: the function to pass argument in. (arguments are passed as brace-hack-included)
-% #2: number of arguments
-\cs_set_protected:Npn \EI_collect_arg:Nn #1 #2 {
- \def \_EIcollecting_balanced {#2}
- \def \_EIbalance_level {0}
- \tl_build_gbegin:N \_EIbalanced_content
- \tl_build_gput_right:Nn \_EIbalanced_content {\noexpand #1}
-}
-
-\cs_set_protected:Npn \EIhandler_EIexpand {
- \EI_collect_arg:Nn \EI_append:x {1}
-}
-
-\cs_set_protected:Npn \EIhandler_EIexecute {
- \EI_collect_arg:Nn \use:n {1}
-}
-
-\cs_set_protected:Npn \execinsideprepare:n #1 {
- \tl_build_gbegin:N \_EIresult
- \def \_EIcollecting_balanced {0}
- \tl_analysis_map_inline:nn {#1} {
- % reminder: ##1: token, ##2: char code (int), ##3: cat code (hex digit)
+\ProvidesExplPackage{prettytok}{2022/07/08}{0.0.1}{Pretty-print token list}
+\RequirePackage{precattl}
- \int_compare:VNnTF \_EIcollecting_balanced > 0 {
- % collecting content.
- \tl_build_gput_right:Nn \_EIbalanced_content {##1}
- \str_case:nn {##3} {
- {1} { \tl_set:Nx \_EIbalance_level {\_EIbalance_level+1} }
- {2} { \tl_set:Nx \_EIbalance_level {\_EIbalance_level-1} }
- }
-
- % we check this every time instead of only after egroup tokens...
- % so that if there's exactly one token to be collected it's still correctly passed through
- \int_compare:nNnT {\_EIbalance_level} = {0} {
-
- % done, call handler function and revert to normal mode.
-
- \tl_set:Nx \_EIcollecting_balanced {\int_eval:n{\_EIcollecting_balanced-1}}
- \int_compare:VNnT \_EIcollecting_balanced = 0 {
- \tl_build_gend:N \_EIbalanced_content
- \tl_set:Nx \_EIbalanced_content {\_EIbalanced_content}
- %\pretty:V \_EIbalanced_content
- \_EIbalanced_content % ← the handler function is embedded in here
- %\pretty:n {done}
- }
- }
- } {
- \let \_EIprocessed \c_false_bool
-
- % check for \EIexecute etc. and handle accordingly.
- \int_compare:nNnT {##2} = {-1} {
- \cs_if_exist_use:cT {
- EIhandler_ \expandafter \cs_to_str:N ##1
- } {
- \let \_EIprocessed \c_true_bool
- }
- }
+% ======== check tl_analysis bug.
+\msg_new:nnn {prettytok} {tl-analysis-bug}
+ {
+ Because~of~an~tl-analysis~bug~(see~https://github.com/latex3/latex3/issues/1073),~functions~will~not~be~usable~inside~tl-analysis~functions!~
+ Upgrade~your~LaTeX~version,~or~
+ define~macro~"prettyignoretlanalysisbug"~before~loading~the~package~to~ignore~this~error.
+ }
- % if not, just append to result.
- \bool_if:NF \_EIprocessed {
- \tl_build_gput_right:Nn \_EIresult {##1}
- }
+\ifdefined \prettyignoretlanalysisbug
+ \relax
+\else
+\begingroup
+ \tl_set:Nn \__test {}
+ \tl_analysis_map_inline:nn {ab} {
+ \tl_analysis_map_inline:nn {cd} {
+ \tl_put_right:Nx \__test {#1 ##1 .}
}
}
-
- \tl_build_gend:N \_EIresult
- \tl_set:Nx \_EIresult {\_EIresult}
-}
-
-\cs_set_protected:Npn \execinside:n #1 {
- \execinsideprepare:n {#1}
- \_EIresult
-}
-\let\execinside\execinside:n % normal-catcode alias
-
-\cs_set_protected:Npn \execinside_set:Nn #1 #2 {
- \execinsideprepare:n {#2}
- \let #1 \_EIresult
-}
-\let\execinsideSet\execinside_set:Nn
-
-\cs_set_protected:Npn \execinside_gset:Nn #1 #2 {
- \execinsideprepare:n {#2}
- \global \let #1 \_EIresult
-}
-\let\execinsideGset\execinside_gset:Nn
-
-\cs_generate_variant:Nn \exp_args:NN {Nc}
-\cs_generate_variant:Nn \EI_append:n {x}
-\cs_generate_variant:Nn \exp_args:Nn {No}
-\cs_generate_variant:Nn \EI_append:n {o}
-\cs_generate_variant:Nn \tl_put_right:Nn {Nx}
-\cs_generate_variant:Nn \use:nn {nV}
-\cs_generate_variant:Nn \execinside_set:Nn {NV}
-
-
-\def \_precattlappend_space #1 {
- \begingroup
- \lccode `\ =#1
- \lowercase{
- \def\_precattltmp{\endgroup \EI_append:n {~}}
+ \tl_if_eq:NnF \__test {ac.ad.bc.bd.} {
+ \msg_error:nn {prettytok} {tl-analysis-bug}
}
- \_precattltmp
-}
-
-\begingroup
-
-
-\global\def \_precattlappend_begin #1 {
- \begingroup
- \lccode `\{=#1
- \lowercase{\endgroup \EI_append_raw:n { \iftrue { \else } \fi }}
-}
-\global\def \_precattlappend_end #1 {
- \begingroup
- \lccode `\}=#1
- \lowercase{\endgroup \EI_append_raw:n { \iffalse { \else } \fi }}
-}
\endgroup
-
-\def \_precattldo_special_cC #1 { \exp_args:Nc \EI_append:n {#1} }
-\def \_precattldo_special_cB #1 { \str_map_inline:nn {#1} { \_precattlappend_begin {`##1} } }
-\def \_precattldo_special_cE #1 { \str_map_inline:nn {#1} { \_precattlappend_end {`##1} } }
-\def \_precattldo_special_cM #1 { \str_map_inline:nn {#1} { \EI_append:x {\char_generate:nn {`##1} {3}} } }
-\def \_precattldo_special_cT #1 { \str_map_inline:nn {#1} { \EI_append:x {\char_generate:nn {`##1} {4}} } }
-\def \_precattldo_special_cP #1 { \str_map_inline:nn {#1} { \exp_args:No \EI_append:o {\char_generate:nn {`##1} {6}} } }
-\def \_precattldo_special_cU #1 { \str_map_inline:nn {#1} { \EI_append:x {\char_generate:nn {`##1} {7}} } }
-\def \_precattldo_special_cD #1 { \str_map_inline:nn {#1} { \EI_append:x {\char_generate:nn {`##1} {8}} } }
-\def \_precattldo_special_cS #1 { \str_map_inline:nn {#1} { \_precattlappend_space {`##1} } }
-\def \_precattldo_special_cL #1 { \str_map_inline:nn {#1} { \EI_append:x {\char_generate:nn {`##1} {11}} } }
-\def \_precattldo_special_cO #1 { \str_map_inline:nn {#1} { \EI_append:x {\char_generate:nn {`##1} {12}} } }
-\def \_precattldo_special_cA #1 { \str_map_inline:nn {#1} {
- \exp_args:No \EI_append:o {\char_generate:nn {`##1} {13}}
-} }
-
-
-
-\def \_precattldo_special #1 #2 {
- % given #1 e.g. \cO, #2 e.g. {abc}, append <abc> in OTHER catcode to EI.
- {
- \escapechar=-1
+\fi
- % let \_precattltmp be the concatenation of \string of all tokens within #2.
- \def \_precattltmp {}
- \tl_analysis_map_inline:nn {#2} {
- \tl_put_right:Nx \_precattltmp {\exp_after:wN \string ##1}
- }
-
- % then pass it to the specific handler.
- \exp_args:Nc \exp_args:NV {_precattldo_special_\string #1} \_precattltmp
+% ======== load Lua module.
+\sys_if_engine_luatex:T{
+ \directlua{require("prettytok")}
+ \precattl_exec:n {
+ \directlua{prettyprint_frozenrelaxtok=token.get_next().tok}\cFrozenRelax
}
}
-\def \_precattldo_special_cC_outer { \_precattldo_special\cC }
-\def \_precattldo_special_cB_outer { \_precattldo_special\cB }
-\def \_precattldo_special_cE_outer { \_precattldo_special\cE }
-\def \_precattldo_special_cM_outer { \_precattldo_special\cM }
-\def \_precattldo_special_cT_outer { \_precattldo_special\cT }
-\def \_precattldo_special_cP_outer { \_precattldo_special\cP }
-\def \_precattldo_special_cU_outer { \_precattldo_special\cU }
-\def \_precattldo_special_cD_outer { \_precattldo_special\cD }
-\def \_precattldo_special_cS_outer { \_precattldo_special\cS }
-\def \_precattldo_special_cL_outer { \_precattldo_special\cL }
-\def \_precattldo_special_cO_outer { \_precattldo_special\cO }
-\def \_precattldo_special_cA_outer { \_precattldo_special\cA }
-
-\def \_precattl_tmp_help #1 {
- \def \_precattl_do_frozen_relax { \EI_append:n {#1} }
- % #1 here will be substituted by the frozen relax
-}
-\expandafter \_precattl_tmp_help \ifnum0=0\fi
-\let \_precattl_tmp_help \undefined
-
-
-
-\def \precattl_prepare:n #1 {
- \begingroup
- \let \EIhandler_EIexpand \undefined
- \let \EIhandler_EIexecute \undefined
- \def \EIhandler_cC { \EI_collect_arg:Nn \_precattldo_special_cC_outer 1 }
- \def \EIhandler_cB { \EI_collect_arg:Nn \_precattldo_special_cB_outer 1 }
- \def \EIhandler_cE { \EI_collect_arg:Nn \_precattldo_special_cE_outer 1 }
- \def \EIhandler_cM { \EI_collect_arg:Nn \_precattldo_special_cM_outer 1 }
- \def \EIhandler_cT { \EI_collect_arg:Nn \_precattldo_special_cT_outer 1 }
- \def \EIhandler_cP { \EI_collect_arg:Nn \_precattldo_special_cP_outer 1 }
- \def \EIhandler_cU { \EI_collect_arg:Nn \_precattldo_special_cU_outer 1 }
- \def \EIhandler_cD { \EI_collect_arg:Nn \_precattldo_special_cD_outer 1 }
- \def \EIhandler_cS { \EI_collect_arg:Nn \_precattldo_special_cS_outer 1 }
- \def \EIhandler_cL { \EI_collect_arg:Nn \_precattldo_special_cL_outer 1 }
- \def \EIhandler_cO { \EI_collect_arg:Nn \_precattldo_special_cO_outer 1 }
- \def \EIhandler_cA { \EI_collect_arg:Nn \_precattldo_special_cA_outer 1 }
- \let \EIhandler_cFrozenRelax \_precattl_do_frozen_relax
- \execinside_gset:Nn \_precattlvalueg {#1}
- \endgroup
- \let \_precattlvalue \_precattlvalueg
-}
-
-\def \precattl_set:Nn #1 #2 {
- \precattl_prepare:n {#2}
- \tl_set_eq:NN #1 \_precattlvalue
-}
-\let\precattlSet\precattl_set:Nn
-
-\def \precattl_exec:n #1 {
- \precattl_prepare:n {#1}
- \_precattlvalue
-}
-\let\precattlExec\precattl_exec:n
-
-
-
-
-
-\RequirePackage{filecontentsdef}
-
-%\sys_if_engine_luatex:T{\directlua{require("prettytok")}}
-
-% usage: \pretty:n, etc.
+% ======== main code start.
\cs_generate_variant:Nn \exp_args:NNn {NNx}
\cs_generate_variant:Nn \iow_open:Nn {NV}
\cs_generate_variant:Nn \exp_args:NNn {NNV}
\cs_generate_variant:Nn \iow_now:Nn {Nx}
\cs_generate_variant:Nn \tl_if_eq:nnF {xoF}
+\cs_generate_variant:Nn \tl_if_eq:nnTF {o}
\cs_generate_variant:Nn \use:N {c}
\cs_generate_variant:Nn \str_map_inline:nn {xn}
\cs_generate_variant:Nn \tl_build_put_right:Nn {Nx}
\cs_generate_variant:Nn \iow_now:Nn {NV}
-\iow_new:N \__prettyh_file
+\iow_new:N \_prettytok_file
+\ior_new:N \_prettytok_input_template_file
+
+
\exp_args:NNx \providecommand \prettyfilename {pretty-\jobname.html}
\providecommand \prettyrefreshstrategy {4}
\providecommand \prettyrefreshduration {1000}
+\msg_new:nnn {prettytok} {already-initialized} {Output~file~is~already~initialized!}
-\cs_new_protected:Npn \pretty:n #1 {
-
- % ======== first write out the preamble if it isn't written. Only do once. Delete the preamble macro if it's already written.
- \cs_if_exist:NT \prettypreamble {
- \iow_open:NV \__prettyh_file \prettyfilename
- {
- \str_set:NV \prettypreamble \prettypreamble
- \precattl_exec:n {
- \str_replace_all:Nnn \prettypreamble {\cO\^^M} {\cO\^^J}
- }
- \iow_now:NV \__prettyh_file \prettypreamble
- \iow_now:Nx \__prettyh_file {set_refresh_strategy(\prettyrefreshstrategy,\prettyrefreshduration)}
- }
- \cs_undefine:N \prettypreamble
- }
-
- % ======== the actual content. Collect to one \write to put them on the same line (also maybe for efficiency???)
- \tl_build_begin:N \__prettyh_content
- \tl_build_put_right:Nn \__prettyh_content {print_tl(}
- \tl_analysis_map_inline:nn {#1} {
- % by documentation of \tl_analysis_map_inline:nn: #1=token, #2=char code, #3=catcode
- \int_compare:nNnTF {##2} = {-1} {
- % token is control sequence
- \tl_build_put_right:Nn \__prettyh_content {cs(}
- \tl_if_eq:xoF {\use:c {}} {##1} {
- \str_map_inline:xn {\exp_after:wN \cs_to_str:N ##1} { % side note, must use str here to preserve spaces
- \tl_build_put_right:Nx \__prettyh_content {\int_eval:n {`####1},}
- }
- }
- \tl_build_put_right:Nn \__prettyh_content {),}
- }
- {
- % token is not control sequence
- \tl_build_put_right:Nn \__prettyh_content {token(##2, "##3"),}
- }
- }
- \tl_build_put_right:Nn \__prettyh_content {)//</script><script>}
- \tl_build_end:N \__prettyh_content
- \iow_now:NV \__prettyh_file \__prettyh_content
-}
-
-\cs_new_protected:Npn \pretty:w #1 \prettystop {
- \pretty:n {#1}
-}
-\cs_generate_variant:Nn \pretty:n {x, o, V}
-\let \pretty:N \pretty:n
+% See also Lua function: local function check_file_opened()
-% normal-catcode alias
-\let\prettyN\pretty:n
-\let\prettyX\pretty:x
-\let\prettyO\pretty:o
-\let\prettyV\pretty:V
+\global\let \pretty_check_already_init: \relax
-\cs_generate_variant:Nn \pretty:N {c}
+\precattl_exec:n {
+ \cs_new_protected:Npn \_prettyinit_unchecked: {
+ \global\protected\def \pretty_check_already_init: {\msg_error:nn {prettytok} {already-initialized}}
-\cs_new_protected:Nn \pretty:nn {
- \pretty:n {#1}
- \pretty:n {#2}
-}
+ \iow_open:NV \_prettytok_file \prettyfilename
-\cs_new_protected:Nn \pretty:nnn {
- \pretty:n {#1}
- \pretty:n {#2}
- \pretty:n {#3}
-}
-
-\cs_new_protected:Nn \pretty:nnnn {
- \pretty:n {#1}
- \pretty:n {#2}
- \pretty:n {#3}
- \pretty:n {#4}
-}
-
-\cs_new_protected:Nn \prettyshow:N {
- \exp_args:No \pretty:n {\meaning #1}
-}
-\let\prettyshowN\prettyshow:N
-
-
-
-
-
-\ExplSyntaxOff
-\begin{filecontentsdefmacro}{\prettypreamble}
-<!doctype html>
-<html lang="en">
-<head>
-<meta charset="utf-8">
-<link rel="icon" href="data:,">
-<style>
-body{
- background-color: black;
- color: white;
-}
-
-/* https://stackoverflow.com/questions/7011602/stretching-iframe-in-html5 */
-#wrap_all { display: none; position:fixed; width:100%; height:100%; top: 0px; left: 0px; }
-
-
-iframe{
- position: absolute;
- width: 100%;
- height: 100%;
- display: none;
-}
-#status{
- flex: 0 0 1.3em;
-}
+ % write the template
+ \begingroup
+ \ior_open:Nn \_prettytok_input_template_file {prettytok_template.html}
+ \ior_str_map_variable:NNn \_prettytok_input_template_file \_prettytok_line {
+ \str_replace_all:Nnn \_prettytok_line {\cO\^^I} {~} % workaround: XeTeX prints literal tab character as ^^I which obviously breaks JavaScript
+ \iow_now:NV \_prettytok_file \_prettytok_line
+ }
+ \ior_close:N \_prettytok_input_template_file
+ \endgroup
-#display_wrap{
- flex: 1 0 auto;
-}
-#controller{
- flex: 0 0 50px;
-}
+ % refresh strategy
+ \iow_now:Nx \_prettytok_file {set_refresh_strategy(\prettyrefreshstrategy,\prettyrefreshduration)}
+ }
-.control-button{
+ \cs_new_protected:Npn \prettyinit: {
+ \pretty_check_already_init:
+ \_prettyinit_unchecked:
+ }
}
+\cs_new_eq:NN \prettyinit \prettyinit:
-.tokenlist, .fileline{
- border: 1px solid gray;
- height: 2em;
- overflow: scroll;
- white-space: nowrap;
-}
-.tokenlist::-webkit-scrollbar, .fileline::-webkit-scrollbar { width: 0 !important }
+\precattl_exec:n {
-.fileline{
- background-color: #404040;
-}
-.explicit_char_target{
- background-color: #FF8080;
-}
-.explicit_char{
- background-color: #606060;
-}
+ \cs_new_protected:Npn \pretty:n #1 {
+ % ======== first write out the preamble if it isn't written. Only do once.
+ \ifx \pretty_check_already_init: \relax \prettyinit: \fi
-.cs, .active_char{
- color: #FFFF00;
-}
-.cs::before{
- content: "\\";
-}
-.cs::after{
- content: " ";
+ % ======== the actual content. Collect to one \write to put them on the same line (also maybe for efficiency???)
+ \tl_build_begin:N \_prettytok_content
+ \tl_build_put_right:Nn \_prettytok_content {print_tl(}
+ \tl_analysis_map_inline:nn {#1} {
+ % by documentation of \tl_analysis_map_inline:nn: #1=token, #2=char code, #3=catcode
+ \int_compare:nNnTF {##2} = {-1} {
+ % token is control sequence
+ \tl_if_eq:onTF {##1} {\cFrozenRelax} {
+ \tl_build_put_right:Nn \_prettytok_content {csfrozenrelax(),}
+ } {
+ \tl_build_put_right:Nn \_prettytok_content {cs(}
+ \tl_if_eq:xoF {\use:c {}} {##1} {
+ \str_map_inline:xn {\exp_after:wN \cs_to_str:N ##1} { % side note, must use str here to preserve spaces
+ \tl_build_put_right:Nx \_prettytok_content {\int_eval:n {`####1},}
+ }
+ }
+ \tl_build_put_right:Nn \_prettytok_content {),}
+ }
+ }
+ {
+ % token is not control sequence
+ \tl_build_put_right:Nn \_prettytok_content {token(##2, "##3"),}
+ }
+ }
+ \tl_build_put_right:Nn \_prettytok_content {)//</script><script>}
+ \tl_build_end:N \_prettytok_content
+ \iow_now:NV \_prettytok_file \_prettytok_content
+ }
}
-#popup{
- display: none;
- position: absolute;
- border: 1px solid gray;
- background-color: #000080ff;
-}
+% ======== Lua expandable variant.
+\sys_if_engine_luatex:T {
+ \cs_new:Npn \prettye:n #1 {
+ \directlua{prettyprint(token.scan_toks())}{#1}
+ }
-.cmd__left_brace_cmd, .cmd__right_brace_cmd, .cmd__mac_param_cmd{
- color: #FFAAAA;
-}
-.cmd__out_param_cmd{
- border: 1px solid #FFAAAA;
-}
-.out_param_expansion{
- border: 1px solid #FFAAAA;
- background-color: #000080;
-}
-.cmd__out_param_cmd::before{
- content: "#";
+ \cs_new:Npn \prettye:w {
+ \directlua{prettyprintw()} {}
+ }
+ \cs_new:Npn \prettye:nw #1 {
+ \directlua{prettyprintw()} {#1}
+ }
}
-.cmd__letter_cmd{
- color: #AAFFAA;
+\cs_new_protected:Npn \pretty:w #1 \prettystop {
+ \pretty:n {#1} #1 \prettystop
}
-.cmd__spacer_cmd{
- color: #808080;
-}
+\cs_new:Npn \prettystop {}
+\cs_generate_variant:Nn \pretty:n {x, o, V}
+\let \pretty:N \pretty:n
-input[type=button]{
- color: white;
- background-color: #0000ff;
- border: 0;
-}
+% ======== normal-catcode alias
+\let\prettyN\pretty:n
+\let\prettyX\pretty:x
+\let\prettyO\pretty:o
+\let\prettyV\pretty:V
+\let\prettyeN\prettye:n
+\let\prettyeW\prettye:w
-#log{
- display: flex;
- flex-direction: column-reverse;
- flex: 0 0 30%;
- overflow: scroll;
-}
-</style>
-</head>
-<body>
-
- <div id=output></div>
- <div id=wrap_all>
- <iframe id=iframe src="about:blank" frameborder=0></iframe>
- <iframe id=iframe2 src="about:blank" frameborder=0></iframe>
- </div>
- <script>
-"use strict"
-function show_html(s){
- return s.replace(/ /g, "␣")
- .replace(/\r|\n/g, "↵")
- .replace(/\t/g, "⇥")
-}
+\cs_generate_variant:Nn \pretty:N {c}
-output.innerHTML=""
-function print_tl(...tokens){
- const tl_div=document.createElement("div")
- tl_div.className="tokenlist"
- for(let token of tokens){
- tl_div.appendChild(token)
+% ======== generate \pretty:nn, \pretty:nnn, etc.
+\begingroup
+ \def \__tmp:NN #1 #2 { % #1: example \pretty:nn, #2: example \pretty:n (the latter has one more n than the former)
+ \cs_new_protected:Npn #1 ##1 ##2 { #2 {##1 ##2} }
}
- output.appendChild(tl_div)
-}
+ \cs_generate_variant:Nn \__tmp:NN {cc}
-function token(charcode /* single character string in hex */, catcode /* integer */){
- const token_span=document.createElement("span")
- const ch=String.fromCodePoint(charcode)
- token_span.innerText=show_html(ch)
- if(catcode==='D'){
- token_span.className="active_char"
- token_span.title=`active ${ch} # ${charcode}`
- }else{
- const cls={
- 1: 'cmd__left_brace_cmd',
- 2: 'cmd__right_brace_cmd',
- 3: 'cmd__math_shift_cmd',
- 4: 'cmd__tab_mark_cmd',
- 6: 'cmd__mac_param_cmd',
- 7: 'cmd__sup_mark_cmd',
- 8: 'cmd__sub_mark_cmd',
- A: 'cmd__spacer_cmd',
- B: 'cmd__letter_cmd',
- C: 'cmd__other_char_cmd',
- }[catcode]
- token_span.className="token "+cls
- token_span.title=`${cls} ${ch} # ${charcode}`
+ \def \__tmp {pretty:n}
+ \int_step_inline:nn {9} {
+ \__tmp:cc {\__tmp n} {\__tmp}
+ \tl_put_right:Nn \__tmp {n}
}
- return token_span
-}
-
-function cs(...codepoints){
- const token_span=document.createElement("span")
- const control_sequence_name=String.fromCodePoint(...codepoints)
- //const meaning_str=readstr()
+ \sys_if_engine_luatex:T {
+ \def \__tmp:NN #1 #2 { % #1: example \prettye:nn, #2: example \prettye:n (the latter has one more n than the former)
+ \cs_new:Npn #1 ##1 ##2 { #2 {##1 ##2} }
+ }
+ \def \__tmp {prettye:n}
+ \int_step_inline:nn {9} {
+ \__tmp:cc {\__tmp n} {\__tmp}
+ \__tmp:cc {\__tmp nw} {\__tmp w}
+ \tl_put_right:Nn \__tmp {n}
+ }
+ }
+\endgroup
- token_span.innerText=show_html(control_sequence_name)
- //token_span.title=`cs '${control_sequence_name}' → ${meaning_str}`
- token_span.className="cs"
- return token_span
+\cs_new_protected:Nn \prettyshow:N {
+ \exp_args:No \pretty:n {\meaning #1}
}
+\cs_generate_variant:Nn \prettyshow:N {c}
+\let\prettyshowN\prettyshow:N
+\let\prettyshowC\prettyshow:c
-var refresh_strategy_already_set=false
-function set_refresh_strategy(strategy, duration){
- if(refresh_strategy_already_set) return
- refresh_strategy_already_set=true
-
- switch(strategy){
- case 0: // do nothing
- return
-
- case 1: // refresh the sub-iframe
- if(window.parent===window){
- print_tl=function(...x) {}
- //output.style.display="none"
- iframe.src=location.href
- iframe.style.display="block"
- wrap_all.style.display="block"
- setInterval(function(){
- iframe.src=iframe.src
- }, duration)
- }
- return
-
- case 2: // refresh two sub-iframes
- if(window.parent===window){
- print_tl=function(...x) {}
- //output.style.display="none"
- iframe.src=iframe2.src=location.href
- iframe.style.display="block"
- iframe2.style.display="block"
- wrap_all.style.display="block"
- async function sleep(ms){
- await new Promise(resolve=>setTimeout(resolve, ms))
- }
- (async function(){
- while(true){
- await sleep(duration/2)
- iframe.src=iframe.src
-
- await sleep(duration/2)
- iframe2.style.zIndex=1
- iframe.style.zIndex=2
-
- await sleep(duration/2)
- iframe2.src=iframe2.src
-
- await sleep(duration/2)
- iframe.style.zIndex=1
- iframe2.style.zIndex=2
- }
- })()
- }
- return
-
- case 3: // refresh whole page
- setTimeout(function(){
- location.reload()
- }, duration)
- return
-
- case 4: // request own file
- window.addEventListener("load", async function(){
- async function get_code(){
- //let text=await (await fetch(location.href)).text()
- let text=await new Promise(function(resolve){
- let request = new XMLHttpRequest();
- request.responseType = "text"
- request.onload = function() {
- resolve(request.responseText)
- }
- request.onerror = function() {
- console.log("Error happened. Read documentation for more details.")
- }
- request.open("GET", location.href, true)
- request.send()
- })
- return text.replace(/.*?-end-template()-/s, "")
- }
- let text=await get_code()
- output.innerHTML=""
- try{ eval(text) }catch(e) {}
- setInterval(async function(){
- let text2=await get_code()
- if(text2!==text){
- output.innerHTML=""
- try{ eval(text2) }catch(e) {}
- text=text2
- }
- }, duration)
- })
- return
- }
-}
- </script>
-<script>
-// -end-template-
-\end{filecontentsdefmacro}
-\ExplSyntaxOn