%^^A meta-comment %^^A An Infrastructure for Semantic Macros and Module Scoping %^^A Copyright (c) 2022 Michael Kohlhase, all rights reserved %^^A this file is released under the %^^A LaTeX Project Public License (LPPL) %^^A %^^A The original of this file is in the public archive at %^^A http://github.com/sLaTeX/sTeX/ %^^A % \iffalse %<*driver> \def\stexdocpath{../doc} \input{\stexdocpath/stex-docheader} \stextoptitle{The \sTeX Package}{stex} \docmodule % % \fi % % % \begin{stexmanual} % \end{stexmanual} % % \begin{documentation} % \begin{sfragment}{\sTeX Developer Manual} % \input{\stexdocpath/stex-devel} % \end{sfragment} % \end{documentation} % % \begin{implementation} % \begin{sfragment}{The \sTeX Implementation} % % \begin{sfragment}{Setting up} % Setup code for the document class % \begin{macrocode} %<*cls> %%%%%%%%%%%%% stex.dtx %%%%%%%%%%%%% \RequirePackage{expl3,l3keys2e} \ProvidesExplClass{stex}{2023/10/13}{3.4.0}{sTeX document class} \IfFileExists{stex-expl-compat.sty}{ \usepackage{stex-expl-compat} }{} \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{stex}} \ProcessOptions \RequirePackage{stex} \LoadClass{article} % % \end{macrocode} % % Setup code for the package % % \begin{macrocode} %<*package> \RequirePackage{expl3,l3keys2e,ltxcmds} \ProvidesExplPackage{stex}{2023/10/13}{3.4.0}{sTeX package} \IfFileExists{stex-expl-compat.sty}{ \usepackage{stex-expl-compat} }{} \RequirePackage{stex-logo} % externalized for backwards-compatibility reasons \RequirePackage{standalone} \message{^^J*~This~is~sTeX~version~3.4.0~*^^J} % \end{macrocode} % % Package options: % % \begin{macrocode} \keys_define:nn { stex / package } { debug .str_set_x:N = \c_stex_debug_clist , lang .clist_set:N = \c_stex_languages_clist , mathhub .tl_set_x:N = \mathhub , usesms .bool_set:N = \c_stex_persist_mode_bool , writesms .bool_set:N = \c_stex_persist_write_mode_bool , checkterms .bool_set:N = \c_stex_check_terms_bool , image .bool_set:N = \c_tikzinput_image_bool, nofrontmatter .bool_set:N = \c_stex_no_frontmatter_bool, unknown .code:n = {} } \exp_args:NNo \clist_set:Nn \c_stex_debug_clist \c_stex_debug_clist \ProcessKeysOptions { stex / package } % \end{macrocode} % % Error messages: % \begin{macrocode} \input{stex-en.ldf} % \end{macrocode} % % \end{sfragment} % % \begin{sfragment}{Utilities} % % \begin{macrocode} \cs_set_eq:NN \stex_undefined: \undefined % \end{macrocode} % % \begin{sfragment}{Calling kpsewhich and Environment Variables} % % \begin{macrocode} %<@@=stex_envs> % \end{macrocode} % % \begin{macro}{\stex_kpsewhich:Nn} % \begin{macrocode} \cs_new_protected:Nn \stex_kpsewhich:Nn {\group_begin: \catcode`\ =12 \sys_get_shell:nnN { kpsewhich ~ #2 } { } \l_tmpa_tl \tl_gset_eq:NN \l_tmpa_tl \l_tmpa_tl \group_end: \exp_args:NNo\str_set:Nn #1 {\l_tmpa_tl} \tl_trim_spaces:N #1 } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_get_env:Nn} % \begin{macrocode} \sys_if_platform_windows:TF{ \cs_new_protected:Nn \stex_get_env:Nn {\group_begin: \escapechar=-1\catcode`\\=12 \exp_args:NNe \stex_kpsewhich:Nn #1 {-expand-var~\c_percent_str#2\c_percent_str} \exp_args:NNx\use:nn\group_end:{ \str_set:Nn \exp_not:N #1 { #1 } } } }{ \cs_new_protected:Nn \stex_get_env:Nn { \stex_kpsewhich:Nn #1 {-var-value~#2} } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Logging} % \begin{macrocode} %<@@=stex_debug> % \end{macrocode} % % \begin{macro}{\stex_debug:nn} % \begin{macrocode} \cs_new_protected:Nn \stex_debug:nn { \exp_args:NNo \clist_if_in:NnTF \c_stex_debug_clist { \tl_to_str:n{all} }{ \_@@_:nn{#1}{#2} }{ \exp_args:NNo \clist_if_in:NnT \c_stex_debug_clist { \tl_to_str:n{#1} }{ \_@@_:nn{#1}{#2} } } } \cs_new_protected:Nn \_@@_:nn { \msg_set:nnn{stex}{debug / #1}{ \\Debug~#1:~#2\\ } \msg_none:nn{stex}{debug / #1} } % \end{macrocode} % \end{macro} % \begin{macro}{\stex_fatal_error:n,\stex_fatal_error:nnn,\stex_fatal_error:nxx} % To avoid dead locks etc., we throw errors and make tex stop % entirely: % \begin{macrocode} \cs_new_protected:Nn \stex_fatal_error:n { \msg_error:nn{stex}{#1}\input{Fatal~Error!!} } \cs_new_protected:Nn \stex_fatal_error:nnn { \msg_error:nnn{stex}{#1}{#2}{#3}\input{Fatal~Error!!} } \cs_generate_variant:Nn \stex_fatal_error:nnn {nxx} % \end{macrocode} % \end{macro} % % We check an environment variable for debugging and % set things up: % % \begin{macrocode} \stex_get_env:Nn\_@@_env_str{STEX_DEBUG} \str_if_empty:NTF\_@@_env_str { \clist_set_eq:NN \l_@@_cl \c_stex_debug_clist }{ \clist_set:No \l_@@_cl {\_@@_env_str} } \clist_clear:N \c_stex_debug_clist \clist_map_inline:Nn \l_@@_cl { \exp_args:NNo \clist_put_right:Nn \c_stex_debug_clist { \tl_to_str:n{#1} } } \exp_args:NNo \clist_if_in:NnTF \c_stex_debug_clist {\tl_to_str:n{all}} { \msg_redirect_module:nnn{ stex }{ none }{ warning } \stex_debug:nn{all}{Logging~everything!} }{ \clist_map_inline:Nn \c_stex_debug_clist { \msg_redirect_name:nnn{ stex }{ debug / #1 }{ warning } \stex_debug:nn{#1}{Logging~#1} } } % \end{macrocode} % % \end{sfragment} % % \begin{sfragment}{Languages} % \begin{macrocode} %<@@=stex_lang> % \end{macrocode} % \begin{variable}{\c_stex_languages_prop,\c_stex_language_abbrevs_prop} % % We store language abbreviations in two (mutually inverse) % property lists: % \begin{macrocode} \exp_args:NNx \prop_const_from_keyval:Nn \c_stex_languages_prop { \tl_to_str:n { en = english , de = ngerman , ar = arabic , bg = bulgarian , ru = russian , fi = finnish , ro = romanian , tr = turkish , fr = french }} \exp_args:NNx \prop_const_from_keyval:Nn \c_stex_language_abbrevs_prop { \tl_to_str:n { english = en , ngerman = de , arabic = ar , bulgarian = bg , russian = ru , finnish = fi , romanian = ro , turkish = tr , french = fr }} % todo: chinese simplified (zhs) % chinese traditional (zht) % \end{macrocode} % \end{variable} % % \begin{variable}{\l_stex_current_language_str} % \begin{macrocode} \str_new:N \l_stex_current_language_str % \end{macrocode} % \end{variable} % % we use the |lang|-package option to load the corresponding % babel languages: % \begin{macro}{\stex_set_language:n, \stex_set_language:x, \stex_set_language:o} % \begin{macrocode} \cs_new_protected:Nn \stex_set_language:n { \str_set:Nn \l_stex_current_language_str { #1 } \prop_if_in:NnTF \c_stex_languages_prop {#1} { \tl_set_rescan:Nnx \l_@@_lang_str {}{\prop_item:Nn \c_stex_languages_prop {#1}} \cs_if_eq:NNTF\@onlypreamble\@notprerr{ \ltx@ifpackageloaded{babel}{ \exp_args:No\selectlanguage\l_@@_lang_str }{} }{ \ltx@ifpackageloaded{babel}{}{ \str_if_eq:nnTF {#1} {tr} { \RequirePackage[turkish,shorthands=:!]{babel} }{ \RequirePackage[\l_@@_lang_str]{babel} } } } }{ \msg_error:nnx{stex}{error/unknownlanguage}{#1} } } \cs_generate_variant:Nn \stex_set_language:n {x,o} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_language_from_file:} % \begin{macrocode} \cs_new_protected:Nn \stex_language_from_file: { \seq_get_right:NN \g_stex_current_file \l_tmpa_str \seq_set_split:NnV \l_tmpa_seq . \l_tmpa_str \seq_pop_right:NN \l_tmpa_seq \l_tmpa_str % = ".tex/.dtx/.sty" \exp_args:No \str_if_eq:nnF \l_tmpa_str {tex} { \exp_args:No \str_if_eq:nnF \l_tmpa_str {dtx} { \exp_args:No \str_if_eq:nnF \l_tmpa_str {ltx} { \exp_args:NNo \seq_put_right:Nn \l_tmpa_seq \l_tmpa_str } } } \seq_pop_left:NN \l_tmpa_seq \l_tmpa_str % \seq_if_empty:NF \l_tmpa_seq { %remaining element should be [.]language \seq_pop_right:NN \l_tmpa_seq \l_@@_str \str_if_eq:NNF \l_@@_str \l_stex_current_language_str { \exp_args:NNo \prop_if_in:NnT \c_stex_languages_prop \l_@@_str { \stex_set_language:o \l_@@_str } } \stex_debug:nn{lang} {Language~\l_stex_current_language_str~ inferred~from~file~name} } } % \end{macrocode} % \end{macro} % % Loading babel: % \begin{macrocode} \clist_if_empty:NF \c_stex_languages_clist { \bool_set_false:N \l_@@_turkish_bool \seq_clear:N \l_tmpa_seq \clist_map_inline:Nn \c_stex_languages_clist { \str_set:Nx \l_tmpa_str {#1} \str_if_eq:nnT {#1}{tr}{ \bool_set_true:N \l_@@_turkish_bool } \prop_get:NoNTF \c_stex_languages_prop \l_tmpa_str \l_tmpa_str { \tl_set_rescan:Nno \l_tmpa_str {} \l_tmpa_str \seq_put_right:No \l_tmpa_seq \l_tmpa_str } { \msg_error:nnx{stex}{error/unknownlanguage}{\l_tmpa_str} } } \stex_debug:nn{lang} {Languages:~\seq_use:Nn \l_tmpa_seq {,~} } \bool_if:NTF \l_@@_turkish_bool { \exp_args:NNe \use:nn \RequirePackage {[main=\seq_use:Nn \l_tmpa_seq, ,shorthands=:!]}{babel} }{ \exp_args:NNe \use:nn \RequirePackage {[main=\seq_use:Nn \l_tmpa_seq, ]}{babel} } } % \end{macrocode} % % \end{sfragment} % % \begin{sfragment}{Group-like Behaviours} % \begin{macrocode} %<@@=stex_groups> % \end{macrocode} % % \begin{macro}{\stex_pseudogroup:nn,\stex_pseudogroup_restore:N} % \begin{macrocode} \cs_new_protected:Npn \stex_pseudogroup:nn { \exp_args:Nne \use:nn } \cs_new:Nn \stex_pseudogroup_restore:N { \tl_if_exist:NTF #1 { \tl_set:Nn \exp_not:N #1 { \exp_args:No \exp_not:n #1 } }{ \cs_undefine:N \exp_not:N #1 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_pseudogroup_with:nn} % \begin{macrocode} \cs_new_protected:Nn \stex_pseudogroup_with:nn { \tl_map_inline:nn{#1}{ \cs_set_eq:cN{_@@_\tl_to_str:n{##1}}##1 } #2 \tl_map_inline:nn{#1}{ \cs_set_eq:Nc##1{_@@_\tl_to_str:n{##1}} \cs_undefine:c{_@@_\tl_to_str:n{##1}} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_metagroup_new:n, \stex_metagroup_new:o} % List of all currently existing metagroup identifiers % \begin{macrocode} \seq_new:N \l_@@_ids_seq % \end{macrocode} % start a new metagroup at the current group level with id \#1 % \begin{macrocode} \cs_new_protected:Nn \stex_metagroup_new:n { \str_set:cx{l_@@_#1_int} {\int_use:N\currentgrouplevel} \seq_put_right:Nn \l_@@_ids_seq {#1} } \cs_generate_variant:Nn \stex_metagroup_new:n {o} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_metagroup_do_in:nn, \stex_metagroup_do_in:nx} % \begin{macrocode} \prg_new_conditional:Nnn \_@@_exists:n {TF} { \str_if_exist:cTF{l_@@_#1_int} \prg_return_true: \prg_return_false: } \cs_new_protected:Nn \stex_metagroup_do_in:nn { \_@@_exists:nTF{#1}{ \_@@_do_in:nn{#1}{#2} }{ \msg_error:nnn{stex}{error/metagroup/missing}{#1} } } \cs_generate_variant:Nn \stex_metagroup_do_in:nn {nx} \cs_new_protected:Nn \_@@_do_in:nn { \exp_args:Nnx\stex_debug:nn{metagroup}{adding~to~\detokenize{#1}:^^J\tl_to_str:n{#2}} \tl_set:Nn\_@@_tmp{#2} \exp_args:Nx \int_compare:nNnF {\use:c{l_@@_#1_int}} = \currentgrouplevel { \tl_if_exist:cTF{g_@@_#1_\the\currentgrouplevel _content}{ \exp_args:Nno \tl_gput_right:cn{g_@@_#1_\the\currentgrouplevel _content} }{ \exp_args:Nno \tl_gset:cn{g_@@_#1_\the\currentgrouplevel _content} }\_@@_tmp \bool_if_exist:cF {l_@@_\the\currentgrouplevel _bool} { \group_insert_after:N \_@@_do: \bool_set_true:c {l_@@_\the\currentgrouplevel _bool} } } \_@@_tmp } \cs_new_protected:Nn \_@@_do: { \seq_map_inline:Nn \l_@@_ids_seq { \tl_if_exist:cT{g_@@_##1_\int_eval:n{\currentgrouplevel+1}_content}{ \exp_args:NNno \exp_args:Nno \_@@_do_in:nn{##1}{ \csname g_@@_##1_\int_eval:n{\currentgrouplevel+1}_content\endcsname } \cs_undefine:c{g_@@_##1_\int_eval:n{\currentgrouplevel+1}_content} } \bool_if_exist:cF {l_@@_\int_eval:n\currentgrouplevel _bool} { \group_insert_after:N \_@@_do: \bool_set_true:c {l_@@_\int_eval:n\currentgrouplevel _bool} } } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{HTML Annotations} % \begin{macrocode} %<@@=stex_annotate> % \end{macrocode} % % \begin{macro}[TF]{\stex_if_do_html:} % Whether to (locally) produce HTML output % \begin{macrocode} \bool_new:N \_stex_html_do_output_bool \bool_set_true:N \_stex_html_do_output_bool \prg_new_conditional:Nnn \stex_if_do_html: {p,T,F,TF} { \bool_if:nTF \_stex_html_do_output_bool \prg_return_true: \prg_return_false: } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_suppress_html:n} % Temporarily disable HTML output % \begin{macrocode} \cs_new_protected:Nn \stex_suppress_html:n { \stex_pseudogroup:nn{ \bool_set_false:N \_stex_html_do_output_bool #1 }{ \stex_if_do_html:T { \bool_set_true:N \_stex_html_do_output_bool } } } % \end{macrocode} % \end{macro} % % We determine the backend: % \begin{macro}[pTF]{\stex_if_html_backend:} % \begin{macro}{\ifstexhtml} % \begin{macro}{\stex@backend} % \begin{macrocode} \ifcsname if@rustex\endcsname\else \expandafter\newif\csname if@rustex\endcsname \@rustexfalse \fi \stex_get_env:Nn\_@@_env_str{STEX_FORCE_PDF} \exp_args:No \str_if_eq:nnTF \_@@_env_str {true} { \def\stex@backend{pdflatex} }{ \tl_if_exist:NF\stex@backend{ \if@rustex \def\stex@backend{rustex} \else \cs_if_exist:NTF\HCode{ \def\stex@backend{tex4ht} }{ \def\stex@backend{pdflatex} } \fi } } \input{stex-backend-\stex@backend.cfg} \newif\ifstexhtml \stex_if_html_backend:TF { \stexhtmltrue \bool_set_true:N \_stex_html_do_output_bool }{ \stexhtmlfalse \bool_set_false:N \_stex_html_do_output_bool } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\_stex_annotate_force_break:n} % \begin{macrocode} \stex_if_html_backend:TF { \cs_new_protected:Nn \_stex_annotate_force_break:n { \stex_annotate_invisible:n{~} #1 \stex_annotate_invisible:n{~} } }{ \cs_new_protected:Nn \_stex_annotate_force_break:n { #1 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\mmlintent,\mmlarg} % \begin{macrocode} \stex_if_html_backend:TF { \cs_new_protected:Npn \mmlintent #1 #2 { \stex_annotate:nn{mml:intent={#1}}{#2} } \cs_new_protected:Npn \mmlarg #1 #2 { \stex_annotate:nn{mml:arg={#1}}{#2} } }{ \cs_new_protected:Npn \mmlintent #1 #2 { #2 } \cs_new_protected:Npn \mmlarg #1 #2 { #2 } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Auxiliary Methods} % \begin{macrocode} %<@@=stex_aux> % \end{macrocode} % \begin{macro}{\stex_deactivate_macro:Nn, \stex_reactivate_macro:N} % \begin{macrocode} \cs_new_protected:Nn \stex_deactivate_macro:Nn { \tl_set_eq:cN{\tl_to_str:n{#1}~-~orig}#1 \cs_set_protected:Npn#1{ \exp_args:Nnno\msg_error:nnnn{stex}{error/deactivated-macro}{#1}{#2} } } \cs_new_protected:Nn \stex_reactivate_macro:N { \exp_after:wN\let\exp_after:wN#1\csname \detokenize{#1}~-~orig\endcsname } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_ignore_spaces_and_pars:} % \begin{macrocode} \protected\def\stex_ignore_spaces_and_pars:{ \begingroup\catcode13=10\relax \@ifnextchar\par{ \endgroup\expandafter\stex_ignore_spaces_and_pars:\@gobble }{ \endgroup } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_keys_define:nnnn} % \begin{macrocode} \cs_new_nopar:Nn \stex_keys_define:nnnn { \tl_gset:cn {_@@_keys_#1_pre_tl}{#2} \tl_gset:cn {_@@_keys_#1_def_tl}{#3} \tl_if_empty:nF{#4}{ \clist_map_inline:nn{#4}{ \tl_set_eq:Nc \l_@@_tl {_@@_keys_##1_pre_tl} \tl_gput_left:co{_@@_keys_#1_pre_tl} \l_@@_tl \tl_set_eq:Nc \l_@@_tl {_@@_keys_##1_def_tl} \tl_gput_left:cn{_@@_keys_#1_def_tl} , \tl_gput_left:co{_@@_keys_#1_def_tl} \l_@@_tl } } \tl_set_eq:Nc \l_@@_tl {_@@_keys_#1_def_tl} \exp_args:Nno \keys_define:nn {stex / #1} {\l_@@_tl} } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_keys_set:nn} % \begin{macrocode} \cs_new_nopar:Nn \stex_keys_set:nn { \use:c{_@@_keys_#1_pre_tl} \keys_set:nn {stex / #1} { #2 } } % \end{macrocode} % \end{macro} % % Some ubiquitous key sets: % \begin{macrocode} \stex_keys_define:nnnn{archive file}{ \str_clear:N \l_stex_key_archive_str \str_clear:N \l_stex_key_file_str }{ archive .str_set_x:N = \l_stex_key_archive_str , file .str_set_x:N = \l_stex_key_file_str }{} \stex_keys_define:nnnn{id}{ \str_clear:N \l_stex_key_id_str }{ id .str_set_x:N = \l_stex_key_id_str }{} \stex_keys_define:nnnn{title}{ \tl_clear:N \l_stex_key_title_tl }{ title .tl_set:N = \l_stex_key_title_tl }{} \stex_keys_define:nnnn{style}{ \clist_clear:N \l_stex_key_style_clist }{ style .clist_set:N = \l_stex_key_style_clist }{} \stex_keys_define:nnnn{deprecate}{ \str_clear:N \l_stex_key_deprecate_str }{ deprecate .str_set_x:N = \l_stex_key_deprecate_str }{} \stex_keys_define:nnnn{uses}{}{ uses .code:n = { \clist_map_inline:nn{#1}{ \stex_str_if_starts_with:nnTF{##1}[{ \_@@_split_at_bracket:w ##1 \_stex_end: }{ \usemodule{##1} } } } }{} \cs_new_protected:Npn \_@@_split_at_bracket:w [ #1 ] #2 \_stex_end: { \usemodule[#1]{#2} } % \end{macrocode} % % \begin{macro}{\_stex_do_deprecation:n} % \begin{macrocode} \cs_new:Nn \_stex_do_deprecation:n { \str_if_empty:NF \l_stex_key_deprecate_str { \msg_warning:nnxx{stex}{warning/deprecated}{#1}{\l_stex_key_deprecate_str} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_do_id:} % \begin{macrocode} \cs_new_protected:Nn \_stex_do_id: { \stex_if_smsmode:F { \str_if_empty:NF \l_stex_key_id_str { \exp_args:No \stex_ref_new_doc_target:n \l_stex_key_id_str } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_new_stylable_env:nnnnnnn,\stex_new_stylable_cmd:nnnn,\stex_style_apply:} % \begin{macrocode} \cs_new_protected:Nn \stex_new_stylable_cmd:nnnn { \exp_after:wN \newcommand \cs:w stexstyle#1 \cs_end:[2][]{ \_@@_patch:nnn{#1}{##1}{##2} } \exp_after:wN \NewDocumentCommand\cs:w #1\cs_end:{#2}{ \cs_set:Npn \stex_style_apply: { \_@@_apply_patch:n{#1} } #3 } \tl_set:cn {_@@_style_#1:} { #4 } } \cs_new_protected:Nn \_@@_apply_patch:n { \clist_if_empty:NTF \l_stex_key_style_clist { \tl_clear:N \thisstyle \use:c{_@@_style_#1:} }{ \clist_get:NN \l_stex_key_style_clist \thisstyle \tl_if_exist:cTF{_@@_style_#1_\thisstyle :}{ \use:c{_@@_style_#1_\thisstyle :} }{ \use:c{_@@_style_#1:} } } } \cs_new_protected:Nn \_@@_patch:nnn { \str_if_empty:nTF {#2}{ \tl_set:cn{_@@_style_#1:}{#3} }{ \tl_set:cn{_@@_style_#1_#2:}{#3} } } \cs_new_protected:Nn \stex_new_stylable_env:nnnnnnn { \exp_after:wN \newcommand \cs:w stexstyle#1 \cs_end:[3][]{ \_@@_patch:nnnn{#1}{##1}{##2}{##3} } \NewDocumentEnvironment{#7#1}{#2}{ \cs_set:Npn \stex_style_apply: { \_@@_apply_patch_begin:n{#1} } #3 }{ \cs_set:Npn \stex_style_apply: { \_@@_apply_patch_end:n{#1} } #4 } \tl_set:cn {_@@_style_#1_start:} { #5 } \tl_set:cn {_@@_style_#1_end:} { #6 } } \cs_new_protected:Nn \_@@_patch:nnnn { \str_if_empty:nTF {#2}{ \tl_set:cn{_@@_style_#1_start:}{#3} \tl_set:cn{_@@_style_#1_end:}{#4} }{ \tl_set:cn{_@@_style_#1_#2_start:}{#3} \tl_set:cn{_@@_style_#1_#2_end:}{#4} } } \cs_new_protected:Nn \_@@_apply_patch_begin:n { \clist_if_empty:NTF \l_stex_key_style_clist { \tl_clear:N \thisstyle \use:c{_@@_style_#1_start:} }{ \clist_get:NN \l_stex_key_style_clist \thisstyle \stex_debug:nn{styling}{dominant~style:~\thisstyle} \tl_if_exist:cTF{_@@_style_#1_\thisstyle _start:}{ \use:c{_@@_style_#1_\thisstyle _start:} }{ \use:c{_@@_style_#1_start:} } } } \cs_new_protected:Nn \_@@_apply_patch_end:n { \tl_if_empty:NTF \thisstyle { \use:c{_@@_style_#1_end:} }{ \tl_if_exist:cTF{_@@_style_#1_\thisstyle _end:}{ \use:c{_@@_style_#1_\thisstyle _end:} }{ \use:c{_@@_style_#1_end:} } } } % \end{macrocode} % % \end{macro} % % \begin{macro}[pTF]{\stex_str_if_ends_with:nn} % \begin{macrocode} \prg_new_conditional:Nnn \stex_str_if_ends_with:nn {p,T,F,TF} { \exp_args:Ne \str_if_eq:nnTF { \str_range:nnn{#1}{- \str_count:n{#2}}{-1} }{#2}\prg_return_true: \prg_return_false: } % \end{macrocode} % \end{macro} % % \begin{macro}[pTF]{\stex_str_if_starts_with:nn} % \begin{macrocode} \prg_new_conditional:Nnn \stex_str_if_starts_with:nn {p,T,F,TF} { \exp_args:Ne \str_if_eq:nnTF { \str_range:nnn{#1}{1}{\str_count:n{#2}} }{#2}\prg_return_true: \prg_return_false: } % \end{macrocode} % \end{macro} % % \begin{macro}[EXP]{\stex_macro_body:N} % \begin{macrocode} \cs_new:Npn \_@@_start:#1\_@@_end: {\exp_not:n{#1}} \cs_new_protected:Nn \_@@_end: {} \cs_new:Nn \stex_macro_body:N { \exp_args:Nne\use:nn{\exp_after:wN \_@@_start: #1}{ \_@@_args:e {\cs_parameter_spec:N #1}\_@@_end: } } \cs_new:Nn \_@@_args:n { \tl_if_empty:nF{#1}{ {##\exp_args:Ne \tl_head:n {\tl_tail:n {#1}}} \_@@_args:e {\exp_args:Ne\tl_tail:n{\tl_tail:n{#1}}} } } \cs_generate_variant:Nn \_@@_args:n {e} % \end{macrocode} % \end{macro} % % \begin{macro}[EXP]{\stex_macro_definition:N} % \begin{macrocode} \cs_new:Nn \stex_macro_definition:N { \_@@_prefix:e {\cs_prefix_spec:N #1} \def\exp_not:N #1 \_@@_params:e {\cs_parameter_spec:N #1} { \stex_macro_body:N #1 } } \cs_new:Nn \_@@_prefix:n { \tl_if_empty:nF{#1}{ \str_if_eq:eeTF { \tl_range:nnn{#1}{1}{10}~ }{\tl_to_str:n{\protected}}{ \protected \_@@_prefix_long:e { \str_range:nnn{#1}{11}{-1} } }{ \_@@_prefix_long:n {#1} } } } \cs_generate_variant:Nn \_@@_prefix:n {e} \cs_new:Nn \_@@_prefix_long:n { \tl_if_empty:nF{#1}{ \str_if_eq:eeT { \tl_range:nnn{#1}{1}{10}~ }{\tl_to_str:n{\long}}{\long} } } \cs_generate_variant:Nn \_@@_prefix_long:n {e} \cs_new:Nn \_@@_params:n { \tl_if_empty:nF{#1}{ \exp_args:NNe \str_if_eq:VnTF \c_hash_str {\tl_head:n{#1}}{ #### }{ \tl_head:n{#1} } \_@@_params:e {\tl_tail:n{#1}} } } \cs_generate_variant:Nn \_@@_params:n {e} % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Persistence} % \begin{macrocode} %<@@=stex_persist> % \end{macrocode} % % We check the environment variables: % \begin{macrocode} \stex_get_env:Nn\_@@_env_str{STEX_USESMS} \str_if_empty:NF\_@@_env_str{ \exp_args:No \str_if_eq:nnF \_@@_env_str{false}{ \bool_set_true:N \c_stex_persist_mode_bool } } \stex_get_env:Nn\_@@_env_str{STEX_WRITESMS} \str_if_empty:NF\_@@_env_str{ \exp_args:No \str_if_eq:nnF \_@@_env_str{false}{ \bool_set_true:N \c_stex_persist_write_mode_bool } } % \end{macrocode} % % \begin{macro}{\stex_persist:n,\stex_persist:e} % \begin{macrocode} \iow_new:N \c_@@_sms_iow \bool_if:NTF \c_stex_persist_write_mode_bool { \stex_if_html_backend:TF{ \cs_new:Npn \stex_persist:n #1 {} \cs_new:Npn \stex_persist:e #1 {} }{ \cs_new_protected:Nn \stex_persist:n { \iow_now:Nn \c_@@_sms_iow {#1} } \cs_generate_variant:Nn \stex_persist:n {e} } }{ \cs_new:Npn \stex_persist:n #1 {} \cs_new:Npn \stex_persist:e #1 {} } % \end{macrocode} % \end{macro} % % Is called at the end of the |.sty|-file: % % \begin{macrocode} \cs_new_protected:Nn \_@@_load_file:n { \file_if_exist:nT{#1}{ \group_begin: \cs_set:Npn \stex_persist:n ##1 {} \cs_set:Npn \stex_persist:e ##1 {} \stex_debug:nn{persist}{restoring~from~sms~file} \catcode`\ =10\relax \cs:w @ @ input \cs_end:#1\relax \group_end: } } \cs_new_protected:Nn \_@@_write_only: { \iow_open:Nn \c_@@_sms_iow {\jobname.sms} \AtEndDocument{ \iow_close:N \c_@@_sms_iow } } \cs_new_protected:Nn \_@@_read_and_write: { \file_if_exist:nTF{\jobname.sms}{ \ior_open:Nn \g_tmpa_ior {\jobname.sms} \iow_open:Nn \g_tmpa_iow {\jobname.sms2} \ior_str_map_inline:Nn \g_tmpa_ior { \iow_now:Nn \g_tmpa_iow {##1} } \iow_close:N \g_tmpa_iow \ior_close:N \g_tmpa_ior \_@@_write_only: \ior_open:Nn \g_tmpa_ior {\jobname.sms2} \ior_str_map_inline:Nn \g_tmpa_ior { \iow_now:Nn \c_@@_sms_iow {##1} } \ior_close:N \g_tmpa_ior \_@@_load_file:n{\jobname.sms2} }\_@@_write_only: } \cs_new_protected:Nn \_stex_persist_read_now: { \bool_if:NTF \c_stex_persist_mode_bool { \bool_if:NTF \c_stex_persist_write_mode_bool \_@@_read_and_write: { \_@@_load_file:n{\jobname.sms} } }{ \bool_if:NT \c_stex_persist_write_mode_bool \_@@_write_only: } } % \end{macrocode} % % \end{sfragment} % % \begin{sfragment}{Files, Paths and URIs} % \begin{macrocode} %<@@=stex_path> % \end{macrocode} % % \begin{macro}{\stex_file_set:Nn, \stex_file_set:No, \stex_file_set:Nx} % \begin{macrocode} \cs_new_protected:Nn \stex_file_set:Nn { \str_if_empty:nTF {#2} { \seq_clear:N #1 }{ \exp_args:NNno \seq_set_split:Nnn #1 / { \tl_to_str:n{#2} } } } \cs_generate_variant:Nn \stex_file_set:Nn {No, Nx} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_file_resolve:Nn, \stex_file_resolve:No, \stex_file_resolve:Nx} % \begin{macrocode} \sys_if_platform_windows:TF{ \cs_new_protected:Npn \_@@_win_take:w #1#2#3 \_@@_: { \str_set:Nn \l_@@_win_drive {#1#2} \str_set:Nn \l_@@_str{#3} } \cs_new_protected:Nn \stex_file_resolve:Nn { \str_set:Nn \l_@@_str {#2} \str_clear:N \l_@@_win_drive \exp_args:NNo \str_replace_all:Nnn \l_@@_str \c_backslash_str / \exp_args:Nx \str_if_eq:nnT {\str_item:Nn \l_@@_str 2} : { \exp_after:wN \_@@_win_take:w \l_@@_str \_@@_: } \stex_file_set:No #1 \l_@@_str \_@@_canonicalize:N #1 \str_if_empty:NF \l_@@_win_drive { \seq_pop_left:NN #1 \l_@@_str \seq_put_left:No #1 \l_@@_win_drive } %\stex_debug:nn{files}{Set~\tl_to_str:n{#1}~to~\stex_file_use:N #1} } }{ \cs_new_protected:Nn \stex_file_resolve:Nn { \str_set:Nn \l_@@_str {#2} \stex_file_set:No #1 \l_@@_str \_@@_canonicalize:N #1 % \stex_debug:nn{files}{Set~\tl_to_str:n{#1}~to~\stex_file_use:N #1} } } \cs_generate_variant:Nn \stex_file_resolve:Nn {No, Nx} \cs_new_protected:Nn \_@@_canonicalize:N { \seq_if_empty:NF #1 { \seq_pop:NN #1 \l_@@_str \seq_clear:N \l_@@_seq \str_if_empty:NTF \l_@@_str { \seq_map_function:NN #1 \_@@_dodots:n \seq_put_left:Nn \l_@@_seq {} }{ \seq_push:No #1 \l_@@_str \seq_map_function:NN #1 \_@@_dodots:n } \seq_set_eq:NN #1 \l_@@_seq } } \cs_new_protected:Nn \_@@_dodots:n { \str_if_empty:nF{#1}{ \str_if_eq:nnF {#1} {.} { \str_if_eq:nnTF {#1} {..} { \seq_if_empty:NF \l_@@_seq { \seq_pop_right:NN \l_@@_seq \l_@@_str } }{ \seq_put_right:Nn \l_@@_seq {#1} } } } } % \end{macrocode} % \end{macro} % % \begin{macro}[pTF]{\stex_if_file_absolute:N} % \begin{macrocode} \sys_if_platform_windows:TF { \prg_new_conditional:Nnn \stex_if_file_absolute:N {p, T, F, TF} { \seq_if_empty:NTF #1 \prg_return_false: { \tl_set:Nx \l_@@_maybewin_str {\seq_item:Nn #1 1} \exp_args:No \tl_if_empty:nTF \l_@@_maybewin_str \prg_return_true: { \exp_args:Nx \str_if_eq:nnTF {\str_item:Nn \l_@@_maybewin_str 2} : \prg_return_true: \prg_return_false: } } } }{ \prg_new_conditional:Nnn \stex_if_file_absolute:N {p, T, F, TF} { \seq_if_empty:NTF #1 \prg_return_false: { \exp_args:Nx \tl_if_empty:nTF {\seq_item:Nn #1 1} \prg_return_true: \prg_return_false: } } } % \end{macrocode} % \end{macro} % % \begin{macro}[EXP]{\stex_file_use:N} % \begin{macrocode} \cs_new:Nn \stex_file_use:N { \seq_use:Nn #1 / } % \end{macrocode} % \end{macro} % % \begin{macro}[TF]{\stex_if_file_starts_with:NN} % \begin{macrocode} \prg_new_protected_conditional:Nnn \stex_if_file_starts_with:NN {T,F,TF} { \seq_set_eq:NN \l_@@_a_seq #1 \seq_set_eq:NN \l_@@_b_seq #2 \tl_clear:N \l_@@_return_tl \bool_while_do:nn{ \bool_not_p:n{ \bool_lazy_any_p:n{ {\seq_if_empty_p:N \l_@@_a_seq} {\seq_if_empty_p:N \l_@@_b_seq} {\bool_not_p:n{\tl_if_empty_p:N \l_@@_return_tl}} } } }{ \seq_pop_left:NN \l_@@_a_seq \l_@@_a_tl \seq_pop_left:NN \l_@@_b_seq \l_@@_b_tl \str_if_eq:NNF \l_@@_a_tl \l_@@_b_tl { \tl_set:Nn \l_@@_return_tl {\prg_return_false:} } } \tl_if_empty:NTF \l_@@_return_tl { \seq_if_empty:NTF \l_@@_b_seq \prg_return_true: \prg_return_false: } \l_@@_return_tl } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_file_split_off_ext:NN,\stex_file_split_off_lang:NN} % \begin{macrocode} \cs_new_protected:Nn \stex_file_split_off_ext:NN { \seq_set_eq:NN #1 #2 \seq_pop_right:NN #1 \l_@@_str \seq_set_split:NnV \l_@@_seq . \l_@@_str \seq_pop_right:NN \l_@@_seq \l_@@_str \seq_put_right:Nx #1 {\seq_use:Nn \l_@@_seq .} } \cs_new_protected:Nn \stex_file_split_off_lang:NN { \seq_set_eq:NN #1 #2 \seq_pop_right:NN #1 \l_@@_str \seq_set_split:NnV \l_@@_seq . \l_@@_str \seq_pop_right:NN \l_@@_seq \l_@@_str \seq_pop_right:NN \l_@@_seq \l_@@_str \exp_args:NNo \prop_if_in:NnF \c_stex_languages_prop \l_@@_str { \seq_put_right:No \l_@@_seq \l_@@_str } \seq_put_right:Nx #1 {\seq_use:Nn \l_@@_seq .} } % \end{macrocode} % \end{macro} % % URIs: % % \begin{macro}{\stex_map_uri:Nnnnn} % \begin{macrocode} \cs_set_protected:Nn \_@@_auth:n { \msg_error:nnx{stex}{error/misused-uri}{\tl_to_str:n{#1}} } \cs_set_eq:NN \_@@_path:n \_@@_auth:n \cs_set_eq:NN \_@@_module:n \_@@_auth:n \cs_set_eq:NN \_@@_name:n \_@@_auth:n \cs_set_protected:Nn \stex_map_uri:Nnnnn{ \stex_pseudogroup_with:nn{\_@@_auth:n\_@@_path:n\_@@_module:n\_@@_name:n}{ \cs_set:Npn \_@@_auth:n ##1 {#2} \cs_set:Npn \_@@_path:n ##1 {#3} \cs_set:Npn \_@@_module:n ##1 {#4} \cs_set:Npn \_@@_name:n ##1 {#5} #1 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_uri_set:Nn, \stex_uri_set:No, \stex_uri_set:Nx} % \begin{macrocode} \str_set:Nx\_@@_colonslash{\c_colon_str/} \cs_new_protected:Nn \_@@_uri_set:NnN { \str_if_empty:nTF {#2} { \msg_error:nnxx{stex}{error/invalid-uri}{\tl_to_str:n{#2}}{empty} }{ \exp_args:NNNo \exp_args:NNno \seq_set_split:Nnn #1 \_@@_colonslash { \tl_to_str:n{#2} } \seq_pop_left:NN #1 \l_@@_auth_str \seq_if_empty:NTF #1 { \msg_error:nnxx{stex}{error/invalid-uri}{\tl_to_str:n{#2}}{missing~authority} }{ \exp_args:NNnx \seq_set_split:Nnn #1 ? {\exp_args:NNo \seq_use:Nn #1 \_@@_colonslash } \seq_pop_left:NN #1 \l_@@_path #3 \l_@@_path \l_@@_path \seq_if_empty:NTF #1 { \exp_args:NNo \_@@_uri_set:Nnxnn #1 \l_@@_auth_str {\stex_file_use:N \l_@@_path} {} {} }{ \seq_pop_left:NN #1 \l_@@_mod \seq_if_empty:NTF #1 { \exp_args:NNo \_@@_uri_set:Nnxon #1 \l_@@_auth_str {\stex_file_use:N \l_@@_path} \l_@@_mod {} }{ \seq_pop_left:NN #1 \l_@@_name \seq_if_empty:NTF #1 { \exp_args:NNo \_@@_uri_set:Nnxon #2 \l_@@_auth_str {\stex_file_use:N \l_@@_path} \l_@@_mod \l_@@_name }{ \msg_error:nnxx{stex}{error/invalid-uri}{\tl_to_str:n{#2}}{too~many~?s} } } } } } \stex_debug:nn{uris}{Set~\tl_to_str:n{#1}~to~\stex_uri_use:N #1} } \cs_new_protected:Nn \_@@_uri_set:Nnnnn{ \tl_set:Nn #1 { \_@@_auth:n{ #2 } \_@@_path:n{ #3 } \_@@_module:n{ #4 } \_@@_name:n{ #5 } } } \cs_generate_variant:Nn\_@@_uri_set:Nnnnn {Nnxnn,Nnxon,Nnxoo} \cs_new_protected:Nn \stex_uri_set:Nn { \_@@_uri_set:NnN #1 {#2} \stex_file_set:No } \cs_generate_variant:Nn \stex_uri_set:Nn {No, Nx} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_uri_resolve:Nn, \stex_uri_resolve:No, \stex_uri_resolve:Nx} % \begin{macrocode} \cs_new_protected:Nn \stex_uri_resolve:Nn { \_@@_uri_set:NnN #1 {#2} \stex_file_resolve:No } \cs_generate_variant:Nn \stex_uri_resolve:Nn {No, Nx} % \end{macrocode} % \end{macro} % % \begin{macro}[EXP]{\stex_uri_use:N} % \begin{macrocode} \cs_new:Npn \_@@_uri_use:w \_@@_auth:n #1 \_@@_path:n #2 \_@@_module:n #3 \_@@_name:n #4 { #1\c_colon_str/ #2 \tl_if_empty:nF { #3 }{ ? #3 \tl_if_empty:nF { #4 }{ ? #4 } } } \cs_new:Nn \stex_uri_use:N { \exp_args:Ne \cs_if_eq:NNTF { \tl_head:N #1 } \_@@_auth:n { \exp_after:wN \_@@_uri_use:w #1 }{ \msg_error:nnnn{stex}{error/invalid-uri}{#1}{Not~a~URI} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_uri_from_repo_file:NNNn, \stex_uri_from_repo_file_nolang:NNNn} % \begin{macrocode} \cs_new_protected:Npn \stex_uri_from_repo_file_nolang:NNNn { \_@@_from_repo_file:NNNNn \stex_file_split_off_lang:NN } \cs_new_protected:Npn \stex_uri_from_repo_file:NNNn { \_@@_from_repo_file:NNNNn \stex_file_split_off_ext:NN } \cs_new_protected:Nn \_@@_from_repo_file:NNNNn { #1 \l_@@_file #4 \prop_if_exist:NTF #3 { \str_clear:N \l_@@_uri \prop_get:NnNF #3 {#5} \l_@@_uri { \prop_get:NnNF #3 {ns} \l_@@_uri { \_@@_uri_set:Nnxnn #2 {file} {\stex_file_use:N \l_@@_file} {} {} } } \str_if_empty:NF \l_@@_uri {\_@@_relativize:N #2} }{ \exp_args:NNx \_@@_uri_set:Nnxnn #2 {\tl_to_str:n{file}} {\stex_file_use:N \l_@@_file} {} {} } } \cs_new_protected:Nn \_@@_relativize:N { \seq_set_eq:NN \l_@@_seq \l_@@_file \seq_map_inline:Nn \c_stex_mathhub_file { % mathhub path \seq_pop_left:NN \l_@@_seq \l_@@_tl } \stex_file_set:Nx \l_@@_path {\prop_item:Nn \l_stex_current_archive_prop {id} } \seq_map_inline:Nn \l_@@_path { % id \seq_pop_left:NN \l_@@_seq \l_@@_tl } \seq_pop_left:NN \l_@@_seq \l_@@_tl % source \stex_uri_set:Nx #1 { \l_@@_uri / \stex_file_use:N \l_@@_seq } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_uri_from_current_file:Nn, \stex_uri_from_current_file_nolang:Nn} % \begin{macrocode} \cs_new_protected:Nn \stex_uri_from_current_file:Nn { \stex_debug:nn{docuri}{Here:~\stex_file_use:N \g_stex_current_file} \stex_uri_from_repo_file:NNNn #1 \l_stex_current_archive_prop \g_stex_current_file {#2} \stex_debug:nn{docuri}{resolved:~\stex_uri_use:N #1} } \cs_new_protected:Nn \stex_uri_from_current_file_nolang:Nn { \stex_uri_from_repo_file_nolang:NNNn #1 \l_stex_current_archive_prop \g_stex_current_file {#2} } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_uri_add_module:NNn, \stex_uri_add_module:NNo} % \begin{macrocode} \cs_new_protected:Nn \stex_uri_add_module:NNn { \exp_args:Ne \cs_if_eq:NNTF { \tl_head:N #2 } \_@@_auth:n { \stex_pseudogroup_with:nn {\_@@_auth:n\_@@_path:n\_@@_module:n\_@@_name:n} { \cs_set:Npn \_@@_module:n ##1 { \tl_if_empty:nTF{##1}{ \exp_not:N \_@@_module:n {#3} }{ \msg_error:nnn{stex}{error/invalid-dpath}{#2} } } \cs_set:Npn \_@@_name:n ##1 { \tl_if_empty:nTF{##1}{ \exp_not:N \_@@_name:n {} }{ \msg_error:nnn{stex}{error/invalid-dpath}{#2} } } \tl_set:Nx #1 {#2} } }{ \msg_error:nnnn{stex}{error/invalid-uri}{#2}{Not~a~URI} } } \cs_generate_variant:Nn \stex_uri_add_module:NNn {NNo} % \end{macrocode} % \end{macro} % % \begin{variable}{\l_stex_current_doc_uri} % \begin{macrocode} \tl_new:N \l_stex_current_doc_uri % \end{macrocode} % \end{variable} % % \begin{macro}{\stex_set_document_uri:} % \begin{macrocode} \cs_new_protected:Nn \stex_set_document_uri: { \stex_uri_from_current_file:Nn \l_stex_current_doc_uri {narr} %\stex_debug:nn{sref}{Document~URI:~\stex_uri_use:N \l_stex_current_doc_uri} } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_set_current_namespace:} % \begin{macrocode} \cs_new_protected:Nn \stex_set_current_namespace: { \stex_uri_from_current_file_nolang:Nn \l_stex_current_ns_uri {source-base} %\stex_debug:nn{modules}{Namespace~URI:~\stex_uri_use:N \l_stex_current_ns_uri} } % \end{macrocode} % \end{macro} % % We determine the PWD % % \begin{variable}{\c_stex_pwd_file,\c_stex_main_file} % \begin{macrocode} \sys_if_platform_windows:TF{ \stex_get_env:Nn\l_@@_str{CD} }{ \stex_get_env:Nn\l_@@_str{PWD} } \stex_file_resolve:No \c_stex_pwd_file \l_@@_str \seq_set_eq:NN \c_stex_main_file \c_stex_pwd_file \seq_put_right:Nx \c_stex_main_file {\jobname\tl_to_str:n{.tex}} \stex_debug:nn {files} {PWD:~\stex_file_use:N \c_stex_pwd_file} % \end{macrocode} % \end{variable} % % \end{sfragment} % % \begin{sfragment}{File Hooks} % % keeps track of file changes: % \begin{macrocode} \seq_gclear_new:N\g_@@_stack \seq_gclear_new:N\g_stex_current_file % \end{macrocode} % % \begin{macro}{\stex_filestack_push:n} % \begin{macrocode} \cs_new_protected:Nn \stex_filestack_push:n { \stex_str_if_ends_with:nnTF {#1}{.tex}{ \stex_file_resolve:No \g_stex_current_file {#1} }{ \stex_file_resolve:No \g_stex_current_file {#1.tex} } \stex_if_file_absolute:NF \g_stex_current_file { \stex_file_resolve:Nx \g_stex_current_file { \stex_file_use:N \c_stex_pwd_file / \stex_file_use:N \g_stex_current_file } } \seq_gset_eq:NN \g_stex_current_file \g_stex_current_file \exp_args:NNx \seq_gpush:Nn \g_@@_stack {\stex_file_use:N \g_stex_current_file} \_stex_every_file: } \cs_new_protected:Nn \_stex_every_file: { \stex_set_document_uri: \stex_language_from_file: \stex_set_current_namespace: } %\AtBeginDocument{\_stex_every_file:} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_filestack_pop:} % \begin{macrocode} \cs_new_protected:Nn \stex_filestack_pop: { \seq_if_empty:NF \g_@@_stack { \seq_gpop:NN \g_@@_stack \l_@@_str } \seq_if_empty:NTF \g_@@_stack { \seq_gset_eq:NN \g_stex_current_file \c_stex_main_file }{ \seq_get:NN \g_@@_stack \l_@@_str \exp_args:NNo \stex_file_set:Nn \g_stex_current_file \l_@@_str \seq_gset_eq:NN \g_stex_current_file \g_stex_current_file } \_stex_every_file: } % \end{macrocode} % \end{macro} % Hooks for the current file: % % \begin{macrocode} \cs_new_protected:Nn \stex_input_with_hooks:n { \tl_set:Nn \l_@@_do_hooks_pre_tl { \tl_gset:Nn \l_@@_do_hooks_pre_tl {} \stex_debug:nn{HERE}{Hook~for~#1^^J\meaning\CurrentFilePath^^J\CurrentFile} \tl_if_empty:NTF\CurrentFilePath{ \exp_args:No \stex_filestack_push:n {\CurrentFile} }{ \exp_args:Ne \stex_filestack_push:n { \CurrentFilePath / \CurrentFile } } } \input{#1} \stex_debug:nn{HERE}{Hook~end~for~#1} \stex_filestack_pop: } \tl_new:N \l_@@_do_hooks_pre_tl {} \AddToHook{file/before}{ \l_@@_do_hooks_pre_tl } %\AddToHook{file/after}{ \stex_filestack_pop: } % \end{macrocode} % % \end{sfragment} % % \end{sfragment} % % \begin{sfragment}{Math Archives} % \begin{macrocode} %<@@=stex_mathhub> % \end{macrocode} % % \begin{variable}{\mathhub, \c_stex_home_file,\c_stex_mathhub_file} % The path to the mathhub directory. If the \cs{mathhub}-macro is not set, % we query |kpsewhich| for the |MATHHUB| system variable. % \begin{macrocode} \sys_if_platform_windows:TF{ \stex_get_env:Nn \l_@@_str {homedrive\c_percent_str\c_percent_str homepath} }{ \stex_get_env:Nn \l_@@_str {HOME} } \stex_file_resolve:No \c_stex_home_file \l_@@_str \str_if_empty:NTF\mathhub{ \stex_get_env:Nn \l_@@_str {MATHHUB} \str_if_empty:NTF \l_@@_str { \ior_open:NnTF \g_tmpa_ior{\stex_file_use:N \c_stex_home_file/.stex/mathhub.path}{ \group_begin: \escapechar=-1\catcode`\\=12 \ior_str_get:NN \g_tmpa_ior \l_@@_str \str_gset_eq:NN \l_@@_str \l_@@_str \group_end: \ior_close:N \g_tmpa_ior \stex_debug:nn{mathhub}{MathHub~directory~determined~from~home~directory} }{ \str_clear:N \l_@@_str } }{ \stex_debug:nn{mathhub}{MathHub~directory~determined~from~environment~variable} } }{ \str_set_eq:NN \l_@@_str \mathhub } \str_if_empty:NTF \l_@@_str { \msg_warning:nn{stex}{warning/nomathhub} \exp_args:NNe \stex_file_set:Nn \c_stex_mathhub_file {\stex_file_use:N \c_stex_home_file \tl_to_str:n{/MathHub}} \seq_clear:N \c_stex_mathhub_file }{ \stex_file_resolve:No \c_stex_mathhub_file \l_@@_str \stex_if_file_absolute:NF \c_stex_mathhub_file { \exp_args:NNe \stex_file_resolve:Nn \c_stex_mathhub_file { \stex_file_use:N \c_stex_main_file / .. / \l_@@_str } } } \exp_args:NNe \str_set:Nn \mathhub {\stex_file_use:N \c_stex_mathhub_file} \stex_debug:nn{mathhub}{MATHHUB:~\mathhub} % \end{macrocode} % \end{variable} % % \begin{variable}{\l_stex_current_archive} % \begin{macro}{\stex_set_current_archive:n} % \begin{macrocode} \cs_new_protected:Nn \stex_set_current_archive:n { \stex_require_archive:n { #1 } \stex_debug:nn{mathhub}{switching~to~archive~#1} \prop_set_eq:Nc \l_stex_current_archive_prop { c_stex_mathhub_#1_manifest_prop } } % \end{macrocode} % \end{macro} % \end{variable} % % \begin{macro}{\stex_in_archive:nn} % \begin{macrocode} \cs_new_protected:Nn \stex_in_archive:nn { \cs_if_exist:NF \l_@@_cs { \cs_set:Npn \l_@@_cs ##1 {} } \stex_pseudogroup:nn{ \cs_set:Npn \l_@@_cs ##1 {#2} \tl_if_empty:nTF{#1}{ \prop_if_exist:NTF \l_stex_current_archive_prop { \exp_args:Ne \l_@@_cs {\prop_item:Nn \l_stex_current_archive_prop { id } } }{ \l_@@_cs {} } }{ \stex_set_current_archive:n{#1} \l_@@_cs {#1} } }{ \stex_pseudogroup_restore:N \l_stex_current_archive_prop \cs_set:Npn \exp_not:N \l_@@_cs ##1 { \exp_args:No \exp_not:n {\l_@@_cs {##1}} } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_require_archive:n,\stex_require_archive:o} % \begin{macrocode} \cs_new_protected:Nn \stex_require_archive:n { \prop_if_exist:cF { c_stex_mathhub_#1_manifest_prop } { \seq_if_empty:NTF \c_stex_mathhub_file { \stex_fatal_error:n{warning/nomathhub} }{ \stex_debug:nn{mathhub}{Opening~archive:~#1} \_@@_do_manifest:n { #1 } } } } \cs_generate_variant:Nn \stex_require_archive:n {o} % \end{macrocode} % \end{macro} % % Code for finding and parsing manifest files: % % \begin{macrocode} \cs_new_protected:Nn \_@@_do_manifest:n { \exp_args:Ne \_@@_find_manifest:n {\stex_file_use:N \c_stex_mathhub_file / #1} \str_if_empty:NT \l_@@_manifest_str { \stex_fatal_error:nxx{error/noarchive} {#1}{\stex_file_use:N \c_stex_mathhub_file} } \_@@_parse_manifest:n {#1} } \cs_new_protected:Nn \_@@_find_manifest:n { \str_clear:N \l_@@_manifest_str \seq_set_split:Nnn \l_@@_seq / {#1} \bool_set_true:N \l_@@_bool \bool_while_do:Nn \l_@@_bool { \tl_if_eq:NNTF \l_@@_seq \c_stex_mathhub_file { \bool_set_false:N \l_@@_bool }{ \_@@_check_manifest: \bool_if:NT \l_@@_bool { \seq_pop_right:NN \l_@@_seq \l_@@_tl } } } } \cs_generate_variant:Nn \_@@_find_manifest:n {x} \cs_new_protected:Nn \_@@_check_manifest: { \_@@_check_manifest:n {MANIFEST.MF} \bool_if:NT \l_@@_bool { \_@@_check_manifest:n {META-INF/MANIFEST.MF} \bool_if:NT \l_@@_bool { \_@@_check_manifest:n {meta-inf/MANIFEST.MF} } } } \cs_new_protected:Nn \_@@_check_manifest:n { \stex_debug:nn{mathhub}{Checking~\stex_file_use:N \l_@@_seq / #1} \file_if_exist:nT {\stex_file_use:N \l_@@_seq / #1} { \bool_set_false:N \l_@@_bool \str_set:Nx \l_@@_manifest_str {\stex_file_use:N \l_@@_seq / #1} } } \ior_new:N \c_@@_manifest_ior \cs_new_protected:Nn \_@@_parse_manifest:n { \ior_open:Nn \c_@@_manifest_ior \l_@@_manifest_str \prop_clear:N \l_@@_prop \ior_map_inline:Nn \c_@@_manifest_ior { \exp_args:NNNo \exp_args:NNNx \seq_set_split:Nnn \l_@@_seq \c_colon_str {\tl_to_str:n{##1}} \seq_pop_left:NNT \l_@@_seq \l_@@_key { \exp_args:NNo \str_set:Nn \l_@@_key \l_@@_key \str_set:Nx \l_@@_val {\seq_use:Nn \l_@@_seq :} \str_case:Nn \l_@@_key { {id} {\prop_put:Nno \l_@@_prop { id } \l_@@_val } {narration-base} {\prop_put:Nno \l_@@_prop { narr } \l_@@_val } {url-base} {\prop_put:Nno \l_@@_prop { docurl } \l_@@_val } {source-base} {\prop_put:Nno \l_@@_prop { ns } \l_@@_val } {ns} {\prop_put:Nno \l_@@_prop { ns } \l_@@_val } } } } \ior_close:N \c_@@_manifest_ior \prop_gset_eq:cN { c_stex_mathhub_#1_manifest_prop } \l_@@_prop \stex_debug:nn{mathhub}{Result:~\prop_to_keyval:N \l_@@_prop} \stex_persist:e { \prop_gset_from_keyval:cn {c_stex_mathhub_#1_manifest_prop}{ \prop_to_keyval:N \l_@@_prop } } } % \end{macrocode} % % Current MathHub archive % \begin{variable}{\c_stex_main_archive_prop, \l_stex_current_archive_prop} % \begin{macrocode} \cs_new_protected:Nn \_stex_main_archive: { \stex_if_file_starts_with:NNTF \c_stex_pwd_file \c_stex_mathhub_file { \_@@_find_manifest:x { \stex_file_use:N \c_stex_pwd_file } \str_if_empty:NTF \l_@@_manifest_str { \stex_debug:nn{mathhub}{Not~currently~in~a~MathHub~archive} }{ \_@@_parse_manifest:n { main } \prop_set_eq:NN \c_stex_main_archive_prop \c_stex_mathhub_main_manifest_prop \cs_undefine:N \c_stex_mathhub_main_manifest_prop \prop_get:NnN \c_stex_main_archive_prop {id} \l_@@_str \prop_set_eq:cN { c_stex_mathhub_\l_@@_str _manifest_prop } \c_stex_main_archive_prop \exp_args:No \stex_set_current_archive:n { \l_@@_str } \stex_debug:nn{mathhub}{Current~archive:~ \prop_item:Nn \l_stex_current_archive_prop {id} } \bool_if:NT \c_stex_persist_write_mode_bool { \tl_put_right:Nx \_stex_persist_read_now: { \stex_persist:n { \prop_gset_from_keyval:cn {c_stex_mathhub_\l_@@_str _manifest_prop}{ \prop_to_keyval:N \c_stex_main_archive_prop } \prop_gset_eq:Nc \exp_not:N \l_stex_current_archive_prop { c_stex_mathhub_\l_@@_str _manifest_prop } \prop_gset_eq:Nc \exp_not:N \c_stex_main_archive_prop { c_stex_mathhub_\l_@@_str _manifest_prop } } } } } }{ \stex_debug:nn{mathhub}{Not~currently~in~the~MathHub~directory} } } %\bool_if:NF \c_stex_persist_mode_bool { \_stex_main_archive: %} % \end{macrocode} % \end{variable} % % \end{sfragment} % % \begin{sfragment}{Documents} % % \begin{sfragment}{Title} % % Stores the title, if it exists: % \begin{macrocode} %<@@=stex_doc> \tl_new:N \g_@@_title_tl % \end{macrocode} % % \begin{macro}{\stexdoctitle} % Initital definition, will be changed at begin document: % \begin{macrocode} \cs_new_protected:Npn \stexdoctitle #1 { \tl_gset:Nn \g_@@_title_tl { #1 } \global\def\stexdoctitle##1{} } % \end{macrocode} % At begin document, we switch to: % \begin{macrocode} \cs_new_protected:Nn \_@@_set_title:n { \stex_if_smsmode:F{ \global\def\stexdoctitle##1{} \stex_debug:nn{title}{Setting~title~to:\tl_to_str:n{#1}} \tl_gset:Nn \g_@@_title_tl { #1 } \_@@_title_html: } } % \end{macrocode} % Hooks, changes and HTML: % \begin{macrocode} \cs_new_protected:Nn \_@@_title_html: { \stex_if_do_html:T{\stex_if_html_backend:T{ \stex_annotate_invisible:nn{shtml:doctitle={}}{ \hbox{\g_@@_title_tl} } }} } \AtBeginDocument { \tl_if_empty:NTF \g_@@_title_tl { \cs_set_eq:NN \stexdoctitle \_@@_set_title:n }{ \stex_debug:nn{title}{Setting~title~to:\exp_args:No\tl_to_str:n\g_@@_title_tl} \global\def\stexdoctitle#1{} \_@@_title_html: } \cs_set_eq:NN \_@@_maketitle: \maketitle \global\protected\def\maketitle{ \tl_if_empty:NF \@title { \exp_args:No \stexdoctitle \@title } \_@@_maketitle: } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Sectioning} % \begin{macrocode} \int_new:N \l_stex_docheader_sect \tl_set:Nn \stex_current_section_level {document} \cs_set_protected:Npn \currentsectionlevel { \stex_if_do_html:TF{ \stex_annotate:nn{shtml:currentsectionlevel={},shtml:capitalize=false}{} }{ \stex_current_section_level } \tl_if_exist:NT\xspace\xspace } \cs_set_protected:Npn \Currentsectionlevel { \stex_if_do_html:TF{ \stex_annotate:nn{shtml:currentsectionlevel={},shtml:capitalize=true}{} }{ \exp_args:No \_stex_capitalize:n \stex_current_section_level } \tl_if_exist:NT\xspace\xspace } \stex_if_html_backend:TF { \cs_new_protected:Nn \_sfragment_do_level:nn { \stexdoctitle{#2} \par \begin{stex_annotate_env}{shtml:section={\int_use:N \l_stex_docheader_sect}} \noindent\stex_annotate:nn{shtml:sectiontitle={}}{ \_stex_annotate_force_break:n{#2} }\par } \cs_new_protected:Nn \_sfragment_end: { \end{stex_annotate_env} } }{ \cs_new_protected:Nn \_sfragment_do_level:nn { \stexdoctitle{#2} \tl_if_empty:NTF \l_stex_key_short_tl { \use:c{#1} }{ \exp_args:Nnx \use:nn{\use:c{#1}}{[\exp_args:No \exp_not:n \l_stex_key_short_tl]} }{#2} \int_incr:N \l_stex_docheader_sect \tl_set:Nn \stex_current_section_level{#1} } \cs_new_protected:Nn \_sfragment_end: {} } \cs_new_protected:Npn \_@@_do_section:n { \int_case:nnF \l_stex_docheader_sect { {0}{\cs_if_exist:NTF \thepart {\_sfragment_do_level:nn{part}}{ \int_incr:N \l_stex_docheader_sect \_@@_do_section:n }} {1}{\cs_if_exist:NTF \thechapter {\_sfragment_do_level:nn{chapter}}{ \int_incr:N \l_stex_docheader_sect \_@@_do_section:n }} {2}{\_sfragment_do_level:nn{section}} {3}{\_sfragment_do_level:nn{subsection}} {4}{\_sfragment_do_level:nn{subsubsection}} {5}{\_sfragment_do_level:nn{paragraph}} }{\_sfragment_do_level:nn{subparagraph}} } \stex_keys_define:nnnn{ sfragment }{ \tl_clear:N \l_stex_key_short_tl }{ short .tl_set:N = \l_stex_key_short_tl }{id} \NewDocumentEnvironment{sfragment}{ O{} m}{ \stex_keys_set:nn{sfragment}{#1} \_@@_do_section:n{#2} \_stex_do_id: }{ \_sfragment_end: } %\int_incr:N \l_stex_docheader_sect \NewDocumentEnvironment{blindfragment}{}{ \_@@_skip_section: }{ \stex_if_html_backend:T{ \stex_annotate_invisible:n{~} \end{stex_annotate_env} } } \cs_new_protected:Nn \_@@_skip_section_i: { \int_case:nn \l_stex_docheader_sect { {0}{\cs_if_exist:NF \thepart { \int_incr:N \l_stex_docheader_sect \_@@_skip_section_i: }} {1}{\cs_if_exist:NF \thechapter { \int_incr:N \l_stex_docheader_sect \_@@_skip_section_i: }} } \int_incr:N \l_stex_docheader_sect } \stex_if_html_backend:TF { \cs_new_protected:Nn \_@@_skip_section: { \_@@_skip_section_i: \begin{stex_annotate_env}{shtml:skipsection={\int_use:N \l_stex_docheader_sect}} \stex_annotate_invisible:n{~} } }{ \cs_set_eq:NN \_@@_skip_section: \_@@_skip_section_i: } \cs_new_protected:Nn \_@@_skip_fragment:n { \stepcounter{#1} } \cs_new_protected:Npn \skipfragment { \int_case:nnF \l_stex_docheader_sect { {0}{\cs_if_exist:NTF \thepart {\_@@_skip_fragment:n{part}}{ \int_incr:N \l_stex_docheader_sect \skipfragment }} {1}{\cs_if_exist:NTF \thechapter {\_@@_skip_fragment:n{chapter}}{ \int_incr:N \l_stex_docheader_sect \skipfragment }} {2}{\_@@_skip_fragment:n{section}} {3}{\_@@_skip_fragment:n{subsection}} {4}{\_@@_skip_fragment:n{subsubsection}} {5}{\_@@_skip_fragment:n{paragraph}} }{\_@@_skip_fragment:n{subparagraph}} } % \end{macrocode} % % \begin{macro}{\setsectionlevel} % \begin{macrocode} \cs_new_protected:Npn \setsectionlevel #1 { \str_case:nnF{#1}{ {part}{\int_set:Nn \l_stex_docheader_sect 0} {chapter}{\int_set:Nn \l_stex_docheader_sect 1} {section}{\int_set:Nn \l_stex_docheader_sect 2} {subsection}{\int_set:Nn \l_stex_docheader_sect 3} {subsubsection}{\int_set:Nn \l_stex_docheader_sect 4} {paragraph}{\int_set:Nn \l_stex_docheader_sect 5} }{ \int_set:Nn \l_stex_docheader_sect 6 } \cs_if_eq:NNTF\@onlypreamble\@notprerr{ \stex_annotate_invisible:nn{shtml:sectionlevel={\int_use:N\l_stex_docheader_sect}}{} }{} } \stex_if_html_backend:T{ \cs_new_protected:Nn \_@@_check_topsect: { \int_case:nnF \l_stex_docheader_sect { {0}{\cs_if_exist:NTF \thepart { \stex_annotate_invisible:nn{shtml:sectionlevel=0}{} }{ \int_incr:N \l_stex_docheader_sect \_@@_check_topsect: }} {1}{\cs_if_exist:NTF \thechapter { \stex_annotate_invisible:nn{shtml:sectionlevel=1}{} }{ \int_incr:N \l_stex_docheader_sect \_@@_check_topsect: }} }{ \stex_annotate_invisible:nn{shtml:sectionlevel={\int_use:N\l_stex_docheader_sect}}{} } } \AtBeginDocument{\_@@_check_topsect:} } \AtBeginDocument{ \bool_if:NF \c_stex_no_frontmatter_bool { \cs_if_exist:NTF\frontmatter{ \let\_@@_orig_frontmatter\frontmatter \let\frontmatter\relax }{ \tl_set:Nn\_@@_orig_frontmatter{ \clearpage %\@mainmatterfalse \pagenumbering{roman} } } \cs_if_exist:NTF\backmatter{ \let\_@@_orig_backmatter\backmatter \let\backmatter\relax }{ \tl_set:Nn\_@@_orig_backmatter{ \clearpage %\@mainmatterfalse \pagenumbering{roman} } } \newenvironment{frontmatter}{ \_@@_orig_frontmatter }{ \cs_if_exist:NTF\mainmatter{ \mainmatter }{ \clearpage %\@mainmattertrue \pagenumbering{arabic} } } \newenvironment{backmatter}{ \_@@_orig_backmatter }{ \cs_if_exist:NTF\mainmatter{ \mainmatter }{ \clearpage %\@mainmattertrue \pagenumbering{arabic} } } } } % \end{macrocode} % \end{macro} % \end{sfragment} % % % \begin{sfragment}{References} % \begin{macrocode} %<@@=stex_refs> % \end{macrocode} % % References are stored in the file |\jobname.sref|, to enable % cross-referencing external documents. % \begin{macrocode} \iow_new:N \c_@@_iow \AtBeginDocument{\iow_open:Nn \c_@@_iow {\jobname.sref}} \AtEndDocument{\iow_close:N \c_@@_iow} % \end{macrocode} % % The following macros are written to the |.aux|-file, and hence % use \LaTeX2e character code scheme: % % \begin{macrocode} \cs_new_protected:Npn \STEXInternalSrefRestoreTarget #1#2#3#4#5 {} \cs_new_protected:Npn \STEXInternalSetSrefSymURL #1 #2 { \str_gset:cn{g_stex_sref_sym_\tl_to_str:n{#1}_target}{#2} } % \end{macrocode} % % \begin{macro}{\stex_ref_new_doc_target:n,\sreflabel} % \begin{macrocode} \seq_new:N \g_@@_files_seq \int_new:N \l_@@_unnamed_counter_int \cs_new_protected:Nn \_stex_ref_new_id:n { \str_if_empty:nTF {#1}{ \int_gincr:N \l_@@_unnamed_counter_int \str_set:Nx \l_@@_str {REF\int_use:N \l_@@_unnamed_counter_int} }{ \str_set:Nn \l_@@_str {#1} } \str_set:Nx \l_stex_ref_url_str {\stex_uri_use:N \l_stex_current_doc_uri ? \l_@@_str} } \cs_new_protected:Nn \stex_ref_new_doc_target:n { \_stex_ref_new_id:n{#1} %\stex_uri_add_module:NNo \l_@@_uri \l_stex_current_doc_uri \l_@@_str %\stex_debug:nn{sref}{New~document~target:~\stex_uri_use:N \l_@@_uri} \_@@_add_doc_ref:xo {\stex_uri_use:N \l_stex_current_doc_uri} \l_@@_str \stex_if_smsmode:F { \iow_now:Nx \c_@@_iow { \STEXInternalSrefRestoreTarget {\stex_uri_use:N \l_stex_current_doc_uri} {\l_@@_str} {\@currentcounter} {\@currentlabel} { \tl_if_exist:NT\@currentlabelname{ \exp_args:No\exp_not:n\@currentlabelname } } } \exp_args:Nx \label {sref@\l_stex_ref_url_str} \stex_if_do_html:T { \pdfdest name "sref@\l_stex_ref_url_str" xyz\relax } } } \NewDocumentCommand \sreflabel {m} {\stex_ref_new_doc_target:n {#1}} \cs_new_protected:Nn \_@@_add_doc_ref:nn { \seq_if_in:NnTF \g_@@_files_seq {#1} { \seq_if_in:cnF {g_@@_#1_seq}{#2}{ \seq_gput_left:cn{g_@@_#1_seq}{#2} } }{ \seq_gput_right:Nn \g_@@_files_seq {#1} \seq_new:c{g_@@_#1_seq} \seq_gput_left:cn{g_@@_#1_seq}{#2} } } \cs_generate_variant:Nn \_@@_add_doc_ref:nn {xo,xx} % \end{macrocode} % \end{macro} % % \begin{macro}{\sref,\extref} % Optional arguments: % \begin{macrocode} \stex_keys_define:nnnn{sref / 1}{}{ % TODO get rid of this fallback .code:n = {}, pre .code:n = {}, post .code:n = {} }{archive file} \stex_keys_define:nnnn{sref / 2}{}{}{archive file, title} \str_new:N \l_@@_default_archive_str \str_new:N \l_@@_default_file_str \tl_new:N \l_@@_default_title_tl \cs_set_protected:Nn \_@@_set_keys_b:n { \tl_if_empty:nTF{#1}{ \str_set_eq:NN \l_stex_key_archive_str \l_@@_default_archive_str \str_set_eq:NN \l_stex_key_file_str \l_@@_default_file_str \tl_set_eq:NN \l_stex_key_title_tl \l_@@_default_title_tl }{ \stex_keys_set:nn{ sref / 2 }{ #1 } } } \newcommand\srefsetin[3][]{ \str_set:Nx \l_@@_default_archive_str {#1} \str_set:Nx \l_@@_default_file_str {#2} \tl_set:Nn \l_@@_default_title_tl {#3} } % \end{macrocode} % % Auxiliary methods: % % \begin{macrocode} \cs_new_protected:Nn \_@@_find_uri:n { \str_clear:N \l_@@_uri_str \stex_debug:nn{sref}{ File:~\l_stex_key_file_str^^J Repo:\l_stex_key_archive_str } \str_if_empty:NTF \l_stex_key_file_str { \stex_debug:nn{sref}{Empty.~Checking~current~file~for~#1} \seq_if_exist:cT{g_@@_\stex_uri_use:N \l_stex_current_doc_uri _seq}{ \exp_args:Nnx \_@@_find_uri_in_file:nnn{#1} {\stex_uri_use:N \l_stex_current_doc_uri}\seq_map_break: } \str_if_empty:NT \l_@@_uri_str { \seq_map_inline:Nn \g_@@_files_seq { \_@@_find_uri_in_file:nnn{#1}{##1}{\seq_map_break:n{\seq_map_break:}} } } }{ \str_if_empty:NTF \l_stex_key_archive_str { \prop_if_exist:NTF \l_stex_current_archive_prop { \_@@_find_uri_in_prop_file:N \l_stex_current_archive_prop }{ \stex_file_resolve:Nx \l_@@_file { \stex_file_use:N \g_stex_current_file / .. / \l_stex_key_file_str } \str_set:Nx \l_@@_uri_str { file:/ \stex_file_use:N \l_@@_file } } }{ \stex_require_archive:o \l_stex_key_archive_str \prop_set_eq:Nc \l_@@_prop { c_stex_mathhub_\l_stex_key_archive_str _manifest_prop } \_@@_find_uri_in_prop_file:N \l_@@_prop } } } \cs_new_protected:Nn \_@@_find_uri_in_prop_file:N { \str_set:Nx \l_@@_uri_str { \stex_file_use:N \c_stex_mathhub_file / \prop_item:Nn #1 {id} / source / \l_stex_key_file_str .sref } \stex_file_resolve:No \l_@@_file \l_@@_uri_str \stex_uri_from_repo_file:NNNn \l_@@_uri #1 \l_@@_file {narr} \str_set:Nx \l_@@_uri_str {\stex_uri_use:N \l_@@_uri} } \cs_new_protected:Nn \_@@_find_uri_in_file:nnn { \stex_debug:nn{sref}{Checking~file~#2} \seq_map_inline:cn{g_@@_#2_seq}{ \str_if_eq:nnT{#1}{##1}{ \str_set:Nx \l_@@_uri_str {\stex_uri_use:N \l_stex_current_doc_uri} \stex_debug:nn{sref}{Found.} #3 } } } % \end{macrocode} % Doing the actual referencing: % \begin{macrocode} \cs_new_protected:Nn \_@@_do_autoref:n { \cs_if_exist:cTF{autoref}{ \exp_args:Nx\autoref{sref@#1} }{ \exp_args:Nx\ref{sref@#1} } } \cs_new_protected:Nn \_@@_do_sref:nn { \str_if_empty:NTF \l_@@_uri_str { \str_if_empty:NTF \l_stex_key_file_str { \stex_debug:nn{sref}{autoref~on~\stex_uri_use:N \l_stex_current_doc_uri?#1} \exp_args:Ne \_@@_do_autoref:n{\stex_uri_use:N \l_stex_current_doc_uri ? #1} }{ \stex_debug:nn{sref}{srefin~on~#1} \_@@_set_keys_b:n{ #2 } \_@@_do_sref_in:n{#1} } }{ \exp_args:NNo \seq_if_in:NnTF \g_@@_files_seq \l_@@_uri_str { \stex_debug:nn{sref}{Using~ref~file~\l_@@_uri_str} \exp_args:Nnx \seq_if_in:cnTF{g_stex_ref_\l_@@_uri_str _seq}{\detokenize{#1}}{ \stex_debug:nn{sref}{Reference~found~in~ref~files;~autoref~on~\l_@@_uri_str?#1} \_@@_do_autoref:n{\l_@@_uri_str?#1} }{ \str_if_empty:NTF \l_stex_key_file_str { \stex_debug:nn{sref}{in~empty;~autoref~on~\l_@@_uri_str?#1} \_@@_do_autoref:n{\l_@@_uri_str?#1} }{ \stex_debug:nn{sref}{in~non-empty;~srefin~on~\l_@@_uri_str?#1} \_@@_set_keys_b:n{ #2 } \_@@_do_sref_in:n{#1} } } }{ \stex_debug:nn{sref}{No~ref~file~found~for~\l_@@_uri_str} \str_if_empty:NTF \l_stex_key_file_str { \stex_debug:nn{sref}{in~empty;~autoref~on~\l_@@_uri_str?#1} \_@@_do_autoref:n{\l_@@_uri_str?#1} }{ \stex_debug:nn{sref}{in~non-empty;~srefin~on~\l_@@_uri_str?#1} \_@@_set_keys_b:n{ #2 } \_@@_do_sref_in:n{#1} } } } } \cs_new_protected:Nn \_@@_do_sref_in:n { \stex_debug:nn{sref}{In: \l_stex_key_file_str^^JRepo:\l_stex_key_archive_str} \stex_debug:nn{sref}{URI: \l_@@_uri_str?#1} \tl_if_exist:cTF{r@sref@\l_@@_uri_str?#1}{ \_@@_do_autoref:n{\l_@@_uri_str?#1} }{ %\msg_warning:nnn{stex}{warning/smsmissing}{} \group_begin:\catcode13=9\relax\catcode10=9\relax \str_if_empty:NTF \l_stex_key_archive_str { \prop_if_exist:NTF \l_stex_current_archive_prop { \str_set:Nx \l_@@_file_str { \stex_file_use:N \c_stex_mathhub_file / \prop_item:Nn \l_stex_current_archive_prop { id } / source / \l_stex_key_file_str .sref } }{ \str_set:Nx \l_@@_file_str { \stex_file_use:N \g_stex_current_file / .. / \l_stex_key_file_str . sref } } }{ \str_set:Nx \l_@@_file_str { \stex_file_use:N \c_stex_mathhub_file / \l_stex_key_archive_str / source / \l_stex_key_file_str . sref } } \stex_file_resolve:No \l_@@_file \l_@@_file_str \str_set:Nx \l_@@_file_str {\stex_file_use:N \l_@@_file } \stex_debug:nn{sref}{File: \l_@@_file_str } \exp_args:NNNx \exp_args:No \str_if_eq:nnTF \l_@@_file_str {\stex_file_use:N\c_stex_pwd_file / \jobname.sref}{ \_@@_do_autoref:n{ \str_if_empty:NF\l_@@_uri_str{\l_@@_uri_str?}#1 } }{ \exp_args:No \IfFileExists \l_@@_file_str { \tl_clear:N \l_@@_return_tl \str_set:Nn \l_@@_id_str {#1} \let\STEXInternalSrefRestoreTarget\_@@_restore_target:nnnnn \use:c{@ @ input}{\l_@@_file_str} \exp_args:No \tl_if_empty:nTF \l_@@_return_tl { \exp_args:Nnno \msg_warning:nnnn{stex}{warning/smslabelmissing}\l_@@_file_str{#1} \_@@_do_autoref:n{ \str_if_empty:NF\l_@@_uri_str{\l_@@_uri_str?}#1 } }{ \l_@@_return_tl } }{ \exp_args:Nnno \msg_warning:nnn{stex}{warning/smsmissing}\l_@@_file_str \_@@_do_autoref:n{ \str_if_empty:NF\l_@@_uri_str{\l_@@_uri_str?}#1 } } } \group_end: } } \cs_new_protected:Nn \_@@_do_return:nnnn { \tl_set:Nn \l_@@_return_tl { \stex_annotate:nn{shtml:sref={#4},shtml:srefin={\l_@@_file_str}}{ \use:c{#3autorefname}~#1\tl_if_empty:nF{#2}{~(#2)} \tl_if_empty:NF\l_stex_key_title_tl{ {}~in~\l_stex_key_title_tl } } } } \cs_new_protected:Nn \_@@_restore_target:nnnnn { \str_if_empty:NTF \l_@@_uri_str { \exp_args:No \str_if_eq:nnT \l_@@_id_str {#2}{ \_@@_do_return:nnnn{#4}{#5}{#3}{#1?#2} } }{ \stex_debug:nn{sref}{\l_@@_uri_str{}~ == ~ #1 ~ ?} \exp_args:No \str_if_eq:nnT \l_@@_uri_str {#1}{ \stex_debug:nn{sref}{\l_@@_id_str~ == ~ #2 ~ ?} \exp_args:No \str_if_eq:nnT \l_@@_id_str {#2}{ \stex_debug:nn{sref}{success!} \_@@_do_return:nnnn{#4}{#5}{#3}{#1?#2} \endinput } } } } % \end{macrocode} % The actual macros: % \begin{macrocode} \NewDocumentCommand \sref { O{} m O{}}{ \stex_keys_set:nn { sref / 1 }{ #1 } \_@@_find_uri:n { #2 } \_@@_do_sref:nn{#2}{#3} } \NewDocumentCommand \extref { O{} m m}{ \stex_keys_set:nn { sref / 1 }{ #1 } \_@@_find_uri:n { #2 } \_@@_set_keys_b:n{ #3 } \str_if_empty:NT \l_stex_key_file_str { \msg_error:nn{stex}{error/extrefmissing} } \_@@_do_sref_in:n{#2} } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_ref_new_sym_target:n} % \begin{macrocode} \cs_new_protected:Nn \stex_ref_new_symbol:n { \cs_if_exist:cF{r@sref@sym@\tl_to_str:n{#1}}{ \_@@_new_symbol:n{#1} } } \cs_new_protected:Nn \_stex_sref_do_aux:n { #1 \iow_now:Nn \@auxout {#1} } \cs_new_protected:Nn \_@@_new_symbol:n { \prop_if_exist:NTF \l_stex_current_archive_prop { \prop_get:NnNTF \l_stex_current_archive_prop {docurl} \l_@@_str { \exp_args:Ne \_stex_sref_do_aux:n { \STEXInternalSetSrefSymURL{#1}{\l_@@_str / symbol? #1} } }{ \_stex_sref_do_aux:n { \STEXInternalSetSrefSymURL{#1}{} } } }{ \_stex_sref_do_aux:n { \STEXInternalSetSrefSymURL{#1}{} } } } \cs_new_protected:Nn \stex_ref_new_sym_target:n { \cs_if_exist:NT \hypertarget{ \exp_args:Ne \hypertarget{\tl_to_str:n{sref@sym@ #1}}{} \str_gset:cx{\tl_to_str:n{r@sref@sym@ #1}}{\tl_to_str:n{sref@sym@ #1}} } } \cs_new_protected:Nn \stex_ref_new_sym_target:nn { \str_if_eq:nnTF{#1}{#2}{ \stex_ref_new_sym_target:n{#1} }{ \str_gset:cn{g_stex_sref_sym_ #1 _label}{#2} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\srefsym} % \begin{macrocode} \NewDocumentCommand \srefsym { m m}{ \stex_get_symbol:n { #1 } \exp_args:Ne \_@@_sym_aux:nn{\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } \cs_new_protected:Npn \_@@_do_internal_link:nn #1 { \cs_if_exist:NTF \hyperlink { \hyperlink{#1} }\use:n } \cs_new_protected:Npn \_@@_do_url_link:nn { \cs_if_exist:NTF \href \href \use_ii:nn } \cs_new_protected:Npn \_@@_sym_aux:nn #1 { \cs_if_exist:cTF{\tl_to_str:n{r@sref@sym@#1}}{ \exp_args:Ne \_@@_do_internal_link:nn{\tl_to_str:n{sref@sym@#1}} }{ \str_if_exist:cTF{g_stex_sref_sym_#1_label}{ \exp_args:Ne \_@@_sym_aux:nn{\use:c{g_stex_sref_sym_#1_label}} }{ \str_if_empty:cTF{g_stex_sref_sym_#1_target}{ \exp_args:Ne \_@@_do_internal_link:nn{\tl_to_str:n{sref@sym@#1}} }{ \exp_args:Ne \_@@_do_url_link:nn{\use:c{g_stex_sref_sym_#1_target}} } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\srefsymuri} % \begin{macrocode} \cs_new_protected:Npn \srefsymuri #1 { \_@@_sym_aux:nn{#1} } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Inputs} % \begin{macrocode} %<@@=stex_inputs> % \end{macrocode} % % \begin{macro}{\stex_resolve_path_pair:Nnn,\stex_resolve_path_pair:Nxx} % \begin{macrocode} \cs_new_protected:Nn \stex_resolve_path_pair:Nnn { \stex_debug:nn{resolving~path}{#3~in~[#2]} \str_if_empty:nTF{#2}{ \prop_if_exist:NTF \l_stex_current_archive_prop { \str_set:Nx #1 {\stex_file_use:N \c_stex_mathhub_file / \prop_item:Nn \l_stex_current_archive_prop { id } / source / #3} \stex_debug:nn{resolving~path}{In~current~archive~ \prop_item:Nn \l_stex_current_archive_prop { id } ;~result:~#1} }{ \str_set:Nx #1 {\stex_file_use:N \c_stex_pwd_file / .. / #3 } \stex_debug:nn{resolving~path}{No~current~archive;~result:~#1} } }{ \stex_require_archive:n { #2 } \str_set:Nx #1 {\stex_file_use:N \c_stex_mathhub_file / \prop_item:cn {c_stex_mathhub_#2_manifest_prop} { id } / source / #3} \stex_debug:nn{resolving~path}{result:~#1} } } \cs_generate_variant:Nn \stex_resolve_path_pair:Nnn {Nxx} % \end{macrocode} % \end{macro} % % \begin{macro}{\inputref,\mhinput,\ifinputref} % \begin{macrocode} \newif \ifinputref \inputreffalse \cs_new_protected:Nn \_@@_mhinput:nn { \stex_in_archive:nn {#1} { \ifinputref \stex_input_with_hooks:n{ \stex_file_use:N \c_stex_mathhub_file / ##1 / source / #2 } \else \inputreftrue \stex_input_with_hooks:n{ \stex_file_use:N \c_stex_mathhub_file / ##1 / source / #2 } \inputreffalse \fi } } \NewDocumentCommand \mhinput { O{} m}{ \exp_args:NNx\exp_args:Nnx\_@@_mhinput:nn{ \tl_to_str:n{#1} }{ \tl_to_str:n{#2} } } \cs_new_protected:Nn \_@@_inputref_html:nn { \str_clear:N \l_tmpa_str \prop_get:NnNF \l_stex_current_archive_prop { narr } \l_tmpa_str { \prop_get:NnNF \l_stex_current_archive_prop { ns } \l_tmpa_str {} } \tl_if_empty:nTF{ #1 }{ \IfFileExists{#2}{ \ifvmode\noindent\fi\stex_annotate_invisible:nn{shtml:inputref={ \l_tmpa_str / #2 }}{} }{ \stex_input_with_hooks:n{#2} } }{ \IfFileExists{ \stex_file_use:N \c_stex_mathhub_file / #1 / source / #2 }{ \ifvmode\noindent\fi\stex_annotate_invisible:nn{shtml:inputref={ \l_tmpa_str / #2 }}{} }{ \input{ \stex_file_use:N \c_stex_mathhub_file / #1 / source / #2 } } } } \cs_new_protected:Nn \_@@_inputref_pdf:nn { \begingroup \inputreftrue \tl_if_empty:nTF{ #1 }{ \stex_input_with_hooks:n{#2} }{ \stex_input_with_hooks:n{ \stex_file_use:N \c_stex_mathhub_file / #1 / source / #2 } } \endgroup } \cs_new_protected:Nn \_@@_inputref:nn { \stex_in_archive:nn {#1} { \stex_if_html_backend:TF \_@@_inputref_html:nn \_@@_inputref_pdf:nn {##1}{#2} } } \NewDocumentCommand \inputref { O{} m}{ \exp_args:NNx \exp_args:Nnx \_@@_inputref:nn{ \tl_to_str:n{#1} }{ \tl_to_str:n{#2} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\addmhbibresource} % \begin{macrocode} \cs_new_protected:Nn \_@@_bibresource:n { \_@@_up_archive:nn{#1}{bib} \seq_if_empty:NTF \l_@@_libinput_files_seq { \msg_error:nnxx{stex}{error/nofile}{\exp_not:N\addmhbibresource}{#1.bib} }{ \seq_map_inline:Nn \l_@@_libinput_files_seq { \addbibresource{ ##1 } } } } \newcommand\addmhbibresource[2][]{ \tl_if_empty:nTF{#1}{ \_@@_bibresource:n{#2} }{ \stex_in_archive:nn{#1}{\_@@_bibresource:n{#2}} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\IfInputref} % \begin{macrocode} \stex_if_html_backend:TF{ \newcommand \IfInputref[2]{ \stex_annotate:nn{shtml:ifinputref=true}{#1} \stex_annotate:nn{shtml:ifinputref=false}{#2} } }{ \newcommand \IfInputref[2]{ \ifinputref #1 \else #2 \fi } } % \end{macrocode} % \end{macro} % % \begin{macro}{\libinput} % \begin{macrocode} \cs_new_protected:Nn \_@@_up_archive:nn { \prop_if_exist:NF \l_stex_current_archive_prop { \msg_error:nnn{stex}{error/notinarchive}\libinput } \prop_get:NnNF \l_stex_current_archive_prop {id} \l_@@_id_str { \msg_error:nnn{stex}{error/notinarchive}\libinput } \seq_clear:N \l_@@_libinput_files_seq \seq_set_eq:NN \l_@@_path_seq \c_stex_mathhub_file \seq_set_split:NnV \l_@@_id_seq / \l_@@_id_str \bool_while_do:nn { ! \seq_if_empty_p:N \l_@@_id_seq }{ \str_set:Nx \l_@@_path_str {\stex_file_use:N \l_@@_path_seq / meta-inf / lib / #1.#2} \IfFileExists{ \l_@@_path_str }{ \exp_args:NNo \seq_if_in:NnF \l_@@_libinput_files_seq \l_@@_path_str { \seq_put_right:No \l_@@_libinput_files_seq \l_@@_path_str } }{} \seq_pop_left:NN \l_@@_id_seq \l_@@_path_str \seq_put_right:No \l_@@_path_seq \l_@@_path_str } \str_set:Nx \l_@@_path_str {\stex_file_use:N \l_@@_path_seq / lib / #1.#2} \IfFileExists{ \l_@@_path_str }{ \exp_args:NNo \seq_if_in:NnF \l_@@_libinput_files_seq \l_@@_path_str { \seq_put_right:No \l_@@_libinput_files_seq \l_@@_path_str } }{} } \cs_new_protected:Nn \_@@_libinput:n { \_@@_up_archive:nn{#1}{tex} \seq_if_empty:NTF \l_@@_libinput_files_seq { \msg_error:nnxx{stex}{error/nofile}{\exp_not:N\libinput}{#1.tex} }{ \seq_map_inline:Nn \l_@@_libinput_files_seq { \input{ ##1 } } } } \newcommand \libinput [2][] { \tl_if_empty:nTF{#1}{ \_@@_libinput:n{#2} }{ \stex_in_archive:nn{#1}{\_@@_libinput:n{#2}} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\libusepackage} % \begin{macrocode} \newcommand\libusepackage[2][]{ \_@@_up_archive:nn{#2}{sty} \int_compare:nNnTF {\seq_count:N \l_@@_libinput_files_seq} = 1 { \str_set:Nx \l_@@_tmp_str {\seq_item:Nn \l_@@_libinput_files_seq 1} \exp_args:Nne \use:n {\usepackage[#1]} { \str_range:Nnn\l_@@_tmp_str 1 {-5} } }{ \stex_fatal_error:nnn{error/nofile}{\libusepackage}{#1.sty} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\mhgraphics,\cmhgraphics,\lstinputmhlisting,\clstinputmhlisting,\mhtikzinput,\cmhtikzinput} % \begin{macrocode} \str_new:N \l_@@_gin_repo_str \ltx@ifpackageloaded{graphicx}{\use:n}{\AtEndOfPackageFile{graphicx}}{ \define@key{Gin}{archive}{ \tl_set:Nx\Gin@mhrepos{\stex_file_use:N \c_stex_mathhub_file / #1 / source /} } \providecommand\mhgraphics[2][]{ \tl_set:Nx\Gin@mhrepos{ \stex_file_use:N \c_stex_mathhub_file / \prop_item:Nn \l_stex_current_archive_prop {id} / source / } \setkeys{Gin}{#1} \includegraphics[#1]{ \Gin@mhrepos #2 } } \providecommand\cmhgraphics[2][]{\begin{center}\mhgraphics[#1]{#2}\end{center}} } \ltx@ifpackageloaded{listings}{\use:n}{\AtEndOfPackageFile{listings}}{ \define@key{lst}{archive}{ \def\lst@mhrepos{\stex_file_use:N \c_stex_mathhub_file / #1 / source /} } \newcommand\lstinputmhlisting[2][]{% \def\lst@mhrepos{ \stex_file_use:N \c_stex_mathhub_file / \prop_item:Nn \l_stex_current_archive_prop {id} / source / } \setkeys{lst}{#1}% \lstinputlisting[#1]{\lst@mhrepos #2}} \newcommand\clstinputmhlisting[2][]{\begin{center}\lstinputmhlisting[#1]{#2}\end{center}} } \ltx@ifpackageloaded{tikzinput}{\use:n}{\AtEndOfPackageFile{tikzinput}}{ \define@key{Gin}{archive}{ \str_set:Nn \l_@@_gin_repo_str {#1} \def\Gin@mhrepos{\stex_file_use:N \c_stex_mathhub_file / #1 / source /} } \newcommand\mhtikzinput[2][]{% \str_clear:N \l_@@_gin_repo_str \def\Gin@mhrepos{ \stex_file_use:N \c_stex_mathhub_file / \prop_item:Nn \l_stex_current_archive_prop {id} / source / } \setkeys{Gin}{#1}% \exp_args:No \stex_in_archive:nn \l_@@_gin_repo_str { \tikzinput[#1]{\Gin@mhrepos #2} } } \newcommand\cmhtikzinput[2][]{\begin{center}\mhtikzinput[#1]{#2}\end{center}} } % \end{macrocode} % \end{macro} % % \begin{macro}{\libusetikzlibrary} % \begin{macrocode} \cs_new_protected:Nn \_@@_usetikzlibrary_i:nn { \pgfkeys@spdef\pgf@temp{#1} \expandafter\ifx\csname tikz@library@\pgf@temp @loaded\endcsname\relax% \expandafter\global\expandafter\let\csname tikz@library@\pgf@temp @loaded\endcsname=\pgfutil@empty% \expandafter\edef\csname tikz@library@#1@atcode\endcsname{\the\catcode`\@} \expandafter\edef\csname tikz@library@#1@barcode\endcsname{\the\catcode`\|} \expandafter\edef\csname tikz@library@#1@dollarcode\endcsname{\the\catcode`\$} \catcode`\@=11 \catcode`\|=12 \catcode`\$=3 \pgfutil@InputIfFileExists{#2}{}{} \catcode`\@=\csname tikz@library@#1@atcode\endcsname \catcode`\|=\csname tikz@library@#1@barcode\endcsname \catcode`\$=\csname tikz@library@#1@dollarcode\endcsname } \cs_new_protected:Nn \_@@_usetikzlibrary:n{ \_@@_up_archive:nn{tikzlibrary#1}{code.tex} \int_compare:nNnTF {\seq_count:N \l_@@_libinput_files_seq} = 1 { \exp_args:Nne \_@@_usetikzlibrary_i:nn{#1}{ \seq_item:Nn \l_@@_libinput_files_seq 1 } }{ \stex_fatal_error:nnn{error/nofile}{\libusetikzlibrary}{tikzlibrary#1.code.tex} } } \newcommand \libusetikzlibrary [2][] { \cs_if_exist:NF \usetikzlibrary { \msg_error:nnx{stex}{error/notikz}{\tl_to_str:n{\libusetikzlibrary}} } \tl_if_empty:nTF{#1}{ \_@@_usetikzlibrary:n{#2} }{ \stex_in_archive:nn{#1}{\_@@_usetikzlibrary:n{#2}} } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \end{sfragment} % % \begin{sfragment}{SMS Mode} % \begin{macrocode} %<@@=stex_smsmode> % \end{macrocode} % % Macros and environments allowed in sms mode: % \begin{macrocode} \tl_new:N \g_@@_allowed_tl \tl_new:N \g_@@_allowed_escape_tl \seq_new:N \g_@@_allowedenvs_seq % \end{macrocode} % % \begin{macro}{\stex_sms_allow:N,\stex_sms_allow_escape:N,\stex_sms_allow_env:n} % \begin{macrocode} \cs_new_protected:Nn \stex_sms_allow:N { \tl_gput_right:Nn \g_@@_allowed_tl {#1} } \cs_new_protected:Nn \stex_sms_allow_escape:N { \tl_gput_right:Nn \g_@@_allowed_escape_tl {#1} } \cs_new_protected:Nn \stex_sms_allow_env:n { \exp_args:NNx \seq_gput_right:Nn \g_@@_allowedenvs_seq {\tl_to_str:n{#1}} } % \end{macrocode} % \end{macro} % Some initial allowed macros: % \begin{macrocode} \stex_sms_allow:N \makeatletter \stex_sms_allow:N \makeatother \stex_sms_allow:N \ExplSyntaxOn \stex_sms_allow:N \ExplSyntaxOff \stex_sms_allow:N \rustexBREAK % \end{macrocode} % % \begin{macro}[pTF]{\stex_if_smsmode:} % \begin{macrocode} \bool_new:N \g_@@_bool \bool_set_false:N \g_@@_bool \prg_new_conditional:Nnn \stex_if_smsmode: { p, T, F, TF } { \bool_if:NTF \g_@@_bool \prg_return_true: \prg_return_false: } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_sms_allow_import:Nn, \stex_sms_allow_import_env:nn} % \begin{macrocode} \tl_new:N \g_@@_allowed_import_tl \seq_new:N \g_@@_allowed_import_env_seq \cs_new_protected:Nn \stex_sms_allow_import:Nn { \tl_gput_right:Nn \g_@@_allowed_import_tl {#1} \tl_gset:cn{\tl_to_str:n{#1}~-~smsmode} {#2} } \cs_new_protected:Nn \stex_sms_allow_import_env:nn { \exp_args:NNx \seq_gput_right:Nn \g_@@_allowed_import_env_seq {\tl_to_str:n{#1}} \tl_gset:cn{\tl_to_str:n{#1}~-~env~-~smsmode} {#2} } \tl_new:N \g_stex_sms_import_code % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_file_in_smsmode:nn,\stex_file_in_smsmode:on} % \begin{macrocode} \cs_new_protected:Nn \_@@_in_smsmode:n { \stex_suppress_html:n { \vbox_set:Nn \l_tmpa_box { \bool_set_true:N \g_@@_bool \bool_set_false:N \_stex_html_do_output_bool #1 } %\box_clear:N \l_tmpa_box } } \quark_new:N \q_@@_break \cs_new_protected:Nn \_@@_start_smsmode:n { \everyeof{\q_@@_break\exp_not:N} \let\stex_smsmode_do:\_@@_smsmode_do: \exp_after:wN \exp_after:wN \exp_after:wN \stex_smsmode_do: \cs:w @ @ input\cs_end: "#1" \relax } \cs_new_protected:Nn \stex_file_in_smsmode:nn { \seq_gclear:N \l_@@_importmodules_seq \seq_gclear:N \l_@@_sigmodules_seq \tl_clear:N \g_stex_sms_import_code \group_begin: \let \l_stex_metatheory_uri \c_stex_default_metatheory \cs_set:Npn \stex_check_term:n ##1 {} \seq_clear:N \l_stex_all_modules_seq \str_clear:N \l_stex_current_module_str #2 \stex_filestack_push:n{#1} \_@@_in_smsmode:n { \let \_@@_do_aux_curr:N \_@@_do_aux_imports:N \tl_map_inline:Nn \g_@@_allowed_import_tl { \use:c{\tl_to_str:n{##1}~-~smsmode} } \seq_map_inline:Nn \g_@@_allowed_import_env_seq { \use:c{\tl_to_str:n{##1}~-~env~-~smsmode} } \_@@_start_smsmode:n{#1} } \_@@_in_smsmode:n \g_stex_sms_import_code \_@@_in_smsmode:n { \let \_@@_do_aux_curr:N \_@@_do_aux_normal:N \_@@_start_smsmode:n{#1} } \stex_filestack_pop: \group_end: } \cs_generate_variant:Nn \stex_file_in_smsmode:nn {on} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_smsmode_do:} % \begin{macrocode} \cs_new_protected:Nn \_@@_smsmode_do: { %\stex_if_smsmode:T { \_@@_do:w %} } \let\stex_smsmode_do:\relax \cs_new:Nn \_@@_check_cs:NNn { \exp_after:wN\if\exp_after:wN\relax\exp_not:N#3 \exp_after:wN#1\exp_after:wN#3\else \exp_after:wN#2\fi } \cs_new_protected:Npn \_@@_do:w #1 { \exp_args:Nx \tl_if_empty:nTF { \tl_tail:n{ #1 }}{ \_@@_check_cs:NNn \_@@_do_aux:N \_@@_do:w { #1 } }{ \_@@_do:w } } \cs_new_protected:Nn \_@@_do_aux:N { \cs_if_eq:NNF #1 \q_@@_break { \_@@_do_aux_curr:N #1 } } \cs_new_protected:Nn \_@@_do_aux_imports:N { % \stex_debug:nn{sms}{Checking~\tl_to_str:n{#1}~in~import} \tl_if_in:NnTF \g_@@_allowed_import_tl {#1} { \stex_debug:nn{sms}{Executing~\tl_to_str:n{#1}~in~import} #1 }{ \cs_if_eq:NNTF \begin #1 { \_@@_check_begin:Nn \g_@@_allowed_import_env_seq }{ \cs_if_eq:NNTF \end #1 { \_@@_check_end:Nn \g_@@_allowed_import_env_seq }{ \_@@_do:w } } } } \cs_new_protected:Nn \_@@_do_aux_normal:N { % \stex_debug:nn{sms}{Checking~\tl_to_str:n{#1}~in~sms~mode} \tl_if_in:NnTF \g_@@_allowed_tl {#1} { \stex_debug:nn{sms}{Executing~\tl_to_str:n{#1}} #1\_@@_do:w }{ \tl_if_in:NnTF \g_@@_allowed_escape_tl {#1} { \stex_debug:nn{sms}{Executing~escaped~\tl_to_str:n{#1}} #1 }{ \cs_if_eq:NNTF \begin #1 { \_@@_check_begin:Nn \g_@@_allowedenvs_seq }{ \cs_if_eq:NNTF \end #1 { \_@@_check_end:Nn \g_@@_allowedenvs_seq }{ \_@@_do:w } } } } } \cs_new_protected:Nn \_@@_check_begin:Nn { % \stex_debug:nn{sms}{Checking~environment~#2} \seq_if_in:NxTF #1 { \tl_to_str:n{#2} }{ \stex_debug:nn{sms}{Environment~#2} \begin{#2} }{ \_@@_do:w } } \cs_new_protected:Nn \_@@_check_end:Nn { % \stex_debug:nn{sms}{Checking~end~environment~#2} \seq_if_in:NxTF #1 { \tl_to_str:n{#2} }{ \stex_debug:nn{sms}{End~Environment~#2} \end{#2}\_@@_do:w }{ %\str_if_eq:nnTF{#2}{document} \endinput \_@@_do:w } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Modules} % % \begin{sfragment}{The smodule-environment} % \begin{macrocode} %<@@=stex_modules> % \end{macrocode} % % \begin{variable}{\l_stex_current_module_str} % The current module: % \begin{macrocode} \str_new:N \l_stex_current_module_str % \end{macrocode} % \end{variable} % % \begin{variable}{\l_stex_all_modules_seq} % Stores all modules currently in scope % \begin{macrocode} \seq_new:N \l_stex_all_modules_seq % \end{macrocode} % \end{variable} % % % \begin{macro}{\stex_every_module:n} % \begin{macrocode} %<@@=stex_module_setup> \tl_clear:N \g_stex_every_module_tl { } \cs_new_protected:Nn \stex_every_module:n { \tl_gput_right:Nn \g_stex_every_module_tl { #1 } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\stex_module_setup:n} % Sets up a new module: % \begin{macrocode} \cs_new_protected:Npn \stex_module_setup:n { \stex_if_in_module:TF \_@@_setup_nested:n \_@@_setup_top:n } \cs_new_protected:Nn \_@@_setup_top:n { \_@@_get_uri_str:n{#1} \stex_debug:nn{module}{Module~URI:~\l_@@_ns_str?#1} \str_if_empty:NTF \l_stex_key_sig_str \_stex_module_setup_top_nosig:n \_@@_setup_top_sig:n {\l_@@_ns_str?#1} \stex_metagroup_new:o \l_stex_current_module_str \g_stex_every_module_tl \stex_execute_in_module:x { \_stex_do_deprecation:n{#1} } \_@@_load_meta: } \cs_new_protected:Nn \_stex_module_setup_top_nosig:n { \stex_if_module_exists:nTF{#1}{ \stex_debug:nn{modules}{(already exists)} }{ \tl_gclear:c{c_stex_module_ #1 _code} \prop_gclear:c{c_stex_module_ #1 _morphisms_prop } \prop_gclear:c{c_stex_module_ #1 _symbols_prop } \prop_gclear:c{c_stex_module_ #1 _notations_prop } } \str_set:Nx \l_stex_current_module_str {#1} \seq_put_right:No \l_stex_all_modules_seq \l_stex_current_module_str } \cs_new_protected:Nn \_@@_setup_top_sig:n { \stex_if_module_exists:nTF{#1}{ \stex_debug:nn{modules}{(already exists)} }{ \stex_debug:nn{modules}{(needs loading)} \_@@_load_sig: } %\stex_if_smsmode:F { % WHY? \stex_activate_module:x { #1 } %} \str_set:Nx\l_stex_current_module_str{#1} } \cs_new_protected:Nn \_@@_load_sig: { \stex_file_split_off_ext:NN \l_@@_sigfile \g_stex_current_file \stex_file_split_off_lang:NN \l_@@_sigfile \l_@@_sigfile \exp_args:Ne \stex_file_in_smsmode:nn { \stex_file_use:N \l_@@_sigfile . \l_stex_key_sig_str . tex }{} } \cs_new_protected:Nn \_@@_setup_nested:n { \exp_after:wN \_@@_split_module:n \l_stex_current_module_str \_@@_end: {#1} \stex_debug:nn{module}{Nested~Module~URI:~\l_stex_current_module_str} \seq_put_right:No \l_stex_all_modules_seq \l_stex_current_module_str \stex_metagroup_new:o \l_stex_current_module_str } \cs_new_protected:Nn \_@@_get_uri_str:n { \str_clear:N \l_@@_ns_str \stex_map_uri:Nnnnn \l_stex_current_ns_uri { \str_set:Nx \l_@@_ns_str{##1\c_colon_str/} }{ \seq_set_split:Nnn \l_@@_seq / {##1} \seq_pop_right:NN \l_@@_seq \l_@@_seg \exp_args:No \str_if_eq:nnF \l_@@_seg {#1} { \seq_put_right:No \l_@@_seq \l_@@_seg } \tl_put_right:Nx \l_@@_ns_str {\seq_use:Nn \l_@@_seq /} }{}{} } \cs_new_protected:Npn \_@@_split_module:n #1?#2 \_@@_end: #3 { \_stex_module_setup_top_nosig:n { #1 ? #2 / #3} } \bool_new:N \l_stex_in_meta_bool \bool_set_false:N \l_stex_in_meta_bool \cs_new_protected:Nn \_@@_load_meta: { \tl_if_empty:NF \l_stex_metatheory_uri { \stex_execute_in_module:x{ \stex_pseudogroup_with:nn{\l_stex_in_meta_bool}{ \stex_activate_module:n {\stex_uri_use:N \l_stex_metatheory_uri } } } } } %<@@=stex_modules> % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_close_module:} % \begin{macrocode} \cs_new:Nn \stex_close_module: { \bool_if:NT \c_stex_persist_write_mode_bool \_@@_persist_module: \stex_debug:nn{module}{ Closing~module~\l_stex_current_module_str^^J Code:~\expandafter\meaning\csname c_stex_module_\l_stex_current_module_str _code\endcsname^^J Imports:\exp_after:wN \prop_to_keyval:N \cs:w c_stex_module_\l_stex_current_module_str _morphisms_prop\cs_end:^^J Declarations:\exp_after:wN \prop_to_keyval:N \cs:w c_stex_module_\l_stex_current_module_str _symbols_prop\cs_end:^^J Notations:\exp_after:wN \prop_to_keyval:N \cs:w c_stex_module_\l_stex_current_module_str _notations_prop\cs_end:^^J } } \cs_new_protected:Nn \_@@_persist_module: { \stex_persist:e { \_@@_restore_module:nnnn {\l_stex_current_module_str}{ \exp_after:wN \prop_to_keyval:N \cs:w c_stex_module_\l_stex_current_module_str _morphisms_prop \cs_end: }{ \exp_after:wN \prop_to_keyval:N \cs:w c_stex_module_\l_stex_current_module_str _symbols_prop \cs_end: }{ \exp_after:wN \exp_after:wN \exp_after:wN \exp_not:n \exp_after:wN \exp_after:wN \exp_after:wN { \cs:w c_stex_module_\l_stex_current_module_str _code \cs_end: } }{} \prop_map_function:cN{c_stex_module_\l_stex_current_module_str _notations_prop} \_@@_persist_nots_i:nn \exp_not:N \STEXRestoreNotsEnd {} } } \cs_new_protected:Nn \_@@_restore_module:nnnn { \prop_gset_from_keyval:cn{c_stex_module_\tl_to_str:n{#1}_morphisms_prop}{#2} \cs_set:Npn \_@@_tl {#3} \exp_args:Nno \prop_gset_from_keyval:cn{c_stex_module_\tl_to_str:n{#1}_symbols_prop}\_@@_tl \prop_map_inline:cn{c_stex_module_\tl_to_str:n{#1}_symbols_prop}{ \stex_ref_new_symbol:n{#1?##1} } \cs_gset:cpn{c_stex_module_\tl_to_str:n{#1}_code}{#4} \prop_gclear:c{c_stex_module_\tl_to_str:n{#1} _notations_prop} \str_set:Nn \l_@@_restore_mod_str {#1} \group_begin: \catcode`_=8\relax \catcode`:=12\relax \_@@_restore_nots:n } \cs_new:Nn \_@@_persist_nots_i:nn { \exp_not:n{#2} } \quark_new:N \STEXRestoreNotsEnd \cs_new_protected:Nn \_@@_restore_nots:n { \_@@_restore_nots_i:n } \cs_new_protected:Nn \_@@_restore_nots_i:n { \tl_if_eq:nnTF{#1}{\STEXRestoreNotsEnd}{ \group_end: }{ \_@@_restore_nots_ii:nnnnn {#1} } } \cs_new_protected:Nn \_@@_restore_nots_ii:nnnnn { \cs_set:Npn \l_@@_tl {{#4}{#5}} \exp_args:NNe\use:nn\prop_gput:cnn{ {c_stex_module_\l_@@_restore_mod_str _notations_prop} {\tl_to_str:n{#1!#2}}{ {\tl_to_str:n{#1}}{\tl_to_str:n{#2}}{#3} \exp_args:No \exp_not:n \l_@@_tl } } \_@@_restore_nots_i:n } % \end{macrocode} % \end{macro} % % \begin{variable}{\l_stex_metatheory_uri} % \begin{macrocode} \tl_new:N \l_stex_metatheory_uri % \end{macrocode} % \end{variable} % % \begin{macro}{\setmetatheory} % \begin{macrocode} \cs_new_protected:Nn \_@@_set_metatheory:nn { \group_begin: \stex_debug:nn{metatheory}{Setting~metatheory~[#1]#2} \stex_import_module_uri:nn { #1 } { #2 } \stex_debug:nn{metatheory}{Here:^^J \l_stex_import_archive_str^^J \l_stex_import_path_str^^J \l_stex_import_name_str^^J } \stex_import_require_module:ooo \l_stex_import_archive_str \l_stex_import_path_str \l_stex_import_name_str \stex_debug:nn{metatheory}{Found:~\l_stex_import_ns_str} \exp_args:Nne \use:nn { \group_end: \stex_uri_resolve:Nn \l_stex_metatheory_uri }{{\l_stex_import_ns_str}} } \NewDocumentCommand \setmetatheory {O{} m}{ \_@@_set_metatheory:nn { #1 }{ #2 } \stex_smsmode_do: } \stex_sms_allow_escape:N \setmetatheory % \end{macrocode} % \end{macro} % % Keys and key handling: % % \begin{macrocode} \stex_keys_define:nnnn{smodule}{ \str_clear:N \l_stex_key_sig_str }{ meta .code:n = { \str_if_empty:nTF {#1}{ \tl_clear:N \l_stex_metatheory_uri }{ \stex_uri_resolve:Nx \l_stex_metatheory_uri { #1 } } }, ns .code:n = { \stex_uri_resolve:Nx \l_stex_current_ns_uri { #1 } } , lang .code:n = { \stex_set_language:n { #1 } } , sig .str_set_x:N = \l_stex_key_sig_str , creators .code:n = {} , % todo ? contributors .code:n = {} , % todo ? srccite .code:n = {} % todo ? }{id, title, style, deprecate} % \end{macrocode} % % \begin{environment}{smodule} % \begin{macrocode} \stex_new_stylable_env:nnnnnnn {module} {O{} m}{ \stex_keys_set:nn { smodule }{ #1 } \tl_set_eq:NN \thistitle \l_stex_key_title_tl \tl_if_empty:NF \thistitle { \exp_args:No \stexdoctitle \thistitle } \exp_args:Nx \stex_module_setup:n { \tl_to_str:n{ #2 } } \stex_if_do_html:T { \exp_args:Nne \begin{stex_annotate_env} { shtml:theory={\l_stex_current_module_str}, shtml:language={ \l_stex_current_language_str}, shtml:signature={\l_stex_key_sig_str} \tl_if_empty:NF \l_stex_metatheory_uri {, shtml:metatheory={\stex_uri_use:N \l_stex_metatheory_uri} } } \stex_annotate_invisible:n{} } \stex_if_smsmode:F { \str_set_eq:NN \thismoduleuri \l_stex_current_module_str \tl_set:Nn \thismodulename {#2} \stex_style_apply: } \stex_smsmode_do: }{ \stex_close_module: \stex_if_smsmode:F \stex_style_apply: \stex_if_do_html:T{ \end{stex_annotate_env} } }{}{}{s} \stex_sms_allow_env:n{smodule} % \end{macrocode} % \end{environment} % % % \begin{macro}[pTF]{\stex_if_in_module:} % Are we currently in a module? % \begin{macrocode} \prg_new_conditional:Nnn \stex_if_in_module: {p, T, F, TF} { \str_if_empty:NTF \l_stex_current_module_str \prg_return_false: \prg_return_true: } % \end{macrocode} % \end{macro} % % \begin{macro}[pTF]{\stex_if_module_exists:n} % Does a module with this URI exist? % \begin{macrocode} \prg_new_conditional:Nnn \stex_if_module_exists:n {p, T, F, TF} { \tl_if_exist:cTF { c_stex_module_#1_code } \prg_return_true: \prg_return_false: } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_do_up_to_module:n,\stex_do_up_to_module:x} % Execute code in the current module (i.e. as if the \cs{begin}\Arg{smodule} % was the current tex group) % \begin{macrocode} \cs_new_protected:Nn \stex_do_up_to_module:n { \exp_args:No \stex_metagroup_do_in:nn \l_stex_current_module_str {#1} } \cs_generate_variant:Nn \stex_do_up_to_module:n {x} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_module_add_code:n,\stex_module_add_code:x} % \begin{macrocode} \cs_new_protected:Nn \stex_module_add_code:n { \tl_gput_right:cn {c_stex_module_\l_stex_current_module_str _code} { #1 } } \cs_generate_variant:Nn \stex_module_add_code:n {x} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_execute_in_module:n,\stex_execute_in_module:x} % \begin{macrocode} \cs_new_protected:Nn \stex_execute_in_module:n { \stex_if_in_module:TF { \stex_module_add_code:n { #1 } \stex_do_up_to_module:n { #1 } }{ #1 }} \cs_generate_variant:Nn \stex_execute_in_module:n {x} % \end{macrocode} % \end{macro} % % \begin{macro}{\STEXexport} % \begin{macrocode} \NewDocumentCommand \STEXexport {} { \ExplSyntaxOn \_@@_export:n } \cs_new_protected:Nn \_@@_export:n { \stex_ignore_spaces_and_pars:#1\ExplSyntaxOff \stex_module_add_code:n { \stex_ignore_spaces_and_pars:#1} \stex_smsmode_do: } % \end{macrocode} % Only allowed in modules, and allowed (escaped) in sms mode: % \begin{macrocode} \stex_deactivate_macro:Nn \STEXexport {module~environments} \stex_sms_allow_escape:N \STEXexport \stex_every_module:n {\stex_reactivate_macro:N \STEXexport} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_module_add_morphism:nnnn, \stex_module_add_morphism:nonn, \stex_module_add_morphism:ooox} % \begin{macrocode} \cs_new_protected:Nn \stex_module_add_morphism:nnnn { \exp_args:Nne \prop_gput:cnn{c_stex_module_\l_stex_current_module_str _morphisms_prop}{ \tl_if_empty:nTF{#1}{[#2]}{#1} }{{#1}{#2}{#3}{#4}} } \cs_generate_variant:Nn \stex_module_add_morphism:nnnn {nonn,ooox} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_module_add_symbol:nnnnnnN} % \begin{arguments} % \item \Arg{Macro name} % \item \Arg{Name} % \item \Arg{arity} % \item \{(\Arg{Arg num}\Arg{Arg str})$^\ast$\} % \item Definiens % \item type % \item Return % \item Command % \end{arguments} % \begin{macrocode} \cs_new_protected:Nn \stex_module_add_symbol:nnnnnnnN { \stex_debug:nn{declaration}{New~declaration:~\l_stex_current_module_str?#2^^J Macro:#1^^JArity:#3~(#4)^^J Def:~\tl_to_str:n{#5}^^J Type:~\tl_to_str:n{#6}^^J Returns:~\tl_to_str:n{#7} } %\prop_gput:cnx{c_stex_module_\l_stex_current_module_str _symbols_prop} %{#2}{\exp_not:n{{#1}{#2}{#3}{#4}{#5}{#6}}{#7}\exp_not:n{#8}} \prop_gput:cnn{c_stex_module_\l_stex_current_module_str _symbols_prop} {#2}{{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}} \tl_if_empty:nF{#1}{ \stex_execute_in_module:n { \_@@_activate_sym:n {#2} } } } \cs_new_protected:Nn \_@@_activate_sym:n { \prop_map_inline:cn{c_stex_module_\l_stex_current_module_str _symbols_prop}{ \str_if_eq:nnT{#1}{##1}{ \_@@_activate_i:nnnnnnnn ##2 } } } \cs_new_protected:Nn \_@@_activate_i:nnnnnnnn { \stex_debug:nn{activating}{#1:\l_stex_current_module_str^^J \tl_to_str:n{{#2}{#3}{#4}{#5}{#6}{#7}#8} } \cs_set:cpx{#1} { \_stex_invoke_symbol:nnnnnnnN {\l_stex_current_module_str} \exp_not:n{{#2}{#3}{#4}{#5}{#6}{#7}{#8}} } \stex_debug:nn{activating}{done} \prop_map_break: } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_module_add_notation:nnnnn, \stex_module_add_notation:eoeoo,\stex_set_notation_macro:nnnnn} % \begin{arguments} % \item URI % \item variant % \item arity % \item macro body % \item op % \end{arguments} % \begin{macrocode} \cs_new_protected:Nn \stex_module_add_notation:nnnnn { \stex_debug:nn{notations}{Adding~notation:^^J #1~\c_hash_str#2~#3^^J to~\l_stex_current_module_str } \prop_gput:cnn{c_stex_module_\l_stex_current_module_str _notations_prop} {#1!#2}{{#1}{#2}{#3}{#4}{#5}} \stex_execute_in_module:n { \_@@_activate_not:nn{#1}{#2} } } \cs_generate_variant:Nn \stex_module_add_notation:nnnnn {eoeoo} \cs_new_protected:Nn \_@@_activate_not:nn { \prop_map_inline:cn{c_stex_module_\l_stex_current_module_str _notations_prop}{ \str_if_eq:nnT{#1!#2}{##1}{ \prop_map_break:n{\stex_set_notation_macro:nnnnn ##2 } } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_set_notation_macro:nnnnn,\stex_set_notation_macro:eoexo} % \begin{macrocode} \cs_new_protected:Nn \stex_set_notation_macro:nnnnn { \tl_set:cn {l_stex_notation_#1_#2_cs}{#4} \cs_if_exist:cF{l_stex_notation_#1__cs}{ \tl_set:cn {l_stex_notation_#1__cs}{#4} } \tl_if_empty:nF{#5}{ \tl_set:cn{l_stex_notation_#1_op_#2_cs}{#5} \cs_if_exist:cF{l_stex_notation_#1_op__cs}{ \cs_set_eq:cc {l_stex_notation_#1_op__cs}{l_stex_notation_#1_op_#2_cs} } } } \cs_generate_variant:Nn \stex_set_notation_macro:nnnnn {eoexo} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_activate_module:n,\stex_activate_module:o,\stex_activate_module:x} % \begin{macrocode} \cs_new_protected:Nn \stex_activate_module:n { \seq_if_in:NnF \l_stex_all_modules_seq { #1 } { \stex_debug:nn{modules}{Activating~module~#1^^J\expandafter\meaning\csname c_stex_module_#1_code\endcsname} \seq_put_right:Nn \l_stex_all_modules_seq { #1 } \stex_pseudogroup:nn{ \str_set:Nn \l_stex_current_module_str {#1} \use:c{ c_stex_module_#1_code } }{ \stex_pseudogroup_restore:N \l_stex_current_module_str } } } \cs_generate_variant:Nn \stex_activate_module:n {o,x} % \end{macrocode} % \end{macro} % % Iterating: % \begin{macrocode} %<@@=stex_iterate> % \end{macrocode} % % \begin{macro}{\stex_iterate_symbols:n} % \begin{macrocode} \cs_new_protected:Nn \stex_iterate_symbols:n { \stex_pseudogroup_with:nn{\_@@_sym_cs:nnnnnnnnN\stex_iterate_break:\stex_iterate_break:n}{ \cs_set:Npn \_@@_sym_cs:nnnnnnnnN ##1 ##2 ##3 ##4 ##5 ##6 ##7 ##8 ##9 { #1 } \cs_set:Npn \stex_iterate_break: { \prop_map_break:n{\seq_map_break:} } \cs_set:Npn \stex_iterate_break:n ##1 { \prop_map_break:n{\seq_map_break:n{##1}} } \seq_map_inline:Nn \l_stex_all_modules_seq { \prop_map_inline:cn{c_stex_module_##1_symbols_prop}{ \_@@_sym_cs:nnnnnnnnN {##1} ####2 } } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_iterate_symbols:nn} % \begin{macrocode} \cs_new_protected:Nn \stex_iterate_symbols:nn { \seq_clear:N \l_@@_mods_seq \stex_pseudogroup_with:nn{\_@@_sym_cs:nnnnnnnnN}{ \cs_set:Npn \_@@_sym_cs:nnnnnnnnN ##1 ##2 ##3 ##4 ##5 ##6 ##7 ##8 ##9 { #2 } \clist_map_function:nN {#1} \_@@_it_decl_i:n } } \cs_new_protected:Nn \_@@_it_decl_i:n { \seq_if_in:NnF \l_@@_mods_seq {#1} { \seq_put_left:Nn \l_@@_mods_seq {#1} \prop_map_inline:cn{c_stex_module_#1_morphisms_prop}{ \_@@_it_decl_check:nnnn ##2 } \prop_map_inline:cn{c_stex_module_#1_symbols_prop}{ \_@@_sym_cs:nnnnnnnnN {#1} ##2 } } } \cs_new_protected:Nn \_@@_it_decl_check:nnnn { \tl_if_empty:nT{#1}{ \_@@_it_decl_i:n {#2} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_iterate_notations:nn} % \begin{macrocode} \cs_new_protected:Nn \stex_iterate_notations:nn { \seq_clear:N \l_@@_mods_seq \stex_pseudogroup_with:nn{\_@@_not_cs:nnnnn}{ \cs_set:Npn \_@@_not_cs:nnnnn ##1 ##2 ##3 ##4 ##5 { #2 } \clist_map_function:nN {#1} \_@@_it_not_i:n } } \cs_new_protected:Nn \_@@_it_not_i:n { \seq_if_in:NnF \l_@@_mods_seq {#1} { \seq_put_left:Nn \l_@@_mods_seq {#1} \prop_map_inline:cn{c_stex_module_#1_notations_prop}{ \_@@_not_cs:nnnnn ##2 } \prop_map_inline:cn{c_stex_module_#1_morphisms_prop}{ \_@@_it_not_check:nnnn ##2 } } } \cs_new_protected:Nn \_@@_it_not_check:nnnn { \tl_if_empty:nT{#1}{ \_@@_it_not_i:n {#2} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_iterate_morphisms:nn} % \begin{macrocode} \cs_new_protected:Nn \stex_iterate_morphisms:nn { \seq_clear:N \l_@@_mods_seq \bool_set_true:N \l_@@_continue_bool \cs_set:Npn \_@@_morphism_cs:nnnn ##1 ##2 ##3 ##4 ##5 { #2 \bool_if:NT \l_@@_continue_bool { \str_if_eq:nnTF{##1}{[##2]}{ \tl_put_right:Nn \l_@@_todo_tl { \_@@_iterate_morphism:nn{##5}{##2} } }{ \tl_put_right:Nn \l_@@_todo_tl { \_@@_iterate_morphism:nn{##5 / ##1}{##2} } } } } \cs_set:Npn \stex_iterate_break:n ##1 { \bool_set_false:N \l_@@_continue_bool \prop_map_break:n{##1} } \_@@_iterate_morphism:nn{}{#1} } \cs_new_protected:Nn \_@@_iterate_morphism:nn { \tl_clear:N \l_@@_todo_tl \seq_if_in:NnF \l_@@_mods_seq {#1 #2}{ \seq_put_right:Nn \l_@@_mods_seq {#1 #2} \prop_map_inline:cn{c_stex_module_#2_morphisms_prop}{ \_@@_morphism_cs:nnnn ##2 {#1} % TODO % ##1: name or [mpath] % ##2 = {####1}{####2}{####3}{####4} % ####1 = name % ####2 = mpath % ####3 = type % ####4 = {origname}{newname}* } \bool_if:NT \l_@@_continue_bool \l_@@_todo_tl } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Structural Features} % \begin{macrocode} %<@@=stex_features> % \end{macrocode} % % \begin{macro}{\stex_structural_feature_module:nn,\stex_structural_feature_module_end:} % \begin{macrocode} \cs_new_protected:Nn \stex_structural_feature_module:nn { \stex_if_do_html:TF { \exp_args:Nne \begin{stex_annotate_env} { shtml:feature-#2={ \l_stex_current_module_str/#1} \str_if_empty:NF \l_stex_macroname_str {, shtml:macroname={\l_stex_macroname_str} } } \stex_annotate_invisible:n{} }\group_begin: \stex_module_setup:n {#1-module} } \cs_new_protected:Nn \stex_structural_feature_module_end: { \tl_gset_eq:NN \g_stex_last_feature_str \l_stex_current_module_str \stex_close_module: \stex_if_do_html:TF{ \end{stex_annotate_env} }\group_end: } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_structural_feature_morphism:nnn,\stex_structural_feature_morphism_end:} % \begin{macrocode} \bool_new:N \l_@@_implicit_bool \cs_new_protected:Nn \stex_structural_feature_morphism:nnnnn { \str_clear:N \l_stex_current_domain_str \tl_if_empty:nT{#3}{ \_stex_get_mathstructure:n{#4} \str_set_eq:NN \l_stex_current_domain_str \l_stex_get_structure_module_str } \str_if_empty:NT \l_stex_current_domain_str { \stex_import_module_uri:nn { #3 }{ #4 } \group_begin: \stex_import_require_module:ooo \l_stex_import_archive_str \l_stex_import_path_str \l_stex_import_name_str \exp_args:Nnx \use:nn \group_end: { \str_set:Nn \exp_not:N\l_stex_current_domain_str {\l_stex_import_ns_str} } } \tl_if_empty:nTF{#1}{ \bool_set_true:N \l_@@_implicit_bool \str_set:Nx \l_tmpa_str {[\l_stex_current_domain_str]} }{ \bool_set_false:N \l_@@_implicit_bool \str_set:Nn \l_tmpa_str {#1} } \stex_if_do_html:TF { \begin{stex_annotate_env} { shtml:feature-#2={\l_stex_current_module_str?\l_tmpa_str}, shtml:domain={\l_stex_current_domain_str} #5 } \stex_annotate_invisible:n{} }\group_begin: \str_set:Nn \l_@@_feature_str {#2} \str_set_eq:NN \l_stex_feature_name_str \l_tmpa_str \_@@_setup: \_@@_reactivate: %^^A\stex_activate_module:o \l_stex_current_domain_str \exp_args:Ne \stex_metagroup_new:n {\l_stex_current_module_str / \l_stex_feature_name_str} } \cs_new_protected:Nn \_@@_do_for_list: { \seq_clear:N \l_stex_fors_seq \clist_map_inline:Nn \l_stex_key_for_clist { \exp_args:Ne\stex_get_in_morphism:n{\tl_to_str:n{##1}} \seq_put_right:Nx \l_stex_fors_seq {\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } } \cs_new_protected:Nn \_@@_add_definiens:nn { \_@@_set_definiens_macros: #1\_@@_break: \_stex_assign_do:n{#2} #2 } \cs_new_protected:Npn \_@@_set_definiens_macros: #1?#2?#3\_@@_break: { \str_set:Nn \l_stex_get_symbol_mod_str {#1?#2} \str_set:Nn \l_stex_get_symbol_name_str {#3} \exp_args:Nne\use:nn{\_@@_set_definiens_macros_i:nnnnnnn}{ \prop_item:Nn \l_stex_morphism_symbols_prop {[#1?#2]/[#3]} } } \cs_new_protected:Nn \_@@_set_definiens_macros_i:nnnnnnn { \tl_set:Nn \l_stex_get_symbol_def_tl{#4} } \cs_new_protected:Nn \stex_structural_feature_morphism_end: { \str_gset_eq:NN \l_stex_feature_name_str \l_stex_feature_name_str \str_gset_eq:NN \l_stex_current_domain_str \l_stex_current_domain_str \seq_gset_eq:NN \l_stex_morphism_symbols_prop \l_stex_morphism_symbols_prop \seq_gset_eq:NN \l_stex_morphism_renames_prop \l_stex_morphism_renames_prop \seq_gset_eq:NN \l_stex_morphism_morphisms_seq \l_stex_morphism_morphisms_seq \_@@_do_elaboration: \stex_if_do_html:TF{ \end{stex_annotate_env} }\group_end: } \cs_new_protected:Nn \_@@_setup: { \prop_clear:N \l_stex_morphism_symbols_prop \prop_clear:N \l_stex_morphism_renames_prop \seq_clear:N \l_stex_morphism_morphisms_seq \_@@_do_decls: \exp_args:No \_@@_do_morphisms:n \l_stex_current_domain_str } \cs_new_protected:Nn \_@@_rename_all: { } \cs_new:Npn \_@@_clean:nnw [#1] / #2 \_stex_end: { [#1]/[#2] } \cs_new_protected:Nn \_@@_do_decls: { \exp_args:No \stex_iterate_symbols:nn \l_stex_current_domain_str { \stex_str_if_starts_with:nnTF{##3}[{ \exp_args:NNe \prop_put:Nnn \l_stex_morphism_symbols_prop { \_@@_clean:nnw ##3 \_stex_end: } }{ \prop_put:Nnn \l_stex_morphism_symbols_prop {[##1]/[##3]} }{ {##2}{##4}{##5}{##6}{##7}{##8}##9 } } } \cs_new_protected:Nn \stex_structural_feature_morphism_check_total: { \prop_map_inline:Nn \l_stex_morphism_symbols_prop { \_@@_total_check: ##1 ##2 } } \cs_new_protected:Npn \_@@_total_check: [#1]/[#2] #3 #4 #5 #6 #7 #8 #9 { \tl_if_empty:nT{#6}{ \msg_error:nnxx{stex}{error/needsdefiniens}{#1?#2}{total~morphism} } } \cs_new:Npn \_@@_split_qm:w #1 ? #2 ? #3 { #3 } \cs_new_protected:Nn \_@@_do_elaboration: { \stex_debug:nn{morphisms}{ Elaborating:^^J\prop_to_keyval:N \l_stex_morphism_symbols_prop ^^J Renamings:^^J \prop_to_keyval:N \l_stex_morphism_renames_prop } \prop_map_inline:Nn \l_stex_morphism_symbols_prop { \_@@_elab_check: ##1 ##2 } \exp_args:No\stex_iterate_notations:nn\l_stex_current_domain_str{ \prop_get:NnNTF \l_stex_morphism_renames_prop {##1}\l_@@_tmp { \exp_args:Ne \stex_module_add_notation:nnnnn {\l_stex_current_module_str ? \exp_after:wN \use_ii:nn \l_@@_tmp} }{ \exp_args:Ne \stex_module_add_notation:nnnnn {\l_stex_current_module_str ? \l_stex_feature_name_str / \_@@_split_qm:w ##1} }{##2}{##3}{##4}{##5} } \stex_module_add_morphism:ooox \l_stex_feature_name_str \l_stex_current_domain_str \l_@@_feature_str {\prop_map_function:NN \l_stex_morphism_renames_prop \_@@_rename:nn} } \cs_new:Nn \_@@_rename:nn{ {#1}{\use_ii:nn#2} } \cs_new_protected:Npn \_@@_elab_check: [#1]/[#2] #3 { \prop_get:NnNTF \l_stex_morphism_renames_prop {#1?#2} \l_@@_tmp { \stex_debug:nn{morphisms}{Generating~\l_@@_tmp} \exp_after:wN \stex_module_add_symbol:nnnnnnnN \l_@@_tmp }{ \bool_if:NTF \l_@@_implicit_bool { \stex_debug:nn{morphisms}{Generating~#3:~\l_stex_feature_name_str / #2} \exp_args:Nno \stex_module_add_symbol:nnnnnnnN {#3}{\l_stex_feature_name_str / #2} }{ \stex_debug:nn{morphisms}{Generating~\l_stex_feature_name_str / #2} \exp_args:Nno \stex_module_add_symbol:nnnnnnnN {}{\l_stex_feature_name_str / #2} } } } \cs_new_protected:Nn \_@@_do_morphisms:n { \prop_map_inline:cn {c_stex_module_#1_morphisms_prop}{ \_@@_do_morph:nnnn ##2 } } \cs_new_protected:Nn \_@@_do_morph:nnnn { \tl_if_empty:nF{#3}{ \seq_put_right:Nn \l_stex_morphism_morphisms_seq {{#1}{#2}{#3}} } \_@@_do_morphisms:n{#2} } \cs_new_protected:Npn \_@@_reactivate: { \stex_deactivate_macro:Nn \symdecl {module~environments} \stex_deactivate_macro:Nn \textsymdecl {module~environments} \stex_deactivate_macro:Nn \symdef {module~environments} \stex_deactivate_macro:Nn \notation {module~environments} \stex_deactivate_macro:Nn \importmodule {module~environments} \stex_deactivate_macro:Nn \requiremodule {module~environments} \stex_deactivate_macro:Nn \smodule {outside~of~morphisms} \stex_reactivate_macro:N \assign \stex_reactivate_macro:N \assignMorphism \stex_reactivate_macro:N \renamedecl \cs_set_eq:NN \_stex_do_for_list: \_@@_do_for_list: \cs_set_eq:NN \_stex_add_definiens:nn \_@@_add_definiens:nn } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_get_in_morphism:n} % \begin{macrocode} \cs_new_protected:Nn \stex_get_in_morphism:n { \str_clear:N \l_stex_get_symbol_name_str \prop_map_inline:Nn \l_stex_morphism_symbols_prop { \exp_args:Nx\_@@_get_check:nnnn{\tl_to_str:n{#1}}##1##2 } \str_if_empty:NT \l_stex_get_symbol_name_str { \prop_map_inline:Nn \l_stex_morphism_renames_prop { \_@@_renamed_check:nnnnn{#1}##1=##2 } \str_if_empty:NT \l_stex_get_symbol_name_str { \msg_error:nnxx{stex}{error/unknownsymbolin}{#1}{ morphism~\l_stex_feature_name_str } } } } \cs_new_protected:Npn \_@@_renamed_check:nnnnn #1#2?#3?#4=#5#6 { \str_if_eq:nnTF{#1}{#5}{ \exp_args:Nnx \use:nn{\_@@_check_break:nnnnnnnnn{#2?#3}{#4}}{ \prop_item:Nn \l_stex_morphism_symbols_prop {[#2?#3]/[#4]} } }{ \str_if_eq:nnT{#1}{#6}{ \exp_args:Nnx \use:nn{\_@@_check_break:nnnnnnnnn{#2?#3}{#4}}{ \prop_item:Nn \l_stex_morphism_symbols_prop {[#2?#3]/[#4]} } } } } \cs_new_protected:Npn \_@@_get_check:nnnn #1[#2]/[#3]#4 { \str_if_eq:nnTF{#1}{#3}{ \_@@_check_break:nnnnnnnnn{#2}{#3}{#4} }{ \str_if_eq:nnTF{#1}{#4}{ \_@@_check_break:nnnnnnnnn{#2}{#3}{#4} }{ \use_none:nnnnnn } } } \cs_new_protected:Nn \_@@_check_break:nnnnnnnnn { \prop_map_break:n{ \str_set:Nn \l_stex_get_symbol_mod_str{#1} \str_set:Nn \l_stex_get_symbol_name_str{#2} \str_set:Nn \l_stex_get_symbol_macro_str{#3} \int_set:Nn \l_stex_get_symbol_arity_int {#4} \tl_set:Nn \l_stex_get_symbol_args_tl {#5} \tl_set:Nn \l_stex_get_symbol_def_tl {#6} \tl_set:Nn \l_stex_get_symbol_type_tl {#7} \tl_set:Nn \l_stex_get_symbol_return_tl {#8} \tl_set:Nn \l_stex_get_symbol_invoke_cs {#9} } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \end{sfragment} % % % \begin{sfragment}{Inheritance} % % \begin{sfragment}{\cs{importmodule}/\cs{usemodule}} % \begin{macrocode} %<@@=stex_importmodule> % \end{macrocode} % % \begin{macro}{\usemodule} % \begin{macrocode} \stex_new_stylable_cmd:nnnn {usemodule} { O{} m } { \stex_import_module_uri:nn { #1 }{ #2 } \stex_import_require_module:ooo \l_stex_import_archive_str \l_stex_import_path_str \l_stex_import_name_str \stex_if_do_html:T { \hbox{\stex_annotate_invisible:nn {shtml:usemodule=\l_stex_import_ns_str} {}} } \stex_if_smsmode:F{ \group_begin: \tl_set_eq:NN \thismoduleuri \l_stex_import_ns_str \tl_set_eq:NN \thismodulename \l_stex_import_name_str \tl_clear:N \thisstyle \stex_style_apply: \group_end: } }{} % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_import_module_uri:nn} % \begin{macrocode} \cs_new_protected:Nn \stex_import_module_uri:nn { \stex_debug:nn{importmodule}{URI:~>#1<~>#2<} \exp_args:NNnx \seq_set_split:Nnn \_@@_seq ? { \tl_to_str:n{ #2 } } \seq_pop_right:NN \_@@_seq \l_stex_import_name_str \str_set:Nx \l_stex_import_path_str { \seq_use:Nn \_@@_seq ? } \tl_if_empty:nTF { #1 } { \stex_debug:nn{importmodule}{No~archive} \prop_if_exist:NTF \l_stex_current_archive_prop { \stex_debug:nn{importmodule}{Picking~current~archive} \str_set:Nx \l_stex_import_archive_str { \prop_item:Nn \l_stex_current_archive_prop { id } } }{ \str_clear:N \l_stex_import_archive_str \str_set:Nn \l_stex_import_uri_str {file:} \str_if_empty:NTF \l_stex_import_path_str { \stex_debug:nn{importmodule}{Empty~Path} \stex_file_split_off_ext:NN \l_@@_path_seq \g_stex_current_file \stex_file_split_off_lang:NN \l_@@_path_seq \l_@@_path_seq \str_set:Nx \l_stex_import_path_str { \stex_file_use:N \l_@@_path_seq } }{ \stex_debug:nn{importmodule}{Resolving~path~\l_stex_import_path_str~relative~to~\stex_file_use:N \g_stex_current_file} \stex_file_resolve:Nx \l_@@_seq { \stex_file_use:N \g_stex_current_file / .. / \l_stex_import_path_str} \str_set:Nx \l_stex_import_path_str { \stex_file_use:N \l_@@_seq } \stex_debug:nn{importmodule}{...yields~\l_stex_import_path_str} } } } { \stex_debug:nn{importmodule}{Archive~#1} \str_set:Nx \l_stex_import_archive_str { #1 } \stex_require_archive:o \l_stex_import_archive_str \str_set:Nx \l_stex_import_uri_str { \prop_item:cn{ c_stex_mathhub_ \l_stex_import_archive_str _manifest_prop}{ ns } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\stex_import_require_module:nnn,\stex_import_require_module:ooo} % \begin{macrocode} \cs_new_protected:Npn \stex_import_require_module:nnn #1 { \tl_if_empty:nTF { #1 } { \str_clear:N \l_@@_archive_str \str_set:Nn \l_stex_import_uri_str {file:} \_@@_get_module:nnn {} }{ \stex_require_archive:n { #1 } \str_set:Nx \l_@@_archive_str {#1} \str_set:Nx \l_stex_import_uri_str { \prop_item:cn{ c_stex_mathhub_ #1 _manifest_prop}{ ns } } \str_set:Nx \l_@@_str { \stex_file_use:N \c_stex_mathhub_file / #1 / source } \exp_args:No \_@@_get_module:nnn \l_@@_str } } \cs_generate_variant:Nn \stex_import_require_module:nnn {ooo} \cs_new_protected:Npn \stex_import_require_module_safe:nnn #1 { \tl_if_empty:nTF { #1 } { \str_clear:N \l_@@_archive_str \str_set:Nn \l_stex_import_uri_str {file:} \_@@_get_module_safe:nnn {} }{ \stex_require_archive:n { #1 } \str_set:Nx \l_@@_archive_str {#1} \str_set:Nx \l_stex_import_uri_str { \prop_item:cn{ c_stex_mathhub_ #1 _manifest_prop}{ ns } } \str_set:Nx \l_@@_str { \stex_file_use:N \c_stex_mathhub_file / #1 / source } \exp_args:No \_@@_get_module_safe:nnn \l_@@_str } } \cs_new_protected:Nn \_@@_get_module_uri:nnn { \tl_if_empty:nF {#2}{ \str_set:Nx \l_stex_import_uri_str {\l_stex_import_uri_str / #2} } \stex_debug:nn{importmodule}{~>#1<^^J>#2<^^J>#3<^^J>\l_stex_import_uri_str<^^J Current~file:\stex_file_use:N \g_stex_current_file^^J Current~namespace:\stex_uri_use:N \l_stex_current_ns_uri } \stex_if_module_exists:nTF {\l_stex_import_uri_str?#3} { \str_set:Nx \l_stex_import_ns_str {\l_stex_import_uri_str?#3} }{ \stex_if_module_exists:nTF{\stex_uri_use:N \l_stex_current_ns_uri ? #3}{ \str_set:Nx \l_stex_import_ns_str {\stex_uri_use:N \l_stex_current_ns_uri ? #3} }{ \_@@_get_from_file:nnn{#1}{#2}{#3} \str_set:Nx \l_stex_import_ns_str {\l_stex_import_uri_str?#3} } } } \cs_new_protected:Nn \_@@_get_module_uri_safe:nnn { \tl_if_empty:nF {#2}{ \str_set:Nx \l_stex_import_uri_str {\l_stex_import_uri_str / #2} } \stex_debug:nn{importmodule}{~>#1<^^J>#2<^^J>#3<^^J>\l_stex_import_uri_str<^^J Current~file:\stex_file_use:N \g_stex_current_file^^J Current~namespace:\stex_uri_use:N \l_stex_current_ns_uri } \stex_if_module_exists:nTF {\l_stex_import_uri_str?#3} { \str_set:Nx \l_stex_import_ns_str {\l_stex_import_uri_str?#3} }{ \stex_if_module_exists:nTF{\stex_uri_use:N \l_stex_current_ns_uri ? #3}{ \str_set:Nx \l_stex_import_ns_str {\stex_uri_use:N \l_stex_current_ns_uri ? #3} }{ \_@@_get_from_file_safe:nnn{#1}{#2}{#3} \str_set:Nx \l_stex_import_ns_str {\l_stex_import_uri_str?#3} } } } \cs_new_protected:Nn \_@@_get_module:nnn { \stex_debug:nn{importmodule}{Requiring~>[#1]#2?#3<} \_@@_get_module_uri:nnn{#1}{#2}{#3} \stex_activate_module:o \l_stex_import_ns_str } \cs_new_protected:Nn \_@@_get_module_safe:nnn { \stex_debug:nn{importmodule}{Requiring~>[#1]#2?#3<} \_@@_get_module_uri_safe:nnn{#1}{#2}{#3} } \cs_new_protected:Nn \_@@_get_from_file:nnn { \stex_file_resolve:Nx \l_@@_seq { \tl_if_empty:nF{ #1 }{ #1 / } #2 } \str_set:Nx \l_@@_str {\stex_file_use:N \l_@@_seq} \stex_debug:nn{imports}{Looking~for~\l_stex_import_uri_str?#3...} \_@@_check_file:nn{ /#3.tex }{ \_@@_check_file:nn{/#3.\l_stex_current_language_str .tex}{ \_@@_check_file:nn{/#3.en.tex}{ \_@@_check_file:nn{.tex}{ \_@@_check_file:nn{.\l_stex_current_language_str .tex}{ \_@@_check_file:nn{.en.tex}{ \msg_error:nnx{stex}{error/unknownmodule}{\l_stex_import_uri_str?#3} } } } } } } \stex_if_smsmode:TF{ \exp_args:NNo \exp_args:Nnx \str_if_eq:nnTF{\l_@@_str}{\stex_file_use:N \g_stex_current_file}{ \stex_debug:nn{imports}{Skipping~current~file} }{ \_@@_load_file:n{#3} } }{ \_@@_load_file:n{#3} } } \cs_new_protected:Nn \_@@_get_from_file_safe:nnn { \stex_file_resolve:Nx \l_@@_seq { \tl_if_empty:nF{ #1 }{ #1 / } #2 } \str_set:Nx \l_@@_str {\stex_file_use:N \l_@@_seq} \stex_debug:nn{imports}{Looking~for~\l_stex_import_uri_str?#3...} \_@@_check_file:nn{ /#3.tex }{ \_@@_check_file:nn{/#3.\l_stex_current_language_str .tex}{ \_@@_check_file:nn{/#3.en.tex}{ \_@@_check_file:nn{.tex}{ \_@@_check_file:nn{.\l_stex_current_language_str .tex}{ \_@@_check_file:nn{.en.tex}{ } } } } } } \stex_if_smsmode:TF{ \exp_args:NNo \exp_args:Nnx \str_if_eq:nnTF{\l_@@_str}{\stex_file_use:N \g_stex_current_file}{ \stex_debug:nn{imports}{Skipping~current~file} }{ \IfFileExists{ \l_@@_str }{ \_@@_load_file:n{#3} }{} } }{ \IfFileExists{ \l_@@_str }{ \_@@_load_file:n{#3} }{} } } \cs_new_protected:Nn \_@@_load_file:n { \stex_file_in_smsmode:on \l_@@_str { \str_if_empty:NF \l_@@_archive_str { \stex_set_current_archive:n \l_@@_archive_str } \stex_debug:nn{modules}{Loading~\l_@@_str} } \stex_if_module_exists:nF {\l_stex_import_uri_str?#1} { \msg_error:nnx{stex}{error/unknownmodule}{\l_stex_import_uri_str?#1} } } \cs_new_protected:Npn \_@@_check_file:nn #1 { \stex_debug:nn{imports}{Checking~ \l_@@_str #1} \IfFileExists{ \l_@@_str #1 }{ \stex_debug:nn{imports}{Success} \str_set:Nx \l_@@_str { \l_@@_str #1 } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\importmodule} % \begin{macrocode} \stex_new_stylable_cmd:nnnn{importmodule} { O{} m } { \_@@_import_module:nn {#1}{#2} \stex_smsmode_do: }{} \stex_deactivate_macro:Nn \importmodule {module~environments} \cs_new_protected:Nn \_@@_import_module:nn { \stex_import_module_uri:nn { #1 }{ #2 } \stex_import_require_module:ooo \l_stex_import_archive_str \l_stex_import_path_str \l_stex_import_name_str \stex_execute_in_module:x{ \stex_activate_module:n{\l_stex_import_ns_str} } \stex_module_add_morphism:nonn {}{\l_stex_import_ns_str}{import}{} \stex_if_do_html:T { \stex_annotate_invisible:nn {shtml:import=\l_stex_import_ns_str} {} } \stex_if_smsmode:F{ \group_begin: \tl_set:Nn \thisarchive {#1} \tl_set_eq:NN \thismoduleuri \l_stex_import_ns_str \tl_set_eq:NN \thismodulename \l_stex_import_name_str \tl_clear:N \thisstyle \stex_style_apply: \group_end: } } \cs_new_protected:Nn \_@@_import_module_presms:nn { \stex_import_module_uri:nn { #1 }{ #2 } \tl_gput_right:Nx \g_stex_sms_import_code { \stex_import_require_module_safe:nnn {\l_stex_import_archive_str} {\l_stex_import_path_str} {\l_stex_import_name_str} } } \stex_sms_allow_escape:N \importmodule \stex_every_module:n {\stex_reactivate_macro:N \importmodule} \stex_sms_allow_import:Nn \importmodule { \stex_reactivate_macro:N \importmodule \let \_@@_import_module:nn \_@@_import_module_presms:nn } \stex_new_stylable_cmd:nnnn{requiremodule} { O{} m } { \stex_import_module_uri:nn { #1 }{ #2 } \stex_import_require_module:ooo \l_stex_import_archive_str \l_stex_import_path_str \l_stex_import_name_str \stex_do_up_to_module:x{ \stex_activate_module:n{\l_stex_import_ns_str} } \stex_if_do_html:T { \stex_annotate_invisible:nn {shtml:import=\l_stex_import_ns_str} {} } \stex_if_smsmode:F{ \group_begin: \tl_set:Nn \thisarchive {#1} \tl_set_eq:NN \thismoduleuri \l_stex_import_ns_str \tl_set_eq:NN \thismodulename \l_stex_import_name_str \tl_clear:N \thisstyle \stex_style_apply: \group_end: } \stex_smsmode_do: }{} \stex_deactivate_macro:Nn \requiremodule {module~environments} % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Theory Morphisms} % \begin{macrocode} %<@@=stex_morphisms> % \end{macrocode} % % \begin{macrocode} \stex_new_stylable_cmd:nnnn {assign} { m m }{ \stex_get_in_morphism:n{#1} \_stex_assign_do:n{#2} \stex_smsmode_do: }{} \stex_sms_allow_escape:N\assign \cs_new_protected:Nn \_stex_assign_do:n{ \stex_debug:nn{assign}{Assigning~\l_stex_get_symbol_name_str~to~\tl_to_str:n{#1}} \tl_if_empty:NF \l_stex_get_symbol_def_tl { %\msg_error:nnxx{stex}{error/symbolalreadydefined}{\l_stex_get_symbol_name_str}{ % morphism~\l_stex_feature_name_str %} } \stex_check_term:n{#1} \stex_debug:nn{HERE!}{ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str^^J \tl_to_str:n{#1} } \stex_if_do_html:T{ \stex_annotate_invisible:nn{shtml:assign={\l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str}}{ \_stex_annotate_force_break:n{ \mode_if_math:T\hbox{$\stex_annotate:nn{shtml:definiens={}}{#1}$} } } } \exp_args:Ne \stex_metagroup_do_in:nx{ \l_stex_current_module_str / \l_stex_feature_name_str }{ \prop_put:Nnn \exp_not:N \l_stex_morphism_symbols_prop {[\l_stex_get_symbol_mod_str]/[\l_stex_get_symbol_name_str]} { {\l_stex_get_symbol_macro_str} {\int_use:N \l_stex_get_symbol_arity_int} {\l_stex_get_symbol_args_tl} {\exp_not:n{#1}} {\exp_args:No\exp_not:n\l_stex_get_symbol_type_tl} {\exp_args:No\exp_not:n\l_stex_get_symbol_return_tl} {\l_stex_get_symbol_invoke_cs} } } } \stex_new_stylable_cmd:nnnn {renamedecl} { m O{} m }{ \stex_get_in_morphism:n{#1} \_stex_renamedecl_do:nn{#2}{#3} \stex_smsmode_do: }{} \stex_sms_allow_escape:N\renamedecl \cs_new_protected:Nn \_stex_renamedecl_do:nn { \stex_debug:nn{renamedecl}{Renaming~\l_stex_get_symbol_name_str~to~[#1]{#2}} \stex_if_do_html:T{ \exp_args:Ne \stex_annotate_invisible:nn{ shtml:rename={\l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str}, shtml:macroname={#2} \str_if_empty:nF{#1}{ ,shtml:to={#1} } }{} } \exp_args:Ne \stex_metagroup_do_in:nx{ \l_stex_current_module_str / \l_stex_feature_name_str }{ \prop_put:Nnn \exp_not:N \l_stex_morphism_renames_prop {\l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str}{{#2}{ \tl_if_empty:nTF{#1}{\l_stex_feature_name_str/\l_stex_get_symbol_name_str}{#1} }} } } \stex_new_stylable_cmd:nnnn {assignMorphism} { m m }{ \str_clear:N \l_@@_morphism_dom_str \stex_iterate_morphisms:nn\l_stex_current_domain_str{ \stex_debug:nn{assignMorphism}{ Checking:~#1~vs:^^J##1^^J##2^^J##3^^J##4 } \str_if_eq:nnTF{#1}{##1}{ \_@@_do_morph_assign:nnn{##1}{##2}{##4} }{ \stex_str_if_ends_with:nnT{##2}{#1}{ \_@@_do_morph_assign:nnn{##1}{##2}{##4} } } } \str_if_empty:NT \l_@@_morphism_dom_str { \msg_error:nnn{stex}{error/nomorphism}{#1} } \bool_set_false:N \l_tmpa_bool \stex_iterate_morphisms:nn \l_stex_current_module_str { \stex_debug:nn{assignMorphism}{ Checking:~#2~vs:^^J##1^^J##2^^J##3^^J##4 } \str_if_eq:nnTF{#2}{##1}{ \stex_debug:nn{assignMorphism}{match!} \stex_iterate_break:n{ \stex_annotate_invisible:nn{ shtml:assignMorphismFrom={\l_@@_morphism_dom_str} ahtml:assignMorphismTo={\l_stex_current_module_str?##1} }{} \bool_set_true:N \l_tmpa_bool } }{ \stex_str_if_ends_with:nnT{##2}{#2}{ \stex_debug:nn{assignMorphism}{match!} \stex_iterate_break:n{ \stex_annotate_invisible:nn{ shtml:assignMorphismFrom={\l_@@_morphism_dom_str}, shtml:assignMorphismTo={\l_stex_current_module_str?##1} }{} \bool_set_true:N \l_tmpa_bool } } } } \bool_if:NF \l_tmpa_bool { \msg_error:nnn{stex}{error/nomorphism}{#2} } }{} \cs_new_protected:Nn \_@@_do_morph_assign:nnn { \stex_iterate_break:n{ \str_set:Nx \l_@@_morphism_dom_str { \l_stex_current_domain_str ? #1 } \stex_debug:nn{assignMorphism}{match!} \stex_iterate_symbols:nn{#2}{ \stex_debug:nn{assignMorphism}{removing~##1?##3} % TODO: non-trivial assignments \prop_remove:Nn \l_stex_morphism_symbols_prop { [##1]/[##3] } } } } \stex_deactivate_macro:Nn \assign {morphism~environments} \stex_deactivate_macro:Nn \renamedecl {morphism~environments} \stex_deactivate_macro:Nn \assignMorphism {morphism~environments} % \end{macrocode} % % \begin{macrocode} \stex_new_stylable_env:nnnnnnn {copymodule}{m O{} m}{ \stex_structural_feature_morphism:nnnnn{#1}{morphism}{#2}{#3}{,shtml:total=false} \stex_if_smsmode:F { \tl_set:Nn \thiscopyname { #1 } \tl_set_eq:NN \thismoduleuri \l_stex_current_domain_str \stex_style_apply: } \stex_smsmode_do: }{ \stex_if_smsmode:F { \stex_style_apply: } \stex_structural_feature_morphism_end: }{}{}{} \stex_deactivate_macro:Nn \copymodule {module~environments} \stex_every_module:n { \stex_reactivate_macro:N \copymodule } \stex_sms_allow_env:n{copymodule} \stex_new_stylable_env:nnnnnnn {interpretmodule}{m O{} m}{ \stex_structural_feature_morphism:nnnnn{#1}{morphism}{#2}{#3}{,shtml:total=true} \stex_if_smsmode:F { \tl_set:Nn \thiscopyname { #1 } \tl_set_eq:NN \thismoduleuri \l_stex_current_domain_str \stex_style_apply: } \stex_smsmode_do: }{ \stex_structural_feature_morphism_check_total: \stex_if_smsmode:F { \stex_style_apply: } \stex_structural_feature_morphism_end: }{}{}{} \stex_deactivate_macro:Nn \interpretmodule {module~environments} \stex_every_module:n { \stex_reactivate_macro:N \interpretmodule } \stex_sms_allow_env:n{interpretmodule} % \end{macrocode} % % \begin{macrocode} \stex_new_stylable_env:nnnnnnn {realization}{O{} m}{ \stex_structural_feature_morphism:nnnnn{}{morphism}{#1}{#2}{,shtml:total=true} %\stex_execute_in_module:x{ % \stex_activate_module:n{\l_stex_current_domain_str} %} \stex_if_smsmode:F { \tl_set:Nn \thiscopyname { #2 } \tl_set_eq:NN \thismoduleuri \l_stex_current_domain_str \stex_style_apply: } \stex_smsmode_do: }{ \stex_structural_feature_morphism_check_total: \stex_if_smsmode:F { \stex_style_apply: } \stex_structural_feature_morphism_end: }{}{}{} \stex_deactivate_macro:Nn \realization {module~environments} \stex_every_module:n { \stex_reactivate_macro:N \realization } \stex_sms_allow_env:n{realization} % \end{macrocode} % % \begin{macrocode} \cs_new_protected:Nn \_@@_parse_assign:n { \str_clear:N \l_@@_name_str \str_clear:N \l_@@_newname_str \tl_clear:N \l_@@_ass_tl \stex_debug:nn{morphisms}{Parsing~#1} \exp_args:NNe \seq_set_split:Nnn \l_@@_seq {\tl_to_str:n{@}} {#1} \int_compare:nNnTF {\seq_count:N \l_@@_seq} = 1 { \stex_debug:nn{morphisms}{No~@} \seq_pop_left:NN \l_@@_seq \l_@@_next_tl }{ \seq_pop_left:NN \l_@@_seq \l_@@_name_str \stex_debug:nn{morphisms}{Name:~\l_@@_name_str} \exp_args:NNo \str_set:Nn \l_@@_name_str \l_@@_name_str \tl_set:Nx \l_@@_next_tl {\seq_use:Nn \l_@@_seq @} } \exp_args:NNNo \seq_set_split:Nnn \l_@@_seq = \l_@@_next_tl \str_if_empty:NTF \l_@@_name_str { \seq_pop_left:NN \l_@@_seq \l_@@_name_str \exp_args:NNo \str_set:Nn \l_@@_name_str \l_@@_name_str \tl_set:Nx \l_@@_ass_tl {\seq_use:Nn \l_@@_seq =} }{ \seq_pop_left:NN \l_@@_seq \l_@@_newname_str \exp_args:NNo \str_set:Nn \l_@@_newname_str \l_@@_newname_str \tl_set:Nx \l_@@_ass_tl {\seq_use:Nn \l_@@_seq =} } \_@@_do_parsed_assign: } \cs_new_protected:Nn \_@@_do_parsed_assign: { \exp_args:No \stex_get_in_morphism:n \l_@@_name_str \str_if_empty:NF \l_@@_newname_str { \exp_after:wN \_@@_do_parsed_newname: \l_@@_newname_str \_@@_end: } \tl_if_empty:NF \l_@@_ass_tl { \exp_args:No \_stex_assign_do:n \l_@@_ass_tl } } \cs_new_protected:Nn \_@@_do_parsed_newname: { \peek_charcode:NTF [ { \_@@_do_parsed_newname:w }{ \_@@_do_parsed_newname:w [] } } \cs_new_protected:Npn \_@@_do_parsed_newname:w [#1] #2 \_@@_end: { \_stex_renamedecl_do:nn{#1}{#2} } \stex_new_stylable_cmd:nnnn{copymod}{m O{} m m}{ \stex_structural_feature_morphism:nnnnn{#1}{morphism}{#2}{#3}{,shtml:total=false} \clist_map_function:nN{#4}\_@@_parse_assign:n \stex_if_smsmode:F { \tl_set:Nn \thiscopyname { #1 } \tl_set_eq:NN \thismoduleuri \l_stex_current_domain_str \stex_style_apply: } \stex_structural_feature_morphism_end: \stex_smsmode_do: }{} \stex_deactivate_macro:Nn \copymod {module~environments} \stex_every_module:n { \stex_reactivate_macro:N \copymod } \stex_sms_allow_escape:N\copymod \stex_new_stylable_cmd:nnnn{interpretmod}{m O{} m m}{ \stex_structural_feature_morphism:nnnnn{#1}{morphism}{#2}{#3}{,shtml:total=true} \clist_map_function:nN{#4}\_@@_parse_assign:n \stex_if_smsmode:F { \tl_set:Nn \thiscopyname { #1 } \tl_set_eq:NN \thismoduleuri \l_stex_current_domain_str \stex_style_apply: } \stex_structural_feature_morphism_check_total: \stex_structural_feature_morphism_end: \stex_smsmode_do: }{} \stex_deactivate_macro:Nn \interpretmod {module~environments} \stex_every_module:n { \stex_reactivate_macro:N \interpretmod } \stex_sms_allow_escape:N\interpretmod \stex_new_stylable_cmd:nnnn{realize}{O{} m m}{ \stex_structural_feature_morphism:nnnnn{}{morphism}{#1}{#2}{,shtml:total=true} \clist_map_function:nN{#3}\_@@_parse_assign:n \stex_if_smsmode:F { \tl_set:Nn \thiscopyname { #1 } \tl_set_eq:NN \thismoduleuri \l_stex_current_domain_str \stex_style_apply: } \stex_structural_feature_morphism_check_total: \stex_structural_feature_morphism_end: \stex_smsmode_do: }{} \stex_deactivate_macro:Nn \realize {module~environments} \stex_every_module:n { \stex_reactivate_macro:N \realize } \stex_sms_allow_escape:N\realize % \end{macrocode} % % \end{sfragment} % % % % \end{sfragment} % % % \begin{sfragment}{Symbols} % % \begin{sfragment}{Declarations} % \begin{macrocode} %<@@=stex_symdecl> % \end{macrocode} % Some setup: % % \begin{macro}[pTF]{\stex_if_check_terms:} % \begin{macrocode} \stex_if_html_backend:TF { \prg_new_conditional:Nnn \stex_if_check_terms: {p, T, F, TF} { \prg_return_false: } }{ \stex_get_env:Nn\_@@_env_str{STEX_CHECKTERMS} \str_if_empty:NF\_@@_env_str{ \exp_args:No \str_if_eq:nnF \_@@_env_str{false}{ \bool_set_true:N \c_stex_check_terms_bool } } \bool_if:NTF \c_stex_check_terms_bool { \prg_new_conditional:Nnn \stex_if_check_terms: {p, T, F, TF} { \prg_return_true: } }{ \prg_new_conditional:Nnn \stex_if_check_terms: {p, T, F, TF} { \prg_return_false: } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_check_term:n} % \begin{macrocode} \stex_if_check_terms:TF{ \cs_new_protected:Nn \stex_check_term:n { \hbox_set:Nn \l_tmpa_box { \group_begin: $#1$ \group_end: } } }{ \cs_new_protected:Nn \stex_check_term:n {} } % \end{macrocode} % \end{macro} % % |symdecl| arguments: % \begin{macrocode} \stex_keys_define:nnnn{symargs}{ \str_clear:N \l_stex_key_args_str \str_clear:N \l_stex_key_role_str \str_clear:N \l_stex_key_reorder_str \str_clear:N \l_stex_key_assoc_str }{ args .str_set:N = \l_stex_key_args_str , reorder .str_set:N = \l_stex_key_reorder_str , assoc .choices:nn = {bin,binl,binr,pre,conj,pwconj} {\str_set:Nx \l_stex_key_assoc_str \l_keys_choice_tl}, role .str_set:N = \l_stex_key_role_str }{} \stex_keys_define:nnnn{decl}{ \str_clear:N \l_stex_key_name_str \str_clear:N \l_stex_key_args_str \tl_clear:N \l_stex_key_type_tl \tl_clear:N \l_stex_key_def_tl \tl_clear:N \l_stex_key_return_tl \str_clear:N \l_stex_key_wikidata_str \clist_clear:N \l_stex_key_argtypes_clist }{ name .str_set:N = \l_stex_key_name_str , return .tl_set:N = \l_stex_key_return_tl , argtypes .clist_set:N = \l_stex_key_argtypes_clist , wikidata .str_set:N = \l_stex_key_wikidata_str , type .tl_set:N = \l_stex_key_type_tl , def .tl_set:N = \l_stex_key_def_tl , align .code:n = {}, gfc .code:n = {} }{style,deprecate,symargs} % \_stex_do_deprecation:n{#2} % \end{macrocode} % % \begin{macro}{\symdecl} % \begin{macrocode} \str_new:N \l_stex_macroname_str \stex_new_stylable_cmd:nnnn {symdecl} { s m O{}} { \stex_keys_set:nn{decl}{#3} \IfBooleanTF #1 { \str_clear:N \l_stex_macroname_str }{ \str_set:Nx \l_stex_macroname_str { #2 } } \stex_symdecl_top:n{#2} \stex_if_smsmode:F{ \group_begin: \tl_set:Nx \thisdecluri {\l_stex_current_module_str ? \l_stex_key_name_str} \tl_set_eq:NN \thisdeclname \l_stex_key_name_str \tl_set_eq:NN \thistype \l_stex_key_type_tl \tl_set_eq:NN \thisdefiniens \l_stex_key_def_tl \tl_set_eq:NN \thisargs \l_stex_key_args_str \tl_clear:N \thisstyle \stex_style_apply: \group_end: } \stex_smsmode_do: }{} \stex_deactivate_macro:Nn \symdecl {module~environments} \stex_every_module:n {\stex_reactivate_macro:N \symdecl} \stex_sms_allow_escape:N \symdecl % \end{macrocode} % \end{macro} % %% \begin{macro}{\stex_symdecl_top:n} % \begin{macrocode} \cs_new_protected:Nn \stex_symdecl_top:n { \str_if_empty:NT \l_stex_key_name_str { \str_set:Nx \l_stex_key_name_str { #1 } } \stex_symdecl_do: \_stex_symdecl_check_terms: \_@@_add_decl: \stex_if_do_html:T { \_stex_symdecl_html: } } \cs_new_protected:Nn \_@@_add_decl: { \exp_args:Nnx \use:nn {\stex_module_add_symbol:nnnnnnnN}{ {\l_stex_macroname_str} {\l_stex_key_name_str} {\int_use:N \l_stex_get_symbol_arity_int} {\l_stex_get_symbol_args_tl} {\tl_if_empty:NF \l_stex_key_def_tl{DEFED} }%{\exp_args:No \exp_not:n \l_stex_key_def_tl} {}%{\exp_args:No \exp_not:n \l_stex_key_type_tl} {\exp_args:No \exp_not:n \l_stex_key_return_tl} \stex_invoke_symbol: } \exp_args:Ne \stex_ref_new_symbol:n {\l_stex_current_module_str?\l_stex_key_name_str} } \cs_new:Nn \_stex_return_args:nn { {\svar{ARGUMENT_#1}\_stex_eat_exclamation_point:} } \cs_new_protected:Nn \_stex_symdecl_html: { \exp_args:Ne \stex_annotate_invisible:nn { shtml:symdecl = {\l_stex_current_module_str ? \l_stex_key_name_str}, shtml:args = {\l_stex_key_args_str} \str_if_empty:NF \l_stex_macroname_str {, shtml:macroname={\l_stex_macroname_str} } \str_if_empty:NF \l_stex_key_wikidata_str {, shtml:wikidata={\l_stex_key_wikidata_str} } \str_if_empty:NF \l_stex_key_assoc_str {, shtml:assoctype={\l_stex_key_assoc_str} } \str_if_empty:NF \l_stex_key_reorder_str {, shtml:reorderargs={\l_stex_key_reorder_str} } \str_if_empty:NF \l_stex_key_role_str {, shtml:role={\l_stex_key_role_str} } }{\hbox\bgroup\_stex_annotate_force_break:n{ \bool_set_true:N \stex_in_invisible_html_bool \tl_if_empty:NF \l_stex_key_type_tl { $\stex_annotate:nn{shtml:type={}}{\l_stex_key_type_tl}$ } \tl_if_empty:NF \l_stex_key_def_tl { $\stex_annotate:nn{shtml:definiens={}}{\l_stex_key_def_tl}$ } \tl_if_empty:NF \l_stex_key_return_tl{ \exp_args:Nno \use:n{ \cs_generate_from_arg_count:NNnn \l_@@_cs \cs_set:Npn \l_stex_get_symbol_arity_int} \l_stex_key_return_tl \tl_set:Nx \l_@@_args_tl {\_stex_map_args:N \_stex_return_args:nn} $\stex_annotate:nn{shtml:returntype={}}{ \exp_after:wN \l_@@_cs \l_@@_args_tl! }$ } \clist_if_empty:NF \l_stex_key_argtypes_clist { \stex_annotate:nn{shtml:argtypes={}}{\_stex_annotate_force_break:n{ \clist_map_inline:Nn \l_stex_key_argtypes_clist { $\stex_annotate:nn{shtml:type={}}{##1}$ } }} } }\egroup} } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_symdecl_do:} % Requires the above keys and \cs{l_stex_macroname_str} to be % set first % \begin{macrocode} \cs_new_protected:Nn \stex_symdecl_do: { \_stex_do_deprecation:n \l_stex_key_name_str \_@@_parse_arity: \_@@_do_args: } \int_new:N \l_stex_assoc_args_count \cs_new_protected:Nn \_@@_parse_arity: { \int_zero:N \l_stex_get_symbol_arity_int \int_zero:N \l_stex_assoc_args_count \str_map_inline:Nn \l_stex_key_args_str { \str_case:nnF ##1 { 0 { \str_map_break: } 1 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {1} \str_set:Nn \l_stex_key_args_str {i} } } 2 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {2} \str_set:Nn \l_stex_key_args_str {ii} } } 3 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {3} \str_set:Nn \l_stex_key_args_str {iii} } } 4 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {4} \str_set:Nn \l_stex_key_args_str {iiii} } } 5 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {5} \str_set:Nn \l_stex_key_args_str {iiiii} } } 6 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {6} \str_set:Nn \l_stex_key_args_str {iiiiii} } } 7 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {7} \str_set:Nn \l_stex_key_args_str {iiiiiii} } } 8 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {8} \str_set:Nn \l_stex_key_args_str {iiiiiiii} } } 9 { \str_map_break:n{ \int_set:Nn \l_stex_get_symbol_arity_int {9} \str_set:Nn \l_stex_key_args_str {iiiiiiiii} } } i {\int_incr:N \l_stex_get_symbol_arity_int} b {\int_incr:N \l_stex_get_symbol_arity_int} a {\int_incr:N \l_stex_get_symbol_arity_int \int_incr:N \l_stex_assoc_args_count} B {\int_incr:N \l_stex_get_symbol_arity_int \int_incr:N \l_stex_assoc_args_count} }{ \msg_error:nnxx{stex}{error/wrongargs}{ \l_stex_current_module_str ? \l_stex_key_name_str }{##1} } } } \cs_new_protected:Nn \_@@_do_args: { \tl_clear:N \l_stex_get_symbol_args_tl \int_step_inline:nn \l_stex_get_symbol_arity_int { \tl_put_right:Nn \l_stex_get_symbol_args_tl {##1} \tl_put_right:Nx \l_stex_get_symbol_args_tl { \str_item:Nn \l_stex_key_args_str {##1} } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_symdecl_check_terms:} % \begin{macrocode} \cs_new_protected:Nn \_stex_symdecl_check_terms: { \stex_check_term:n{ \stex_debug:nn{check_terms}{Checking~type...} \group_begin:\l_stex_key_type_tl\group_end: \stex_debug:nn{check_terms}{Checking~definiens...} \group_begin:\l_stex_key_def_tl\group_end: \stex_debug:nn{check_terms}{Checking~return...} \group_begin:\l_stex_key_return_tl!\group_end: \stex_debug:nn{check_terms}{Checking~argument~types...} \group_begin:\l_stex_key_argtypes_clist\group_end: } } % \end{macrocode} % \end{macro} % % \begin{macro}{\textsymdecl} % \begin{macrocode} \stex_keys_define:nnnn{textsymdecl}{ \str_clear:N \l_stex_key_name_str \tl_clear:N \l_stex_key_type_tl \tl_clear:N \l_stex_key_def_tl }{ name .str_set:N = \l_stex_key_name_str , type .tl_set:N = \l_stex_key_type_tl , def .tl_set:N = \l_stex_key_def_tl }{style,deprecate} \stex_new_stylable_cmd:nnnn {textsymdecl} {m O{} m} { \stex_keys_set:nn{symdef}{} \stex_keys_set:nn{textsymdecl}{#2} \str_set:Nx \l_stex_macroname_str { #1 } \str_if_empty:NT \l_stex_key_name_str { \str_set:Nn \l_stex_key_name_str {#1} }%{ % \str_set:Nx \l_stex_key_name_str {\l_stex_key_name_str-sym} %} \str_set:Nn \l_stex_key_role_str {textsymdecl} \stex_symdecl_do: \_stex_symdecl_check_terms: \exp_args:Nnx \use:nn {\stex_module_add_symbol:nnnnnnnN}{ {\l_stex_macroname_str} {\l_stex_key_name_str} {0}{} {\tl_if_empty:NF \l_stex_key_def_tl{DEFED} } {}% type {\use:c{#1name_nospace}}% return \stex_invoke_text_symbol: } \exp_args:Ne \stex_ref_new_symbol:n {\l_stex_current_module_str?\l_stex_key_name_str} \stex_if_do_html:T { \_stex_symdecl_html: } \int_set:Nn \l_stex_get_symbol_arity_int 0 \tl_clear:N \l_stex_key_op_tl \str_clear:N \l_stex_key_intent_str \str_clear:N \l_stex_key_prec_str \str_set_eq:NN \l_stex_get_symbol_mod_str \l_stex_current_module_str \str_set_eq:NN \l_stex_get_symbol_name_str \l_stex_key_name_str \stex_notation_parse:n{\hbox{#3}} \_stex_notation_add: \stex_if_do_html:T { \def\comp{\_comp} \_stex_notation_do_html:n{\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } \stex_execute_in_module:x{ \_@@_set_textsymdecl_macro:nnn{#1}{\l_stex_current_module_str?\l_stex_key_name_str} \exp_not:n{{#3}} } \stex_if_smsmode:F{ \group_begin: \tl_set:Nx \thisdecluri {\l_stex_current_module_str ? \l_stex_key_name_str} \tl_set_eq:NN \thisdeclname \l_stex_key_name_str \tl_clear:N \thisstyle \stex_style_apply: \group_end: } \stex_smsmode_do: }{} \stex_deactivate_macro:Nn \textsymdecl {module~environments} \stex_every_module:n {\stex_reactivate_macro:N \textsymdecl} \stex_sms_allow_escape:N \textsymdecl \cs_new_protected:Nn \_@@_set_textsymdecl_macro:nnn { \cs_set_protected:cpn{#1name_nospace}{#3} \cs_set_protected:cpn{#1name}{ \mode_if_vertical:T{\hbox_unpack:N\c_empty_box} \mode_if_math:T\hbox{\let\xspace\relax #3} \mode_if_math:F{\cs_if_exist:NT\xspace\xspace} } } \cs_new_protected:Nn \stex_invoke_text_symbol: { \mode_if_vertical:T{\hbox_unpack:N\c_empty_box} \_stex_term_oms_or_omv:nnn{}{}{\maincomp{\let\xspace\relax\l_stex_current_return_tl}} \group_end:\mode_if_math:F{\cs_if_exist:NT\xspace\xspace} } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_get_symbol:n} % \begin{macrocode} \cs_new_protected:Nn \stex_get_symbol:n { \_stex_get_symbol:n{ #1 } \str_if_empty:NT \l_stex_get_symbol_name_str { \msg_error:nnn{stex}{error/unknownsymbol}{#1} } } \cs_new_protected:Nn \_stex_get_symbol:n { \str_clear:N \l_stex_get_symbol_mod_str \str_clear:N \l_stex_get_symbol_name_str \cs_if_exist:cTF { #1 }{ \cs_set_eq:Nc \l_@@_cs { #1 } % command name \exp_args:Ne \tl_if_empty:nTF { \cs_argument_spec:N \l_@@_cs }{ % ...that takes no arguments \exp_args:Ne \cs_if_eq:NNTF {\tl_head:N \l_@@_cs} \_stex_invoke_symbol:nnnnnnnN \_@@_get_symbol_from_cs: {\_@@_get_symbol_from_string:n { #1 }} }{ \_@@_get_symbol_from_string:n { #1 } } }{ \_@@_get_symbol_from_string:n { #1 } } } \int_new:N \l_stex_get_symbol_arity_int \cs_new_protected:Nn \_@@_get_symbol_from_cs: { \stex_debug:nn{symbols}{Getting~from~cs...} \stex_pseudogroup_with:nn{\_stex_invoke_symbol:nnnnnnnN}{ \cs_set:Npn \_stex_invoke_symbol:nnnnnnnN ##1 ##2 ##3 ##4 ##5 ##6 ##7 ##8 { \str_set:Nn \l_stex_get_symbol_mod_str {##1} \str_set:Nn \l_stex_get_symbol_name_str {##2} \int_set:Nn \l_stex_get_symbol_arity_int {##3} \tl_set:Nn \l_stex_get_symbol_args_tl {##4} \tl_set:Nn \l_stex_get_symbol_def_tl {##5} \tl_set:Nn \l_stex_get_symbol_type_tl {##6} \tl_set:Nn \l_stex_get_symbol_return_tl {##7} \tl_set:Nn \l_stex_get_symbol_invoke_cs {##8} } \l_@@_cs } } \cs_new_protected:Nn \_@@_get_symbol_from_string:n { \stex_debug:nn{symbols}{Getting~from~string~#1...} \seq_set_split:Nnn \l_@@_seq ? {#1} \seq_pop_right:NN \l_@@_seq \l_@@_name \seq_if_empty:NTF \l_@@_seq { \exp_args:No \_@@_get_from_one_string:n {#1} }{ \exp_args:NNe \exp_args:Nno \_@@_get_symbol_from_modules:nn { \seq_use:Nn \l_@@_seq ? } \l_@@_name } } \cs_new_protected:Nn \_@@_sym_from_str_i:nnnn { \bool_lazy_any:nTF{ {\str_if_eq_p:nn{#2}{#3}} {\str_if_eq_p:nn{#2}{#4}} {\stex_str_if_ends_with_p:nn{#4}{/#2}} }{ \_@@_sym_i_finish:nnnnnnnN{#1}{#4} }{ \_@@_sym_i_gobble:nnnnnn } } \cs_new_protected:Nn \_@@_sym_i_gobble:nnnnnn {} \cs_new_protected:Nn \_@@_sym_i_finish:nnnnnnnN { \prop_map_break:n{\seq_map_break:n{ \str_set:Nn \l_stex_get_symbol_mod_str {#1} \str_set:Nn \l_stex_get_symbol_name_str {#2} \int_set:Nn \l_stex_get_symbol_arity_int {#3} \tl_set:Nn \l_stex_get_symbol_args_tl {#4} \tl_set:Nn \l_stex_get_symbol_def_tl {#5} \tl_set:Nn \l_stex_get_symbol_type_tl {#6} \tl_set:Nn \l_stex_get_symbol_return_tl {#7} \tl_set:Nn \l_stex_get_symbol_invoke_cs {#8} }} } \cs_new_protected:Nn \_@@_get_symbol_from_modules:nn { \stex_debug:nn{symbols}{Getting~#2~in~#1...} \seq_map_inline:Nn \l_stex_all_modules_seq { \stex_str_if_ends_with:nnT{##1}{#1}{ \prop_map_inline:cn{c_stex_module_##1_symbols_prop}{ \_@@_sym_from_str_i:nnnn{##1}{#2} ####2 } } } } \cs_new_protected:Nn \_@@_get_from_one_string:n { \stex_debug:nn{symbols}{Getting~#1~anywhere...} \stex_iterate_symbols:n{ %\stex_debug:nn{symbols}{>#1==##2~|~#1==##3<...} \bool_lazy_any:nT{ {\str_if_eq_p:nn{#1}{##2}} {\str_if_eq_p:nn{#1}{##3}} {\stex_str_if_ends_with_p:nn{##3}{/#1}} }{ \stex_iterate_break:n{ \str_set:Nn \l_stex_get_symbol_mod_str {##1} \str_set:Nn \l_stex_get_symbol_name_str {##3} \int_set:Nn \l_stex_get_symbol_arity_int {##4} \tl_set:Nn \l_stex_get_symbol_args_tl {##5} \tl_set:Nn \l_stex_get_symbol_def_tl {##6} \tl_set:Nn \l_stex_get_symbol_type_tl {##7} \tl_set:Nn \l_stex_get_symbol_return_tl {##8} \tl_set:Nn \l_stex_get_symbol_invoke_cs {##9} } } } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Notations} % \begin{macrocode} %<@@=stex_notations> % \end{macrocode} % % \begin{macro}{\_stex_map_args:N,\_stex_map_notation_args:N} % \begin{macrocode} \cs_new:Nn \_stex_map_args:N { \tl_if_empty:NF \l_stex_get_symbol_args_tl { \exp_after:wN \_@@_map_args_i:w \exp_after:wN #1 \l_stex_get_symbol_args_tl \_@@_args_end: } } \cs_new:Npn \_@@_map_args_i:w #1 #2 #3 #4 \_@@_args_end: { #1 #2 #3 \tl_if_empty:nF{#4}{ \_@@_map_args_i:w #1 #4 \_@@_args_end: } } \cs_new:Nn \_stex_map_notation_args:N { \tl_if_empty:NF \l_stex_notation_args_tl { \exp_after:wN \_@@_map_args_ii:w \exp_after:wN #1 \l_stex_get_symbol_args_tl \_@@_args_end: } } \cs_new:Npn \_@@_map_args_ii:w #1 #2 #3 #4 #5 #6 \_@@_args_end: { #1 #2 #3 #4 #5 \tl_if_empty:nF{#6}{ \_@@_map_args_ii:w #1 #6 \_@@_args_end: } } % \end{macrocode} % \end{macro} % % |notation| arguments: % \begin{macrocode} \stex_keys_define:nnnn{notation}{ \str_clear:N \l_stex_key_variant_str \str_clear:N \l_stex_key_prec_str \str_clear:N \l_stex_key_op_tl \str_clear:N \l_stex_key_intent_str \clist_clear:N \l_stex_key_intent_args_clist }{ variant .str_set_x:N = \l_stex_key_variant_str , prec .str_set_x:N = \l_stex_key_prec_str , op .tl_set:N = \l_stex_key_op_tl , intent .str_set:N = \l_stex_key_intent_str , argnames .clist_set:N = \l_stex_key_intent_args_clist , unknown .code:n = { \str_if_empty:NTF \l_keys_key_str { \str_set:Nx \l_stex_key_variant_str {\l_keys_key_tl} }{ \str_set_eq:NN \l_stex_key_variant_str \l_keys_key_str } } }{style} % \end{macrocode} % % \begin{macro}{\notation} % \begin{macrocode} \stex_new_stylable_cmd:nnnn {notation} { s m O{} m} { \stex_keys_set:nn{notation}{#3} \stex_get_symbol:n{#2} \stex_notation_parse:n{#4} \stex_if_check_terms:T{ \_stex_notation_check: } \_stex_notation_add: \stex_if_do_html:T { \def\comp{\_comp} \_stex_notation_do_html:n{\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } \IfBooleanTF#1{ \_stex_notation_set_default:n{ \l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str } }{} \stex_if_smsmode:F{ \group_begin: \_@@_styledefs: \stex_style_apply: \group_end: } \stex_smsmode_do: }{} \cs_new_protected:Nn \_@@_styledefs: { \str_set_eq:NN\thisnotationvariant\l_stex_key_variant_str \str_set:Nn \thisdeclname \l_stex_get_symbol_name_str \tl_set:Nx \thisdecluri {\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} \def\thisnotation{ $ \tl_set_eq:NN \l_stex_current_symbol_str\thisdecluri \exp_args:Nne \use:nn{\l_stex_notation_macrocode_cs}{ \_stex_notation_make_args: }$ } } \stex_deactivate_macro:Nn \notation {module~environments} \stex_every_module:n {\stex_reactivate_macro:N \notation} \stex_sms_allow_escape:N \notation % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_notation_parse:n} % requires the above keys, \cs{l_stex_get_symbol_arity_int}, and % \cs{l_stex_get_symbol_args_tl} % \begin{macrocode} \cs_new_protected:Nn \stex_notation_parse:n { \tl_if_empty:NF \l_stex_key_op_tl { \tl_set:Nx \l_stex_key_op_tl { \exp_not:N\maincomp { \exp_args:No \exp_not:n \l_stex_key_op_tl } } } \seq_clear:N \l_@@_precs_seq \tl_clear:N \l_stex_notation_args_tl \int_compare:nNnTF \l_stex_get_symbol_arity_int = 0 { \_@@_const_precs: \tl_if_empty:NT \l_stex_key_op_tl { \tl_set:Nn \l_stex_key_op_tl { \maincomp{#1} } } }{ \_@@_fun_precs: \str_set:Nn \l_@@_missing_str {#1} \tl_clear:N \l_@@_missing_tl \_stex_map_args:N \_@@_add_missing_args:nn \tl_if_empty:NT \l_stex_key_op_tl { \hbox_set:Nn \l_tmpa_box { \str_set:Nn \l_stex_current_symbol_str {} \cs_set:Npn \l_tmpa_cs ##1 ##2 ##3 ##4 ##5 ##6 ##7 ##8 ##9 { #1 } \cs_set:Npn \maincomp ##1 { \tl_gset:Nn \l_stex_key_op_tl { \maincomp{##1} } ##1 } \cs_set:Npn \argsep ##1 ##2 {##1 ##2} \cs_set:Npn \argmap ##1 ##2 ##3 {##1 ##3} \cs_set:Npn \argarraymap ##1 ##2 ##3 ##4 { ##1 ##2 } \stex_suppress_html:n{$\l_tmpa_cs abcdefghj$} } } } \exp_args:NNe \tl_set:Nn \l_stex_notation_macrocode_cs { \STEXInternalNotation { \l_stex_key_variant_str } { \l_@@_opprec_tl } { \l_stex_key_intent_str } { \l_stex_notation_args_tl } { \int_compare:nNnTF \l_stex_get_symbol_arity_int = 0 { \exp_not:n { \maincomp{ #1 } } } { \exp_not:n { #1 } \l_@@_missing_tl } } } \stex_debug:nn{notation}{Notation:~\meaning\l_stex_notation_macrocode_cs} } \cs_new_protected:Nn \_@@_const_precs: { \str_if_empty:NTF \l_stex_key_prec_str { \tl_set:No \l_@@_opprec_tl { \neginfprec } }{ \str_if_eq:onTF \l_stex_key_prec_str {nobrackets}{ \tl_set:No \l_@@_opprec_tl { \neginfprec } }{ \tl_set_eq:NN \l_@@_opprec_tl \l_stex_key_prec_str } } } \cs_new_protected:Nn \_@@_fun_precs: { \str_if_empty:NTF \l_stex_key_prec_str { \tl_set:No \l_@@_opprec_tl { \neginfprec } }{ \str_if_eq:onTF \l_stex_key_prec_str {nobrackets}{ \tl_set:No \l_@@_opprec_tl { \neginfprec } }{ \tl_set_eq:NN \l_@@_opprec_tl \l_stex_key_prec_str } } \str_if_empty:NTF \l_stex_key_prec_str { \tl_set:Nn \l_@@_opprec_tl { 0 } \int_step_inline:nn \l_stex_get_symbol_arity_int { \seq_put_right:Nn \l_@@_precs_seq {0} } }{ \str_if_eq:onTF \l_stex_key_prec_str {nobrackets}{ \stex_debug:nn{notation}{No~brackets} \tl_set:No \l_@@_opprec_tl { \neginfprec } \int_step_inline:nn \l_stex_get_symbol_arity_int { \exp_args:NNo \seq_put_right:Nn \l_@@_precs_seq \infprec } }\_@@_parse_precs: } \_@@_do_argnames: } \cs_new_protected:Nn \_@@_parse_precs: { \stex_debug:nn{notation}{parsing~precedence~\l_stex_key_prec_str} \seq_set_split:NnV \l_@@_seq ; \l_stex_key_prec_str \seq_pop_left:NNTF \l_@@_seq \l_@@_str { \tl_set_eq:NN \l_@@_opprec_tl \l_@@_str \seq_pop_left:NNT \l_@@_seq \l_@@_str { \exp_args:NNo \seq_set_split:NnV \l_@@_seq {\tl_to_str:n{x}} \l_@@_str } }{ \tl_set:No \l_@@_opprec_tl { 0 } } \int_step_inline:nn \l_stex_get_symbol_arity_int { \seq_pop_left:NNTF \l_@@_seq \l_@@_str { \seq_put_right:No \l_@@_precs_seq \l_@@_str }{ \seq_put_right:No \l_@@_precs_seq \l_@@_opprec_tl } } } \cs_new_protected:Nn \_@@_do_argnames: { \tl_clear:N \l_stex_notation_args_tl \_stex_map_args:N \_@@_do_argname:nn } \cs_new_protected:Nn \_@@_do_argname:nn { \clist_if_empty:NTF \l_stex_key_intent_args_clist { \tl_put_right:Nx \l_stex_notation_args_tl { #1#2{\seq_item:Nn \l_@@_precs_seq #1}{ \str_if_empty:NF \l_stex_key_intent_str {#1} } } }{ \tl_put_right:Nx \l_stex_notation_args_tl { #1#2{\seq_item:Nn \l_@@_precs_seq #1} {\c_dollar_str\clist_item:Nn \l_stex_key_intent_args_clist 1} } \clist_pop:NN \l_stex_key_intent_args_clist \l_tmpa_tl } } \cs_new:Nn \_@@_add_missing_args:nn { \exp_args:NNe \str_if_in:NnF \l_@@_missing_str {\c_hash_str\c_hash_str#1}{ \tl_put_right:Nn \l_@@_missing_tl{\STEXinvisible{## #1}} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_notation_check:,\_stex_notation_add:,\_stex_notation_do_html:n,\_stex_notation_make_args:} % \begin{macrocode} \cs_new_protected:Nn \_stex_notation_check: { \stex_check_term:n{ \str_set:Nn \l_stex_current_symbol_str {test} \cs_set:Npn \comp ##1 {##1} \stex_debug:nn{check_terms}{Checking~notation...} \exp_args:Nne \use:nn{\l_stex_notation_macrocode_cs{}}{ \_stex_notation_make_args: } } } \cs_new_protected:Nn \_stex_notation_add: { \stex_module_add_notation:eoeoo{ \l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str }\l_stex_key_variant_str {\int_use:N \l_stex_get_symbol_arity_int} \l_stex_notation_macrocode_cs \l_stex_key_op_tl } \cs_new_protected:Nn \_stex_notation_do_html:n { \hbox{\stex_annotate_invisible:nn { shtml:notation={#1}, shtml:notationfragment={\l_stex_key_variant_str}, shtml:precedence={\l_@@_opprec_tl}, shtml:argprecs={\seq_use:Nn \l_@@_precs_seq ,} }{ \cs_set_protected:Npn \argsep ##1 ##2 { \stex_annotate:nn{shtml:argsep={}}{ ##1 ##2 } } \cs_set_protected:Npn \argmap ##1 ##2 ##3 { \cs_set:Npn \_@@_map_cs: ####1 { ##2 } \stex_annotate:nn{shtml:argmap={}}{ \_@@_map_cs:{##1} ##3 } } \cs_set_protected:Npn \maincomp { \_do_comp:nNn {maincomp}\compemph@uri } $ \str_set:Nx \l_stex_current_symbol_str {#1} \stex_annotate:nn{shtml:notationcomp={}}{ \exp_args:Nne \use:nn { \l_stex_notation_macrocode_cs {} }{ \_stex_map_args:N \_@@_make_arg_html:nn } } $ \tl_if_empty:NF \l_stex_key_op_tl { $ \str_set:Nx \l_stex_current_symbol_str {#1} \stex_annotate:nn{shtml:notationopcomp={}}{ \_stex_term_oms:nnn{\l_stex_key_variant_str}{}{\l_stex_key_op_tl} } $ } }} } \cs_new:Nn \_@@_make_arg_html:nn { % \str_case:nnF #2 { % a {{ % \stex_annotate:nn{shtml:argnum=#1a}{x}, % \stex_annotate:nn{shtml:argnum=#1b}{x} % }} % B {{ % \stex_annotate:nn{shtml:argnum=#1a}{x}, % \stex_annotate:nn{shtml:argnum=#1b}{x} % }} % }{ { \stex_annotate:nn{shtml:argnum=#1}{x} } % } } \cs_new:Nn \_stex_notation_make_args: { \_stex_map_notation_args:N \_@@_make_arg:nnnn } \cs_new:Nn \_@@_make_arg:nnnn { \str_case:nnF #2 { a {{ a\c_math_subscript_token{#1,1}, a\c_math_subscript_token{#1,2} }} B {{ B\c_math_subscript_token{#1,1}, B\c_math_subscript_token{#1,2} }} }{ \_stex_term_arg:nnnnn{#1}{#2}{#3}{#4} {{#2}\c_math_subscript_token{#1}} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\setnotation,\_stex_notation_set_default:n} % \begin{macrocode} \cs_new_protected:Npn \setnotation #1 #2 { \stex_get_symbol:n{#1} \cs_if_exist:cTF{l_stex_notation_ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str _#2_cs }{ \tl_set_eq:Nc \l_stex_notation_macrocode_cs {l_stex_notation_ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str _#2_cs } \cs_if_exist:cTF{l_stex_notation_ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str _op_#2_cs }{ \tl_set_eq:Nc \l_stex_key_op_tl {l_stex_notation_ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str _op_#2_cs } }{ \tl_clear:N \l_stex_key_op_tl } \_stex_notation_set_default:n{ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str } }{ \msg_error:nnxx{stex}{unknownnotation}{#2}{ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str } } } \cs_new_protected:Nn \_stex_notation_set_default:n{ \stex_if_in_module:TF{ \stex_module_add_notation:eoeoo{#1}{} {\int_use:N \l_stex_get_symbol_arity_int} \l_stex_notation_macrocode_cs \l_stex_key_op_tl }{ \cs_set_eq:cN {l_stex_notation_ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str __cs}\l_stex_notation_macrocode_cs \tl_if_empty:NF \l_stex_key_op_tl { \cs_set_eq:cN{l_stex_notation_ \l_stex_get_symbol_mod_str?\l_stex_get_symbol_name_str _op__cs}\l_stex_key_op_tl } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\varnotation} % \begin{macrocode} \stex_new_stylable_cmd:nnnn {varnotation} { s m O{} m} { \stex_keys_set:nn{notation}{#3} \stex_get_var:n{#2} \str_set_eq:NN \l_stex_key_name_str \l_stex_get_symbol_name_str \stex_notation_parse:n{#4} \stex_if_check_terms:T{ \_stex_notation_check: } \_stex_vardecl_notation_macro: \IfBooleanTF#1{ \_stex_notation_set_default:n{\l_stex_get_symbol_name_str} }{} \group_begin: \tl_set_eq:NN \thisvarname \l_stex_get_symbol_name_str \tl_clear:N \thisstyle \str_set_eq:NN\thisnotationvariant\l_stex_key_variant_str \def\thisnotation{ $\let\l_stex_current_symbol_str\thisvarname \def\comp{\_varcomp}\exp_args:Nne \use:nn{\l_stex_notation_macrocode_cs{}}{ \_stex_notation_make_args: }$ } \stex_style_apply: \group_end: }{} % \end{macrocode} % \end{macro} % % \begin{macro}{\symdef} % \begin{macrocode} \stex_keys_define:nnnn{symdef}{}{}{decl,notation} \cs_new_protected:Nn \_stex_symdef_styledefs: { \tl_set:Nx \thisdecluri {\l_stex_current_module_str ? \l_stex_key_name_str} \tl_set_eq:NN \thisdeclname \l_stex_key_name_str \tl_set_eq:NN \thistype \l_stex_key_type_tl \tl_set_eq:NN \thisdefiniens \l_stex_key_def_tl \tl_set_eq:NN \thisargs \l_stex_key_args_str \tl_clear:N \thisstyle \str_set_eq:NN\thisnotationvariant\l_stex_key_variant_str \def\thisnotation{ $\let\l_stex_current_symbol_str\thisdecluri \def\comp{\_comp}\exp_args:Nne \use:nn{\l_stex_notation_macrocode_cs}{ \_stex_notation_make_args: }$ } } \stex_new_stylable_cmd:nnnn {symdef} { m O{} m} { \stex_keys_set:nn{symdef}{#2} \str_set:Nx \l_stex_macroname_str { #1 } \stex_symdecl_top:n{#1} \stex_debug:nn{symdef}{Doing~\l_stex_current_module_str ? \l_stex_key_name_str} \str_set_eq:NN \l_stex_get_symbol_mod_str \l_stex_current_module_str \str_set_eq:NN \l_stex_get_symbol_name_str \l_stex_key_name_str \stex_notation_parse:n{#3} \stex_debug:nn{Here!}{\meaning\l_stex_notation_args_tl} \_stex_notation_check: \_stex_notation_add: \stex_if_do_html:T{ \_stex_notation_do_html:n{\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } \stex_if_smsmode:F{ \group_begin: \_stex_symdef_styledefs: \stex_style_apply: \group_end: } \stex_smsmode_do: }{} \stex_deactivate_macro:Nn \symdef {module~environments} \stex_every_module:n {\stex_reactivate_macro:N \symdef} \stex_sms_allow_escape:N \symdef % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_do_default_notation_op:} % \begin{macrocode} \cs_new_protected:Nn \stex_do_default_notation: { \stex_do_default_notation_op: \tl_if_empty:NTF \l_stex_current_args_tl { \tl_clear:N \l_@@_args_tl }{ \_@@_make_name: \tl_set_eq:NN \l_stex_get_symbol_args_tl \l_stex_current_args_tl \tl_set:Nx \l_@@_args_tl { \_stex_map_args:N \_@@_augment_arg:nn } \tl_put_right:Nn \l_stex_default_notation {\comp(} \seq_clear:N \l_tmpa_seq \int_step_inline:nn \l_stex_current_arity_str { \seq_put_right:Nn \l_tmpa_seq {#### ##1} } \tl_put_right:Nx \l_stex_default_notation { \seq_use:Nn \l_tmpa_seq {\mathpunct{\comp{,}}} } \tl_put_right:Nn \l_stex_default_notation {\comp)} } \tl_set:Nx \l_stex_default_notation {\STEXInternalNotation{}{0}{}{\l_@@_args_tl}{ \exp_args:No \exp_not:n \l_stex_default_notation }} } \cs_new:Nn \_@@_augment_arg:nn { #1#2{0}{} } \cs_new_protected:Nn \_@@_make_name: { \exp_args:NNNo \seq_set_split:Nnn \l_tmpa_seq ? \l_stex_current_symbol_str \seq_pop_right:NN \l_tmpa_seq \l_@@_name_str \exp_args:NNNo \seq_set_split:Nnn \l_tmpa_seq / \l_@@_name_str \seq_pop_right:NN \l_tmpa_seq \l_@@_name_str } \cs_new_protected:Nn \stex_do_default_notation_op: { \_@@_make_name: \tl_set:Nx \l_stex_default_notation {\exp_not:N \maincomp{ \exp_not:N \mathrm {\l_@@_name_str} }} } % \end{macrocode} % \end{macro} % % \begin{macro}{\STEXInternalNotation} % \begin{macrocode} % 1: variant 2: operator precedence 3: intent 4: arguments 5: code 6: next \cs_new_protected:Npn \STEXInternalNotation #1 #2 #3 #4 #5 #6 { \_@@_process_notation:nnnnnn{#1}{#2}{#3}{#4}{#5}{ \l_@@_code_tl #6 } } \cs_new_protected:Npn \_@@_process_notation:nnnnnn #1 #2 #3 #4 { \tl_if_empty:nTF{#4}{ \_@@_simple:nnnnn{#1}{#2}{#3} }{ \_@@_complex:nnnnnn{#1}{#2}{#3}{#4} } } \cs_new_protected:Nn \_@@_simple:nnnnn { \stex_debug:nn{Notation~code}{\tl_to_str:n{#4}} \tl_set:Nn \l_@@_code_tl { \cs_set:Npn \l_@@_cs { \_stex_maybe_brackets:nn{#2}{ \_stex_term_oms_or_omv:nnn{#1}{#3}{#4} } } \l_@@_cs } \stex_debug:nn{Here:Notation}{\meaning \l_@@_code_tl } #5 } \cs_new_protected:Nn \_@@_complex:nnnnnn { \stex_debug:nn{Notation~code}{\tl_to_str:n{#5}} \int_zero:N \l_tmpa_int \tl_set:Nn \l_@@_pre_tl {\cs_set_eq:NN \_stex_term_oma_or_omb:nnn \_stex_term_oma:nnn} \tl_set:Nn \l_@@_code_tl { \cs_generate_from_arg_count:NNnn \l_@@_cs \cs_set:Npn \l_tmpa_int { \_stex_maybe_brackets:nn{#2}{ \_stex_term_oma_or_omb:nnn{#1}{#3}{ \bool_set_false:N \l_stex_brackets_dones_bool #5 } } } \l_@@_cs } \tl_set:Nn \l_@@_after_tl{ \exp_args:NNo \tl_put_left:Nn \l_@@_code_tl \l_@@_pre_tl \tl_put_left:Nx \l_@@_code_tl { \int_set:Nn \l_tmpa_int {\int_use:N \l_tmpa_int} } \stex_debug:nn{Here:Notation}{\meaning \l_@@_code_tl } #6 } \_@@_parse_notation_args:nnnnw #4 \_@@_args_end: } \cs_new_protected:Npn \_@@_parse_notation_args:nnnnw #1 #2 #3 #4 #5 \_@@_args_end: { \tl_if_empty:nTF{#5}{ \_@@_add_last:nnnnn{#1}{#2}{#3}{#4} }{ \_@@_add_next:nnnnnn{#1}{#2}{#3}{#4}{#5} } } \cs_new_protected:Nn \_@@_add_next:nnnnnn { \_@@_add:nnnnn{#1}{#2}{#3}{#4}{#6} \_@@_parse_notation_args:nnnnw #5 \_@@_args_end: } \cs_new_protected:Nn \_@@_add_last:nnnnn { \_@@_add:nnnnn{#1}{#2}{#3}{#4}{#5} \l_@@_after_tl } \cs_new_protected:Nn \_@@_add:nnnnn { \int_incr:N \l_tmpa_int \str_case:nn{#2}{ i { \tl_put_right:Nn \l_@@_code_tl { {\_stex_term_arg:nnnnn{#1}{#2}{#3}{#4}{#5}} } } b { \tl_set:Nn \l_@@_pre_tl { \cs_set_eq:NN \_stex_term_oma_or_omb:nnn \_stex_term_omb:nnn } \tl_put_right:Nn \l_@@_code_tl { {\_stex_term_arg:nnnnn{#1}{#2}{#3}{#4}{#5}} } } a { \tl_put_right:Nn \l_@@_code_tl { {\_stex_term_arg_aB:nnnnn{#1}{#2}{#3}{#4}{#5}} } } B { \tl_set:Nn \l_@@_pre_tl { \cs_set_eq:NN \_stex_term_oma_or_omb:nnn \_stex_term_omb:nnn } \tl_put_right:Nn \l_@@_code_tl { {\_stex_term_arg_aB:nnnnn{#1}{#2}{#3}{#4}{#5}} } } } } % \end{macrocode} % \end{macro} % % \begin{sfragment}{a/B-mode argument handling} % % \begin{macro}{\argsep} % \begin{macrocode} \cs_new_protected:Nn \_@@_check_aB_arg:Nn { \exp_args:Ne \cs_if_eq:NNF {\tl_head:n{#2}} \_stex_term_arg_aB:nnnnn { \msg_error:nnx{stex}{error/assocarg}{\tl_to_str:n{#1}} } } \cs_new_protected:Npn \argsep #1 #2 { \_@@_check_aB_arg:Nn\argsep{#1} \stex_pseudogroup_with:nn{\_stex_term_do_aB_clist:}{ \tl_set:Nn \_stex_term_do_aB_clist: { \seq_use:Nn \l_stex_aB_args_seq {#2} } #1 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\argmap} % \begin{macrocode} \cs_new_protected:Npn \argmap #1 #2 #3 { \_@@_check_aB_arg:Nn\argmap{#1} \stex_pseudogroup_with:nn{ \_stex_term_do_aB_clist: \_@@_map_cs: }{ \cs_set:Npn \_@@_map_cs: ##1 { #2 } \tl_set:Nn \_stex_term_do_aB_clist: { \seq_clear:N \l_tmpa_seq \seq_map_inline:Nn \l_stex_aB_args_seq { \tl_if_eq:nnTF{##1}{\ellipses}{ \seq_put_right:Nn \l_tmpa_seq \ellipses }{ \seq_put_right:Nx \l_tmpa_seq { \exp_after:wN \exp_not:n \exp_after:wN { \_@@_map_cs: {##1} } } } } \seq_set_eq:NN \l_stex_aB_args_seq \l_tmpa_seq \seq_use:Nn \l_stex_aB_args_seq {#3} } #1 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\argarraymap} % \begin{macrocode} \int_new:N \l_@@_clist_count_int \cs_new_protected:Npn \argarraymap #1 #2 #3 #4 { \_@@_check_aB_arg:Nn\argarraymap{#1} \stex_pseudogroup_with:nn{ \_stex_term_do_aB_clist: \_@@_map_cs: }{ \cs_set:Npn \_@@_map_cs: ##1 { #3 } \int_set:Nn \l_@@_clist_count_int {\exp_args:No\clist_count:n{\tl_to_str:n{#4}}} \tl_set:Nn \_stex_term_do_aB_clist: { \tl_clear:N \l_tmpa_tl \int_zero:N \l_tmpa_int \seq_map_inline:Nn \l_stex_aB_args_seq { \int_incr:N \l_tmpa_int \int_compare:nNnT \l_tmpa_int > \l_@@_clist_count_int { \int_set:Nn \l_tmpa_int 1 } \tl_put_right:Nx \l_tmpa_tl { \exp_after:wN \exp_not:n \exp_after:wN { \_@@_map_cs: {##1} } \clist_item:nn{#4}\l_tmpa_int } } \seq_set_eq:NN \l_stex_aB_args_seq \l_tmpa_seq \begin{array}{#2} \l_tmpa_tl \end{array} } #1 } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \end{sfragment} % % \begin{sfragment}{Variables} % \begin{macrocode} %<@@=stex_vars> % \end{macrocode} % % \begin{macro}{\vardef} % \begin{macrocode} \tl_new:N \l_stex_variables_prop \bool_new:N \l_@@_bind_bool \cs_new_protected:Nn \_stex_variable:nnnnnnnN {} \stex_keys_define:nnnn{vardef}{ \bool_set_false:N \l_@@_bind_bool }{ bind .bool_set:N = \l_@@_bind_bool }{symdef} \stex_new_stylable_cmd:nnnn {vardef} { m O{} m} { \stex_keys_set:nn{vardef}{#2} \str_set:Nx \l_stex_macroname_str { #1 } \str_if_empty:NT \l_stex_key_name_str { \str_set:Nx \l_stex_key_name_str { #1 } } \stex_symdecl_do: \_stex_symdecl_check_terms: \_@@_add: \_@@_macro: \stex_if_do_html:T \_@@_html: \int_set:Nn \l_stex_get_symbol_arity_int {\l_stex_get_symbol_arity_int} \stex_debug:nn{vardef}{Doing~\l_stex_key_name_str} \tl_set_eq:NN \l_stex_get_symbol_return_tl \l_stex_key_return_tl \stex_notation_parse:n{#3} \stex_if_check_terms:T{ \_stex_notation_check: } \_stex_vardecl_notation_macro: \stex_if_do_html:T { \def\comp{\_varcomp} \_stex_notation_do_html:n \l_stex_key_name_str } \group_begin: \tl_set_eq:NN \thisvarname \l_stex_key_name_str \tl_clear:N \thisstyle \str_set_eq:NN\thisnotationvariant\l_stex_key_variant_str \def\thisnotation{ $\let\l_stex_current_symbol_str\thisvarname \def\comp{\_varcomp}\exp_args:Nne \use:nn{\l_stex_notation_macrocode_cs{}}{ \_stex_notation_make_args: }$ } \stex_style_apply: \group_end:\ignorespaces }{} \cs_new_protected:Nn \_@@_add: { \exp_args:NNNo \exp_args:NNnx \prop_put:Nnn \l_stex_variables_prop \l_stex_key_name_str { {\l_stex_macroname_str} {\l_stex_key_name_str} {\int_use:N \l_stex_get_symbol_arity_int} {\l_stex_get_symbol_args_tl} {\exp_args:No \exp_not:n \l_stex_key_def_tl} {\exp_args:No \exp_not:n \l_stex_key_type_tl} {\exp_args:No \exp_not:n \l_stex_key_return_tl} \stex_invoke_symbol: } } \cs_new_protected:Nn \_@@_macro: { \tl_set:cx{\l_stex_macroname_str}{ \_stex_invoke_variable:nnnnnnN {\l_stex_key_name_str} {\int_use:N \l_stex_get_symbol_arity_int} {\l_stex_get_symbol_args_tl} {\exp_args:No \exp_not:n \l_stex_key_def_tl} {\exp_args:No \exp_not:n \l_stex_key_type_tl} {\exp_args:No \exp_not:n \l_stex_key_return_tl} \stex_invoke_symbol: } } \cs_new_protected:Nn \_@@_html: { \stex_if_do_html:T { \hbox\bgroup\exp_args:Ne \stex_annotate_invisible:nn { shtml:vardef = {\l_stex_key_name_str}, shtml:args = {\l_stex_key_args_str} \str_if_empty:NF \l_stex_macroname_str {, shtml:macroname={\l_stex_macroname_str} } \str_if_empty:NF \l_stex_key_assoc_str {, shtml:assoctype={\l_stex_key_assoc_str} } \str_if_empty:NF \l_stex_key_role_str {, shtml:role={\l_stex_key_role_str} } \str_if_empty:NF \l_stex_key_reorder_str {, shtml:reorderargs={\l_stex_key_reorder_str} } \bool_if:NT \l_@@_bind_bool {, shtml:bind={} } }{ \_stex_annotate_force_break:n{ \bool_set_true:N \stex_in_invisible_html_bool \tl_if_empty:NF \l_stex_key_type_tl { \stex_annotate:nn{shtml:type={}}{$\l_stex_key_type_tl$} } \tl_if_empty:NF \l_stex_key_def_tl { \stex_annotate:nn{shtml:definiens={}}{$\l_stex_key_def_tl$} } \tl_if_empty:NF \l_stex_key_return_tl{ \exp_args:Nno \use:n{ \cs_generate_from_arg_count:NNnn \l_@@_cs \cs_set:Npn \l_stex_get_symbol_arity_int} \l_stex_key_return_tl \tl_set:Nx \l_@@_args_tl {\_stex_map_args:N \_stex_return_args:nn} $\stex_annotate:nn{shtml:returntype={}}{ \exp_after:wN \l_@@_cs \l_@@_args_tl!}$ } \tl_if_empty:NF \l_stex_key_argtypes_clist { \stex_annotate:nn{shtml:argtypes={}}{ \_stex_annotate_force_break:n{ \clist_map_inline:Nn \l_stex_key_argtypes_clist { $\stex_annotate:nn{shtml:type={}}{##1}$ } } } } } }\egroup } } % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_vardecl_notation_macro:} % \begin{macrocode} \cs_new_protected:Nn \_stex_vardecl_notation_macro: { \tl_set_eq:cN {l_stex_notation_ \l_stex_key_name_str _ \l_stex_key_variant_str _cs }\l_stex_notation_macrocode_cs \cs_if_exist:cF {l_stex_notation_\l_stex_key_name_str __cs}{ \tl_set_eq:cN{l_stex_notation_\l_stex_key_name_str __cs} \l_stex_notation_macrocode_cs } \tl_if_empty:NF \l_stex_key_op_tl { \tl_set_eq:cN {l_stex_notation_\l_stex_key_name_str _op_ \l_stex_key_variant_str _cs}\l_stex_key_op_tl \cs_if_exist:cF {l_stex_notation_\l_stex_key_name_str _op__cs}{ \cs_set_eq:cN{l_stex_notation_\l_stex_key_name_str _op__cs} \l_stex_key_op_tl } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_get_symbol_or_var:n,\stex_get_var:n} % \begin{macrocode} \cs_new_protected:Nn \_@@_set_vars:nnnnnnN { \stex_debug:nn{symbols}{Variable~#1~found} \cs_set:Npn \_stex_variable:nnnnnnnN ##1 ##2 ##3 ##4 ##5 ##6 ##7 ##8 {} \str_clear:N \l_stex_get_symbol_mod_str \str_set:Nn \l_stex_get_symbol_name_str {#1} \int_set:Nn \l_stex_get_symbol_arity_int {#2} \tl_set:Nn \l_stex_get_symbol_args_tl {#3} \tl_set:Nn \l_stex_get_symbol_def_tl {#4} \tl_set:Nn \l_stex_get_symbol_type_tl {#5} \tl_set:Nn \l_stex_get_symbol_return_tl {#6} \tl_set:Nn \l_stex_get_symbol_invoke_cs {#7} } \cs_new_protected:Nn \_@@_get_var:n { \prop_map_inline:Nn \l_stex_variables_prop { \_@@_check_var:nnnnnnnnN {#1} ##2 } } \cs_new_protected:Nn \_@@_check_var:nnnnnnnnN { \str_if_eq:nnTF{#1}{#2}{ \prop_map_break:n{\_@@_set_vars:nnnnnnN {#3}{#4}{#5}{#6}{#7}{#8}#9} }{ \str_if_eq:nnT{#1}{#3}{ \prop_map_break:n{\_@@_set_vars:nnnnnnN {#3}{#4}{#5}{#6}{#7}{#8}#9} } } } \cs_new_protected:Nn \stex_get_var:n { \str_clear:N \l_stex_get_symbol_name_str \_@@_get_var:n{#1} \str_if_empty:NT \l_stex_get_symbol_name_str { \msg_error:nnn{stex}{error/unknownsymbol}{#1} } } \cs_new_protected:Nn \stex_get_symbol_or_var:n { \str_clear:N \l_stex_get_symbol_name_str \_@@_get_var:n{#1} \str_if_empty:NT \l_stex_get_symbol_name_str { \stex_debug:nn{symbols}{No~variable~#1~found} \stex_get_symbol:n{#1} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\svar} % \begin{macrocode} \NewDocumentCommand \svar {O{} m}{ \group_begin: \tl_if_empty:nTF{#1}{ \str_set:Nn \l_stex_current_symbol_str {#2} }{ \str_set:Nn \l_stex_current_symbol_str {#1} } \bool_if:NTF \l_stex_allow_semantic_bool{ \tl_clear:N \l_stex_current_term_tl \_stex_term_omv:nnn{}{}{\_varcomp{#2}} }{ \msg_error:nnxx{stex}{error/notallowed}{Variable}{\l_stex_current_symbol_str} } \group_end: } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Sequences} % \begin{macrocode} %<@@=stex_seqs> % \end{macrocode} % % \begin{macro}{\varseq} % \begin{macrocode} \stex_new_stylable_cmd:nnnn {varseq}{m O{} m m} { \stex_keys_set:nn{symdef}{#2} \str_set:Nx \l_stex_macroname_str { #1 } \str_if_empty:NT \l_stex_key_name_str { \str_set:Nx \l_stex_key_name_str { #1 } } \str_if_empty:NT \l_stex_key_args_str { \str_set:Nn \l_stex_key_args_str {1} } \stex_symdecl_do: \tl_set_eq:NN \l_stex_get_symbol_return_tl \l_stex_key_return_tl \clist_set:Nn \l_@@_range_clist {#3} \tl_if_empty:NTF \l_stex_key_op_tl { \stex_notation_parse:n{#4} \tl_clear:N \l_stex_key_op_tl }{ \stex_notation_parse:n{#4} } \stex_if_do_html:T \_@@_html: \stex_if_check_terms:T \_@@_check_terms: \_@@_add: \_@@_macro: \stex_if_check_terms:T \_stex_notation_check: \_stex_vardecl_notation_macro: \group_begin: \tl_set_eq:NN \thisvarname \l_stex_key_name_str \tl_clear:N \thisstyle \str_set_eq:NN\thisnotationvariant\l_stex_key_variant_str \def\thisnotation{ $\let\l_stex_current_symbol_str\thisvarname \def\comp{\_varcomp}\exp_args:Nne \use:nn{\l_stex_notation_macrocode_cs{}}{ \_@@_make_args: }$ } \stex_style_apply: \group_end:\ignorespaces }{} \cs_new_protected:Nn \_@@_add: { \exp_args:NNNo \exp_args:NNnx \prop_put:Nnn \l_stex_variables_prop \l_stex_key_name_str { {\l_stex_macroname_str} {\l_stex_key_name_str} {\int_use:N \l_stex_get_symbol_arity_int} {\l_stex_get_symbol_args_tl} {\exp_args:No \exp_not:n \l_stex_key_def_tl} {\exp_args:No \exp_not:n \l_@@_range_clist} {\exp_args:No \exp_not:n \l_stex_key_return_tl} \stex_invoke_sequence: } } \cs_new_protected:Nn \_@@_macro: { \tl_set:cx{\l_stex_macroname_str}{ \_stex_invoke_variable:nnnnnnN {\l_stex_key_name_str} {\int_use:N \l_stex_get_symbol_arity_int} {\l_stex_get_symbol_args_tl} {\exp_args:No \exp_not:n \l_stex_key_def_tl} {\exp_args:No \exp_not:n \l_@@_range_clist} {\exp_args:No \exp_not:n \l_stex_key_return_tl} \stex_invoke_sequence: } } \cs_new_protected:Nn \_@@_make_args: { \TODO } \cs_new_protected:Nn \_@@_check_terms: { \TODO } \cs_new_protected:Nn \_@@_html: { \exp_args:Ne \stex_annotate_invisible:nn { shtml:varseq = {\l_stex_key_name_str}, shtml:args = {\l_stex_key_args_str} \str_if_empty:NF \l_stex_macroname_str {, shtml:macroname={\l_stex_macroname_str} } \str_if_empty:NF \l_stex_key_assoc_str {, shtml:assoctype={\l_stex_key_assoc_str} } \str_if_empty:NF \l_stex_key_role_str {, shtml:role={\l_stex_key_role_str} } \str_if_empty:NF \l_stex_key_reorder_str {, shtml:reorderargs={\l_stex_key_reorder_str} } }{\hbox\bgroup \_stex_annotate_force_break:n{ \tl_if_empty:NF \l_stex_key_type_tl { \stex_annotate:nn{shtml:type={}}{$\l_stex_key_type_tl$} } \tl_if_empty:NF \l_stex_key_def_tl { \stex_annotate:nn{shtml:definiens={}}{$\l_stex_key_def_tl$} } \tl_if_empty:NF \l_stex_key_return_tl{ \exp_args:Nno \use:n{ \cs_generate_from_arg_count:NNnn \l_@@_cs \cs_set:Npn \l_stex_get_symbol_arity_int} \l_stex_key_return_tl \tl_set:Nx \l_@@_args_tl {\_stex_map_args:N \_stex_return_args:nn} \stex_annotate:nn{shtml:returntype={}}{ $\exp_after:wN \l_@@_cs \l_@@_args_tl!$} } \tl_if_empty:NF \l_stex_key_argtypes_clist { \stex_annotate:nn{shtml:argtypes={}}{ \_stex_annotate_force_break:n{ \clist_map_inline:Nn \l_stex_key_argtypes_clist { \stex_annotate:nn{shtml:type={}}{$##1$} } } } } } \egroup} } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_invoke_sequence:} % \begin{macrocode} \cs_new_protected:Nn \stex_invoke_sequence: { \peek_charcode_remove:NTF ! { \peek_charcode:NTF [ \_@@_do_op:w { \_@@_do_op:w [] } }\_@@_do_first: } \cs_new_protected:Npn \_@@_do_op:w [#1] { \cs_if_exist:cTF {l_stex_notation_\l_stex_current_symbol_str _op_#1_cs}{ \_stex_maybe_brackets:nn{\neginfprec}{ \_stex_term_oms_or_omv:nnn{#1}{} {\use:c{l_stex_notation_\l_stex_current_symbol_str _op_#1_cs}} } \group_end: }{ \_@@_get_index_notation:n{#1} \peek_charcode:NTF [ \_@@_doop_range:w { \_@@_doop_range:w[] } } } \cs_new_protected:Npn \_@@_doop_range:w [#1] { \bool_set_true:N \l_stex_allow_semantic_bool \clist_clear:N \l_@@_clist \clist_map_function:NN \l_stex_current_type_tl \_@@_doop_arg:n \stex_annotate:nn{ shtml:term=OMV, shtml:head={\l_stex_current_symbol_str}, shtml:notationid={} }{ \l_@@_clist } \group_end: } \cs_new_protected:Nn \_@@_doop_arg:n { \tl_if_eq:nnTF{#1}{\ellipses}{ \clist_put_right:Nn \l_@@_clist { \ellipses } }{ \clist_put_right:Nn \l_@@_clist { \exp_args:No \str_if_eq:nnTF \l_stex_current_arity_str {1}{ \group_begin: \l_@@_cs \group_end: {#1} }{ \group_begin: \l_@@_cs \group_end: #1 } } } } \cs_new_protected:Nn \_@@_get_index_notation:n { \cs_if_exist:cTF {l_stex_notation_\l_stex_current_symbol_str _#1_cs}{ \cs_set_eq:Nc \l_@@_cs {l_stex_notation_\l_stex_current_symbol_str _#1_cs} }{ \stex_do_default_notation: \cs_set_eq:NN \l_@@_cs \l_stex_default_notation } } \cs_new:Nn \_@@_do_first_arg:n {{\exp_not:n{## #1}}} \cs_new_protected:Nn \_@@_do_first: { \exp_args:Nnx \use:nn{ \cs_generate_from_arg_count:NNnn \l_@@_cs \cs_set:Npn \l_stex_current_arity_str} {{ \tl_set:Nn \exp_not:N \l_@@_first_args_tl { \int_step_function:nN \l_stex_current_arity_str \_@@_do_first_arg:n } \exp_not:N \_@@_do_first_next: }} \l_@@_cs } \cs_new_protected:Nn \_@@_do_first_next: { \peek_charcode_remove:NTF ! { \peek_charcode:NTF [ \_@@_do_one:w {\_@@_do_one:w []} }{ \peek_charcode:NTF [ \_@@_do_all:w {\_@@_do_all:w []} } } \cs_new_protected:Npn \_@@_do_one:w [#1] { \_@@_get_index_notation:n{#1} \stex_debug:nn{HERE~seq~one}{\meaning\l_@@_cs^^J\meaning\l_@@_first_args_tl} \exp_args:Nno\use:nn{\l_@@_cs\group_end:}\l_@@_first_args_tl } \cs_new_protected:Npn \_@@_do_all:w [#1] { \stex_debug:nn{HERE~seq~all}{\meaning\l_@@_first_args_tl} \exp_args:Nno\use:nn{\_stex_invoke_notation:w [#1]}\l_@@_first_args_tl } % \end{macrocode} % \end{macro} % % \begin{macro}{\seqmap} % \begin{macrocode} \cs_new_protected:Npn \seqmap #1 #2 { \symuse{Metatheory?sequence~expression}{\seqmap{#1}{#2}}%\l_tmpa_tl {#2} } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Expressions} % \begin{macrocode} %<@@=stex_expr> % \end{macrocode} % % Various variables: % % \begin{macrocode} \bool_new:N \l_stex_allow_semantic_bool \bool_set_true:N \l_stex_allow_semantic_bool \tl_new:N \l_stex_current_term_tl \tl_set:Nn \l_stex_every_symbol_tl { \bool_set_false:N \l_stex_allow_semantic_bool } % \end{macrocode} % % \begin{macro}{\_stex_next_symbol:n} % \begin{macrocode} \tl_new:N \l_@@_reset_tl \cs_new_protected:Nn \_stex_next_symbol:n { \tl_set:Nx \l_stex_every_symbol_tl { \tl_gset:Nn \exp_not:N \l_@@_reset_tl { \tl_set:Nn \exp_not:N \l_stex_every_symbol_tl { \exp_args:No \exp_not:n \l_stex_every_symbol_tl } \tl_gset:Nn \exp_not:N \l_@@_reset_tl { \exp_args:No \exp_not:n \l_@@_reset_tl } } \tl_set:Nn \exp_not:N \l_stex_every_symbol_tl { \exp_args:No \exp_not:n \l_stex_every_symbol_tl } \exp_not:n{ \aftergroup \l_@@_reset_tl } \exp_not:N \l_stex_every_symbol_tl \exp_not:n{ #1 } } } \cs_generate_variant:Nn \_stex_next_symbol:n {e} % \end{macrocode} % \end{macro} % % \begin{macro}{\STEXinvisible} % \begin{macrocode} \cs_new_protected:Npn \STEXinvisible #1 { \stex_annotate_invisible:n { #1 } } % \end{macrocode} % \end{macro} % % \begin{sfragment}{Invoking Semantic Macros} % % \begin{macro}{\_stex_invoke_symbol:nnnnnnnN} % \begin{macrocode} \cs_new_protected:Nn \_stex_invoke_symbol:nnnnnnnN { \bool_if:NTF \l_stex_allow_semantic_bool{ \stex_if_html_backend:T{\ifvmode\indent\fi} \_@@_setup:nnnnnn{\_comp}{#1?#2}{#3}{#4}{#7}{#6} \cs_set_eq:NN \_stex_term_oms_or_omv:nnn \_stex_term_oms:nnn \tl_put_right:Nn \l_stex_current_redo_tl{ \cs_set_eq:NN \_stex_term_oms_or_omv:nnn \_stex_term_oms:nnn } #8 }{ \msg_error:nnxx{stex}{error/notallowed}{#1?#2}{\l_stex_current_symbol_str} } } \cs_generate_variant:Nn \_stex_invoke_symbol:nnnnnnnN {ooxooooN} \cs_new_protected:Nn \_@@_setup:nnnnnn { \group_begin: \tl_clear:N \l_stex_return_notation_tl \tl_set:Nn \l_stex_current_redo_tl { \let \this \stex_current_this: \def\comp{#1} \def\maincomp{\comp} \str_set:Nn \l_stex_current_symbol_str {#2} \str_set:Nn \l_stex_current_arity_str{ #3 } \tl_set:Nn \l_stex_current_args_tl{ #4 } \tl_set:Nn \l_stex_current_return_tl{ #5 } \tl_set:Nn \l_stex_current_type_tl{ #6 } \tl_clear:N \l_stex_current_term_tl } \tl_put_right:Nx \l_stex_current_redo_tl { \exp_args:No \exp_not:n \l_stex_every_symbol_tl } \l_stex_current_redo_tl } % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_invoke_variable:nnnnnn} % \begin{macrocode} \cs_new_protected:Nn \_stex_invoke_variable:nnnnnnN { \bool_if:NTF \l_stex_allow_semantic_bool{ \stex_if_html_backend:T{\ifvmode\indent\fi} \_@@_setup:nnnnnn{\_varcomp}{#1}{#2}{#3}{#6}{#5} \cs_set_eq:NN \_stex_term_oms_or_omv:nnn \_stex_term_omv:nnn \tl_put_right:Nn \l_stex_current_redo_tl { \cs_set_eq:NN \_stex_term_oms_or_omv:nnn \_stex_term_omv:nnn } #7 }{ \msg_error:nnxx{stex}{error/notallowed}{#1}{\l_stex_current_symbol_str} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\symuse} % \begin{macrocode} \cs_new_protected:Npn \symuse #1 { \stex_get_symbol:n{#1} \exp_args:Nno \use:n {\_stex_invoke_symbol:ooxooooN \l_stex_get_symbol_mod_str \l_stex_get_symbol_name_str {\int_use:N \l_stex_get_symbol_arity_int} \l_stex_get_symbol_args_tl \l_stex_get_symbol_def_tl \l_stex_get_symbol_type_tl \l_stex_get_symbol_return_tl} \l_stex_get_symbol_invoke_cs } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_invoke_symbol:} % % Top-Level: Check whether text/math mode or custom notation, % whether delimited by !, return code etc. % \begin{macrocode} \cs_new_protected:Nn \stex_invoke_symbol: { \stex_debug:nn{expressions}{Invoking~\l_stex_current_symbol_str} \mode_if_math:TF \@@_invoke_math: \@@_invoke_text: } \cs_new_protected:Nn \@@_invoke_text: { \stex_debug:nn{expressions}{text~mode} \peek_charcode_remove:NTF ! \@@_invoke_op_custom:n \@@_invoke_custom:n } \cs_new_protected:Nn \@@_invoke_math: { \stex_debug:nn{expressions}{math~mode} \peek_charcode_remove:NTF ! { % operator \peek_charcode_remove:NTF * \@@_invoke_op_custom:n { % op notation \peek_charcode:NTF [ \@@_invoke_op_notation:w { \@@_invoke_op_notation:w [] } } }{ \peek_charcode_remove:NTF * \@@_invoke_custom:n { % normal \peek_charcode:NTF [ \_stex_invoke_notation:w { \_stex_invoke_notation:w [] } } } } % \end{macrocode} % % Notations: % % \begin{macrocode} \cs_new_protected:Npn \_stex_invoke_notation:w [#1] { \stex_debug:nn{expressions}{using~notation~#1~for~\l_stex_current_symbol_str} \cs_if_exist:cTF{l_stex_notation_\l_stex_current_symbol_str _#1_cs}{ \tl_if_empty:NTF \l_stex_current_return_tl { \stex_debug:nn{expressions}{return~empty} \use:c{l_stex_notation_\l_stex_current_symbol_str _#1_cs}{\group_end:\_stex_eat_exclamation_point:} }{ \stex_debug:nn{expressions}{return?} \exp_after:wN\exp_after:wN\exp_after:wN \@@_invoke_return_maybe:n \exp_after:wN\exp_after:wN\exp_after:wN {\cs:w l_stex_notation_\l_stex_current_symbol_str _#1_cs \cs_end: {}} } }{ \stex_do_default_notation: \tl_if_empty:NTF \l_stex_current_return_tl { \l_stex_default_notation{\group_end:\_stex_eat_exclamation_point:} }{ \exp_after:wN \@@_invoke_return_maybe:n \exp_after:wN {\l_stex_default_notation {}} } } } \cs_new_protected:Npn \@@_invoke_op_notation:w [#1] { \stex_debug:nn{expressions}{op~notation~for~\l_stex_current_symbol_str} \cs_if_exist:cTF{l_stex_notation_\l_stex_current_symbol_str _op_#1_cs}{ \_stex_maybe_brackets:nn{\neginfprec}{ \_stex_term_oms_or_omv:nnn{#1}{} {\use:c{l_stex_notation_\l_stex_current_symbol_str _op_#1_cs}} } \group_end: }{ \int_compare:nNnTF \l_stex_current_arity_str = 0 { \tl_clear:N \l_stex_current_return_tl \_stex_invoke_notation:w [#1] }{ \stex_do_default_notation_op: \_stex_maybe_brackets:nn{\neginfprec}{ \_stex_term_oms_or_omv:nnn{#1}{} {\l_stex_default_notation} } \group_end: } } } % \end{macrocode} % % Return: % % \begin{macrocode} \cs_new_protected:Nn \@@_invoke_return_maybe:n { \tl_clear:N \l_@@_return_args_tl \tl_set:Nn \l_@@_return_this_tl {#1} \exp_args:Nnx \use:n { \cs_generate_from_arg_count:NNnn \_@@_ret_cs \cs_set:Npn \l_stex_current_arity_str } { \int_step_function:nN \l_stex_current_arity_str \_@@_return_arg:n \_@@_invoke_return_next: } \_@@_ret_cs } \cs_new:Nn \_@@_return_arg:n { \tl_put_right:Nn \exp_not:N \l_@@_return_args_tl {{#### #1}} } \cs_new_protected:Nn \_@@_invoke_return_next: { \peek_charcode_remove:NTF ! { \exp_after:wN \l_@@_return_this_tl \l_@@_return_args_tl \group_end: }\_@@_invoke_return: } \cs_new_protected:Nn \_@@_invoke_return: { \tl_set:Nx \l_@@_return_this_tl { \_@@_return_notation:n { \exp_after:wN \exp_after:wN \exp_after:wN \exp_not:n \exp_after:wN \exp_after:wN \exp_after:wN { \exp_after:wN \l_@@_return_this_tl \l_@@_return_args_tl } } } \stex_debug:nn{return}{Notation:~\meaning\l_@@_return_this_tl} \tl_put_left:Nx \l_@@_return_this_tl { \group_begin:\exp_args:No \exp_not:n \l_stex_current_redo_tl } \exp_args:Nnx \use:n { \cs_generate_from_arg_count:NNnn \_@@_ret_cs \cs_set:Npn \l_stex_current_arity_str } { \exp_args:No \exp_not:n \l_stex_current_return_tl } \stex_debug:nn{return}{ \meaning\_@@_ret_cs^^J \meaning\l_@@_return_this_tl^^J \exp_args:No \exp_not:n \l_@@_return_args_tl^^J } \exp_args:Nnx \use:nn { \exp_after:wN \group_end: \_@@_ret_cs }{ \exp_args:No \exp_not:n \l_@@_return_args_tl { \exp_args:No \exp_not:n \l_@@_return_this_tl \group_end: } } } \cs_new_protected:Nn \_@@_return_notation:n { \tl_if_empty:NTF \l_stex_return_notation_tl { #1 }{ \l_stex_return_notation_tl } } % \end{macrocode} % % Custom Notations: % % \begin{macrocode} \cs_new_protected:Nn \@@_invoke_op_custom:n { \stex_debug:nn{expressions}{custom~op} \bool_set_true:N \l_stex_allow_semantic_bool \_stex_term_oms_or_omv:nnn{}{}{\maincomp{#1}} \group_end: } \int_new:N \l_@@_arg_counter_int \cs_new_protected:Nn \@@_invoke_custom:n { \stex_debug:nn{custom}{custom~notation~for~\l_stex_current_symbol_str} \stex_pseudogroup:nn{ \bool_set_true:N \l_stex_allow_semantic_bool \prop_gclear:N \l_@@_customs_prop \seq_gclear:N \l_@@_customs_seq \int_gzero:N \l_@@_arg_counter_int \tl_if_empty:NF \l_stex_current_args_tl { \exp_after:wN \_@@_add_prop_arg:nnw \l_stex_current_args_tl \_stex_args_end: \cs_set_eq:NN \arg \_@@_arg:n } \tl_set_eq:NN \l_stex_get_symbol_args_tl \l_stex_current_args_tl \cs_set_eq:NN \_@@_do_ab_next:nnn \_stex_term_oma:nnn \_stex_map_args:N \_@@_check_b:nn \_@@_do_ab_next:nnn{}{}{#1} }{ \prop_if_exist:NT \l_@@_customs_prop { \prop_gset_from_keyval:Nn \exp_not:N \l_@@_customs_prop { \prop_to_keyval:N \l_@@_customs_prop } } \int_gset:Nn \l_@@_arg_counter_int { \int_use:N \l_@@_arg_counter_int} \seq_if_exist:NT \l_@@_customs_seq { \seq_gset_split:Nnn \exp_not:N \l_@@_customs_seq , { \seq_use:Nn \l_@@_customs_seq , } } } % TODO check that all arguments are present \group_end: } \cs_new_protected:Npn \_@@_add_prop_arg:nnw #1 #2 #3\_stex_args_end: { \prop_gput:Nnn \l_@@_customs_prop {#1} {} \seq_gput_right:Nn \l_@@_customs_seq {#2} \tl_if_empty:nF{#3}{\_@@_add_prop_arg:nnw #3 \_stex_args_end:} } \cs_new:Nn \_@@_check_b:nn { \str_case:nn #2 { b {\cs_set_eq:NN \_@@_do_ab_next:nnn \_stex_term_omb:nnn} B {\cs_set_eq:NN \_@@_do_ab_next:nnn \_stex_term_omb:nnn} } } \NewDocumentCommand \_@@_arg:n {s O{} m} { \IfBooleanTF #1 { \stex_annotate_invisible:n{ \_@@_arg_inner:nn{#2}{#3} } }{ \_@@_arg_inner:nn{#2}{#3} } } \cs_new_protected:Nn \_@@_arg_inner:nn { \tl_if_empty:nTF{#1}{ \int_gincr:N \l_@@_arg_counter_int \exp_args:Ne \_@@_check:nTF{ \int_use:N \l_@@_arg_counter_int }{ \_@@_arg_do:oon \l_tmpa_tl \l_tmpb_tl }{ \_@@_arg_inner:nn{} }{ #2 } }{ \_@@_check:nTF {#1}{ \_@@_arg_do:oon \l_tmpa_tl \l_tmpb_tl { #2 } }{ \exp_args:No \str_case:nnTF \l_tmpb_tl { {a}{ \exp_args:NNnx \prop_gput:Nnn \l_@@_customs_prop {#1}{ \l_tmpa_tl X } \tl_set:Nx \l_tmpa_tl { #1 \int_eval:n {\tl_count:N \l_tmpa_tl + 1} } } {B}{ \exp_args:NNnx \prop_gput:Nnn \l_@@_customs_prop {#1}{ \l_tmpa_tl X } \tl_set:Nx \l_tmpa_tl { #1 \int_eval:n {\tl_count:N \l_tmpa_tl + 1} } } }{ \_@@_arg_do:oon \l_tmpa_tl \l_tmpb_tl { #2 } }{ \msg_error:nnxx{stex}{error/invalidarg}{#1}{\l_stex_current_symbol_str} } } } } \prg_new_conditional:Nnn \_@@_check:n {TF} { \exp_args:NNe \prop_get:NnNTF \l_@@_customs_prop {#1} \l_tmpa_tl { \tl_set:Nx \l_tmpb_tl {\seq_item:Nn \l_@@_customs_seq {#1} } \tl_if_empty:NTF \l_tmpa_tl { \exp_args:NNe \prop_gput:Nnn \l_@@_customs_prop { #1 }{X} \exp_args:No \str_case:nnF \l_tmpb_tl { {a}{ \tl_set:Nx \l_tmpa_tl{ #1 1 } } {B}{ \tl_set:Nx \l_tmpa_tl{ #1 1 } } }{ \tl_set:Nx \l_tmpa_tl{ #1 } } \prg_return_true: }{ \prg_return_false: } }{ \msg_error:nnxx{stex}{error/invalidarg}{#1}{\l_stex_current_symbol_str} \prg_return_false: } } % #1 argnum #2 argmode #3 code \cs_new_protected:Nn \_@@_arg_do:nnn { \stex_debug:nn{custom}{Doing~argument~#1~of~mode~#2:~\tl_to_str:n{#3}} \group_begin: \bool_set_true:N \l_stex_allow_semantic_bool \_stex_term_arg:nnn {#2}{#1}{#3} \group_end: } \cs_generate_variant:Nn \_@@_arg_do:nnn {oon} % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Argument Handling and Annotating} % % \begin{macro}{\_stex_term_arg:nnnnn,\_stex_term_arg:nnn} % \begin{macrocode} % 1: argnum 2: argmode 3: precedence 4: argname 5: code \cs_new_protected:Nn \_stex_term_arg:nnnnn { \group_begin: \str_clear:N \l_stex_current_symbol_str \tl_clear:N \l_stex_current_term_tl \int_set:Nn \l_stex_notation_downprec { #3 } \bool_set_true:N \l_stex_allow_semantic_bool \_stex_term_arg:nnn {#2}{#1}{ \tl_if_empty:nTF{#4}{ #5 }{ \stex_annotate:nn{mml:arg={#4}}{#5} } } \group_end: } \cs_new_protected:Nn \_stex_term_arg:nnn { \stex_annotate:nn{ shtml:arg={#2}, shtml:argmode={#1}}{ \_stex_annotate_force_break:n{ #3 } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_term_arg_aB:nnnnn} % \begin{macrocode} \tl_set:Nn \_@@_do_aB_clist: { \seq_use:Nn \l_stex_aB_args_seq { \mathpunct{\comp{,}} } } \tl_set_eq:NN \_stex_term_do_aB_clist: \_@@_do_aB_clist: \int_new:N \l_@@_count_int \cs_new_protected:Nn \_stex_term_arg_aB:nnnnn { \tl_if_empty:nTF{#5}{ \_stex_term_arg:nnnnn{#1}{#2}{#3}{#4}{} }{ \seq_clear:N \l_stex_aB_args_seq \int_zero:N \l_@@_count_int \clist_map_inline:nn{#5}{ \_@@_aB_arg:nnnnn{##1}{#1}{#2}{#3}{#4} } \_stex_term_do_aB_clist: } } % 1: code 2: argnum 3: argmode 4: precedence 5: argname \cs_new_protected:Npn \_@@_aB_arg:nnnnn #1 { \int_incr:N \l_@@_count_int \_@@_is_varseq:nTF{#1}{ \exp_after:wN \exp_after:wN \exp_after:wN \_@@_assoc_seq:nnnnnnn \exp_after:wN \_@@_gobble:nnnnnnnn #1 \_@@_end: }{ \_@@_is_seqmap:nTF{#1}{ \exp_args:NNe \use:nn \_@@_do_seqmap:nnnnnn {\tl_tail:n{#1}} }{ \_@@_aB_simple_arg:nnnnn{#1} } } } \cs_new:Npn \_@@_gobble:nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8 #9 \_@@_end: { {#2} #3 {#6} } \cs_new_protected:Nn \_@@_aB_simple_arg:nnnnn{ \seq_put_right:Nx \l_stex_aB_args_seq { \_stex_term_arg:nnnnn{#2\int_use:N\l_@@_count_int}{#3}{#4}{#5}{ \exp_not:n{ \tl_set_eq:NN \_stex_term_do_aB_clist: \_@@_do_aB_clist: #1 } } } } \cs_new_protected:Nn \_stex_is_sequentialized:n { \group_begin: #1 \group_end: } % \end{macrocode} % % Conditionals: Is the argument a sequence variable or a |\seqmap|? % % \begin{macrocode} \prg_new_conditional:Nnn \_@@_is_varseq:n {TF} { \int_compare:nNnTF {\tl_count:n{#1}} = 1 { \exp_args:Ne \cs_if_eq:NNTF {\exp_args:No \tl_head:n{#1}} \_stex_invoke_variable:nnnnnnN { \exp_args:Ne \cs_if_eq:NNTF {\exp_args:No\tl_item:nn{#1}{8}} \stex_invoke_sequence: \prg_return_true:\prg_return_false: }\prg_return_false: }\prg_return_false: } \prg_new_conditional:Nnn \_@@_is_seqmap:n {TF} { \int_compare:nNnTF {\tl_count:n{#1}} = 3 { \exp_args:Ne \tl_if_eq:nnTF {\tl_head:n{#1}} {\seqmap} \prg_return_true:\prg_return_false: }\prg_return_false: } % \end{macrocode} % % Sequence variable: % % \begin{macrocode} % 1: name 2: arity 3: clist 4: argnum 5: argmode 6: precedence 7: argname \cs_new_protected:Nn \_@@_assoc_seq:nnnnnnn { \group_begin: \seq_clear:N \l_stex_aB_args_seq \_@@_assoc_make_seq:nnn{#1}{#3}{#2} \exp_args:NNe \use:nn \group_end: { \seq_put_right:Nn \exp_not:N \l_stex_aB_args_seq { \_stex_is_sequentialized:n{ \_stex_term_arg:nnnnn{#4\int_use:N\l_@@_count_int}{#5}{#6}{#7}{ \bool_set_true:N \l_stex_allow_semantic_bool \str_set:Nn \exp_not:N \l_stex_current_symbol_str {\l_stex_current_symbol_str} \tl_if_empty:NF \l_stex_current_term_tl { \tl_set:Nn \exp_not:N \l_stex_current_term_tl { \exp_args:No \exp_not:n \l_stex_current_term_tl } } \stex_annotate:nn{ shtml:term=OMV, shtml:head={#1}, shtml:notationid={} }{ \_stex_annotate_force_break:n{ \_stex_term_do_aB_clist: } } } } } } } % #1: name, #2: clist, #3:arity \cs_new_protected:Nn \_@@_assoc_make_seq:nnn { \cs_if_exist:cTF{l_stex_notation_#1__cs}{ \cs_set_eq:Nc \l_@@_cs {l_stex_notation_#1__cs} }{ \stex_do_default_notation: \cs_set_eq:NN \l_@@_cs \l_stex_default_notation } \clist_map_inline:nn{#2}{ \tl_if_eq:nnTF{##1}{\ellipses}{ \seq_put_right:Nn \l_stex_aB_args_seq { ##1 } }{ \int_compare:nNnTF {#3} = 1 { \tl_set:Nn \l_@@_iarg_tl { {##1} } }{ \tl_set:Nn \l_@@_iarg_tl { ##1 } } \seq_put_right:Nx \l_stex_aB_args_seq { \group_begin: \exp_not:n { \tl_set_eq:NN \_stex_term_do_aB_clist: \_@@_do_aB_clist: \def\comp{\_varcomp} \str_set:Nn \l_stex_current_symbol_str{#1} } \exp_after:wN \exp_after:wN \exp_after:wN \exp_not:n \exp_after:wN \exp_after:wN \exp_after:wN { \exp_after:wN \l_@@_cs \exp_after:wN \group_end: \l_@@_iarg_tl } } } } } % \end{macrocode} % % |\seqmap|: % % \begin{macrocode} % 1: fun 2: clist 3: argnum 4: argmode 5: precedence 6: argname \cs_new_protected:Nn \_@@_do_seqmap:nnnnnn { \group_begin: \cs_set:Npn \l_tmpa_cs ##1 {#1} \seq_clear:N \l_stex_aB_args_seq \clist_map_inline:nn{#2}{ \_@@_is_varseq:nTF{##1}{ \exp_after:wN \_@@_varseq_in_map:nnnnnnnn ##1 }{ \seq_put_right:Nn \l_stex_aB_args_seq {##1} } } \seq_clear:N \l_@@_old_seq \seq_map_inline:Nn \l_stex_aB_args_seq { \tl_if_eq:nnTF{##1}{\ellipses}{ \seq_put_right:Nn \l_@@_old_seq {##1} } % TODO \_stex_is_sequentialized:n { \exp_args:NNo \seq_put_right:Nn \l_@@_old_seq { \l_tmpa_cs {##1} } } } \seq_set_eq:NN \l_stex_aB_args_seq \l_@@_old_seq \exp_args:NNe \use:nn \group_end: { \seq_put_right:Nn \exp_not:N \l_stex_aB_args_seq { \_stex_is_sequentialized:n{ \_stex_term_arg:nnnnn{#4\int_use:N\l_@@_count_int}{#4}{#5}{#6}{ \bool_set_true:N \l_stex_allow_semantic_bool \str_set:Nn \exp_not:N \l_stex_current_symbol_str {\l_stex_current_symbol_str} \tl_set:Nn \exp_not:N \l_stex_current_term_tl { \symuse{Metatheory?sequence~map} {\exp_args:No \exp_not:n \l_tmpa_tl} {\_stex_term_do_aB_clist:} } \_@@_do_headterm:nn{}{ \_stex_term_do_aB_clist: } } } } } } \cs_new_protected:Nn \_@@_varseq_in_map:nnnnnnnn { \_@@_assoc_make_seq:nnn{#2}{#6}{#3} } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Term HTML Annotations} % % \begin{macro}{\_stex_term_oms_or_omv:nnn,\_stex_term_oms:nnn,\_stex_term_omv:nnn} % \begin{macrocode} \cs_new_protected:Nn \_stex_eat_exclamation_point: { \peek_charcode_remove:NT ! { \_stex_eat_exclamation_point: } } \bool_new:N \stex_in_invisible_html_bool \bool_set_false:N \stex_in_invisible_html_bool \stex_if_html_backend:TF { % 1: variant 2: intent 3: code \cs_new_protected:Nn \_stex_term_oms:nnn { \tl_if_empty:NTF \l_stex_current_term_tl { \stex_annotate:nn{ shtml:term=OMID, shtml:head={\l_stex_current_symbol_str}, shtml:notationid={#1}, }{ \_stex_annotate_force_break:n{#3} } }{ \_@@_do_headterm:nn{#1}{#3} } } \cs_new_protected:Nn \_stex_term_omv:nnn { \tl_if_empty:NTF \l_stex_current_term_tl { \stex_annotate:nn{ shtml:term=OMV, shtml:head={\l_stex_current_symbol_str}, shtml:notationid={#1} }{ \_stex_annotate_force_break:n{#3} } }{ \_@@_do_headterm:nn{#1}{#3} } } \cs_new_protected:Nn \_@@_do_headterm:nn { \bool_if:NTF \stex_in_invisible_html_bool { {\bool_set_true:N \l_stex_allow_semantic_bool \ensuremath{\l_stex_current_term_tl} } }{ \stex_annotate:nn{ shtml:term=complex, shtml:head={\l_stex_current_symbol_str}, shtml:notationid={#1} }{ \_stex_annotate_force_break:n{ \stex_annotate_invisible:nn{shtml:headterm={}}{ {\bool_set_true:N \l_stex_allow_semantic_bool \ensuremath{\l_stex_current_term_tl} } } } #2 } } } }{ \cs_new_protected:Nn \_stex_term_oms:nnn {#3} \cs_new_protected:Nn \_stex_term_omv:nnn {#3} \cs_new_protected:Nn \_@@_do_headterm:nn { #2 } } \cs_set_eq:NN \_stex_term_oms_or_omv:nnn \_stex_term_oms:nnn % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_term_oma:nnn} % \begin{macrocode} \stex_if_html_backend:TF { \cs_new_protected:Nn \_stex_term_oma:nnn { \tl_if_empty:NTF \l_stex_current_term_tl { \stex_annotate:nn{ shtml:term=OMA, shtml:head={\l_stex_current_symbol_str}, shtml:notationid={#1} }{ \_stex_annotate_force_break:n{#3} } }{ \stex_annotate:nn{ shtml:term=OMA, shtml:head={\l_stex_current_symbol_str}, shtml:notationid={#1} }{ \_stex_annotate_force_break:n{ \stex_annotate_invisible:nn{shtml:headterm={}}{{ \bool_set_true:N \l_stex_allow_semantic_bool \l_stex_current_term_tl }} #3 } } } } }{ \cs_new_protected:Nn \_stex_term_oma:nnn {#3} } % \end{macrocode} % \end{macro} % % \begin{macro}{\_stex_term_omb:nnn} % \begin{macrocode} \stex_if_html_backend:TF { \cs_new_protected:Nn \_stex_term_omb:nnn { \tl_if_empty:NTF \l_stex_current_term_tl { \stex_annotate:nn{ shtml:term=OMBIND, shtml:head={\l_stex_current_symbol_str}, shtml:notationid={#1} }{ \_stex_annotate_force_break:n{#3} } }{ \stex_annotate:nn{ shtml:term=OMBIND, shtml:head={\l_stex_current_symbol_str}, shtml:notationid={#1} }{ \_stex_annotate_force_break:n{ \stex_annotate_invisible:nn{shtml:headterm={}}{{ \bool_set_true:N \l_stex_allow_semantic_bool \l_stex_current_term_tl }} #3 } } } } }{ \cs_new_protected:Nn \_stex_term_omb:nnn { #3 } } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Automated Bracketing} % % \begin{macro}{\infprec,\neginfprec} % \begin{macrocode} \tl_const:Nx \infprec {\int_use:N \c_max_int} \tl_const:Nx \neginfprec {-\int_use:N \c_max_int} % \end{macrocode} % \end{macro} % % \begin{macro}{\dobrackets} % \begin{macrocode} \int_new:N \l_stex_notation_downprec \int_set:Nn \l_stex_notation_downprec \infprec \tl_set:Nn \l_@@_left_bracket_str ( \tl_set:Nn \l_@@_right_bracket_str ) \bool_new:N \l_stex_brackets_dones_bool \cs_new_protected:Nn \_stex_maybe_brackets:nn { \bool_if:NTF \l_stex_brackets_dones_bool { \bool_set_false:N \l_stex_brackets_dones_bool #2 } { \stex_debug:nn{brackets}{#1>\int_eval:n \l_stex_notation_downprec?} \int_compare:nNnTF { #1 } > \l_stex_notation_downprec { %\bool_if:NTF \l_stex_inparray_bool { #2 }{ \dobrackets { #2 } %} }{ #2 } } } %\RequirePackage{scalerel} \cs_new_protected:Npn \dobrackets #1 { %\ThisStyle{\if D\m@switch % \exp_args:Nnx \use:nn % { \exp_after:wN \left\l_@@_left_bracket_str #1 } % { \exp_not:N\right\l_@@_right_bracket_str } % \else \group_begin: %\stex_pseudogroup_with:nn{\l_stex_brackets_dones_bool\l_stex_notation_downprec}{ \bool_set_true:N \l_stex_brackets_dones_bool %\int_set:Nn \l_stex_notation_downprec \infprec \mathopen{\cs_if_exist:NT\l_stex_current_symbol_str\comp \l_@@_left_bracket_str } #1 \group_end:%} \mathclose{\cs_if_exist:NT\l_stex_current_symbol_str\comp \l_@@_right_bracket_str } %\fi} } % \end{macrocode} % \end{macro} % % \begin{macro}{\withbrackets} % \begin{macrocode} \cs_new_protected:Npn \withbrackets #1 #2 #3 { \stex_pseudogroup_with:nn{\l_@@_left_bracket_str\l_@@_right_bracket_str}{ \tl_set:Nn \l_@@_left_bracket_str { #1 } \tl_set:Nn \l_@@_right_bracket_str { #2 } #3 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\dowithbrackets} % \begin{macrocode} \cs_new_protected:Npn \dowithbrackets #1 #2 #3 { \withbrackets{#1}{#2}{\dobrackets{#3}} } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Symname and Variants} % % \begin{macro}{\symname,\sn,\sns,\Symname,\Sn,\Sns,\symref,\sr,\varref,\varname,\Varname} % \begin{macrocode} \def\maincomp{\comp} \stex_keys_define:nnnn{symname}{ \tl_clear:N \l_stex_key_pre_tl \tl_clear:N \l_stex_key_post_tl %\tl_clear:N \l_stex_key_proot_tl }{ pre .tl_set:N = \l_stex_key_pre_tl , post .tl_set:N = \l_stex_key_post_tl , root .code:n = {}%.tl_set:N = \l_stex_key_root_tl }{} \NewDocumentCommand \symref { O{} m m} { \group_begin: \stex_keys_set:nn{symname}{#1} \stex_get_symbol:n{#2} \_@@_do_ref:nNn{#3}\symrefemph@uri\_stex_term_oms:nnn } \let\sr\symref \NewDocumentCommand \symname { O{} m} { \group_begin: \stex_keys_set:nn{symname}{#1} \stex_get_symbol:n{#2} \_@@_do_ref:nNn{ \l_stex_key_pre_tl\l_stex_get_symbol_name_str\l_stex_key_post_tl }\symrefemph@uri\_stex_term_oms:nnn } \let\sn\symname \protected\def\sns{\symname[post=s]} \NewDocumentCommand \Symname { O{} m} { \group_begin: \stex_keys_set:nn{symname}{#1} \stex_get_symbol:n{#2} \_@@_do_ref:nNn{ \l_stex_key_pre_tl\exp_after:wN\_stex_capitalize:n\l_stex_get_symbol_name_str\l_stex_key_post_tl }\symrefemph@uri\_stex_term_oms:nnn } \cs_new_protected:Nn \_stex_capitalize:n { \uppercase{#1} } \let\Sn\Symname \protected\def\Sns{\Symname[post=s]} \cs_new:Npn \_stex_split_slash: #1/#2/#3\_stex_args_end: { \tl_if_empty:nTF{#3}{ #2 }{ \_stex_split_slash: #2 / #3 \_stex_args_end: } } \NewDocumentCommand \varref { O{} m m} { \group_begin: \stex_keys_set:nn{symname}{#1} \stex_get_var:n{#2} \_@@_do_ref:nNn{#3}\varemph@uri{ \str_set_eq:NN \l_stex_current_symbol_str\l_stex_get_symbol_name_str \def\comp{\_varcomp} \_stex_term_omv:nnn } } \NewDocumentCommand \varname { O{} m} { \group_begin: \stex_keys_set:nn{symname}{#1} \stex_get_var:n{#2} \_@@_do_ref:nNn{ \l_stex_key_pre_tl\l_stex_get_symbol_name_str\l_stex_key_post_tl }\varemph@uri{ \str_set_eq:NN \l_stex_current_symbol_str\l_stex_get_symbol_name_str \def\comp{\_varcomp} \_stex_term_omv:nnn } } \NewDocumentCommand \Varname { O{} m} { \group_begin: \stex_keys_set:nn{symname}{#1} \stex_get_var:n{#2} \_@@_do_ref:nNn{ \l_stex_key_pre_tl\exp_after:wN\_stex_capitalize:n\l_stex_get_symbol_name_str\l_stex_key_post_tl }\varemph@uri{ \str_set_eq:NN \l_stex_current_symbol_str\l_stex_get_symbol_name_str \def\comp{\_varcomp} \_stex_term_omv:nnn } } \cs_new_protected:Nn \_@@_do_ref:nNn { \stex_if_html_backend:T{\ifvmode\indent\fi} \bool_if:NTF \l_stex_allow_semantic_bool{ \str_set:Nx\l_stex_current_symbol_str {\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} \str_if_in:NnT \l_stex_get_symbol_name_str / { \str_set:Nx \l_stex_get_symbol_name_str { \exp_after:wN \_stex_split_slash: \l_stex_get_symbol_name_str /\_stex_args_end: } } \tl_clear:N \l_stex_current_term_tl \def\comp{\_comp} \let\compemph@uri#2 #3{}{}{\comp{#1}} }{ \msg_error:nnxx{stex}{error/notallowed}{#1}{\l_stex_current_symbol_str} } \group_end: } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Highlighting} % \begin{macrocode} %<@@=stex_notationcomps> % \end{macrocode} % % \begin{macro}{\comp,\compemph@uri,\compemph,\defemph,\defemph@uri,\symrefemph,\symrefemph@uri,\varemph,\varemph@uri} % \begin{macrocode} \cs_new_protected:Nn \_do_comp:nNn { \stex_pseudogroup_with:nn{\comp}{ \def\comp##1{##1} \str_if_empty:NTF \l_stex_current_symbol_str { #3 }{ \stex_if_html_backend:TF { \stex_annotate:nn { shtml:#1 = \l_stex_current_symbol_str}{ #3 } }{ \exp_args:Nno #2 { #3 } \l_stex_current_symbol_str } } } } \cs_new_protected:Npn \_comp { \_do_comp:nNn {comp}\compemph@uri } \cs_new_protected:Npn \_varcomp { \_do_comp:nNn {varcomp}\varemph@uri } \cs_new_protected:Npn \_defcomp { \_do_comp:nNn {definiendum}\defemph@uri } \cs_set_protected:Npn \comp {} \cs_new_protected:Npn \compemph@uri #1 #2 { \compemph{ #1 } } \cs_new_protected:Npn \compemph #1 { #1 } \cs_new_protected:Npn \defemph@uri #1 #2 { \defemph{#1} } \cs_new_protected:Npn \defemph #1 { \ifmmode\else\expandafter\textbf\fi{#1} } \cs_new_protected:Npn \symrefemph@uri #1 #2 { \symrefemph{#1} } \cs_new_protected:Npn \symrefemph #1 { \emph{#1} } \cs_new_protected:Npn \varemph@uri #1 #2 { \varemph{#1} } \cs_new_protected:Npn \varemph #1 { #1 } % \end{macrocode} % \end{macro} % % \end{sfragment} % % \end{sfragment} % % \end{sfragment} % % \begin{sfragment}{Mathematical Structures} % \begin{macrocode} %<@@=stex_structures> % \end{macrocode} % % \begin{macro}{\this} % \begin{macrocode} \cs_new_protected:Npn \stex_current_this: { { \bool_set_true:N \l_stex_allow_semantic_bool \tl_if_empty:NTF \l_stex_current_this_tl {{}}{ \str_set:Nx \l_stex_current_symbol_str { \l_stex_current_module_str ? \l_@@_name_str } \maincomp{\l_stex_current_this_tl} } } } \let \this \stex_current_this: % \end{macrocode} % \end{macro} % % \begin{environment}{mathstructure} % \begin{macrocode} \stex_new_stylable_env:nnnnnnn {mathstructure}{m O{}}{ \_@@_begin:nn{#1}{#2} \stex_smsmode_do: }{ \stex_structural_feature_module_end: \_@@_do_externals: }{}{}{} \stex_keys_define:nnnn{mathstructure}{ \tl_clear:N \l_stex_current_this_tl \str_clear:N \l_@@_name_str }{ this .tl_set:N = \l_stex_current_this_tl , unknown .code:n = { \str_if_empty:NTF \l_keys_key_str { \str_set:Nx \l_@@_name_str {\l_keys_key_tl} }{ \str_set_eq:NN \l_@@_name_str \l_keys_key_str } } }{} \cs_new_protected:Nn \_@@_begin:nn { \stex_keys_set:nn {mathstructure}{#2} \str_if_empty:NT \l_@@_name_str { \str_set:Nn \l_@@_name_str {#1} } \def\comp{\_comp} \exp_args:Nne \use:nn { \stex_module_add_symbol:nnnnnnnN } { {#1}{\l_@@_name_str}{0}{}{defed}{ \l_stex_current_module_str / \l_@@_name_str-module }} {}\stex_invoke_structure: \str_set:Nx \l_stex_macroname_str {#1} \stex_execute_in_module:x{ \seq_clear:c{l_stex_structure_macros_\l_stex_current_module_str / \l_@@_name_str-module_seq} \seq_put_right:cn{l_stex_structure_macros_\l_stex_current_module_str / \l_@@_name_str-module_seq}{#1} } \exp_args:No \stex_structural_feature_module:nn {\l_@@_name_str}{structure} } \stex_sms_allow_env:n{mathstructure} \stex_deactivate_macro:Nn \mathstructure {module~environments} \stex_every_module:n {\stex_reactivate_macro:N \mathstructure} \cs_new_protected:Nn \_@@_do_externals: { \tl_set:Nn \l_@@_replace_this_tl {####1} \exp_args:No \stex_iterate_symbols:nn{\g_stex_last_feature_str}{ \_@@_external_decl:nnnn{##5}{##4}{##3}{##8} } } \cs_new_protected:Nn \_@@_external_decl:nnnn { %\stex_debug:nn{structure}{ % Generating~external~declaration~\l_@@_name_str/#3~in~ % \l_stex_current_module_str^^J % \tl_to_str:n{#1}^^J\tl_to_str:n{#2}^^J\tl_to_str:n{#4} %} %\tl_set:Nn \l_stex_get_symbol_args_tl {#1} %\exp_args:Nnx \use:nn {\stex_module_add_symbol:nnnnnnnN} { % {}{\l_@@_name_str/#3}{\int_eval:n{#2 + 1}} % {1i\tl_if_empty:nF{#1}{\_stex_map_args:N \_@@_shift_argls:nn}} % {defed}{typed} %}{#4}\stex_invoke_outer_field: } \cs_new:Nn \_@@_shift_argls:nn { \int_eval:n{#1+1}#2 } % \end{macrocode} % \end{environment} % % \begin{macro}{\stex_get_mathstructure:n} % \begin{macrocode} \cs_new_protected:Nn \stex_get_mathstructure:n { \_stex_get_mathstructure:n{#1} \str_if_empty:NT \l_stex_get_structure_module_str { \msg_error:nnn{stex}{error/unknownstructure}{#1} } } \cs_new_protected:Nn \_stex_get_mathstructure:n { \str_clear:N \l_stex_get_structure_module_str \_stex_get_symbol:n{#1} \str_if_empty:NF \l_stex_get_symbol_name_str { \exp_args:No \tl_if_eq:NNT \l_stex_get_symbol_invoke_cs \stex_invoke_structure: { \str_set_eq:NN \l_stex_get_structure_module_str \l_stex_get_symbol_type_tl } } } % \end{macrocode} % \end{macro} % % \begin{environment}{extstructure} % \begin{macrocode} \stex_new_stylable_env:nnnnnnn {extstructure}{m O{} m}{ \seq_clear:N \l_@@_imports_seq \clist_map_inline:nn{#3}{ \stex_get_mathstructure:n{##1} \clist_map_inline:Nn \l_stex_get_symbol_type_tl { \exp_args:Ne \stex_if_module_exists:nT{\tl_to_str:n{####1}}{ \seq_put_right:Nn \l_@@_imports_seq{####1} } } \stex_execute_in_module:x{ \seq_put_right:cn{l_stex_structure_macros_\l_stex_get_structure_module_str _seq}{#1} } } \_@@_begin:nn{#1}{#2} \seq_map_inline:Nn\l_@@_imports_seq{ \stex_if_do_html:T { \hbox{\stex_annotate_invisible:nn {shtml:import={##1}} {}} } \stex_module_add_morphism:nonn {}{##1}{import}{} \stex_execute_in_module:x{ \stex_activate_module:n{##1} } } \stex_smsmode_do: }{ \stex_structural_feature_module_end: \_@@_do_externals: }{}{}{} \stex_sms_allow_env:n{extstructure} \stex_deactivate_macro:Nn \extstructure {module~environments} \stex_every_module:n { \stex_reactivate_macro:N \extstructure } \cs_new:Nn \_@@_extend_structure_i:NnnnnnnnN { \exp_not:n{#1{#2}{#3}{#4}{#5}{defed}}{\l_@@_extmod_str,#7}\exp_not:n{{#8}#9} } \cs_new_protected:Nn \_@@_extend_structure:nn { \stex_debug:nn{ext}{Extending~#1~by~#2} \str_set:Nn \l_@@_extmod_str{#2} \tl_set:cx{#1}{ \exp_after:wN \exp_after:wN \exp_after:wN \_@@_extend_structure_i:NnnnnnnnN \cs:w #1 \cs_end: } } \stex_new_stylable_env:nnnnnnn {extstructure*}{m}{ \_@@_new_extstruct_name: \seq_clear:N \l_@@_imports_seq \stex_get_mathstructure:n{#1} \clist_map_inline:Nn \l_stex_get_symbol_type_tl { \exp_args:Ne \stex_if_module_exists:nT{\tl_to_str:n{##1}}{ \seq_put_right:Nn \l_@@_imports_seq{##1} } } \stex_execute_in_module:x{ \seq_map_inline:cn{l_stex_structure_macros_\l_stex_get_structure_module_str _seq}{ \exp_not:N \tl_if_exist:cT{####1}{ \_@@_extend_structure:nn{####1}{\l_stex_current_module_str/\l_@@_exstruct_name_str -module} } } } \exp_args:No \_@@_begin:nn\l_@@_exstruct_name_str{} \seq_map_inline:Nn \l_@@_imports_seq { \stex_if_do_html:T { \stex_annotate_invisible:nn {shtml:import= {##1}} {} } \stex_module_add_morphism:nonn {}{##1}{import}{} \stex_execute_in_module:x{ \stex_activate_module:n{##1} } } \stex_smsmode_do: }{ \prop_map_inline:cn{ c_stex_module_ \l_stex_current_module_str _symbols_prop }{ \_@@_check_def:nnnnnnnn ##2 } \stex_structural_feature_module_end: \_@@_do_externals: }{}{}{} \stex_sms_allow_env:n{extstructure*} \exp_after:wN \stex_deactivate_macro:Nn \cs:w extstructure*\cs_end: {module~environments} \stex_every_module:n { \exp_after:wN \stex_reactivate_macro:N \cs:w extstructure*\cs_end: } \cs_new_protected:Nn \_@@_check_def:nnnnnnnn { \tl_if_empty:nT{#5}{ \msg_error:nnnn{stex}{error/needsdefiniens}{#2}{extstructure*} } } \stex_every_module:n{ \str_set:Nn \l_@@_extname_count 0} \cs_new_protected:Nn \_@@_new_extstruct_name: { \stex_do_up_to_module:n { \str_set:Nx \l_@@_extname_count {\int_eval:n{\l_@@_extname_count+1}} } \str_set:Nx \l_@@_exstruct_name_str {EXTSTRUCT_\l_@@_extname_count} } % \end{macrocode} % \end{environment} % % Invoking structures: % \begin{macrocode} \cs_new_protected:Nn \stex_invoke_structure: { \tl_set:Nn \l_@@_set_comp_tl {\_@@_set_thiscomp:} \_@@_invoke_top:n {} } \cs_new_protected:Nn \_@@_invoke_top:n { \stex_debug:nn{structure}{ invoking~structure~{\l_stex_current_type_tl}<\tl_to_str:n{#1}> } \peek_charcode:NTF [ { \_@@_merge:nw{#1} }{ \_@@_invokation_type:n {#1} \tl_set:Nn \l_@@_this_tl {} \peek_charcode_remove:NTF ! { \peek_charcode:NTF [ { \_@@_maybe_notation:w }{ \_@@_maybe_notation:w [] } }{ \_@@_invoke_this:n } } } \cs_new_protected:Npn \_@@_merge:nw #1 [ #2 ] { \exp_args:Ne \stex_str_if_starts_with:nnTF {\tl_to_str:n{#2}}{comp=}{ \_@@_set_customcomp: #2 \_@@_end: \_@@_invoke_top:n{#1} }{ \exp_args:Ne \stex_str_if_starts_with:nnTF {\tl_to_str:n{#2}}{this=}{ \_@@_set_thisnotation: #2 \_@@_end: \_@@_invoke_top:n{#1} }{ \tl_if_empty:nTF{#1}{ \_@@_invoke_top:n{#2} }{ \tl_if_empty:nTF{#2}{ \_@@_invoke_top:n{#1} }{ \_@@_invoke_top:n{#1,#2} } } } } } \cs_new_protected:Npn \_@@_set_thisnotation: this= #1 \_@@_end: { \tl_set:Nn \l_stex_return_notation_tl { \comp{#1} } \tl_set:Nn \l_@@_set_comp_tl {} } \cs_new_protected:Npn \_@@_set_customcomp: comp= #1 \_@@_end: { \tl_set:Nn \l_@@_set_comp_tl { \_@@_set_custom_comp:n{#1} } \tl_set:Nn \l_stex_return_notation_tl { \comp{} } } % \end{macrocode} % The structure type: % \begin{macrocode} \cs_new_protected:Nn \_@@_invokation_type:n { \_@@_do_assign_list:n{#1} \clist_if_empty:NTF \l_@@_fields_clist { \int_compare:nNnTF {\clist_count:N \l_stex_current_type_tl} = 1 { \tl_set:Nx \l_@@_current_type_tl { \exp_args:No \exp_not:n \l_stex_current_redo_tl \_stex_term_oms_or_omv:nnn{}{}{} } }{ \exp_args:No \_@@_make_type:n \l_stex_current_type_tl } }{ \int_compare:nNnTF {\clist_count:N \l_stex_current_type_tl} = 1 { \_@@_make_type:n {} }{ \exp_args:No \_@@_make_type:n \l_stex_current_type_tl } } } \cs_new_protected:Nn \_@@_do_assign_list:n { \clist_clear:N \l_@@_fields_clist \tl_if_empty:nF {#1} { \keyval_parse:NNn\TODO\_@@_do_assign:nn{#1} } } \cs_new_protected:Nn \_@@_do_assign:nn { \clist_put_right:Nn \l_@@_fields_clist {{#1}{#2}} } \cs_new_protected:Nn \_@@_make_type:n { \tl_if_empty:nTF{#1}{ \seq_clear:N \l_tmpa_seq }{ \seq_set_split:Nnn \l_tmpa_seq ,{#1} \seq_pop_right:NN \l_tmpa_seq \l_tmpa_tl \seq_reverse:N \l_tmpa_seq } \tl_set:Nx \l_@@_current_type_tl { \symuse{Metatheory?module~type~merge}{ { \exp_args:No \exp_not:n \l_stex_current_redo_tl \_stex_term_oms_or_omv:nnn{}{}{} } \seq_map_function:NN \l_tmpa_seq \_@@_make_mod:n \clist_if_empty:NF \l_@@_fields_clist { ,\symuse{Metatheory?anonymous~record}{ \exp_args:Ne \tl_tail:n{ \clist_map_function:NN \l_@@_fields_clist \_@@_make_oml:n } } } } } } \cs_new:Nn \_@@_make_mod:n { ,\symuse{Metatheory?module~type}{ \stex_annotate:nn{shtml:term=OMMOD,shtml:head={#1}}{} } } \cs_new:Nn \_@@_make_oml:n { \_@@_make_oml:nn #1 } \cs_new:Nn \_@@_make_oml:nn { ,\stex_annotate:nn{ shtml:term=OML, shtml:head={#1} }{ \_stex_annotate_force_break:n{ \stex_annotate:nn{shtml:definiens={}}{\exp_not:n{#2!}} } } } % \end{macrocode} % Insert the structure type as a term: % \begin{macrocode} \cs_new:Nn \_@@_current_type: { %\exp_args:No \exp_not:n \l_stex_current_redo_tl \tl_set:Nn \exp_not:N \l_stex_current_term_tl { \exp_args:No\exp_not:n\l_@@_current_type_tl } \_stex_term_oms_or_omv:nnn{}{}{} } % \end{macrocode} % The structure type itself: % \begin{macrocode} \cs_new_protected:Npn \_@@_maybe_notation:w [ #1 ] { \tl_set_eq:NN \l_stex_current_term_tl \l_@@_current_type_tl \cs_if_exist:cTF{l_stex_notation_\l_stex_current_symbol_str _#1_cs}{ \use:c{l_stex_notation_\l_stex_current_symbol_str _#1_cs}\group_end: }{ \_@@_make_prop: \_@@_make_prop_assign: \_@@_present_i:w [#1] } } \cs_new_protected:Nn \_@@_present: { \peek_charcode:NTF [ { \_@@_present_i:w }{ \_@@_present:nn{}{} } } \cs_new_protected:Npn \_@@_present_i:w [#1] { \int_compare:nNnTF{\clist_count:n{#1}} = 1 { \_@@_present:nn{}{#1} }{ \peek_charcode:NTF [ { \_@@_present_ii:nw{#1} }{ \_@@_present:nn{#1}{} } } } %First: clist, second:notation-id \cs_new_protected:Npn \_@@_present_ii:nw #1 [#2] { \_@@_present:nn{#1}{#2} } \cs_new_protected:Nn \_@@_present:nn { \clist_clear:N \l_@@_clist \tl_if_empty:nTF{#1}{ \cs_set:Npn \l_@@_cs ##1 ##2 ##3 { \tl_if_empty:nF{##2}{ \_@@_present_entry:nn {##1}{##3} } } }{ \cs_set:Npn \l_@@_cs ##1 ##2 ##3 { \exp_args:Ne \clist_if_in:nnT{\tl_to_str:n{#1}}{##1}{ \_@@_present_entry:nn {##1}{##3} } } } \prop_map_inline:Nn \l_@@_prop { \l_@@_cs {##1} ##2 } \_stex_term_oms_or_omv:nnn{}{}{ \exp_args:Nno \use:n{ \bool_set_true:N \l_stex_allow_semantic_bool \symuse{Metatheory?mathematical~structure}[#2] }{\l_@@_clist} }\group_end: } \cs_new_protected:Nn \_@@_present_entry:nn { \seq_if_in:NnTF \l_@@_assigned_seq {#1}{ \clist_put_right:Nn \l_@@_clist {#2!} }{ \exp_args:NNe \clist_put_right:Nn \l_@@_clist { \_stex_next_symbol:n { \exp_args:No \exp_not:n \l_@@_set_comp_tl \tl_set:Nn \exp_not:N \l_@@_this_tl { \exp_args:No \exp_not:n \l_@@_this_tl } \exp_not:n { \tl_set_eq:NN \this \l_@@_this_tl } \tl_set:Nn \exp_not:N \l_stex_return_notation_tl { \exp_args:No \exp_not:n \l_stex_return_notation_tl } } \exp_not:n{#2!} } } } \cs_new_protected:Npn \_thiscomp #1 #2 { {\tl_set:cn{this}{{}}#1{#2}\c_math_subscript_token{ \group_begin: \bool_set_true:N \l_stex_allow_semantic_bool \l_@@_this_tl \group_end: } } } \cs_new_protected:Nn \_@@_set_thiscomp: { \exp_args:Ne \tl_if_eq:NNF {\tl_head:N \maincomp} \_thiscomp { \edef\maincomp {\_thiscomp{\comp}} } } \cs_new_protected:Nn \_@@_set_custom_comp:n { \exp_args:Ne \tl_if_eq:NNF {\tl_head:N \maincomp} \_customthiscomp { \cs_set_protected:Npx \_customthiscomp ##1 { \group_begin: \bool_set_true:N \l_stex_allow_semantic_bool \exp_not:n{ \cs_set:Npn \l_@@_comp_cs ##1 { #1 } \def\maincomp }{\comp} \exp_not:N\l_@@_comp_cs{\comp{##1}} \group_end: } \def\maincomp {\_customthiscomp} } } % \end{macrocode} % |this| (of type |structure|): % \begin{macrocode} \cs_new_protected:Nn \_@@_invoke_this:n { \peek_charcode_remove:NTF ! { \exp_args:Nne\use:nn{ \group_end:\symuse{Metatheory?of~type}[invisible]{#1} }{ {\_@@_current_type:} } }{ \_@@_invoke_maybe_field:nn{#1} } } \cs_new_protected:Nn \_@@_invoke_maybe_field:nn { \_@@_make_prop: \_@@_set_this:n{#1} \tl_if_empty:nTF{#2}{ \_@@_make_prop_assign: \_@@_present: }{ \_@@_invoke_field:n{#2} } } \cs_new_protected:Nn \_@@_set_this:n { \tl_if_empty:nTF{#1}{ %\tl_put_right:Nn \l_stex_current_redo_tl { % \tl_clear:N \l_@@_this_tl %} }{ \tl_set:Nx \l_@@_this_tl {{ \bool_set_true:N \l_stex_allow_semantic_bool \tl_set:Nn \exp_not:N \this { \exp_args:No \exp_not:n \this } \exp_not:n{#1} }} \tl_set_eq:NN \this \l_@@_this_tl % \l_stex_return_notation_tl } } \cs_new_protected:Nn \_@@_get_field_name:n { \str_set:Nx \l_@@_field_name_str { \exp_args:Nne \use:n {\exp_after:wN \use_i:nn \use:n} {\prop_item:Nn \l_@@_prop {#1}} } \str_if_empty:NT \l_@@_field_name_str { \str_set:Nn \l_@@_field_name_str {#1} } } \cs_new_protected:Nn \_@@_invoke_field:n { \prop_if_in:NnTF \l_@@_prop {#1}{ \_@@_get_field_name:n{#1} \tl_clear:N \l_@@_more_nextsymbol_tl %\exp_args:NNe \seq_if_in:NnF \l_@@_assigned_seq {\tl_to_str:n{#1}}{ \tl_set:Nx \l_@@_more_nextsymbol_tl { \tl_set:Nn \exp_not:N \l_@@_this_tl { \exp_args:No \exp_not:n \l_@@_this_tl } \exp_not:n { \tl_set_eq:NN \this \l_@@_this_tl } \tl_set:Nn \exp_not:N \l_stex_return_notation_tl { \exp_args:No \exp_not:n \l_stex_return_notation_tl } \exp_args:No \exp_not:n \l_@@_set_comp_tl } %} \exp_args:NNx \use:nn \group_end: { \_stex_next_symbol:n { \exp_args:No \exp_not:n \l_@@_redo_tl \tl_set:Nn \exp_not:N \l_stex_current_term_tl { \symuse{Metatheory?record~field}{ \symuse{Metatheory?of~type}{ \exp_args:No \exp_not:n \l_@@_this_tl }{ \_@@_current_type: } }{ \stex_annotate:nn{shtml:term=OML,shtml:head={\l_@@_field_name_str}}{} } } \exp_args:No \exp_not:n \l_@@_more_nextsymbol_tl } \exp_not:N \use_ii:nn \prop_item:Nn \l_@@_prop {#1} } }{ \msg_error:nnn{stex}{error/unknownfield}{#1} } } \cs_new_protected:Nn \_@@_make_prop: { \prop_clear:N \l_@@_prop \seq_clear:N \l_@@_seq \seq_clear:N \l_@@_assigned_seq \tl_clear:N \l_@@_redo_tl \_@@_prop_do_decls: \_@@_prop_do_notations: } \cs_new_protected:Nn \_@@_make_prop_assign: { \clist_if_empty:NF \l_@@_fields_clist { \clist_map_inline:Nn \l_@@_fields_clist { \_@@_make_prop_assign:nn ##1 } } } \cs_new_protected:Nn \_@@_make_prop_assign:nn { \prop_if_in:NnTF \l_@@_prop {#1}{ \exp_args:NNe \seq_put_right:Nn \l_@@_assigned_seq {\tl_to_str:n{#1}} \exp_args:Nne \use:nn {\_@@_make_prop_assign_replace:nnnn {#1}{#2}} {\prop_item:Nn \l_@@_prop {#1}} }{ \msg_error:nnn{stex}{error/unknownfieldass}{#1} } } \cs_new_protected:Nn \_@@_make_prop_assign_replace:nnnn { \prop_put:Nnn \l_@@_prop {#1}{{#3}{#2}} \tl_if_empty:nF{#3}{ \tl_set:cn{#1}{ #2 } \tl_put_right:Nn \l_@@_redo_tl { \tl_set:cn{#1}{ #2 } } } } \cs_new_protected:Nn \_@@_prop_do_decls: { \exp_args:No \stex_iterate_symbols:nn \l_stex_current_type_tl { \tl_if_empty:nTF{##2}{ \_@@_do_decl_nomacro:nnnnnnnnn{##3} }{ \_@@_do_decl:nnnnnnnnn{##2} } {##1}{##3}{##4}{##5}{##6}{##7}{##8}{##9} } } \cs_new_protected:Nn \_@@_do_decl_nomacro:nnnnnnnnn { \prop_if_in:NnF \l_@@_prop {#1} { \seq_put_left:Nx \l_@@_seq {\tl_to_str:n{#2?#3}} \prop_put:Nnn \l_@@_prop {#1}{ {}{ \_stex_invoke_symbol:nnnnnnnN {#2} {#3} {#4}{#5}{#6}{#7}{#8}#9 } } } } \cs_new_protected:Nn \_@@_do_decl:nnnnnnnnn { \prop_if_in:NnF \l_@@_prop {#1} { \seq_put_left:Nx \l_@@_seq {\tl_to_str:n{#2?#3}} \prop_put:Nnn \l_@@_prop {#1}{ {#3}{ \_stex_invoke_symbol:nnnnnnnN {#2} {#3} {#4}{#5}{#6}{#7}{#8}#9 } } } %\tl_set:cn{#1}{ % \_stex_invoke_symbol:nnnnnnnN % {#2}{#3}{#4}{#5}{#6}{#7}{#8}#9 %} %\tl_put_right:Nn \l_@@_redo_tl { % \tl_set:cn{#1}{ % \_stex_invoke_symbol:nnnnnnnN % {#2}{#3}{#4}{#5}{#6}{#7}{#8}#9 % } %} } \cs_new_protected:Nn \_@@_prop_do_notations: { \exp_args:No \stex_iterate_notations:nn\l_stex_current_type_tl{ \exp_args:NNe \seq_if_in:NnT \l_@@_seq {\tl_to_str:n{##1}}{ \tl_put_right:Nn \l_@@_redo_tl { \cs_if_exist:cF{l_stex_notation_##1 _##2_cs}{ \tl_set:cn{l_stex_notation_##1 _##2_cs}{##4} } \cs_if_exist:cF{l_stex_notation_##1 __cs}{ \tl_set:cn{l_stex_notation_##1 __cs}{##4} } } \cs_if_exist:cF{l_stex_notation_##1 _##2_cs}{ \tl_set:cn{l_stex_notation_##1 _##2_cs}{##4} } \cs_if_exist:cF{l_stex_notation_##1 __cs}{ \tl_set:cn{l_stex_notation_##1 __cs}{##4} } \tl_if_empty:nF{##5}{ \tl_put_right:Nn \l_@@_redo_tl { \cs_if_exist:cF{l_stex_notation_##1 _op_##2_cs}{ \tl_set:cn{l_stex_notation_##1 _op_##2_cs}{##5} } \cs_if_exist:cF{l_stex_notation_##1 _op__cs}{ \tl_set:cn{l_stex_notation_##1 _op__cs}{##5} } } \cs_if_exist:cF{l_stex_notation_##1 _op_##2_cs}{ \tl_set:cn{l_stex_notation_##1 _op_##2_cs}{##5} } \cs_if_exist:cF{l_stex_notation_##1 _op__cs}{ \tl_set:cn{l_stex_notation_##1 _op__cs}{##5} } } } } } % \end{macrocode} % % \begin{macro}{\usestructure} % \begin{macrocode} \cs_new_protected:Npn \usestructure #1 { \stex_get_mathstructure:n{ #1 } \seq_clear:N \l_@@_imports_seq \clist_map_inline:Nn \l_stex_get_symbol_type_tl { \exp_args:Ne \stex_if_module_exists:nT{\tl_to_str:n{##1}}{ \seq_put_right:Nn \l_@@_imports_seq{##1} } } \seq_map_inline:Nn \l_@@_imports_seq { \stex_if_do_html:T { \hbox{\stex_annotate_invisible:nn {shtml:usemodule=##1} {}} } \stex_activate_module:n {##1} } } % \end{macrocode} % % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Statements} % \begin{macrocode} %<@@=stex_statements> \stex_keys_define:nnnn{statement}{ \str_clear:N \l_stex_key_name_str \str_clear:N \l_stex_key_macroname_str \clist_clear:N \l_stex_key_for_clist \str_clear:N \l_stex_key_args_str \tl_clear:N \l_stex_key_type_tl \tl_clear:N \l_stex_key_def_tl \tl_clear:N \l_stex_key_return_tl \clist_clear:N \l_stex_key_argtypes_clist }{ name .str_set:N = \l_stex_key_name_str , for .clist_set:N = \l_stex_key_for_clist , macro .str_set:N = \l_stex_key_macroname_str , % start .str_set:N = \l_stex_key_title_str , % TODO remove type .tl_set:N = \l_stex_key_type_tl , judgment .code:n = {}, from .code:n= {}, % TODO remove to .code:n={} % TODO remove }{id,title,style,symargs} % \end{macrocode} % % \begin{macro}{\stex_new_statement:nn} % \begin{macrocode} \cs_new_protected:Npn \_stex_do_for_list: { \seq_clear:N \l_stex_fors_seq \clist_map_inline:Nn \l_stex_key_for_clist { \exp_args:Ne\stex_get_symbol:n{\tl_to_str:n{##1}} \seq_put_right:Nx \l_stex_fors_seq {\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } } \cs_new_protected:Nn \_@@_setup:nn { \str_if_empty:NF \l_stex_key_macroname_str { \str_if_empty:NT \l_stex_key_name_str { \str_set_eq:NN \l_stex_key_name_str \l_stex_key_macroname_str } } \_stex_do_for_list: \str_if_empty:NF \l_stex_key_name_str { \_@@_force_id: \seq_put_right:Nx \l_stex_fors_seq { \l_stex_current_module_str ? \l_stex_key_name_str } \str_set_eq:NN \l_stex_macroname_str \l_stex_key_macroname_str \str_set:Nn \l_stex_key_role_str {#2} \stex_symdecl_do: \exp_args:Nnx \use:nn {\stex_module_add_symbol:nnnnnnnN}{ {\l_stex_key_macroname_str}{\l_stex_key_name_str} {\int_use:N \l_stex_get_symbol_arity_int} {\l_stex_get_symbol_args_tl} {#1}{}{}\stex_invoke_symbol: } \stex_if_do_html:T \_stex_symdecl_html: } \str_clear:N \l_@@_uri_str \str_if_empty:NTF \l_stex_key_name_str { \stex_debug:nn{statement}{no~name} \int_compare:nNnTF {\seq_count:N \l_stex_fors_seq} = 1 { \str_set:Nx \l_@@_uri_str {\seq_item:Nn \l_stex_fors_seq 1} \stex_debug:nn{statement}{for:~\l_@@_uri_str} }{ \stex_debug:nn{statement}{no~for} } }{ \str_set:Nx \l_@@_uri_str {\l_stex_current_module_str ? \l_stex_key_name_str} \stex_debug:nn{statement}{name:~\l_@@_uri_str} } } \cs_new:Nn \_@@_html_keyvals:nn { shtml:#1={}, shtml:inline={#2}, \seq_if_empty:NF \l_stex_fors_seq {, shtml:fors={\seq_use:Nn \l_stex_fors_seq ,} } \str_if_empty:NF \l_stex_key_id_str {, shtml:id={\stex_uri_use:N \l_stex_current_doc_uri ? \l_stex_key_id_str} } \clist_if_empty:NF \l_stex_key_style_clist {, shtml:styles={\l_stex_key_style_clist} } } \cs_new_protected:Nn \stex_new_statement:nnn { \stex_new_stylable_env:nnnnnnn {#1}{O{}}{ \stex_keys_set:nn{statement}{##1} #3 \stex_if_smsmode:F { \exp_args:Nne \begin{stex_annotate_env}{ \_@@_html_keyvals:nn{#1}{false} } \tl_set_eq:NN \thistitle \l_stex_key_title_tl \str_set_eq:NN \thisname \l_stex_key_name_str \clist_set_eq:NN \thisfor \l_stex_key_for_str \stex_if_html_backend:TF { \noindent \stex_annotate:nn{shtml:statementtitle={}}{\_stex_annotate_force_break:n\l_stex_key_title_tl} } \stex_style_apply: } \_stex_do_id: \stex_smsmode_do: }{ \stex_if_smsmode:F { \stex_if_html_backend:F \stex_style_apply: \end{stex_annotate_env} } }{}{}{s} \stex_sms_allow_env:n{s#1} \tl_if_empty:nF{#2}{ \exp_after:wN \NewDocumentCommand \cs:w inline#2\cs_end: { O{} m}{ \group_begin: \stex_keys_set:nn{statement}{##1} #3 \_stex_do_id: \stex_if_smsmode:F{ \exp_args:Ne \stex_annotate:nn{\_@@_html_keyvals:nn{#1}{true}}{ \_stex_annotate_force_break:n{##2} } } \group_end: \stex_smsmode_do: } \exp_after:wN \stex_sms_allow_escape:N\cs:w inline#2\cs_end: } } \cs_new_protected:Nn \_@@_setup_def: { \stex_if_smsmode:F{ \seq_map_inline:Nn \l_stex_fors_seq { \stex_ref_new_sym_target:n{##1} } } \stex_reactivate_macro:N \definiendum \stex_reactivate_macro:N \defnotation \stex_reactivate_macro:N \definame \stex_reactivate_macro:N \Definame \stex_reactivate_macro:N \varbind } \cs_new_protected:Nn \_@@_force_id: { \str_if_empty:NT \l_stex_key_id_str { \_stex_ref_new_id:n{} \str_set_eq:NN \l_stex_key_id_str \l__stex_refs_str } } \stex_new_statement:nnn{definition}{def}{ \_@@_force_id: \_@@_setup:nn{}{} \_@@_setup_def: \stex_reactivate_macro:N \definiens } \stex_new_statement:nnn{assertion}{ass}{ \_@@_setup:nn{}{assertion} \stex_if_smsmode:F{ \seq_map_inline:Nn \l_stex_fors_seq { \stex_ref_new_sym_target:n{##1} } } \stex_reactivate_macro:N \varbind \stex_reactivate_macro:N \conclusion \stex_reactivate_macro:N \premise \stex_reactivate_macro:N \definiendum \stex_reactivate_macro:N \defnotation \stex_reactivate_macro:N \definame \stex_reactivate_macro:N \Definame } \stex_new_statement:nnn{example}{ex}{\_@@_setup:nn{}{example}} \stex_new_statement:nnn{paragraph}{}{ \clist_if_in:NnTF \l_stex_key_style_clist {symdoc}{ \_@@_force_id: \_@@_setup:nn{}{} \_@@_setup_def: }{ \_@@_setup:nn{}{} } } % \end{macrocode} % \end{macro} % % \begin{macro}{definiendum} % \begin{macrocode} \cs_new_protected:Nn \_@@_do_defref:nn { \stex_if_html_backend:T{\ifvmode\indent\fi} \group_begin: \stex_get_symbol:n{#1} \bool_if:NTF \l_stex_allow_semantic_bool{ \str_set:Nx\l_stex_current_symbol_str {\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} \str_if_in:NnT \l_stex_get_symbol_name_str / { \str_set:Nx \l_stex_get_symbol_name_str { \exp_after:wN \_stex_split_slash: \l_stex_get_symbol_name_str /\_stex_args_end: } } \exp_args:No \stex_ref_new_sym_target:n \l_stex_current_symbol_str \def\comp{\_defcomp} \stex_annotate:nn{shtml:definiendum=\l_stex_current_symbol_str}{\comp{#2}} }{ \msg_error:nnxx{stex}{error/notallowed}{#1}{\l_stex_current_symbol_str} } \group_end: } \NewDocumentCommand \defnotation{ m } { \_stex_next_symbol:n { \def\comp{\_defcomp}}#1 } \stex_deactivate_macro:Nn \defnotation {definition~environments} \NewDocumentCommand \definiendum { O{} m m} { \stex_keys_set:nn{symname}{ #1 } \_@@_do_defref:nn{#2}{#3} } \stex_deactivate_macro:Nn \definiendum {definition~environments} \NewDocumentCommand \definame { O{} m } { \stex_keys_set:nn{symname}{#1} \_@@_do_defref:nn{#2}{ \l_stex_key_pre_tl\l_stex_get_symbol_name_str\l_stex_key_post_tl } } \stex_deactivate_macro:Nn \definame {definition~environments} \NewDocumentCommand \Definame { O{} m } { \stex_keys_set:nn{symname}{#1} \_@@_do_defref:nn{#2}{ \l_stex_key_pre_tl\exp_after:wN\_stex_capitalize:n\l_stex_get_symbol_name_str\l_stex_key_post_tl } } \stex_deactivate_macro:Nn \Definame {definition~environments} \NewDocumentCommand \definiens { O{} m }{ \group_begin: \str_clear:N \l_stex_get_symbol_name_str \tl_if_empty:nF {#1} { \stex_get_symbol:n { #1 } \str_set:Nx \l_@@_uri_str {\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } \str_if_empty:NT \l_@@_uri_str { \msg_error:nn{stex}{error/definiensfor} } \stex_debug:nn{definiens}{Checking~\l_@@_uri_str} \exp_args:No \_stex_add_definiens:nn \l_@@_uri_str{#2} \group_end: \stex_smsmode_do: } \stex_deactivate_macro:Nn \definiens {definition~environments} \stex_sms_allow_escape:N \definiens \cs_new_protected:Nn \_stex_add_definiens:nn { \exp_args:Nno \stex_str_if_starts_with:nnT{#1} \l_stex_current_module_str { \prop_map_inline:cn{c_stex_module_\l_stex_current_module_str _symbols_prop}{ \stex_debug:nn{definiens}{#1 == \l_stex_current_module_str?##1} \str_if_eq:noT {#1} {\l_stex_current_module_str?##1}{ \prop_map_break:n{\_stex_add_definiens_inner:nnnnnnnn ##2} } } } \stex_if_smsmode:F{ \stex_annotate:nn{ shtml:definiens={#1}}{ #2 %\_stex_annotate_force_break:n{ #2 } } } } \cs_new_protected:Nn \_stex_add_definiens_inner:nnnnnnnn { \stex_debug:nn{definiens}{Adding~definiens~to~\l_stex_current_module_str?#2} \prop_gput:cnn{c_stex_module_\l_stex_current_module_str _symbols_prop} {#2}{{#1}{#2}{#3}{#4}{defed}{#6}{#7}{#8}} } \NewDocumentCommand \varbind {m} { \clist_map_inline:nn {#1} { \stex_get_var:n {##1} \stex_if_do_html:T { \stex_annotate_invisible:nn {shtml:bind=\l_stex_get_symbol_name_str}{} } } } \stex_deactivate_macro:Nn \varbind {definition~or~assertion~environments} \NewDocumentCommand \conclusion { O{} m} { \group_begin: \str_clear:N \l_stex_get_symbol_name_str \tl_if_empty:nF {#1} { \stex_get_symbol:n { #1 } \str_set:Nx \l_@@_uri_str {\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } \str_if_empty:NT \l_@@_uri_str { \msg_error:nn{stex}{error/conclusionfor} } \stex_annotate:nn{ shtml:conclusion=\l_@@_uri_str}{ #2 %\_stex_annotate_force_break:n{ #2 } } \group_end: } \stex_deactivate_macro:Nn \conclusion {assertion~environments} \NewDocumentCommand \premise {O{} m} { \tl_if_empty:nF {#1} { \stex_debug:nn{Here:}{Variable~#1} \exp_args:Nne\use:nn{\vardef}{{v#1}[name=#1]{#1}} } \stex_annotate:nn{shtml:premise={#1}}{#2} } \stex_deactivate_macro:Nn \premise {assertion~environments} % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Proofs} % % We first define some keys for the \env{sproof} environment. % \begin{macrocode} %<@@=stex_proof> \stex_keys_define:nnnn{ spf }{ \tl_clear:N \l_stex_key_for_clist \tl_clear:N \l_stex_key_from_tl \tl_set_eq:NN \l_stex_key_proofend_tl \_@@_proof_box_tl \tl_clear:N \l_stex_key_continues_tl \tl_clear:N \l_stex_key_term_tl \tl_clear:N \l_stex_key_functions_tl \tl_clear:N \l_stex_key_method_tl \bool_set_false:N \l_stex_key_hide_bool }{ for .clist_set:N = \l_stex_key_for_clist , from .tl_set:N = \l_stex_key_from_tl , proofend .tl_set:N = \l_stex_key_proofend_tl, continues .tl_set:N = \l_stex_key_continues_tl, functions .tl_set:N = \l_stex_key_functions_tl, term .tl_set:N = \l_stex_key_term_tl, method .tl_set:N = \l_stex_key_method_tl, hide .bool_set:N = \l_stex_key_hide_bool }{id,style,title} \bool_set_true:N \l_@@_inc_counter_bool % \end{macrocode} % % For proofs, we will have to have deeply nested structures of enumerated list-like % environments. However, {\LaTeX} only allows |enumerate| environments up to nesting depth % 4 and general list environments up to listing depth 6. This is not enough for us. % Therefore we have decided to go along the route proposed by Leslie Lamport to use a % single top-level list with dotted sequences of numbers to identify the position in the % proof tree. Unfortunately, we could not use his |pf.sty| package directly, since it does % not do automatic numbering, and we have to add keyword arguments all over the place, to % accomodate semantic information. % % \begin{macrocode} \intarray_new:Nn\l_@@_counter_intarray{50} \cs_new_protected:Npn \_@@_insert_number: { \int_set:Nn \l_tmpa_int {1} \bool_while_do:nn { \int_compare_p:nNn { \intarray_item:Nn \l_@@_counter_intarray \l_tmpa_int } > 0 }{ \intarray_item:Nn \l_@@_counter_intarray \l_tmpa_int . \int_incr:N \l_tmpa_int } } \cs_new_protected:Nn \_@@_number_as_string:N { \str_clear:N #1 \int_set:Nn \l_tmpa_int {1} \bool_while_do:nn { \int_compare_p:nNn { \intarray_item:Nn \l_@@_counter_intarray \l_tmpa_int } > 0 }{ \str_put_right:Nx #1 {\intarray_item:Nn \l_@@_counter_intarray \l_tmpa_int .} \int_incr:N \l_tmpa_int } } \cs_new_protected:Npn \_@@_inc_counter: { \int_set:Nn \l_tmpa_int {1} \bool_while_do:nn { \int_compare_p:nNn { \intarray_item:Nn \l_@@_counter_intarray \l_tmpa_int } > 0 }{ \int_incr:N \l_tmpa_int } \int_compare:nNnF \l_tmpa_int = 1 { \int_decr:N \l_tmpa_int } \intarray_gset:Nnn \l_@@_counter_intarray \l_tmpa_int { \intarray_item:Nn \l_@@_counter_intarray \l_tmpa_int + 1 } } \cs_new_protected:Npn \_@@_add_counter: { \int_set:Nn \l_tmpa_int {1} \bool_while_do:nn { \int_compare_p:nNn { \intarray_item:Nn \l_@@_counter_intarray \l_tmpa_int } > 0 }{ \int_incr:N \l_tmpa_int } \intarray_gset:Nnn \l_@@_counter_intarray \l_tmpa_int { 1 } } \cs_new_protected:Npn \_@@_remove_counter: { \int_set:Nn \l_tmpa_int {1} \bool_while_do:nn { \int_compare_p:nNn { \intarray_item:Nn \l_@@_counter_intarray \l_tmpa_int } > 0 }{ \int_incr:N \l_tmpa_int } \int_decr:N \l_tmpa_int \intarray_gset:Nnn \l_@@_counter_intarray \l_tmpa_int { 0 } } % \end{macrocode} % % \begin{macro}{spfsketch} % \begin{macrocode} \newenvironment{spfsketchenv}{}{} \stex_new_stylable_cmd:nnnn{spfsketch}{O{} m}{\par \begin{spfsketchenv} \stex_keys_set:nn{spf}{#1} \_stex_do_for_list: \_stex_do_id: \exp_args:Ne \stex_annotate:nn{ shtml:proofsketch={ \seq_if_empty:NF \l_stex_fors_seq { \seq_use:Nn \l_stex_fors_seq , } } }{ \stex_style_apply: #2 } \end{spfsketchenv} }{ \noindent\emph{\spfsketchenvautorefname :}~ } % \end{macrocode} % \end{macro} % %\begin{macro}{\sproofend} % This macro places a little box at the end of the line if there is space, or at the % end of the next line if there isn't % \begin{macrocode} \tl_set:Nn \_@@_proof_box_tl { \ltx@ifpackageloaded{amssymb}{$\square$}{ \hbox{\vrule\vbox{\hrule width 6 pt\vskip 6pt\hrule}\vrule} } } \tl_set:Nn \sproofend { \tl_if_empty:NF \l_stex_key_proofend_tl { \hfil\null\nobreak\hfill\l_stex_key_proofend_tl\par\smallskip } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stexcommentfont} % \begin{macrocode} \cs_new_protected:Npn \stexcommentfont { \small\itshape } % \end{macrocode} % \end{macro} % % \begin{environment}{sproof} % \begin{macrocode} \cs_new_protected:Nn \_@@_start_list:n { \begin{list}{}{ \setlength\topsep{0pt} \setlength\parsep{0pt} \setlength\rightmargin{0pt} }\item[#1] } \cs_new_protected:Nn \_@@_end_list: { \end{list} } \cs_new_protected:Nn \_@@_html: { \stex_annotate_invisible:n{\hbox{ \tl_if_empty:NF \l_stex_key_term_tl { $\stex_annotate:nn{shtml:proofterm={}}{\l_stex_key_term_tl}$ } \tl_if_empty:NF \l_stex_key_method_tl { \stex_annotate:nn{shtml:proofmethod={}}{\l_stex_key_method_tl} } }} } \cs_new_protected:Nn \_@@_html_env:n { \exp_args:Nne \begin{stex_annotate_env}{ shtml:#1={ \seq_if_empty:NF \l_stex_fors_seq { \seq_use:Nn \l_stex_fors_seq , } } \bool_if:NT \l_stex_key_hide_bool {, shtml:proofhide=true } } \_@@_html: } \bool_set_false:N \l_@@_in_spfblock_bool \cs_new_protected:Nn \_@@_begin_proof:nn {\par \intarray_gzero:N \l_@@_counter_intarray \intarray_gset:Nnn \l_@@_counter_intarray 1 1 \stex_keys_set:nn{spfsteps}{#1} \_stex_do_for_list: \stex_if_do_html:T { \_@@_html_env:n{proof} } \seq_map_inline:Nn \l_stex_fors_seq { \stex_debug:nn{definiens}{Adding~definiens~to~##1} \_stex_add_definiens:nn {##1}{\STEXinvisible{proven}} } \stex_style_apply: \_stex_do_id: \stex_reactivate_macro:N \subproof \stex_reactivate_macro:N \spfstep \stex_reactivate_macro:N \conclude \stex_reactivate_macro:N \assumption \stex_reactivate_macro:N \eqstep \stex_reactivate_macro:N \yield \stex_reactivate_macro:N \spfblock \stex_reactivate_macro:N \spfjust \stex_annotate:nn{shtml:prooftitle={}}{#2} \stex_if_do_html:T{ \begin{stex_annotate_env}{shtml:proofbody={}} } } \stex_new_stylable_env:nnnnnnn{proof}{O{} m}{ \_@@_begin_proof:nn{#1}{#2} \bool_set_true:N\l_@@_in_spfblock_bool\_@@_start_list:n{} \group_begin:\stexcommentfont }{ \stex_style_apply: \stex_if_do_html:T{\end{stex_annotate_env}\end{stex_annotate_env}} }{ \emph{\sproofautorefname :}~ }{ \sproofend }{s} \AddToHook{env/sproof/end}{ \bool_if:NT\l_@@_in_spfblock_bool { \group_end:\_@@_end_list: } } \stex_new_stylable_env:nnnnnnn{proof*}{O{}}{ \_@@_begin_proof:nn{#1}{} \bool_set_false:N\l_@@_in_spfblock_bool }{ \stex_style_apply: \stex_if_do_html:T{\end{stex_annotate_env}\end{stex_annotate_env}} }{ \emph{Proof:}~ }{ \sproofend }{s} % \end{macrocode} % \end{environment} % % \begin{environment}{subproof} % \begin{macrocode} \str_set_eq:NN \subproofautorefname \spfstepautorefname \stex_new_stylable_env:nnnnnnn{subproof}{s O{} m}{\par \stex_keys_set:nn{spf}{#2} \_stex_do_for_list: \stex_if_do_html:T { \_@@_html_env:n{subproof} } \seq_map_inline:Nn \l_stex_fors_seq { \stex_debug:nn{definiens}{Adding~definiens~to~##1} \_stex_add_definiens:nn {##1}{\STEXinvisible{proven}} } \IfBooleanTF #1 { \stex_style_apply: \str_if_empty:NF \l_stex_key_id_str { \_@@_number_as_string:N \@currentlabel \str_set:Nx \@currentHref{subproof.\@currentlabel} \_stex_do_id: } \bool_set_false:N \l_@@_in_spfblock_bool \stex_annotate:nn{shtml:prooftitle={}}{#3} }{ \bool_if:NTF \l_@@_in_spfblock_bool { \str_if_empty:NF \l_stex_key_id_str { \_@@_number_as_string:N \@currentlabel \str_set:Nx \@currentHref{subproof.\@currentlabel} \_stex_do_id: } \_@@_start_list:n\_@@_insert_number: \stex_annotate:nn{shtml:prooftitle={}}{#3} \_@@_add_counter: \stex_style_apply: }{ \stex_annotate:nn{shtml:prooftitle={}}{#3} \stex_style_apply: \_stex_do_id: } } \stex_if_do_html:T{ \begin{stex_annotate_env}{shtml:proofbody={}} } \bool_if:NT \l_@@_in_spfblock_bool {\group_begin:\stexcommentfont} }{ \stex_style_apply: \bool_if:NT \l_@@_in_spfblock_bool \_@@_inc_counter: \stex_if_do_html:T{\end{stex_annotate_env}} \bool_if:NT\l_@@_in_spfblock_bool \_@@_end_list: \stex_if_do_html:T{\end{stex_annotate_env}} \aftergroup \_@@_inblock_restore: }{}{}{} \AddToHook{env/subproof/before}{ \bool_if:NT \l_@@_in_spfblock_bool \group_end: } \AddToHook{env/subproof/end}{ \bool_if:NT\l_@@_in_spfblock_bool { \group_end:\_@@_remove_counter: %\_@@_end_list: } } \stex_deactivate_macro:Nn \subproof {sproof~environments} \cs_new_protected:Nn \_@@_inblock_restore: { \bool_if:NT\l_@@_in_spfblock_bool { \group_begin:\stexcommentfont } } % \end{macrocode} % \end{environment} % % \begin{macro}{\spfstep,\conclude,\assumption,\have,\eqstep} % \begin{macrocode} \stex_keys_define:nnnn { spfsteps } { \clist_clear:N \l_stex_key_for_clist \str_clear:N \l_stex_key_name_str \tl_clear:N \l_stex_key_method_tl \tl_clear:N \l_stex_key_term_tl }{ for .clist_set:N = \l_stex_key_for_clist , method .tl_set:N = \l_stex_key_method_tl, term .tl_set:N = \l_stex_key_term_tl, name .str_set_x:N = \l_stex_key_name_str % todo: style=inline }{id,style,title} \newenvironment{spfstepenv}{ \str_set_eq:NN \spfstepenvautorefname \spfstepautorefname }{} \cs_new_protected:Nn \_@@_step_html:nn { \stex_if_do_html:TF{ \exp_args:Ne \stex_annotate:nn{ shtml:spf#1={ \seq_if_empty:NF \l_stex_fors_seq { \seq_use:Nn \l_stex_fors_seq , } } \str_if_empty:NF \l_stex_key_name_str {, shtml:stepname={\l_stex_key_name_str} } }{ \_@@_html: #2 } }{ #2 } } \cs_new_protected:Nn \_@@_make_step_macro:Nnnnn { \NewDocumentCommand #1 {s O{} +m} { \bool_if:NT \l_@@_in_spfblock_bool \group_end: \stex_keys_set:nn{spfsteps}{##2} \str_if_empty:NF \l_stex_key_name_str { \stex_debug:nn{Here:}{Variable~\l_stex_key_name_str} \exp_args:Nne\use:nn{\vardef}{{v\l_stex_key_name_str}[name=\l_stex_key_name_str]{\l_stex_key_name_str}} } \begin{spfstepenv} \str_if_empty:NF \l_stex_key_id_str { \_@@_number_as_string:N \@currentlabel \str_set:Nx \@currentHref{spfstep.\@currentlabel} \_stex_do_id: } \bool_if:NTF \l_@@_in_spfblock_bool { \IfBooleanTF ##1 { \_@@_step_html:nn{#2}{##3} }{ \_@@_step_html:nn{#2}{\_@@_start_list:n{#3} ##3 \_@@_end_list:} #5 } \end{spfstepenv} \group_begin:\stexcommentfont }{ \_@@_step_html:nn{#2}{##3} \end{spfstepenv} } } \stex_deactivate_macro:Nn #1 {sproof~environments} } \_@@_make_step_macro:Nnnnn \assumption {assumption} \_@@_insert_number: {} \_@@_inc_counter: \_@@_make_step_macro:Nnnnn \conclude {conclusion} {$\Rightarrow$} {} {} \_@@_make_step_macro:Nnnnn \spfstep {step} \_@@_insert_number: {} \_@@_inc_counter: \NewDocumentCommand \eqstep {s m}{ \bool_if:NTF \l_@@_in_spfblock_bool { \group_end: \IfBooleanTF #1 { \_@@_step_html:nn{eqstep}{$= #2$} }{ \_@@_step_html:nn{eqstep}{\_@@_start_list:n{$=$} $#2$ \_@@_end_list:} } \group_begin:\stexcommentfont }{ \_@@_step_html:nn{eqstep}{$= #2$} } } \stex_deactivate_macro:Nn \eqstep {sproof~environments} \NewDocumentCommand \yield {+m}{ \stex_annotate:nn{shtml:proofterm={}}{ #1 } } \stex_deactivate_macro:Nn \yield {sproof~environments} \NewDocumentEnvironment{spfblock}{}{ \bool_set_false:N \l_@@_in_spfblock_bool }{ \aftergroup\_@@_inblock_restore: } \stex_deactivate_macro:Nn \spfblock {sproof~environments} \AddToHook{env/spfblock/before}{ \bool_if:NT \l_@@_in_spfblock_bool \group_end: } \newcommand\spfjust[1]{ \stex_annotate:nn{spfjust={}}{ #1 } } \stex_deactivate_macro:Nn \spfjust {sproof~environments} % \end{macrocode} % \end{macro} % % \end{sfragment} % % \begin{sfragment}{Metatheory} % \begin{macrocode} %<@@=stex_meta> \group_begin: \cs_set:Npn \__stex_modules_persist_module: {} \cs_set:Npn \stex_check_term:n #1 {} \cs_set:Npn \_stex_sref_do_aux:n #1 { #1 } \bool_set_false:N \_stex_html_do_output_bool \bool_set_false:N \c_stex_check_terms_bool \stex_uri_resolve:Nn \l_stex_current_ns_uri {http://mathhub.info/sTeX/meta} \stex_module_setup:n{Metatheory} \symdef{of~type}[args=ii,invisible]{#1} \notation{of~type}[colon]{#1 \mathbin{\comp{:}} #2} \symdef{apply}[args=ia,prec=0;\infprec x\infprec]{#1\mathopen{\comp(} #2 \mathclose{\comp)}} \notation{apply}[lambda]{#1\; \argsep{#2}{\;}} \notation{apply}[infixop]{\argsep{#2}{\mathbin{#1}}} \notation{apply}[infixrel]{\argsep{#2}{\mathrel{#1}}} % structures \symdef{module~type}[args=i,op=\mathtt{MOD}] {\mathopen{\comp{\mathtt{MOD}(}}#1\mathclose{\comp{)}}} \symdef{module~type~merge}[args=a,op=\oplus] {\argsep{#1}{\mathbin{\comp{\oplus}}}} \symdef{anonymous~record}[args=a] {\mathopen{\comp{[[}}#1\mathclose{\comp{]]}}} \symdef{record~field}[args=2]{#1\comp{.}#2} \symdecl*{record~type} \symdecl{mathstruct}[name=mathematical~structure,args=a] % TODO \notation{mathstruct}[angle,prec=nobrackets] {\mathopen{\comp\langle} #1 \mathclose{\comp\rangle}} \notation{mathstruct}[parens,prec=nobrackets] {\mathopen{\comp(} #1 \mathclose{\comp)}} % sequences \symdef{ellipses}[ldots]{\ldots} \symdef{sequence~expression}[comma,args=a]{#1} \symdef{sequence~type}[args=1]{#1^{\comp\ast}} \symdef{sequence~map}[args=ia]{ \comp{\mathrm{map}}\mathopen{\comp{(}}#1\mathpunct{\comp{,}} #2\mathclose{\comp{)}} } \iffalse % binder (\forall, \Pi, \lambda etc.) \symdef{pibind}[name=dependent function type,prec=nobrackets, op=(\cdot)\;\to\;\cdot,args=Bi,assoc=pre] {\argmap{#1}{ \mathopen{\comp(} ##1 \mathclose{\comp{)}} }{\mathbin{\comp{\to}}} \mathbin{\comp{\to}} #2} \notation{pibind}[forall]{\comp\forall #1\mathpunct{\comp.} #2} \notation{pibind}[Pi]{\mathop{\comp\prod}\c_math_subscript_token{#1}#2} \symdef{mapbind}[name=lambda,mapsto,prec=nobrackets,op=\mapsto,args=Bi,assoc=pre] { #1 \mathrel{\comp\mapsto} #2} \notation{mapbind}[lambda,prec=nobrackets,op=\lambda] {\comp\lambda #1 \mathpunct{\comp.} #2} \fi \symdecl{bind}[args=Bi,assoc=pre] \notation{bind}[depfun,prec=nobrackets,op=(\cdot)\;\to\;\cdot] {\mathopen{\comp(} #1 \mathclose{\comp{)}\mathbin{\comp{\to}}} #2} \notation{bind}[forall]{\comp\forall #1.\;#2} \notation{bind}[Pi]{\mathop{\comp\prod}\c_math_subscript_token{#1}#2} \symdef{implicit~bind}[args=Bi,assoc=pre]{\mathopen{\comp\{} #1 \mathclose{\comp{\}\c_math_subscript_token I}} #2} \symdecl*{integer~literal} \notation{integer~literal}{\mathbb Z} \symdecl*{ordinal} \notation{ordinal}{\mathtt{Ord}} % propositions \symdef{prop}[name=proposition]{\mathtt{Prop}} \symdef{judgment~holds}[args=i,role=judgment]{\comp\vdash\;#1} % any object \symdef{object}{\mathtt{Obj}} % TODO DELETE \symdef{aseqdots}[args=a,prec=nobrackets] {#1\comp{,\ldots}}%{##1\comp,##2} \symdef{aseqfromto}[args=ai,prec=nobrackets] {#1\comp{,\ldots,}#2}%{##1\comp,##2} \symdef{aseqfromtovia}[args=aii,prec=nobrackets] {#1\comp{,\ldots,}#2\comp{,\ldots,}#3}%{##1\comp,##2} \stex_close_module: \stex_uri_add_module:NNn \l_stex_metatheory_uri \l_stex_current_ns_uri {Metatheory} \global \let \l_stex_metatheory_uri \l_stex_metatheory_uri \global \let \c_stex_default_metatheory \l_stex_metatheory_uri \group_end: % \end{macrocode} % % \end{sfragment} % % % \begin{sfragment}{MMT Interfaces} % \begin{macrocode} %<@@=todo> \cs_new_protected:Npn \MSC #1 {} % \end{macrocode} % \end{sfragment} % % \begin{macro}{\MMTinclude} % \begin{macrocode} \stex_new_stylable_cmd:nnnn{MMTinclude}{m}{ \stex_annotate_invisible:nn{shtml:import={#1}}{} }{} \stex_deactivate_macro:Nn \MMTinclude {module~environments} \stex_every_module:n {\stex_reactivate_macro:N \MMTinclude} % \end{macrocode} % \end{macro} % % \begin{macro}{\MMTrule} % \begin{macrocode} \NewDocumentCommand \MMTrule {m m}{ \tl_if_empty:nTF{#2}{\seq_clear:N \l_tmpa_seq}{ \seq_set_split:Nnn \l_tmpa_seq , {#2} } \int_zero:N \l_tmpa_int \stex_annotate_invisible:n{ $ \stex_annotate:nn{shtml:rule={scala://#1}}{ \_stex_annotate_force_break:n{ \seq_if_empty:NF \l_tmpa_seq { \seq_map_inline:Nn \l_tmpa_seq { \int_incr:N \l_tmpa_int \stex_annotate:nn{ shtml:argmode=i, shtml:arg={\int_use:N \l_tmpa_int} }{ ##1 } } } } }$ } } \stex_deactivate_macro:Nn \MMTrule {module~environments} \stex_every_module:n{\stex_reactivate_macro:N \MMTrule} % \end{macrocode} % \end{macro} % % \begin{environment}{mmtinterface} % \begin{macrocode} \NewDocumentEnvironment { mmtinterface } { O{} m m } { \_stex_module_setup_top_nosig:n { #3 } \str_set_eq:NN \l_@@_mmt_module_str \l_stex_current_module_str \str_clear:N \l_stex_current_module_str \stex_keys_set:nn { smodule }{ #1 } \stex_module_setup:n{ #2 } \str_set_eq:NN \l_@@_stex_module_str \l_stex_current_module_str \stex_debug:nn{mmt}{Interface~\l_@@_stex_module_str^^Jfor~\l_@@_mmt_module_str} \stex_if_do_html:T { \exp_args:Nne \begin{stex_annotate_env} { shtml:theory={\l_stex_current_module_str}, shtml:language={ \l_stex_current_language_str}, shtml:signature={} \tl_if_empty:NF \l_stex_metatheory_uri {, shtml:metatheory={\stex_uri_use:N \l_stex_metatheory_uri} } } \stex_annotate_invisible:n{} \stex_annotate_invisible:nn {shtml:import=\l_@@_mmt_module_str} {} } \stex_module_add_code:x{ \stex_activate_module:n{ \l_@@_mmt_module_str } } \stex_module_add_morphism:nonn {}{\l_@@_mmt_module_str}{import}{} \stex_reactivate_macro:N \mmtdef \stex_smsmode_do: }{ \str_set_eq:NN \l_stex_current_module_str \l_@@_mmt_module_str \stex_close_module: \str_set_eq:NN \l_stex_current_module_str \l_@@_stex_module_str \stex_close_module: \stex_if_do_html:T { \end{stex_annotate_env} } } \stex_sms_allow_env:n{mmtinterface} % \end{macrocode} % \end{environment} % % \begin{macro}{\mmtdef} % \begin{macrocode} \NewDocumentCommand \mmtdef {m O{} m} { \stex_keys_set:nn{symdef}{#2} \str_set:Nx \l_stex_macroname_str { #1 } \str_if_empty:NT \l_stex_key_name_str { \str_set:Nx \l_stex_key_name_str { #1 } } \stex_symdecl_do: \str_set_eq:NN \l_stex_current_module_str \l_@@_mmt_module_str \cs_set_eq:NN \l_@@_old_metagroup_cd \stex_metagroup_do_in:nn \cs_set_protected:Npn \stex_metagroup_do_in:nn ##1 ##2 {##2} \exp_args:Nnx \use:nn {\stex_module_add_symbol:nnnnnnnN}{ {\l_stex_macroname_str} {\l_stex_key_name_str} {\int_use:N \l_stex_get_symbol_arity_int} {\l_stex_get_symbol_args_tl} {} {} {} \stex_invoke_symbol: } \cs_set_eq:NN \stex_metagroup_do_in:nn \l_@@_old_metagroup_cd \str_set_eq:NN \l_stex_current_module_str \l_@@_stex_module_str \str_set_eq:NN \l_stex_get_symbol_mod_str \l_@@_mmt_module_str \str_set_eq:NN \l_stex_get_symbol_name_str \l_stex_key_name_str \stex_notation_parse:n{#3} \_stex_notation_check: \_stex_notation_add: \stex_if_do_html:T{ \_stex_notation_do_html:n{\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str} } \stex_smsmode_do: } \stex_deactivate_macro:Nn \mmtdef {mmtinterface~environments} \stex_sms_allow_escape:N \mmtdef % \end{macrocode} % \end{macro} % % VoLL-KI Annotations % \begin{macrocode} \newcommand\precondition[2]{ \str_clear:N \l_stex_get_symbol_name_str \stex_get_symbol:n{#2} \str_if_empty:NTF \l_stex_get_symbol_name_str{ \errmessage{Unknown~symbol~#2} }{ \str_case:nnTF {#1}{ {remember}{} {understand}{} {analyze}{} {evaluate}{} {apply}{} {create}{} }{ \stex_annotate_invisible:nn{ shtml:preconditionsymbol={\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str}, shtml:preconditiondimension={#1} }{} }{\errmessage{Unknown~cognitive~dimension~#1}} } } \newcommand\objective[2]{ \str_clear:N \l_stex_get_symbol_name_str \stex_get_symbol:n{#2} \str_if_empty:NTF \l_stex_get_symbol_name_str{ \errmessage{Unknown~symbol~#2} }{ \str_case:nnTF {#1}{ {remember}{} {understand}{} {analyze}{} {evaluate}{} {apply}{} {create}{} }{ \stex_annotate_invisible:nn{ shtml:objectivesymbol={\l_stex_get_symbol_mod_str ? \l_stex_get_symbol_name_str}, shtml:objectivedimension={#1} }{} }{\errmessage{Unknown~cognitive~dimension~#1}} } } % \end{macrocode} % % \begin{macrocode} \seq_if_empty:NT \g_stex_current_file { \seq_gset_eq:NN \g_stex_current_file \c_stex_main_file } \_stex_persist_read_now: \_stex_every_file: \cs_new_protected:Nn \_@@_newlabel:n { \exp_args:Ne\_@@_old_newlabel:{\tl_to_str:n{#1}} } \AtBeginDocument{ \iow_now:Nn \@auxout { \ExplSyntaxOn \let\_@@_old_newlabel:\newlabel \let\newlabel\_@@_newlabel:n \ExplSyntaxOff } } % % \end{macrocode} % \end{sfragment} % \end{implementation} \endinput