% \iffalse meta-comment % % Copyright (C) 2019-2025 by Pablo González L % % This work may be distributed and/or modified under the conditions of the % LaTeX Project Public License, either version 1.3c of this license or (at % your option) any later version. The latest version of this license is in % % https://www.latex-project.org/lppl.txt % % and version 1.3c or later is part of all distributions of LaTeX version % 2005/12/01 or later. % % This work is "maintained" (as per the LPPL maintenance status) % by Pablo González Luengo. % % This work consists of the files scontents.dtx and % scontents.ins, % and the derived files scontents.sty, % scontents.tex, % t-scontents.mkiv and % scontents-code.tex. % %<*driver> \documentclass[full]{l3doc} % imakeidx also opens a write stream for the .idx file, and that conflicts % with the one opened by l3doc. Here we close that write stream: \makeatletter \immediate\closeout\@indexfile \makeatother % and later we will copy the write stream opened by imakeidx into \@indexfile % so that entries written to both streams end up in the same file. \usepackage[english]{babel} \usepackage[top=0.5in,bottom=0.3in,left=2in,right=0.7in,footskip=0.2in,headheight=1cm,headsep=0.27cm]{geometry} \usepackage[llscaled=0.95]{libertine} % need by setup-texlive-action@v3 \usepackage[osf,nomath,mono=false,ScaleSF=0.95,ScaleRM=0.95]{libertinus-otf} % Set Monospace font, fix 'quotes' in verbatim \usepackage{sourcecodepro} \defaultfontfeatures[\ttfamily] { Numbers = OldStyle, Scale = 0.80, Extension = .otf, } \setmonofont[ UprightFont = *-Regular, ItalicFont = *-RegularIt, BoldFont = *-Semibold, BoldItalicFont = *-SemiboldIt, RawFeature = {+zero,+ss06}]{SourceCodePro} \newfontfamily\mysourcecodeprolight{SourceCodePro-Regular.otf}[ Scale = 0.80,FakeStretch =0.75, FontFace = {m}{it}{Font =SourceCodePro-RegularIt.otf,Color=FF0000}] \RenewDocumentCommand{\MacroLongFont}{} { \mysourcecodeprolight\small } % The character of visible space is now taken from Latin Modern Mono % to prevent fonts in T1. The original definition for xetex/luatex is % \def\verbvisiblespace{\usefont{OT1}{cmtt}{m}{n}\asciispace} \def\verbvisiblespace{{\fontfamily{lmtt}\selectfont\char"2423}} \usepackage{unicode-math} % Unicode-math changes the position of the glyphs, so the position 26A is now % a letter `j'. The doc package ensures that mathcode and the | actually prints % a j inside docstrip guards. This changes the mathcode of | to 07C: \makeatletter \def\mod@math@codes{\mathcode`\|="207C \mathcode`\&="2026 % \mathcode`\-="702D \mathcode`\+="702B \mathcode`\:="703A \mathcode`\=="703D } \makeatother \setmathfont[Scale = 0.95]{latinmodern-math.otf} \usepackage{fontawesome5} \newfontfamily\fetamontotf{ffmw10.otf}[ Scale = 0.95,% RawFeature = {+latn,+rand,+kern,+size},% FontFace = {b}{n}{ffmw10.otf},% fix replace font ] \usepackage[svgnames]{xcolor} \usepackage[sf,bf,compact,medium,pagestyles]{titlesec} \usepackage{lastpage,microtype,attachfile2} \usepackage{adjustbox,multicol,listings,accsupp,titletoc} \usepackage{imakeidx} \usepackage{scontents} % main \usepackage[contents]{colordoc} % \show\docCodelineNo \def\textnew#1{\color{color-def}#1\/} \def\AltMacroFont{\fontencoding\encodingdefault \fontfamily\ttdefault \fontseries\mddefault \fontshape\updefault \small }% % Patching colordoc.sty to work with l3doc.cls \ExplSyntaxOn \cs_new_eq:cN { liii@xmacro@code } \__codedoc_xmacro_code:n \ExplSyntaxOff \begingroup \makeatletter \catcode`\[\@ne\catcode`\]\tw@ \@makebracesactive \gdef{[\@openingbrace[\char'173]] \gdef}[\@closingbrace[\char'175]] \catcode`\|\z@\catcode`\%12 \catcode`\ \active\catcode`\\\active |gdef|xmacro@code#1% \end{macrocode}[|liii@xmacro@code[#1]|end[macrocode]] |catcode`| 12|gdef|sxmacro@code#1% \end{macrocode*}[|liii@xmacro@code[#1]|end[macrocode*]] |endgroup % Patching colordoc.sty to work with doc v3 (TeX Live 2022 & lualatex-dev) \usepackage{etoolbox} \makeatletter \@ifpackagelater{doc}{2022-06-01}% {\patchcmd\macro@finish {\ifnot@excluded % \if \edef\@tempa{\noexpand\SpecialIndex{\bslash\macro@namepart}}% \@tempa \fi}% {\maybe@index@macro \macro@namepart} {}{\FAILED}% \let\default@color\current@color }% {} \makeatother \EnableCrossrefs % \PageIndex % \CodelineIndex undoes what \PageIndex does % \CodelineIndex tries to open another write stream for the index file. We don't % want that, so we temporarily make \makeindex a no-op: \let\ORGmakeindex\makeindex \def\makeindex{} \CodelineIndex \let\makeindex\ORGmakeindex \DoNotIndex{\ , \1,\^} \expandafter\DoNotIndex\expandafter{\string\{} \expandafter\DoNotIndex\expandafter{\string\}} \expandafter\DoNotIndex\expandafter{\string\begin} \newcommand{\HP}[1]{\emph{\hyperpage{#1}}\normalsize} \ExplSyntaxOn \cs_new_protected:Npn \StartImplementation { \bool_set_true:N \l__codedoc_in_implementation_bool } \bool_set_false:N \l__codedoc_in_implementation_bool \cs_new_protected:Npn \MYSortIndex #1 #2 { \bool_if:NTF \l__codedoc_in_implementation_bool { \index{#1\actualchar#2|HP} } { \index[userdoc]{#1\actualchar#2|HP} } } \ExplSyntaxOff \indexsetup{level=\section,firstpagestyle=myheader,othercode=\pagestyle{myheader}} \makeindex[name=userdoc,options={-q -s gind.ist},columnsep=15pt,title={Index of Documentation}] \makeindex[options={-q -s gind.ist},columnsep=15pt,title={Index of Implementation}] % Now, after imakeidx opens the write stream for the index file, we copy % the reference to \@indexfile: \makeatletter \expandafter\let\expandafter\@indexfile\csname \jobname @idxfile\endcsname \makeatother \setlength{\parindent}{0pt} % Colors \definecolor{optcolor}{rgb}{0.281,0.275,0.485} \definecolor{pkgcolor}{rgb}{0,0.5,0.5} \definecolor{araracolor}{rgb}{0, 0.72, 0.28} \definecolor{linkcolor}{rgb}{0.04,0.38,0.04} \definecolor{rulecolor}{rgb}{0.96,0.96,0.96} % Only for arara... I like arara :) \usepackage[scale=0.85]{comfortaa} \newcommand{\araratext}[1]{{\small\normalfont\comfortaa\color{araracolor}\bfseries#1}} \newcommand*\arara{\araratext{ar\kern-.03emar\kern-.03ema}} % User level commands \ExplSyntaxOn % Logo with fetamont font \NewDocumentCommand \pkglogo {} { \group_begin: \fetamontotf{\textcolor{pkgcolor}{s}\textcolor{OrangeRed}{content}\textcolor{pkgcolor}{s}} \group_end: } % Custom \meta[...]{...}, \marg[...]{...} and \oarg[...]{...} with color \NewDocumentCommand \mymeta {O{}m} { \userdoc_meta_generic:Nnn \userdoc_meta:n { #1 } { #2 } } \NewDocumentCommand \mymarg {O{}m} { \userdoc_meta_generic:Nnn \userdoc_marg:n { #1 } { #2 } } \NewDocumentCommand \myoarg {O{}m} { \userdoc_meta_generic:Nnn \userdoc_oarg:n { #1 } { #2 } } % Variables and keys \tl_new:N \l_userdoc_meta_font_tl \keys_define:nn { userdoc / mymeta } { type .choice:, type / tt .code:n = \tl_set:Nn \l_userdoc_meta_font_tl { \ttfamily }, type / rm .code:n = \tl_set:Nn \l_userdoc_meta_font_tl { \rmfamily }, type .initial:n = tt, cf .tl_set:N = \l_userdoc_meta_color_tl, cf .initial:n = optcolor, ac .tl_set:N = \l_userdoc_meta_anglecolor_tl, ac .initial:n = lightgray, sbc .tl_set:N = \l_userdoc_meta_brackcolor_tl, sbc .initial:n = gray, cbc .tl_set:N = \l_userdoc_meta_bracecolor_tl, cbc .initial:n = gray, } % Internal commands \cs_new_protected:Npn \userdoc_meta_generic:Nnn #1 #2 #3 { \group_begin: \keys_set:nn { userdoc / mymeta } { #2 } \color{ \l_userdoc_meta_color_tl } \l_userdoc_meta_font_tl #1 { #3 } % #1 is \userdoc_meta:n, \userdoc_marg:n or \userdoc_oarg:n \group_end: } \cs_new_protected:Npn \userdoc_meta:n #1 { \userdoc_meta_angle:n { \textlangle } \userdoc_meta_meta:n { #1 } \userdoc_meta_angle:n { \textrangle } } \cs_new_protected:Npn \userdoc_marg:n #1 { \userdoc_meta_brace:n { \textbraceleft } \userdoc_meta:n { #1 } \userdoc_meta_brace:n { \textbraceright } } \cs_new_protected:Npn \userdoc_oarg:n #1 { \userdoc_meta_brack:n { [ } \userdoc_meta:n { #1 } \userdoc_meta_brack:n { ] } } \cs_new_protected:Npn \userdoc_meta_meta:n #1 { \textnormal{\textit{#1}} } \cs_new_protected:Npn \userdoc_meta_angle:n #1 { \group_begin: \fontfamily{lmr}\selectfont \textcolor{\l_userdoc_meta_anglecolor_tl}{#1} \group_end: } \cs_new_protected:Npn \userdoc_meta_brace:n #1 { \group_begin: \color{\l_userdoc_meta_bracecolor_tl} #1 \group_end: } \cs_new_protected:Npn \userdoc_meta_brack:n #1 { \textcolor{\l_userdoc_meta_brackcolor_tl}{#1} } % \envexamp{m} \newsavebox{\boxexaenv} \NewDocumentCommand \envexamp {m} { \begin{lrbox}{\boxexaenv}% \begin{minipage}[t]{\marginparwidth}% \raggedright\ttfamily\small \textcolor{gray}{\textbackslash begin\{\textcolor{pkgcolor}{{#1}}\}\myoarg [type=tt,sbc=gray,ac=lightgray,cf=optcolor]{key \textnormal{\textcolor{gray}{=}} val}}\par% \hspace{0.5cm}\mymeta[type=tt,ac=lightgray,cf=gray]{body ~ env}\par% \textcolor{gray}{\textbackslash end\{{\textcolor{pkgcolor}{{#1}}}\}}\par \end{minipage}% \end{lrbox}% \usebox{\boxexaenv} } \NewDocumentCommand \envexaplain {O{} m O{end}} { \begin{lrbox}{\boxexaenv}% \begin{minipage}[t]{\marginparwidth}% \raggedright\ttfamily\small \textcolor{pkgcolor}{{\textbackslash#1#2}}\myoarg [type=tt,sbc=gray,ac=lightgray,cf=optcolor]{key \textnormal{\textcolor{gray}{=}} val}\par% \hspace{0.5cm}\mymeta[type=tt,ac=lightgray,cf=gray]{body ~ env}\par% \textcolor{pkgcolor}{{\textbackslash #3#2}}\par \end{minipage}% \end{lrbox}% \usebox{\boxexaenv} } % \cmdexamp{s m o m o} \DeclareDocumentCommand \cmdexamp {o m o m o} { \group_begin: \small\ttfamily \textcolor{pkgcolor}{\textbackslash#2} \IfValueT{#1}{ \textcolor{MediumOrchid}{#1} } \IfValueT{#3}{ \myoarg[type=tt,sbc=gray,ac=lightgray,cf=optcolor]{#3} } \IfValueTF{#5} { \mymeta[ac=gray,type=tt,cf=MediumOrchid]{#5}% \mymeta[type=tt,ac=gray,cf=optcolor]{#4} \mymeta[ac=gray,type=tt,cf=MediumOrchid]{#5}% } { \mymarg[type=tt,cbc=gray,ac=lightgray,cf=optcolor]{#4} } \par \group_end: } % \keyexamp*{m m m} \NewDocumentCommand \keyexamp{s m m m } { \adjustbox{outer=-\marginparsep}{\textcolor{optcolor}{\small\ttfamily{#2}}} \IfBooleanTF{#1} { \hphantom{\textcolor{white}{\,\bfseries\texttt{=}}\,{}} \mymeta[type=tt,cbc=gray,ac=lightgray,cf=lightgray]{\small{#3}} } { \textcolor{gray}{\,\bfseries\texttt{=}}\,{} \mymarg[type=tt,cbc=gray,ac=lightgray,cf=optcolor]{\small{#3}} } \hfill\textcolor{gray}{\small\textsf{default}:~\emph{#4}}\par% \MYSortIndex{Keys}{Keys ~ provide ~ by ~ \pkglogo :>\texttt{#2}} } % \mykey{m} \NewDocumentCommand \mykey { m } { \textcolor{optcolor}{\texttt{#1}} \MYSortIndex{Keys}{Keys ~ provide ~ by ~\pkglogo :>\texttt{#1}}% } % \mypkg{sm} \NewDocumentCommand \mypkg {sm} { \group_begin: \IfBooleanTF{#1} { \pkglogo \MYSortIndex{packages}{Packages:>\texttt{#2}} } { \textcolor{OrangeRed}{\textsf{#2}} \MYSortIndex{packages}{Packages:>\texttt{#2}}% } \group_end: } % \myenv{sm} \NewDocumentCommand \myenv {sm} { \IfBooleanTF{#1} { \textcolor{pkgcolor}{\ttfamily{#2}}% \MYSortIndex{environment}{Environments ~ provide ~ by ~\pkglogo :>\texttt{#2}} } { \textcolor{optcolor}{\ttfamily{#2}}% \MYSortIndex{environment}{Environments:>\texttt{#2}} } } % \ics{sm} \NewDocumentCommand \ics {sm} { \IfBooleanTF{#1} { \tl_set:Nn \l_tmpa_tl { #2 } \regex_replace_once:nnN { (\*) } { \c{textcolor}\cB\{MediumOrchid\cE\}\cB\{\1\cE\} } \l_tmpa_tl \textcolor{pkgcolor}{\ttfamily\textbackslash{\tl_use:N \l_tmpa_tl}} \MYSortIndex{Commands}{ Commands ~ provide ~ by ~ \pkglogo :>\texttt{\textbackslash#2}} } { \textcolor{darkgray}{\ttfamily\textbackslash{#2}} \MYSortIndex{#2}{\texttt{\textbackslash#2}} } } % \bomba \NewDocumentCommand \bomba { } { \par\hspace*{-0.5\marginparsep}% \makebox[0pt][r] { \makebox[\marginparsep][r] { \footnotesize\textcolor{pkgcolor}{\faIcon{bomb}} } } \hskip 0.5\marginparsep } \NewDocumentEnvironment{important}{ s } { \small\sffamily \IfBooleanTF{#1} { \bomba } { \color{OrangeRed} } }{} \ExplSyntaxOff % email https://tex.stackexchange.com/a/663 \catcode`\_=11\relax% \newcommand\email[1]{\_email #1\q_nil}% \def\_email#1@#2\q_nil{% \href{mailto:#1@#2}{{\emailfont #1\emailampersat #2}}% }% \newcommand\emailfont{\sffamily}% \newcommand\emailampersat{{\color{optcolor}\footnotesize @}}% \catcode`\_=8\relax% % Custom vertamimsc \makeatletter \let\verbatimsc\@undefined \let\endverbatimsc\@undefined \makeatother \usepackage{listings} \lstnewenvironment{verbatimsc} { \lstset{ language =,% basicstyle = \ttfamily\small, gobble = 2,% } }{} \makeatother % Don't copy numbers in code example \newcommand*{\noaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}} % Create a language for documentation \lstdefinelanguage{scontents-doc}{ texcsstyle = *,% escapechar = Ç,% extendedchars = true,% keepspaces = true,% stringstyle = {\color{red}},% basicstyle = \ttfamily\small,% alsoletter = {-,@,.},% % comments morecomment = [l]{\%},% commentstyle = \ttfamily\small\color{lightgray},% % Important words 1 keywordstyle = [1]{\color{gray}},% keywords = [1]{begin,end,env,myseq,false,ExplSyntaxOff,ExplSyntaxOn,% NTF, N,x,e,n,nn,nnn,D,Nnn,DocumentMetadata,IfDocumentMetadataTF,},% % Other words 2 (LaTeX) keywordstyle = [2]{\color{blue!75}},% keywords = [2]{usepackage,section,documentclass,input,usemodule,% subsection,RequirePackage,% ProvidesExplPackage,obeyedline,lstinline,Verb,macro,% makebox,verb,detokenize,meaning,RenewDocumentCommand,% definetyping,lstset,small,ttfamily,tiny,color,scantokens,% peek_charcode_ignore_spaces,cs_argument_spec,cs_parameter_spec,% regex_replace_all,tl_replace_all,tex_scantokens,tex_endinput,% file_input_stop,peek_charcode,cs_undefine,tl_rescan,int_to_roman,% int_step_tokens,keys_set,l_keys_key_str,tl_gset_rescan,contextlmtxmode,},% % Other words 3 keywordstyle = [3]{\color{optcolor!85}},% keywords = [3]{document,article,setlength,pagestyle,definecolor,myenvstore},% % Reserved words 4 (scontents pkg) keywordstyle = [4]{\color{pkgcolor}},% keywords = [4]{scontents,Scontents,getstored,typestored,verbatimsc,mergesc, % endverbatimsc,countsc,meaningsc,foreachsc,newenvsc,setupsc,cleanseqsc,% endverbatim, endscontents,startscontents,stopscontents,scontents.tex},% % Reserved words 5 (in red) keywordstyle = [5]{\color{red}},% keywords = [5]{makeatletter, makeatother, let, @undefined, def,@bsphack, @esphack,% par,item,parindent,@ifpackagelater,ver@xparse.sty, MakeFile,% ver@scontents.sty,dospecials,do@noligs,char,outer,jobname,inner},% % Reserved words 6 (optcolor) keywordstyle = [6]{\color{optcolor}},% keywords = [6]{store-cmd,store-env,print-env,print-cmd,write-env,verb-font,% start,stopt,wrapper,sep,step,before,after,write-out,write-cmd,% overwrite,width-tab,force-eol,inner,outer,I,J,M,L,Ascheol,store-all, 1-end,Verbatim,lang,pdfversion,pdfstandard,testphase,tagging,},% % Reserved words 7 (OrangeRed) keywordstyle = [7]{\color{OrangeRed}},% keywords = [7]{DefineVerbatimEnvironment,lstnewenvironment,newminted,% newtheorem,newenvironment,VerbatimEnvironment,listings,minted,},% % literate literate =*{\{}{{{\color{gray}{\char`\{}}}}{1} {\}}{{{\color{gray}{\char`\}}}}}{1} {\|}{{{\color{gray}{\char`\|}}}}{1} {\$}{{{\color{gray}{\char`\$}}}}{1} {\#}{{{\color{optcolor}{\char`\#}}}}{1} {[}{{\textcolor{gray}{[}}}{1} {]}{{\textcolor{gray}{]}}}{1} {,}{{\textcolor{gray}{,}}}{1} {;}{{\textcolor{gray}{;}}}{1} {:}{{\textcolor{MediumOrchid}{:}}}{1} {`}{{\textcolor{gray}{\textasciigrave}}}{1} {\&}{{\textcolor{gray}{\&}}}{1} {>}{{\textcolor{OrangeRed}{\guillemotright}}}{1} {<}{{\textcolor{OrangeRed}{\guillemotleft}}}{1} {*}{{\textcolor{MediumOrchid}{*}}}{1} {\^}{{\textcolor{optcolor}{\textasciicircum}}}{1} {0}{{\textcolor{MediumOrchid}{0}}}{1} {1}{{\textcolor{MediumOrchid}{1}}}{1} {2}{{\textcolor{MediumOrchid}{2}}}{1} {3}{{\textcolor{MediumOrchid}{3}}}{1} {4}{{\textcolor{MediumOrchid}{4}}}{1} {5}{{\textcolor{MediumOrchid}{5}}}{1} {6}{{\textcolor{MediumOrchid}{6}}}{1} {7}{{\textcolor{MediumOrchid}{7}}}{1} {8}{{\textcolor{MediumOrchid}{8}}}{1} {9}{{\textcolor{MediumOrchid}{9}}}{1} {.0}{{\textcolor{MediumOrchid}{.0}}}{2}% Following is to ensure that only periods {.1}{{\textcolor{MediumOrchid}{.1}}}{2}% followed by a digit are changed. {.2}{{\textcolor{MediumOrchid}{.2}}}{2} {.3}{{\textcolor{MediumOrchid}{.3}}}{2} {.4}{{\textcolor{MediumOrchid}{.4}}}{2} {.5}{{\textcolor{MediumOrchid}{.5}}}{2} {.6}{{\textcolor{MediumOrchid}{.6}}}{2} {.7}{{\textcolor{MediumOrchid}{.7}}}{2} {.8}{{\textcolor{MediumOrchid}{.8}}}{2} {.9}{{\textcolor{MediumOrchid}{.9}}}{2} {=}{{\textcolor{gray}{=}}}{1},% }[keywords,tex,comments,strings]% end language % \begin{examplecode}[key=val]...\end{examplecode} \lstnewenvironment{examplecode}[1][]{% \lstset{ language = scontents-doc,% stringstyle = {\color{red}},% basicstyle = \ttfamily\small,% columns = fullflexible,% fontadjust = true,% aboveskip = 8pt,% belowskip = 5pt,% rulecolor = \color{gray!50},% framesep = \fboxsep,% framerule = \fboxrule,% xleftmargin = \dimexpr\fboxsep+\fboxrule\relax,% xrightmargin= \dimexpr\fboxsep+\fboxrule\relax,% #1,% }% close lstset }{}% close examplecode % \lstinline[style=inline]|...| \lstdefinestyle{inline} { language = scontents-doc,% upquote = true,% numbersep = 1em,% numberstyle = \tiny\color{lightgray}\noaccsupp,% literate =*{\%}{{\textcolor{gray}{\%}}}{1} } % Set default \lstinline style \lstset{style=inline} % Set short §...§ \lstMakeShortInline[language=scontents-doc,basicstyle=\ttfamily]§ % Get file info \GetFileInfo{scontents.sty} % Config hyperref \hypersetup{ allcolors = linkcolor, colorlinks = true, linktoc = all, pdftitle = {.:: The scontents package --- \fileinfo{} ::.}, pdfauthor = {Pablo González L}, pdfsubject = {Documentation for \fileversion{} [\filedate] }, pdfkeywords = {sequences, contents, external files, expl3, l3seq, store contents}, bookmarksopenlevel = 1 } % Configuration titleps and titlesec \settitlemarks{section} \renewpagestyle{plain}[\color{optcolor}\small\sffamily]{% \setfoot{\rlap{\hskip\dimexpr-\oddsidemargin-1in\relax% \parbox{1.93\paperwidth}{\hfil\thepage\,/\,\pageref{LastPage}}}}% {}% {}% } \newpagestyle{myheader}[\color{optcolor}\small\sffamily]{% \renewcommand\makeheadrule{% \rlap{\hskip\dimexpr-\oddsidemargin-1in\relax \color{rulecolor}\rule[0.3cm]{\paperwidth}{0.7cm}}\hss } \setfoot{\rlap{\hskip\dimexpr-\oddsidemargin-1in\relax% \parbox{1.93\paperwidth}{\hfil\thepage\,/\,\pageref{LastPage}}}}% {\parbox{\textwidth}{\raggedright \textcolor{gray}{\raisebox{-1pt}{\textcopyright}{}2019--2025 by Pablo González L}}}% {}% \sethead{\llap{\raisebox{0.55cm}{\parbox{\dimexpr\oddsidemargin+1in\relax}{\makebox[0pt][l]{\hspace{15pt}\pkglogo\space\fileversion}}}}} {\raisebox{0.55cm}{\parbox{\textwidth}{\hspace*{-\oddsidemargin}\centering\small\S.\thesection\space\sectiontitle}}}% {}% } \titlecontents{section}[0mm]{}% {\bfseries\contentspush{\makebox[5mm][l]{\thecontentslabel\hfill}}}% {\hspace*{-5mm}}% numberless {\hspace{0.25em}\titlerule*[6pt]{.}\contentspage}% \titlecontents{subsection}[5mm]{}% {\contentspush{\makebox[6mm][l]{\thecontentslabel\hfill}}} {\hspace*{-11mm}}% numberless {\hspace{0.25em}\titlerule*[6pt]{.}\contentspage}% % Table of contents \makeatletter \renewcommand\tableofcontents{% \begingroup% \section*{\contentsname\quad{\color{gray}\leaders\hrule height 5pt depth -4.4pt\hfill}% \@mkboth{% \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}% \vspace*{-14pt} \setlength{\columnsep}{10pt}% \begin{multicols}{2}% \@starttoc{toc}% \end{multicols}% \vspace*{-3pt}{\color{gray}\hrule height 0.6pt}% \vspace*{5pt} \endgroup } \makeatother % thanks \makeatletter \renewcommand*{\@fnsymbol}[1]{\ensuremath{\ifcase#1\or \textcolor{pkgcolor}{*} \or \textcolor{pkgcolor}{\dagger} \or \ddagger\or \mathsection \or \mathparagraph\or \|\or **\or \dagger\dagger \or \ddagger\ddagger \else\@ctrerr\fi}} \makeatother \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \title{ % \scalebox{1.72}{\pkglogo}\\[1pt] % \Large % \textcolor{gray}{\fetamontotf{stores} \hologo{LaTeX} \fetamontotf{contents}}\\[3pt] % \fileversion \quad \filedate\thanks{ % This file describes a documentation for \fileversion, last revised % \filedate.}\\[25pt] % \author{ % \large % \raisebox{-1pt}{\textcopyright}{}2019--2025 by Pablo González L\thanks{ % E-mail: \textcolor{OrangeRed}{\textsf{\guillemotleft}}\email{pablgonz@educarchile.cl}\textcolor{OrangeRed}{\textsf{\guillemotright}}. % }% % } % \small % \textsc{ctan}: \url{https://www.ctan.org/pkg/scontents}\\ % \textcolor{gray}{\scriptsize\faIcon[regular]{github}}\,\,\,\url{https://github.com/pablgonz/scontents} % \vspace*{-2cm} % } % \date{} % \maketitle % % \begin{scontents}[store-env=abstract, print-env=true] % \begin{abstract} % This package allows to store \hologo{LaTeX} code, including \enquote{\emph{verbatim}}, % in \mymeta{sequences} using the \mypkg{l3seq} module of \mypkg{expl3}. The \mymeta{stored % content} can be used as many times as desired in the document, additionally you can write % to \mymeta{external files} or show it in \mymeta{verbatim style}. % \end{abstract} % \end{scontents} % % \tableofcontents % % \setlength{\parskip}{3pt} % % \section{Description of the package} % % \begin{scontents}[store-env=description, print-env=true] % The \mypkg*{scontents} package allows to \mymeta{store contents} in \mymeta{sequences} % or \mymeta{external files}. In some ways it is similar to the \mypkg{filecontentsdef} % package, with the difference in which the \mymeta{content} is stored. The idea behind % this package is to get an approach to \hologo{ConTeXt} \emph{\enquote{buffers}} by % making use \mymeta{sequences}. % \end{scontents} % % \section{Motivation and Acknowledgments} % % In \hologo{LaTeX} there is no direct way to record content for later use, although % you can do this using §\macro§, recording \mymeta{verbatim content} is a % problem, usually you can avoid this by creating external files or boxes. % % The general idea of this package is to try to imitate this implementation % \enquote{\emph{buffers}} that has \hologo{ConTeXt} which allows you to save content in % memory, including \emph{verbatim}, to be used later. The \mypkg{filecontentsdef}\cite{filecontentsdef} % package solves this problem and since \mypkg{expl3}\cite{expl3} has an excellent way to manage data, % ideas were combined giving rise to this package. % % This package would not be possible without the great work of \textsc{Jean % Fran\c{c}ois Burnol} who was kind enough to take my requirements into account % and add the \myenv{filecontentsdefmacro} environment to \mypkg{filecontentsdef} package. % Also a special thanks to Phelype Oleinik who has collaborated and adapted a large part of the code and % all \hologo{LaTeX} team for their great work and to the different members % of the \href{https://tex.stackexchange.com}{TeX-SX} community who have provided % great answers and ideas. Here a note of the main ones: % % \begin{enumerate}[left=0pt, labelsep=5pt, noitemsep, nosep, label=\small\arabic*.] % \item \href{https://tex.stackexchange.com/q/45946/7832}{Stack datastructure using LaTeX} % % \item \href{https://tex.stackexchange.com/q/5338/7832}{LaTeX equivalent of ConTeXt buffers} % % \item \href{https://tex.stackexchange.com/q/215563/7832}{Storing an array of strings in a command} % % \item \href{https://tex.stackexchange.com/q/184503/7832}{Collecting contents of environment and store them for later retrieval} % % \item \href{https://tex.stackexchange.com/q/373647/7832}{Collect contents of an environment (that contains verbatim content)} % \end{enumerate} % % \begin{important}* % Starting with version 2.3 the \mypkg*{scontents} package is fully % compatible with \emph{tagged} \texttt{PDF} and will have \LaTeX{} % release 2024-11-01 (\TeX{} Live 2024) as a minimum requirement. % \end{important} % % \thispagestyle{plain} % \newpage % \pagestyle{myheader} % % \section{License and Requirements} % \label{sec:licence} % % Permission is granted to copy, distribute and/or modify this software under % the terms of the LaTeX Project Public License (lppl), version 1.3 or later % (\url{https://www.latex-project.org/lppl.txt}). The software has the status % \enquote{maintained}. % % The package \mypkg*{scontents} requires an updated version of \LaTeX{} to work % (minimum required to \LaTeX{} release 2024-11-01). This package can be used with "plain", % "context", "xelatex", "lualatex", "pdflatex" and the classical workflow % §latex>dvips>ps2pdf§. % % \section{The \texttt{scontents} package} % \label{sec:pkgscontents} % % \subsection{Installation} % % The package \mypkg*{scontents} is present in \hologo{TeX} Live and \hologo{MiKTeX}, % use the package manager to install. For manual installation, download % \href{https://mirrors.ctan.org/macros/latex/contrib/scontents.zip}{scontents.zip} % and unzip it, run \lstinline[language=scontents-doc,basicstyle=\ttfamily]+luatex scontents.ins+ % and move all files to appropriate locations, then run "mktexlsr". To produce the documentation % with source code run \lstinline[language=scontents-doc,basicstyle=\ttfamily]+luatex scontents.ins+ and % "lualatex scontents.dtx" three times. % % \iffalse %<*example> % \fi \begin{examplecode}[frame=single,language={}] scontents.tex > TDS:tex/generic/scontents/ scontents-code.tex > TDS:tex/generic/scontents/ scontents.sty > TDS:tex/latex/scontents/ t-scontents.mkiv > TDS:tex/context/third/scontents/ scontents.pdf > TDS:doc/latex/scontents/ README.md > TDS:doc/latex/scontents/ scontents.dtx > TDS:source/latex/scontents/ scontents.ins > TDS:source/latex/scontents/ \end{examplecode} % \iffalse % % \fi % % \subsection{Loading and options} % % The package is loaded in the usual way: % % \subsubsection*{For \hologo{LaTeX} users} % % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] \usepackageÇ\small\myoarg{key \textnormal{\textcolor{gray}{=}} val}Ç{scontents} \end{examplecode} % \iffalse % % \fi % % \subsubsection*{For \hologo{plainTeX} users} % % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] \input scontents.tex \end{examplecode} % \iffalse % % \fi % % \subsubsection*{For \hologo{ConTeXt} users} % % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] \usemodule{scontents} \end{examplecode} % \iffalse % % \fi % % \begin{important}* % The package options are not available for \hologo{plainTeX} and % \hologo{ConTeXt} and must be passed using §\setupsc§ (see \S\ref{sec:confopt}). % \hologo{ConTeXt} users should use |-luatex|, the implementation does % not support LuaMetaTeX. % \end{important} % % \subsection{The TAB character} % \label{sec:tabcharacter} % % Some users use horizontal \texttt{TAB} `\LKeyTab' from keyboard to indented the source % code of the document and depending on the text editor used, some will use real \texttt{TAB} % (\emph{hard tabs}), others with \emph{soft tabs} (\verb*| | or \verb*| |) % or both. % % At first glance it may seem the same, but the way in which \texttt{TAB} (\emph{hard tabs}) % are processed according to the context in which they are found within % a file, both in \mymeta{reading}\footnote{Check the answer given by Ulrich Diez % in \href{https://tex.stackexchange.com/a/508103/7832}{Keyboard TAB % character in argument v (xparse)}.} and \mymeta{writing}\footnote{Check the answer % given by Enrico Gregorio in \href{https://tex.stackexchange.com/a/58740/7832}{How to output a % tabulation into a file}.} are different and may have adverse consequences. % % In a standard \hologo{LaTeX} document, the character \texttt{TAB} `\LKeyTab' % are treated as explicit spaces (in most contexts) and is the behavior when % \mymeta{stored content}, but when \mymeta{writing files} these are preserved. % % With a \hologo{TeX} Live distribution, the \texttt{TAB} character is \emph{printable} % for "latex", "pdflatex" and "lualatex", but if you use "xelatex" you % must add the \texttt{\textcolor{optcolor}{-8bit}} option on the command % line, otherwise you will get \hologo{TeX} character \texttt{TAB} `§^^I§' % in the \mymeta{output file}. % % As a general recommendation \emph{\enquote{Do not use \texttt{TAB} character unless strictly % necessary}}, for example within a \emph{\enquote{verbatim environment}} that supports % this character such as \myenv{Verbatim} of the packages \mypkg{fancyvrb}\cite{fancyvrb}, % \mypkg{fvextra}\cite{fvextra} or \myenv{lstlisting} of the package \mypkg{listings}\cite{listings} % or when you want to generate a §MakeFile§ file. % % \subsection{Configuration of the options} % \label{sec:confopt} % % Most of the options can be passed directly to the package or using the % command \ics*{setupsc}. All boolean keys can be passed using the % equal sign `\textnormal{\textcolor{gray}{=}}' or just the % name of the key, all unknown \mymeta{keys} will return an error. In this section % are described some of the options, a summary of all options is shown in \S\ref{sec:optover}. % % \vspace*{-10pt} % % \begin{function}{\setupsc} % \begin{syntax} % \cmdexamp{setupsc}{key \textnormal{\textcolor{gray}{=}} val} % \end{syntax} % % The command \ics*{setupsc} sets the \mymeta{keys} in a global way, % it can be used both in the preamble and in the body of the document % as many times as desired. However, options set in the declaration of % an environment (with \ics*{newenvsc}) have precedence over options % set with \ics*{setupsc}. % % Options in the optional arguments of environments and % commands have the highest precedence, overriding both % options in \ics*{newenvsc}, and in \ics*{setupsc}. % \end{function} % % \keyexamp{verb-font}{font family}{\textnormal{\ttfamily\textbackslash{}ttfamily}} % Sets the \mymeta{font family} used to display the \mymeta{stored content} for % \ics*{typestored}, \ics*{mergesc} and \ics*{meaningsc} commands. This key % is only available as a package option or using \ics*{setupsc}. % % \medskip % % \keyexamp{store-all}{seq name}{not used} % It is a \mymeta{meta-key} that sets the \mykey{store-env} key of the \myenv*{scontents} % environment and the \mykey{store-cmd} key of the \ics*{Scontents} command. This key is % only available as a package option or using \ics*{setupsc}. % % \medskip % % \keyexamp{overwrite}{true \textnormal{\textcolor{lightgray}{\textbar}} false}{false} % Sets whether the \mymeta{files} generated by \mykey{write-out} and \mykey{write-env} % from the \myenv*{scontents} environment will be rewritten. This key is available as % a package option, for \ics*{setupsc}, for \ics*{Scontents*} and for the environment % \myenv*{scontents}. % % \medskip % % \keyexamp{print-all}{true \textnormal{\textcolor{lightgray}{\textbar}} false}{false} % It is a \mymeta{meta-key} that sets the \mykey{print-env} key of the \myenv*{scontents} % environment and the \mykey{print-cmd} key of the \ics*{Scontents} command. This key is % only available as a package option or using \ics*{setupsc}. % % \keyexamp{force-eol}{true \textnormal{\textcolor{lightgray}{\textbar}} false}{false} % Sets if the \emph{last end of line} for the \mymeta{stored content} is hidden or not. % This key is necessary only if the \emph{last line} is the closing of some % environment defined by \mypkg{fancyvrb}\cite{fancyvrb} or \mypkg{fvextra}\cite{fvextra} % packages as §\end{Verbatim}§ or another environment that does not support % a comments `\texttt{\textcolor{gray}{\%}}' after closing §\end{}%§. % This key is available for the \myenv*{scontents} environment and the \ics*{Scontents*} command. % % \keyexamp{width-tab}{integer}{1} % Sets the equivalence in \mymeta{spaces} for the character \texttt{TAB} % used when displaying \mymeta{stored content} in \emph{verbatim style}. The value % must be a \mymeta{positive integer}. This key is available for \ics*{typestored}, % \ics*{mergesc} and \ics*{meaningsc} commands. % % \subsection{Options Overview} % \label{sec:optover} % % \newcommand*{\xmark}{\textcolor{OrangeRed}{✘}}% % \newcommand*{\cmark}{\textcolor{linkcolor}{✔}}% % % Summary of available options: % % \setlength{\tabcolsep}{0.25em} % \vspace*{-\baselineskip} % \begin{center} % \small % \begin{tabular}{lcccccccc} % \toprule % \texttt{key} & \texttt{package} &\ics*{setupsc} &\myenv*{scontents} &\ics*{Scontents} &\ics*{Scontents*} &\ics*{typestored} &\ics*{meaningsc} &\ics*{mergesc}\\ % \midrule % \mykey{store-env} & \cmark & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark & \xmark \\ % \mykey{store-cmd} & \cmark & \cmark & \xmark & \cmark & \cmark & \xmark & \xmark & \xmark \\ % \mykey{print-env} & \cmark & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark & \xmark \\ % \mykey{print-cmd} & \cmark & \cmark & \xmark & \cmark & \cmark & \cmark & \cmark & \cmark \\ % \mykey{print-all} & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark & \xmark & \xmark \\ % \mykey{store-all} & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark & \xmark & \xmark \\ % \mykey{write-env} & \xmark & \xmark & \cmark & \xmark & \xmark & \xmark & \xmark & \xmark \\ % \mykey{write-cmd} & \xmark & \xmark & \xmark & \xmark & \cmark & \xmark & \xmark & \xmark \\ % \mykey{write-out} & \xmark & \xmark & \cmark & \xmark & \cmark & \cmark & \cmark & \cmark \\ % \mykey{overwrite} & \cmark & \cmark & \cmark & \xmark & \cmark & \cmark & \cmark & \cmark \\ % \mykey{width-tab} & \cmark & \cmark & \xmark & \xmark & \xmark & \cmark & \cmark & \cmark \\ % \mykey{force-eol} & \cmark & \cmark & \cmark & \xmark & \cmark & \xmark & \xmark & \xmark \\ % \mykey{verb-font} & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark & \xmark & \xmark \\ % \mykey{typestored} & \xmark & \xmark & \xmark & \xmark & \xmark & \xmark & \xmark & \cmark \\ % \mykey{meaningsc} & \xmark & \xmark & \xmark & \xmark & \xmark & \xmark & \xmark & \cmark \\ % \bottomrule % \end{tabular} % \end{center} % % \section{User interface} % \label{sec:interface} % % The user interface consists in \myenv*{scontents} environment, \ics*{Scontents} % and \ics*{Scontents*} commands to \mymeta{stored content}, \ics*{getstored} % command to get the \mymeta{stored content}, \ics*{typestored} and \ics*{mergesc} commands to print % \emph{verbatim style} the \mymeta{stored content} along with other utilities described % in this documentation. % % \subsection{The environment \texttt{scontents}} % \label{sec:envscontents} % % \vspace*{-10pt} % % \begin{function}[label=SCONTENTS]{scontents} % \begin{syntax} % \envexamp{scontents} % \end{syntax} % % The \myenv*{scontents} environment processes \mymarg{body env} and % \emph{\enquote{stores}} it in a \mymeta{sequence} or \emph{\enquote{writes}} % it to an \mymeta{external file} if desired, including \emph{verbatim % material}. After the package has been loaded, the environment can be % used both in the preamble and in the body of the document. % % For the correct operation §\begin{scontents}§ and §\end{scontents}§ must % be in \emph{different lines}, all \mymeta{keys} must be passed separated by % commas and \emph{without separation} `\verb*+ +' of the start of the % environment. % \end{function} % % Comments `\texttt{\textcolor{gray}{\%}}' or \emph{any character} after % §\begin{scontents}§ or \myoarg{key \textnormal{\textcolor{gray}{=}} val} on % the \emph{same line} are NOT supported, the package will return an \enquote{error} message if this happens. % In a similar way comments `\texttt{\textcolor{gray}{\%}}' or \emph{any character} % after §\end{scontents}§ on the \emph{same line} the package will return a \enquote{warning} message. % % The environment can be \emph{\enquote{nested}} if it is properly balanced and % does not appear \emph{\enquote{literally}} in commented lines or in some \emph{verbatim} % environment or command. As an example: % % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] \begin{scontents}[store-env=outer] This text is in the outer environment (before nested). \begin{scontents}[store-env=inner] This text is found in the inner environment (inside of nested). \end{scontents} This text is in the outer environment (after nested). \end{scontents} \end{examplecode} % \iffalse % % \fi % % Of course, the \mymeta{stored content} in the \emph{sequence} \mymarg{inner} % is \emph{only available} after \mymeta{stored content} in the \emph{sequence} % \mymarg{outer} one has been retrieved, either by using the key \mykey{print-env} % or \ics*{getstored} command. % % \begin{important}* % It is advisable to \mymeta{stored content} within \emph{sequences} with % different names, so as not to get lost in the order (position) in which % they are stored. % \end{important} % % \subsection*{Notes for \hologo{plainTeX} and \hologo{ConTeXt} users} % % In \hologo{plainTeX} there is not environments as in \hologo{LaTeX}. % Instead of using the environment \myenv*{scontents}, one should use a % \emph{\enquote{pseudo environment}} delimited by \ics*{scontents} and \ics*{endscontents}. % % \vspace*{-10pt} % \begin{function}{\scontents,\endscontents} % \begin{syntax} % \envexaplain{scontents} % \end{syntax} % \end{function} % % \hologo{ConTeXt} users should use \ics*{startscontents} and \ics*{stopscontents}. % \vspace*{-10pt} % \begin{function}{\startscontents,\stopscontents} % \begin{syntax} % \envexaplain[start]{scontents}[stop] % \end{syntax} % \end{function} % % \subsection*{Options for environment} % % The environment options can be configured globally using option % in package or the \ics*{setupsc} command and locally using % \myoarg{key \textnormal{\textcolor{gray}{=}} val} in the environment. % The key \mykey{force-eol} is available for this environment. % % \keyexamp{store-env}{seq name}{contents} % Sets the \emph{name} of the \emph{sequence} in which the \mymarg{body env} will be % stored. If the \emph{sequence} does not exist, it will be created globally. % % \medskip % % \keyexamp{print-env}{true \textnormal{\textcolor{lightgray}{\textbar}} false}{false} % Sets if the \mymeta{stored content} is displayed or not at the time of % running the environment. The \mymeta{stored content} is extracted from % the \emph{sequence} \mymarg{seq name} set by the key \mykey{store-env} % at the time it is executed. % % \medskip % % \keyexamp{write-env}{file.ext}{not used} % Sets the \emph{name} of the \mymeta{external file} in which the \mymarg{body env} of % the environment will be written. The \mymeta{file.ext} will be created % in the working directory and the \mymarg{body env} will be \emph{stored} % in the \emph{sequence} set by the key \mykey{store-env} % at the time it is executed. If \mymeta{file.ext} does not exist, it will % be created or overwritten if the \mykey{overwrite} key is used. % % \medskip % % \keyexamp{write-out}{file.ext}{not used} % Sets the \emph{name} of the \mymeta{external file} in which the \mymarg{body env} of % the environment will be written. The \mymeta{file.ext} will be created % in the working directory and the \mymarg{body env} will NOT be \emph{stored} % in the \emph{sequence} set by the key \mykey{store-env} % at the time it is executed. If \mymeta{file.ext} does not exist, it will % be created or overwritten if the \mykey{overwrite} key is used. % % \begin{important}* % In the keys \mykey{write-env} and \mykey{write-out} the character % \texttt{TAB} will be written in \mymeta{file.ext}, % relative or absolute paths are not supported. \hologo{XeLaTeX} users % using character \texttt{TAB} must add \texttt{\textcolor{optcolor}{-8bit}} % at the command line, otherwise you will get \hologo{TeX} character % \texttt{TAB} `§^^I§' in \mymeta{file.ext}. % \end{important} % % \subsection{The command \cs{newenvsc}} % \label{sec:newenvsc} % % \newsavebox{\exaboxtmp} % \begin{lrbox}{\exaboxtmp} % \small\ttfamily % \textcolor{pkgcolor}{\textbackslash newenvsc}\mymarg{env name}\myoarg{initial keys} % \end{lrbox} % % \vspace*{-10pt} % % \begin{function}{\newenvsc} % \begin{syntax} % \usebox{\exaboxtmp} % \end{syntax} % \end{function} % % The command \ics*{newenvsc} allows you to create \mymeta{new environments} % based on the same characteristics of the \myenv*{scontents} environment. % The values entered in \myoarg{initial keys} will be considered as the % default values for this new environment and the valid \mymeta{keys} are % \mykey{store-env} and \mykey{print-env}. For example: % % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] \newenvsc{myenvstore}[store-env=myseq,print-env=false] \end{examplecode} % \iffalse % % \fi % % created the environment §myenvstore§ that \mymeta{stored content} in % the \emph{sequence} \mymarg{myseq} and will NOT display the \mymeta{stored content} % when the environment it is executed. % % \subsection{The command \cs{Scontents}} % \label{sec:Scontents} % % \vspace*{-10pt} % % \begin{function}{\Scontents} % \begin{syntax} % \cmdexamp{Scontents}[key \textnormal{\textcolor{gray}{=}} val]{argument} % \cmdexamp[*]{Scontents}[key \textnormal{\textcolor{gray}{=}} val]{argument} % \cmdexamp[*]{Scontents}[key \textnormal{\textcolor{gray}{=}} val]{argument}[del] % \end{syntax} % \end{function} % % The \ics*{Scontents} command reads the \mymarg{argument} in standard % mode and \emph{\enquote{stores}} it in the \emph{sequence} set % by the key \mykey{store-cmd} at the time it is executed. It is not % possible to pass \emph{verbatim things}, but it is possible to use % the implementation of §\Verb§ delimited by \emph{braces} % `\texttt{\textcolor{gray}{\{}} \texttt{\textcolor{gray}{\}}}' % provided by the \mypkg{fvextra}\cite{fvextra} package for \emph{verbatim one line} % and §\lstinline§ from \mypkg{listings}\cite{listings} package, but it % is preferable to use the \emph{starred argument} `§*§'. % % The \ics*{Scontents*} command reads the \mymarg{argument} under \emph{verbatim catcode} % regimen and \emph{\enquote{stores}} it in the \emph{sequence} set % by the key \mykey{store-cmd} at the time it is executed. If its \emph{\enquote{first}} % delimiter is a \emph{brace} `\texttt{\textcolor{gray}{\{}}', it will be % assumed that the \mymarg{argument} is nested into \emph{braces}. Otherwise it % will be assumed that \mymarg{argument} is delimited by that % first delimiter \mymeta[cf=MediumOrchid]{del} like command §\verb§. % Blank lines are preserved, escaped braces `\texttt{\textcolor{gray}{\textbackslash\{}}' and % `\texttt{\textcolor{gray}{\textbackslash\}}}' must also be % balanced if the \mymarg{argument} is used with \emph{braces} and character \texttt{TAB} typed % from the keyboard are converted into spaces. % % The \emph{starred argument} `§*§' and \myoarg{key \textnormal{\textcolor{gray}{=}} val} % must NOT be separated by \emph{spaces} `\verb*+ +' between them and the command. % Both versions can be used anywhere in the document and cannot be used % as an \mymarg{argument} for other command. % % \subsection*{Options for command}\label{sec:optcmdsc} % % The command options can be configured globally using option in package % or the \ics*{setupsc} command and locally using \myoarg{key \textnormal{\textcolor{gray}{=}} val}. % % \keyexamp{store-cmd}{seq name}{contents} % Sets the \emph{name} of the \emph{sequence} in which the \mymarg{argument} % is stored. If the \emph{sequence} does not exist, it will be created globally. % % \medskip % % \keyexamp{print-cmd}{true \textnormal{\textcolor{lightgray}{\textbar}} false}{false} % Sets if the \mymeta{stored content} is displayed or not at the time of % running the command. The \mymeta{stored content} is extracted from the \emph{sequence} % \mymarg{seq name} set by the key \mykey{store-cmd} at the time it is executed. % % \subsection*{Options only for starred version} % % The \mykey{force-eol} and \mykey{overwrite} keys is available for this \emph{starred version}. % % \keyexamp{write-cmd}{file.ext}{not used} % Sets the \emph{name} of the \mymeta{external file} in which the \mymarg{argument} % will be written. The \mymeta{file.ext} will be created in the working % directory and the \mymarg{argument} will be \emph{stored} % in the \emph{sequence} set by the key \mykey{store-cmd} % at the time it is executed. If \mymeta{file.ext} does not exist, it will % be created or overwritten if the \mykey{overwrite} key is used. % % \keyexamp{write-out}{file.ext}{not used} % Sets the \emph{name} of the \mymeta{external file} in which the \mymarg{argument} % will be written. The \mymeta{file.ext} will be created in the working % directory and the \mymarg{argument} will NOT be \emph{stored} % in any \emph{sequence} set by the key \mykey{store-cmd} % at the time it is executed. If \mymeta{file.ext} does not exist, it will % be created or overwritten if the \mykey{overwrite} key is used. % % \begin{important}* % In the keys \mykey{write-cmd} and \mykey{write-out} the character % \texttt{TAB} will be written in \mymeta{file.ext}, relative or absolute % paths are not supported. \hologo{XeLaTeX} users using character \texttt{TAB} % must add \texttt{\textcolor{optcolor}{-8bit}} at the command line, otherwise % you will get \hologo{TeX} character \texttt{TAB} `§^^I§' in \mymeta{file.ext}. % \end{important} % % \subsection{The command \cs{getstored}} % \label{sec:getstored} % % \vspace*{-10pt} % % \begin{function}{\getstored} % \begin{syntax} % \cmdexamp{getstored}[index]{seq name} % \end{syntax} % \end{function} % % The \ics*{getstored} command retrieves the \mymeta{stored content} % according to the \emph{integer value} set in \mymeta{index} which % corresponds to the \emph{position} of the \mymeta{stored content} % in the \emph{sequence} \mymarg{seq name}. % % The command is robust and can be used as an \mymarg{argument} for % another command. If the \emph{optional argument} is not passed, % the default value is the \emph{\enquote{last}} \mymeta{stored content} % in the \emph{sequence} \mymarg{seq name}. % % \subsection{The command \cs{foreachsc}} \label{sec:foreachsc} % % \vspace*{-10pt} % % \begin{function}{\foreachsc} % \begin{syntax} % \cmdexamp{foreachsc}[key \textnormal{\textcolor{gray}{=}} val]{seq name} % \end{syntax} % \end{function} % % The command \ics*{foreachsc} goes through and executes the command §\getstored§ % on the \mymeta{stored content} in the \emph{sequence} \mymarg{seq name}. If the % \emph{optional argument} is not passed run §\getstored§ on all \mymeta{stored content} % in the \emph{sequence} \mymarg{seq name}. % % \subsubsection*{Options for command} % \label{sec:optcmdfor} % % \keyexamp{sep}{code}{empty} % Establishes the \emph{separation} between each \mymeta{stored content} % in the \emph{sequence} \mymarg{seq name}. % For example, you can use §sep={\\[10pt]}§ for vertical separation of % \mymeta{stored contents}. % % \keyexamp{step}{integer}{1} % Sets the \emph{increment} (\mymeta{step}) applied to the value set by key §start§ % for each \mymeta{stored content} in the \emph{sequence} \mymarg{seq name}. % The value must be a \mymeta{positive integer}. % % \keyexamp{start}{integer}{1} % Set the \emph{position} of the \mymeta{stored content} within the % \emph{sequence} \mymarg{seq name} from which to \emph{start} executing. % The value must be a \mymeta{positive integer}. % % \keyexamp{stop}{integer}{total} % Set the \emph{position} of the \mymeta{stored content} within the % \emph{sequence} \mymarg{seq name} at which execution ends. The value % must be a \mymeta{positive integer}. % % \keyexamp{before}{code}{empty} % Sets the \mymarg{code} that will be executed \emph{before} each \mymeta{stored content} % within the \emph{sequence} \mymarg{seq name}. The \mymarg{code} must % be passed \emph{between braces} `\texttt{\textcolor{gray}{\{}} \texttt{\textcolor{gray}{\}}}'. % % \keyexamp{after}{code}{empty} % Sets the \mymarg{code} that will be executed \emph{after} each \mymeta{stored content} % within the \emph{sequence} \mymarg{seq name}. The \mymarg{code} must % be passed \emph{between braces} `\texttt{\textcolor{gray}{\{}} \texttt{\textcolor{gray}{\}}}'. % % \newsavebox{\hashbox} % \begin{lrbox}{\hashbox} % \lstinline[language=scontents-doc,basicstyle=\small\ttfamily]+{#1}+ % \end{lrbox} % % \keyexamp{wrapper}{code{} \space\usebox{\hashbox} more code}{empty} % Wraps the \mymeta{stored content} within the \emph{sequence} \mymarg{seq name} % referenced by §{#1}§. The \mymarg{code} must be passed \emph{between braces} % `\texttt{\textcolor{gray}{\{}} \texttt{\textcolor{gray}{\}}}'. % For example §\foreachsc[wrapper={\makebox[1em][l]{#1}}]{contents}§. % % \subsection{The command \cs{typestored}} % \label{sec:typestored} % % \vspace*{-10pt} % % \begin{function}{\typestored} % \begin{syntax} % \cmdexamp{typestored}[index\textnormal{\textcolor{gray}{,}} start-stop\textnormal{\textcolor{gray}{,}} 1-end\textnormal{\textcolor{gray}{,}} keys]{seq name} % \end{syntax} % The command \ics*{typestored} places the \mymeta{stored content} in % the \emph{sequence} \mymarg{seq name} into the internally \myenv*{verbatimsc} % environment (\S\ref{sec:verbatimsc}). The \emph{integer value} set at \mymeta{index} corresponds % to the \emph{position} of the \mymeta{stored content} in the \emph{sequence} % \mymarg{seq name} will be printed, if \mymeta{1-end} is used \emph{\enquote{all}} % \mymeta{stored content} in the \emph{sequence} \mymarg{seq name} will be printed. % \end{function} % % The \emph{integer values} ​​set by \mymeta{start-stop} define the \emph{range} % of the \mymeta{stored content} in the \emph{sequence} \mymarg{seq name} % that will be printed, the rest of the accepted \mymeta{keys} are \mykey{print-cmd} % with default value \textcolor{gray}{\texttt{true}}, \mykey{write-out}, \mykey{width-tab} % and \mykey{overwrite}. % % If the \emph{optional argument} is not passed, the \emph{first} \mymeta{stored content} % in the \emph{sequence} \mymarg{seq name} will be printed. % % \begin{important}* % In the key \mykey{write-out} the character \texttt{TAB} will be written % in \mymeta{file.ext}, relative or absolute paths are not supported. % \hologo{XeLaTeX} users using character \texttt{TAB} must add \texttt{\textcolor{optcolor}{-8bit}} % at the command line, otherwise you will get \hologo{TeX} character % \texttt{TAB} `§^^I§' in \mymeta{file.ext}. % \end{important} % % \subsection{The command \cs{meaningsc}} % \label{sec:meaningsc} % % \vspace*{-10pt} % % \begin{function}{\meaningsc} % \begin{syntax} % \cmdexamp{meaningsc}[index\textnormal{\textcolor{gray}{,}} start-stop\textnormal{\textcolor{gray}{,}} 1-end\textnormal{\textcolor{gray}{,}} keys]{seq name} % \end{syntax} % The command \ics*{meaningsc} executes §\meaning§ on the \mymeta{stored content} % in the \emph{sequence} \mymarg{seq name}. The \mymeta{index}, % \mymeta{start-stop}, \mymeta{1-end} and \mymeta{keys} they have the % same behavior as in the command §\typestored§. If the \emph{optional argument} % is not passed it defaults to the first \mymeta{stored content} in the % \emph{sequence} \mymarg{seq name}. % \end{function} % % % % \subsection{The command \cs{mergesc}} % \label{sec:mergesc} % % \vspace*{-10pt} % % \newsavebox{\argmergesc} % \begin{lrbox}{\argmergesc} % \small\mymarg{seq A}\myoarg{index}\textcolor{gray}{, }\mymarg{seq B}\myoarg{start \textcolor{gray}{-} stop}\textcolor{gray}{, }\mymarg{seq C}\myoarg{1-end} % \end{lrbox} % % \begin{function}{\mergesc} % \begin{syntax} % \cmdexamp{mergesc}[typestored \textnormal{\textcolor{lightgray}{\textbar}} meaningsc\textcolor{lightgray}{, }keys]{\usebox{\argmergesc}} % \end{syntax} % The command \ics*{mergesc} assembles the \mymeta{stored content} % in the \emph{sequences} \mymarg{seq A}§[1]§, \mymarg{seq B}§[2-5]§ and % \mymarg{seq C}§[1-§\textcolor{optcolor}{\texttt{end}}§]§ and then executes % §\typestored§ (\S\ref{sec:typestored}) if the \mykey{typestored} key is % active or §\meaningsc§ (\S\ref{sec:meaningsc}) if the \mykey{meaningsc} % key is active. % \end{function} % % The \mymarg{argument} taken by this command is a \emph{comma separated list} % of the form \mymarg{seq name} followed by either \myoarg{index}, % \myoarg{start-stop} or \myoarg{1-end}. % The use of the keys \mykey{typestored} or \mykey{meaningsc} are % \emph{\enquote{mandatory}} and disjoint from each other, the rest of the % accepted \mymeta{keys} are \mykey{print-cmd}, \mykey{write-out}, % \mykey{width-tab} and \mykey{overwrite}. % % The use of the \mykey{write-out} key with this command follows the same % rules already described, the main advantage is that it allows to join % \mymeta{stored content} \emph{without rewriting} the file over and over again, % by design \hologo{TeX} does not have an \emph{append mode} for writing % files, this effectively allows you to write chunks of code and then % merge them into a single file. % %^^A \newpage % % \subsection{The environment \env{verbatimsc}} % \label{sec:verbatimsc} % % \vspace*{-10pt} % % \begin{function}{verbatimsc} % The environment used by \ics*{typestored} and \ics*{mergesc} to % display the \mymeta{stored content} in \emph{verbatim style}. % The environment is compatible with \emph{tagged} \texttt{PDF} and can % be customized in the following ways after loading the \mypkg*{scontents} % package: % \end{function} % % Using the packages \mypkg{fvextra}\cite{fvextra} or \mypkg{fancyvrb}\cite{fancyvrb}: % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] \ExplSyntaxOn \cs_undefine:N \verbatimsc \cs_undefine:N \endverbatimsc \ExplSyntaxOff \usepackage{fancyvrb} \DefineVerbatimEnvironment{verbatimsc}{Verbatim}{numbers=left} \end{examplecode} % \iffalse % % \fi % Using the package \mypkg{minted}\cite{minted}: % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] \ExplSyntaxOn \cs_undefine:N \verbatimsc \cs_undefine:N \endverbatimsc \ExplSyntaxOff \usepackage{minted} \newminted{tex}{linenos} \newenvironment{verbatimsc}{\VerbatimEnvironment\begin{texcode}}{\end{texcode}} \end{examplecode} % \iffalse % % \fi % Using the package \mypkg{listings}\cite{listings}: % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] \ExplSyntaxOn \cs_undefine:N \verbatimsc \cs_undefine:N \endverbatimsc \ExplSyntaxOff \usepackage{listings} \lstnewenvironment{verbatimsc} { \lstset{ basicstyle=\small\ttfamily, columns=fullflexible, language=[LaTeX]TeX, numbers=left, numberstyle=\tiny\color{gray}, keywordstyle=\color{red} } }{} \end{examplecode} % \iffalse % % \fi % % \begin{important}* % At the moment, the \mypkg{fvextra}\cite{fvextra} and \mypkg{fancyvrb}\cite{fancyvrb} % packages partially support \emph{tagged} \texttt{PDF}. % \end{important} % % \section{Other commands provided} % % \subsection{The command \cs{countsc}} % \label{sec:countsc} % % \vspace*{-10pt} % % \begin{function}{\countsc} % \begin{syntax} % \cmdexamp{countsc}{seq name} % \end{syntax} % The command \ics*{countsc} count a number of \mymeta{stored content} in the % \emph{sequence} \mymarg{seq name}. % \end{function} % % \subsection{The command \cs{cleanseqsc}} % \label{sec:cleansc} % % \vspace*{-10pt} % % \begin{function}{\cleanseqsc} % \begin{syntax} % \cmdexamp{cleanseqsc}{seq name} % \end{syntax} % The command \ics*{cleanseqsc} remove all \mymeta{stored content} in the % \emph{sequence} \mymarg{seq name}. % \end{function} % % \section[The \textnormal{\texttt{scontents}} package in action]{The \mypkg*{scontents} package in action} % % Remember the abstract on the first page?, this is it: % % \getstored{abstract} % % And the description of the package? % % \getstored{description} % % \medskip % % I've only written: % % \typestored{abstract} % % and % % \typestored{description} % % Of course, I didn't copy and paste. The real code they were written with is: % % \iffalse %<*example> % \fi \begin{examplecode}[numbers=left] \begin{scontents}[store-env=abstract,print-env=true] \begin{abstract} This package allows to store \hologo{LaTeX} code, including \enquote{\emph{verbatim}}, in \mymeta{sequences} using the \mypkg{l3seq} module of \mypkg{expl3}. The \mymeta{stored content} can be used as many times as desired in the document, additionally you can write to \mymeta{external files} or show it in \mymeta{verbatim style}. \end{abstract} \end{scontents} \end{examplecode} % \iffalse % % \fi % % and % % \iffalse %<*example> % \fi \begin{examplecode}[numbers=left] \begin{scontents}[store-env=description, print-env=true] The \mypkg*{scontents} package allows to \mymeta{store contents} in \mymeta{sequences} or \mymeta{external files}. In some ways it is similar to the \mypkg{filecontentsdef} package, with the difference in which the \mymeta{content} is stored. The idea behind this package is to get an approach to \hologo{ConTeXt} \emph{\enquote{buffers}} by making use \mymeta{sequences}. \end{scontents} \end{examplecode} % \iffalse % % \fi % % I stored the content in memory and then ran §\getstored§ and % §\typestored§. This is one of the ways you can use \mypkg*{scontents}. % % \section{Examples} % % These are some adapted examples that have served as inspiration for % the creation of this package. The examples are attached to this documentation % and can be extracted from your PDF viewer or from the command line by running: % \iffalse %<*example> % \fi \begin{examplecode}[frame=single] $ pdfdetach -saveall scontents.pdf \end{examplecode} % \iffalse % % \fi % and then you can use the excellent \arara\footnote{The cool \TeX\ automation tool: % \url{https://www.ctan.org/pkg/arara}} tool to compile them. % % \subsection{From \texttt{answers} package} % % \subsubsection*{Example 1} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp1.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage[store-cmd=solutions]{scontents} \newtheorem{ex}{Exercise} \setlength{\parindent}{0pt} \pagestyle{empty} \begin{document} \section{Problems} \begin{ex} First exercise \Scontents{First solution.} \end{ex} \begin{ex} Second exercise \Scontents{Second solution.} \end{ex} \section{Solutions} \foreachsc[sep={\\[10pt]}]{solutions} \end{document} \end{scontents} % \iffalse % % \fi % % Adaptation of example 1 of the package \mypkg{answers}\cite{answers} % \textattachfile[color=linkcolor,print=false]{scexamp1.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp1.ltx} % % \subsection{From \texttt{filecontentsdef} package} % % \subsubsection*{Example 2} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp2.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage[store-env=defexercise,store-cmd=defexercise]{scontents} \setlength{\parindent}{0pt} \pagestyle{empty} \begin{document} % not starred \Scontents{ Prove that \[x^n+y^n=z^n\] is not solvable in positive integers if $n$ is at most $-3$.\par } % starred \Scontents*|Refute the existence of black holes in less than $140$ characters.| % write environment to \jobname.txt \begin{scontents}[write-env=\jobname.txt] \def\NSA{NSA}% Prove that factorization is easily done via probabilistic algorithms and advance evidence from knowledge of the names of its employees in the seventies that the \NSA\ has known that for 40 years.\par \end{scontents} % see all stored \begin{itemize} \foreachsc[before={\item }]{defexercise} \end{itemize} % \getstored are robust :) \section{\getstored[2]{defexercise}} \end{document} \end{scontents} % \iffalse % % \fi % % Adaptation of example from package \mypkg{filecontentsdef}\cite{filecontentsdef} % \textattachfile[color=linkcolor,print=false]{scexamp2.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp2.ltx} % % \subsection{From TeX-SX} % % \subsubsection*{Example 3} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp3.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage[store-cmd=tikz]{scontents} \usepackage{tikz} \setlength{\parindent}{0pt} \pagestyle{empty} \Scontents{\matrix{ \node (a) {$a$} ; & \node (b) {$b$} ; \\ } ;} \Scontents{\matrix[ampersand replacement=\&] { \node (a) {$a$} ; \& \node (b) {$b$} ; \\ } ;} \Scontents{\matrix{\node (a) {$a$} ; & \node (b) {$b$} ; \\ } ; } \begin{document} \section{tikzpicture} \begin{tikzpicture} \getstored[1]{tikz} \end{tikzpicture} \begin{tikzpicture} \getstored[2]{tikz} \end{tikzpicture} \begin{tikzpicture} \getstored{tikz} \end{tikzpicture} \begin{scontents}[store-env=buffer] Hello World! This is a \verb*|fake poor man's buffer :)|. \end{scontents} \section{source tikz} \typestored[1]{tikz} \typestored[2]{tikz} \typestored[3]{tikz} \section{fake buffer} \subsection{real content} \getstored[1]{buffer} \subsection{verbatim style} \typestored[1]{buffer} \subsection{meaning} \meaningsc[1]{buffer} \section{tikz again} \foreachsc[before={\begin{tikzpicture}},after={\end{tikzpicture}},sep={\\[10pt]}]{tikz} \end{document} \end{scontents} % \iffalse % % \fi % % Adapted from \href{https://tex.stackexchange.com/q/5338/7832}{LaTeX equivalent of ConTeXt buffers} % \textattachfile[color=linkcolor,print=false]{scexamp3.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp3.ltx} % % \subsubsection*{Example 4} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp4.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage{scontents} \setlength{\parindent}{0pt} \pagestyle{empty} \begin{document} \begin{scontents}[store-env=main] Something for main A. \end{scontents} \begin{scontents}[store-env=main] Something for \verb|main B|. \end{scontents} \begin{scontents}[store-env=other] Something for \verb|other|. \end{scontents} \textbf{Let's print them} This is first stored in main: \getstored[1]{main}\par This is second stored in main: \getstored{main}\par This is stored in other: \getstored{other} \textbf{Print all of stored in main}\par \foreachsc[sep={\\[10pt]}]{main} \end{document} \end{scontents} % \iffalse % % \fi % % Adapted from \href{https://tex.stackexchange.com/q/184503/7832}{Collecting contents of environment and store them for later retrieval} % \textattachfile[color=linkcolor,print=false]{scexamp4.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp4.ltx} % % \subsubsection*{Example 5} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp5.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage{scontents} \setlength{\parindent}{0pt} \pagestyle{empty} \begin{document} \section{Problem stated the first time} \begin{scontents}[print-env=true,store-env=problem] This is normal text. \verb|This is from the verb command.| \verb*|This is from the verb* command.| This is normal text. \begin{verbatim} This is from the verbatim environment: &%{}~ \end{verbatim} \end{scontents} \section{Problem restated} \getstored[1]{problem} \section{Problem restated once more} \getstored[1]{problem} \end{document} \end{scontents} % \iffalse % % \fi % % Adapted from \href{https://tex.stackexchange.com/q/373647/7832}{Collect contents of an environment (that contains verbatim content)} % \textattachfile[color=linkcolor,print=false]{scexamp5.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp5.ltx} % % \subsubsection*{Example 6} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp6.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass[10pt]{article} \usepackage{scontents} \newenvsc{forshort}[store-env=forshort,print-env=false] \setlength{\parindent}{0pt} \pagestyle{empty} \begin{document} Something in the whole course. \begin{forshort} Just a summary... \end{forshort} \end{document} \end{scontents} % \iffalse % % \fi % % Adapted from \href{https://tex.stackexchange.com/q/509595/7832}{Environment hiding its content} % \textattachfile[color=linkcolor,print=false]{scexamp6.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp6.ltx} % % \subsection{Customization of \texttt{verbatimsc}} % % \subsubsection*{Example 7} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp7.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage{scontents} \ExplSyntaxOn \cs_undefine:N \verbatimsc \cs_undefine:N \endverbatimsc \ExplSyntaxOff \usepackage{fvextra} \usepackage{xcolor} \definecolor{mygray}{gray}{0.9} \usepackage{tcolorbox} \newenvironment{verbatimsc}% {\VerbatimEnvironment \begin{tcolorbox}[colback=mygray, boxsep=0pt, arc=0pt, boxrule=0pt] \begin{Verbatim}[fontsize=\scriptsize, breaklines, breakafter=*, breaksymbolsep=0.5em, breakaftersymbolpre={\,\tiny\ensuremath{\rfloor}}]}% {\end{Verbatim}% \end{tcolorbox}} \setlength{\parindent}{0pt} \pagestyle{empty} \begin{document} \section{Test \texttt{\textbackslash begin\{scontents\}} with \texttt{fancyvrb}} Test \verb+{scontents}+ \par \begin{scontents} Using \verb+scontents+ env no \verb+[key=val]+, save in seq \verb+contents+ with index 1. Prove new \Verb*{ fancyvrb with braces } and environment \verb+Verbatim*+ \begin{verbatim} verbatim environment \end{verbatim} \end{scontents} \section{Test \texttt{\textbackslash Scontents} with \texttt{fancyvrb}} \Scontents{ We have coded this in \LaTeX: $E=mc^2$.} \section{Test \texttt{\textbackslash getstored}} \getstored[1]{contents}\par \getstored{contents} \section{Test \texttt{\textbackslash meaningsc}} \meaningsc[1]{contents}\par \meaningsc[2]{contents} \section{Test \texttt{\textbackslash typestored}} \typestored[1]{contents} \typestored[2]{contents} \end{document} \end{scontents} % \iffalse % % \fi % % Customization of \myenv*{verbatimsc} using the \mypkg{fvextra}\cite{fvextra} and % \mypkg{tcolorbox}\cite{tcolorbox} package % \textattachfile[color=linkcolor,print=false]{scexamp7.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp7.ltx} % % \subsubsection*{Example 8} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp8.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage{scontents} \ExplSyntaxOn \cs_undefine:N \verbatimsc \cs_undefine:N \endverbatimsc \ExplSyntaxOff \usepackage{xcolor} \usepackage{listings} \lstnewenvironment{verbatimsc} { \lstset{ basicstyle=\small\ttfamily, breaklines=true, columns=fullflexible, language=[LaTeX]TeX, numbers=left, numbersep=1em, numberstyle=\tiny\color{gray}, keywordstyle=\color{red} } }{} \setlength{\parindent}{0pt} \pagestyle{empty} \begin{document} \section{Test \texttt{\textbackslash begin\{scontents\}} with \texttt{listings}} Test \verb+{scontents}+ \par \begin{scontents} Using \verb+scontents+ env no \verb+[key=val]+, save in seq \verb+contents+ with index 1.\par Prove \lstinline[basicstyle=\ttfamily]| lstinline | and environment \verb+Verbatim*+ \begin{verbatim} verbatim environment \end{verbatim} \end{scontents} \section{Test \texttt{\textbackslash Scontents*} with \texttt{listings}} \Scontents*+We have coded this in \lstinline[basicstyle=\ttfamily]|\LaTeX: $E=mc^2$| and more.+ \section{Test \texttt{\textbackslash getstored}} \getstored{contents}\par \getstored[1]{contents} \section{Test \texttt{\textbackslash typestored}} \typestored[1]{contents} \typestored[2]{contents} \end{document} \end{scontents} % \iffalse % % \fi % % Customization of \myenv*{verbatimsc} using the \mypkg{listings}\cite{listings} package % \textattachfile[color=linkcolor,print=false]{scexamp8.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp8.ltx} % % \subsubsection*{Example 9} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp9.ltx] % arara: xelatex: {shell: true, options: [-8bit]} % arara: xelatex: {shell: true, options: [-8bit]} % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage{scontents} \ExplSyntaxOn \cs_undefine:N \verbatimsc \cs_undefine:N \endverbatimsc \ExplSyntaxOff \usepackage{minted} \newminted{tex}{linenos} \newenvironment{verbatimsc}{\VerbatimEnvironment\begin{texcode}}{\end{texcode}} \pagestyle{empty} \setlength{\parindent}{0pt} \begin{document} \section{Test \texttt{\textbackslash begin\{scontents\}} with \texttt{minted}} Test \verb+{scontents}+ \par \begin{scontents}[overwrite,write-env=\jobname.tsc,force-eol=true] Using \verb+scontents+ env no \verb+[key=val]+, save in seq \verb+contents+ with index 1.\par Prove new \Verb*{ new fvextra with braces } and environment \verb+Verbatim*+ \begin{Verbatim}[obeytabs, showtabs, tab=\rightarrowfill, tabcolor=red] No tab One real tab Two real Tab plus one tab \end{Verbatim} \end{scontents} \section{See \Verb{\jobname.tsc}} Read \Verb{\jobname.tsc} (shows TABs as red arrows): \VerbatimInput[obeytabs, showtabs, tab=\rightarrowfill, tabcolor=red]{\jobname.tsc} \section{Test \texttt{\textbackslash Scontents} with \texttt{minted}} \Scontents{ We have coded \par this in \LaTeX: $E=mc^2$.} \section{Test \texttt{\textbackslash getstored}} \getstored[1]{contents}\par \getstored{contents} \section{Test \texttt{\textbackslash typestored}} \typestored[1]{contents} \typestored[2]{contents} \end{document} \end{scontents} % \iffalse % % \fi % % Customization of \myenv*{verbatimsc} using the \mypkg{minted}\cite{minted} package % \textattachfile[color=linkcolor,print=false]{scexamp9.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp9.ltx} % % \subsection{The command \texttt{\textbackslash{}mergesc} in action} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp10.ltx] % arara: pdflatex % arara: clean: { extensions: [ aux, log] } \documentclass{article} \usepackage{scontents} % Fix part of a MCE that should go before babel's loading \begin{scontents}[store-env=mce] \documentclass[french]{article} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{lmodern} \usepackage[a4paper]{geometry} \end{scontents} % Fix part of a MCE that should go after (>=) babel's loading \begin{scontents}[store-env=mce] \usepackage{babel} \begin{document} \end{scontents} % Fix part of a MCE that should go after its body \begin{scontents}[store-env=mce] \end{document} \end{scontents} \begin{document} \section{First annswer} % Variable part of a MCE that should added to the fixed preamble, before babel's loading \begin{scontents}[store-env=mce-1] \usepackage{amsmath} \end{scontents} % Variable part of a MCE being the code snippet \begin{scontents}[store-env=mce-1] \begin{align} 0 & \neq 1 \\ 1 & \neq 0 \end{align} \end{scontents} \begin{description} \item[Preamble's addition]\leavevmode \typestored[1]{mce-1} \item[Code snippet]\leavevmode \typestored[2]{mce-1} \item[MCE]\leavevmode \mergesc[typestored, print-cmd=true] { {mce}[1], {mce-1}[1], {mce}[2], {mce-1}[2], {mce}[3] } \end{description} \section{Second annswer} % Variable part of a MCE that should added to the fixed preamble, before babel's loading \begin{scontents}[store-env=mce-2] \usepackage{amsmath} \end{scontents} % Variable part of a MCE being the code snippet \begin{scontents}[store-env=mce-2] \begin{flalign} 0 & \neq 1 \\ 1 & \neq 0 \end{flalign} \end{scontents} \begin{description} \item[Preamble's addition]\leavevmode \typestored[1]{mce-2} \item[Code snippet]\leavevmode \typestored[2]{mce-2} \item[MCE]\leavevmode \mergesc[typestored, print-cmd=true, write-out=mce.txt, overwrite=true] { {mce}[1], {mce-2}[1], {mce}[2], {mce-2}[2], {mce}[3] } \end{description} \end{document} \end{scontents} % \iffalse % % \fi % The command §\mergesc§ in action, adapted from Denis Bitouzé request % at \url{https://github.com/pablgonz/scontents/issues/2} % \textattachfile[color=linkcolor,print=false]{scexamp10.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp10.ltx} % % \subsection{The tagged PDF example} % % \iffalse %<*example> % \fi \begin{scontents}[write-out=scexamp11.ltx] % arara: lualatex % arara: clean: { extensions: [ aux, log] } \DocumentMetadata{tagging=on, lang=en-US, pdfversion=2.0, pdfstandard=ua-2, testphase=latest} \documentclass{article} \usepackage{scontents,unicode-math,hyperref} \hypersetup{pdftitle = {Test scontents package},} \begin{document} Some \begin{scontents}[print-env=true] First code \verb|\foo| And more code \verb|\bar| \end{scontents} Text \begin{scontents}[print-env=true] Second code \verb|\foo| And more code \verb|\bar| \end{scontents} Text \Scontents*{code \verb|\baz|} % \typestored \typestored[1]{contents} % \mergesc \mergesc[typestored]{ {contents}[1-end] } % \getstored \getstored[2]{contents} \end{document} \end{scontents} % \iffalse % % \fi % % This example is just to show the compatibility of \mypkg*{scontents} with % \emph{tagged} \texttt{PDF} using |lualatex|. The attached files here % are just for testing \textattachfile[color=linkcolor,print=false]{scexamp11.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp11.ltx} % % \begin{important}* % This example have been checked using \href{https://dev.verapdf-rest.duallab.com}{\texttt{veraPDF}} % together with \href{https://ngpdf.com}{\texttt{ngpdf}}. % \end{important} % % % \newpage % % \section{Change history} % \label{sec:changes} % % In this section you will find some (not all) of the changes in \mypkg*{scontents} % development, from the first public implementation using the \mypkg{filecontentsdef}\cite{filecontentsdef} % package to the current version with only \mypkg{expl3}\cite{expl3}. % % \medskip % % \setlist[itemize,1]{label=\textendash,wide=0.5em,nosep,noitemsep,leftmargin=10pt} % \newlength\descrwidth % \settowidth{\descrwidth}{\textsf{v1.0a, (ctan), 2019-07-30} } % % \begin{description}[font=\small\sffamily,wide=0pt,style=multiline,leftmargin=\descrwidth,nosep,noitemsep] % \item [\fileversion{} (ctan), \filedate] % \begin{itemize} % \item Optimization of expansion code from `§x§' to `§e§'. % \item Restructuring code for documentation and implementation. % \item Add new keys for §\typestored§ and §\meaningsc§. % \item Check the version of \mypkg{expl3} in \hologo{plainTeX} and \hologo{ConTeXt}. % \end{itemize} % \item [v2.3 (ctan), 2025-04-23] % \begin{itemize} % \item Adapting the §verbatimsc§ environment for \emph{tagged} \texttt{PDF}. % \item Update minimum required to \LaTeX{} release 2024-11-01. % \item Safer code for replacement §\obeyedline§. % \end{itemize} % \item [v2.2 (ctan), 2025-03-26] % \begin{itemize} % \item Fix internal definition for some functions. % \item Replace §\peek_charcode_ignore_spaces:NTF§ by §\peek_charcode:NTF§. % \item Set correct code for §\obeyedline§ implement in \LaTeX{} release 2024-06-01. % \end{itemize} % \item [v2.1 (ctan), 2024-06-14] % \begin{itemize} % \item Fix §\cleanseqsc§ command. % \item Add §\mergesc§ command. % \item Fix internal definition for seq var. % \item Fix internal code for §\typestored§. % \item Replace §\cs_argument_spec:N§ by §\cs_parameter_spec:N§. % \item Detect \mypkg{l3keys2e} package (obsolete in june 2022 \LaTeX{} release). % \item Minor adjustments in the documentation. % \end{itemize} % \item [v2.0 (ctan), 2022-04-04] % \begin{itemize} % \item Adapting the §verbatimsc§ environment (compatibility \mypkg{verbatim} package). % \item Removed compatibility layer for older \hologo{LaTeX} releases. % \item Fix loader in \hologo{plainTeX} and \hologo{ConTeXt}. % \item Minor adjustments in the documentation. % \end{itemize} % \item [v1.9 (ctan), 2020-01-21] % \begin{itemize} % \item Update and improvements in the internal code. % \item Updating the generic code for |I/O| verification. % \item Add §write-cmd§ and §write-out§ keys for §\Scontents*§. % \item Fix §sep§ key in §\foreachsc§. % \end{itemize} % \item [v1.8 (ctan), 2019-11-18] % \begin{itemize} % \item Add §\newenvsc§ command. % \item Fix nested environment in \hologo{plainTeX} and \hologo{ConTeXt}. % \item Modified default value in §\getstored§. % \item Add §overwrite§ key to reduce |I/O| operations. % \item Deleted an unnecessary group in the code. % \end{itemize} % \item [v1.7 (ctan), 2019-10-29] % \begin{itemize} % \item The §verbatimsc§ environment was rewritten. % \item Minor adjustments in documentation. % \end{itemize} % \item [v1.6 (ctan), 2019-10-26] % \begin{itemize} % \item The internal behavior of §\getstored§ has been modified. % \item The internal behavior of §\foreachsc§ has been modified. % \item Corrected file extension for \hologo{ConTeXt}. % \item Remove spurious warning. % \end{itemize} % \item [v1.5 (ctan), 2019-10-24] % \begin{itemize} % \item Add support for \hologo{plainTeX} and \hologo{ConTeXt}. % \item Split internal code for optimization. % \item Add support for vertical spaces in \myoarg{key \textnormal{\textcolor{gray}{=}} val}. % \item Add §\foreachsc§ command. % \item Check if \mypkg{verbatim} package is loaded. % \end{itemize} % \item [v1.4 (ctan), 2019-10-03] % \begin{itemize} % \item Add §store-all§ key. % \item Messages and keys were separated. % \item Restructuring of documentation. % \item Now the version of \mypkg{expl3} is checked instead of \mypkg{xparse}. % \item The internal behavior of §force-eol§ has been modified. % \end{itemize} % \item [v1.3 (ctan), 2019-09-24] % \begin{itemize} % \item The environment §scontents§ can now nest. % \item Added §force-eol§, §verb-font§ and §width-tab§ keys. % \item The extra space has been removed when you run §\getstored§. % \item Internal code has been rewritten more efficiently. % \item Remove \emph{starred argument} `§*§' for §\typestored§. % \item Remove \mypkg{filecontentsdef} dependency. % \item Changing §\regex_replace_all:§ for §\tl_replace_all:§. % \end{itemize} % \item [v1.2 (ctan), 2019-08-28] % \begin{itemize} % \item Restructuring of documentation. % \item Added copy of §\tex_scantokens:§. % \end{itemize} % \item [v1.1 (ctan), 2019-08-12] % \begin{itemize} % \item Extension of documentation. % \item Replace §\tex_endinput:D§ by §\file_input_stop:§. % \end{itemize} % \item [v1.0 (ctan), 2019-07-30] % \begin{itemize} % \item First public release. % \end{itemize} % \end{description} % % \newpage % % \indexprologue{ % The italic numbers denote the pages where the corresponding entry is % described.} % % \printindex[userdoc] % % \let\stdsection\section % \def\section*#1{\stdsection{#1}} % % \begin{thebibliography}{10} % \bibitem{expl3} The \hologo{LaTeX} Project. \enquote{The \textsf{expl3} % package}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/expl3}, 2025. % % \bibitem{filecontentsdef} \textsc{Burnol, Jean François}. \enquote{The % \textsf{filecontentsdef} package}. Available from % \textsc{ctan}, \url{https://ctan.org/pkg/filecontentsdef}, 2019. % % \bibitem{xparse} The \hologo{LaTeX} Project. \enquote{The \textsf{xparse} % package}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/xparse}, 2024. % % \bibitem{xsim} \textsc{Niederberger, Clemens}. \enquote{\textsf{xsim} – eXercise % Sheets IMproved}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/xsim}, 2023. % % \bibitem{fancyvrb} \textsc{Van Zandt, Timothy}. \enquote{The \textsf{fancyvrb} % package - Fancy Verbatims in \hologo{LaTeX}}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/fancyvrb}, 2024. % % \bibitem{listings} \textsc{Hoffmann, Jobst}. \enquote{The \textsf{listings} % package}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/listings}, 2024. % % \bibitem{fvextra} \textsc{Poore, Geoffrey M}. \enquote{The \textsf{fvextra} % package - Highlighted source code in \hologo{LaTeX}}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/minted}, 2025. % % \bibitem{minted} \textsc{Poore, Geoffrey M}. \enquote{The \textsf{minted} % package - Highlighted source code in \hologo{LaTeX}}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/minted}, 2025. % % \bibitem{inter3} The \hologo{LaTeX} Project. \enquote{The \hologo{LaTeX}3 % Interfaces}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/l3kernel}, 2025. % % \bibitem{latex2e} The \hologo{LaTeX} Project. \enquote{The \hologo{LaTeX2e} % sources}. Available from % \textsc{ctan}, \url{https://ctan.org/tex-archive/macros/latex/base}, 2025. % % \bibitem{userguide} The \hologo{LaTeX} Project. \enquote{\hologo{LaTeX} for authors % current version}. Available from % \textsc{ctan}, \url{https://ctan.org/pkg/latex-base}, 2025. % % \bibitem{tagpdf} \textsc{Fischer, Ulrike}. \enquote{\textsf{tagpdf} – \hologo{LaTeX} % kernel code for PDF tagging}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/tagpdf}, 2025. % % \bibitem{latexlab} The \hologo{LaTeX} Project. \enquote{\textsf{latex-lab} – \hologo{LaTeX} % laboratory}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/latex-lab}, 2025. % % \bibitem{tcolorbox} \textsc{F. Sturm, Thomas}. \enquote{\textsf{tcolorbox} – Coloured boxes, % for \hologo{LaTeX} examples and theorems, etc}. Available from % \textsc{ctan}, \url{https://ctan.org/pkg/tcolorbox}, 2025. % % \bibitem{verbatim} The \hologo{LaTeX} Project. \enquote{\textsf{verbatim} – Reimplementation % of and extensions to \hologo{LaTeX} \textsf{verbatim}}. Available from % \textsc{ctan}, \url{https://www.ctan.org/pkg/verbatim}, 2023. % % \bibitem{keyval} \textsc{Wright, Joseph}. \enquote{Programming % \textsf{key–value} in \textsf{expl3}}. Available from % \textsc{TUGboat}, % \url{https://www.tug.org/TUGboat/tb31-1/tb97wright-l3keys.pdf}, 2010. % % \bibitem{answers} \textsc{Wright, Joseph}. \enquote{\textsf{answers} – Setting % questions (or exercises) and answers}. Available from % \textsc{ctan}, % \url{https://ctan.org/pkg/answers}, 2014. % \end{thebibliography} % % \let\section\stdsection % % \newpage % % \StartImplementation % % \StopEventually{^^A % \newgeometry{top=0.5in,bottom=0.3in,left=1.0in,right=0.5in,footskip=0.2in,headheight=1cm,headsep=0.27cm} % \addtocontents{toc}{\protect\setcounter{tocdepth}{2}} % \cleardoublepage % \phantomsection % \indexprologue{ % The italic numbers denote the pages where the corresponding entry is % described, the numbers underlined and all others indicate the line on % which they are implemented in the package code. % } % \printindex % } % % \section{Implementation} % \label{sec:Implementation} % \addtocontents{toc}{\protect\setcounter{tocdepth}{0}} % % The most recent publicly released version of \mypkg*{scontents} is available at % \textsc{ctan}: \url{https://www.ctan.org/pkg/scontents}. Historical and % developmental versions are available at \textcolor{gray}{\scriptsize\faIcon[regular]{github}} % \url{https://github.com/pablgonz/scontents}. While general feedback via email is % welcomed, specific bugs or feature requests should be reported through the issue % tracker: \url{https://github.com/pablgonz/scontents/issues}. % % \begin{important}* % All variables and functions defined in this package are private and % are NOT intended to work or be used by another package or module. % \end{important} % % \subsection{Declaration of the package} % % First we set up the module name for \pkg{DocStrip} \pkg{l3doc} class: % \begin{macrocode} %<@@=scontents> % \end{macrocode} % % Now we define some common macros to hold the package date and version: % \begin{macrocode} %\def\ScontentsFileDate{2025-05-15}% %\def\ScontentsCoreFileDate{2025-05-15}% %<*loader> \def\ScontentsFileVersion{2.4}% \def\ScontentsFileDescription{Stores LaTeX contents in memory or files}% % \end{macrocode} % % The \LaTeX{} loader is quite simple, we just need to make sure of the % minimum version for correct operation and then set interfaces up. % The choice of \LaTeX{} release 2024-11-01 is the latest available in % \TeX{} Live 2024 (frozen) and is necessary to be able to implement % the package's full compatibility with \emph{tagged} \texttt{PDF}. % % \begin{macrocode} %<*latex> \NeedsTeXFormat{LaTeX2e}[2024-11-01] \ProvidesExplPackage {scontents} {\ScontentsFileDate} {\ScontentsFileVersion} {\ScontentsFileDescription} % % \end{macrocode} % % The \hologo{plainTeX} and \hologo{ConTeXt} loaders are similar % (probably because I don't know how to make a proper \hologo{ConTeXt} % module :-). We define a \LaTeX{}-style §\ver@scontents.sty§ macro with % version info (just in case) and add §\ExplSyntaxOn§ to be able to load % the frozen \mypkg{xparse}\cite{xparse} later (\S\ref{comp:layer}). % \begin{macrocode} %<*!latex> %\writestatus{loading}{User Module scontents v\ScontentsFileVersion} %\unprotect \input expl3-generic.tex \ExplSyntaxOn \tl_gset:ce { ver @ scontents . sty } { \ScontentsFileDate\space v\ScontentsFileVersion\space \ScontentsFileDescription } \iow_log:e { Package: ~ scontents ~ \use:c { ver @ scontents . sty } } % \end{macrocode} % For \hologo{plainTeX} and \hologo{ConTeXt} we must check the minimum % requirement, in this case §\int_step_tokens:nn§ which % was added in release 2025-01-14 of \mypkg{expl3} included in % \hologo{TeX} Live 2024 (frozen). % \begin{macrocode} \cs_if_exist:NF \int_step_tokens:nn { \msg_new:nnn { scontents } { expl-too-old } { Please~install~an~up~to~date~TeX~distribution~or~update~using~ your~TeX~package~manager~or~from~CTAN. \\ See~documentation.~Loading~scontents~will~abort! } \msg_fatal:nn { scontents } { expl-too-old } \ExplSyntaxOff \file_input_stop: } % % \end{macrocode} % In \hologo{plainTeX}, check that the package isn't being loaded twice % (\LaTeX{} and \hologo{ConTeXt} already defend against that): % \begin{macrocode} %<*plain> \cs_if_exist:NT \@@_rescan_tokens:n { \msg_new:nnn { scontents } { already-loaded } { The~'scontents'~package~is~already~loaded.~Aborting~input~\msg_line_context:. } \msg_warning:nn { scontents } { already-loaded } \ExplSyntaxOff \file_input_stop: } % % \end{macrocode} % In \hologo{ConTeXt} we must take a precaution when running under LMTX % since §\tex_scantokens:D§ is a copy of the primitive \hologo{eTeX} % §\scantokens§ and §\tl_gset_rescan:Nnn§ is a wrapper around it and are % not available under LMTX. % \begin{important}* % This is an adaptation of the file \texttt{t-lua-widow-control.mkxl} part % of Max Chernoff's \mypkg{lua-widow-control} package, §\contextlmtxmode§ % is described at \url{https://source.contextgarden.net/tex/context/base/mkxl/context.mkxl}. % \end{important} % \begin{macrocode} %<*context> \bool_if:NT \contextlmtxmode { \msg_new:nnn { scontents } { luametatex } { The~'scontents'~package~doesn't~work~under~LMTX. } \msg_error:nn { scontents } { luametatex } } % % % \end{macrocode} % % \subsubsection{Load \texttt{xparse-generic} in \hologo{plainTeX} and \hologo{ConTeXt}}\label{comp:layer} % % \begin{macro}{\l_@@_char_value_int} % When loading the package outside of \LaTeX{} we can't usually use % \mypkg{xparse}\cite{xparse} now \mypkg{ltcmd}\cite{latex2e} part of % the \LaTeX{} kernel. However since the old \mypkg{xparse}\cite{xparse} % provide \texttt{xparse-generic.tex} is loadable in any format. % \begin{macrocode} %<*loader&!latex> \int_new:N \l_@@_char_value_int \int_set:Nn \l_@@_char_value_int { \char_value_catcode:n { `\@ } } \char_set_catcode_letter:N \@ \file_input:n { xparse-generic.tex } \char_set_catcode:nn { `\@ } { \l_@@_char_value_int } % % \end{macrocode} % \begin{important}* % The file \texttt{TDS:/tex/latex/l3packages/xparse/xparse-generic.tex} % is always available and frozen since 2021. % \end{important} % \end{macro} % % \subsubsection{Definition of variables by format} % % We define and set variables that must be handled separately in order % to work properly with \hologo{plainTeX}, \hologo{ConTeXt} and \LaTeX. % % \begin{macro}{\g_@@_end_verbatimsc_tl, \c_@@_end_env_tl, % \l_@@_env_name_tl,} % The global token list \cs{g_@@_end_verbatimsc_tl} match when ending % §verbatimsc§ (\S\ref{env:verbatimsc}). % \begin{macrocode} %<*loader> \tl_new:N \g_@@_end_verbatimsc_tl \tl_gset_rescan:Nnn \g_@@_end_verbatimsc_tl { \char_set_catcode_other:N \\ %<*latex> \char_set_catcode_other:N \{ \char_set_catcode_other:N \} % } % { \end{verbatimsc} } % { \endverbatimsc } % { \stopverbatimsc } % \end{macrocode} % The constant token list \cs{c_@@_end_env_tl} match when ending % environments defined by §\newenvsc§, the token list\cs{l_@@_env_name_tl} % storing the \emph{name} of environments defined by §\newenvsc§ (\S\ref{cmd:newenvsc}). % \begin{macrocode} \tl_new:N \l_@@_env_name_tl \tl_const:Ne \c_@@_end_env_tl { \c_backslash_str % end % stop % \c_left_brace_str \exp_not:N \l_@@_env_name_tl % \c_right_brace_str } % % \end{macrocode} % \end{macro} % % \subsubsection{Loading the package core} % % Now we load the core \mypkg*{scontents} code: % \begin{macrocode} %<*loader> \file_input:n { scontents-code.tex } % \end{macrocode} % \begin{macro}{\@@_format_case:nnn} % Sometimes we need to detect the format from within a macro: % \begin{macrocode} \cs_new:Npn \@@_format_case:nnn #1 #2 #3 % {#1} % LaTeX % {#2} % Plain/Generic % {#3} % ConTeXt % % \end{macrocode} % \end{macro} % % \subsubsection{Checking proper loader} % % Checking that the package was loaded with the proper loader code. This code % was copied from \texttt{expl3-code.tex}. % \begin{macrocode} %<*core> \begingroup \catcode32=10 \endlinechar=32 \def\next{\endgroup}% \expandafter\ifx\csname PackageError\endcsname\relax \begingroup \def\next{\endgroup\endgroup}% \def\PackageError#1#2#3% {% \endgroup \errhelp{#3}% \errmessage{#1 Error: #2!}% }% \fi \expandafter\ifx\csname ScontentsFileDate\endcsname\relax \def\next {% \PackageError{scontents}{No scontents loader detected} {% You have attempted to use the scontents code directly rather than using the correct loader. Loading of scontents will abort. }% \endgroup \endinput }% \else \ifx\ScontentsFileDate\ScontentsCoreFileDate \else \def\next {% \PackageError{scontents}{Mismatched scontents files detected} {% You have attempted to load scontents with mismatched files: probably you have one or more files 'locally installed' which are in conflict. Loading of scontents will abort. }% \endgroup \endinput }% \fi \fi \next % \end{macrocode} % % \subsection{Keys for the package} % % \begin{macro}[int]{store-env, store-cmd,verb-font,print-env,print-cmd, % force-eol, overwrite, width-tab, print-all, store-all} % We create some common \mymeta{keys} that will be used by the options % passed to the package as well as by the environments and commands % defined. % \begin{macrocode} \keys_define:nn { scontents } { store-env .tl_set:N = \l_@@_name_seq_env_tl, store-env .initial:n = contents, store-env .value_required:n = true, store-cmd .tl_set:N = \l_@@_name_seq_cmd_tl, store-cmd .initial:n = contents, store-cmd .value_required:n = true, verb-font .tl_set:N = \l_@@_verb_font_tl, verb-font .value_required:n = true, print-env .bool_set:N = \l_@@_print_env_bool, print-env .initial:n = false, print-env .default:n = true, print-cmd .bool_set:N = \l_@@_print_cmd_bool, print-cmd .initial:n = false, print-cmd .default:n = true, force-eol .bool_set:N = \l_@@_forced_eol_bool, force-eol .initial:n = false, force-eol .default:n = true, overwrite .bool_set:N = \l_@@_overwrite_bool, overwrite .initial:n = false, overwrite .default:n = true, width-tab .int_set:N = \l_@@_tab_width_int, width-tab .initial:n = 1, width-tab .value_required:n = true, print-all .meta:n = { print-env = #1, print-cmd = #1 }, print-all .default:n = true, store-all .meta:n = { store-env = #1, store-cmd = #1 }, store-all .value_required:n = true } % % \end{macrocode} % Set default value for §verb-font§ key. % \begin{macrocode} %\keys_define:nn { scontents } % { verb-font .initial:n = \ttfamily } % { verb-font .initial:n = \tt } % \end{macrocode} % In \LaTeX{} mode process the \mymeta{keys} as options passed on to the % package and will return an error when they are. % \begin{macrocode} %<*latex> \ProcessKeyOptions [ scontents ] % % \end{macrocode} % \end{macro} % % \subsection{Internal variables} % % \begin{macro}{\l_@@_save_every_body_lines_tl, \l_@@_processed_body_lines_tl, % \l_@@_environment_keys_tl, \l_@@_nesting_env_int, % \l_@@_nesting_aux_int,} % The token list \cs{l_@@_save_every_body_lines_tl} holds the % \mymarg{body env} of an environment, §scontents§ by default, as it's % being read, the token list \cs{l_@@_processed_body_lines_tl} saves % all sanitized lines saved in \cs{l_@@_save_every_body_lines_tl}. % % The token list \cs{l_@@_environment_keys_tl} saves the \mymeta{keys} % passed to the \emph{optional argument} after they are sanitized and % the integer variables \cs{l_@@_nesting_env_int} together with % \cs{l_@@_nesting_aux_int} are used to analyze the nesting of the % environment. % \begin{important}* % All of these variables are used in the implementation of §\newenvsc§ % (\S\ref{cmd:newenvsc}) and the environments base functions (\S\ref{fun:base:env}). % \end{important} % \begin{macrocode} %<*core> \tl_new:N \l_@@_save_every_body_lines_tl \tl_new:N \l_@@_processed_body_lines_tl \tl_new:N \l_@@_environment_keys_tl \int_new:N \l_@@_nesting_env_int \int_new:N \l_@@_nesting_aux_int % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_cmd_name_tl,} % The token list \cs{l_@@_cmd_name_tl} saves the \emph{name} of the % commands §\Scontents§, §\foreachsc§, §\typestored§, §\meaningsc§ % and §\mergesc§. % \begin{macrocode} \tl_new:N \l_@@_cmd_name_tl % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_Scontents_arg_tl, \l_@@_foreachsc_arg_tl, % \l_@@_typestored_arg_tl, \l_@@_meaningsc_arg_tl, % \l_@@_mergesc_arg_tl,} % The token lists \cs{l_@@_Scontents_arg_tl}, \cs{l_@@_foreachsc_arg_tl}, % \cs{l_@@_typestored_arg_tl} and \cs{l_@@_meaningsc_arg_tl} save the % \mymarg{argument} passed to the §\Scontents§ (\S\ref{cmd:Scontents}), % §\foreachsc§ (\S\ref{cmd:foreachsc}), §\typestored§ (\S\ref{cmd:typestored}) % and §\meaningsc§ (\S\ref{cmd:meaningsc}) commands. % \begin{macrocode} \tl_new:N \l_@@_Scontents_arg_tl \tl_new:N \l_@@_foreachsc_arg_tl \tl_new:N \l_@@_typestored_arg_tl \tl_new:N \l_@@_meaningsc_arg_tl % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_mergesc_arg_tl, \l_@@_mergesc_keys_tl, % \l_@@_current_seq_name_str,} % The token list \cs{l_@@_mergesc_arg_tl} save the \mymarg{argument} % and the token list \cs{l_@@_mergesc_keys_tl} save the \mymeta{keys} % passed to the §\mergesc§ (\S\ref{cmd:mergesc}) command. % % The string variable \cs{l_@@_current_seq_name_str} stores the name of % the \emph{current sequence} passed as an \mymarg{argument} to the % §\typestored§ and §\meaningsc§ commands and is used by the function % \cs{@@_parse_type_meaning_key:n}. % \begin{macrocode} \tl_new:N \l_@@_mergesc_arg_tl \tl_new:N \l_@@_mergesc_keys_tl \str_new:N \l_@@_current_seq_name_str % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_file_name_tl, \l_@@_file_write_iow, % \l_@@_writing_bool, l_@@_storing_bool, % \l_@@_writable_bool,} % The token list \cs{l_@@_file_name_tl} is used for store the name of % the \mymeta{output file}, when there's one. Its value is set by the % keys §write-env§, §write-out§ and §write-cmd§ (\S\ref{keys:env}). % % The variable \cs{l_@@_file_write_iow} is an \emph{output stream} for % write the \mymarg{body env} of an environment or \mymarg{argument} % for command to a \mymeta{output file} when the keys §write-env§, % §write-out§ or §write-cmd§ are active. % % The boolean variables \cs{l_@@_writing_bool} and \cs{l_@@_storing_bool} % (true by default) set by the §write-out§, §write-env§ and §write-cmd§ keys determine % whether the content is stored and written or just written to a \mymeta{output file}. % % The boolean variable \cs{l_@@_writable_bool} keeps track of whether % we should write to a file, it is in write-only or in mode overwrite % when the key §overwrite§ is used. % \begin{important}* % This variable is used by the function \cs{@@_file_if_writable:nTF} % (see \ref{fun:save:body}). % \end{important} % % \begin{macrocode} \tl_new:N \l_@@_file_name_tl \iow_new:N \l_@@_file_write_iow \bool_new:N \l_@@_writing_bool \bool_new:N \l_@@_storing_bool \bool_set_true:N \l_@@_storing_bool \bool_new:N \l_@@_writable_bool % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_foreach_print_seq, \g_@@_foreach_exec_tl, % \l_@@_foreach_before_tl, \l_@@_foreach_before_bool, % \l_@@_foreach_after_tl, \l_@@_foreach_after_bool, % \l_@@_foreach_stop_int, \l_@@_foreach_before_bool, % \l_@@_foreach_wrapper_bool} % Internal variables used by \mymeta{keys} (\S\ref{keys:foreachsc}) % and implementation of §\foreachsc§ command (\S\ref{cmd:foreachsc}). % \begin{macrocode} \seq_new:N \l_@@_foreach_print_seq \tl_new:N \g_@@_foreach_exec_tl \tl_new:N \l_@@_foreach_before_tl \bool_new:N \l_@@_foreach_before_bool \tl_new:N \l_@@_foreach_after_tl \bool_new:N \l_@@_foreach_after_bool \int_new:N \l_@@_foreach_stop_int \bool_new:N \l_@@_foreach_stop_bool \bool_new:N \l_@@_foreach_wrapper_bool % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_seq_item_seq, \g_@@_name_sc!internal_seq,} % The sequence variable \cs{l_@@_seq_item_seq} save the \mymeta{indexes} in the % \emph{sequence} of the items requested to §\typestored§, §\mergesc§ % or §\meaningsc§ and the sequence \cs{g_@@_name_sc!internal_seq} assemble this. % \begin{macrocode} \seq_new:N \l_@@_seq_item_seq \seq_new:c { g_@@_name_sc!internal_seq } % \end{macrocode} % \end{macro} % % \begin{macro}{\g_@@_last_stored_tl} % The token list \cs{g_@@_last_stored_tl} used by the function % \cs{@@_lastfrom_seq:n} (\S\ref{impl:seq:funct}) to execute the % last \mymeta{stored content} outside the group. % \begin{macrocode} \tl_new:N \g_@@_last_stored_tl % \end{macrocode} % \end{macro} % % \begin{macro}{\c_@@_hidden_space_str} % The variable \cs{c_@@_hidden_space_str} is a constant \emph{string} % to used to hide the \mymeta{forced space} added by \hologo{TeX} when % recording content in a macro. This \emph{string} contains the \emph{reserved phrase} % `§%§§^^Ascheol%§' which is added to the end of the \mymarg{argument} stored % in \emph{sequence} when the key §force-eol§ is false. % \begin{macrocode} \str_const:Ne \c_@@_hidden_space_str { \c_percent_str \c_circumflex_str \c_circumflex_str A scheol \c_percent_str } % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_save_sf_int,\l_@@_save_skip} % Internal variables used by functions \cs{@@_bsphack:} and % \cs{@@_esphack:} (\S\ref{func:sphack}). % \begin{macrocode} \int_new:N \l_@@_save_sf_int \skip_new:N \l_@@_save_skip % \end{macrocode} % \end{macro} % % \begin{macro}{\q_@@_stop,\q_@@_mark,\s_@@_stop,\s_@@_mark} % Some quarks and scan's used along the code as macro delimiters. % \begin{macrocode} \quark_new:N \q_@@_stop \quark_new:N \q_@@_mark \scan_new:N \s_@@_stop \scan_new:N \s_@@_mark % % \end{macrocode} % \end{macro} % % \begin{macro}{\l_@@_plain_bool} % The boolean variable \cs{l_@@_plain_bool} used in the \hologo{plainTeX} % implementation of the §verbatimsc§ environment (\S\ref{env:verbatimsc}). % \begin{macrocode} %<*plain> \bool_new:N \l_@@_plain_bool % % \end{macrocode} % \end{macro} % % \subsection{Utility functions} % % \begin{macro}{\@@_rescan_tokens:n,\@@_rescan_tokens:V,\@@_rescan_tokens:e} % The function §\tl_rescan:nn§ provided by \mypkg{expl3} doesn't fit % the needs of this package because it does not allow \emph{catcode changes} % inside the argument, so verbatim used inside one of \mypkg*{scontents}'s % commands/environments will not work. Here we create a private copy % of §\tex_scantokens:D§ which will serve our purposes. See the answer % by Ulrich Diez in \href{https://tex.stackexchange.com/a/577183/7832}{How do use % \{\} in \textbackslash tl_set_rescan:Nnn to replace % \textbackslash scantokens?} % % \begin{macrocode} %<*core> \cs_new_protected:Npn \@@_rescan_tokens:n #1 { \tex_scantokens:D {#1} } \cs_generate_variant:Nn \@@_rescan_tokens:n { V, e } % \end{macrocode} % \end{macro} % % \begin{macro}[int]{\tl_if_empty:fTF} % Some nonstandard kernel variant. % \begin{macrocode} \prg_generate_conditional_variant:Nnn \tl_if_empty:n { f } { p, TF } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_use_delimit_by_s_stop:nw, % \@@_use_i_delimit_by_s_stop:nw, % \@@_use_none_delimit_by_s_stop:w, % \@@_use_none_delimit_by_q_stop:w,} % Some functions used in the implementation of §\mergesc§ (\S\ref{cmd:mergesc}) % and §scontents§ (\S\ref{env:scontents}). % \begin{macrocode} \cs_new:Npn \@@_use_delimit_by_s_stop:nw #1 \s_@@_stop {#1} \cs_new:Npn \@@_use_i_delimit_by_s_stop:nw #1 #2 \s_@@_stop {#1} \cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { } \cs_new:Npn \@@_use_none_delimit_by_q_stop:w #1 \q_@@_stop { } % \end{macrocode} % \end{macro} % % \begin{macro}[TF]{\@@_tl_if_head_is_q_mark:n} % The conditional function \cs{@@_tl_if_head_is_q_mark:n} tests % if the head of the token list is \cs{q_@@_mark}. % \begin{macrocode} \prg_new_protected_conditional:Npnn \@@_tl_if_head_is_q_mark:n #1 { T, F, TF } { \exp_after:wN \if_meaning:w \exp_after:wN \q_@@_mark \@@_use_i_delimit_by_s_stop:nw #1 ? \s_@@_stop \prg_return_true: \else: \prg_return_false: \fi: } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_file_if_writable:n, \@@_file_if_writable:nT, % \@@_file_if_writable:nF, \@@_file_if_writable:nTF,} % The conditional function \cs{@@_file_if_writable:n} used by the §write-env§, % §write-cmd§, §write-out§ and §overwrite§ keys. % \begin{macrocode} \prg_new_protected_conditional:Npnn \@@_file_if_writable:n #1 { T, F, TF } { \bool_if:NTF \l_@@_writing_bool { \file_if_exist:nTF {#1} { \bool_if:NTF \l_@@_overwrite_bool { \msg_warning:nne { scontents } { overwrite-file } {#1} \prg_return_true: } { \msg_warning:nne { scontents } { not-writing } {#1} \prg_return_false: } } { \msg_warning:nne { scontents } { writing-file } {#1} \prg_return_true: } } { \prg_return_false: } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_file_write_cmd:nn, \@@_file_write_cmd:VV,} % The function \cs{@@_file_write_cmd:nn} used by the §write-env§, % §write-cmd§, §write-out§ and §overwrite§ keys for commands. % \begin{macrocode} \cs_new_protected:Npn \@@_file_write_cmd:nn #1#2 { \@@_file_if_writable:nT {#1} { \iow_open:Nn \l_@@_file_write_iow {#1} \iow_now:Nn \l_@@_file_write_iow {#2} \iow_close:N \l_@@_file_write_iow } } \cs_generate_variant:Nn \@@_file_write_cmd:nn { VV } % \end{macrocode} % \end{macro} % % \subsubsection{Functions for \texttt{TAB} and \texttt{verbatimsc}} % % \begin{macro}{\@@_tab:,\@@_par:} % Control sequences to replace tab `§^^I§' and form feed `§^^L§' % characters. % \begin{macrocode} \cs_new:Ne \@@_tab: { \c_space_tl } \cs_new:Nn \@@_par: { ^^J ^^J } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_tabs_to_spaces:} % In a \emph{verbatim} context the \texttt{TAB} character is made active % and set equal to \cs{@@_tabs_to_spaces:}, to produce as many spaces as % the §width-tab§ key was set to. % \begin{macrocode} \cs_new:Nn \@@_tabs_to_spaces: { \prg_replicate:nn { \l_@@_tab_width_int } { ~ } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_do_noligs:N} % The function \cs{@@_do_noligs:N} is an alternative definition for \LaTeXe's % §\do@noligs§ which makes sure to not consume following space % tokens. The \LaTeXe{} version ends with §\char`#1§, which % leaves \TeX{} still looking for an \mymeta{optional~space}. % \begin{macrocode} \cs_new_protected:Npn \@@_do_noligs:N #1 { \char_set_catcode_active:N #1 \cs_set:cpe { @@_active_char_ \token_to_str:N #1 : } { \mode_leave_vertical: \tex_kern:D \c_zero_dim \tex_char:D `\exp_not:N #1 } \char_set_active_eq:Nc #1 { @@_active_char_ \token_to_str:N #1 : } } % \end{macrocode} % \end{macro} % % \begin{macro}{ % \@@_set_active_eq:NN, \@@_make_control_chars_active:, % \@@_plain_disable_outer_par:} % Shortcut definitions for common catcode changes. % The `§^^L§' needs a special treatment in non-\LaTeX{} mode % because in \hologo{plainTeX} it is an §\outer§ token. % \begin{macrocode} \cs_new_protected:Npn \@@_set_active_eq:NN #1 { \char_set_catcode_active:N #1 \char_set_active_eq:NN #1 } % %<*loader> \group_begin: % \char_set_catcode_active:n { `\* } \cs_new_protected:Nn \@@_plain_disable_outer_par: %<*plain> { \group_begin: \char_set_lccode:nn { `\* } { `\^^L } \tex_lowercase:D { \group_end: \tex_let:D * \scan_stop: } } % % { } \group_end: % %<*core> \group_begin: \char_set_catcode_active:N \* \cs_new_protected:Nn \@@_make_control_chars_active: { \@@_plain_disable_outer_par: \@@_set_active_eq:NN \^^I \@@_tab: \@@_set_active_eq:NN \^^L \@@_par: \@@_set_active_eq:NN \^^M \@@_ret:w } \group_end: % % \end{macrocode} % \end{macro} % % \subsubsection{Functions \cs{@bsphack} and \cs{@esphack}}\label{func:sphack} % % \begin{macro}{\@@_bsphack:,\@@_esphack:} % We emulate §\@bsphack§ and §\@esphack§ for \hologo{plainTeX}. % This is necessary to prevent \emph{unwanted spaces} when the §print-cmd§ % key is false. % \begin{macrocode} %<*core> \cs_new_protected:Nn \@@_bsphack: { \scan_stop: \mode_if_horizontal:T { \skip_set_eq:NN \l_@@_save_skip \tex_lastskip:D \int_set_eq:NN \l_@@_save_sf_int \tex_spacefactor:D } } \cs_new_protected:Nn \@@_esphack: { \scan_stop: \mode_if_horizontal:T { \int_set_eq:NN \tex_spacefactor:D \l_@@_save_sf_int \dim_compare:nNnT { \l_@@_save_skip } > { \c_zero_skip } { \skip_if_eq:nnT { \tex_lastskip:D } { \c_zero_skip } { \nobreak \skip_horizontal:n { \c_zero_skip } } \tex_ignorespaces:D } } } % %<*latex> \cs_gset_eq:NN \@@_bsphack: \@bsphack \cs_gset_eq:NN \@@_esphack: \@esphack % % \end{macrocode} % \end{macro} % % \subsection{Keys for environment}\label{keys:env} % % \begin{macro}[int]{write-env,write-out,print-env,store-env,force-eol, % overwrite,unknown,} % We define a set of \mymeta{keys} for environment §scontents§. % \begin{macrocode} %<*core> \keys_define:nn { scontents / scontents } { write-env .code:n = { \bool_set_true:N \l_@@_storing_bool \bool_set_true:N \l_@@_writing_bool \tl_set:Nn \l_@@_file_name_tl {#1} }, write-out .code:n = { \bool_set_false:N \l_@@_storing_bool \bool_set_true:N \l_@@_writing_bool \tl_set:Nn \l_@@_file_name_tl {#1} }, write-env .value_required:n = true, write-out .value_required:n = true, print-env .meta:nn = { scontents } { print-env = #1 }, print-env .default:n = true, store-env .meta:nn = { scontents } { store-env = #1 }, force-eol .meta:nn = { scontents } { force-eol = #1 }, force-eol .default:n = true, overwrite .meta:nn = { scontents } { overwrite = #1 }, overwrite .default:n = true, unknown .code:n = { \@@_unknown_keys_env:n {#1} }, } % \end{macrocode} % \end{macro} % % \subsubsection{Handling unknown keys for environment \env{scontents}} % % The \mymeta{keys} are save in the string variable §\l_keys_key_str§ % and the value (if any) is passed as an argument to each \mymeta{function}. % % \begin{macro}{\@@_unknown_keys_env:n, % \@@_unknown_keys_env:nn} % We check the \mymeta{keys} passed to the environment % §scontents§ and process it with \cs{@@_parse_environment_keys:n} % if the \mymeta{key} is \emph{unknown} we return an error message. % \begin{macrocode} \cs_new_protected:Npn \@@_unknown_keys_env:n #1 { \exp_args:NV \@@_unknown_keys_env:nn \l_keys_key_str {#1} } \cs_new_protected:Npn \@@_unknown_keys_env:nn #1#2 { \tl_if_blank:nTF {#2} { \msg_error:nnn { scontents } { env-key-unknown } {#1} } { \msg_error:nnnn { scontents } { env-key-value-unknown } {#1} {#2} } } % \end{macrocode} % \end{macro} % % \subsection{Keys for commands}\label{keys:all} % % We add the \mymeta{keys} divided into subgroups to handle \emph{errors} % and \emph{unknown} \mymeta{keys} separately. % % \subsubsection{Keys for command \cs{Scontents}} % % \begin{macro}[int]{write-cmd,write-out,print-cmd,store-cmd,force-eol, % overwrite,unknown,} % We define a set of \mymeta{keys} for commands §\Scontents§ and % §\Scontents*§. % \begin{macrocode} \keys_define:nn { scontents / Scontents } { write-cmd .code:n = { \bool_set_true:N \l_@@_storing_bool \bool_set_true:N \l_@@_writing_bool \tl_set:Nn \l_@@_file_name_tl {#1} }, write-out .code:n = { \bool_set_false:N \l_@@_storing_bool \bool_set_true:N \l_@@_writing_bool \tl_set:Nn \l_@@_file_name_tl {#1} }, write-cmd .value_required:n = true, write-out .value_required:n = true, print-cmd .meta:nn = { scontents } { print-cmd = #1 }, print-cmd .default:n = true, store-cmd .meta:nn = { scontents } { store-cmd = #1 }, force-eol .meta:nn = { scontents } { force-eol = #1 }, force-eol .default:n = true, overwrite .meta:nn = { scontents } { overwrite = #1 }, overwrite .default:n = true, unknown .code:n = { \@@_unknown_keys_cmd:n {#1} }, } % \end{macrocode} % \end{macro} % % \subsubsection{Keys for command \cs{foreachsc}}\label{keys:foreachsc} % % \begin{macro}[int]{before, after, start, stop, step, wrapper, sep, % unknown,} % We define a set of \mymeta{keys} for command §\foreachsc§. % \begin{macrocode} \keys_define:nn { scontents / foreachsc } { before .code:n = { \bool_set_true:N \l_@@_foreach_before_bool \tl_set:Nn \l_@@_foreach_before_tl {#1} }, before .value_required:n = true, after .code:n = { \bool_set_true:N \l_@@_foreach_after_bool \tl_set:Nn \l_@@_foreach_after_tl {#1} }, after .value_required:n = true, start .int_set:N = \l_@@_foreach_start_int, start .value_required:n = true, start .initial:n = 1, stop .code:n = { \bool_set_true:N \l_@@_foreach_stop_bool \int_set:Nn \l_@@_foreach_stop_int {#1} }, stop .value_required:n = true, step .int_set:N = \l_@@_foreach_step_int, step .value_required:n = true, step .initial:n = 1, wrapper .code:n = { \bool_set_true:N \l_@@_foreach_wrapper_bool \cs_set_protected:Npn \@@_foreach_wrapper:n ##1 {#1} }, wrapper .value_required:n = true, sep .tl_set:N = \l_@@_foreach_sep_tl, sep .initial:n = { }, sep .value_required:n = true, unknown .code:n = { \@@_unknown_keys_cmd:n {#1} }, } % \end{macrocode} % \end{macro} % % \subsubsection{Handling unknown keys for \cs{Scontents} and \cs{foreachsc}} % % \begin{macro}{\@@_unknown_keys_cmd:n, % \@@_unknown_keys_cmd:nn} % We check the \mymeta{keys} passed to commands §\Scontents§, §\Scontents*§ or % §\foreachsc§ and process it with \cs{@@_unknown_keys_cmd:n} % if the \mymeta{key} is \emph{unknown} we return an error message. % \begin{macrocode} \cs_new_protected:Npn \@@_unknown_keys_cmd:n #1 { \exp_args:NV \@@_unknown_keys_cmd:nn \l_keys_key_str {#1} } \cs_new_protected:Npn \@@_unknown_keys_cmd:nn #1#2 { \tl_if_blank:nTF {#2} { \msg_error:nnn { scontents } { cmd-key-unknown } {#1} } { \msg_error:nnnn { scontents } { cmd-key-value-unknown } {#1} {#2} } } % \end{macrocode} % \end{macro} % % \subsubsection{Keys for commands \cs{typestored} and \cs{meaningsc}}\label{keys:typemeaning} % % \begin{macro}[int]{width-tab,write-out,overwrite,print-cmd, unknown,} % We define a \mymeta{keys} for command §\typestored§ and §\meaningsc§. % Both commands accept the same type of \emph{optional arguments}, just define % a common \mymeta{keys}. % Here we will implement the §write-out§, §overwrite§ and §print-cmd§ % keys which are necessary in the implementation of the §\mergesc§ % command (\S\ref{cmd:mergesc}). % \begin{macrocode} \keys_define:nn { scontents / typemeaning } { width-tab .meta:nn = { scontents } { width-tab = #1 }, write-out .code:n = { \bool_set_false:N \l_@@_storing_bool \bool_set_true:N \l_@@_writing_bool \tl_set:Nn \l_@@_file_name_tl {#1} }, write-out .value_required:n = true, overwrite .meta:nn = { scontents } { overwrite = #1 }, overwrite .default:n = true, print-cmd .bool_set:N = \l_@@_print_verb_style_bool, print-cmd .initial:n = true, print-cmd .default:n = true, unknown .code:n = { \@@_parse_type_meaning_key:n {#1} }, } % \end{macrocode} % \end{macro} % % \subsubsection{Keys for command \cs{mergesc}}\label{keys:mergesc} % % \begin{macro}[int]{typestored, meaningsc, \@@_mergesc_cmd:nn,} % We define two \mymeta{keys} \mykey{typestored} and \mykey{meaningsc} % as \emph{mandatory}, returning an \enquote{error} through the function % \cs{@@_mergesc_cmd:nn}. % \begin{macrocode} \keys_define:nn { scontents / mergesc } { typestored .code:n = { \cs_set_eq:NN \@@_mergesc_cmd:nn \@@_typestored:nn }, typestored .value_forbidden:n = true, meaningsc .code:n = { \cs_set_eq:NN \@@_mergesc_cmd:nn \@@_meaningsc:nn }, meaningsc .value_forbidden:n = true, } \cs_new_protected:Npn \@@_mergesc_cmd:nn #1 #2 { \msg_error:nn { scontents } { mergesc-missing-key } } % \end{macrocode} % \end{macro} % % \subsubsection{Parsing keys for \cs{typestored}, \cs{meaningsc} and \cs{mergesc}} % % \begin{macro}{\@@_parse_type_meaning_key:n, \@@_parse_type_meaning_key:nn, % \@@_parse_type_meaning_range:w, \@@_range_parser:nnnn, % \@@_range_parser:nnen, \@@_range_parser_aux:nnn,} % The §\typestored§, §\meaningsc§ and §\mergesc§ commands (which % internally uses the previous two) accept an \emph{optional argument} % containing the \mymeta{index} position, \mymeta{1-end} or the range of % \mymeta{start-stop} positions of the \mymeta{stored content} in the % \emph{sequence} along with other \mymeta{keys}. % % To avoid the awkward §\typestored[...]§\myoarg{keys}§{...}§ syntax, we'll make the % commands have a single \emph{optional argument} which is processed by % \mypkg{l3keys}\cite{inter3}, and the \emph{unknown} \mymeta{keys} are brought here to % \cs{@@_parse_typemeaning_key:n} to process. % % First we check if the \mymeta{key} is an integer using §\int_to_roman:n§. % If it is, we check that the value passed to the \mymeta{key} is blank % (otherwise something odd as §1=1§ might have been used). If everything % is correct, then set the value of the integer which holds the \mymeta{index}, % otherwise raise an error about an \emph{unknown} option. % \begin{macrocode} \cs_new_protected:Npn \@@_parse_type_meaning_key:n #1 { \exp_args:NV \@@_parse_type_meaning_key:nn \l_keys_key_str {#1} } \cs_new_protected:Npn \@@_parse_type_meaning_key:nn #1#2 { \tl_if_blank:nTF {#2} { \@@_parse_type_meaning_range:w #1 - \q_@@_mark - \s_@@_mark } { \msg_error:nnee { scontents } { cmd-key-value-unknown } {#1} {#2} } } \cs_new_protected:Npn \@@_parse_type_meaning_range:w #1 - #2 - #3 \s_@@_mark { \@@_range_parser:nnen {#1} {#2} { \seq_count:c { g_@@_name_ \l_@@_current_seq_name_str _seq } } { \msg_error:nnn { scontents } { cmd-key-unknown } {#1} } } \cs_new_protected:Npn \@@_range_parser:nnnn #1 #2 #3 #4 { \exp_args:Nee \@@_range_parser_aux:nnn { \str_if_eq:nnTF {#1} { end } {#3} { \exp_not:n {#1} } } { \str_if_eq:nnTF {#2} { end } {#3} { \exp_not:n {#2} } } { #4 } } \cs_generate_variant:Nn \@@_range_parser:nnnn { nnen } \cs_new_protected:Npn \@@_range_parser_aux:nnn #1 #2 #3 { \@@_tl_if_head_is_q_mark:nTF {#2} { \tl_if_empty:fTF { \int_to_roman:n { -0 #1 } } { \seq_put_right:Ne \l_@@_seq_item_seq { \int_eval:n {#1} } } { #3 {#1} } } { \bool_lazy_and:nnTF { \tl_if_empty_p:f { \int_to_roman:n { -0 #1 } } } { \tl_if_empty_p:f { \int_to_roman:n { -0 #2 } } } { \int_compare:nNnTF {#2} > {#1} { \int_step_inline:nnnn {#1} { 1 } {#2} } { \int_step_inline:nnnn {#1} { -1 } {#2} } { \seq_put_right:Nn \l_@@_seq_item_seq {##1} } } { #3 { #1-#2 } } } } % % \end{macrocode} % \end{macro} % % \subsection{Functions for sequences}\label{impl:seq:funct} % % The \emph{storage system} of the package \mypkg*{scontents} is done % using |seq| variables. Here we set up the macros that will manage % the variables. % % \begin{macro}{\@@_append_contents:nn,\@@_append_contents:Ve} % The function \cs{@@_append_contents:nn} creates a \emph{sequence} % \mymarg{seq name} pass to §#1§ if one didn't exist and appends the % \mymarg{body env} for environments or \mymarg{argument} for commands % to the right of the \emph{sequence} \mymarg{seq name} pass to §#2§. % \begin{macrocode} %<*core> \cs_new_protected:Npn \@@_append_contents:nn #1#2 { \tl_if_blank:nT {#1} { \msg_error:nn { scontents } { empty-store-cmd } } \seq_if_exist:cF { g_@@_name_#1_seq } { \seq_new:c { g_@@_name_#1_seq } } \seq_gput_right:cn { g_@@_name_#1_seq } {#2} } \cs_generate_variant:Nn \@@_append_contents:nn { Ve } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_store_to_seq:NN} % The function \cs{@@_store_to_seq:NN} writes the recorded contents % in §#1§ to the log and stores it in §#2§. % \begin{macrocode} \cs_new_protected:Npn \@@_store_to_seq:NN #1#2 { \tl_log:N #1 \@@_append_contents:Ve #2 { \exp_not:V #1 } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_finish_storing:NNN} % The \cs{@@_finish_storing:NNN} function will first check if we are in % standard \emph{storing mode}, that is, the §write-out§ key is NOT active, then % the state of the variable \cs{l_@@_forced_eol_bool} set by the % §force-eol§ key is checked and if this is \enquote{false} (default value) % we will add \cs{c_@@_hidden_space_str} to the end of the token list passed % in §{#1}§ which contains \mymarg{body env} for the generic environment §scontents§ % and the \mymarg{argument} for the §\Scontents§ command. % % Then the function \cs{@@_store_to_seq:NN} is applied to \enquote{store} % in the \emph{sequence} passed in §{#2}§ and finally the state of the % boolean variable passed in §{#3}§ established by the §print-env§ and §print-cmd§ % keys is checked and if it is \enquote{true}, \mymarg{body env} or \mymarg{argument} % will be printed from the \emph{sequence} in which it was stored by means % of the \cs{@@_lastfrom_seq:V} function. % \begin{macrocode} \cs_new_protected:Npn \@@_finish_storing:NNN #1 #2 #3 { \bool_if:NT \l_@@_storing_bool { \bool_if:NF \l_@@_forced_eol_bool { \tl_put_right:Ne #1 { \c_@@_hidden_space_str } } \@@_store_to_seq:NN #1 #2 \bool_if:NT #3 { \@@_lastfrom_seq:V #2 } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_getfrom_seq:Nn, \@@_getfrom_seq:nNn, \@@_getfrom_seq_aux:nnn, % \@@_getfrom_seq:nn, \@@_getfrom_seq:nnn,} % The function \cs{@@_getfrom_seq:Nn} retrieves the \mymeta{stored content} % pass to §{#1}§ from the \emph{sequence} \mymarg{seq name} pass to §{#2}§. % \begin{macrocode} \cs_new:Npn \@@_getfrom_seq:Nn #1#2 { \seq_if_exist:cTF { g_@@_name_#2_seq } { \exp_args:Nf \@@_getfrom_seq:nNn { \seq_count:c { g_@@_name_#2_seq } } #1 {#2} } { \msg_expandable_error:nnn { scontents } { undefined-storage } {#2} } } \cs_new:Npn \@@_getfrom_seq:nNn #1 #2 #3 { \seq_map_tokens:Nn #2 { \@@_getfrom_seq_aux:nnn {#1} {#3} } } \cs_new:Npn \@@_getfrom_seq_aux:nnn #1 #2 #3 { \exp_args:Nnf \use:n { \@@_getfrom_seq:nnn {#1} } { \int_eval:n {#3} } {#2} } \cs_new:Npn \@@_getfrom_seq:nn #1#2 { \seq_if_exist:cTF { g_@@_name_#2_seq } { \exp_args:Nf \@@_getfrom_seq:nnn { \seq_count:c { g_@@_name_#2_seq } } {#1} {#2} } { \msg_expandable_error:nnn { scontents } { undefined-storage } {#2} } } \cs_new:Npn \@@_getfrom_seq:nnn #1#2#3 { \bool_lazy_or:nnTF { \int_compare_p:nNn {#2} = { 0 } } { \int_compare_p:nNn { \int_abs:n {#2} } > {#1} } { \msg_expandable_error:nnnnn { scontents } { index-out-of-range } {#2} {#3} {#1} } { \seq_item:cn { g_@@_name_#3_seq } {#2} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_lastfrom_seq:n,\@@_lastfrom_seq:V} % The function \cs{@@_lastfrom_seq:n} save the last \mymeta{stored content} % from the \emph{sequence} pass to §#1§ in \cs{g_@@_last_tl} % then rescan with the function \cs{@@_rescan_tokens:V} when the keys §print-env§ % or §print-cmd§ are active. % \begin{macrocode} \cs_new_protected:Npn \@@_lastfrom_seq:n #1 { \tl_gset:Ne \g_@@_last_stored_tl { \seq_item:cn { g_@@_name_#1_seq } { -1 } } \group_insert_after:N \@@_rescan_tokens:V \group_insert_after:N \g_@@_last_stored_tl \group_insert_after:N \tl_gclear:N \group_insert_after:N \g_@@_last_stored_tl } \cs_generate_variant:Nn \@@_lastfrom_seq:n { V } % % \end{macrocode} % \end{macro} % % \subsection{Base functions for environments}\label{fun:base:env} % % In version 1.8 (2019-11-18) the command §\newenvsc§ (\S\ref{cmd:newenvsc}) % was implemented, allowing you to create environments with the same % behavior as the base environment §scontents§. Since that version, % the base environment §scontents§ (\S\ref{env:scontents}) is defined % using §\newenvsc§. % % The references to §\begin{scontents}§ or §\end{scontents}§ described in % this section are for illustrative purposes only, but apply to any % environment defined using §\newenvsc§. % % \subsubsection{Functions for keyval of environment} % % \begin{macro}{\@@_grab_opt_arg:n,\@@_grab_opt_arg:w} % The function \cs{@@_grab_opt_arg:w} is called from the % §scontents§ environment with the tokens following the % §\begin{scontents}§ when the next character is a `§[§'. This function % is defined using \mypkg{ltcmd}\cite{latex2e} to exploit its delimited % argument processor. % \begin{macrocode} %<*core> \NewDocumentCommand \@@_grab_opt_arg:w { r[] } { \@@_grab_opt_arg:n {#1} } % \end{macrocode} % The function is called from a context where `§^^M§' is active, so % \cs{@@_normalise_line_ends:N} is used to replace active `§^^M§' % characters by spaces. % \begin{macrocode} \cs_new_protected:Npn \@@_grab_opt_arg:n #1 { \tl_if_novalue:nF {#1} { \tl_set:Nn \l_@@_environment_keys_tl {#1} \@@_normalise_line_ends:N \l_@@_environment_keys_tl \keys_set:nV { scontents / scontents } \l_@@_environment_keys_tl } \@@_start_after_option:w } % % \end{macrocode} % \end{macro} % % \subsubsection{Functions for save the body of environment}\label{fun:save:body} % % \begin{macro}{\@@_start_environment:w,\@@_start_after_option:w, % \@@_check_line_process:en,\@@_stop_environment:} % Here we make `§^^I§', `§^^L§' and `§^^M§' active characters so that the end of % line can be \enquote{seen} to be used as a delimiter, and \hologo{TeX} doesn't try to % eliminate space-like characters. % % First we check if the immediate next token after §\begin{scontents}§ % is a `§[§'. If it is, then \cs{@@_grab_opt_arg:w} is called % to do the heavy lifting. \cs{@@_grab_opt_arg:w} processes the optional % argument and calls \cs{@@_start_after_option:w}. % % The function \cs{@@_start_after_option:w} also checks for trailing % tokens after the optional argument and issues an error if any. % In all cases, the function \cs{@@_check_line_process:en} checks that % everything past §\begin{scontents}§ is empty and then process % the environment. % % The function \cs{@@_check_line_process:en} calls the function % \cs{@@_file_tl_write_start:V} which will then read the contents % of the environment and optionally store them in a token list or write to % an \mymeta{external file}. % % When that's done, the function \cs{@@_file_write_stop:N} does the % cleanup. This part of the code is inspired and adapted from the code of % the package \mypkg{xsim}\cite{xsim} by Clemens Niederberger. % \begin{macrocode} %<*core> \group_begin: \char_set_catcode_active:N \^^I \char_set_catcode_active:N \^^L \char_set_catcode_active:N \^^M \cs_new_protected:Npn \@@_normalise_line_ends:N #1 { \tl_replace_all:Nnn #1 { ^^M } { ~ } } \cs_new_protected:Npn \@@_start_environment:w #1 ^^M { \tl_if_head_is_N_type:nTF {#1} { \str_if_eq:eeTF { \tl_head:n {#1} } { [ } { \@@_grab_opt_arg:w #1 ^^M } { \@@_check_line_process:en { } {#1} } } { \@@_check_line_process:en { } {#1} } } \cs_new_protected:Npn \@@_start_after_option:w #1 ^^M { \@@_check_line_process:en { [...] } {#1} } \cs_new_protected:Npn \@@_check_line_process:en #1 #2 { \tl_if_blank:nF {#2} { \msg_error:nnee { scontents } { junk-after-begin } { after~\c_backslash_str begin { \l_@@_env_name_tl } #1 } {#2} } \@@_make_control_chars_active: \@@_file_tl_write_start:V \l_@@_file_name_tl } \cs_new_protected:Nn \@@_stop_environment: { \@@_file_write_stop:N \l_@@_processed_body_lines_tl \bool_lazy_and:nnT { \l_@@_storing_bool } { \tl_if_empty_p:N \l_@@_processed_body_lines_tl } { \msg_warning:nne { scontents } { empty-environment } { \l_@@_env_name_tl } } } % \end{macrocode} % \end{macro} % % \begin{macro}{ % \@@_file_tl_write_start:n, % \@@_file_tl_write_start:V, % \@@_verb_processor_iterate:w, % \@@_verb_processor_iterate:nnn, % \@@_setup_verb_processor:, % \@@_file_write_stop:N, % \@@_remove_leading_nl:n, % \@@_remove_leading_nl:w, % } % This is the main macro/function to collect the \mymarg{body env} of a verbatim % environment. The function \cs{@@_file_tl_write_start:n} starts a \emph{group}, % opens the \mymeta{output file}, if necessary, sets \emph{verbatim catcodes}, % and then issues `§^^M§' (set equal to \cs{@@_ret:w}) to read \mymarg{body env} % of the environment line by line until reaching its end. The output token list % will be appended with an active `§^^J§' character and the line just read, and % this line is written to the \mymeta{output file}, if any. At the end of the % environment the \mymeta{output file} is closed (if it was open), and the % output token list is smuggled out of the verbatim group. A leading `§^^J§' % is removed from the token list using \cs{@@_remove_leading_nl:n}, which % expects an active `§^^J§' token at the head of the token list; a low level % \hologo{TeX} \enquote{error} is raised otherwise. % \begin{macrocode} \cs_new_protected:Npn \@@_file_tl_write_start:n #1 { \group_begin: \@@_file_if_writable:nTF {#1} { \bool_set_true:N \l_@@_writable_bool \iow_open:Nn \l_@@_file_write_iow {#1} } { \bool_set_false:N \l_@@_writable_bool } \tl_clear:N \l_@@_save_every_body_lines_tl \seq_map_function:NN \l_char_special_seq \char_set_catcode_other:N \int_step_function:nnnN { 128 } { 1 } { 255 } \char_set_catcode_letter:n \cs_set_protected:Npe \@@_ret:w ##1 ^^M { \exp_not:N \@@_verb_processor_iterate:w ##1 \c_@@_end_env_tl \c_@@_end_env_tl \exp_not:N \q_@@_stop } \@@_make_control_chars_active: \@@_ret:w } \cs_new:Nn \@@_setup_verb_processor: { \use:e { \cs_set:Npn \exp_not:N \@@_verb_processor_iterate:w ##1 \c_@@_end_env_tl ##2 \c_@@_end_env_tl ##3 \exp_not:N \q_@@_stop } { \@@_verb_processor_iterate:nnn {##1} {##2} {##3} } } \cs_new:Npn \@@_verb_processor_iterate:nnn #1 #2 #3 { \tl_if_blank:nTF {#3} { \@@_analyse_nesting:n {#1} \@@_verb_processor_output:n {#1} } { \@@_if_nested:TF { \@@_nesting_decr: \@@_verb_processor_output:e { \exp_not:n {#1} \c_@@_end_env_tl \exp_not:n {#2} } } { \tl_if_blank:nF {#1} { \@@_verb_processor_output:n {#1} } \cs_set_protected:Npe \@@_ret:w { \@@_env_end_function: \bool_lazy_or:nnF { \tl_if_blank_p:n {#2} } { \str_if_eq_p:ee {#2} { \c_percent_str } } { \str_if_eq:VnF \c_@@_hidden_space_str {#2} { \msg_warning:nnnn { scontents } { rescanning-text } {#2} { \tl_use:N \l_@@_env_name_tl } } \@@_rescan_tokens:n {#2} } } \char_set_active_eq:NN ^^M \@@_ret:w } } ^^M } \cs_new:Nn \@@_env_end_function: { \@@_format_case:nnn { \exp_not:N \end { \if_false: } \fi: } { \exp_after:wN \exp_not:N \cs:w end } { \exp_after:wN \exp_not:N \cs:w stop } \tl_use:N \l_@@_env_name_tl \@@_format_case:nnn { \if_false: { \fi: } } { \cs_end: } { \cs_end: } } \cs_new_protected:Npn \@@_file_write_stop:N #1 { \bool_if:NT \l_@@_writable_bool { \iow_close:N \l_@@_file_write_iow } \use:e { \group_end: \bool_if:NT \l_@@_storing_bool { \tl_set:Nn \exp_not:N #1 { \exp_args:NV \@@_remove_leading_nl:n \l_@@_save_every_body_lines_tl } } } } \cs_new:Npn \@@_remove_leading_nl:n #1 { \tl_if_head_is_N_type:nTF {#1} { \exp_args:Nf \@@_remove_leading_nl:nn { \tl_head:n {#1} } {#1} } { \exp_not:n {#1} } } \cs_new:Npn \@@_remove_leading_nl:nn #1 #2 { \token_if_eq_meaning:NNTF ^^J #1 { \exp_not:o { \@@_remove_leading_nl:w #2 } } { \exp_not:n {#2} } } \cs_new:Npn \@@_remove_leading_nl:w ^^J { } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_verb_processor_output:n,\@@_verb_processor_output:e} % The function \cs{@@_verb_processor_output:n} does the output of % each line read, to a token list and to a file, depending on the % booleans \cs{l_@@_writing_bool} and \cs{l_@@_storing_bool}. % \begin{macrocode} \cs_new_protected:Npn \@@_verb_processor_output:n #1 { \bool_if:NT \l_@@_writable_bool { \iow_now:Nn \l_@@_file_write_iow {#1} } \bool_if:NT \l_@@_storing_bool { \tl_put_right:Nn \l_@@_save_every_body_lines_tl { ^^J #1 } } } \group_end: \cs_generate_variant:Nn \@@_verb_processor_output:n { e } \cs_generate_variant:Nn \@@_file_tl_write_start:n { V } % \end{macrocode} % \end{macro} % % \begin{macro}{ % \@@_analyse_nesting:n, % \@@_analyse_nesting:w, % \@@_nesting_decr:, % \@@_use_none_delimit_by_q_stop:w, % } % \begin{macro}[TF]{\@@_if_nested:} % The function \cs{@@_analyse_nesting:n} scans nested §\begin{scontents}§ % and steps a \cs{l_@@_nesting_env_int} counter. The \cs{@@_if_nested:} % conditional tests if we're in a nested environment, and \cs{@@_nesting_decr:} % reduces the nesting level, if an §\end{scontents}§ is found. % \begin{macrocode} \cs_new_protected:Npn \@@_analyse_nesting:n #1 { \int_zero:N \l_@@_nesting_aux_int \@@_analyse_nesting_format:n {#1} \int_compare:nNnT { \l_@@_nesting_aux_int } > { 1 } { \msg_warning:nn { scontents } { multiple-begin } } } \cs_new_protected:Nn \@@_nesting_incr: { \int_incr:N \l_@@_nesting_env_int \int_incr:N \l_@@_nesting_aux_int } \cs_new_protected:Nn \@@_nesting_decr: { \int_decr:N \l_@@_nesting_env_int } \prg_new_protected_conditional:Npnn \@@_if_nested: { TF } { \int_compare:nNnTF { \l_@@_nesting_env_int } > { \c_zero_int } { \prg_return_true: } { \prg_return_false: } } % \end{macrocode} % % \begin{important}* % Multiple §\end{scontents}§ in the same line are NOT supported\dots % \end{important} % % In \LaTeX{}, environments start with §\begin{}§, so checking if a % string contains §\begin{scontents}§ is straightforward. Since no §}§ can % appear inside §§, then just a macro delimited by `§}§' is enough. % \begin{macrocode} \use:e { \cs_new_protected:Npn \exp_not:N \@@_analyse_nesting_latex:w #1 \c_backslash_str begin \c_left_brace_str #2 \c_right_brace_str } { \@@_tl_if_head_is_q_mark:nTF {#2} { \@@_use_none_delimit_by_q_stop:w } { \str_if_eq:VnT \l_@@_env_name_tl {#2} { \@@_nesting_incr: } \@@_analyse_nesting_latex:w } } \cs_new_protected:Npe \@@_analyse_nesting_latex:n #1 { \@@_analyse_nesting_latex:w #1 \c_backslash_str begin \c_left_brace_str \exp_not:N \q_@@_mark \c_right_brace_str \exp_not:N \q_@@_stop } % \end{macrocode} % In other formats, however, we don't have an \enquote{end anchor} to delimit the % environment name, so a delimited macro won't help. We have to search for % the entire environment command (usually §\scontents§ and §\startscontents§). % \begin{macrocode} \cs_new_protected:Npn \@@_analyse_nesting_generic_process:nn #1 #2 { \tl_if_head_is_N_type:nTF {#2} { \@@_tl_if_head_is_q_mark:nF {#2} { \@@_nesting_incr: \@@_analyse_nesting_generic:w #2 \q_@@_stop } } { \@@_analyse_nesting_generic:w #2 \q_@@_stop } } \cs_new_protected:Npn \@@_analyse_nesting_generic:nn #1 #2 { \@@_define_generic_nesting_function:n {#1} \use:e { \exp_not:N \@@_analyse_nesting_generic:w #2 \c_backslash_str #1 \tl_use:N \l_@@_env_name_tl \exp_not:N \q_@@_mark \exp_not:N \q_@@_stop } } \cs_new_protected:Npn \@@_define_generic_nesting_function:n #1 { \use:e { \cs_set_protected:Npn \exp_not:N \@@_analyse_nesting_generic:w ##1 \c_backslash_str #1 \tl_use:N \l_@@_env_name_tl ##2 \exp_not:N \q_@@_stop } { \@@_analyse_nesting_generic_process:nn {##1} {##2} } } % % \end{macrocode} % Now we just need to call the \cs{@@_analyse_nesting_format:n} % function to analyze the nesting. % \begin{macrocode} %<*loader> %\cs_new_eq:NN \@@_analyse_nesting_format:n % \@@_analyse_nesting_latex:n %\cs_new_protected:Npn \@@_analyse_nesting_format:n % { \@@_analyse_nesting_generic:nn { } } % { \@@_analyse_nesting_generic:nn { start } } % % \end{macrocode} % \end{macro} % \end{macro} % % \subsection{The command \cs{newenvsc}}\label{cmd:newenvsc} % % In version 1.8 (2019-11-18) the command §\newenvsc§ was implemented, % allowing you to create environments with the same behavior as the base % environment §scontents§. To achieve this, we will create new environments % so that they wrap around the base functions (\S\ref{fun:base:env}). % % \begin{macro}{\@@_generic_begin:,\@@_generic_end:,} % The function \cs{@@_generic_begin:} leaves the `§^^M§' character % active and calls the generic environment start function % \cs{@@_start_environment:w}. % \begin{macrocode} %<*core> \cs_new_protected:Npn \@@_generic_begin: { \char_set_catcode_active:N \^^M \@@_start_environment:w } % \end{macrocode} % The function \cs{@@_generic_end:} calls the generic environment stop % function \cs{@@_stop_environment:} and finally calls the function % \cs{@@_finish_storing:NNN} which stores \mymarg{body env} in % the \emph{sequence} \mymarg{seq name} and prints it from the \emph{sequence} % if the §print-env§ key is active. % \begin{macrocode} \cs_new_protected:Npn \@@_generic_end: { \@@_stop_environment: \@@_finish_storing:NNN \l_@@_processed_body_lines_tl \l_@@_name_seq_env_tl \l_@@_print_env_bool } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_setting_env:nn,\@@_define_env:nnn,} % The function \cs{@@_setting_env:nn} receives the environment \emph{name} % passed in §{#1}§ and save it in the variable \cs{l_@@_env_name_tl} % along with the initial \mymeta{keys} passed in §{#2}§. % % Two functions will be created \cs[no-index]{@@_\#1_begin:} and % \cs[no-index]{@@_\#1_end:} which will internally call the % \cs{@@_generic_begin:} and \cs{@@_generic_end:} functions and expand % the arguments of the function \cs{@@_define_env:nnn} function. % \begin{macrocode} \cs_new_protected:Npn \@@_setting_env:nn #1 #2 { \cs_new_protected:cpn { @@_#1_begin: } { \tl_set:Nn \l_@@_env_name_tl {#1} \keys_set:nn { scontents } {#2} \@@_setup_verb_processor: \@@_generic_begin: } \cs_new_protected:cpn { @@_#1_end: } { \@@_generic_end: } \exp_args:Nooo \@@_define_env:nnn % http://nooooooooooooooo.com :) jeje { \tl_to_str:n {#1} } { \cs:w @@_#1_begin: \cs_end: } { \cs:w @@_#1_end: \cs_end: } } % % \end{macrocode} % The function \cs{@@_define_env:nnn} will create the environments for % \hologo{LaTeX}, \hologo{plainTeX} and \hologo{ConTeXt}. % \begin{macrocode} %<*loader> \cs_new_protected:Npn \@@_define_env:nnn #1 #2 #3 { % \NewDocumentEnvironment {#1} { } % \cs_new_protected:cpn { start #1 } { % \group_begin: #2 } % \cs_new_protected:cpn { stop #1 } { #3 % \group_end: } } % \end{macrocode} % \end{macro} % % \begin{macro}{\newenvsc,} % Now we just need to create the user command §\newenvsc§ % for \hologo{LaTeX}, \hologo{plainTeX} and \hologo{ConTeXt}. % \begin{macrocode} \NewDocumentCommand \newenvsc { m O{} } { % \cs_if_exist:cTF { #1 } % \cs_if_exist:cTF { start #1 } { \msg_error:nnn { scontents } { env-already-defined } {#1} } { \@@_setting_env:nn {#1} {#2} } } % % \end{macrocode} % \end{macro} % % \subsection{The environment \env{scontents}}\label{env:scontents} % % \begin{macro}{ % scontents, % \scontents, % \endscontents, % \startscontents, % \stopscontents, % } % Finally defining the §scontents§ environment should be easy :) % \begin{macrocode} %<*loader> \newenvsc{scontents} % % \end{macrocode} % \end{macro} % % \subsection{The environment \env{verbatimsc}}\label{env:verbatimsc} % % The §verbatimsc§ environment is, in a way, a customized version of the % standard \myenv{verbatim} environment provided by \hologo{LaTeX}. For % correct operation in \hologo{plainTeX}, \hologo{LaTeX} and \hologo{ConTeXt}, % we must add a couple of additional functions. % % \begin{macro}[int]{\dospecials} % The \myenv{verbatim} environment in \LaTeX requires §\dospecials§. % In case it doesn't exist (at the time \mypkg*{scontents} is loaded) % we define §\dospecials§ % to use the \cs{l_char_special_seq}. % \begin{macrocode} %<*!latex> \cs_if_exist:NF \dospecials { \cs_new:Npn \dospecials { \seq_map_function:NN \l_char_special_seq \do } } % % \end{macrocode} % \end{macro} % % \begin{macro}[int]{\@@_xverb:w,\end{verbatimsc},\endverbatimsc,\stopverbatimsc} % The environment §verbatimsc§ needs to literally find the end of % this §\end{verbatimsc}§ in the case of \hologo{LaTeX}. Here we set this % for \hologo{plainTeX}, \hologo{LaTeX}, and \hologo{ConTeXt}. % \begin{macrocode} %<*loader> %<*!context> \use:e { \cs_new_protected:Npn \exp_not:N \@@_xverb:w #1 \g_@@_end_verbatimsc_tl % { #1 \exp_not:N \end{verbatimsc} } % { #1 \exp_not:N \endverbatimsc } % { #1 \exp_not:N \stopverbatimsc } } % % % \end{macrocode} % \end{macro} % % \subsubsection{\hologo{plainTeX} version off \texttt{verbatimsc}} % % \begin{macro}[int]{\verbatimsc,\endverbatimsc,\@@_verbatimsc_aux:, % \@@_vobeyspaces:,\@@_xverb:,\@@_nolig_list:,\@@_xobeysp:} % In \hologo{plainTeX} we emulate \LaTeX's \myenv{verbatim} environment. % \begin{macrocode} %<*plain> \cs_new_protected:Npn \verbatimsc { \group_begin: \@@_verbatimsc_aux: \frenchspacing \@@_vobeyspaces: \@@_xverb: } \cs_new_protected:Npn \endverbatimsc { \group_end: } \cs_new_protected:Nn \@@_verbatimsc_aux: { \skip_vertical:N \parskip \dim_zero:N \parindent \skip_set:Nn \parfillskip { 0pt plus 1fil } \skip_set:Nn \parskip { 0pt plus0pt minus0pt } \tex_par:D \bool_set_false:N \l_@@_plain_bool \cs_set:Npn \par { \bool_if:NTF \l_@@_plain_bool { \mode_leave_vertical: \null \tex_par:D \penalty \interlinepenalty } { \bool_set_true:N \l_@@_plain_bool \mode_if_horizontal:T { \tex_par:D \penalty \interlinepenalty } } } \cs_set_eq:NN \do \char_set_catcode_other:N \dospecials \obeylines \tl_use:N \l_@@_verb_font_tl \cs_set_eq:NN \do \@@_do_noligs:N \@@_nolig_list: \tex_everypar:D \exp_after:wN { \tex_the:D \tex_everypar:D \tex_unpenalty:D } } \cs_new_protected:Nn \@@_nolig_list: { \do\`\do\<\do\>\do\,\do\'\do\- } \cs_new_protected:Nn \@@_vobeyspaces: { \@@_set_active_eq:NN \ \@@_xobeysp: } \cs_new_protected:Nn \@@_xobeysp: { \mode_leave_vertical: \nobreak \ } % % \end{macrocode} % \end{macro} % % \subsubsection{\hologo{ConTeXt} version off \texttt{verbatimsc}} % % \begin{macro}[int]{\startverbatimsc,\stopverbatimsc,} % In \hologo{ConTeXt} we use our own tool §\definetyping§. % \begin{macrocode} %<*loader> %\definetyping[verbatimsc] % % \end{macrocode} % \end{macro} % % \subsubsection{\hologo{LaTeX} version off \texttt{verbatimsc}} % % \begin{macro}{\@@_verbatimsc_instance:,verbatimsc} % To be compatible with \emph{tagged} \texttt{PDF} we must define the % environment §verbatimsc§ in terms of the \mypkg{xtemplate}\cite{latex2e} % module integrated into the \LaTeX{} kernel and the new \texttt{blocks-code} % from \mypkg{latex-lab}\cite{latexlab}. This code is adapted directly % from Mrs. Ulrike Fischer's answer to \href{https://tex.stackexchange.com/a/741178/7832}{New verbatim environment with block code (tagged-pdf)}. % \begin{macrocode} %<*loader> %<*latex> \cs_new_protected:Nn \@@_verbatimsc_instance: { \DeclareInstance{blockenv}{verbatimsc}{display} { env-name = verbatimsc, tag-name = verbatim, tag-class = , tagging-recipe = standard, inner-level-counter = , level-increase = false, setup-code = , block-instance = displayblock, inner-instance = , final-code = \legacyverbatimsetup \tag_tool:n {paratag=codeline}, para-flattened = true } } \NewDocumentEnvironment { verbatimsc } { } { \IfDocumentMetadataTF { \@@_verbatimsc_instance: \UseInstance{blockenv}{verbatimsc}{} \@setupverbinvisiblespace\frenchspacing\@vobeyspaces \@@_xverb: } { \cs_set_eq:cN { @xverbatim } \@@_xverb: \verbatim } } % \end{macrocode} % The §\endverbatim§ in the second argument of the §verbatimsc§ % environment is only needed for compatibility with the \mypkg{verbatim}\cite{verbatim} % package. % \begin{macrocode} { \IfDocumentMetadataTF { \endblockenv } { \endverbatim } } % % % \end{macrocode} % \end{macro} % % \subsection{The command \cs{Scontents}}\label{cmd:Scontents} % % \begin{macro}{ % \Scontents, % \@@_Scontents_code:nn, % \@@_Scontents_norm_arg:n, % \@@_Scontents_verb_arg:w, % } % User command §\Scontents§ to \mymeta{stored content} in a \emph{sequence}, % adapted from code by Ulrich Diez in \href{https://tex.stackexchange.com/a/472044/7832}{Stringify % input - \textbackslash string on token list} % and code by user \texttt{@siracusa} in % \href{https://tex.stackexchange.com/a/500281/7832}{Convert a macro from Latex2e to expl3}. % \begin{macrocode} %<*core> \NewDocumentCommand \Scontents { !s !O{} } { \tl_set:Nn \l_@@_cmd_name_tl { Scontents } \@@_Scontents_code:nn {#1} {#2} } % \end{macrocode} % The internal function \cs{@@_Scontents_code:nn} first executes % \cs{@@_bsphack:}, opens a group and checks the \mymeta{keys} passed in % §{#2}§, leaves the \texttt{TAB} character active and then checks the % \emph{starred argument} `§*§' passed in §{#1}§. If the latter is present % it will call the function \cs{@@_Scontents_verb_arg:w} otherwise it will % call the function \cs{@@_Scontents_norm_arg:n}. % \begin{macrocode} \cs_new_protected:Npn \@@_Scontents_code:nn #1 #2 { \@@_bsphack: \group_begin: \tl_if_novalue:nF {#2} { \keys_set:nn { scontents / Scontents } {#2} } \char_set_catcode_active:n { 9 } \bool_if:NTF #1 { \@@_Scontents_verb_arg:w } { \@@_Scontents_norm_arg:n } } % \end{macrocode} % The function \cs{@@_Scontents_verb_arg:w} saves the \mymarg{argument} % passed in §{#1}§ under the \emph{verbatim catcode} using |v-|type % argument from \mypkg{ltcmd} in \cs{l_@@_Scontents_arg_tl} % and replaces all `§^^M§' and §\obeyedline§ added in \hologo{LaTeX} % release 2024-06-01 by `§^^J§' and then calls the function \cs{@@_Scontents_finish:}. % Here we will apply §\RenewDocumentCommand§ since §\obeyedline§ can be % modified by the user and if so the code would return a low-level error. % \begin{macrocode} \NewDocumentCommand \@@_Scontents_verb_arg:w { +v } { \tl_set:Nn \l_@@_Scontents_arg_tl {#1} \cs_if_exist:NT \obeyedline { \RenewDocumentCommand \obeyedline { } { \iow_char:N \^^M } \tl_replace_all:Nee \l_@@_Scontents_arg_tl { \obeyedline } { \iow_char:N \^^M } } \tl_replace_all:Nee \l_@@_Scontents_arg_tl { \iow_char:N \^^M } { \iow_char:N \^^J } \@@_Scontents_finish: } % \end{macrocode} % The function \cs{@@_Scontents_norm_arg:n} saves the \mymarg{argument} % passed in §{#1}§ in the \emph{standard catcode} regimen and then % calls the function \cs{@@_Scontents_finish:}. % \begin{macrocode} \cs_new_protected:Npn \@@_Scontents_norm_arg:n #1 { \tl_set:Nn \l_@@_Scontents_arg_tl {#1} \@@_Scontents_finish: } % \end{macrocode} % The function \cs{@@_Scontents_finish:} will first call the function % \cs{@@_file_write_cmd:VV} used by the §write-out§ and §write-cmd§ keys, % then call the function \cs{@@_finish_storing:NNN} to \emph{store} the % \mymarg{argument} passed to the §\Scontents§ command saved in % the \cs{l_@@_Scontents_arg_tl} variable in the \emph{sequence} \cs{l_@@_name_seq_cmd_tl} % and print it from this \emph{sequence} according to the state of % the \cs{l_@@_print_cmd_bool} variable set by the §print-cmd§ key. % Finally it will close the \emph{group} opened at the beginning of % the command definition and run \cs{@@_esphack:} if the §print-cmd§ % key is not active. % \begin{macrocode} \cs_new_protected:Nn \@@_Scontents_finish: { \@@_file_write_cmd:VV \l_@@_file_name_tl \l_@@_Scontents_arg_tl \@@_finish_storing:NNN \l_@@_Scontents_arg_tl \l_@@_name_seq_cmd_tl \l_@@_print_cmd_bool \use:e { \group_end: \bool_if:NF \l_@@_print_cmd_bool { \@@_esphack: } } } % \end{macrocode} % \end{macro} % % \subsection{The command \cs{getstored}}\label{cmd:getstored} % % \begin{macro}{\getstored,\@@_getstored:nn} % User command §\getstored§ to extract \mymeta{stored content} in % \emph{sequence} (robust). % \begin{macrocode} \NewDocumentCommand \getstored { O{-1} m } { \@@_getstored:nn {#1} {#2} } % \end{macrocode} % The internal function \cs{@@_getstored:nn} will set the end of line % then apply the function \cs{@@_rescan_tokens:e} on the \mymeta{stored content} % at the \mymeta{index} given by §{#1}§ in the sequence §{#2}§ via % the function \cs{@@_getfrom_seq:nn}. % \begin{macrocode} \cs_new_protected:Npn \@@_getstored:nn #1 #2 { \group_begin: \int_set:Nn \tex_newlinechar:D { `\^^J } \@@_rescan_tokens:e { \endgroup % This assumes \catcode`\\=0... Things might go off otherwise. \@@_getfrom_seq:nn {#1} {#2} } } % \end{macrocode} % \end{macro} % % \subsection{The command \cs{foreachsc}}\label{cmd:foreachsc} % % \begin{macro}{\foreachsc,\@@_foreachsc:nn,\@@_foreach_add_body:n} % User command §\foreachsc§ to loop over \mymeta{stored content} in \emph{sequence}. % \begin{macrocode} \NewDocumentCommand \foreachsc { o m } { \tl_set:Nn \l_@@_cmd_name_tl { foreachsc } \@@_foreachsc:nn {#1} {#2} } \cs_new_protected:Npn \@@_foreachsc:nn #1 #2 { \group_begin: \tl_if_novalue:nF {#1} { \keys_set:nn { scontents / foreachsc } {#1} } \tl_set:Nn \l_@@_foreachsc_arg_tl {#2} \seq_clear:N \l_@@_foreach_print_seq \bool_if:NF \l_@@_foreach_stop_bool { \int_set:Nn \l_@@_foreach_stop_int { \seq_count:c { g_@@_name_#2_seq } } } \int_step_function:nnnN { \l_@@_foreach_start_int } { \l_@@_foreach_step_int } { \l_@@_foreach_stop_int } \@@_foreach_add_body:n \tl_gset:Ne \g_@@_foreach_exec_tl { \exp_args:NNV \seq_use:Nn \l_@@_foreach_print_seq \l_@@_foreach_sep_tl } \group_end: \exp_after:wN \tl_gclear:N \exp_after:wN \g_@@_foreach_exec_tl \g_@@_foreach_exec_tl } \cs_new_protected:Npn \@@_foreach_add_body:n #1 { \seq_put_right:Ne \l_@@_foreach_print_seq { \bool_if:NT \l_@@_foreach_before_bool { \exp_not:V \l_@@_foreach_before_tl } \bool_if:NTF \l_@@_foreach_wrapper_bool { \@@_foreach_wrapper:n } { \use:n } { \getstored [#1] { \tl_use:N \l_@@_foreachsc_arg_tl } } \bool_if:NT \l_@@_foreach_after_bool { \exp_not:V \l_@@_foreach_after_tl } } } % \end{macrocode} % \end{macro} % % \subsection{The command \cs{typestored}}\label{cmd:typestored} % % \begin{macro}{\typestored,\@@_typestored:nn,\@@_typestored:N, % \@@_xverb:w} % The §\typestored§ commands fetches a buffer from memory, prints it % to the log file, and then calls \cs{@@_typestored:N}. % \begin{macrocode} \NewDocumentCommand \typestored { o m } { \tl_set:Nn \l_@@_cmd_name_tl { typestored } \@@_typestored:nn {#1} {#2} } \cs_new_protected:Npn \@@_typestored:nn #1 #2 { \@@_bsphack: \group_begin: \seq_clear:N \l_@@_seq_item_seq \str_set:Ne \l_@@_current_seq_name_str {#2} \tl_if_novalue:nF {#1} { \keys_set:nn { scontents / typemeaning } {#1} } \seq_if_empty:NT \l_@@_seq_item_seq { \seq_set_from_clist:Nn \l_@@_seq_item_seq { 1 } } \tl_set:Ne \l_@@_typestored_arg_tl { \@@_getfrom_seq:Nn \l_@@_seq_item_seq {#2} } \@@_remove_trailing_eol:N \l_@@_typestored_arg_tl \tl_replace_all:Nen \l_@@_typestored_arg_tl { \c_@@_hidden_space_str } { ^^J } \tl_log:N \l_@@_typestored_arg_tl \tl_if_empty:NF \l_@@_typestored_arg_tl { \bool_if:NT \l_@@_print_verb_style_bool { \@@_typestored:N \l_@@_typestored_arg_tl } } \@@_file_write_cmd:VV \l_@@_file_name_tl \l_@@_typestored_arg_tl \use:e { \group_end: \bool_if:NF \l_@@_print_verb_style_bool { \@@_esphack: } } } % \end{macrocode} % The \cs{@@_typestored:N} macro is defined with active carriage return % (\textsc{ascii} 13) characters to \emph{mimic} an actual §verbatim§ environment % \enquote{on the loose}. The contents of the environment are placed in a % §verbatimsc§ environment and rescanned using \cs{@@_rescan_tokens:e}. % \begin{macrocode} \group_begin: \char_set_catcode_active:N \^^M \cs_new_protected:Npn \@@_typestored:N #1 { \tl_if_blank:VT #1 { \msg_error:nnn { scontents } { empty-variable } {#1} } \cs_set_eq:NN \@@_verb_print_EOL: ^^M \cs_set_eq:NN ^^M \scan_stop: \cs_set_eq:cN { do@noligs } \@@_do_noligs:N \int_set:Nn \tex_newlinechar:D { `\^^J } \@@_rescan_tokens:e { \@@_format_case:nnn { \exp_not:N \begin{verbatimsc} } % LaTeX { \verbatimsc } % Plain/Generic { \startverbatimsc } % ConTeXt ^^M \exp_not:V #1 ^^M \g_@@_end_verbatimsc_tl } \cs_set_eq:NN ^^M \@@_verb_print_EOL: } \group_end: \cs_new_protected:Nn \@@_xverb: { \char_set_catcode_active:n { 9 } \char_set_active_eq:nN { 9 } \@@_tabs_to_spaces: \@@_xverb:w } % \end{macrocode} % \end{macro} % % \subsection{The command \cs{meaningsc}}\label{cmd:meaningsc} % % \begin{macro}{\meaningsc,\@@_meaningsc:nn,\@@_meaningsc:n} % User command §\meaningsc§ to see content stored in |seq|. % \begin{macrocode} \NewDocumentCommand \meaningsc { o m } { \tl_set:Nn \l_@@_cmd_name_tl { meaningsc } \@@_meaningsc:nn {#1} {#2} } \cs_new_protected:Npn \@@_meaningsc:nn #1 #2 { \@@_bsphack: \group_begin: \seq_clear:N \l_@@_seq_item_seq \str_set:Ne \l_@@_current_seq_name_str {#2} \tl_if_novalue:nF {#1} { \keys_set:nn { scontents / typemeaning } {#1} } \seq_if_empty:NT \l_@@_seq_item_seq { \seq_set_from_clist:Nn \l_@@_seq_item_seq { 1 } } \@@_meaningsc:n {#2} \use:e { \group_end: \bool_if:NF \l_@@_print_verb_style_bool { \@@_esphack: } } } \group_begin: \char_set_catcode_active:N \^^I \cs_new_protected:Npn \@@_meaningsc:n #1 { \tl_set:Ne \l_@@_meaningsc_arg_tl { \@@_getfrom_seq:Nn \l_@@_seq_item_seq {#1} } \tl_replace_all:Nen \l_@@_meaningsc_arg_tl { \iow_char:N \^^J } { ~ } \tl_replace_all:Nen \l_@@_meaningsc_arg_tl { \c_@@_hidden_space_str } { ~ } \tl_log:N \l_@@_meaningsc_arg_tl \tl_use:N \l_@@_verb_font_tl \tl_replace_all:Nne \l_@@_meaningsc_arg_tl { ^^I } { \@@_tabs_to_spaces: } \tl_if_empty:NF \l_@@_meaningsc_arg_tl { \bool_if:NT \l_@@_print_verb_style_bool { \cs_replacement_spec:N \l_@@_meaningsc_arg_tl } } \@@_file_write_cmd:VV \l_@@_file_name_tl \l_@@_meaningsc_arg_tl } \group_end: % \end{macrocode} % \end{macro} % % \subsection{The command \cs{mergesc}}\label{cmd:mergesc} % % The §\mergesc§ command parses a comma separated list given as \mymarg{argument}, % and just assembles it as a temporary \emph{internal sequence}, then % passes it to the §\typestored§ or §\meaningsc§ command. % % \begin{macro}{\mergesc, \@@_mergesc_code:nn, \@@_mergesc_parse_list:n, % \@@_remove_trailing_eol:N, \@@_remove_trailing_eol:w, % \@@_parse_mergesc:nw, \@@_parse_mergesc_aux:nw, \@@_parse_mergesc_range:nw,} % The §\mergesc§ command parses a list given as argument, and just assembles % it as a temporary internal sequence, then passes it to the requested command. % \begin{macrocode} \NewDocumentCommand \mergesc { o m } { \tl_set:Nn \l_@@_cmd_name_tl { mergesc } \@@_mergesc_code:nn {#1} {#2} } \cs_new_protected:Npn \@@_mergesc_code:nn #1 #2 { \group_begin: \tl_clear:N \l_@@_mergesc_keys_tl \tl_if_novalue:nF {#1} { \keys_set_known:nnN { scontents / mergesc } {#1} \l_@@_mergesc_keys_tl } \seq_gclear:c { g_@@_name_sc!internal_seq } \@@_mergesc_parse_list:n {#2} \exp_args:Ne \@@_mergesc_cmd:nn { 1-end, \exp_not:V \l_@@_mergesc_keys_tl } { sc!internal } \group_end: } % \end{macrocode} % \begin{macrocode} \cs_new_protected:Npn \@@_mergesc_parse_list:n #1 { \clist_map_inline:nn {#1} { \@@_parse_mergesc:nw ##1 \s_@@_stop } \seq_gpop_right:cN { g_@@_name_sc!internal_seq } \l_@@_mergesc_arg_tl \@@_remove_trailing_eol:N \l_@@_mergesc_arg_tl \seq_gput_right:cV { g_@@_name_sc!internal_seq } \l_@@_mergesc_arg_tl } \cs_new_protected:Npe \@@_remove_trailing_eol:N #1 { \exp_not:N \exp_after:wN \exp_not:N \@@_remove_trailing_eol:w #1 \s_@@_stop \c_@@_hidden_space_str \s_@@_stop \s_@@_mark #1 } \use:e { \cs_new_protected:Npn \exp_not:N \@@_remove_trailing_eol:w #1 \c_@@_hidden_space_str \s_@@_stop #2 \s_@@_mark #3 } { \tl_set:Ne #3 { \tl_if_empty:nTF {#2} { \exp_not:o { \@@_use_delimit_by_s_stop:nw #1 } } { \exp_not:n {#1} } } } \cs_new_protected:Npn \@@_parse_mergesc:nw #1 { \peek_remove_spaces:n { \peek_charcode:NTF [ % ] { \@@_parse_mergesc_aux:nw {#1} } { \@@_parse_mergesc_aux:nw {#1} [ 1-\seq_count:c { g_@@_name_#1_seq } ] } } } \cs_new_protected:Npn \@@_parse_mergesc_aux:nw #1 [#2] { \seq_clear:N \l_@@_seq_item_seq \clist_map_inline:nn {#2} { \@@_parse_mergesc_range:nw {#1} ##1 - \q_@@_mark - \s_@@_mark } \seq_map_inline:Nn \l_@@_seq_item_seq { \seq_gput_right:ce { g_@@_name_sc!internal_seq } { \seq_item:cn { g_@@_name_#1_seq } {##1} } } \@@_use_none_delimit_by_s_stop:w } \cs_new_protected:Npn \@@_parse_mergesc_range:nw #1 #2 - #3 - #4 \s_@@_mark { \cs_set_protected:Npn \@@_tmp:w ##1 { \msg_error:nneee { scontents } { index-out-of-range } {##1} {#1} { \seq_count:c { g_@@_name_#1_seq } } } \@@_range_parser:nnen {#2} {#3} { \seq_count:c { g_@@_name_#1_seq } } { \@@_tmp:w } } % \end{macrocode} % \end{macro} % % \subsection{The command \cs{setupsc}} % % \begin{macro}{\setupsc} % User command §\setupsc§ to setup module for §\keys_set:nn { scontents }§. % \begin{macrocode} \NewDocumentCommand \setupsc { +m } { \keys_set:nn { scontents } {#1} } % \end{macrocode} % \end{macro} % % \subsection{The command \cs{countsc}} % % \begin{macro}{\countsc} % User command §\countsc§ to count number of \mymeta{stored contents} % in the \emph{sequence}. % \begin{macrocode} \NewExpandableDocumentCommand \countsc { m } { \seq_count:c { g_@@_name_#1_seq } } % \end{macrocode} % \end{macro} % % \subsection{The command \cs{cleanseqsc}} % % \begin{macro}{\cleanseqsc} % A user command §\cleanseqsc§ to clear (remove) all \mymeta{stored contents} % in the \emph{sequence}. % \begin{macrocode} \NewDocumentCommand \cleanseqsc { m } { \seq_gclear_new:c { g_@@_name_#1_seq } } % \end{macrocode} % \end{macro} % % \subsection{Warning and error messages} % % Warning and error messages used throughout the package. % % \begin{macrocode} \msg_new:nnn { scontents } { junk-after-begin } { Junk~characters~#1~\msg_line_context: : \\ \\ #2 } \msg_new:nnnn { scontents } { env-already-defined } { Environment~'#1'~already~defined! } { You~have~used~\newenvsc with~an~environment~that~already~has~a~definition. \\ \\ The~existing~definition~of~'#1'~will~not~be~altered. } \msg_new:nnn { scontents } { empty-stored-content } { Empty~value~for~key~'getstored'~\msg_line_context:. } \msg_new:nnn { scontents } { empty-variable } { Variable~'#1'~empty~\msg_line_context:. } \msg_new:nnn { scontents } { overwrite-file } { Overwriting~file~'#1'. } \msg_new:nnn { scontents } { writing-file } { Writing~file~'#1'. } \msg_new:nnn { scontents } { not-writing } { File~`#1'~already~exists.~Not~writing. } \msg_new:nnn { scontents } { rescanning-text } { Rescanning~text~'#1'~after~\c_backslash_str end{#2}~\msg_line_context:.} \msg_new:nnn { scontents } { multiple-begin } { Multiple~\c_backslash_str begin{ \l_@@_env_name_tl }~\msg_line_context:.} \msg_new:nnn { scontents } { undefined-storage } { Storage~named~'#1'~is~not~defined. } \msg_new:nnnn { scontents } { mergesc-missing-key } { Need~mandatory~key~'typestored'~or~'meaningsc'~for~\\ command~\c_backslash_str mergesc~\msg_line_context:. } { The~command~\c_backslash_str mergesc~need~a~mandatory~key~typestored~or~meaningsc.\\ Check~that~you~have~spelled~the~key~name~correctly. } \msg_new:nnn { scontents } { index-out-of-range } { \int_compare:nNnTF {#1} = { 0 } { Index~of~sequence~cannot~be~zero. } { Index~'#1'~out~of~range~for~'#2'.~ \int_compare:nNnTF {#1} > { 0 } { Max = } { Min = -} #3. } } \msg_new:nnnn { scontents } { env-key-unknown } { The~key~'#1'~is~unknown~by~environment~ '\l_@@_env_name_tl'~and~is~being~ignored. } { The~environment~'\l_@@_env_name_tl'~does~not~have~a~key~called~'#1'.\\ Check~that~you~have~spelled~the~key~name~correctly. } \msg_new:nnnn { scontents } { env-key-value-unknown } { The~key~'#1=#2'~is~unknown~by~environment~ '\l_@@_env_name_tl'~and~is~being~ignored. } { The~environment~'\l_@@_env_name_tl'~does~not~have~a~key~called~'#1'.\\ Check~that~you~have~spelled~the~key~name~correctly. } \msg_new:nnnn { scontents } { cmd-key-unknown } { The~key~'#1'~is~unknown~by~command~\c_backslash_str \l_@@_cmd_name_tl \c_space_tl and~is~being~ignored~ \msg_line_context:. } { The~command~\c_backslash_str \l_@@_cmd_name_tl \c_space_tl does~not~have~a~key~called~'#1'.\\ Check~that~you~have~spelled~the~key~name~correctly. } \msg_new:nnnn { scontents } { cmd-key-value-unknown } { The~key~'#1=#2'~is~unknown~by~command~\c_backslash_str \l_@@_cmd_name_tl \c_space_tl and~is~being~ignored~ \msg_line_context:. } { The~command~\c_backslash_str \l_@@_cmd_name_tl \c_space_tl does~not~have~a~key~called~'#1'.\\ Check~that~you~have~spelled~the~key~name~correctly. } \msg_new:nnn { scontents } { empty-environment } { environment~'#1'~empty~\msg_line_context:. } \msg_new:nnnn { scontents } { verbatim-newline } { Verbatim~argument~of~#1~ended~by~end~of~line. } { The~verbatim~argument~of~the~#1~cannot~contain~more~than~one~line,~ but~the~end~ of~the~current~line~has~been~reached.~You~may~have~forgotten~the~ closing~delimiter. \\ \\ LaTeX~will~ignore~'#2'. } \msg_new:nnnn { scontents } { verbatim-tokenized } { The~verbatim~#1~cannot~be~used~inside~an~argument. } { The~#1~takes~a~verbatim~argument.~ It~may~not~appear~within~the~argument~of~another~function.~ It~received~an~illegal~token \tl_if_empty:nF {#3} { ~'#3' } . \\ \\ LaTeX~will~ignore~'#2'. } % % \end{macrocode} % % \subsection{Finish package} % % Finish package implementation. % % \begin{macrocode} %\ExplSyntaxOff %\endinput %\file_input_stop: % \end{macrocode} % % \Finale