% \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>
\providecommand\bibfolder{../../lib/bib}
\input{../../doc/stex-docheader}

\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \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/02/26}{3.0.1}{sTeX document class}
\LoadClass[border=1px,varwidth]{standalone}
\setlength\textwidth{15cm}

\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{stex}}
\ProcessOptions

\RequirePackage{stex}
%</cls>
%    \end{macrocode}
%
% \subsection{Preliminaries}
%
%    \begin{macrocode}
%<*package>

%%%%%%%%%%%%%   basics.dtx   %%%%%%%%%%%%%

\RequirePackage{expl3,l3keys2e,ltxcmds}
\ProvidesExplPackage{stex}{2022/02/26}{3.0.1}{sTeX package}

%\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 ,
  sms       .bool_set:N   = \c_stex_persist_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}
\protected\def\stex{%
  \@ifundefined{texorpdfstring}%
  {\let\texorpdfstring\@firstoftwo}%
  {}%
  \texorpdfstring{\raisebox{-.5ex}S\kern-.5ex\TeX}{sTeX}\xspace%
}
\def\sTeX{\stex}
%    \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 } {
    \exp_args:Nnnx\msg_set:nnn{stex}{debug / #1}{
      \\Debug~#1:~#2\\
    }
    \msg_none:nn{stex}{debug / #1}
  }{
    \clist_if_in:NnT \c_stex_debug_clist { #1 } {
      \exp_args:Nnnx\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>
\RequirePackage{rustex}
%    \end{macrocode}
%
% We add the namespace abbreviation |ns:stex="http://kwarc.info/ns/sTeX"| to \rustex:
%
%    \begin{macrocode}
\rustex_add_Namespace:nn{stex}{http://kwarc.info/ns/sTeX}
%    \end{macrocode}
%
% Conditionals for \latexml:
%
% \begin{macro}{\if@latexml}
%    \begin{macrocode}
\ifcsname if@latexml\endcsname\else
    \expandafter\newif\csname if@latexml\endcsname\@latexmlfalse
\fi
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF]{\latexml_if:}
%    \begin{macrocode}
\prg_new_conditional:Nnn \latexml_if: {p, T, F, TF} {
  \if@latexml
    \prg_return_true:
  \else:
    \prg_return_false:
  \fi:
}
%    \end{macrocode}
% \end{macro}
%
% \begin{variable}{\l_@@_arg_tl, \c_@@_emptyarg_tl}
%
% Used by annotation macros to ensure that the HTML output to annotate
% is not empty.
%
%    \begin{macrocode}
\tl_new:N \l_@@_arg_tl
\tl_const:Nx \c_@@_emptyarg_tl {
  \rustex_if:TF {
    \rustex_direct_HTML:n { \c_ampersand_str lrm; }
  }{~}
}
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\_@@_checkempty:n}
%    \begin{macrocode}
\cs_new_protected:Nn \_@@_checkempty:n {
  \tl_set:Nn \l_@@_arg_tl { #1 }
  \tl_if_empty:NT \l_@@_arg_tl {
    \tl_set_eq:NN \l_@@_arg_tl \c_@@_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}
\rustex_if:TF{
  \cs_new_protected:Nn \stex_annotate:nnn {
    \_@@_checkempty:n { #3 }
    \rustex_annotate_HTML:nn {
      property="stex:#1" ~
      resource="#2"
    } {
      \mode_if_vertical:TF{
        \tl_use:N \l_@@_arg_tl\par
      }{
        \tl_use:N \l_@@_arg_tl
      }
    }
  }
  \cs_new_protected:Nn \stex_annotate_invisible:n {
    \_@@_checkempty:n { #1 }
    \rustex_annotate_HTML:nn {
      stex:visible="false" ~
      style:display="none"
    } {
      \mode_if_vertical:TF{
        \tl_use:N \l_@@_arg_tl\par
      }{
        \tl_use:N \l_@@_arg_tl
      }
    }
  }
  \cs_new_protected:Nn \stex_annotate_invisible:nnn {
    \_@@_checkempty:n { #3 }
    \rustex_annotate_HTML:nn {
      property="stex:#1" ~
      resource="#2" ~
      stex:visible="false" ~
      style:display="none"
    } {
      \mode_if_vertical:TF{
        \tl_use:N \l_@@_arg_tl\par
      }{
        \tl_use:N \l_@@_arg_tl
      }
    }
  }
  \NewDocumentEnvironment{stex_annotate_env} { m m } {
    \par
    \rustex_annotate_HTML_begin:n {
      property="stex:#1" ~
      resource="#2"
    }
  }{
    \par\rustex_annotate_HTML_end:
  }
}{
  \latexml_if:TF {
    \cs_new_protected:Nn \stex_annotate:nnn {
      \_@@_checkempty:n { #3 }
      \mode_if_math:TF {
        \cs:w latexml@annotate@math\cs_end:{#1}{#2}{
          \tl_use:N \l_@@_arg_tl
        }
      }{
        \cs:w latexml@annotate@text\cs_end:{#1}{#2}{
          \tl_use:N \l_@@_arg_tl
        }
      }
    }
    \cs_new_protected:Nn \stex_annotate_invisible:n {
      \_@@_checkempty:n { #1 }
      \mode_if_math:TF {
        \cs:w latexml@invisible@math\cs_end:{
          \tl_use:N \l_@@_arg_tl
        }
      } {
        \cs:w latexml@invisible@text\cs_end:{
          \tl_use:N \l_@@_arg_tl
        }
      }
    }
    \cs_new_protected:Nn \stex_annotate_invisible:nnn {
      \_@@_checkempty:n { #3 }
      \cs:w latexml@annotate@invisible\cs_end:{#1}{#2}{
        \tl_use:N \l_@@_arg_tl
      }
    }
    \NewDocumentEnvironment{stex_annotate_env} { m m } {
      \par\begin{latexml@annotateenv}{#1}{#2}
    }{
      \par\end{latexml@annotateenv}
    }
  }{
    \cs_new_protected:Nn \stex_annotate:nnn {#3}
    \cs_new_protected:Nn \stex_annotate_invisible:n {}
    \cs_new_protected:Nn \stex_annotate_invisible:nnn {}
    \NewDocumentEnvironment{stex_annotate_env} { m m } {}{}
  }
}
%    \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}
\prop_const_from_keyval:Nn \c_stex_languages_prop {
  en = english ,
  de = ngerman ,
  ar = arabic ,
  bg = bulgarian ,
  ru = russian ,
  fi = finnish ,
  ro = romanian ,
  tr = turkish ,
  fr = french
}

\prop_const_from_keyval:Nn \c_stex_language_abbrevs_prop {
  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}
\clist_if_empty:NF \c_stex_languages_clist {
  \clist_clear:N \l_tmpa_clist
  \clist_map_inline:Nn \c_stex_languages_clist {
    \prop_get:NnNTF \c_stex_languages_prop { #1 } \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 {,~} }
  \RequirePackage[\clist_use:Nn \l_tmpa_clist,]{babel}
}
%    \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}{#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
  }
}
%</package>
%    \end{macrocode}
% \end{macro}
%
% \end{implementation}
%
% \PrintIndex
