% 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. \ProvidesExplPackage{prettytok}{2022/07/08}{0.0.1}{Pretty-print token list} \RequirePackage{precattl} % ======== 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. } \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_if_eq:NnF \__test {ac.ad.bc.bd.} { \msg_error:nn {prettytok} {tl-analysis-bug} } \endgroup \fi % ======== load Lua module. \sys_if_engine_luatex:T{ \directlua{require("prettytok")} \precattl_exec:n { \directlua{prettyprint_frozenrelaxtok=token.get_next().tok}\cFrozenRelax } } % ======== 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 \_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!} % See also Lua function: local function check_file_opened() \global\let \pretty_check_already_init: \relax \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 % 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 % refresh strategy \iow_now:Nx \_prettytok_file {set_refresh_strategy(\prettyrefreshstrategy,\prettyrefreshduration)} } \cs_new_protected:Npn \prettyinit: { \pretty_check_already_init: \_prettyinit_unchecked: } } \cs_new_eq:NN \prettyinit \prettyinit: \precattl_exec:n { \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 % ======== 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 {)//