diff options
Diffstat (limited to 'macros/latex/contrib')
-rw-r--r-- | macros/latex/contrib/scontents/README.md | 12 | ||||
-rw-r--r-- | macros/latex/contrib/scontents/scontents.dtx | 1817 | ||||
-rw-r--r-- | macros/latex/contrib/scontents/scontents.pdf | bin | 198211 -> 244760 bytes |
3 files changed, 1213 insertions, 616 deletions
diff --git a/macros/latex/contrib/scontents/README.md b/macros/latex/contrib/scontents/README.md index c446c1bf8d..c5ea150461 100644 --- a/macros/latex/contrib/scontents/README.md +++ b/macros/latex/contrib/scontents/README.md @@ -1,17 +1,17 @@ ## scontents — Stores LaTeX contents in memory or files -- Version: 1.2 -- Date: 2019/08/28 +- Version: 1.3 +- Date: 2019/09/24 - Author: Pablo González ## Description The `scontents` package stores valid `LaTeX` code in memory (sequences) using the -`l3seq` module of `expl3`. The stored content (including verbatim) can be +`l3seq` module of `expl3`. The stored content, including `verbatim` material, can be used as many times as desired in the document, additionally can be written -to external files if desired. +to external files. ## Requirements -The package requires the following packages: -- [filecontentsdef](https://ctan.org/pkg/filecontentsdef) +The package loads and depends on updated versions of: +- [expl3](https://ctan.org/pkg/expl3) - [l3keys2e](https://ctan.org/pkg/l3keys2e) - [xparse](https://ctan.org/pkg/xparse) diff --git a/macros/latex/contrib/scontents/scontents.dtx b/macros/latex/contrib/scontents/scontents.dtx index 9084a7ea35..1aa64dcc3d 100644 --- a/macros/latex/contrib/scontents/scontents.dtx +++ b/macros/latex/contrib/scontents/scontents.dtx @@ -60,7 +60,6 @@ \usepackage{scontents} % main \usepackage[contents]{colordoc} - % Patching colordoc.sty to work with l3doc.cls \ExplSyntaxOn \cs_new_eq:cN { liii@xmacro@code } \__codedoc_xmacro_code:n @@ -103,13 +102,13 @@ \setlength{\parindent}{0pt} -%^^A------------------- ONLY FOR DOCUMENTATION ------------------------%% -%^^A Colors for options +%%-------------------- ONLY FOR DOCUMENTATION ------------------------%% +% Colors for options \definecolor{optcolor}{rgb}{0.281,0.275,0.485} \definecolor{mypkgcolor}{RGB}{0,128,128}% -%^^A Custom \meta[...]{...}, \marg[...]{...} and \oarg[...]{...} with color +% Custom \meta[...]{...}, \marg[...]{...} and \oarg[...]{...} with color \ExplSyntaxOn -%^^A user level commands +% User level commands \NewDocumentCommand{\mymeta}{O{}m} { \userdoc_meta_generic:Nnn \userdoc_meta:n { #1 } { #2 } @@ -122,7 +121,7 @@ { \userdoc_meta_generic:Nnn \userdoc_oarg:n { #1 } { #2 } } -%^^A variables and keys +% Variables and keys \tl_new:N \l_userdoc_meta_font_tl \keys_define:nn { userdoc / mymeta } @@ -140,7 +139,7 @@ cbc .tl_set:N = \l_userdoc_meta_bracecolor_tl, cbc .initial:n = black, } -%^^A internal commands +% Internal commands \cs_new_protected:Npn \userdoc_meta_generic:Nnn #1 #2 #3 { \group_begin: @@ -191,7 +190,7 @@ \textcolor{\l_userdoc_meta_brackcolor_tl}{#1} } -%^^A \envexamp{m} +% \envexamp{m} \newsavebox{\boxexaenv} \NewDocumentCommand{\envexamp}{m} { @@ -207,7 +206,7 @@ \usebox{\boxexaenv} } -%^^A \cmdexamp{s m o m o} +% \cmdexamp{s m o m o} \DeclareDocumentCommand{\cmdexamp}{s m o m o} { \group_begin: @@ -227,11 +226,11 @@ \MYSortIndex{Commands}{Commands ~ provide ~ by ~ \textcolor{gray}{scontents}>\texttt{\textbackslash#2}}% } -%^^A \keyexamp{mmm} +% \keyexamp{mmm} \DeclareDocumentCommand{\keyexamp}{ m m m } { \par - \adjustbox{outer=-\marginparsep}{\textcolor{mypkgcolor}{\small\ttfamily{#1}}} + \adjustbox{outer=-\marginparsep}{\textcolor{black}{\small\ttfamily{#1}}} \textcolor{gray}{\,\bfseries\texttt{=}}\,{} \mymarg[type=tt,cbc=OrangeRed,ac=NavyBlue,cf=MediumOrchid]{\small{#2}} \hfill\textcolor{gray}{\small\textsf{(default: ~ \texttt{#3})}} @@ -239,7 +238,7 @@ \MYSortIndex{Keys}{Keys>\texttt{#1}}% } -%^^A \mypkg{sm} +% \mypkg{sm} \NewDocumentCommand{\mypkg}{sm} { \IfBooleanTF{#1} @@ -253,7 +252,7 @@ } } -%^^A \myenv{sm} +% \myenv{sm} \DeclareDocumentCommand{\myenv}{sm} { \IfBooleanTF{#1} @@ -267,7 +266,7 @@ } } -%^^A \ics{sm} +% \ics{sm} \DeclareDocumentCommand{\ics}{sm} { \IfBooleanTF{#1} @@ -282,7 +281,7 @@ } \ExplSyntaxOff -%^^A email https://tex.stackexchange.com/a/663 +% email https://tex.stackexchange.com/a/663 \catcode`\_=11\relax% \newcommand\email[1]{\_email #1\q_nil}% \def\_email#1@#2\q_nil{% @@ -293,7 +292,7 @@ \catcode`\_=8\relax% \makeatletter -%^^A Logo whit fetamont font for title +% Logo whit fetamont font for title \newsavebox{\logobox} \savebox{\logobox}{% \normalsize\fetamontotf{\textcolor{mypkgcolor}{s}\textcolor{OrangeRed}{content}\textcolor{mypkgcolor}{s}}} @@ -303,10 +302,10 @@ } \makeatother -%^^A Don't copy numbers in code example +% Don't copy numbers in code example \newcommand*{\noaccsupp}[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}} -%^^A Create a language for documentation +% Create a language for documentation \lstdefinelanguage{scontents-doc}{ texcsstyle=*,% escapechar=`,% @@ -347,7 +346,7 @@ {=}{{\textcolor{red}{=}}}{1},% }[keywords,tex,comments,strings]% end languaje -%^^A \begin{examplecode}[key=val]...\end{examplecode} +% \begin{examplecode}[key=val]...\end{examplecode} \lstnewenvironment{examplecode}[1][]{% \lstset{ language=scontents-doc,% @@ -364,7 +363,7 @@ }% close lstset }{}% close examplecode -%^^A \lstinline[style=inline]|...| +% \lstinline[style=inline]|...| \lstdefinestyle{inline} { language=scontents-doc,% @@ -376,13 +375,13 @@ literate=*{\%}{{\bfseries\textcolor{gray}{\%}}}{1} } -%^^A Set default style +% Set default \lstinline style \lstset{style=inline} -%^^A Get file info +% Get file info \GetFileInfo{\jobname.sty} -%^^A Config hyperref +% Config hyperref \hypersetup{ linkcolor = blue!50, citecolor = red!50,% @@ -394,12 +393,12 @@ pdfsubject = {Documentation for \fileversion{} [\filedate] },% pdfcopyright = {\textcopyright 2019 by Pablo González}, pdfcontacturl = {https://github.com/pablgonz/scontents}, - pdfkeywords = {filecontents, filecontentsdef, xparse, expl3, l3seq, Store contents}, + pdfkeywords = {contents, external files, expl3, xparse, l3seq, Store contents}, pdfstartview = {FitH},% bookmarksopenlevel = 1,% } -%^^A Configuration titleps and titlesec +% Configuration titleps and titlesec \settitlemarks{section} \renewpagestyle{plain}[\color{gray}\small\sffamily]{ \setfoot{}{}{\thepage/\pageref{LastPage}}} @@ -425,7 +424,7 @@ {\hspace*{-11mm}}% numberless {\hspace{0.25em}\titlerule*[6pt]{.}\contentspage}% -%^^A Table of contents +% Table of contents \makeatletter \renewcommand\tableofcontents{% \begingroup% @@ -469,10 +468,10 @@ % \maketitle % % \begin{abstract} -% The \mypkg*{scontents} package stores valid \hologo{LaTeX} code in memory (sequences) using -% the \mypkg{l3seq} module of \mypkg{expl3}. The stored content (including -% \emph{verbatim}) can be used as many times as desired in the document, -% additionally can be written to external files if desired. +% The \mypkg*{scontents} package stores valid \hologo{LaTeX} code in memory +% (sequences) using the \mypkg{l3seq} module of \mypkg{expl3}. The stored +% content, including \emph{verbatim} material, can be used as many times +% as desired in the document, additionally can be written to external files. % \end{abstract} % % \tableofcontents @@ -488,13 +487,13 @@ % \emph{buffers} that has \hologo{ConTeXt} which allows you to save content in % memory, including \emph{verbatim}, to be used later. The package % \mypkg{filecontentsdef} solves this problem and since \mypkg{expl3} has an -% excellent way to manage data, I decided to combine the best of both. +% 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. Also a special thanks to % Phelype Oleinik who has collaborated and adapted a large part of the code and -% all \hologo{LaTeX3} team for their great work and to the different members +% all \hologo{LaTeX3} 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: % @@ -518,10 +517,9 @@ % (\url{http://www.latex-project.org/lppl.txt}). The software has the status % \enquote{maintained}. % -% The \mypkg*{scontents} package loads \mypkg{xparse}, -% \mypkg{filecontentsdef} and \mypkg{l3keys2e}. This package can be used -% with |xelatex|, |lualatex|, |pdflatex| and the classical workflow -% |latex|-|dvips|-|ps2pdf|. +% The \mypkg*{scontents} package loads \mypkg{expl3}, \mypkg{xparse} and +% \mypkg{l3keys2e}. This package can be used with |xelatex|, |lualatex| +% , |pdflatex| and the classical workflow |latex|-|dvips|-|ps2pdf|. % % \thispagestyle{plain} % @@ -534,14 +532,12 @@ % % \subsection{Description} % -% The \mypkg*{scontents} package encapsulates the \mypkg{filecontentsdef} -% package of \textsc{Jean Fran\c{c}ois Burnol} which allows you to save the -% content in a |\macro| and save it in external files, adding a user interface -% style \myoarg{key = val} along with the ability to save content in sequences -% for later use in different parts of the document. -% -% \subsection{Loading package} -% \label{sec:loadoptpkg} +% The \mypkg*{scontents} package allows to store contents in memory (sequence) +% or external files, provides a user interface style \myoarg{key = val} +% along with the ability to store contents in sequences for later use in +% different parts of the document. In some ways it works very much like +% the \mypkg{filecontentsdef} package, with the difference that it preserves +% the |TAB|s characters in the output files (see \ref{sec:tabcharacter}). % % The package is loaded in the usual way: % @@ -565,11 +561,46 @@ %</example> % \fi % +% \subsection{The TAB character} +% \label{sec:tabcharacter} +% +% In a standard \hologo{LaTeX} document, horizontal |TAB|s (\LKeyTab) typed +% from the keyboard are treated as explicit spaces in most contexts. Some +% users use this character to indented the source code of the document and +% depending on the text editor used, some will use real |TAB|s (sometimes +% called \enquote{hard tabs}), others with \enquote{soft tabs} +% (\textvisiblespace\textvisiblespace or \textvisiblespace +% \textvisiblespace\textvisiblespace\textvisiblespace) or both. +% +% At first glance it may seem the same, but the way in which |TAB|s (\enquote{hard tabs}) +% are processed according to the context in which they are found within +% a file, both in 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 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. +% +% The behavior of this character for the \emph{stored} content can be +% configured with the |widht-tab| key, but, these will be preserved by +% writing an output file, unfortunately, dependent on the \hologo{TeX} +% distribution you have and how the formats were initialized. +% +% With a \hologo{TeX}Live distribution, the formats for |latex|, |pdflatex| +% and |lualatex| are prepared feeding the option |-translate-file=cp227.tcx|, +% that makes the |TAB| character \enquote{printable}. To write a literal +% |TAB| character using |xelatex| you must add the |-8bit| option on command +% line, otherwise you will get \hologo{TeX}-|TAB|s (|^^I|) in the \mymeta{output file}. +% +% As a general recommendation \enquote{Do not use |TAB|s unless strictly +% necessary}, for example within a verbatim environment that supports +% this character such as |Verbatim| or |lstlisting| 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 can be -% configured by means of the command \ics*{setupsc}. +% Most of the options can be passed directly to the package or using the +% command the command \ics*{setupsc}. % % \vspace*{-10pt} % @@ -579,11 +610,17 @@ % \end{syntax} % % The command \ics*{setupsc} configures the options in a global way, -% for \ics*{Scontents}, \ics*{Scontents*} and environment \myenv*{scontents}. % it can be used both in the preamble and in the body of the document % as many times as desired. % \end{function} % +% \medskip +% +% \keyexamp{verb-font}{number}{ \textbackslash{}ttfamily } +% Sets the font type used to display the stored content for the commands +% \ics*{typestored} and \ics*{meaningsc}. This key is only available as +% a package option or using \ics*{setupsc}. +% % \subsection{Options Overview} % \label{sec:optover} % @@ -592,26 +629,31 @@ % % Summary table of available options. % -% \begin{tabular}{cccccc} +% \setlength{\tabcolsep}{0.25em} +% \begin{tabular}{cccccccc} % \toprule -% \texttt{key} & package & \ics{setupsc} & \myenv*{scontents} & \ics*{Scontents} & \ics*{Scontents*}\\ +% \texttt{key} &package &\ics{setupsc} &\myenv*{scontents} &\ics*{Scontents} &\ics*{Scontents*} &\ics*{typestored} &\ics*{meaningsc}\\ % \midrule -% \texttt{store-env} & \cmark & \cmark & \cmark & \xmark & \xmark \\ -% \texttt{store-cmd} & \cmark & \cmark & \xmark & \cmark & \cmark \\ -% \texttt{print-env} & \cmark & \cmark & \cmark & \xmark & \xmark \\ -% \texttt{print-cmd} & \cmark & \cmark & \xmark & \cmark & \cmark \\ -% \texttt{print-all} & \cmark & \cmark & \cmark & \xmark & \xmark \\ -% \texttt{write-env} & \xmark & \xmark & \cmark & \xmark & \xmark \\ -% \texttt{write-out} & \xmark & \xmark & \cmark & \xmark & \xmark \\ +% \texttt{store-env} & \cmark & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark \\ +% \texttt{store-cmd} & \cmark & \cmark & \xmark & \cmark & \cmark & \xmark & \xmark \\ +% \texttt{print-env} & \cmark & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark \\ +% \texttt{print-cmd} & \cmark & \cmark & \xmark & \cmark & \cmark & \xmark & \xmark \\ +% \texttt{print-all} & \cmark & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark \\ +% \texttt{write-env} & \xmark & \xmark & \cmark & \xmark & \xmark & \xmark & \xmark \\ +% \texttt{write-out} & \xmark & \xmark & \cmark & \xmark & \xmark & \xmark & \xmark \\ +% \texttt{width-tab} & \cmark & \cmark & \xmark & \xmark & \xmark & \cmark & \cmark \\ +% \texttt{force-eol} & \cmark & \cmark & \cmark & \xmark & \cmark & \xmark & \xmark \\ +% \texttt{verb-font} & \cmark & \cmark & \xmark & \xmark & \xmark & \xmark & \xmark \\ % \bottomrule % \end{tabular} % % \section{User interface} % \label{sec:interface} % -% The \emph{user interface} provided by this package consists in \myenv*{scontents} environment, -% \ics*{Scontents} and \ics*{Scontents*} commands to stored contents and \ics*{getstored} command -% to get the \meta{stored content} along with other utilities described in this documentation. +% The \emph{user interface} provided by this package consists in \myenv*{scontents} +% environment, \ics*{Scontents} and \ics*{Scontents*} commands to stored +% contents and \ics*{getstored} command to get the \meta{stored content} +% along with other utilities described in this documentation. % % \subsection{The environment \env{scontents}} % \label{sec:scontents} @@ -623,27 +665,36 @@ % \envexamp{scontents} % \end{syntax} % -% The \myenv*{scontents} environment encapsulates the \myenv{filecontentsdef*} and -% \myenv{filecontentsdefmacro} environments provided by the \mypkg{filecontentsdef} -% package. This allows you to record content including verbatim for later reuse. +% The \myenv*{scontents} environment allows you to save the content to memory +% or external files in a similar way to the package \mypkg{filecontentsdef}. +% This allows you to record content, including \emph{verbatim}, for later reuse. +% +% Some considerations to keep in mind, |\begin{scontents}| and |\end{scontents}| +% must be on different lines, the \myoarg{key=val} options must be passed on +% \mymeta{one line} right after starting the environment and |TAB|s characters +% are preserved when writing an \mymeta{external file}. % \end{function} % -% Some considerations to keep in mind: +% The environment can be nested complying with the above considerations +% and bearing in mind that within it should not be written literally, as a +% comment or within verbatim environments |\begin{scontents}| and |\end{scontents}|. +% For example: % -% \begin{enumerate}[nosep] -% \item The environment cannot be nested. -% \item Both \lstinline[style=inline]|\begin| and \lstinline[style=inline]|\end| -% must be on different lines. -% \item The \myoarg{key=val} options must be passed on one line right after -% starting the environment. -% \item The content of the environment is treated in the same way as -% \myenv{filecontents*} environment. -% \item If you don't want the extra space added by \hologo{TeX}, you should use -% \ics{relax} or \lstinline[style=inline]|%| at the end of environment. -% \end{enumerate} -% -% For more technical information about the environment it is better to read -% the documentation of the \mypkg{filecontentsdef} package. +% \iffalse +%<*example> +% \fi +\begin{examplecode}[frame=single] +\begin{scontents}[store-env=outer] +This text is in the outermost environment. +\begin{scontents}[store-env=inner] +This text is found in the most inner environment. +\end{scontents} +This text is in the outermost environment. +\end{scontents} +\end{examplecode} +% \iffalse +%</example> +% \fi % % \subsection*{Options for environment} % @@ -654,8 +705,8 @@ % \medskip % % \keyexamp{store-env}{seq name}{contents} -% The name of the sequence in which the content recorded by the environment -% was stored. +% The name of the \mymeta{sequence} in which the content recorded by the +% environment was stored. % % \medskip % @@ -664,23 +715,45 @@ % % \medskip % +% \keyexamp{force-eol}{true\textbar false}{false} +% This key is only necessary if the last line inside the environment is +% |\end{Verbatim}| or the |\end{...}| of some environment created with +% the package \mypkg{fancyvrb}. This adds an extra line to the \ics*{typestored} +% output. +% +% \medskip +% % \keyexamp{write-env}{file.ext}{not used} -% In addition to storing the content of the environment will write this in -% an external file. +% In addition to storing the content of the environment will write this +% in an external \mymeta{file.ext}, if \mymeta{file.ext} exists it will +% be overwritten. The \mymeta{file.ext} will be created in the working +% directory, relative or absolute paths are not supported, the way the +% external \mymeta{file.ext} is recorded is similar to that produced by +% \myenv{filecontents*} environment. If the content within the environment +% has literal |TAB|s they will be recorded in \mymeta{file.ext}. +% +% To write a literal |TAB| character using |xelatex| you must add the |-8bit| +% option on command line, otherwise you will get \hologo{TeX}-|TAB|s (|^^I|) in +% the \mymeta{output file}. % % \medskip % % \keyexamp{write-out}{file.ext}{not used} -% It will write the contents of the environment in an external file, but, -% it will not store the contents of this one. It is analogous to the -% \myenv{filecontents*} environment. +% It will write the contents in an external \mymeta{file.ext}, but, it +% will not store the contents of this one. The \mymeta{file.ext} will be +% created in the working directory, relative or absolute paths are not +% supported. The way the external \mymeta{file.ext} is recorded is similar +% to that produced by \myenv{filecontents*} environment. If the content +% within the environment has literal |TAB|s they will be recorded in +% \mymeta{file.ext}. +% +% To write a literal |TAB| character using |xelatex| you must add the |-8bit| +% option on command line, otherwise you will get \hologo{TeX}-|TAB|s (|^^I|) in +% the \mymeta{output file}. % % \subsection{The command \cs{Scontents}} % \label{sec:Scontents} % -% The command to store content directly in memory, the star version allows to save -% \meta{verbatim} contents. -% % \vspace*{-10pt} % % \begin{function}{\Scontents} @@ -691,32 +764,29 @@ % \end{syntax} % \end{function} % -% The \ics*{Scontents} command reads the \meta{argument} in standard mode. -% It is not possible to pass environments such as \meta{verbatim}, but it is -% possible to use the implementation of \ics{Verb} provided by the -% \mypkg{fvextra} package for contents on one line and \ics{lstinline} from -% \mypkg{listings} package, but it is preferable to use the starred version. -% -% It can be used anywhere in the document and cannot be used as an \meta{argument} -% for another command. -% -% The \ics*{Scontents*} command reads the \meta{argument} under verbatim -% category code regimen. If its first delimiter is a brace, it will be assumed that -% the \meta{argument} is nested into braces. Otherwise it will be assumed that -% the ending of that argument is delimited by that first delimiter-like the -% argument of \ics{verb}. Some considerations to keep in mind: -% -% \begin{enumerate}[nosep] -% \item Blank lines are preserved. -% \item The command cannot be used as an argument for another command. -% \item If you don't want the extra space added by \hologo{TeX}, you should use -% \ics{relax} or \lstinline[style=inline]|%| at the end. -% \end{enumerate} +% The \ics*{Scontents} command reads the \mymeta{argument} in standard +% mode. It is not possible to pass environments such as \meta{verbatim}, +% but it is possible to use the implementation of \ics{Verb} provided by +% the \mypkg{fvextra} package for contents on one line and \ics{lstinline} +% from \mypkg{listings} package, but it is preferable to use the starred +% version. +% +% The \ics*{Scontents*} command reads the \mymeta{argument} under verbatim +% category code regimen. If its first delimiter is a brace, it will be +% assumed that the \mymeta{argument} is nested into braces. Otherwise it +% will be assumed that the ending of that argument is delimited by that +% first delimiter-like the argument of \ics{verb}. Blank lines are preserved, +% escaped |\{| and |\}| must also be balanced if the argument is used +% with braces and |TAB|s characters typed from the keyboard are converted +% into spaces. +% +% Both versions can be used anywhere in the document and cannot be used +% as an \mymeta{argument} for other command. % % \subsection*{Options for command} % \label{sec:optcmdsc} % -% The command options (including star version) can be configured globally +% The command options (including starred version) can be configured globally % using option in package or the \ics*{setupsc} command and locally % using \myoarg{key=val}. % \medskip @@ -727,9 +797,17 @@ % % \medskip % -% \keyexamp{print-cmd}{true\textbar false}{false} +% \keyexamp{print-cmd}{true\textbar{}false}{false} % It will show the current content of \ics*{Scontents}. % +% \medskip +% +% \keyexamp{force-eol}{true\textbar{}false}{false} +% This key is only necessary if the last line inside the command is +% |\end{Verbatim}| or the |\end{...}| of some environment created with +% the package \mypkg{fancyvrb}. This adds an extra line to the \ics*{typestored} +% output. +% % \subsection{The command \cs{getstored}} % \label{sec:getstored} % @@ -742,9 +820,10 @@ % \end{function} % % The command \ics*{getstored} gets the content stored in \meta{seq name} -% according to the index in which it was stored. The command is robust -% and can be used as an \meta{argument} for another command. If the optional argument -% is not passed it defaults to the last element saved in the \meta{seq name}. +% according to the \mymeta{index} in which it was stored. The command is +% robust and can be used as an \meta{argument} for another command. If the +% optional argument is not passed it defaults to the last element saved +% in the \meta{seq name}. % % \subsection{The command \cs{typestored}} % \label{sec:typestored} @@ -753,19 +832,22 @@ % % \begin{function}{\typestored} % \begin{syntax} -% \cmdexamp{typestored}[index]{seq name} -% \cmdexamp*{typestored}[index]{seq name} +% \cmdexamp{typestored}[index, width-tab=number]{seq name} % \end{syntax} % \end{function} % -% The command \ics*{typestored} shows the content stored in \meta{seq name} in -% \emph{verbatim} mode. Internally places the content into the \myenv*{verbatimsc} environment. +% The command \ics*{typestored} internally places the content stored in +% the \meta{seq name} into the \myenv*{verbatimsc} environment. The \mymeta{index} +% number corresponds to the position in which the content is stored in +% the \meta{seq name}. % -% The command \ics*{typestored*} must be used for content stored by \ics*{Scontents*} command. -% Internally places the content into the \myenv*{verbatimsc} environment. +% If the optional argument is not passed it defaults to the last element +% saved in the \meta{seq name}. +% \medskip % -% If the optional argument is not passed it defaults to the -% last element saved in the \meta{seq name}. +% \keyexamp{width-tab}{number}{ 1 } +% Establishes the equivalence in \mymeta{spaces} for the character |TAB| +% typed from the keyboard. The value must be a \mymeta{positive integer}. % % \subsection{The environment \env{verbatimsc}} % \label{sec:verbatimsc} @@ -773,13 +855,14 @@ % \vspace*{-10pt} % % \begin{function}{verbatimsc} -% Internal environment used by \cs{typestored} and \cs{typestored*} to display -% \meta{verbatim style} contents. +% Internal environment used by \cs{typestored} to display \meta{verbatim style} +% contents. % \end{function} % -% One consideration to keep in mind is that this is a \emph{representation} of the content -% in a \meta{verbatim} environment and not a real \meta{verbatim} environment, the line ends -% are not respected. The \myenv*{verbatimsc} environment can be in the following ways: +% One consideration to keep in mind is that this is a \emph{representation} +% of the content in a \meta{verbatim} environment and not a real \meta{verbatim} +% environment. The \myenv*{verbatimsc} environment can be customized in the +% following ways: % % Using the package \mypkg{fancyvrb}: % \iffalse @@ -846,13 +929,20 @@ % % \begin{function}{\meaningsc} % \begin{syntax} -% \cmdexamp{meaningsc}[index]{seq name} +% \cmdexamp{meaningsc}[index, width-tab=number]{seq name} % \end{syntax} % The command \ics*{meaningsc} executes \ics{meaning} on the content stored -% in \meta{seq name}. If the optional argument is not passed it defaults to the -% last element saved in the \meta{seq name}. +% in \meta{seq name}. The \mymeta{index} number corresponds to the position +% in which the content is stored in the \meta{seq name}. If the optional +% argument is not passed it defaults to the last element saved in the \meta{seq name}. % \end{function} % +% \medskip +% +% \keyexamp{width-tab}{number}{ 1 } +% Establishes the equivalence in \mymeta{spaces} for the character |TAB| +% typed from the keyboard. The value must be a \mymeta{positive integer}. +% % \subsection{The command \cs{countsc}} % \label{sec:countsc} % @@ -877,6 +967,8 @@ % The command \ics*{cleansc} remove all contents stored in \meta{seq name}. % \end{function} % +% \newpage +% % \section{Examples} % % These are some (adapted) examples that have served as inspiration for @@ -886,31 +978,41 @@ % % \subsubsection*{Example 1} % -% \begin{VerbatimOut}{scexamp1.ltx} -% \documentclass[12pt,a4paper]{article} -% \usepackage[store-cmd=solutions]{scontents} -% \usepackage{pgffor} -% \newtheorem{ex}{Exercise} -% \begin{document} -% \section{Problems} -% \begin{ex} -% First exercise -% \Scontents{ -% First solution. -% } -% \end{ex} -% \begin{ex} -% Second exercise -% \Scontents{ -% Second solution. -% } -% \end{ex} -% \section{Solutions} -% \foreach \i in {1,...,\countsc{solutions}} { -% \noindent\textbf{\i} \getstored[\i]{solutions}\par -% } -% \end{document} -% \end{VerbatimOut} +% \iffalse +%<*example> +% \fi +\begin{scontents}[write-out=scexamp1.ltx] +\documentclass[12pt,a4paper]{article} +\usepackage[store-cmd=solutions]{scontents} +\usepackage{pgffor} +\newtheorem{ex}{Exercise} +\begin{document} +\section{Problems} + +\begin{ex} +First exercise +\Scontents{ + First solution. +} +\end{ex} + +\begin{ex} +Second exercise +\Scontents{ + Second solution. +} +\end{ex} + +\section{Solutions} + +\foreach \i in {1,...,\countsc{solutions}} { +\noindent\textbf{\i} \getstored[\i]{solutions}\par +} +\end{document} +\end{scontents} +% \iffalse +%</example> +% \fi % % Adaptation of example 1 (ansexam1) of the package \mypkg{answers} % \textattachfile[color=0 0 1]{scexamp1.ltx}{\faFile*[regular]}. @@ -920,32 +1022,41 @@ % % \subsubsection*{Example 2} % -% \begin{VerbatimOut}{scexamp2.ltx} -% \documentclass{article} -% \usepackage[store-env=defexercise,store-cmd=defexercise]{scontents} -% \usepackage{pgffor} -% \pagestyle{empty} -% \begin{document} -% \Scontents{ -% Prove that \[x^n+y^n=z^n\] is not solvable in positive integers if $n$ is at -% most $-3$.\par -% } -% \Scontents*{Refute the existence of black holes in less than $140$ characters.\relax} -% \begin{scontents}[write-env=\jobname-3.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} -% -% \foreach \i in {1,...,3} { -% \begin{itemize} -% \item \getstored[\i]{defexercise} -% \end{itemize}} -% -% \section{\getstored[2]{defexercise}} % \getstored are robust :) -% \end{document} -% \end{VerbatimOut} +% \iffalse +%<*example> +% \fi +\begin{scontents}[write-out=scexamp2.ltx] +\documentclass{article} +\usepackage[store-env=defexercise,store-cmd=defexercise]{scontents} +\usepackage{pgffor} +\pagestyle{empty} +\begin{document} + +\Scontents{ +Prove that \[x^n+y^n=z^n\] is not solvable in positive integers if $n$ is at +most $-3$.\par +} + +\Scontents*{Refute the existence of black holes in less than $140$ characters.} + +\begin{scontents}[write-env=\jobname-3.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} + +\foreach \i in {1,...,3} { +\begin{itemize} +\item \getstored[\i]{defexercise} +\end{itemize}} + +\section{\getstored[2]{defexercise}} % \getstored are robust :) +\end{document} +\end{scontents} +% \iffalse +%</example> +% \fi % % Adaptation of example from package \mypkg{filecontentsdef} % \textattachfile[color=0 0 1]{scexamp2.ltx}{\faFile*[regular]}. @@ -955,66 +1066,83 @@ % % \subsubsection*{Example 3} % -% \begin{VerbatimOut}{scexamp3.ltx} -% \documentclass{article} -% \usepackage[store-cmd=tikz]{scontents} -% \usepackage{tikz} -% \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[3]{tikz} -% \end{tikzpicture} -% \section{source} -% \foreach \i in {1,...,\countsc{tikz}}{ -% \typestored*[\i]{tikz}} -% \end{document} -% \end{VerbatimOut} +% \iffalse +%<*example> +% \fi +\begin{scontents}[write-out=scexamp3.ltx] +\documentclass{article} +\usepackage[store-cmd=tikz]{scontents} +\usepackage{tikz} +\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[3]{tikz} +\end{tikzpicture} + +\section{source} +\typestored[1]{tikz} +\typestored[2]{tikz} +\typestored[3]{tikz} +\end{document} +\end{scontents} +% \iffalse +%</example> +% \fi +% % Adapted from \href{https://tex.stackexchange.com/q/5338/7832}{LaTeX equivalent of ConTeXt buffers} % \textattachfile[color=0 0 1]{scexamp3.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp3.ltx} % % \subsubsection*{Example 4} % -% \begin{VerbatimOut}{scexamp4.ltx} -% \documentclass{article} -% \usepackage{scontents} -% \usepackage{pgffor} -% \pagestyle{empty} -% \begin{document} -% \begin{scontents}[store-env=a] -% Something for a -% \end{scontents} -% -% \begin{scontents}[store-env=a] -% Something for b -% \end{scontents} -% -% \begin{scontents}[store-env=a] -% Something with no label -% \end{scontents} -% -% \textbf{Let's print them} -% -% This is a: \getstored[1]{a} -% -% This is b: \getstored[2]{a} -% -% \textbf{Print all of them} -% -% \foreach \i in {1,...,\countsc{a}} {\getstored[\i]{a}\par} -% \end{document} -% \end{VerbatimOut} +% \iffalse +%<*example> +% \fi +\begin{scontents}[write-out=scexamp4.ltx] +\documentclass{article} +\usepackage{scontents} +\usepackage{pgffor} +\pagestyle{empty} +\begin{document} +\begin{scontents}[store-env=a] +Something for a +\end{scontents} + +\begin{scontents}[store-env=a] +Something for b +\end{scontents} + +\begin{scontents}[store-env=a] +Something with no label +\end{scontents} + +\textbf{Let's print them} + +This is a: \getstored[1]{a} + +This is b: \getstored[2]{a} + +\textbf{Print all of them} + +\foreach \i in {1,...,\countsc{a}} {\getstored[\i]{a}\par} +\end{document} +\end{scontents} +% \iffalse +%</example> +% \fi % % Adapted from \href{https://tex.stackexchange.com/q/184503/7832}{Collecting contents of environment and store them for later retrieval} % \textattachfile[color=0 0 1]{scexamp4.ltx}{\faFile*[regular]}. @@ -1022,27 +1150,35 @@ % % \subsubsection*{Example 5} % -% \begin{VerbatimOut}{scexamp5.ltx} -% \documentclass{article} -% \usepackage{scontents} -% \pagestyle{empty} -% \setlength{\parindent}{0pt} -% \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+. This is normal text. -% \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{VerbatimOut} +% \iffalse +%<*example> +% \fi +\begin{scontents}[write-out=scexamp5.ltx] +\documentclass{article} +\usepackage{scontents} +\pagestyle{empty} +\setlength{\parindent}{0pt} +\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 +%</example> +% \fi % % Adapted from \href{https://tex.stackexchange.com/q/373647/7832}{Collect contents of an environment (that contains verbatim content)} % \textattachfile[color=0 0 1]{scexamp5.ltx}{\faFile*[regular]}. @@ -1052,166 +1188,187 @@ % % \subsubsection*{Example 6} % -% \begin{VerbatimOut}{scexamp6.ltx} -% \documentclass{article} -% \usepackage{scontents} -% \makeatletter -% \let\verbatimsc\@undefined -% \let\endverbatimsc\@undefined -% \makeatother -% \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\}} whit \texttt{fancyvrb}} -% Test \verb+\begin{scontents}+ \par -% -% \begin{scontents} -% Using \verb+scontents+ env no \verb+[key=val]+, save in seq \verb+contents+ -% with index 1. -% -% Prove new \Verb*{ fancyvrb whit braces } and environment \verb+Verbatim*+ -% \begin{verbatim} -% verbatim environment -% \end{verbatim} -% \end{scontents} -% -% \section{Test \texttt{\textbackslash Scontents} whit \texttt{fancyvrb}} -% -% \Scontents{ We have coded this in \LaTeX: $E=mc^2$.} -% -% \section{Test \texttt{\textbackslash getstored}} -% -% \getstored[1]{contents}\par -% \getstored[2]{contents} -% -% \section{Test \texttt{\textbackslash meaningsc}} -% -% \meaningsc[1]{contents}\par -% -% \meaningsc[2]{contents} -% -% \section{Test \texttt{\textbackslash typestored}} -% -% \typestored[1]{contents} +% \iffalse +%<*example> +% \fi +\begin{scontents}[write-out=scexamp6.ltx] +\documentclass{article} +\usepackage{scontents} +\makeatletter +\let\verbatimsc\@undefined +\let\endverbatimsc\@undefined +\makeatother +\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\}} whit \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 whit braces } and environment \verb+Verbatim*+ +\begin{verbatim} + verbatim environment +\end{verbatim} +\end{scontents} + +\section{Test \texttt{\textbackslash Scontents} whit \texttt{fancyvrb}} + +\Scontents{ We have coded this in \LaTeX: $E=mc^2$.} + +\section{Test \texttt{\textbackslash getstored}} + +\getstored[1]{contents}\par +\getstored[2]{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 +%</example> +% \fi % -% \typestored*[2]{contents} -% \end{document} -% \end{VerbatimOut} % Customization of \myenv*{verbatimsc} using the \mypkg{fancyvrb} and \mypkg{tcolorbox} package % \textattachfile[color=0 0 1]{scexamp6.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp6.ltx} % % \subsubsection*{Example 7} % -% \begin{VerbatimOut}{scexamp7.ltx} -% \documentclass{article} -% \usepackage{scontents} -% \makeatletter -% \let\verbatimsc\@undefined -% \let\endverbatimsc\@undefined -% \makeatother -% \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\}} whit \texttt{listings}} -% Test \verb+\begin{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*} whit \texttt{listings}} -% -% \Scontents*+ We have coded this in \lstinline[basicstyle=\ttfamily]|\LaTeX: $E=mc^2$| -% and more.+ -% -% \section{Test \texttt{\textbackslash getstored}} -% -% \getstored[2]{contents}\par -% -% \getstored[1]{contents} -% -% \section{Test \texttt{\textbackslash typestored}} -% -% \typestored[1]{contents} -% \typestored*[2]{contents} -% \end{document} -% \end{VerbatimOut} +% \iffalse +%<*example> +% \fi +\begin{scontents}[write-out=scexamp7.ltx] +\documentclass{article} +\usepackage{scontents} +\makeatletter +\let\verbatimsc\@undefined +\let\endverbatimsc\@undefined +\makeatother +\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\}} whit \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*} whit \texttt{listings}} + +\Scontents*+ We have coded this in \lstinline[basicstyle=\ttfamily]|\LaTeX: $E=mc^2$| +and more.+ + +\section{Test \texttt{\textbackslash getstored}} + +\getstored[2]{contents}\par +\getstored[1]{contents} + +\section{Test \texttt{\textbackslash typestored}} + +\typestored[1]{contents} +\typestored[2]{contents} +\end{document} +\end{scontents} +% \iffalse +%</example> +% \fi +% % Customization of \myenv*{verbatimsc} using the \mypkg{listings} package % \textattachfile[color=0 0 1]{scexamp7.ltx}{\faFile*[regular]}. % \lstinputlisting[language=scontents-doc,numbers=left]{scexamp7.ltx} % % \subsubsection*{Example 8} % -% \begin{VerbatimOut}{scexamp8.ltx} -% \documentclass{article} % need shell-escape -% \usepackage{scontents} -% \makeatletter -% \let\verbatimsc\@undefined -% \let\endverbatimsc\@undefined -% \makeatother -% \usepackage{minted} -% \newminted{tex}{linenos} -% \newenvironment{verbatimsc}{\VerbatimEnvironment\begin{texcode}}{\end{texcode}} -% \pagestyle{empty} -% \begin{document} -% \section{Test \texttt{\textbackslash begin\{scontents\}} whit \texttt{minted}} -% Test \verb+\begin{scontents}+ \par -% -% \begin{scontents} -% Using \verb+scontents+ env no \verb+[key=val]+, save in seq \verb+contents+ with index 1.\par -% -% Prove new \Verb*{ new fvextra whit braces } and environment \verb+Verbatim*+ -% \begin{verbatim} -% verbatim environment -% \end{verbatim} -% \end{scontents} -% -% \section{Test \texttt{\textbackslash Scontents} whit \texttt{minted}} -% -% \Scontents{ We have coded \par this in \LaTeX: $E=mc^2$.} -% -% \section{Test \texttt{\textbackslash getstored}} -% \getstored[2]{contents}\par -% \getstored[1]{contents} -% -% \section{Test \texttt{\textbackslash typestored}} -% \typestored[1]{contents} -% \end{document} -% \end{VerbatimOut} +% \iffalse +%<*example> +% \fi +\begin{scontents}[write-out=scexamp8.ltx] +\documentclass{article} % need --shell-escape +\usepackage{scontents} +\makeatletter +\let\verbatimsc\@undefined +\let\endverbatimsc\@undefined +\makeatother +\usepackage{minted} +\newminted{tex}{linenos} +\newenvironment{verbatimsc}{\VerbatimEnvironment\begin{texcode}}{\end{texcode}} +\pagestyle{empty} +\begin{document} +\section{Test \texttt{\textbackslash begin\{scontents\}} whit \texttt{minted}} +Test \verb+{scontents}+ \par + +\begin{scontents}[write-env=usingtab.tex,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 whit braces } and environment \verb+Verbatim*+ +% Real TABs here :) +\begin{Verbatim}[obeytabs, showtabs, tab=\rightarrowfill, tabcolor=red,showspaces, spacecolor=blue] +No tab + One real tab + Two real Tab plus one tab +\end{Verbatim} +\end{scontents} + +\section{Test \texttt{\textbackslash Scontents} whit \texttt{minted}} + +\Scontents{ We have coded \par this in \LaTeX: $E=mc^2$.} + +\section{Test \texttt{\textbackslash getstored}} +\getstored[1]{contents}\par +\getstored[2]{contents} + +\section{Test \texttt{\textbackslash typestored}} +\typestored[1]{contents} +\typestored[2]{contents} +\end{document} +\end{scontents} +% \iffalse +%</example> +% \fi % % Customization of \myenv*{verbatimsc} using the \mypkg{minted} package % \textattachfile[color=0 0 1]{scexamp8.ltx}{\faFile*[regular]}. @@ -1220,6 +1377,10 @@ % \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} +% package to the current version with only \mypkg{expl3}. +% % \setlist[itemize,1]{label=\textendash, wide=0.5em, nosep, noitemsep, leftmargin=10pt} % \newlength\descrwidth % \settowidth{\descrwidth}{\textsf{v1.0, (ctan), 2019/07/30} } @@ -1227,6 +1388,16 @@ % \begin{description}[font=\small\sffamily, wide=0pt, style=multiline, leftmargin=\descrwidth, nosep, noitemsep] % \item [\fileversion{} (ctan), \filedate] % \begin{itemize} +% \item The environment can now nest. +% \item Added \verb+force-eol+, \verb+verb-font+ and \verb+width-tab+ keys. +% \item The extra space has been removed when you run \verb+\getstored+. +% \item Internal code has been rewritten more efficiently. +% \item Remove \verb+\typestored*+. +% \item Remove \verb+filecontentsdef+ dependency. +% \item Changing \verb+\regex_replace_all:+ for \verb+\tl_replace_all:+. +% \end{itemize} +% \item [v1.2 (ctan), 2019/08/28] +% \begin{itemize} % \item Restructuring of documentation. % \item Added copy of \verb+\tex_scantokens:D+. % \end{itemize} @@ -1272,14 +1443,18 @@ % % Then, we can give the traditional declaration of a package written with % \pkg{expl3} and the necessary packages for its operation. +% +%%^^A Initial declaration of the package % \begin{macrocode} -\RequirePackage{filecontentsdef}[2019/04/20] \RequirePackage{l3keys2e} \RequirePackage{xparse}[2019/05/28] -\ProvidesExplPackage{scontents}{2019/08/28}{1.2} +\ProvidesExplPackage{scontents}{2019/09/24}{1.3} {Stores LaTeX contents in memory or files} % \end{macrocode} +% % A check to make sure that \pkg{xparse} is not too old +% +%%^^A Checking the version of xparse % \begin{macrocode} \@ifpackagelater { xparse } { 2019/05/03 } { } @@ -1298,28 +1473,41 @@ % % We create some common keys that will be used by the options passed to % the package as well as by the environments and commands defined. +% +%%^^A Common keys available as package options % \begin{macrocode} \keys_define:nn { scontents } { store-env .tl_set:N = \l_@@_name_seq_env_tl, store-env .initial:n = contents, - print-env .bool_set:N = \l_@@_print_env_bool, - print-env .initial:n = false, + 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 .initial:n = \ttfamily, + 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-all .meta:n = { print-env = true , print-cmd = true }, - store-env .value_required:n = true, - store-cmd .value_required:n = true, - print-env .value_required:n = true, - print-cmd .value_required:n = true, - print-all .value_required:n = true + print-cmd .default:n = true, + force-eol .bool_set:N = \l_@@_forced_eol_bool, + force-eol .initial:n = false, + force-eol .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, + unknown .code:n = { \@@_parse_unknown_key:n {#1} } } % \end{macrocode} % % We process the keys as options passed on to the package. -%%^^A Process options for pkg +% +%%^^A Process options for package % \begin{macrocode} \ProcessKeysOptions { scontents } % \end{macrocode} @@ -1328,30 +1516,44 @@ % % Now we declare the internal variables we will use. % -%%^^A Internal tl vars -% \begin{macro}{\l_@@_macro_tmp_tl,\l_@@_fname_out_tl,\l_@@_temp_tl} +% \begin{macro}{\l_@@_macro_tmp_tl,\l_@@_fname_out_tl,\l_@@_temp_tl, +% \l_@@_file_tl,\g_@@_temp_tl} % \cs{l_@@_macro_tmp_tl} is a temporary token list to hold the contents % of the macro/environment, \cs{l_@@_fname_out_tl} is used as the name -% of the output file, when there's one, and \cs{l_@@_temp_tl} is a -% generic temporary token list. +% of the output file, when there's one, \cs{l_@@_file_tl} holds the contents +% of an environment as it's being read, and \cs{l_@@_temp_tl} and +% \cs{g_@@_temp_tl} are generic temporary token lists. +% +%%^^A Internal token list vars % \begin{macrocode} \tl_new:N \l_@@_macro_tmp_tl \tl_new:N \l_@@_fname_out_tl \tl_new:N \l_@@_temp_tl +\tl_new:N \l_@@_file_tl +\tl_new:N \g_@@_temp_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_@@_seq_item_int,\l_@@_env_nesting_int,\l_@@_tmpa_int} +% \cs{l_@@_seq_item_int} stores the index in the sequence of the item +% requested to \cs{typestored} or \cs{meaningsc}. \cs{l_@@_env_nesting_int} +% stores the current nesting level of the \env{scontents} environment. +% +%%^^A Internal int vars +% \begin{macrocode} +\int_new:N \l_@@_seq_item_int +\int_new:N \l_@@_env_nesting_int +\int_new:N \l_@@_tmpa_int % \end{macrocode} % \end{macro} % +% \begin{macro}{\l_@@_writing_bool,\l_@@_storing_bool} +% The boolean \cs{l_@@_writing_bool} keeps track of whether we should write +% to a file, and \cs{l_@@_storing_bool} determines whether it is in write-only +% mode when the |write-out| option is used. +% %%^^A Internal bool vars -% \begin{macro}{\l_@@_typeverb_env_bool,\l_@@_writing_bool, -% \l_@@_storing_bool} -% The boolean \cs{l_@@_typeverb_env_bool} keeps track whether the -% starred variant of the \cs{typestored} macro was used, -% \cs{l_@@_writing_bool} if we should write to a file, and -% \cs{l_@@_storing_bool} determines whether it is in write-only mode -% when the |write-out| option is used. % \begin{macrocode} -\bool_new:N \l_@@_typeverb_env_bool -\bool_set_true:N \l_@@_typevrb_env_bool \bool_new:N \l_@@_writing_bool \bool_set_false:N \l_@@_writing_bool \bool_new:N \l_@@_storing_bool @@ -1359,45 +1561,86 @@ % \end{macrocode} % \end{macro} % -%%^^A Internal quarks +% \begin{macro}{\g_@@_end_verbatimsc_tl,\c_@@_end_env_tl} +% A token list to match when ending \env{verbatimsc} and \env{scontents} +% environments. +% +%%^^A A token list to match \env{verbatimsc} and \env{scontents} +% \begin{macrocode} +\tl_new:N \g_@@_end_verbatimsc_tl +\tl_gset_rescan:Nnn + \g_@@_end_verbatimsc_tl + { + \char_set_catcode_other:N \\ + \char_set_catcode_other:N \{ + \char_set_catcode_other:N \} + } + { \end{verbatimsc} } +\tl_const:Nx \c_@@_end_env_tl + { \c_backslash_str end \c_left_brace_str scontents \c_right_brace_str } +% \end{macrocode} +% \end{macro} +% +% % \begin{macro}{\q_@@_stop,\q_@@_mark} % Some quarks used along the code as macro delimiters. +% +%%^^A Internal quarks % \begin{macrocode} \quark_new:N \q_@@_stop \quark_new:N \q_@@_mark % \end{macrocode} % \end{macro} % -%%^^A Internal quarks -% \begin{macro}{\@@_rescan_tokens:w} +% \begin{macro}{\l_@@_file_iow} +% An output stream for saving the contents of an environment to a file. +% +%%^^A Stream for saving the contents +% \begin{macrocode} +\iow_new:N \l_@@_file_iow +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_rescan_tokens:n} % \cs{tl_rescan:nn} doesn't fit the needs of this package because % it does not allow catcode changes inside the argument, so verbatim % commands used inside one of \mypkg*{scontents}'s commands/environments % will not work. Here we create a private copy of \cs{tex_scantokens:D} -% which will serve our purposes: +% which will serve our purposes. +% +%%^^A Copy of scantokens in expl3 % \begin{macrocode} -\cs_new_eq:NN \@@_rescan_tokens:w \tex_scantokens:D +\cs_new_protected:Npn \@@_rescan_tokens:n #1 { \tex_scantokens:D {#1} } +\cs_generate_variant:Nn \@@_rescan_tokens:n { V, x } % \end{macrocode} % \end{macro} % -% \begin{macro}{\g_@@_end_verbatimsc_tl} -% A token list to match when ending verbatim environments. +% \begin{macro}{\@@_tab:,\@@_par:} +% Control sequences to replace tab (|^^I|) and form feed (|^^L|) characters. +% +%%^^A Internal \tab and \par % \begin{macrocode} -\tl_new:N \g_@@_end_verbatimsc_tl -\tl_gset_rescan:Nnn - \g_@@_end_verbatimsc_tl - { - \char_set_catcode_other:N \\ - \char_set_catcode_other:N \{ - \char_set_catcode_other:N \} - } - { \end{verbatimsc} } +\cs_new:Npx \@@_tab: { \c_space_tl } +\cs_new:Npn \@@_par: { ^^J ^^J } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_remove_once:NV,\tl_replace_all:Nxx, +% \tl_replace_all:Nxn,\tl_replace_all:Nnx,\tl_if_empty:fTF} +% Some nonstandard variants. +% +%%^^A Some nonstandard variants +% \begin{macrocode} +\cs_generate_variant:Nn \tl_remove_once:Nn { NV } +\cs_generate_variant:Nn \tl_replace_all:Nnn { Nx, Nxx, Nnx } +\prg_generate_conditional_variant:Nnn \tl_if_empty:n { f } { TF } % \end{macrocode} % \end{macro} % % \subsection{Add keys for environment} % % We define a set of keys for environment \env{scontents}. +% %%^^A Add keys to scontents environnment % \begin{macrocode} \keys_define:nn { scontents } @@ -1420,26 +1663,70 @@ % % A sub/keys for command |\Scontents| and |\Scontents*| % -%%^^A A sub/keys for command |\Scontents| +%%^^A A sub/keys for command \Scontents % \begin{macrocode} \keys_define:nn { scontents / Scontents } { print-cmd .meta:nn = { scontents } { print-cmd = #1 }, - store-cmd .meta:nn = { scontents } { store-cmd = #1 } + store-cmd .meta:nn = { scontents } { store-cmd = #1 }, + force-eol .meta:nn = { scontents } { force-eol = #1 } + } +% \end{macrocode} +% +% \subsection{Handling undefined keys} +% +% \begin{macro}{\@@_parse_unknown_key:n,\@@_parse_unknown_key:nn} +% The commands \cs{typestored} and \cs{meaningsc} accept an optional +% argument for setting the \texttt{width-tab} to print the stored +% contents. However their optional argument also contains the number +% of the item to retrieve from the stored sequence. To avoid the +% awkward \verb|\typestored[][<options>]{...}| syntax, we'll make the +% commands have a single optional argument which is processed by +% \pkg{l3keys}, and the unknown keys are brought here to +% \cs{@@_parse_unknown_key:n} to process. +% +% The key is stored in the token list variable \cs{l_keys_key_tl}, and +% the value (if any) is passed as argument to this function. +% +% First we check if the key is an integer using \cs{int_to_roman:n}. +% If it is, we check that the value passed to the 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 index. +% Otherwise raise an error about an unknown option. +% +%%^^A Parse unknown keys +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_unknown_key:n #1 + { \exp_args:NV \@@_parse_unknown_key:nn \l_keys_key_tl {#1} } +\cs_new_protected:Npn \@@_parse_unknown_key:nn #1 #2 + { + \tl_if_empty:fTF { \int_to_roman:n { -0 #1 } } + { + \tl_if_blank:nTF {#2} + { \int_set:Nn \l_@@_seq_item_int {#1} } + { \msg_error:nnnn { scontents } { key-value-unknown } {#1} {#2} } + } + { + \tl_if_blank:nTF {#2} + { \msg_error:nnn { scontents } { key-unknown } {#1} } + { \msg_error:nnnn { scontents } { key-value-unknown } {#1} {#2} } + } } % \end{macrocode} +% \end{macro} % % \subsection{Programming of the sequences} % -%%^^A Append content to seq -% \begin{macro}{\@@_append_contents:nn,\@@_getfrom_seq:nn} +% \begin{macro}{\@@_append_contents:nn,\@@_getfrom_seq:nn,\@@_getfrom_seq:nnn} % The storage of the package is done using |seq| variables. Here we % set up the macros that will manage the variables. % % \cs{@@_append_contents:nn} creates a seq variable if one didn't % exist and appends the contents in the argument to the right of the -% sequence. \cs{@@_getfrom_seq:nn} retrieves the saved item from the +% sequence. \cs{@@_getfrom_seq:nn} retrieves the saved item from the % sequence. +% +%%^^A Programming of the sequences % \begin{macrocode} \cs_new_protected:Npn \@@_append_contents:nn #1#2 { @@ -1451,19 +1738,51 @@ } \cs_generate_variant:Nn \@@_append_contents:nn { Vx } \cs_new:Npn \@@_getfrom_seq:nn #1#2 - { \seq_item:cn { g_@@_seq_name_#2_seq } {#1} } + { + \seq_if_exist:cTF { g_@@_seq_name_#2_seq } + { + \exp_args:Nf \@@_getfrom_seq:nnn + { \seq_count:c { g_@@_seq_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_@@_seq_name_#3_seq } {#2} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_store_to_seq:NN} +% The \cs{@@_store_to_seq:NN} writes the recorded contents +% in |#1| to the log and stores it in |#2|. +% +%%^^A Storing content in sequences +% \begin{macrocode} +\cs_new_protected:Npn \@@_store_to_seq:NN #1 #2 + { + \tl_log:N #1 + \@@_append_contents:Vx #2 { \exp_not:V #1 } + } % \end{macrocode} % \end{macro} % % \subsection{Construction of environment scontents} % % We define the environment \env{scontents}, next to the system |key=val|. -% The environment is divided into three parts. This implementation is taken +% The environment is divided into three parts. This implementation is taken % from answer by Enrico Gregorio in \url{https://tex.stackexchange.com/a/487746/7832}. % -%%^^A Define |scontents| whit [key=val] (delaying) +% % \begin{macro}{scontents} % This is the main environment used in the document. +% +%%^^A Definition of {scontents}[key=val] env % \begin{macrocode} \NewDocumentEnvironment { scontents } { } { @@ -1477,48 +1796,10 @@ % \end{macrocode} % \end{macro} % -% \subsubsection{The environment itself} -% -% The environment itself -% -%%^^A First \cs{@@_start_environment:w} -% \begin{macro}{\@@_start_environment:w,\@@_stop_environment:} -% Here we make |^^M| an active character so that the end of line can -% be ``seen'' to be used as a delimiter. First we check if the line -% directly after |\begin{scontents}| contains an optional argument -% enclosed in |[...]|, or other tokens. The trailing tokens are -% treated as junk and an error is raised. The -% \cs{@@_environment_inline:w} macro checks for those cases. -% \begin{macrocode} -\group_begin: - \char_set_catcode_active:N \^^M - \cs_new_protected:Npn \@@_start_environment:w #1 ^^M - { - \@@_environment_inline:w #1 \q_@@_mark - \group_begin: - \bool_if:NTF \l_@@_writing_bool - { - \use:c { filecontentsdef* } { \l_@@_fname_out_tl } - { \l_@@_macro_tmp_tl } ^^M - } - { \filecontentsdefmacro { \l_@@_macro_tmp_tl } ^^M } - } - \cs_new_protected:Npn \@@_stop_environment: - { - \bool_if:NTF \l_@@_writing_bool - { \endfilecontentsdef } - { \endfilecontentsdefmacro } - \group_end: - } -\group_end: -% \end{macrocode} -% \end{macro} -% % \subsubsection{key val for environment} % % Define a |key=val| for environment \env{scontents} % -%%^^A key val for environment scontents % \begin{macro}{\@@_environment_inline:w,\@@_environment_keys:w, % \@@_environment_junk:nw,\@@_environment_junk:xw} % The macro \cs{@@_environment_inline:w} is called from the @@ -1527,6 +1808,8 @@ % is a |[|, then we look for an optional argument delimited by a |]|. % All the remaining tokens are treated as junk and an error is raised % if they are non-blank. +% +%%^^A Test [key=val] for environment scontents % \begin{macrocode} \cs_new_protected:Npn \@@_environment_inline:w { @@ -1552,39 +1835,258 @@ % \end{macrocode} % \end{macro} % +% \subsubsection{The environment itself} +% +% \begin{macro}{\@@_start_environment:w,\@@_stop_environment:} +% Here we make |^^I|, |^^L|, and |^^M| active characters so that the end of +% line can be ``seen'' to be used as a delimiter, and TeX doesn't try to +% eliminate space-like characters. First we check if the line +% directly after |\begin{scontents}| contains an optional argument +% enclosed in |[...]|, or other tokens. The trailing tokens are +% treated as junk and an error is raised. The +% \cs{@@_environment_inline:w} macro checks for those cases. +% +% \cs{@@_start_environment:w} calls the \cs{@@_file_tl_write_start:V} +% function, which will then read the contents of the environment and +% optionally store them in a token list or write to an external file. +% +% When that's done, \cs{@@_file_write_stop:N} does the cleanup and the +% read token list is smuggled out of the verbatim group. This part of +% the code is inspired and adapted from the code of the package \pkg{xsimverb} +% by Clemens Niederberger. +% +%^^A Hm... Apparently this is not the verbatim group, but one level above. Is +%^^A this group really necessary? +%^^A Reply : Maybe the groups aren't in the right places, but when you remove +%^^A them it just gives you errors...(test-pkg-current.tex) +% +%%^^A First start_environment/stop_environment +% \begin{macrocode} +\group_begin: + \char_set_catcode_active:N \^^I + \char_set_catcode_active:N \^^L + \char_set_catcode_active:N \^^M + \cs_new_protected:Npn \@@_start_environment:w #1 ^^M + { + \@@_environment_inline:w #1 \q_@@_mark + \@@_make_control_chars_active: + \group_begin: + \@@_file_tl_write_start:V \l_@@_fname_out_tl + } + \cs_new_protected:Npn \@@_stop_environment: + { + \@@_file_write_stop:N \l_@@_macro_tmp_tl + \exp_args:NNNV + \group_end: + \tl_set:Nn \l_@@_macro_tmp_tl \l_@@_macro_tmp_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ +% \@@_file_tl_write_start:n, +% \@@_file_tl_write_start:V, +% \@@_verb_processor_iterate:w, +% \@@_file_write_stop:N, +% \@@_remove_leading_nl:n, +% \@@_remove_leading_nl:w, +% } +% This is the main macro to collect the contents of a verbatim environment. +% The macro starts a group, opens the output file, if necessary, sets verbatim +% catcodes, and then issues |^^M| (set equal to \cs{@@_ret:w}) to read 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 output file, if any. At the end of the environment +% the output file is closed (if it was open), and the output token list is +% smuggled out of the verbatim group. A leading |^^M| is removed from the +% token list using \cs{@@_remove_leading_nl:n} (which expects an active |^^M| +% token at the head of the token list; a low level TeX error is raised +% otherwise). +% +%%^^A File write start/File write stop +% \begin{macrocode} + \cs_new_protected:Npn \@@_file_tl_write_start:n #1 + { + \group_begin: + \bool_if:NT \l_@@_writing_bool + { + \file_if_exist:nTF {#1} + { \msg_warning:nnx { scontents } { rewriting-file } {#1} } + { \msg_warning:nnx { scontents } { writing-file } {#1} } + \iow_open:Nn \l_@@_file_iow {#1} + } + \tl_clear:N \l_@@_file_tl + \seq_map_function:NN \l_char_special_seq \char_set_catcode_other:N + \int_step_function:nnN { 128 } { 255 } \char_set_catcode_letter:n + \cs_set_protected:Npx \@@_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 + } + \use:x + { + \cs_new:Npn \exp_not:N \@@_verb_processor_iterate:w + ##1 \c_@@_end_env_tl + ##2 \c_@@_end_env_tl + ##3 \exp_not:N \q_@@_stop + } { + \tl_if_blank:nTF {#3} + { + \@@_analyse_nesting:n {#1} + \@@_verb_processor_output:n {#1} + } + { + \@@_if_nested:TF + { + \@@_nesting_decr: + \@@_verb_processor_output:x + { \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:Npx \@@_ret:w + { + \exp_not:N \end{scontents} + \bool_lazy_or:nnF + { \tl_if_blank_p:n {#2} } + { \str_if_eq_p:ee {#2} { \c_percent_str } } + { + \msg_warning:nnn { scontents } { rescanning-text } {#2} + \@@_rescan_tokens:n {#2} + } + } + \char_set_active_eq:NN ^^M \@@_ret:w + } + } + ^^M + } + \cs_new_protected:Npn \@@_file_write_stop:N #1 + { + \bool_if:NT \l_@@_writing_bool + { \iow_close:N \l_@@_file_iow } + \use:x + { + \group_end: + \bool_if:NT \l_@@_storing_bool + { + \tl_set:Nn \exp_not:N #1 + { + \exp_args:NV \@@_remove_leading_nl:n \l_@@_file_tl + \bool_if:NT \l_@@_forced_eol_bool { \exp_not:N ^^J } + } + } + } + } + \cs_new:Npn \@@_remove_leading_nl:n #1 + { \exp_not:o { \@@_remove_leading_nl:w #1 } } + \cs_new:Npn \@@_remove_leading_nl:w ^^J { } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ +% \@@_verb_processor_output:n, +% \@@_verb_processor_output:x, +% \@@_analyse_nesting:n, +% \@@_analyse_nesting:w, +% \@@_nesting_decr:, +% \@@_use_none_delimit_by_q_stop:w, +% } +% \begin{macro}[TF]{\@@_if_nested:} +% \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}. +% +% \cs{@@_analyse_nesting:n} looks for nested \cs{begin}|{scontents}| +% and adds to a \cs{l_@@_env_nesting_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 \cs{end}|{scontents}| +% is found. +% +% Multiple \cs{end}|{scontents}| in the same line are not supported... +% \begin{macrocode} + \cs_new_protected:Npn \@@_verb_processor_output:n #1 + { + \bool_if:NT \l_@@_writing_bool + { \iow_now:Nn \l_@@_file_iow {#1} } + \bool_if:NT \l_@@_storing_bool + { \tl_put_right:Nn \l_@@_file_tl { ^^J #1 } } + } + \cs_generate_variant:Nn \@@_verb_processor_output:n { x } + \cs_new_protected:Npx \@@_analyse_nesting:n #1 + { + \int_zero:N \l_@@_tmpa_int + \exp_not:N \@@_analyse_nesting:w #1 + \c_backslash_str begin + \c_left_brace_str \exp_not:N \q_@@_mark \c_right_brace_str + \exp_not:N \q_@@_stop + \int_compare:nNnT { \l_@@_tmpa_int } > { 1 } + { \msg_warning:nn { scontents } { multiple-begin } } + } + \use:x + { + \cs_new_protected:Npn \exp_not:N \@@_analyse_nesting:w ##1 + \c_backslash_str begin \c_left_brace_str ##2 \c_right_brace_str + } { + \if_meaning:w \q_@@_mark #2 + \exp_after:wN \use_i:nn + \else: + \exp_after:wN \use_ii:nn + \fi: + { \@@_use_none_delimit_by_q_stop:w } + { + \str_if_eq:eeT {#2} {scontents} + { + \int_incr:N \l_@@_env_nesting_int + \int_incr:N \l_@@_tmpa_int + \@@_analyse_nesting:w + } + \@@_analyse_nesting:w + } + } + \cs_new_protected:Npn \@@_nesting_decr: + { \int_decr:N \l_@@_env_nesting_int } + \prg_new_protected_conditional:Npnn \@@_if_nested: { TF } + { + \int_compare:nNnTF { \l_@@_env_nesting_int } > { \c_zero_int } + { \prg_return_true: } + { \prg_return_false: } + } + \cs_new:Npn \@@_use_none_delimit_by_q_stop:w #1 \q_@@_stop { } +\group_end: +\cs_generate_variant:Nn \@@_file_tl_write_start:n { V } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \subsubsection{Recording of the content in the sequence} % -% \begin{macro}{\@@_atend_environment:,\@@_stored_to_seq:} -% Finishes the environment by optionally calling \cs{@@_stored_to_seq:} +% \begin{macro}{\@@_atend_environment:} +% Finishes the environment by optionally calling \cs{@@_store_to_seq:} % and then clearing the temporary token list. % -% The \cs{@@_stored_to_seq:} function replaces a carriage return -% (\textsc{ascii} 13) by a new line character (\textsc{ascii} 10) for -% optionally logging the contents of the current \env{scontents} -% environment. -% -%^^A TODO: Perhaps replace the regex by a delimited macro to improve -%^^A performance... Or temporarily redefine ^^M to mean ^^J... -%^^A Reply: Or maybe it is better to preserve the end of line with -%^^A \tex_newlinechar:D = 13 \scan_stop: +%%^^A Second atend_environment/stored_to_seq % \begin{macrocode} \cs_new_protected:Npn \@@_atend_environment: { \bool_if:NT \l_@@_storing_bool { - \@@_stored_to_seq: - \bool_if:NT \l_@@_print_env_bool - { \@@_getfrom_seq:nn { -1 } { \l_@@_name_seq_env_tl } } + \@@_store_to_seq:NN \l_@@_macro_tmp_tl \l_@@_name_seq_env_tl + } + \bool_if:NT \l_@@_print_env_bool + { + \tl_gset_eq:NN \g_@@_temp_tl \l_@@_macro_tmp_tl + \tl_gput_right:NV \g_@@_temp_tl \c_percent_str + \group_insert_after:N \@@_rescan_tokens:V + \group_insert_after:N \g_@@_temp_tl } \tl_clear:N \l_@@_macro_tmp_tl } -\cs_new_protected:Npn \@@_stored_to_seq: - { - \regex_replace_all:nnN { \^^M } { \^^J } \l_@@_macro_tmp_tl - \tl_log:N \l_@@_macro_tmp_tl - \@@_append_contents:Vx \l_@@_name_seq_env_tl - { \exp_not:N \@@_rescan_tokens:w { \tl_use:N \l_@@_macro_tmp_tl } } - } % \end{macrocode} % \end{macro} % @@ -1593,49 +2095,51 @@ % User command to stored content, adapted from % \url{https://tex.stackexchange.com/a/500281/7832}. % -%%^^A User command to stored content -% -% \begin{macro}{\Scontents,\@@_norm:n,\@@_verb:w} +% \begin{macro}{\Scontents,\@@_norm_arg:n,\@@_verb_arg:w} % The \cs{Scontents} macro starts by parsing an optional argument and -% then delegates to \cs{@@_verb:w} or \cs{@@_norm:n} depending whether +% then delegates to \cs{@@_verb_arg:w} or \cs{@@_norm_arg:n} depending whether % a star argument is present. % -% \cs{@@_norm:n} grabs a normal argument, adds it to the |seq| varaible, +% \cs{@@_norm_arg:n} grabs a normal argument, adds it to the |seq| varaible, % and optionally prints it. % -% \cs{@@_verb:w} grabs a verbatim argument using \pkg{xparse}'s |v| +% \cs{@@_verb_arg:w} grabs a verbatim argument using \pkg{xparse}'s |+v| % argument parser. % %^^A NOTE: Any particular reason why \keys_set_known:nn instead of just %^^A \keys_set:nn? The latter reports if an unknown key is used... %^^A Reply: The redirection of error messages has never worked well for me %^^A perhaps it would be better to implement it. +% +%%^^A User command \Scontents to stored content % \begin{macrocode} \NewDocumentCommand { \Scontents }{ !s !O{} } { \group_begin: \IfNoValueF {#2} { \keys_set_known:nn { scontents / Scontents } {#2} } - \IfBooleanTF{#1} - { \@@_verb:w } - { \@@_norm:n } + \char_set_catcode_active:n { 9 } + \IfBooleanTF {#1} + { \@@_verb_arg:w } + { \@@_norm_arg:n } } -\cs_new_protected:Npn \@@_norm:n #1 +\cs_new_protected:Npn \@@_norm_arg:n #1 { - \exp_args:NV \@@_append_contents:nn \l_@@_name_seq_cmd_tl {#1} - \bool_if:NT \l_@@_print_cmd_bool - { \@@_getfrom_seq:nn { -1 } { \l_@@_name_seq_cmd_tl } } - \group_end: + \exp_args:NV \@@_append_contents:nn \l_@@_name_seq_cmd_tl {#1} + \bool_if:NT \l_@@_print_cmd_bool { \@@_rescan_tokens:n {#1} } + \group_end: } -\NewDocumentCommand { \@@_verb:w } { +v } +\NewDocumentCommand { \@@_verb_arg:w } { +v } { - \tl_set:Nn \l_@@_temp_tl {#1} - \regex_replace_all:nnN { \^^M } { \^^J } \l_@@_temp_tl - \tl_log:N \l_@@_temp_tl - \exp_args:NVx \@@_append_contents:nn \l_@@_name_seq_cmd_tl - { \exp_not:N \@@_rescan_tokens:w { \tl_use:N \l_@@_temp_tl } } + \tl_set:Nx \l_@@_temp_tl + { + \exp_not:n {#1} + \bool_if:NT \l_@@_forced_eol_bool { \exp_not:N ^^J } + } + \tl_replace_all:Nxx \l_@@_temp_tl { \iow_char:N \^^M } { \iow_char:N \^^J } + \@@_store_to_seq:NN \l_@@_temp_tl \l_@@_name_seq_cmd_tl \bool_if:NT \l_@@_print_cmd_bool - { \@@_getfrom_seq:nn { -1 } { \l_@@_name_seq_cmd_tl } } + { \@@_rescan_tokens:V \l_@@_temp_tl } \group_end: } % \end{macrocode} @@ -1647,9 +2151,19 @@ % \begin{macro}{\getstored} % User command \cs{getstored} to extract stored content in |seq| % (robust). +% +%%^^A User command \getstored to get content % \begin{macrocode} \NewDocumentCommand { \getstored } { O{1} m } - { \@@_getfrom_seq:nn {#1} {#2} } + { + \group_begin: + \@@_rescan_tokens:x + { + \@@_getfrom_seq:nn {#1} {#2} + \c_percent_str + } + \group_end: + } % \end{macrocode} % \end{macro} % @@ -1658,103 +2172,132 @@ % This implementation is an adaptation taken from answer by Phelype Oleinik % in (\url{https://tex.stackexchange.com/a/497651/7832}). % -% \begin{macro}{\typestored,\@@_fcdef_print:N,\@@_xverb:w,verbatimsc} +% \begin{macro}{\typestored,\@@_verb_print:N,\@@_xverb:w,verbatimsc} % The \cs{typestored} commands fetches a buffer from memory, prints it -% to the log file, -%^^A NOTE: Perhaps this logging should be optional, with a key to switch -%^^A it on and off. -%^^A Reply:I used * because it's easier to associate it with \Scontents* -% and then calls \pkg{filecontentsdef}'s \tn{filecontentsdef@get} macro -% to read the contents of the token list and pass them to -% \cs{@@_fcdef_print:N}. +% to the log file, and then calls \cs{@@_verb_print:N}. +% +%%^^A User command \typestored to verbatimized content % \begin{macrocode} -\NewDocumentCommand { \typestored } { s O{1} m } +\NewDocumentCommand { \typestored } { o m } { \group_begin: - \tl_set:Nx \l_@@_temp_tl { \@@_getfrom_seq:nn {#2} {#3} } + \int_set:Nn \l_@@_seq_item_int { 1 } + \IfValueT {#1} { \keys_set:nn { scontents } {#1} } + \tl_set:Nx \l_@@_temp_tl { \exp_args:NV \@@_getfrom_seq:nn \l_@@_seq_item_int {#2} } \tl_log:N \l_@@_temp_tl - \IfBooleanTF {#1} - { \bool_set_false:N \l_@@_typeverb_env_bool } - { \bool_set_true:N \l_@@_typeverb_env_bool } - \use:c { filecontentsdef@get } \@@_fcdef_print:N \l_@@_temp_tl + \tl_if_empty:NF \l_@@_temp_tl + { \@@_verb_print:N \l_@@_temp_tl } \group_end: } % \end{macrocode} -% The \cs{@@_fcdef_print:N} macro is defined with active carriage return +% The \cs{@@_verb_print:N} macro is defined with active carriage return % (\textsc{ascii} 13) characters to mimick an actual verbatim environment -% ``on the loose''. The contents of the environment are placed in a -% \env{verbatimsc} environment and rescanned using \tn{scantokens}. +% \enquote{on the loose}. The contents of the environment are placed in a +% \env{verbatimsc} environment and rescanned using \cs{@@_rescan_tokens:x}. +% +%%^^A Internal verb_print:N, need to verbatimized content % \begin{macrocode} \group_begin: - \char_set_catcode_active:N \^^M - \cs_new_protected:Npn \@@_fcdef_print:N #1 + \char_set_catcode_active:N \^^M + \cs_new_protected:Npn \@@_verb_print:N #1 { \tl_if_blank:VT #1 { \msg_error:nnn { scontents } { empty-variable } {#1} } - \cs_set_eq:NN \@@_fcdef_saved_EOL: ^^M + \cs_set_eq:NN \@@_verb_print_EOL: ^^M \cs_set_eq:NN ^^M \scan_stop: - \use:x + \cs_set_eq:cN { do@noligs } \@@_do_noligs:N + \@@_rescan_tokens:x { - \exp_not:N \@@_rescan_tokens:w - { - \exp_not:N \begin{verbatimsc} ^^M - \@@_strip_scantokens:N #1 - \bool_if:NF \l_@@_typeverb_env_bool { ^^M } - \g_@@_end_verbatimsc_tl - } + \exp_not:N \begin{verbatimsc} ^^M + \exp_not:V #1 ^^M + \g_@@_end_verbatimsc_tl } - \cs_set_eq:NN ^^M \@@_fcdef_saved_EOL: + \cs_set_eq:NN ^^M \@@_verb_print_EOL: } \group_end: % \end{macrocode} +% % Finally, the \env{verbatimsc} environment is defined. -%^^A An idea taken from spverbatim +% +%%^^A Definition of verbatimsc environment % \begin{macrocode} +\cs_new_protected:Npn \@@_xverb: + { + \char_set_catcode_active:n { 9 } + \char_set_active_eq:nN { 9 } \@@_tabs_to_spaces: + \@@_xverb:w + } \use:x - { \cs_gset_protected:Npn \exp_not:N \@@_xverb:w ##1 \g_@@_end_verbatimsc_tl } + { + \cs_new_protected:Npn \exp_not:N \@@_xverb:w + ##1 \g_@@_end_verbatimsc_tl + } { #1 \end{verbatimsc} } \NewDocumentEnvironment { verbatimsc } { } { - \cs_set_eq:cN { @xverbatim } \@@_xverb:w + \cs_set_eq:cN { @xverbatim } \@@_xverb: \verbatim } { } % \end{macrocode} % \end{macro} % -% \begin{macro}{ -% \@@_strip_scantokens:N, -% \@@_strip_scantokens:n, -% \@@_if_scantokens:Nw, -% } -% The \cs{@@_strip_scantokens:n} (\cs{@@_strip_scantokens:N}) macro -% takes a token list (variable) as argument and examines it. If the -% argument token list is \emph{exactly} |\scantokens{|\meta{stuff}|}|, -% then the function returns \meta{stuff}, otherwise it returns the -% input token list without change. The token list is wrapped in -% \cs{exp_not:n} to avoid further expansion. +% \subsection{Some auxiliaries} +% +% \begin{macro}{\@@_tabs_to_spaces:} +% In a verbatim context the |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. +% +%%^^A Tab to space +% \begin{macrocode} +\cs_new:Npn \@@_tabs_to_spaces: + { \prg_replicate:nn { \l_@@_tab_width_int } { ~ } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_do_noligs:N} +% \cs{@@_do_noligs:N} is an alternative definition for \LaTeXe's +% \cs{do@noligs} which makes sure to not consume following space +% tokens. The \LaTeXe{} version ends with \cs{char}|`#1|, which +% leaves \TeX{} still looking for an \meta{optional~space}. +% This version uses \cs{char_generate:nn} to ensure that doesn't +% happen. +% +%%^^A Patch do_noligs for ligatures % \begin{macrocode} -\cs_new:Npn \@@_strip_scantokens:N #1 - { \exp_args:NV \@@_strip_scantokens:n #1 } -\cs_new:Npn \@@_strip_scantokens:n #1 +\cs_new:Npn \@@_do_noligs:N #1 { - \tl_if_head_is_N_type:nTF {#1} + \char_set_catcode_active:N #1 + \char_set_active_eq:Nc #1 { @@_active_char_ \token_to_str:N #1 : } + \cs_set:cpx { @@_active_char_ \token_to_str:N #1 : } { - \@@_if_scantokens:NwTF #1 \q_@@_mark - { - \exp_args:No \tl_if_single_token:nTF { \use_none:nn #1 ? } - { \exp_not:o { \use_ii:nn #1 } } - { \exp_not:n {#1} } - } - { \exp_not:n {#1} } + \mode_leave_vertical: + \tex_kern:D \c_zero_dim + \char_generate:nn { `#1 } { 12 } } - { \exp_not:n {#1} } } -\prg_new_conditional:Npnn \@@_if_scantokens:Nw #1#2 \q_@@_mark { TF } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{ +% \@@_set_active_eq:NN, +% \@@_make_control_chars_active:, +% } +% Shortcut definitions for common catcode changes. +% +%%^^A Common catcode changes +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_active_eq:NN #1 + { + \char_set_catcode_active:N #1 + \char_set_active_eq:NN #1 + } +\cs_new_protected:Npn \@@_make_control_chars_active: { - \token_if_eq_meaning:NNTF \@@_rescan_tokens:w #1 - { \prg_return_true: } - { \prg_return_false: } + \@@_set_active_eq:NN \^^I \@@_tab: + \@@_set_active_eq:NN \^^L \@@_par: + \@@_set_active_eq:NN \^^M \@@_ret:w } % \end{macrocode} % \end{macro} @@ -1762,9 +2305,11 @@ % \subsection{The command \cs{setupsc}} % % User command \cs{setupsc} to setup module. -%%^^A User command to setup module +% % \begin{macro}{\setupsc} -% A user-level wrapper for \cs{keys_set:nn}|{ scontents }| +% A user-level wrapper for \cs{keys_set:nn}|{ scontents }|. +% +%%^^A User command \setupsc % \begin{macrocode} \NewDocumentCommand { \setupsc } { m } { \keys_set:nn { scontents } {#1} } @@ -1773,30 +2318,42 @@ % % \subsection{The command meaningsc} % -% \begin{macro}[do-not-index=\v]{\meaningsc} -% User command \cs{meaningsc} to see content stored in seq. -%^^A NOTE: Perhaps replace \cs{regex_replace_all:nnN} by something more -%^^A efficient... -%^^A Reply: I've only used it to avoid ΩΩ ... +% +% \begin{macro}{\meaningsc} +% User command \cs{meaningsc} to see content stored in |seq|. +% +%%^^A User command \meaningsc % \begin{macrocode} -\NewDocumentCommand { \meaningsc } { O{1} m } +\NewDocumentCommand { \meaningsc } { o m } { \group_begin: - \tl_set:Nx \l_@@_temp_tl { \@@_getfrom_seq:nn {#1} {#2} } - \tl_log:N \l_@@_temp_tl - \tl_set:Nx \l_@@_temp_tl { \@@_strip_scantokens:N \l_@@_temp_tl } - \regex_replace_all:nnN { \v{1,} } { } \l_@@_temp_tl - \ttfamily - \cs_replacement_spec:N \l_@@_temp_tl + \int_set:Nn \l_@@_seq_item_int { 1 } + \IfValueT {#1} { \keys_set:nn { scontents } {#1} } + \@@_meaningsc:n {#2} \group_end: } +\group_begin: + \char_set_catcode_active:N \^^I + \cs_new_protected:Npn \@@_meaningsc:n #1 + { + \tl_set:Nx \l_@@_temp_tl { \exp_args:NV \@@_getfrom_seq:nn \l_@@_seq_item_int {#1} } + \tl_replace_all:Nxn \l_@@_temp_tl { \iow_char:N \^^J } { ~ } + \tl_log:N \l_@@_temp_tl + \tl_use:N \l_@@_verb_font_tl + \tl_replace_all:Nnx \l_@@_temp_tl { ^^I } { \@@_tabs_to_spaces: } + \cs_replacement_spec:N \l_@@_temp_tl + } +\group_end: % \end{macrocode} % \end{macro} % % \subsection{The command \cs{countsc}} % +% % \begin{macro}{\countsc} -% User command \cs{countsc} to count number of contents stored in seq. +% User command \cs{countsc} to count number of contents stored in |seq|. +% +%%^^A User command \countsc % \begin{macrocode} \NewExpandableDocumentCommand { \countsc } { m } { \seq_count:c { g_@@_seq_name_#1_seq } } @@ -1805,8 +2362,11 @@ % % \subsection{The command \cs{cleanseqsc}} % +% % \begin{macro}{\cleanseqsc} -% A user command \cs{cleanseqsc} to clear (remove) a defined seq +% A user command \cs{cleanseqsc} to clear (remove) a defined |seq|. +% +%%^^A User command \cleanseqsc % \begin{macrocode} \NewDocumentCommand { \cleanseqsc } { m } { \seq_clear_new:c { g_@@_seq_name_#1_seq } } @@ -1814,9 +2374,10 @@ % \end{macro} % % \subsection{Messages} +% % Messages used throughout the package. -%%^^A Messages % +%%^^A Messages used throughout the package % \begin{macrocode} \msg_new:nnn { scontents } { junk-after-begin } { @@ -1827,18 +2388,54 @@ \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:. } + { Variable~`#1'~empty~\msg_line_context:. } +\msg_new:nnn { scontents } { rewriting-file } + { Overwriting ~ file ~ `#1' } +\msg_new:nnn { scontents } { writing-file } + { Writing ~ file ~ `#1' } +\msg_new:nnn { scontents } { rescanning-text } + { Rescanning~text~`#1'~after~\c_backslash_str end{scontents}~\msg_line_context:.} +\msg_new:nnn { scontents } { multiple-begin } + { Multiple~\c_backslash_str begin{scontents}~\msg_line_context:.} +\msg_new:nnn { scontents } { tab-to-space } + { Tab~has~been~converted~to~Blank~Space } +\msg_new:nnn { scontents } { feed-to-space } + { Form~Feed~has~been~converted~to~Blank~Space } +\msg_new:nnnn { scontents } { key-unknown } + { The~key~'#1'~is~unknown~and~is~being~ignored. } + { + The~module~'scontents'~does~not~have~a~key~called~'#1'.\\ + Check~that~you~have~spelled~the~key~name~correctly. + } +\msg_new:nnnn { scontents } { key-value-unknown } + { The~key~'#1'~to~which~you~passed~'#2'~is~unknown~and~is~being~ignored. } + { + The~module~'scontents'~does~not~have~a~key~called~'#1'.\\ + Check~that~you~have~spelled~the~key~name~correctly. + } +\msg_new:nnn { scontents } { undefined-storage } + { Storage~named~'#1'~is~not~defined. } +\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. + } + } % \end{macrocode} % % \subsection{Finish package} +% % Finish package -%%^^A Finish package % +%%^^A Finish package :) % \begin{macrocode} \file_input_stop: % \end{macrocode} % \iffalse %</package> % \fi -% % \Finale diff --git a/macros/latex/contrib/scontents/scontents.pdf b/macros/latex/contrib/scontents/scontents.pdf Binary files differindex 6e78f883be..3dd1234ddb 100644 --- a/macros/latex/contrib/scontents/scontents.pdf +++ b/macros/latex/contrib/scontents/scontents.pdf |