summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2019-09-22 22:17:43 +0000
committerKarl Berry <karl@freefriends.org>2019-09-22 22:17:43 +0000
commite8ecc48889dada1c120538d29a91b305dc934237 (patch)
treeb908c56088d96a508db5530b5033925644bee249 /Master
parent44d4827fac150f508a6985f9053579f13479b5da (diff)
scontents (23sep19)
git-svn-id: svn://tug.org/texlive/trunk@52155 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/scontents/README.md12
-rw-r--r--Master/texmf-dist/doc/latex/scontents/scontents.pdfbin198211 -> 244760 bytes
-rw-r--r--Master/texmf-dist/source/latex/scontents/scontents.dtx1817
-rw-r--r--Master/texmf-dist/tex/latex/scontents/scontents.sty512
4 files changed, 1604 insertions, 737 deletions
diff --git a/Master/texmf-dist/doc/latex/scontents/README.md b/Master/texmf-dist/doc/latex/scontents/README.md
index c446c1bf8db..c5ea1504613 100644
--- a/Master/texmf-dist/doc/latex/scontents/README.md
+++ b/Master/texmf-dist/doc/latex/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/Master/texmf-dist/doc/latex/scontents/scontents.pdf b/Master/texmf-dist/doc/latex/scontents/scontents.pdf
index 6e78f883be3..3dd1234ddba 100644
--- a/Master/texmf-dist/doc/latex/scontents/scontents.pdf
+++ b/Master/texmf-dist/doc/latex/scontents/scontents.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/scontents/scontents.dtx b/Master/texmf-dist/source/latex/scontents/scontents.dtx
index 9084a7ea356..1aa64dcc3de 100644
--- a/Master/texmf-dist/source/latex/scontents/scontents.dtx
+++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/tex/latex/scontents/scontents.sty b/Master/texmf-dist/tex/latex/scontents/scontents.sty
index 35771c8f982..6983b4517d5 100644
--- a/Master/texmf-dist/tex/latex/scontents/scontents.sty
+++ b/Master/texmf-dist/tex/latex/scontents/scontents.sty
@@ -1,8 +1,9 @@
-\RequirePackage{filecontentsdef}[2019/04/20]
+%%^^A Initial declaration of the package
\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}
+%%^^A Checking the version of xparse
\@ifpackagelater { xparse } { 2019/05/03 }
{ }
{
@@ -14,41 +15,52 @@
}
\file_input_stop:
}
+%%^^A Common keys available as package options
\keys_define:nn { scontents }
{
store-env .tl_set:N = \l__scontents_name_seq_env_tl,
store-env .initial:n = contents,
- print-env .bool_set:N = \l__scontents_print_env_bool,
- print-env .initial:n = false,
+ store-env .value_required:n = true,
store-cmd .tl_set:N = \l__scontents_name_seq_cmd_tl,
store-cmd .initial:n = contents,
+ store-cmd .value_required:n = true,
+ verb-font .tl_set:N = \l__scontents_verb_font_tl,
+ verb-font .initial:n = \ttfamily,
+ verb-font .value_required:n = true,
+ print-env .bool_set:N = \l__scontents_print_env_bool,
+ print-env .initial:n = false,
+ print-env .default:n = true,
print-cmd .bool_set:N = \l__scontents_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__scontents_forced_eol_bool,
+ force-eol .initial:n = false,
+ force-eol .default:n = true,
+ width-tab .int_set:N = \l__scontents_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 = { \__scontents_parse_unknown_key:n {#1} }
}
-%%^^A Process options for pkg
+%%^^A Process options for package
\ProcessKeysOptions { scontents }
-%%^^A Internal tl vars
+%%^^A Internal token list vars
\tl_new:N \l__scontents_macro_tmp_tl
\tl_new:N \l__scontents_fname_out_tl
\tl_new:N \l__scontents_temp_tl
+\tl_new:N \l__scontents_file_tl
+\tl_new:N \g__scontents_temp_tl
+%%^^A Internal int vars
+\int_new:N \l__scontents_seq_item_int
+\int_new:N \l__scontents_env_nesting_int
+\int_new:N \l__scontents_tmpa_int
%%^^A Internal bool vars
-\bool_new:N \l__scontents_typeverb_env_bool
-\bool_set_true:N \l__scontents_typevrb_env_bool
\bool_new:N \l__scontents_writing_bool
\bool_set_false:N \l__scontents_writing_bool
\bool_new:N \l__scontents_storing_bool
\bool_set_true:N \l__scontents_storing_bool
-%%^^A Internal quarks
-\quark_new:N \q__scontents_stop
-\quark_new:N \q__scontents_mark
-%%^^A Internal quarks
-\cs_new_eq:NN \__scontents_rescan_tokens:w \tex_scantokens:D
+%%^^A A token list to match \env{verbatimsc} and \env{scontents}
\tl_new:N \g__scontents_end_verbatimsc_tl
\tl_gset_rescan:Nnn
\g__scontents_end_verbatimsc_tl
@@ -58,6 +70,23 @@
\char_set_catcode_other:N \}
}
{ \end{verbatimsc} }
+\tl_const:Nx \c__scontents_end_env_tl
+ { \c_backslash_str end \c_left_brace_str scontents \c_right_brace_str }
+%%^^A Internal quarks
+\quark_new:N \q__scontents_stop
+\quark_new:N \q__scontents_mark
+%%^^A Stream for saving the contents
+\iow_new:N \l__scontents_file_iow
+%%^^A Copy of scantokens in expl3
+\cs_new_protected:Npn \__scontents_rescan_tokens:n #1 { \tex_scantokens:D {#1} }
+\cs_generate_variant:Nn \__scontents_rescan_tokens:n { V, x }
+%%^^A Internal \tab and \par
+\cs_new:Npx \__scontents_tab: { \c_space_tl }
+\cs_new:Npn \__scontents_par: { ^^J ^^J }
+%%^^A Some nonstandard variants
+\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 }
%%^^A Add keys to scontents environnment
\keys_define:nn { scontents }
{
@@ -73,13 +102,31 @@
write-env .value_required:n = true,
write-out .value_required:n = true
}
-%%^^A A sub/keys for command |\Scontents|
+%%^^A A sub/keys for command \Scontents
\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 }
}
-%%^^A Append content to seq
+%%^^A Parse unknown keys
+\cs_new_protected:Npn \__scontents_parse_unknown_key:n #1
+ { \exp_args:NV \__scontents_parse_unknown_key:nn \l_keys_key_tl {#1} }
+\cs_new_protected:Npn \__scontents_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__scontents_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} }
+ }
+ }
+%%^^A Programming of the sequences
\cs_new_protected:Npn \__scontents_append_contents:nn #1#2
{
\tl_if_blank:nT {#1}
@@ -90,8 +137,30 @@
}
\cs_generate_variant:Nn \__scontents_append_contents:nn { Vx }
\cs_new:Npn \__scontents_getfrom_seq:nn #1#2
- { \seq_item:cn { g__scontents_seq_name_#2_seq } {#1} }
-%%^^A Define |scontents| whit [key=val] (delaying)
+ {
+ \seq_if_exist:cTF { g__scontents_seq_name_#2_seq }
+ {
+ \exp_args:Nf \__scontents_getfrom_seq:nnn
+ { \seq_count:c { g__scontents_seq_name_#2_seq } }
+ {#1} {#2}
+ }
+ { \msg_expandable_error:nnn { scontents } { undefined-storage } {#2} }
+ }
+\cs_new:Npn \__scontents_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__scontents_seq_name_#3_seq } {#2} }
+ }
+%%^^A Storing content in sequences
+\cs_new_protected:Npn \__scontents_store_to_seq:NN #1 #2
+ {
+ \tl_log:N #1
+ \__scontents_append_contents:Vx #2 { \exp_not:V #1 }
+ }
+%%^^A Definition of {scontents}[key=val] env
\NewDocumentEnvironment { scontents } { }
{
\char_set_catcode_active:N \^^M
@@ -101,29 +170,7 @@
\__scontents_stop_environment:
\__scontents_atend_environment:
}
-%%^^A First \cs{@@_start_environment:w}
-\group_begin:
- \char_set_catcode_active:N \^^M
- \cs_new_protected:Npn \__scontents_start_environment:w #1 ^^M
- {
- \__scontents_environment_inline:w #1 \q__scontents_mark
- \group_begin:
- \bool_if:NTF \l__scontents_writing_bool
- {
- \use:c { filecontentsdef* } { \l__scontents_fname_out_tl }
- { \l__scontents_macro_tmp_tl } ^^M
- }
- { \filecontentsdefmacro { \l__scontents_macro_tmp_tl } ^^M }
- }
- \cs_new_protected:Npn \__scontents_stop_environment:
- {
- \bool_if:NTF \l__scontents_writing_bool
- { \endfilecontentsdef }
- { \endfilecontentsdefmacro }
- \group_end:
- }
-\group_end:
-%%^^A key val for environment scontents
+%%^^A Test [key=val] for environment scontents
\cs_new_protected:Npn \__scontents_environment_inline:w
{
\peek_charcode_ignore_spaces:NTF [ % ]
@@ -145,135 +192,322 @@
{ \msg_error:nnnn { scontents } { junk-after-begin } {#1} {#2} }
}
\cs_generate_variant:Nn \__scontents_environment_junk:nw { x }
+%%^^A First start_environment/stop_environment
+\group_begin:
+ \char_set_catcode_active:N \^^I
+ \char_set_catcode_active:N \^^L
+ \char_set_catcode_active:N \^^M
+ \cs_new_protected:Npn \__scontents_start_environment:w #1 ^^M
+ {
+ \__scontents_environment_inline:w #1 \q__scontents_mark
+ \__scontents_make_control_chars_active:
+ \group_begin:
+ \__scontents_file_tl_write_start:V \l__scontents_fname_out_tl
+ }
+ \cs_new_protected:Npn \__scontents_stop_environment:
+ {
+ \__scontents_file_write_stop:N \l__scontents_macro_tmp_tl
+ \exp_args:NNNV
+ \group_end:
+ \tl_set:Nn \l__scontents_macro_tmp_tl \l__scontents_macro_tmp_tl
+ }
+%%^^A File write start/File write stop
+ \cs_new_protected:Npn \__scontents_file_tl_write_start:n #1
+ {
+ \group_begin:
+ \bool_if:NT \l__scontents_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__scontents_file_iow {#1}
+ }
+ \tl_clear:N \l__scontents_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 \__scontents_ret:w ##1 ^^M
+ {
+ \exp_not:N \__scontents_verb_processor_iterate:w
+ ##1 \c__scontents_end_env_tl
+ \c__scontents_end_env_tl
+ \exp_not:N \q__scontents_stop
+ }
+ \__scontents_make_control_chars_active:
+ \__scontents_ret:w
+ }
+ \use:x
+ {
+ \cs_new:Npn \exp_not:N \__scontents_verb_processor_iterate:w
+ ##1 \c__scontents_end_env_tl
+ ##2 \c__scontents_end_env_tl
+ ##3 \exp_not:N \q__scontents_stop
+ } {
+ \tl_if_blank:nTF {#3}
+ {
+ \__scontents_analyse_nesting:n {#1}
+ \__scontents_verb_processor_output:n {#1}
+ }
+ {
+ \__scontents_if_nested:TF
+ {
+ \__scontents_nesting_decr:
+ \__scontents_verb_processor_output:x
+ { \exp_not:n {#1} \c__scontents_end_env_tl \exp_not:n {#2} }
+ }
+ {
+ \tl_if_blank:nF {#1}
+ { \__scontents_verb_processor_output:n {#1} }
+ \cs_set_protected:Npx \__scontents_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}
+ \__scontents_rescan_tokens:n {#2}
+ }
+ }
+ \char_set_active_eq:NN ^^M \__scontents_ret:w
+ }
+ }
+ ^^M
+ }
+ \cs_new_protected:Npn \__scontents_file_write_stop:N #1
+ {
+ \bool_if:NT \l__scontents_writing_bool
+ { \iow_close:N \l__scontents_file_iow }
+ \use:x
+ {
+ \group_end:
+ \bool_if:NT \l__scontents_storing_bool
+ {
+ \tl_set:Nn \exp_not:N #1
+ {
+ \exp_args:NV \__scontents_remove_leading_nl:n \l__scontents_file_tl
+ \bool_if:NT \l__scontents_forced_eol_bool { \exp_not:N ^^J }
+ }
+ }
+ }
+ }
+ \cs_new:Npn \__scontents_remove_leading_nl:n #1
+ { \exp_not:o { \__scontents_remove_leading_nl:w #1 } }
+ \cs_new:Npn \__scontents_remove_leading_nl:w ^^J { }
+ \cs_new_protected:Npn \__scontents_verb_processor_output:n #1
+ {
+ \bool_if:NT \l__scontents_writing_bool
+ { \iow_now:Nn \l__scontents_file_iow {#1} }
+ \bool_if:NT \l__scontents_storing_bool
+ { \tl_put_right:Nn \l__scontents_file_tl { ^^J #1 } }
+ }
+ \cs_generate_variant:Nn \__scontents_verb_processor_output:n { x }
+ \cs_new_protected:Npx \__scontents_analyse_nesting:n #1
+ {
+ \int_zero:N \l__scontents_tmpa_int
+ \exp_not:N \__scontents_analyse_nesting:w #1
+ \c_backslash_str begin
+ \c_left_brace_str \exp_not:N \q__scontents_mark \c_right_brace_str
+ \exp_not:N \q__scontents_stop
+ \int_compare:nNnT { \l__scontents_tmpa_int } > { 1 }
+ { \msg_warning:nn { scontents } { multiple-begin } }
+ }
+ \use:x
+ {
+ \cs_new_protected:Npn \exp_not:N \__scontents_analyse_nesting:w ##1
+ \c_backslash_str begin \c_left_brace_str ##2 \c_right_brace_str
+ } {
+ \if_meaning:w \q__scontents_mark #2
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ { \__scontents_use_none_delimit_by_q_stop:w }
+ {
+ \str_if_eq:eeT {#2} {scontents}
+ {
+ \int_incr:N \l__scontents_env_nesting_int
+ \int_incr:N \l__scontents_tmpa_int
+ \__scontents_analyse_nesting:w
+ }
+ \__scontents_analyse_nesting:w
+ }
+ }
+ \cs_new_protected:Npn \__scontents_nesting_decr:
+ { \int_decr:N \l__scontents_env_nesting_int }
+ \prg_new_protected_conditional:Npnn \__scontents_if_nested: { TF }
+ {
+ \int_compare:nNnTF { \l__scontents_env_nesting_int } > { \c_zero_int }
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+ \cs_new:Npn \__scontents_use_none_delimit_by_q_stop:w #1 \q__scontents_stop { }
+\group_end:
+\cs_generate_variant:Nn \__scontents_file_tl_write_start:n { V }
+%%^^A Second atend_environment/stored_to_seq
\cs_new_protected:Npn \__scontents_atend_environment:
{
\bool_if:NT \l__scontents_storing_bool
{
- \__scontents_stored_to_seq:
- \bool_if:NT \l__scontents_print_env_bool
- { \__scontents_getfrom_seq:nn { -1 } { \l__scontents_name_seq_env_tl } }
+ \__scontents_store_to_seq:NN \l__scontents_macro_tmp_tl \l__scontents_name_seq_env_tl
+ }
+ \bool_if:NT \l__scontents_print_env_bool
+ {
+ \tl_gset_eq:NN \g__scontents_temp_tl \l__scontents_macro_tmp_tl
+ \tl_gput_right:NV \g__scontents_temp_tl \c_percent_str
+ \group_insert_after:N \__scontents_rescan_tokens:V
+ \group_insert_after:N \g__scontents_temp_tl
}
\tl_clear:N \l__scontents_macro_tmp_tl
}
-\cs_new_protected:Npn \__scontents_stored_to_seq:
- {
- \regex_replace_all:nnN { \^^M } { \^^J } \l__scontents_macro_tmp_tl
- \tl_log:N \l__scontents_macro_tmp_tl
- \__scontents_append_contents:Vx \l__scontents_name_seq_env_tl
- { \exp_not:N \__scontents_rescan_tokens:w { \tl_use:N \l__scontents_macro_tmp_tl } }
- }
-%%^^A User command to stored content
+%%^^A User command \Scontents to stored content
\NewDocumentCommand { \Scontents }{ !s !O{} }
{
\group_begin:
\IfNoValueF {#2}
{ \keys_set_known:nn { scontents / Scontents } {#2} }
- \IfBooleanTF{#1}
- { \__scontents_verb:w }
- { \__scontents_norm:n }
+ \char_set_catcode_active:n { 9 }
+ \IfBooleanTF {#1}
+ { \__scontents_verb_arg:w }
+ { \__scontents_norm_arg:n }
}
-\cs_new_protected:Npn \__scontents_norm:n #1
+\cs_new_protected:Npn \__scontents_norm_arg:n #1
{
- \exp_args:NV \__scontents_append_contents:nn \l__scontents_name_seq_cmd_tl {#1}
- \bool_if:NT \l__scontents_print_cmd_bool
- { \__scontents_getfrom_seq:nn { -1 } { \l__scontents_name_seq_cmd_tl } }
- \group_end:
+ \exp_args:NV \__scontents_append_contents:nn \l__scontents_name_seq_cmd_tl {#1}
+ \bool_if:NT \l__scontents_print_cmd_bool { \__scontents_rescan_tokens:n {#1} }
+ \group_end:
}
-\NewDocumentCommand { \__scontents_verb:w } { +v }
+\NewDocumentCommand { \__scontents_verb_arg:w } { +v }
{
- \tl_set:Nn \l__scontents_temp_tl {#1}
- \regex_replace_all:nnN { \^^M } { \^^J } \l__scontents_temp_tl
- \tl_log:N \l__scontents_temp_tl
- \exp_args:NVx \__scontents_append_contents:nn \l__scontents_name_seq_cmd_tl
- { \exp_not:N \__scontents_rescan_tokens:w { \tl_use:N \l__scontents_temp_tl } }
+ \tl_set:Nx \l__scontents_temp_tl
+ {
+ \exp_not:n {#1}
+ \bool_if:NT \l__scontents_forced_eol_bool { \exp_not:N ^^J }
+ }
+ \tl_replace_all:Nxx \l__scontents_temp_tl { \iow_char:N \^^M } { \iow_char:N \^^J }
+ \__scontents_store_to_seq:NN \l__scontents_temp_tl \l__scontents_name_seq_cmd_tl
\bool_if:NT \l__scontents_print_cmd_bool
- { \__scontents_getfrom_seq:nn { -1 } { \l__scontents_name_seq_cmd_tl } }
+ { \__scontents_rescan_tokens:V \l__scontents_temp_tl }
\group_end:
}
+%%^^A User command \getstored to get content
\NewDocumentCommand { \getstored } { O{1} m }
- { \__scontents_getfrom_seq:nn {#1} {#2} }
-\NewDocumentCommand { \typestored } { s O{1} m }
{
\group_begin:
- \tl_set:Nx \l__scontents_temp_tl { \__scontents_getfrom_seq:nn {#2} {#3} }
+ \__scontents_rescan_tokens:x
+ {
+ \__scontents_getfrom_seq:nn {#1} {#2}
+ \c_percent_str
+ }
+ \group_end:
+ }
+%%^^A User command \typestored to verbatimized content
+\NewDocumentCommand { \typestored } { o m }
+ {
+ \group_begin:
+ \int_set:Nn \l__scontents_seq_item_int { 1 }
+ \IfValueT {#1} { \keys_set:nn { scontents } {#1} }
+ \tl_set:Nx \l__scontents_temp_tl { \exp_args:NV \__scontents_getfrom_seq:nn \l__scontents_seq_item_int {#2} }
\tl_log:N \l__scontents_temp_tl
- \IfBooleanTF {#1}
- { \bool_set_false:N \l__scontents_typeverb_env_bool }
- { \bool_set_true:N \l__scontents_typeverb_env_bool }
- \use:c { filecontentsdef@get } \__scontents_fcdef_print:N \l__scontents_temp_tl
+ \tl_if_empty:NF \l__scontents_temp_tl
+ { \__scontents_verb_print:N \l__scontents_temp_tl }
\group_end:
}
+%%^^A Internal verb_print:N, need to verbatimized content
\group_begin:
- \char_set_catcode_active:N \^^M
- \cs_new_protected:Npn \__scontents_fcdef_print:N #1
+ \char_set_catcode_active:N \^^M
+ \cs_new_protected:Npn \__scontents_verb_print:N #1
{
\tl_if_blank:VT #1
{ \msg_error:nnn { scontents } { empty-variable } {#1} }
- \cs_set_eq:NN \__scontents_fcdef_saved_EOL: ^^M
+ \cs_set_eq:NN \__scontents_verb_print_EOL: ^^M
\cs_set_eq:NN ^^M \scan_stop:
- \use:x
+ \cs_set_eq:cN { do@noligs } \__scontents_do_noligs:N
+ \__scontents_rescan_tokens:x
{
- \exp_not:N \__scontents_rescan_tokens:w
- {
- \exp_not:N \begin{verbatimsc} ^^M
- \__scontents_strip_scantokens:N #1
- \bool_if:NF \l__scontents_typeverb_env_bool { ^^M }
- \g__scontents_end_verbatimsc_tl
- }
+ \exp_not:N \begin{verbatimsc} ^^M
+ \exp_not:V #1 ^^M
+ \g__scontents_end_verbatimsc_tl
}
- \cs_set_eq:NN ^^M \__scontents_fcdef_saved_EOL:
+ \cs_set_eq:NN ^^M \__scontents_verb_print_EOL:
}
\group_end:
+%%^^A Definition of verbatimsc environment
+\cs_new_protected:Npn \__scontents_xverb:
+ {
+ \char_set_catcode_active:n { 9 }
+ \char_set_active_eq:nN { 9 } \__scontents_tabs_to_spaces:
+ \__scontents_xverb:w
+ }
\use:x
- { \cs_gset_protected:Npn \exp_not:N \__scontents_xverb:w ##1 \g__scontents_end_verbatimsc_tl }
+ {
+ \cs_new_protected:Npn \exp_not:N \__scontents_xverb:w
+ ##1 \g__scontents_end_verbatimsc_tl
+ }
{ #1 \end{verbatimsc} }
\NewDocumentEnvironment { verbatimsc } { }
{
- \cs_set_eq:cN { @xverbatim } \__scontents_xverb:w
+ \cs_set_eq:cN { @xverbatim } \__scontents_xverb:
\verbatim
}
{ }
-\cs_new:Npn \__scontents_strip_scantokens:N #1
- { \exp_args:NV \__scontents_strip_scantokens:n #1 }
-\cs_new:Npn \__scontents_strip_scantokens:n #1
+%%^^A Tab to space
+\cs_new:Npn \__scontents_tabs_to_spaces:
+ { \prg_replicate:nn { \l__scontents_tab_width_int } { ~ } }
+%%^^A Patch do_noligs for ligatures
+\cs_new:Npn \__scontents_do_noligs:N #1
{
- \tl_if_head_is_N_type:nTF {#1}
+ \char_set_catcode_active:N #1
+ \char_set_active_eq:Nc #1 { __scontents_active_char_ \token_to_str:N #1 : }
+ \cs_set:cpx { __scontents_active_char_ \token_to_str:N #1 : }
{
- \__scontents_if_scantokens:NwTF #1 \q__scontents_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 \__scontents_if_scantokens:Nw #1#2 \q__scontents_mark { TF }
+%%^^A Common catcode changes
+\cs_new_protected:Npn \__scontents_set_active_eq:NN #1
+ {
+ \char_set_catcode_active:N #1
+ \char_set_active_eq:NN #1
+ }
+\cs_new_protected:Npn \__scontents_make_control_chars_active:
{
- \token_if_eq_meaning:NNTF \__scontents_rescan_tokens:w #1
- { \prg_return_true: }
- { \prg_return_false: }
+ \__scontents_set_active_eq:NN \^^I \__scontents_tab:
+ \__scontents_set_active_eq:NN \^^L \__scontents_par:
+ \__scontents_set_active_eq:NN \^^M \__scontents_ret:w
}
-%%^^A User command to setup module
+%%^^A User command \setupsc
\NewDocumentCommand { \setupsc } { m }
{ \keys_set:nn { scontents } {#1} }
-\NewDocumentCommand { \meaningsc } { O{1} m }
+%%^^A User command \meaningsc
+\NewDocumentCommand { \meaningsc } { o m }
{
\group_begin:
- \tl_set:Nx \l__scontents_temp_tl { \__scontents_getfrom_seq:nn {#1} {#2} }
- \tl_log:N \l__scontents_temp_tl
- \tl_set:Nx \l__scontents_temp_tl { \__scontents_strip_scantokens:N \l__scontents_temp_tl }
- \regex_replace_all:nnN { \v{1,} } { } \l__scontents_temp_tl
- \ttfamily
- \cs_replacement_spec:N \l__scontents_temp_tl
+ \int_set:Nn \l__scontents_seq_item_int { 1 }
+ \IfValueT {#1} { \keys_set:nn { scontents } {#1} }
+ \__scontents_meaningsc:n {#2}
\group_end:
}
+\group_begin:
+ \char_set_catcode_active:N \^^I
+ \cs_new_protected:Npn \__scontents_meaningsc:n #1
+ {
+ \tl_set:Nx \l__scontents_temp_tl { \exp_args:NV \__scontents_getfrom_seq:nn \l__scontents_seq_item_int {#1} }
+ \tl_replace_all:Nxn \l__scontents_temp_tl { \iow_char:N \^^J } { ~ }
+ \tl_log:N \l__scontents_temp_tl
+ \tl_use:N \l__scontents_verb_font_tl
+ \tl_replace_all:Nnx \l__scontents_temp_tl { ^^I } { \__scontents_tabs_to_spaces: }
+ \cs_replacement_spec:N \l__scontents_temp_tl
+ }
+\group_end:
+%%^^A User command \countsc
\NewExpandableDocumentCommand { \countsc } { m }
{ \seq_count:c { g__scontents_seq_name_#1_seq } }
+%%^^A User command \cleanseqsc
\NewDocumentCommand { \cleanseqsc } { m }
{ \seq_clear_new:c { g__scontents_seq_name_#1_seq } }
-%%^^A Messages
+%%^^A Messages used throughout the package
\msg_new:nnn { scontents } { junk-after-begin }
{
Junk~characters~#1~\msg_line_context: :
@@ -283,6 +517,42 @@
\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:. }
-%%^^A Finish package
+ { 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.
+ }
+ }
+%%^^A Finish package :)
\file_input_stop: