% \iffalse meta-comment % An Infrastructure for Semantic Macros and Module Scoping % Copyright (c) 2019 Michael Kohlhase, all rights reserved % this file is released under the % LaTeX Project Public License (LPPL) % % The original of this file is in the public repository at % http://github.com/sLaTeX/sTeX/ % % TODO update copyright % %<*driver> \def\bibfolder#1{../../lib/bib/#1} \input{../../doc/stex-docheader} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \title{ \sTeX-Basics % \thanks{Version {\fileversion} (last revised {\filedate})} % } % % \author{Michael Kohlhase, Dennis Müller\\ % FAU Erlangen-Nürnberg\\ % \url{http://kwarc.info/} % } % % \maketitle % %\ifinfulldoc\else % This is the documentation for the \pkg{stex-basics} package. % For a more high-level introduction, % see \href{\basedocurl/manual.pdf}{the \sTeX Manual} or the % \href{\basedocurl/stex.pdf}{full \sTeX documentation}. % \fi % % \begin{documentation}\label{pkg:basics:doc} % % This sub package provides general set up code, auxiliary methods % and abstractions for |xhtml| annotations. % %\ifinfulldoc\else % \input{../../doc/packages/stex-basics} % \fi % % % \section{Macros and Environments}\label{pkg:basics:doc:macros} % % \begin{function}{\sTeX , \stex} % Both print this \stex logo. % \end{function} % % \begin{function}{\stex_debug:nn} % \begin{syntax} % \cs{stex_debug:nn} \Arg{log-prefix} \Arg{message} ^^A \meta{comma list} % \end{syntax} % Logs \meta{message}, if the package option |debug| contains \meta{log-prefix}. % \end{function} % % \subsection{HTML Annotations} % % \begin{function}{\if@latexml} % \LaTeX2e conditional for \latexml % \end{function} % % \begin{function}[pTF]{\latexml_if:} % \LaTeX3 conditionals for \latexml. % \end{function} % % \begin{function}[pTF]{\stex_if_do_html:} % Whether to currently produce any HTML annotations (can be false % in some advanced structuring environments, for example) % \end{function} % % \begin{function}{\stex_suppress_html:n} % Temporarily disables HTML annotations in its argument code % \end{function} % % % We have four macros for annotating generated HTML (via \latexml % or \rustex) with attributes: % % \begin{function}{\stex_annotate:nnn, \stex_annotate_invisible:nnn, % \stex_annotate_invisible:n} % \begin{syntax} \cs{stex_annotate:nnn} \Arg{property} \Arg{resource} \Arg{content} \end{syntax} % Annotates the HTML generated by \meta{content} with\\ % \begin{center} % |property="stex:|\meta{property}|", resource="|\meta{resource}|"|. % \end{center} % % \cs{stex_annotate_invisible:n} adds the attributes\\ % \begin{center} % |stex:visible="false", style="display:none"|. % \end{center} % % \cs{stex_annotate_invisible:nnn} combines the functionality of both. % \end{function} % % \begin{environment}{stex_annotate_env} % \begin{syntax} \cs{begin}|{stex_annotate_env}|\Arg{property}\Arg{resource} % \meta{content} % \cs{end}|{stex_annotate_env}| % \end{syntax} % behaves like \cs{stex_annotate:nnn} \Arg{property} \Arg{resource} % \Arg{content}. % \end{environment} % % \subsection{Babel Languages} % % \begin{variable}{\c_stex_languages_prop,\c_stex_language_abbrevs_prop} % Map language abbreviations to their full babel names and vice versa. % e.g. \cs{c_stex_languages_prop}|{en}| yields |english|, and % \cs{c_stex_language_abbrevs_prop}|{english}| yields |en|. % \end{variable} % % \subsection{Auxiliary Methods} % % \begin{function}{\stex_deactivate_macro:Nn , \stex_reactivate_macro:N} % \begin{syntax}\cs{stex_deactivate_macro:Nn}\meta{cs}\Arg{environments}\end{syntax} % Makes the macro \meta{cs} throw an error, indicating that it % is only allowed in the context of \meta{environments}. % % \cs{stex_reactivate_macro:N}\meta{cs} reactivates it again, i.e. % this happens ideally in the \meta{begin}-code of the associated % environments. % \end{function} % % \begin{function}{\ignorespacesandpars} % ignores white space characters and |\par| control sequences. % Expands tokens in the process. % \end{function} % % \end{documentation} % % \begin{implementation} % % \section{\sTeX-Basics Implementation}\label{pkg:basics:impl} % % \subsection{The \sTeX Document Class} % % The \cls{stex} document class is pretty straight-forward: It largely extends the \cls{standalone} package % and loads the \pkg{stex} package, passing all provided options on to the package. % % \begin{macrocode} %<*cls> %%%%%%%%%%%%% basics.dtx %%%%%%%%%%%%% \RequirePackage{expl3,l3keys2e} \ProvidesExplClass{stex}{2022/05/24}{3.1.0}{sTeX document class} \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{stex}} \ProcessOptions \bool_set_true:N \c_stex_document_class_bool \RequirePackage{stex} \stex_html_backend:TF { \LoadClass{article} }{ \LoadClass[border=1px,varwidth,crop=false]{standalone} \setlength\textwidth{15cm} } \RequirePackage{standalone} \clist_if_empty:NT \c_stex_languages_clist { \seq_get_right:NN \g_stex_currentfile_seq \l_tmpa_str \seq_set_split:NnV \l_tmpa_seq . \l_tmpa_str \seq_pop_right:NN \l_tmpa_seq \l_tmpa_str % .tex \exp_args:No \str_if_eq:nnF \l_tmpa_str {tex} { \exp_args:No \str_if_eq:nnF \l_tmpa_str {dtx} { \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_tmpa_str \prop_if_in:NoT \c_stex_languages_prop \l_tmpa_str { \stex_debug:nn{language} {Language~\l_tmpa_str~ inferred~from~file~name} \exp_args:NNo \stex_set_language:Nn \l_tmpa_str \l_tmpa_str } } } % % \end{macrocode} % % \subsection{Preliminaries} % % \begin{macrocode} %<*package> %%%%%%%%%%%%% basics.dtx %%%%%%%%%%%%% \RequirePackage{expl3,l3keys2e,ltxcmds} \ProvidesExplPackage{stex}{2022/05/24}{3.1.0}{sTeX package} \bool_if_exist:NF \c_stex_document_class_bool { \bool_set_false:N \c_stex_document_class_bool \RequirePackage{standalone} } \message{^^J*~This~is~sTeX~version~3.1.0~*^^J} %\RequirePackage{morewrites} %\RequirePackage{amsmath} % \end{macrocode} % % Package options: % % \begin{macrocode} \keys_define:nn { stex } { debug .clist_set: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 , image .bool_set:N = \c_tikzinput_image_bool, unknown .code:n = {} } \ProcessKeysOptions { stex } % \end{macrocode} % % \begin{macro}{\stex,\sTeX} % The \sTeX logo: % % \begin{macrocode} \RequirePackage{stex-logo} % externalized for backwards-compatibility reasons % \end{macrocode} % \end{macro} % % % \subsection{Messages and logging} % % \begin{macrocode} %<@@=stex_log> % \end{macrocode} % % Warnings and error messages % % \begin{macrocode} \msg_new:nnn{stex}{error/unknownlanguage}{ Unknown~language:~#1 } \msg_new:nnn{stex}{warning/nomathhub}{ MATHHUB~system~variable~not~found~and~no~ \detokenize{\mathhub}-value~set! } \msg_new:nnn{stex}{error/deactivated-macro}{ The~\detokenize{#1}~command~is~only~allowed~in~#2! } % \end{macrocode} % % \begin{macro}{\stex_debug:nn} % % A simple macro issuing package messages with subpath. % % \begin{macrocode} \cs_new_protected:Nn \stex_debug:nn { \clist_if_in:NnTF \c_stex_debug_clist { all } { \msg_set:nnn{stex}{debug / #1}{ \\Debug~#1:~#2\\ } \msg_none:nn{stex}{debug / #1} }{ \clist_if_in:NnT \c_stex_debug_clist { #1 } { \msg_set:nnn{stex}{debug / #1}{ \\Debug~#1:~#2\\ } \msg_none:nn{stex}{debug / #1} } } } % \end{macrocode} % \end{macro} % % Redirecting messages: % % \begin{macrocode} \clist_if_in:NnTF \c_stex_debug_clist {all} { \msg_redirect_module:nnn{ stex }{ none }{ term } }{ \clist_map_inline:Nn \c_stex_debug_clist { \msg_redirect_name:nnn{ stex }{ debug / ##1 }{ term } } } \stex_debug:nn{log}{debug~mode~on} % \end{macrocode} % % % \subsection{HTML Annotations} % \begin{macrocode} %<@@=stex_annotate> % \end{macrocode} % % \begin{macrocode} % \end{macrocode} % % \begin{variable}{\l_stex_html_arg_tl, \c_stex_html_emptyarg_tl} % % Used by annotation macros to ensure that the HTML output to annotate % is not empty. % % \begin{macrocode} \tl_new:N \l_stex_html_arg_tl % \end{macrocode} % \end{variable} % % \begin{macro}{\_stex_html_checkempty:n} % \begin{macrocode} \cs_new_protected:Nn \_stex_html_checkempty:n { \tl_set:Nn \l_stex_html_arg_tl { #1 } \tl_if_empty:NT \l_stex_html_arg_tl { \tl_set_eq:NN \l_stex_html_arg_tl \c_stex_html_emptyarg_tl } } % \end{macrocode} % \end{macro} % % \begin{macro}[pTF]{\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} % Whether to (locally) produce HTML output % \begin{macrocode} \cs_new_protected:Nn \stex_suppress_html:n { \exp_args:Nne \use: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} % % % \begin{environment}{stex_annotate_env} % \begin{macro}{\stex_annotate:nnn, \stex_annotate_invisible:n, % \stex_annotate_invisible:nnn} % % We define four macros for introducing attributes in the HTML % output. The definitions depend on the ``backend'' used % (\latexml, \rustex, \texttt{pdflatex}). % % The \texttt{pdflatex}-macros largely do nothing; the % \rustex-implementations are pretty clear in what they do, % the \latexml-implementations resort to perl bindings. % % \begin{macrocode} \tl_if_exist:NF\stex@backend{ \ifcsname if@rustex\endcsname \def\stex@backend{rustex} \else \ifcsname if@latexml\endcsname \def\stex@backend{latexml} \else \def\stex@backend{pdflatex} \fi \fi } \input{stex-backend-\stex@backend.cfg} \newif\ifstexhtml \stex_html_backend:TF\stexhtmltrue\stexhtmlfalse % \end{macrocode} % \end{macro} % \end{environment} % % \subsection{Babel Languages} % \begin{macrocode} %<@@=stex_language> % \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} % % we use the |lang|-package option to load the corresponding % babel languages: % % \begin{macrocode} \cs_new_protected:Nn \stex_set_language:Nn { \str_set:Nx \l_tmpa_str {#2} \prop_get:NoNT \c_stex_languages_prop \l_tmpa_str #1 { \ifx\@onlypreamble\@notprerr \ltx@ifpackageloaded{babel}{ \exp_args:No \selectlanguage #1 }{} \else \exp_args:No \str_if_eq:nnTF #1 {turkish} { \RequirePackage[#1,shorthands=:!]{babel} }{ \RequirePackage[#1]{babel} } \fi } } \clist_if_empty:NF \c_stex_languages_clist { \bool_set_false:N \l_tmpa_bool \clist_clear:N \l_tmpa_clist \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_tmpa_bool } \prop_get:NoNTF \c_stex_languages_prop \l_tmpa_str \l_tmpa_str { \clist_put_right:No \l_tmpa_clist \l_tmpa_str } { \msg_error:nnx{stex}{error/unknownlanguage}{\l_tmpa_str} } } \stex_debug:nn{lang} {Languages:~\clist_use:Nn \l_tmpa_clist {,~} } \bool_if:NTF \l_tmpa_bool { \RequirePackage[\clist_use:Nn \l_tmpa_clist,,shorthands=:!]{babel} }{ \RequirePackage[\clist_use:Nn \l_tmpa_clist,]{babel} } } \AtBeginDocument{ \stex_html_backend:T { \seq_get_right:NN \g_stex_currentfile_seq \l_tmpa_str \seq_set_split:NnV \l_tmpa_seq . \l_tmpa_str \seq_pop_right:NN \l_tmpa_seq \l_tmpa_str % .tex \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_tmpa_str \stex_debug:nn{basics} {Language~\l_tmpa_str~ inferred~from~file~name} \stex_annotate_invisible:nnn{language}{ \l_tmpa_str }{} } } } % \end{macrocode} % % \subsection{Persistence} % % \begin{macrocode} %<@@=stex_persist> \bool_if:NTF \c_stex_persist_mode_bool { \def \stex_persist:n #1 {} \def \stex_persist:x #1 {} }{ \bool_if:NTF \c_stex_persist_write_mode_bool { \iow_new:N \c_@@_iow \iow_open:Nn \c_@@_iow{\jobname.sms} \AtEndDocument{ \iow_close:N \c_@@_iow } \cs_new_protected:Nn \stex_persist:n { \tl_set:Nn \l_tmpa_tl { #1 } \regex_replace_all:nnN { \cP\# } { \cO\# } \l_tmpa_tl \regex_replace_all:nnN { \ } { \~ } \l_tmpa_tl \exp_args:NNo \iow_now:Nn \c_@@_iow \l_tmpa_tl } \cs_generate_variant:Nn \stex_persist:n {x} }{ \def \stex_persist:n #1 {} \def \stex_persist:x #1 {} } } % \end{macrocode} % % \subsection{Auxiliary Methods} % % \begin{macro}{\stex_deactivate_macro:Nn} % \begin{macrocode} \cs_new_protected:Nn \stex_deactivate_macro:Nn { \exp_after:wN\let\csname \detokenize{#1} - orig\endcsname#1 \def#1{ \msg_error:nnnn{stex}{error/deactivated-macro}{\detokenize{#1}}{#2} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\stex_reactivate_macro:N} % \begin{macrocode} \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}{\ignorespacesandpars} % \begin{macrocode} \protected\def\ignorespacesandpars{ \begingroup\catcode13=10\relax \@ifnextchar\par{ \endgroup\expandafter\ignorespacesandpars\@gobble }{ \endgroup } } \cs_new_protected:Nn \stex_copy_control_sequence:NNN { \tl_set:Nx \_tmp_args_tl {\cs_argument_spec:N #2} \exp_args:NNo \tl_remove_all:Nn \_tmp_args_tl \c_hash_str \int_set:Nn \l_tmpa_int {\tl_count:N \_tmp_args_tl} \tl_clear:N \_tmp_args_tl \int_step_inline:nn \l_tmpa_int { \tl_put_right:Nx \_tmp_args_tl {{\exp_not:n{####}\exp_not:n{##1}}} } \tl_set:Nn #3 {\cs_generate_from_arg_count:NNnn #1 \cs_set:Npn} \tl_put_right:Nx #3 { {\int_use:N \l_tmpa_int}{ \exp_after:wN\exp_after:wN\exp_after:wN \exp_not:n \exp_after:wN\exp_after:wN\exp_after:wN { \exp_after:wN #2 \_tmp_args_tl } }} } \cs_generate_variant:Nn \stex_copy_control_sequence:NNN {cNN} \cs_generate_variant:Nn \stex_copy_control_sequence:NNN {NcN} \cs_generate_variant:Nn \stex_copy_control_sequence:NNN {ccN} \cs_new_protected:Nn \stex_copy_control_sequence_ii:NNN { \tl_set:Nx \_tmp_args_tl {\cs_argument_spec:N #2} \exp_args:NNo \tl_remove_all:Nn \_tmp_args_tl \c_hash_str \int_set:Nn \l_tmpa_int {\tl_count:N \_tmp_args_tl} \tl_clear:N \_tmp_args_tl \int_step_inline:nn \l_tmpa_int { \tl_put_right:Nx \_tmp_args_tl {{\exp_not:n{########}\exp_not:n{##1}}} } \edef \_tmp_args_tl { \exp_after:wN\exp_after:wN\exp_after:wN \exp_not:n \exp_after:wN\exp_after:wN\exp_after:wN { \exp_after:wN #2 \_tmp_args_tl } } \exp_after:wN \def \exp_after:wN \_tmp_args_tl \exp_after:wN ##\exp_after:wN 1 \exp_after:wN ##\exp_after:wN 2 \exp_after:wN { \_tmp_args_tl } \edef \_tmp_args_tl { \exp_after:wN \exp_not:n \exp_after:wN { \_tmp_args_tl {####1}{####2} } } \tl_set:Nn #3 {\cs_generate_from_arg_count:NNnn #1 \cs_set:Npn} \tl_put_right:Nx #3 { {\int_use:N \l_tmpa_int}{ \exp_after:wN\exp_not:n\exp_after:wN{\_tmp_args_tl} }} } \cs_generate_variant:Nn \stex_copy_control_sequence_ii:NNN {cNN} \cs_generate_variant:Nn \stex_copy_control_sequence_ii:NNN {NcN} \cs_generate_variant:Nn \stex_copy_control_sequence_ii:NNN {ccN} % \end{macrocode} % \end{macro} % % \begin{macro}{\MMTrule} % \begin{macrocode} \NewDocumentCommand \MMTrule {m m}{ \seq_set_split:Nnn \l_tmpa_seq , {#2} \int_zero:N \l_tmpa_int \stex_annotate_invisible:nnn{mmtrule}{scala://#1}{ \seq_if_empty:NF \l_tmpa_seq { $\seq_map_inline:Nn \l_tmpa_seq { \int_incr:N \l_tmpa_int \stex_annotate:nnn{arg}{i\int_use:N \l_tmpa_int}{##1} }$ } } } \NewDocumentCommand \MMTinclude {m}{ \stex_annotate_invisible:nnn{import}{#1}{} } \tl_new:N \g_stex_document_title \cs_new_protected:Npn \STEXtitle #1 { \tl_if_empty:NT \g_stex_document_title { \tl_gset:Nn \g_stex_document_title { #1 } } } \cs_new_protected:Nn \stex_document_title:n { \tl_if_empty:NT \g_stex_document_title { \tl_gset:Nn \g_stex_document_title { #1 } \stex_annotate_invisible:n{\noindent \stex_annotate:nnn{doctitle}{}{ #1 } \par} } } \AtBeginDocument { \let \STEXtitle \stex_document_title:n \tl_if_empty:NF \g_stex_document_title { \stex_annotate_invisible:n{\noindent \stex_annotate:nnn{doctitle}{}{ \g_stex_document_title } \par} } \let\_stex_maketitle:\maketitle \def\maketitle{ \tl_if_empty:NF \@title { \exp_args:No \stex_document_title:n \@title } \_stex_maketitle: } } \cs_new_protected:Nn \stex_par: { \mode_if_vertical:F{ \if@minipage\else\if@nobreak\else\par\fi\fi } } % % \end{macrocode} % \end{macro} % % \end{implementation} % \ifinfulldoc\else\printbibliography\fi % % \PrintIndex