diff options
author | Karl Berry <karl@freefriends.org> | 2023-04-18 19:40:32 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2023-04-18 19:40:32 +0000 |
commit | 421c46931938c705ca7c62437a5086ab6b0cfd8a (patch) | |
tree | 93b7c599956d37b6ca920a67e6bf8e236433b725 /Master/texmf-dist/tex | |
parent | e63869c62873cc3e4ab1a936a91117f26ae926a3 (diff) |
prettytok (18apr23)
git-svn-id: svn://tug.org/texlive/trunk@66884 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
4 files changed, 474 insertions, 397 deletions
diff --git a/Master/texmf-dist/tex/latex/prettytok/prettytok-decode-8bit.py b/Master/texmf-dist/tex/latex/prettytok/prettytok-decode-8bit.py new file mode 100755 index 00000000000..231cf84bd97 --- /dev/null +++ b/Master/texmf-dist/tex/latex/prettytok/prettytok-decode-8bit.py @@ -0,0 +1,12 @@ +#!/bin/python3 +""" +A hack to allow decoding for example ^^[ to the proper escape sequence. +""" + +import sys +import re +def replace_8bit(match_: re.Match) -> str: + return chr(ord(match_.group(1))^0x40) +if __name__ == '__main__': + for line in sys.stdin: + sys.stdout.write(re.sub(r"\^\^(.)", replace_8bit, line)) diff --git a/Master/texmf-dist/tex/latex/prettytok/prettytok.lua b/Master/texmf-dist/tex/latex/prettytok/prettytok.lua index a0aba072435..0abb6595f0e 100644 --- a/Master/texmf-dist/tex/latex/prettytok/prettytok.lua +++ b/Master/texmf-dist/tex/latex/prettytok/prettytok.lua @@ -6,8 +6,8 @@ end -- public API :: once the package is loaded, this holds the .tok value of the frozen relax token prettyprint_frozenrelaxtok=nil -local function prettyprint_one_arg(tokenlist) +local function prettyprint_one_arg(tokenlist) if looks_like_token(tokenlist) then return prettyprint_one_arg({tokenlist}) end @@ -46,8 +46,9 @@ local function prettyprint_one_arg(tokenlist) s=s.."csfrozenrelax()," else s=s.."cs(" - for j=1, #t.csname do - s=s..t.csname:byte(j).."," + -- TODO + for _, c in utf8.codes(t.csname) do + s=s..c.."," end s=s..")," end @@ -58,41 +59,192 @@ local function prettyprint_one_arg(tokenlist) return s end -local function check_file_opened() - -- if it's \relax then get_macro() also returns nil - if token.get_macro("pretty_check_already_init:") == nil then - error("Output file not initialized!") - end +local function get_output_format() + return token.get_macro "_prettytok_mode" end local function get_file_number() - check_file_opened() - return token.get_mode(token.create("__prettyh_file")) + return token.get_mode(token.create("_prettytok_file")) end function prettyprint(...) - local prettyfilenumber=get_file_number() - - local s="print_tl(" + local output_format=get_output_format() local args={...} - for i=1, select("#", ...) do - s=s..prettyprint_one_arg(args[i]) - end + if output_format=="html" then + local prettyfilenumber=get_file_number() + + local s="print_tl(" + for i=1, select("#", ...) do + s=s..prettyprint_one_arg(args[i]) + end + + texio.write(prettyfilenumber, s..")//</script><script>\n") + else + assert(output_format=="term-8bit" or output_format=="term-shell") + texio.write_nl("") + + local content="" + local content_len=0 -- only count visible content + + local function typeout_content() + print(content) + content="" + content_len=0 + end + + local function append_content(s) -- only call this on content that takes visible width. For example don't use this to set color + assert(type(s)=="string") + content=content..s + content_len=content_len+utf8.len(s) + end + + append_content(token.get_macro "prettytermprefix") + local wraplimit=tonumber(token.get_macro "prettytermwraplimit") + + ---- color + + --[[ + local gray ='\x1b[90m' + local red ='\x1b[31m' + local green ='\x1b[38;5;121m' + local yellow='\x1b[93m' + local white ='\x1b[0m' + ]] - texio.write(prettyfilenumber, s..")//</script><script>\n") + local gray =token.get_macro "_prettytok_gray" + local red =token.get_macro "_prettytok_red" + local green =token.get_macro "_prettytok_green" + local yellow=token.get_macro "_prettytok_yellow" + local white =token.get_macro "_prettytok_white" + + local current_color=white + local function setcolor(c) + if current_color~=c then + current_color=c + content=content..c + end + end + + local prettytermprefixmore=token.get_macro "prettytermprefixmore" + + local function check_wrap() + if content_len>wraplimit then + if current_color~=white then + content=content..white + end + print(content) + + content="" + content_len=0 + append_content(prettytermprefixmore) + if current_color~=white then + content=content..current_color + end + end + end + + local function prettyprint_term_one_arg(tokenlist) + if looks_like_token(tokenlist) then + return prettyprint_term_one_arg({tokenlist}) + end + + + local function print_term_char(code) + if code<27 then + if code==9 then + append_content("⇥") + else + append_content("^^"..string.char(code+64)) + if code==13 or code==10 then + typeout_content() + append_content(prettytermprefixmore) -- color the prefix with the same color + end + end + elseif code==32 then + append_content("␣") + else + append_content(utf8.char(code)) -- unlike TeX implementation currently this does not show ^^⟨hex digits⟩ representation + end + end + + + local function printstring(t) + -- this is just for debugging/convenience purpose. If the item is a string instead of a token... + t=tostring(t) + for _, c in utf8.codes(t) do + if c==32 then + setcolor(gray) + append_content("␣") + else + setcolor(white) + append_content(utf8.char(c)) + end + end + end + + if type(tokenlist)~="table" then + -- user give a string (or something similar). Print it as detokenized characters + printstring(tokenlist) + check_wrap() + + else + + -- normal print of tokenlist + for i=1, #tokenlist do + local t=tokenlist[i] + if not looks_like_token(t) then + printstring(t) + check_wrap() + elseif t.csname==nil then + setcolor(({left_brace=red, right_brace=red, math_shift=red, tab_mark=red, mac_param=red, sup_mark=red, sub_mark=red, spacer=gray, letter=green, other_char=white})[t.cmdname]) + print_term_char(t.mode) + check_wrap() + else + if t.active then + setcolor(yellow) + print_term_char(utf8.codepoint(t.csname)) + elseif t.tok==prettyprint_frozenrelaxtok then + setcolor(red) + append_content("\\relax ") + else + setcolor(yellow) + append_content("\\") + for _, c in utf8.codes(t.csname) do + print_term_char(c) + end + append_content(" ") + end + check_wrap() + end + end + + end + end + + for i=1, select("#", ...) do + prettyprint_term_one_arg(args[i]) + end + + setcolor(white) + + typeout_content() + end end function prettyprintw() - check_file_opened() + local callback=token.scan_toks() local extra=token.scan_toks() local s={} + local last_token while true do - local n=token.get_next() - s[#s+1]=n - if n.csname=="prettystop" then break end + last_token=token.get_next() + if last_token.csname=="prettystop" then break end + s[#s+1]=last_token + callback[#callback+1]=last_token end - prettyprint(extra, s) - token.put_next(s) + prettyprint(extra, s) -- exclude the \prettystop token + callback[#callback+1]=last_token + token.put_next(callback) end end diff --git a/Master/texmf-dist/tex/latex/prettytok/prettytok.sty b/Master/texmf-dist/tex/latex/prettytok/prettytok.sty index 3acea38c621..d12abc727d2 100644 --- a/Master/texmf-dist/tex/latex/prettytok/prettytok.sty +++ b/Master/texmf-dist/tex/latex/prettytok/prettytok.sty @@ -1,5 +1,5 @@ % File: prettytok.sty -% Copyright 2022 user202729 +% Copyright 2022-2023 user202729 % % This work may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this license or @@ -12,33 +12,60 @@ % % The Current Maintainer of this work is user202729. -\ProvidesExplPackage{prettytok}{2022/07/08}{0.0.1}{Pretty-print token list} +\ProvidesExplPackage{prettytok}{2023-04-18}{0.2.0}{Pretty-print token list} \RequirePackage{precattl} +\RequirePackage{l3keys2e} -% ======== 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. - } +\keys_define:nn{prettytok}{ + mode.choices:nn={ term-8bit, term-shell, html }{ + \str_set:Nx \_prettytok_mode {\l_keys_choice_tl} + }, + mode.initial:n = { term-8bit }, -\ifdefined \prettyignoretlanalysisbug - \relax -\else -\begingroup - \tl_set:Nn \__test {} + ignore-tlanalysis-bug.bool_set:N=\_prettytok_ignore_tlanalysis_bug, + + term-shell-decode-cmd.tl_set:N=\_prettytok_term_shell_decode_cmd, + term-shell-decode-cmd.initial:n={}, + term-shell-decode-cmd-print.bool_set:N=\_prettytok_term_shell_decode_cmd_print, + + html-file-name.tl_set:N=\_prettytok_html_file_name, + html-file-name.initial:x={pretty-\jobname.html}, + html-refresh-strategy.tl_set:N=\_prettytok_html_refresh_strategy, + html-refresh-strategy.initial:n=4, + html-refresh-duration.tl_set:N=\_prettytok_html_refresh_duration, + html-refresh-duration.initial:n=1000, + + term-prefix.tl_set:N=\prettytermprefix, + term-prefix.initial:n={>~}, + term-prefix-more.tl_set:N=\prettytermprefixmore, + term-prefix-more.initial:n={>~ ..~}, + term-wrap-limit.tl_set:N=\prettytermwraplimit, + term-wrap-limit.initial:n=70, + +} +\ProcessKeysOptions{prettytok} + + +% ======== check tl_analysis bug. +\bool_if:NF \_prettytok_ignore_tlanalysis_bug { + \tl_set:Nn \_prettytok_test {} \tl_analysis_map_inline:nn {ab} { \tl_analysis_map_inline:nn {cd} { - \tl_put_right:Nx \__test {#1 ##1 .} + \tl_put_right:Nx \_prettytok_test {#1 ##1 .} } } - \tl_if_eq:NnF \__test {ac.ad.bc.bd.} { + \tl_if_eq:NnF \_prettytok_test {ac.ad.bc.bd.} { + \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~ + pass-option~"ignore-tlanalysis-bug"~to~ignore~this~error. + } \msg_error:nn {prettytok} {tl-analysis-bug} } -\endgroup -\fi +} % ======== load Lua module. \sys_if_engine_luatex:T{ @@ -49,7 +76,6 @@ } % ======== 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} @@ -59,90 +85,241 @@ \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 \tl_build_put_right:Nn {NV} \cs_generate_variant:Nn \iow_now:Nn {NV} -\iow_new:N \_prettytok_file -\ior_new:N \_prettytok_input_template_file +\str_if_eq:VnTF \_prettytok_mode {html} { + \iow_new:N \_prettytok_file + \ior_new:N \_prettytok_input_template_file + + \iow_open:NV \_prettytok_file \_prettytok_html_file_name -\exp_args:NNx \providecommand \prettyfilename {pretty-\jobname.html} -\providecommand \prettyrefreshstrategy {4} -\providecommand \prettyrefreshduration {1000} + \precattl_exec:n{ + % write the template + \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 -\msg_new:nnn {prettytok} {already-initialized} {Output~file~is~already~initialized!} + % refresh strategy + \iow_now:Nx \_prettytok_file {set_refresh_strategy(\_prettytok_html_refresh_strategy,\_prettytok_html_refresh_duration)} + \cs_new_protected:Npn \pretty:n #1 { -% See also Lua function: local function check_file_opened() + % ======== 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 + } + } -\global\let \pretty_check_already_init: \relax +} { + \str_if_eq:VnTF \_prettytok_mode {term-shell} { + \newwrite \_prettytok_typeout_stream + \tl_if_empty:NTF \_prettytok_term_shell_decode_cmd { + \sys_get_shell:nnN {kpsewhich~ prettytok-decode-8bit.py} {\cctab_select:N \c_other_cctab} \_prettytok_term_shell_decode_cmd + } { + \begingroup + \escapechar=-1~ + \str_gset:NV \_prettytok_term_shell_decode_cmd \_prettytok_term_shell_decode_cmd + \endgroup + } + \bool_if:NT \_prettytok_term_shell_decode_cmd_print { + \typeout{^^JThe~ value~ of~ term-shell-decode-cmd~ is:~ [[[\_prettytok_term_shell_decode_cmd]]]^^J} + } + \immediate \openout \_prettytok_typeout_stream = {|\_prettytok_term_shell_decode_cmd} + } { + \int_const:Nn \_prettytok_typeout_stream {128} % 16 works except on LuaLaTeX + } -\precattl_exec:n { - \cs_new_protected:Npn \_prettyinit_unchecked: { - \global\protected\def \pretty_check_already_init: {\msg_error:nn {prettytok} {already-initialized}} - \iow_open:NV \_prettytok_file \prettyfilename + \precattl_exec:n{ + \str_gset:Nn \_prettytok_gray {\cO\^^[[90m} + \str_gset:Nn \_prettytok_red {\cO\^^[[31m} + \str_gset:Nn \_prettytok_green {\cO\^^[[38;5;121m} % this is the color vim use for green on my machine. Anyway~ + %\str_gset:Nn \_prettytok_green {\cO\^^[[92m} + \str_gset:Nn \_prettytok_yellow {\cO\^^[[93m} + %\str_gset:Nn \_prettytok_white {\cO\^^[[0m} % i.e. the default + \str_gset:Nn \_prettytok_white {\cO\^^[[97m} % vim terminal has a quirk that if a line wraps, the status at the start of the line is considered "default" for that line, so need to explicitly specify color as white - % 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 + % https://stackoverflow.com/q/4842424/5267751 - % refresh strategy - \iow_now:Nx \_prettytok_file {set_refresh_strategy(\prettyrefreshstrategy,\prettyrefreshduration)} + \cs_new_protected:Npn \_prettytok_setcolor:N #1 { + \ifx \_prettytok_current_color #1 + \else + \let \_prettytok_current_color #1 + \tl_build_put_right:NV \_prettytok_content #1 + \fi } - \cs_new_protected:Npn \prettyinit: { - \pretty_check_already_init: - \_prettyinit_unchecked: + % caller should call \_prettytok_check_wrap: when useful. + \cs_new_protected:Npn \_prettytok_term_prepare_print_char:n #1 { + \_prettytok_append_content:x { + \ifnum #1 < 27 ~ + \ifnum #1 = 9 ~ % tab + \cO{⇥} + \else + \cO{\^\^} \char_generate:nn {#1+64} {12} + \bool_if:nT {\int_compare_p:nNn {#1} = {13} || \int_compare_p:nNn {#1} = {10}} { + \cO{^^J} \prettytermprefixmore + } + \fi + \else + \ifnum #1 = 32 ~ + \cO{␣} + \else + \bool_if:nTF {\int_compare_p:nNn {#1} > {32} && \int_compare_p:nNn {#1} < {127}} { % printable ASCII character + \char_generate:nn {#1} {12} + } { + \ifnum #1 < "100 ~ + ^ ^ + \expandafter \@gobble \exp:w \exp_end_continue_f:w \int_to_hex:n {"100+#1} % convert to hex, exactly 2 digits (by adding 100 then delete first '1') + \else + \ifnum #1 < "10000 ~ + ^ ^ ^ ^ + \expandafter \@gobble \exp:w \exp_end_continue_f:w \int_to_hex:n {"10000+#1} % convert to hex, exactly 4 digits + \else + ^ ^ ^ ^ ^ ^ + \expandafter \@gobble \exp:w \exp_end_continue_f:w \int_to_hex:n {"1000000+#1} % convert to hex, exactly 6 digits + \fi + \fi + } + \fi + \fi + } } -} + \cs_generate_variant:Nn \_prettytok_term_prepare_print_char:n {x} -\cs_new_eq:NN \prettyinit \prettyinit: + \int_new:N \_prettytok_content_len + % only call this on content that takes visible width. For example don't use this to set color + \cs_new_protected:Npn \_prettytok_append_content:n #1 { + \tl_build_put_right:Nn \_prettytok_content {#1} + \int_add:Nn \_prettytok_content_len {\str_count:n {#1}} + } -\precattl_exec:n { + \cs_generate_variant:Nn \_prettytok_append_content:n {V,x} + + \cs_new_protected:Npn \_prettytok_check_wrap: { + \int_compare:nNnT {\_prettytok_content_len} > {\prettytermwraplimit} { + % be careful to not color the \prettytermprefixmore part + \ifx \_prettytok_current_color \_prettytok_white + \else + \tl_build_put_right:NV \_prettytok_content \_prettytok_white + \fi + \tl_build_end:N \_prettytok_content + \_prettytok_typeout_content: + + \tl_build_begin:N \_prettytok_content + \int_zero:N \_prettytok_content_len + \_prettytok_append_content:V \prettytermprefixmore + \ifx \_prettytok_current_color \_prettytok_white + \else + \tl_build_put_right:NV \_prettytok_content \_prettytok_current_color + \fi + } + } + % \_prettytok_content must have been called \tl_build_end:N on before this function is called + \sys_if_engine_luatex:TF { + \cs_new_protected:Npn \_prettytok_typeout_content: { + \directlua{ + texio.write_nl("") + print(token.get_macro("_prettytok_content")) + } % https://tex.stackexchange.com/questions/64462/lualatex-print-directlua-env-and-newlinehttps://tex.stackexchange.com/questions/64462/lualatex-print-directlua-env-and-newline + } + } { + \cs_new_protected:Npn \_prettytok_typeout_content: { + \immediate\write\_prettytok_typeout_stream{\_prettytok_content} + } + } \cs_new_protected:Npn \pretty:n #1 { + \tl_build_begin:N \_prettytok_content + \int_zero:N \_prettytok_content_len + \_prettytok_append_content:V \prettytermprefix - % ======== first write out the preamble if it isn't written. Only do once. - \ifx \pretty_check_already_init: \relax \prettyinit: \fi + \let \_prettytok_current_color \_prettytok_white - % ======== 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(),} + \_prettytok_setcolor:N \_prettytok_red + \_prettytok_append_content:n { \cO\\relax~ } } { - \tl_build_put_right:Nn \_prettytok_content {cs(} + \_prettytok_setcolor:N \_prettytok_yellow + \_prettytok_append_content:n { \cO\\ } \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},} + \_prettytok_term_prepare_print_char:x {\int_eval:n {`####1}} } } - \tl_build_put_right:Nn \_prettytok_content {),} + \_prettytok_append_content:n {~} + \_prettytok_check_wrap: % here we do not wrap in the middle of a csname } } { % token is not control sequence - \tl_build_put_right:Nn \_prettytok_content {token(##2, "##3"),} + \if ##3 B % letter + \_prettytok_setcolor:N \_prettytok_green + \else + \if ##3 A % spacer + \_prettytok_setcolor:N \_prettytok_gray + \else + \if ##3 D % active + \_prettytok_setcolor:N \_prettytok_yellow + \else + \if ##3 C % other cat + \_prettytok_setcolor:N \_prettytok_white + \else % something else. + \_prettytok_setcolor:N \_prettytok_red + \fi + \fi + \fi + \fi + + \_prettytok_term_prepare_print_char:n {##2} + \_prettytok_check_wrap: } } - \tl_build_put_right:Nn \_prettytok_content {)//</script><script>} + \_prettytok_setcolor:N \_prettytok_white \tl_build_end:N \_prettytok_content - \iow_now:NV \_prettytok_file \_prettytok_content + + \_prettytok_typeout_content: + } } + } + % ======== Lua expandable variant. \sys_if_engine_luatex:T { \cs_new:Npn \prettye:n #1 { @@ -150,65 +327,84 @@ } \cs_new:Npn \prettye:w { - \directlua{prettyprintw()} {} + \directlua{prettyprintw()} {} {} } \cs_new:Npn \prettye:nw #1 { - \directlua{prettyprintw()} {#1} + \directlua{prettyprintw()} {#1} {} + } + \cs_new:Npn \prettye:nnw #1 #2 { + \directlua{prettyprintw()} {#1} {#2} } } -\cs_new_protected:Npn \pretty:w #1 \prettystop { - \pretty:n {#1} #1 \prettystop -} +% ======== w variant. +\cs_new_protected:Npn \pretty:w { \pretty_aux:w \empty } +\cs_new_protected:Npn \pretty_aux:w #1 \prettystop { + \pretty:o { #1 } % use o-expansion to remove the \empty + #1 \prettystop +} \cs_new:Npn \prettystop {} +% ======== other variants. \cs_generate_variant:Nn \pretty:n {x, o, V} -\let \pretty:N \pretty:n +\cs_new_eq:NN \pretty:N \pretty:n +\cs_generate_variant:Nn \pretty:N {c} -% ======== 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 +\cs_new_protected:Npn \prettythenrun:n #1 { + \pretty:n {running~#1} + #1 + \pretty:n {done} +} +\cs_new_protected:Npn \prettythenrun:w #1 \prettythenrunstop { + \prettythenrun:n {#1} +} -\cs_generate_variant:Nn \pretty:N {c} +\cs_new_protected:Nn \prettyshow:N { \pretty:o {\meaning #1} } +\cs_generate_variant:Nn \prettyshow:N {c} % ======== 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) + \def \_prettytok_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} } } - \cs_generate_variant:Nn \__tmp:NN {cc} + \cs_generate_variant:Nn \_prettytok_tmp:NN {cc} - \def \__tmp {pretty:n} + \def \_prettytok_tmp {pretty:n} \int_step_inline:nn {9} { - \__tmp:cc {\__tmp n} {\__tmp} - \tl_put_right:Nn \__tmp {n} + \_prettytok_tmp:cc {\_prettytok_tmp n} {\_prettytok_tmp} + \tl_put_right:Nn \_prettytok_tmp {n} } \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) + \def \_prettytok_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} + \def \_prettytok_tmp {prettye:n} + \int_step_inline:nn {9} { + \_prettytok_tmp:cc {\_prettytok_tmp n} {\_prettytok_tmp} + \tl_put_right:Nn \_prettytok_tmp {n} + } + + \def \_prettytok_tmp:NN #1 #2 { % #1: example \prettye:nnnw, #2: example \prettye:nnw (the latter has one more n than the former) + \cs_new:Npn #1 ##1 ##2 ##3 { #2 {##1} {##2 ##3} } % here ##1 is the callback (first ⟨n⟩), ##2 etc. are the additional-print things + } + \def \_prettytok_tmp {prettye:nn} \int_step_inline:nn {9} { - \__tmp:cc {\__tmp n} {\__tmp} - \__tmp:cc {\__tmp nw} {\__tmp w} - \tl_put_right:Nn \__tmp {n} + \_prettytok_tmp:cc {\_prettytok_tmp nw} {\_prettytok_tmp w} + \tl_put_right:Nn \_prettytok_tmp {n} } } \endgroup - -\cs_new_protected:Nn \prettyshow:N { - \exp_args:No \pretty:n {\meaning #1} -} -\cs_generate_variant:Nn \prettyshow:N {c} +% ======== normal-catcode alias +\let\prettyN\pretty:n +\let\prettyX\pretty:x +\let\prettyO\pretty:o +\let\prettyV\pretty:V +\let\prettyW\pretty:w +\let\prettyeN\prettye:n +\let\prettyeW\prettye:w \let\prettyshowN\prettyshow:N \let\prettyshowC\prettyshow:c - - diff --git a/Master/texmf-dist/tex/latex/prettytok/prettytok_template.html b/Master/texmf-dist/tex/latex/prettytok/prettytok_template.html deleted file mode 100644 index 8764d498095..00000000000 --- a/Master/texmf-dist/tex/latex/prettytok/prettytok_template.html +++ /dev/null @@ -1,283 +0,0 @@ -<!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; -} - -#display_wrap{ - flex: 1 0 auto; -} -#controller{ - flex: 0 0 50px; -} - -.control-button{ -} - - - -.tokenlist, .fileline{ - border: 1px solid gray; - overflow: scroll; - white-space: nowrap; -} -.tokenlist::-webkit-scrollbar, .fileline::-webkit-scrollbar { width: 0 !important } - -.fileline{ - background-color: #404040; -} - -.explicit_char_target{ - background-color: #FF8080; -} -.explicit_char{ - background-color: #606060; -} - - -.cs, .active_char{ - color: #FFFF00; -} -.cs::before{ - content: "\\"; -} -.cs::after{ - content: " "; -} - -#popup{ - display: none; - position: absolute; - border: 1px solid gray; - background-color: #000080ff; -} - -.cmd__left_brace_cmd, .cmd__right_brace_cmd, .cmd__mac_param_cmd, .frozenrelax{ - 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: "#"; -} - -.cmd__letter_cmd{ - color: #AAFFAA; -} - -.cmd__spacer_cmd{ - color: #606060; -} - - -input[type=button]{ - color: white; - background-color: #0000ff; - border: 0; -} - -#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, "⇥") -} - -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) - if({13: true, 10: true}[token.data_charcode]){ - tl_div.appendChild(document.createElement("br")) - } - } - output.appendChild(tl_div) -} - -function token(charcode /* int */, catcode /* single character string in hex */){ - const token_span=document.createElement("span") - const ch=String.fromCodePoint(charcode) - token_span.innerText=show_html(ch) - token_span.data_charcode=charcode - 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}` - } - return token_span -} - -function cs(...codepoints){ - const token_span=document.createElement("span") - - const control_sequence_name=String.fromCodePoint(...codepoints) - //const meaning_str=readstr() - - token_span.innerText=show_html(control_sequence_name) - //token_span.title=`cs '${control_sequence_name}' → ${meaning_str}` - token_span.className="cs" - - return token_span -} - -function csfrozenrelax(){ - const token_span=document.createElement("span") - token_span.innerText="relax" - token_span.title="frozen relax" - token_span.className="cs frozenrelax" - return token_span -} - -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- |