diff options
author | Karl Berry <karl@freefriends.org> | 2022-05-28 20:23:06 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-05-28 20:23:06 +0000 |
commit | 9ddf4513815730b922a72693349b23b6262cf038 (patch) | |
tree | b8d2d88ccc8e2aa6ab4490688ea8550ce79e543b /Master/texmf-dist | |
parent | cfcd43f33b17b5eb32ebb5a917f144700c9c1ef1 (diff) |
prettytok (28may22)
git-svn-id: svn://tug.org/texlive/trunk@63430 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/latex/prettytok/DEPENDS.txt | 2 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/prettytok/README | 23 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/prettytok/prettytok.pdf | bin | 0 -> 335928 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/prettytok/prettytok.tex | 139 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/prettytok/prettytok.sty | 669 |
5 files changed, 833 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/prettytok/DEPENDS.txt b/Master/texmf-dist/doc/latex/prettytok/DEPENDS.txt new file mode 100644 index 00000000000..5e0ae3b076f --- /dev/null +++ b/Master/texmf-dist/doc/latex/prettytok/DEPENDS.txt @@ -0,0 +1,2 @@ +expl3 +filecontentsdef diff --git a/Master/texmf-dist/doc/latex/prettytok/README b/Master/texmf-dist/doc/latex/prettytok/README new file mode 100644 index 00000000000..cefd81b493c --- /dev/null +++ b/Master/texmf-dist/doc/latex/prettytok/README @@ -0,0 +1,23 @@ +prettytok -- Pretty-print token list + +Released under the LaTeX Project Public License v1.3c or later +See http://www.latex-project.org/lppl.txt + +Report bugs at https://github.com/user202729/TeXlib + +======== + +Copyright 2022 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 +(at your option) any later version. The latest version of this license is in +the file: + + http://www.latex-project.org/lppl.txt + +This work has the LPPL maintenance status `maintained'. + +The Current Maintainer of this work is user202729. + +This work consists of the files prettytok.sty. diff --git a/Master/texmf-dist/doc/latex/prettytok/prettytok.pdf b/Master/texmf-dist/doc/latex/prettytok/prettytok.pdf Binary files differnew file mode 100644 index 00000000000..76ca759f676 --- /dev/null +++ b/Master/texmf-dist/doc/latex/prettytok/prettytok.pdf diff --git a/Master/texmf-dist/doc/latex/prettytok/prettytok.tex b/Master/texmf-dist/doc/latex/prettytok/prettytok.tex new file mode 100644 index 00000000000..d21af2d0fe2 --- /dev/null +++ b/Master/texmf-dist/doc/latex/prettytok/prettytok.tex @@ -0,0 +1,139 @@ +%! TEX program = lualatex +\ProvidesFile{prettytok.tex} [2022/05/28 v0.0.0 Pretty-print token lists] +% yes, this is not dtx +\documentclass{l3doc} +%\usepackage[a4paper,margin=25mm,left=50mm,nohead]{geometry} +%\usepackage[numbered]{hypdoc} +%\usepackage{\jobname} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} +\GetFileInfo{\jobname.tex} +\DoNotIndex{\newcommand,\newenvironment} + +\title{\textsf{prettytok} --- Pretty-print token lists\thanks{This file + describes version \fileversion, last revised \filedate.} +} +\author{user202729% +%\thanks{E-mail: (not set)} +} +\date{Released \filedate} + +\maketitle + +\changes{v0.0.0}{2022/05/18}{First public release} + +\begin{abstract} + Pretty-print token lists. +\end{abstract} + +\section{Usage} + +\subsection{Main function} +\begin{function}{\pretty:n,\pretty:x,\pretty:o,\pretty:V} + \begin{syntax} + \cs{pretty:n} \Arg{token list} \\ + \end{syntax} + Print the content of \meta{token list}. +\end{function} + +\begin{function}{\pretty:N,\pretty:c} + \begin{syntax} + \cs{pretty:N} \meta{token} \\ + \cs{pretty:c} \Arg{control sequence name} \\ + \end{syntax} + Print \meta{token}. \\ + This function is not very useful. Usually it's preferable to use |\pretty:V| to print a token list variable's value, + or |\prettyshow:N| to print a control sequence's meaning. +\end{function} + +\subsection{View result} + +The result is printed to a HTML file named |pretty-|\meta{jobname}|.html| by default. +Open the file in any browser to view the result. + +Note that the HTML file will not be touched if nothing is printed, as such it's encouraged to add a line such as |\pretty:n {start}| right after loading the file. + +Why HTML file? + +\begin{itemize} + \item Because if the TeX program stops with error / has some error that corrupts the PDF output, the output will even with corrupted more by the debug print. + \item Printing to the console is extremely limited (difficult syntax highlighting/scrolling/line wrapping), and most likely cluttered with the traceback/other TeX default output. + \item Output to another \TeX\ file to be compiled is a bit absurd, and compiling \TeX\ file takes longer than loading a HTML file. +\end{itemize} + +By default, the output refreshes whenever the TeX file is recompiled. The behavior +can be customized with \cs{prettyrefreshstrategy} and \cs{prettyrefreshduration}. + +\subsection{\LaTeX2 interface} + + +\begin{function}{\prettyN,\prettyX,\prettyO,\prettyV} + \begin{syntax} + \cs{prettyN} \Arg{token list} \\ + \end{syntax} + Alias of the correspondingly-named commands. +\end{function} + +\subsection{Additional functions} + +There are also these functions, for convenience. + +\begin{function}{\pretty:nn, \pretty:nnn} + \begin{syntax} + \cs{pretty:nn} \Arg{token list} \Arg{token list} + \cs{pretty:nnn} \Arg{token list} \Arg{token list} \Arg{token list} + \end{syntax} + Print multiple token lists. +\end{function} + +\begin{function}{\pretty:w} + \begin{syntax} + \cs{pretty:w} \meta{token list} \cs{prettystop} + \end{syntax} + Print the content of \meta{token list}. For now, it must be brace-balanced. +\end{function} + +\begin{function}{\prettyshow:N} + \begin{syntax} + \cs{prettyshow:N} \meta{token} + \end{syntax} + Show the meaning of a |N|-type argument. +\end{function} + +\subsection{Customization} + +These variables can be redefined before the +first call to |\pretty:n| to customize the behavior. + +\begin{variable}{\prettyfilename} + The output file name. Defaults to |pretty-|\meta{jobname}|.html|, as mentioned above. +\end{variable} + +\begin{variable}{\prettyrefreshstrategy} + The auto-refresh strategy. Allowed values are 0-4. 0 is no refresh. \\ + Which value works best depends on the particular browser. \\ + On Google Chrome, passing |--allow-file-access-from-files| may be useful. +\end{variable} + +\begin{variable}{\prettyrefreshduration} + The duration between two consecutive refresh check, in milliseconds. Defaults to 1000. +\end{variable} + +\begin{variable}{\prettypreamble} + The HTML source code preamble. This can be redefined to change styles, but the + behavior is not guaranteed. +\end{variable} + +\section{Implementation} + +Unfortunately, the implementation is not typesetted in \TeX. Read the |.sty| file. + +\StopEventually{^^A + \PrintChanges + \PrintIndex +} + +\Finale +\end{document} diff --git a/Master/texmf-dist/tex/latex/prettytok/prettytok.sty b/Master/texmf-dist/tex/latex/prettytok/prettytok.sty new file mode 100644 index 00000000000..e17eb204c68 --- /dev/null +++ b/Master/texmf-dist/tex/latex/prettytok/prettytok.sty @@ -0,0 +1,669 @@ +% File: prettytok.sty +% Copyright 2022 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 +% (at your option) any later version. The latest version of this license is in +% the file: +% +% http://www.latex-project.org/lppl.txt +% +% 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) + + \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 + } + } + + % if not, just append to result. + \bool_if:NF \_EIprocessed { + \tl_build_gput_right:Nn \_EIresult {##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 {~}} + } + \_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 + + % 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 + } +} + +\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. + +\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 \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 +\exp_args:NNx \providecommand \prettyfilename {pretty-\jobname.html} +\providecommand \prettyrefreshstrategy {4} +\providecommand \prettyrefreshduration {1000} + + +\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 + +% normal-catcode alias +\let\prettyN\pretty:n +\let\prettyX\pretty:x +\let\prettyO\pretty:o +\let\prettyV\pretty:V + +\cs_generate_variant:Nn \pretty:N {c} + +\cs_new_protected:Nn \pretty:nn { + \pretty:n {#1} + \pretty:n {#2} +} + +\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; +} + +#display_wrap{ + flex: 1 0 auto; +} +#controller{ + flex: 0 0 50px; +} + +.control-button{ +} + + + +.tokenlist, .fileline{ + border: 1px solid gray; + height: 2em; + 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{ + 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: #808080; +} + + +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) + } + output.appendChild(tl_div) +} + +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}` + } + 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 +} + +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 |