summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2023-02-28 21:05:07 +0000
committerKarl Berry <karl@freefriends.org>2023-02-28 21:05:07 +0000
commit0f449ea2cee2e60c39cfa835b78a86b9f61c860e (patch)
tree49be9f427643d503e78b62d007e44d9954f77c18 /Master/texmf-dist/source
parent8d584fcc6097a3e5925137923c1b9911d8185753 (diff)
fistrum (28feb23) (branch)
git-svn-id: svn://tug.org/texlive/branches/branch2022.final@66263 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/latex/fistrum/fistrum.dtx1484
-rw-r--r--Master/texmf-dist/source/latex/fistrum/fistrum.ins117
2 files changed, 1601 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/fistrum/fistrum.dtx b/Master/texmf-dist/source/latex/fistrum/fistrum.dtx
new file mode 100644
index 00000000000..189bb3c6362
--- /dev/null
+++ b/Master/texmf-dist/source/latex/fistrum/fistrum.dtx
@@ -0,0 +1,1484 @@
+% \iffalse meta-comment
+%
+% This file is part of the package fistrum for use with LaTeX2e.
+%
+% Function: Access to 150 paragraphs of the well known Lorem Ipsum dummy text.
+%
+% This program may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% Please send error reports and suggestions for improvements to
+% https://github.com/daviddavo/fistrum
+%
+\def\fistrumversion{0.1}
+\def\fistrumdate{2023-02-28}
+%<*driver>
+\ProvidesFile{fistrum.dtx}%
+ [\fistrumdate\space v\fistrumversion\space
+ Por la gloria de mi madre, ese pedazo de texto de ejemplo.]
+\documentclass{l3doc}
+\usepackage{xcolor}
+\usepackage{booktabs}
+\usepackage{tabularx}
+\usepackage{enumitem}
+\usepackage{tikz}
+\usetikzlibrary{positioning}
+\usepackage[a4paper,
+ top=2cm, left=8.8cm, right=2cm, bottom=3cm,
+ marginparwidth=6.3cm, marginparsep=.5cm,
+]{geometry}
+\newlength\fullmargin
+\setlength\fullmargin\marginparwidth
+\addtolength\fullmargin\marginparsep
+\usepackage{mdframed}
+\mdfdefinestyle{expl}{%
+ backgroundcolor=black!5!white,
+ linewidth=0pt,
+ middlelinewidth=0pt
+}
+\newmdenv[style=expl]{explbox}
+
+\usepackage{fistrum,multicol}
+\usepackage{multirow}
+\usepackage[latin, spanish, es-noshorthands]{babel}
+\usepackage[useregional]{datetime2}
+\makeatletter
+\newcommand\@subtitle{}
+\newcommand\subtitle[1]{%
+ \renewcommand\@subtitle{#1}}
+ \renewcommand\maketitle[1]{%
+ \noindent
+ \hspace{-\fullmargin}%
+ \begin{minipage}{\textwidth+\fullmargin}
+ \renewcommand\thefootnote{\fnsymbol{footnote}}
+ \let\thanks\footnote
+ {
+ \centering
+ {\LARGE \@title}\\[.8\baselineskip]
+ {\LARGE \@subtitle}\\[2\baselineskip]
+ {\Large \@author}\\[\baselineskip]
+ {\Large \@date}\\[\baselineskip]
+ }
+ \ifx\\#1\\\else
+ \begin{multicols}{2}[%
+ \subsection*{\hfill\abstractname\hfill\null}]
+ \setlength{\columnsep}{.5cm}%
+ #1
+ \end{multicols}
+ \fi
+ \end{minipage}}
+\makeatother
+\newenvironment{wide}
+ {\hspace{-.75\fullmargin}%
+ \begin{minipage}{\textwidth+.75\fullmargin}}
+ {\end{minipage}}
+\newcommand\opt[1]{\textsf{#1}} % l3doc does not have some markup for package options...
+\newcommand\fist{\emph{Lorem fistrum\ldots}}
+\renewcommand\topfraction{.85}
+\renewcommand\textfraction{.15}
+\renewcommand\floatpagefraction{.85}
+\emergencystretch 2em
+\newcommand\secref[1]{(see section~\ref{#1})}
+\usepackage{hyperref}
+\def\ghissue#1{%
+ \texttt{\##1}\footnote{%
+ \url{https://github.com/daviddavo/fistrum/issues/#1}}}
+\begin{document}
+ \DocInput{fistrum.dtx}
+\end{document}
+%</driver>
+%<*package>
+\NeedsTeXFormat{LaTeX2e}
+\RequirePackage{l3keys2e}
+\@ifundefined{NewDocumentCommand}
+ {\RequirePackage{xparse}}{}
+\ProvidesExplPackage {fistrum} {\fistrumdate} {\fistrumversion}
+ {150 paragraphs of Lorem Fistrum dummy text}
+%</package>
+% \fi
+%
+% \title{\pkg{fistrum}}
+% \subtitle{Access to 150 paragraphs of Lorem Fistrum very dummy
+% text\thanks{Version: \fistrumversion}^^A
+% \thanks{Basado en \href{https://chiquitoipsum.com}{Chiquito Ipsum} de
+% Isabel Nieto, Carlos A. Hernández y Gauss Multimedia}.
+% }
+% \author{David Davó\thanks{david@ddavo.me}}
+% \date{\DTMdate{2023-02-28}}
+% \RecordChanges
+% \changes{v0.1}{Feb 2023}{First release}
+% \maketitle{\pkg{fistrum} es un paquete de \LaTeX{} derivado de \pkg{lipsum} que produce texto de ejemplo
+% para usarlo en documentos y ejemplos. Los párrafos se han tomado con permiso de
+% \url{https://www.chiquitoipsum.com/}.
+%
+% Por favor, si encuentras un bug, alguna errata o tienes alguna sugerencia
+% abre un \textit{issue} en
+% \url{https://github.com/daviddavo/fistrum}.}
+%
+% \begin{documentation}
+%
+% \section{Al ataquerl}
+%
+% \textbf{Nota: La documentación es una copia de la de lipsum, pueden haber quedado erratas}
+%
+% To load the package, write
+% \begin{verbatim}
+% \usepackage{fistrum}
+% \end{verbatim}
+% in the preamble of your document. Probably the most important macro
+% provided by this package is \DescribeMacro{\fistrum}\cs{fistrum}, which
+% typesets the \emph{Lorem fistrum} paragraphs. The first optional
+% argument allows to specify the range of the paragraphs. For example,
+% \verb|\fistrum[4-57]| typesets the paragraphs 4 to 57 and accordingly,
+% \verb|\fistrum[23]| typesets the 23\textsuperscript{rd} paragraph.
+% Using \cs{fistrum} without its optional argument typesets the
+% paragraphs 1--7 of \fist
+%
+% As of version 2.0, \cs{fistrum} has a second optional argument which allows
+% selecting a range of sentences from the paragraphs. To get the sentences
+% four to eight from paragraphs three to nine, use |\fistrum[3-9][4-8]|.
+% The sentences are counted from the first sentence of the first selected
+% paragraph. In the previous example, sentence number~1 is the first
+% sentence of paragraph number~3.
+%
+% \section{Usage}
+%
+% \pkg{fistrum} was intended to quickly provide a way to fill a page or two to
+% analyze the page
+% layout\footnote{\url{https://groups.google.com/d/topic/de.comp.text.tex/oPeLOjkrLfk}}.
+% While it has grown in the meanwhile and now provides some more advanced
+% features, it still is only intended to quickly provide text. If you want more
+% features, look at the \pkg{blindtext}-package.
+%
+% \subsection{Package Options}
+% \label{sec:pkg-opt}
+%
+% \pkg{fistrum} outputs a range of paragraphs taken from the \fist\ dummy
+% text. The package options control mainly the behaviour of the
+% \cs{fistrum} and \cs{unpackfistrum} commands, and can be set at
+% load-time with \cs{usepackage}|[|\meta{option}|]{fistrum}|, or later in
+% the document by using \cs{setfistrum}|{|\meta{option}|}|.
+%
+% \begingroup
+% \RenewDocumentCommand \item { r[] e= d() }
+% {\par\medskip\noindent\llap
+% {\smash{\begin{tabular}{@{}l@{}}\toprule
+% \opt{#1}\\\bottomrule\end{tabular}}~~}%^^A
+% \IfValueT{#2}{=~~\!\meta{#2}\hfill
+% \IfValueT{#3}{\quad(default: \texttt{#3})}\null
+% \newline}\ignorespaces}
+%
+% \item[nopar]={boolean}(false)
+% Changes the initial default separator between each paragraph of
+% \cs{fistrum} from \cs{par} to \cs{space}, and the other way around
+% for \cs{fistrum*}.
+% \item[text]={name}(fistrum-es)
+% Selects the dummy text \meta{name} that is used by \cs{fistrum} and
+% \cs{unpackfistrum} \secref{sec:other-texts}.
+% \item[language]={lang}(latin)
+% Sets the language to be used by \cs{fistrum} to typeset the currently
+% active dummy text \secref{sec:hyphenation}. Changing the dummy text
+% with the \opt{text} option will also change the current
+% \opt{language}.
+% \item[auto-lang]={boolean}(true)
+% Turns on/off automatic language switching. This changed since
+% version 2.3, in which this option (didn't exist thus) was |false| by
+% default. See section~\ref{sec:hyphenation} for more details.
+% \item[default-range]={p_i\texttt{-}p_f}(1-7)
+% Sets the default range of paragraphs produced by \cs{fistrum} when no
+% optional argument is provided. The value to \opt{default-range}
+% obeys the \meta{range} syntax described in
+% section~\ref{sec:range-syntax}. If no value is given to
+% \opt{default-range} (that is, \cs{setfistrum}|{default-range}|), then
+% the default is reset to |1-7|.
+%
+% \endgroup
+%
+% \medskip
+%
+% Besides these options, there are still ones that can be passed to the
+% package to influence the paragraph and sentence separators and other
+% such things. These options are detailed in
+% section~\ref{sec:separators}.
+%
+%^^A Besides the listed options, there are still options that can be
+%^^A passed to the package to influence the paragraph and sentence
+%^^A separators and other things like that. The options for paragraphs
+%^^A are:
+%^^A \AddToHookNext{env/multicols/before}
+%^^A {\setlength{\multicolsep}{0.5\multicolsep}}
+%^^A \begin{multicols}{2}
+%^^A \ttfamily \setlist{nosep}
+%^^A \begin{itemize}
+%^^A \item par-before
+%^^A \item par-begin
+%^^A \item par-sep
+%^^A \item par-end
+%^^A \item par-after
+%^^A \end{itemize}
+%^^A \begin{itemize}
+%^^A \item par-before*
+%^^A \item par-begin*
+%^^A \item par-sep*
+%^^A \item par-end*
+%^^A \item par-after*
+%^^A \end{itemize}
+%^^A \end{multicols}
+%^^A and for sentences, the same group with |sentence| instead of |par|
+%^^A in their name. These options are detailed in
+%^^A section~\ref{sec:separators}.
+%
+% \subsection{User Commands}
+%
+% \begin{function}{\fistrum}
+% \begin{syntax}
+% \cs{fistrum}\meta{*}\oarg{par range}\oarg{sentence range}
+% \end{syntax}
+% \cs{fistrum} outputs the \meta{par range} from the
+% currently active dummy text. If \meta{par range} is not given
+% or is empty, the \opt{default-range} (initially |1-7|) is output.
+% ^^A
+% If a \meta{sentence range} is given, the selected paragraphs are
+% split into sentences, numbered starting from~1, and the specified
+% range of sentences is taken out from those paragraphs.
+% ^^A
+% If the \meta{*} version is used, a different set of separators is
+% inserted around the paragraphs or sentences.
+%
+% \cs{fistrum} changes the active language to that of the dummy text
+% for typesetting, so the proper hyphenation patterns are used.
+% See section~\ref{sec:hyphenation}.
+% ^^A
+% Section~\ref{sec:range-syntax} explains the syntax of ranges, and
+% section~\ref{sec:separators} explains the separators added around
+% the pieces of text.
+% \end{function}
+%
+% \begin{function}{\unpackfistrum,\fistrumexp}
+% \begin{syntax}
+% \cs{unpackfistrum}\meta{*}\oarg{par range}\oarg{sentence range}
+% \ldots
+% \cs{fistrumexp}
+% \end{syntax}
+% \cs{unpackfistrum} selects the paragraphs and/or sentences exactly as
+% described for \cs{fistrum}, but instead of outputting them, it saves
+% the selected text in the \cs{fistrumexp} macro. Additionally,
+% \cs{unpackfistrum} \ldots\cs{fistrumexp} is not completely equivalent
+% to \cs{fistrum} because it doesn't change languages as \cs{fistrum}
+% does.
+% \end{function}
+%
+% \begin{function}{\setfistrum}
+% \begin{syntax}
+% \cs{setfistrum}\Arg{key-val list}
+% \end{syntax}
+% Applies the \meta{key-val list} of options to the package. The
+% options are described in section~\ref{sec:pkg-opt} and in
+% section~\ref{sec:separators}.
+% \end{function}
+%
+% \subsection{Other commands}
+%
+% These commands exist for necessity or backwards comatibility, and
+% should normally not be needed in user documents.
+%
+% \begin{function}{\SetFistrumText}
+% \begin{syntax}
+% \cs{SetFistrumDefault}\Arg{name}
+% \end{syntax}
+% Loads the dummy text \meta{name} \secref{sec:other-texts}.
+% This command does the same as option \opt{text}, but it is
+% kept for backwards compatibility.
+% \end{function}
+%
+% \begin{function}{\SetFistrumDefault}
+% \begin{syntax}
+% \cs{SetFistrumDefault}\Arg{range}
+% \end{syntax}
+% Sets the default range for \cs{fistrum} and \cs{unpackfistrum}.
+% This command does the same as option \opt{default-range}, but it is
+% kept for backwards compatibility.
+% \end{function}
+%
+% \section{General remarks on behaviour}
+%
+% Here are some topics that are general considerations about the
+% behaviour of \pkg{fistrum} and its commands. These are technicalities
+% that most end users don't care too much about, unless you are trying
+% to do something beyond the usual ``print me some dummy text''.
+%
+% \subsection{Syntax of paragraph and sentence ranges}
+% \label{sec:range-syntax}
+%
+% A \meta{range} argument can either be blank, a single integer, or a
+% proper integer range. If the \meta{range} argument is blank, the
+% commands behave as if the argument was not given at all. For example,
+% |\fistrum[]| behaves exaclty like |\fistrum| and outputs the default
+% paragraph range. Note that |\fistrum[][2-5]| does \textbf{not} behave
+% as |\fistrum[2-5]|, but behaves as |\fistrum[1-7][2-5]| (assuming
+% |default=range=1-7|), because the default value is then taken for the
+% first argument. If the \meta{range} argument is an integer, then only
+% a single paragraph/sentence is selected.
+%
+% If the argument contains a |-| (\textsc{ascii}~45), it is interpreted
+% as a \emph{proper} range \meta{n_i}|-|\meta{n_f}. In a proper range,
+% if \meta{n_i} is blank, it is taken to be the start of the possible
+% range, and in the same way, if \meta{n_f} is empty it is taken to be
+% the end of the possible range. That is, |\fistrum[-9]| is the same as
+% |\fistrum[1-9]|, and |\fistrum[5-]| is the same (assuming the standard
+% 150-paragraph dummy text) as |\fistrum[5-150]|, and similarly,
+% |\fistrum[-]| is the same as |\fistrum[1-150]|.
+%
+% Only one |-| is allowed in a range, so if more than one |-| is given,
+% an error is raised and no paragraphs/sentences are output. No
+% paragraphs or sentences will be output also in case one of the ranges
+% is reversed, so |\fistrum[2-1]| returns no paragraphs, as does
+% |\fistrum[][2-1]| output no sentences, for example. Note that
+% ``returning no paragraphs/sentences'' is not ``the output is empty'':
+% that is mostly true, except that the |-before| and |-after| separators
+% are still output \secref{sec:separators}.
+%
+% Finally, if a range spans more paragraphs or sentences than what the
+% dummy text actually provides, the range is truncated so that it fits
+% the available text. If the range in the argument does not intersect
+% with the range provided by the dummy text, no paragraphs or sentences
+% are output.
+%
+% \subsection{Hyphenation patterns}
+% \label{sec:hyphenation}
+%
+% Since version~2.4, the command \cs{fistrum} automatically changes the
+% hyphenation patterns when typesetting a dummy text, so that
+% line-breaking looks better \secref{sec:foreword2.4}. This feature is
+% on by default, so if you need the old behaviour you have to explicitly
+% disable automatic language switching with
+% |\setfistrum{auto-lang=false}|.
+%
+% The language is defined individually for each dummy text
+% \secref{sec:other-texts}, but you may change it for the current dummy
+% text by using |\setfistrum{language=|\meta{lang}|}|. If you load
+% another dummy text (for example with the \opt{text} option), then the
+% option \opt{language} is also changed according to the dummy text
+% loaded \secref{sec:other-texts}.
+%
+% \subsection{Paragraph and sentence separators}
+% \label{sec:separators}
+%
+% As may be clear by now, \pkg{fistrum} has two modes of operation:
+% sentence output, and paragraph output, selected by providing or not
+% providing the second optional argument to \cs{fistrum}. In each mode,
+% the dummy text is separated into chunks (paragraphs or sentences),
+% which are counted, and then output accordingly.
+%
+% When \cs{fistrum} (or \cs{unpackfistrum}) is used with a single (or no)
+% optional argument, then a range of paragraphs is output, along with
+% some ``separators'' (in the lack of a better name) between paragraphs,
+% around each paragraph, and before and after the whole output.
+% A schematic (very colorful, because I couldn't find a better visual)
+% representation of the output is:
+%
+% \begin{function}{
+% par-before,
+% par-begin,
+% par-sep,
+% par-end,
+% par-after,
+% sentence-before,
+% sentence-begin,
+% sentence-sep,
+% sentence-end,
+% sentence-after,
+% }
+% \noindent
+% \begin{tikzpicture}[x=0.703cm,
+% item/.style={
+% draw,
+% rounded corners=2mm,
+% minimum width=2.2cm,
+% execute at begin node=\strut,
+% rotate=54,
+% font=\footnotesize,
+% },
+% ]
+% \def\sep#1{\texttt{par-\textbf{#1}}\null}
+% \node [item,fill=red!40 ] at (0 ,0) {\sep{before}};
+% \node [item,fill=red!20 ] at (1 ,0) {\sep{begin }};
+% \node [item,fill=red!20 ] at (2 ,0) {\meta{paragraph}};
+% \node [item,fill=red!20 ] at (3 ,0) {\sep{end \ }};
+% \node [item,shading=axis,left color=red!30,right color=green!30,
+% shading angle=54] at (4 ,0) {\sep{sep \ }};
+% \node [item,fill=green!20] at (5 ,0) {\sep{begin }};
+% \node [item,fill=green!20] at (6 ,0) {\meta{paragraph}};
+% \node [item,fill=green!20] at (7 ,0) {\sep{end \ }};
+% \node [item,shading=axis,left color=green!30,right color=blue!30,
+% shading angle=54] at (8 ,0) {\sep{sep \ }};
+% \node [item,fill=blue!20 ] at (9 ,0) {\sep{begin }};
+% \node [item,fill=blue!20 ] at (10,0) {\meta{paragraph}};
+% \node [item,fill=blue!20 ] at (11,0) {\sep{end \ }};
+% \node [item,fill=blue!40 ] at (12,0) {\sep{after\ }};
+% \end{tikzpicture}
+%
+% When \cs{fistrum} is called, the first thing it outputs is the
+% \opt{par-before} tokens. These tokens are output unconditionally,
+% regardless of how many (if any) paragraph is output.
+%
+% Then, before each paragraph in the range, \cs{fistrum} outputs the
+% \opt{par-begin} tokens, and then the actual text of the
+% \meta{paragraph}, and then the \opt{par-end} tokens. These tokens are
+% output conditionally, if the paragraph text is output. If more than
+% one paragraph is output, then the \opt{par-sep} tokens are inserted
+% between the \opt{par-end} of one paragraph and the \opt{par-begin} of
+% the paragraph that follows.
+%
+% \end{function}
+%
+% Finally, at the end, the \opt{par-after} tokens are inserted
+% unconditionally at the end, same as for \opt{par-before}.
+%
+% As mentioned before, in case of an error parsing the range, the output
+% will be no paragraphs, but the \opt{par-before} and \opt{par-after}
+% tokens are still output.
+%
+% The explanation above is equally valid for the starred variants. If
+% \cs{fistrum}|*| is used, the \opt{par-before*} tokens are
+% inserted, and so on. It is also true for sentences (starred or
+% otherwise), replacing |par| in the option names by |sentence|, so when
+% you use, for example, |\fistrum[][1-9]|, the \opt{sentence-before}
+% tokens will be unconditionally inserted, and so on.
+%
+% Note that, when \cs{fistrum} is used in sentence-mode (for example,
+% with |\fistrum[1-3][1-9]|), only the |sentence-...| tokens are inserted
+% in the output, regardless of how many paragraphs those sentences were
+% collected from. In the same way, if paragraph-mode is being used, only
+% |par-...| tokens are inserted.
+%
+% \subsubsection{Deprecated command-based syntax}
+%
+% Older versions of \pkg{fistrum} (from 2.0 to 2.3) provided~10 CamelCase
+% commands for changing the separators, but the syntax was rather
+% cumbersome to use, so the keyval syntax presented thus far was
+% introduced in the hopes of making things a bit easier. The old
+% commands will still exist for some time in the package, but with a
+% deprecation warning. Changing to the keyval syntax is advised, so
+% here is a correspondence table between the old and new syntaxes:
+%
+% \begin{center}
+% \ttfamily \makeatletter
+% \definecolor{a}{HTML}{E0211A}\colorlet{a}{a!60!black}
+% \definecolor{b}{HTML}{5970D5}\colorlet{b}{b!60!black}
+% \protected@edef\x#1#2{\string\SetFistrum
+% {\color{a}#1}List{\color{b}#2}}%
+% \def\y#1#2{{\color{a}#1}-{\color{b}#2}}
+% \begin{tabular}{@{}ll@{}}
+% \toprule
+% \textrm{Old command} & \textrm{New key name} \\
+% \midrule
+% \x{Par}{Start} & \y{par}{before} \\
+% \x{Par}{ItemStart} & \y{par}{begin} \\
+% \x{Par}{ItemSeparator} & \y{par}{sep} \\
+% \x{Par}{ItemEnd} & \y{par}{end} \\
+% \x{Par}{End} & \y{par}{after} \\
+% \x{Sentence}{Start} & \y{sentence}{before} \\
+% \x{Sentence}{ItemStart} & \y{sentence}{begin} \\
+% \x{Sentence}{ItemSeparator} & \y{sentence}{sep} \\
+% \x{Sentence}{ItemEnd} & \y{sentence}{end} \\
+% \x{Sentence}{End} & \y{sentence}{after} \\
+% \bottomrule
+% \end{tabular}
+% \end{center}
+%
+% Additionally, the command-based interface provided shortcuts
+% |\SetFistrum|\meta{Thing}|List|(|Item|)|Surrounders|, which are
+% equivalent to just using the commands
+% |\SetFistrum|\meta{Thing}|List|(|Item|)|Start| then |\...End|. These
+% don't provide any functionality, other than requiring a little less
+% typing, so no key-val alternative was implemented.
+% The |\...|\meta{Thing}|...Surrounders| commands should be replaced by
+% \meta{thing}|-before| and \meta{thing}|-after|, and the
+% |\...|\meta{Thing}|...ItemSurrounders| commands should be replaced by
+% \meta{thing}|-begin| and \meta{thing}|-end|, as in the correspondence
+% table below:
+%
+% \begin{center}
+% \ttfamily \makeatletter
+% \definecolor{a}{HTML}{E0211A}\colorlet{a}{a!60!black}
+% \definecolor{b}{HTML}{5970D5}\colorlet{b}{b!60!black}
+% \protected@edef\x#1#2{\string\SetFistrum
+% {\color{a}#1}List{\color{b}#2}Surrounders%^^A
+% \kern .5\tabcolsep \xleaders\hbox{\vrule
+% width 2pt height \dimexpr .5ex+.4pt\relax depth -.5ex
+% \kern 2pt}%
+% \hskip 0pt plus 1filll \kern -.5\tabcolsep
+% \raise.5ex\rlap{\kern.5\tabcolsep
+% \vrule width \tabcolsep height 0.4pt depth 0pt
+% \kern-0.5\tabcolsep
+% \smash{\vrule depth \normalbaselineskip width 0.4pt
+% \raise-\normalbaselineskip
+% \hbox{\vrule width .5\tabcolsep height 0.4pt depth 0pt}}}}%
+% \def\y#1#2{{\color{a}#1}-{\color{b}#2}}
+% \begin{tabular}{@{}ll@{}}
+% \toprule
+% \textrm{Old command} & \textrm{New key names} \\
+% \midrule
+% \x{Par}{} & \y{par}{}before \\
+% & \y{par}{}after \\
+% \x{Par}{Item} & \y{par}{begin} \\
+% & \y{par}{end} \\
+% \x{Sentence}{} & \y{sentence}{}before \\
+% & \y{sentence}{}after \\
+% \x{Sentence}{Item} & \y{sentence}{begin} \\
+% & \y{sentence}{end} \\
+% \bottomrule
+% \end{tabular}
+% \end{center}
+%
+% \section{Loading and defining dummy texts}
+% \label{sec:other-texts}
+%
+% Starting with \pkg{fistrum} v2.2, a simple interface is provided to
+% define and load other texts for the output of \cs{fistrum} and friends.
+% This interface can, for example, be used to implement dummy texts in
+% different languages without re-coding the logic implemented by
+% \pkg{fistrum}.
+%
+% \begin{function}{\NewFistrumPar}
+% \begin{syntax}
+% \cs{NewFistrumPar}\Arg{paragraph}
+% \end{syntax}
+% In order to provide a new text that will be used by \pkg{fistrum},
+% define the text by using a set of \cs{NewFistrumPar}\Arg{paragraph}
+% commands in a file with the ending |.ftd.tex| (|ftd| means
+% \emph{fistrum text definition}\footnotemark{}) to a location where
+% your \TeX{} system will find it. The \meta{paragraph}-argument is a
+% single paragraph of the new text. Thus, the first occurence of
+% \cs{NewFistrumPar} defines the first paragraph, the second occurence
+% the second paragraph and so on.
+% \end{function}
+% \footnotetext{To avoid name clashes with files using general languages
+% as names, I chose to introduce the |.ftd.tex| file ending. I did not
+% find a file with this ending in my |texmf|-tree, so I guess it is
+% safe.}
+%
+% \begin{function}{\SetFistrumLanguage}
+% \begin{syntax}
+% \cs{SetFistrumLanguage}\Arg{lang}
+% \end{syntax}
+% Additionally, tell \pkg{fistrum} the language of the dummy text using
+% \cs{SetFistrumLanguage}\Arg{lang} somewhere in the |.ftd.tex| file.
+% \end{function}
+%
+% \medskip
+%
+% To specify the new text as output for \cs{fistrum} and friends, use
+% \cs{setfistrum}|{|\opt{text}|=|\meta{name}|}|, where \meta{name} is the
+% name of the file without the ending |.ftd.tex|, as given in the table
+% below. When a new dummy text is loaded, the previous one is cleared,
+% and the language is changed as well, according to the table.
+%
+% \begin{table}[ht]
+% \begin{wide}
+% \begin{tabularx}{\textwidth}{lllX}
+% \toprule
+% File (\texttt{.ftd.tex}) & Language & Source & Description \\
+% \midrule
+% \texttt{fistrum-la} & Latin
+% & Chiquito
+% & Contiene el texto \emph{Lorem fistrum} tras seleccionar la opción
+% latín en \url{https://www.chiquitoipsum.com/}. \\
+% \texttt{fistrum-es} & Spanish
+% & Chiquito
+% & Contiene el texto \emph{Lorem fistrum} tras seleccionar la opción
+% fistrum en \url{https://www.chiquitoipsum.com/}. \\
+% \bottomrule
+% \end{tabularx}
+% \end{wide}
+% \end{table}
+%
+% \subsection{Guidelines on providing new dummy texts}
+%
+% \cs{SetFistrumText} more or less just uses an \cs{input} or, to be more
+% precise, the \LaTeX3-variant \cs{file_input:n}, to load the |.ftd.tex|
+% file. This means, that the file is not necessarily loaded in the
+% preamble of the document and thus the contents of the file underlie
+% the respective restrictions.
+%
+% Should you want a new dummy text, create an issue in the GitHub
+% repository\footnote{\url{https://github.com/daviddavo/fistrum}}
+% with the source for the dummy text.
+%
+% Should you prefer to distribute the dummy text as a separate package,
+% make sure that the text follows the layout of \pkg{fistrum}'s dummy
+% texts, so that everything works correctly. The dummy text definition
+% file should contain a line with \cs{SetFistrumLanguage}, and then as
+% many \cs{NewFistrumPar} entries as there are paragraphs in the dummy
+% text. Make sure that the file has the |.ftd.tex| extension, and
+% everything should work smoothly.
+%
+% \end{documentation}
+%
+% \clearpage
+% \newgeometry{left=5cm,right=2cm}
+%
+% \begin{implementation}
+%
+% \section{\pkg{fistrum} Implementation}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=fistrum>
+% \end{macrocode}
+%
+% \subsection{Variables}
+%
+% \begin{variable}{\g_@@_par_int}
+% Stores the number of paragraphs in the current text.
+% \begin{macrocode}
+\int_new:N \g_@@_par_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_language_tl}
+% Stores the language of the dummy text for hyphenation patterns.
+% \begin{macrocode}
+\tl_new:N \g_@@_language_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}[int]{\g_fistrum_default_range_tl}
+% The default range for fistrum paragraphs.
+% \begin{macrocode}
+\tl_new:N \g_fistrum_default_range_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_output_tl}
+% This variables is used to store the token list containing the
+% selected output.
+% \begin{macrocode}
+\tl_new:N \l_@@_output_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_text_str}
+% Holds the current text loaded for the output of \cs{fistrum} and
+% friends. Used to avoid loading the same text definition if it is
+% already used.
+% \begin{macrocode}
+\str_new:N \g_@@_text_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_sep_set_str}
+% Holds the name of the active separator token set. By default it is
+% empty to use the default separator set (empty).
+% \begin{macrocode}
+\str_new:N \l_@@_sep_set_str
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_autolang_bool}
+% Boolean whether to change hyphenation patterns according to the
+% dummy text language.
+% \begin{macrocode}
+\bool_new:N \l_@@_autolang_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\q_@@_mark,\s_@@}
+% Quark and scan mark used throughout the package.
+% \begin{macrocode}
+\quark_new:N \q_@@_mark
+\scan_new:N \s_@@
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_tmpa_str,\l_@@_a_int,\l_@@_b_int}
+% Scratch variables.
+% \begin{macrocode}
+\str_new:N \l_@@_tmpa_str
+\int_new:N \l_@@_a_int
+\int_new:N \l_@@_b_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_tmp:w}
+% Scratch macro.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_tmp:w ?
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_<thing>_<place>_<version>_tl}
+% \csname @gobble\endcsname{
+% \l_@@_par_end_nostar_tl,
+% \l_@@_par_end_star_tl,
+% \l_@@_par_end__tl,
+% \l_@@_par_itemend_nostar_tl,
+% \l_@@_par_itemend_star_tl,
+% \l_@@_par_itemend__tl,
+% \l_@@_par_itemseparator_nostar_tl,
+% \l_@@_par_itemseparator_star_tl,
+% \l_@@_par_itemseparator__tl,
+% \l_@@_par_itemstart_nostar_tl,
+% \l_@@_par_itemstart_star_tl,
+% \l_@@_par_itemstart__tl,
+% \l_@@_par_start_nostar_tl,
+% \l_@@_par_start_star_tl,
+% \l_@@_par_start__tl,
+% \l_@@_sentence_end_nostar_tl,
+% \l_@@_sentence_end_star_tl,
+% \l_@@_sentence_end__tl,
+% \l_@@_sentence_itemend_nostar_tl,
+% \l_@@_sentence_itemend_star_tl,
+% \l_@@_sentence_itemend__tl,
+% \l_@@_sentence_itemseparator_nostar_tl,
+% \l_@@_sentence_itemseparator_star_tl,
+% \l_@@_sentence_itemseparator__tl,
+% \l_@@_sentence_itemstart_nostar_tl,
+% \l_@@_sentence_itemstart_star_tl,
+% \l_@@_sentence_itemstart__tl,
+% \l_@@_sentence_start_nostar_tl,
+% \l_@@_sentence_start_star_tl,
+% \l_@@_sentence_start__tl,
+% }
+% These variables store the separators and delimiters added around the
+% paragraphs and sentences, in the starred or nonstarred variants, as
+% well as the generic version for runtime usage.
+% \begin{macrocode}
+\clist_map_inline:nn { start, itemstart, itemseparator, itemend, end }
+ {
+ \clist_map_inline:nn { par, sentence }
+ {
+ \clist_map_inline:nn { { }, star, nostar }
+ { \tl_new:c { l_@@_##1_#1_####1_tl } }
+ }
+ \tl_new:c { l_@@_par_#1_parsepar_tl }
+ }
+\tl_set:Nn \l_@@_par_itemseparator_parsepar_tl { ~ }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Developer interface}
+%
+% \begin{macro}{\@@_parse_par_range:nNN,\@@_parse_par_range:eNN}
+% \begin{macro}{\@@_parse_sentence_range:nNN,\@@_parse_sentence_range:eNN}
+% \begin{macro}{\@@_parse_range_arg:nNNn,\@@_parse_range_arg:wnNNn}
+% \begin{macro}{\@@_int_set:Nnn}
+% Parses an argument that may be a single integer or an integer range
+% separated by a |-|, and stores them into the integer registers |#2|
+% and |#3|. If a number is blank, zero is used. If only a single
+% number is given, |#3| is set equal to |#2|.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_parse_par_range:nNN #1 #2 #3
+ {
+ \tl_if_blank:nTF {#1}
+ { \exp_args:NV \@@_parse_range_arg:nNNn \g_fistrum_default_range_tl }
+ { \@@_parse_range_arg:nNNn {#1} }
+ #2 #3 { \g_@@_par_int }
+ }
+\cs_new_protected:Npn \@@_parse_sentence_range:nNN #1 #2 #3
+ { \@@_parse_range_arg:nNNn {#1} #2 #3 { \c_max_int } }
+\cs_new_protected:Npn \@@_parse_range_arg:nNNn #1
+ {
+ \exp_last_unbraced:No \@@_parse_range_arg:wnNNn
+ \tl_to_str:n { #1 - - } \s_@@ {#1}
+ }
+\cs_new_protected:Npn \@@_parse_range_arg:wnNNn
+ #1 - #2 - #3 \s_@@ #4 #5#6 #7
+ {
+ \str_if_eq:nnTF {#3} { - }
+ {
+ \@@_int_set:Nnn #5 {#1} { 1 }
+ \@@_int_set:Nnn #6 {#2} {#7}
+ }
+ {
+ \tl_if_empty:nTF {#3}
+ {
+ \@@_int_set:Nnn #5 {#1} { \ERROR }
+ \int_set_eq:NN #6 #5
+ }
+ {
+ \msg_error:nnn { fistrum } { invalid-range } {#4}
+ \@@_parse_range_arg:nNNn { 2 - 1 } #5 #6 {#7}
+ }
+ }
+ }
+\cs_new_protected:Npn \@@_int_set:Nnn #1 #2 #3
+ { \int_set:Nn #1 { \tl_if_blank:nT {#2} {#3} #2 } }
+\cs_generate_variant:Nn \@@_parse_par_range:nNN { e }
+\cs_generate_variant:Nn \@@_parse_sentence_range:nNN { e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_sep_item:nn}
+% A shorthand to leave an (\cs{undexpanded}) token list.
+% \begin{macrocode}
+\cs_new:Npn \@@_sep_item:nn #1 #2
+ { \exp_not:v { l_@@_#1_#2_ \l_@@_sep_set_str _tl } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\fistrum_get_range:nn}
+% \begin{macro}{
+% \@@_build_list:nn,
+% \@@_build_list_aux:n,
+% \@@_get_paragraph:ww,
+% \@@_get_paragraph_end:w,
+% }
+% Expands to the paragraphs between \meta{number_1} and
+% \meta{number_2} with the proper delimiters added. Text is returned
+% in \cs{exp_not:n}, so this macro can be safely used in an \cs{edef}.
+% \begin{macrocode}
+\cs_new:Npn \fistrum_get_range:nn #1 #2
+ {
+ \@@_sep_item:nn { par } { start }
+ \use:e
+ {
+ \exp_not:N \@@_get_paragraph:ww
+ \@@_build_list:nn {#1} {#2}
+ \exp_not:N \q_@@_mark ;
+ \exp_not:N \q_@@_mark ; \s_@@
+ }
+ \@@_sep_item:nn { par } { end }
+ }
+\cs_new:Npn \@@_build_list:nn #1 #2
+ {
+ \int_step_function:nnN
+ { \int_max:nn {#1} { 1 } }
+ { \int_min:nn {#2} { \g_@@_par_int } }
+ \@@_build_list_aux:n
+ }
+\cs_new:Npn \@@_build_list_aux:n #1 { #1 ; }
+\cs_new:Npn \@@_get_paragraph:ww #1 ; #2 ;
+ {
+ \if_meaning:w \q_@@_mark #2
+ \if_meaning:w \q_@@_mark #1
+ \@@_get_paragraph_end:w
+ \else:
+ \fistrum_get_paragraph:n {#1}
+ \fi:
+ \else:
+ \fistrum_get_paragraph:n {#1}
+ \@@_sep_item:nn { par } { itemseparator }
+ \fi:
+ \@@_get_paragraph:ww #2 ;
+ }
+\cs_new:Npn \@@_get_paragraph_end:w #1 \s_@@ { \fi: \fi: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\fistrum_get_paragraph:n}
+% Expands to the paragraph \meta{number} with the proper delimiters
+% added. Text is returned in \cs{exp_not:n}, so this macro can be
+% safely used in an \cs{edef}.
+% \begin{macrocode}
+\cs_new:Npn \fistrum_get_paragraph:n #1
+ {
+ \@@_sep_item:nn { par } { itemstart }
+ \@@_unexpanded_par:n {#1}
+ \@@_sep_item:nn { par } { itemend }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_unexpanded_par:n}
+% Expands to the paragraph \meta{number} wrapped in \cs{exp_not:n}.
+% If \meta{number} is out of range, it expands to nothing.
+% \begin{macrocode}
+\cs_new:Npn \@@_unexpanded_par:n #1
+ {
+ \bool_lazy_and:nnT
+ { \int_compare_p:nNn { 0 } < {#1} }
+ { \int_compare_p:nNn {#1} < { \g_@@_par_int + 1 } }
+ { \exp_not:v { g_@@_par_#1_tl } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\fistrum_get_sentences:nnn,\fistrum_get_sentences:nnV}
+% \begin{macro}{\@@_get_sentences:nnnw,\@@_get_sentences_end:w}
+% Expands to the sentences numbered between \meta{number_1} and
+% \meta{number_2}, inclusive, contained in the \meta{text}, and adding
+% the proper separators.
+% \begin{macrocode}
+\cs_new:Npn \fistrum_get_sentences:nnn #1 #2 #3
+ {
+ \@@_sep_item:nn { sentence } { start }
+ \exp_args:Ne \use_ii_i:nn { { \int_max:nn {#1} { 1 } } }
+ { \@@_get_sentences:nnnw { 1 } } {#2}
+ #3 ~ \q_@@_mark .~ \s_@@
+ \@@_sep_item:nn { sentence } { end }
+ }
+\cs_new:Npn \@@_get_sentences:nnnw #1 #2 #3 #4 .~
+ {
+ \int_compare:nNnT {#1} > {#3} { \@@_get_sentences_end:w }
+ \use:nn { \if_meaning:w \q_@@_mark } #4
+ \exp_after:wN \@@_get_sentences_end:w
+ \else:
+ \int_compare:nNnF {#1} < {#2}
+ {
+ \int_compare:nNnF {#1} = {#2}
+ { \@@_sep_item:nn { sentence } { itemseparator } }
+ \@@_sep_item:nn { sentence } { itemstart }
+ \exp_not:n { #4 . }
+ \@@_sep_item:nn { sentence } { itemend }
+ }
+ \fi:
+ \exp_args:Nf \@@_get_sentences:nnnw { \int_eval:n { #1 + 1 } }
+ {#2} {#3}
+ }
+\cs_new:Npn \@@_get_sentences_end:w #1 \s_@@ { }
+\cs_generate_variant:Nn \fistrum_get_sentences:nnn { nnV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{User- and developer-level commands}
+%
+% \begin{macro}[int]{\fistrumPar}
+% Macro to typeset a single paragraph of \fist\ Was not officially
+% available in version prior to 2.0.
+% \begin{arguments}
+% \item Number of the paragraph to typeset.
+% \end{arguments}
+% Implemented as follows:
+% \begin{macrocode}
+\NewDocumentCommand \fistrumPar { m }
+ {
+ \@@_deprecated:n { FistrumPar }
+ \@@_unexpanded_par:n {#1} \par
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Tokens surrounding the \fist\ content}
+%
+% \begin{macro}{\@@_element_set:nnn}
+% A general macro for setting starred/non-starred versions of several
+% elements used between chunks of dummy text. Arguments are:
+% \begin{arguments}
+% \item Element name;
+% \item Boolean true or false if the |*| variant was used;
+% \item Value to set the element to.
+% \end{arguments}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_element_set:nnn #1 #2 #3
+ { \tl_set:cn { l_@@_ #1 _ \IfBooleanF {#2} { no } star _tl } {#3} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_deprecated:n}
+% Warns about deprecated commands and destroys itself.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_deprecated:n #1
+ {
+ \msg_warning:nnn { fistrum } { cmd-deprecated } {#1}
+ \cs_gset_eq:NN \@@_deprecated:n \use_none:n
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{
+% \SetFistrumParListStart,
+% \SetFistrumParListEnd,
+% \SetFistrumParListSurrounders,
+% \SetFistrumParListItemSeparator,
+% \SetFistrumParListItemStart,
+% \SetFistrumParListItemEnd,
+% \SetFistrumParListItemSurrounders,
+% \SetFistrumSentenceListStart,
+% \SetFistrumSentenceListEnd,
+% \SetFistrumSentenceListSurrounders,
+% \SetFistrumSentenceListItemSeparator,
+% \SetFistrumSentenceListItemStart,
+% \SetFistrumSentenceListItemEnd,
+% \SetFistrumSentenceListItemSurrounders,
+% }
+% A dirty loop to quickly define the old command-based user-interface.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1 #2 #3 #4
+ {
+ \str_set:Nx \l_@@_tmpa_str
+ { #2 \tl_if_empty:nTF {#4} {#3} { start } }
+ \use:e
+ {
+ \NewDocumentCommand \exp_not:c { SetFistrum #1 List #2 #3 }
+ { s +m \tl_if_empty:nF {#4} { +m } }
+ {
+ \@@_deprecated:n { SetFistrum #1 List #2 #3 }
+ \@@_element_set:nnn
+ { \exp_args:Ne \str_lowercase:n { #1_\l_@@_tmpa_str } }
+ {##1} {##2}
+ \tl_if_empty:nT {#4} { \use_none:nnnn }
+ \@@_element_set:nnn { \str_lowercase:n { #1_#2 #4 } }
+ {##1} {##3}
+ }
+ }
+ }
+\clist_map_inline:nn { Par, Sentence }
+ {
+ \clist_map_inline:nn
+ { { Start } { }, { End } { }, { Surrounders } { end } }
+ { \@@_tmp:w {#1} { Item } ##1 \@@_tmp:w {#1} { } ##1 }
+ \@@_tmp:w {#1} { Item } { Separator } { }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SetFistrumDefault}
+% Command to change the default range used by \cs{fistrum} and friends.
+% \begin{arguments}
+% \item[\meta{range}] Range to be used as default.
+% \end{arguments}
+% Implemented as:
+% \begin{macrocode}
+\NewDocumentCommand \SetFistrumDefault { m }
+ {
+ \@@_parse_par_range:eNN {#1} \l_@@_a_int \l_@@_b_int
+ \tl_gset:Nx \g_fistrum_default_range_tl
+ { \int_use:N \l_@@_a_int - \int_use:N \l_@@_b_int }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% The following macros are considered to be user-level commands and thus
+% all lower-case.
+%
+% \begin{macro}{\fistrum}
+% \begin{arguments}
+% \item Range-like string that specifies the number of the
+% paragraphs taken from \fist\ If omitted, the value set by
+% \cs{SetFistrumDefault} is used, which defaults to |1-7|.
+% \item Sentences to be typeset from the range selected by
+% \meta{paragraph range}. If sentences outside the number of
+% sentences in \meta{paragraph range} are specified, only existing
+% sentences are typeset.
+% \end{arguments}
+% The difference between \cs{fistrum} and \cs{fistrum*} is the token(s)
+% that are inserted after each paragraph (only if called without the
+% second optional argument).
+%
+% \cs{fistrum} and \cs{unpackfistrum} have the same interface and do
+% almost the same thing, so both are implemented using a common macro
+% \cs{@@_do:nnnn} that does the heavy-lifting, and at the end
+% executes the code in |#4|.
+% \begin{macrocode}
+\NewDocumentCommand \fistrum { s O { \g_fistrum_default_range_tl } o }
+ {
+ \@@_do:nnnn {#1} {#2} {#3}
+ {
+ \@@_set_hyphens:
+ \tl_use:N ##1
+ \@@_restore_hyphens:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\unpackfistrum,\fistrumexp}
+% This command does the same as \cs{fistrum}, but instead of
+% typesetting the paragraphs or sentences, it stores the expanded
+% content in the \cs{fistrumexp} token list. The tokens between items
+% of the list, set, for example, by using the package option
+% \opt{space} or by using the \cs{SetFistrum...List} commands, are
+% |x|-expanded.
+% \begin{macrocode}
+\NewDocumentCommand \unpackfistrum { s O { \g_fistrum_default_range_tl } o }
+ { \@@_do:nnnn {#1} {#2} {#3} { \tl_gset_eq:NN \fistrumexp ##1 } }
+\cs_new_eq:NN \fistrumexp \prg_do_nothing:
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_do:nnnn}
+% \begin{macro}{\@@_do:N}
+% This is the main macro for \cs{fistrum} and \cs{unpackfistrum}.
+% It parses the paragraph range, sets the sentence/paragraph
+% separators, then acts accordingly if a sentence range was provided.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_do:nnnn #1 #2 #3 #4
+ {
+ \cs_set_protected:Npn \@@_do:N ##1 {#4}
+ \@@_parse_par_range:eNN {#2} \l_@@_a_int \l_@@_b_int
+ \str_set_eq:NN \l_@@_tmpa_str \l_@@_sep_set_str
+ \str_set:Nx \l_@@_sep_set_str { \IfBooleanF {#1} { no } star }
+ \bool_lazy_or:nnTF
+ { \tl_if_novalue_p:n {#3} }
+ { \tl_if_blank_p:n {#3} }
+ {
+ \tl_set:Nx \l_@@_output_tl
+ { \fistrum_get_range:nn { \l_@@_a_int } { \l_@@_b_int } }
+ }
+ {
+ \str_set:Nn \l_@@_sep_set_str { parsepar }
+ \tl_set:Nx \l_@@_output_tl
+ { \fistrum_get_range:nn { \l_@@_a_int } { \l_@@_b_int } }
+ \str_set:Nx \l_@@_sep_set_str { \IfBooleanF {#1} { no } star }
+ \@@_parse_sentence_range:eNN {#3} \l_@@_a_int \l_@@_b_int
+ \tl_set:Nx \l_@@_output_tl
+ {
+ \fistrum_get_sentences:nnV { \l_@@_a_int } { \l_@@_b_int }
+ \l_@@_output_tl
+ }
+ }
+ \str_set_eq:NN \l_@@_sep_set_str \l_@@_tmpa_str
+ \@@_do:N \l_@@_output_tl
+ }
+\cs_new_eq:NN \@@_do:N ?
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_hyphens:,\@@_restore_hyphens:}
+% Selects the hyphenation patterns for the language of the dummy text,
+% using \cs{hyphenrules} if that's defined. If \cs{hyphenrules}
+% doesn't exist try setting hyphenation with \cs{@@_set_hyphens_raw:}.
+% Each \cs[no-index]{@@_set_hyphens_\meta{method}:} function
+% appropriately redefines \cs{@@_restore_hypehens:} to reset the
+% hyphenation patterns.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_hyphens:
+ {
+ \bool_if:NTF \l_@@_autolang_bool
+ { \use:n } { \use_none:n }
+ {
+ \cs_if_exist:NTF \hyphenrules
+ {
+ \cs_if_exist:cTF { ver@polyglossia.sty }
+ { \@@_set_hyphens_polyglossia: }
+ { \@@_set_hyphens_babel: }
+ }
+ { \@@_set_hyphens_raw: }
+ }
+ }
+\cs_new_protected:Npn \@@_restore_hyphens:
+ { \prg_do_nothing: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_hyphens_babel:}
+% \pkg{babel} makes things pretty simple. We just check if
+% \cs[no-index]{l@\meta{lang}} is defined, and if so, use
+% \cs{hyphenrules} to set it, and once more to reset in
+% \cs{@@_restore_hyphens:}. \cs{hyphenrules} is actually an
+% environment, but in \pkg{babel} its \cs[no-index]{end} part does
+% nothing, and its effect can be undone by just using another
+% \cs{hyphenrules} on top of it.
+%
+% If the language is not defined, the language either doesn't exist at
+% all, or we are using Lua\TeX. Both cases are handled by
+% \cs{@@_lang_not_available:}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_hyphens_babel:
+ {
+ \cs_if_exist:cTF { l@ \g_@@_language_tl }
+ {
+ \exp_args:NV \hyphenrules \g_@@_language_tl
+ \cs_set_protected:Npx \@@_restore_hyphens:
+ { \exp_not:N \hyphenrules { \languagename } }
+ }
+ { \@@_lang_not_available: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_hyphens_polyglossia:}
+% \pkg{polyglossia} less friendly. We also check if the language is
+% loaded (looking at \cs[no-index]{\meta{lang}@loaded}), and if it
+% is, load it with the \env{hyphenrules} environment. Here we can't
+% use the command form, as the \cs[no-index]{end} part is not a no-op.
+% This also means that an extra group is added around the dummy text,
+% which causes issue \ghissue{1} when used with \pkg{wrapfig}, for
+% example. But not too much we can do about that for now.
+%
+% In case the language is not loaded, fall back to
+% \cs{@@_set_hyphens_raw:} for a final attempt before giving up.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_hyphens_polyglossia:
+ {
+ \cs_if_exist:cTF { \g_@@_language_tl @loaded }
+ {
+ \exp_args:NnV \begin{hyphenrules} \g_@@_language_tl
+ \cs_set_protected:Npn \@@_restore_hyphens:
+ { \end{hyphenrules} }
+ }
+ { \@@_set_hyphens_raw: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_set_hyphens_raw:}
+% If nothing else is available, try setting the language using
+% \cs{language}\meta{number}. This is always available,
+% except with Lua\TeX, which loads languages on-the-fly.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_set_hyphens_raw:
+ {
+ \cs_if_exist:cTF { l@ \g_@@_language_tl }
+ {
+ \use:x
+ {
+ \language \use:c { l@ \g_@@_language_tl }
+ \cs_set_protected:Npn \@@_restore_hyphens:
+ { \language \int_eval:n { \language } \scan_stop: }
+ }
+ }
+ { \@@_lang_not_available: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_lang_not_available:}
+% If the requested language is for some reason unavailable, warn the
+% user, then fall back to the current language. If the requested
+% language and \cs{languagename} are the same, we are probably running
+% into this warning again because we have no languages loaded (e.g.,
+% testing environments). In that case, shut up because there's not
+% much that can be done (and a warning that says ``language "english"
+% is not available; using "english" instead'' is of little use).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_lang_not_available:
+ {
+ \str_if_eq:VVF \g__fistrum_language_tl \languagename
+ {
+ \msg_warning:nnx { fistrum } { missing-language }
+ { \g_@@_language_tl }
+ \tl_gset_eq:NN \g_@@_language_tl \languagename
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\NewFistrumPar}
+% Developer-Level macro to add a paragraph to the dummy text used by
+% \cs{fistrum} and related commands. To specify a new dummy text, see
+% section~\ref{sec:other-texts}.
+% \begin{macrocode}
+\cs_new_protected:Npn \NewFistrumPar #1
+ {
+ \int_gincr:N \g_@@_par_int
+ \tl_gclear_new:c { g_@@_par_ \int_use:N \g_@@_par_int _tl }
+ \tl_gset:cn { g_@@_par_ \int_use:N \g_@@_par_int _tl } {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SetFistrumText}
+% Used to select and load the text output by \cs{fistrum} and friends.
+% See the section on loading and defining new outputs for \cs{fistrum}
+% (section~\ref{sec:other-texts}). It first checks whether the
+% requested text is already loaded, and if not, it loads the
+% corresponding fistrum text definition file, and clears remaining
+% paragraphs from the previous text, in case their lengths differ.
+% \begin{macrocode}
+\NewDocumentCommand \SetFistrumText { m }
+ {
+ \str_if_eq:VnF \g_@@_text_str {#1}
+ {
+ \tl_gset:Nn \g_@@_language_tl { english }
+ \int_gzero:N \g_@@_par_int
+ \file_input:n { #1.ftd }
+ \str_gset:Nn \g_@@_text_str {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SetFistrumLanguage}
+% This macro sets the language for hyphenation patterns of the dummy
+% text. When a new fistrum text is read, this is reset.
+% \begin{macrocode}
+\NewDocumentCommand \SetFistrumLanguage { m }
+ { \tl_gset:Nn \g_@@_language_tl {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Package options and defaults}
+%
+% \begin{macro}[int]{
+% \fistrumRestoreParList,
+% \fistrumRestoreSentenceList,
+% \fistrumRestoreAll,
+% }
+% \begin{macro}{\@@_delim_restore:nnn}
+% \begin{macro}{\@@_restore_par_list:,\@@_restore_sentence_list:}
+% These are some auxiliaries for the package options and for setting
+% up the default behaviour.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_delim_restore:nnn #1 #2 #3
+ {
+ \keys_set:nn { fistrum }
+ {
+ #1-before = , #1-begin = , #1-end = , #1-after = ,
+ #1-before* = , #1-begin* = , #1-end* = , #1-after* = ,
+ #1-sep = {#2}, #1-sep* = {#3}
+ }
+ }
+\cs_new_protected:Nn \@@_restore_sentence_list:
+ { \@@_delim_restore:nnn { sentence } { ~ } { ~ } }
+\cs_new_eq:NN \@@_restore_par_list: ?
+\cs_new_protected:Npn \fistrumRestoreParList
+ {
+ \@@_deprecated:n { FistrumRestoreParList }
+ \@@_restore_par_list:
+ }
+\cs_new_protected:Npn \fistrumRestoreSentenceList
+ {
+ \@@_deprecated:n { FistrumRestoreSentenceList }
+ \@@_restore_sentence_list:
+ }
+\cs_new_protected:Npn \fistrumRestoreAll
+ {
+ \@@_deprecated:n { FistrumRestoreAll }
+ \@@_restore_par_list: \@@_restore_sentence_list:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\setfistrum}
+% Here are the options available at load-time and to \cs{setfistrum}.
+% \begin{macrocode}
+\NewDocumentCommand \setfistrum { +m }
+ { \keys_set:nn { fistrum } {#1} }
+\keys_define:nn { fistrum }
+ {
+% \end{macrocode}
+% \opt{nopar} is implemented as a choice key instead of a boolean so
+% we can update the separators using \cs{@@_delim_restore:nnn}.
+% It's initially false, and the default is |true| so that
+% |\usepackage[nopar]{fistrum}| works as it always did.
+% \begin{macrocode}
+ nopar .choice: ,
+ nopar / true .code:n =
+ {
+ \cs_gset_protected:Npn \@@_restore_par_list:
+ { \@@_delim_restore:nnn { par } { ~ } { \par } }
+ } ,
+ nopar / false .code:n =
+ {
+ \cs_gset_protected:Nn \@@_restore_par_list:
+ { \@@_delim_restore:nnn { par } { \par } { ~ } }
+ } ,
+ nopar .initial:n = false ,
+ nopar .default:n = true ,
+% \end{macrocode}
+% \opt{auto-lang} sets \cs{l_@@_autolang_bool}. It is initially
+% |true|, changing the default behaviour from previous versions.
+% \begin{macrocode}
+ auto-lang .bool_set:N = \l_@@_autolang_bool ,
+ auto-lang .initial:n = true ,
+ auto-lang .default:n = true ,
+% \end{macrocode}
+% \opt{text} just does \cs{SetFistrumText}. The |initial| value is not
+% set here because this chunk of code is executed in \pkg{expl3}
+% syntax, then thetextloadswithoutspaces, so |\setfistrum{text=fistrum-la}|
+% is used later.
+% \begin{macrocode}
+ text .code:n = \SetFistrumText{#1} ,
+ text .value_required:n = true ,
+% \end{macrocode}
+% \opt{language} sets the language to be used when typesetting.
+% \begin{macrocode}
+ language .tl_gset:N = \g_@@_language_tl ,
+ language .value_required:n = true ,
+% \end{macrocode}
+% \opt{default-range} does \cs{SetFistrumDefault}, initially |1-7|, as
+% documented. It's default is also |1-7| so that the key has two
+% meanings: \cs{setfistrum}|{default-range=|\meta{range}|}| sets the
+% range to the given value, while \cs{setfistrum}|{default-range}| sets
+% the range to the ``default default range''. Pretty neat :)
+% \begin{macrocode}
+ default-range .code:n = \SetFistrumDefault{#1} ,
+ default-range .initial:n = 1-7 ,
+ default-range .default:n = 1-7 ,
+ }
+% \end{macrocode}
+% This chunk defines the keys \meta{thing}-\meta{place}[*], where
+% \meta{thing} is |par| or |sentence|, \meta{place} is |before|,
+% |begin|, |sep|, |end|, and |after|, which totals~10 keys, and
+% another~10 with the |*| in the name. Each sets a token list called
+% \cs[no-index]{l_@@_\meta{thing}_\meta{place}_[no]star_tl}.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1 #2 #3
+ {
+ \keys_define:nn { fistrum }
+ {
+ #1-before #2 .tl_set:c = l_@@_#1_start _#3star_tl ,
+ #1-begin #2 .tl_set:c = l_@@_#1_itemstart _#3star_tl ,
+ #1-sep #2 .tl_set:c = l_@@_#1_itemseparator _#3star_tl ,
+ #1-end #2 .tl_set:c = l_@@_#1_itemend _#3star_tl ,
+ #1-after #2 .tl_set:c = l_@@_#1_end _#3star_tl ,
+ }
+ }
+\@@_tmp:w { par } { } { no } \@@_tmp:w { sentence } { } { no }
+\@@_tmp:w { par } * { } \@@_tmp:w { sentence } * { }
+% \end{macrocode}
+% \end{macro}
+%
+% Now turn \cs{ExplSyntaxOff} for a while, and load the default \fist{}
+% text, then process the package options, and finally turn
+% \cs{ExplSyntaxOn} again. Finally, call \cs{@@_restore_par_list:} and
+% \cs{@@_restore_sentence_list:} to set the defaults
+% (\cs{@@_restore_par_list:} may have been redefined by \opt{nopar}).
+% \begin{macrocode}
+\ExplSyntaxOff
+\setfistrum{text=fistrum-es}
+\ProcessKeysOptions{fistrum}
+\ExplSyntaxOn
+\@@_restore_par_list:
+\@@_restore_sentence_list:
+% \end{macrocode}
+%
+% \subsection{Messages}
+%
+% Now define the messages used throughout the package.
+% \begin{macrocode}
+\msg_new:nnn { fistrum } { invalid-range }
+ { Invalid~number~or~range~'#1'. }
+\msg_new:nnn { fistrum } { cmd-deprecated }
+ {
+ Command~'\iow_char:N\\#1'~deprecated. \\
+ See~the~fistrum~documentation~for~help.
+ }
+\msg_new:nnn { fistrum } { missing-language }
+ {
+ Unknown~language~'#1'.~Hyphenation~patterns~for~
+ '\languagename'~will~be~used~instead.
+ \sys_if_engine_luatex:T
+ {
+ \\ \\
+ \cs_if_exist:cTF { ver@polyglossia.sty }
+ {
+ With~polyglossia,~you~have~to~explicitly~load~languages~
+ with~\iow_char:N\\setotherlanguage{#1}~or~similar.
+ }
+ {
+ With~LuaTeX,~fistrum~requires~babel~to~get~proper~
+ hyphenation~(you~can~use~
+ \iow_char:N\\usepackage[base]{babel}).
+ }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \endinput
+% Local Variables:
+% mode: doctex
+% TeX-master: t
+% End:
diff --git a/Master/texmf-dist/source/latex/fistrum/fistrum.ins b/Master/texmf-dist/source/latex/fistrum/fistrum.ins
new file mode 100644
index 00000000000..5f0cfbe3486
--- /dev/null
+++ b/Master/texmf-dist/source/latex/fistrum/fistrum.ins
@@ -0,0 +1,117 @@
+%%
+%% Copyright (C) 2014-2019 by Patrick Happel (lipsum)
+%% Copyright (C) 2021 by Phelype Oleinik (lipsum)
+%% Copyright (C) 2023 by David Davó (fistrum)
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3 of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3 or later is part of all distributions of
+%% LaTeX version 2005/12/01 or later.
+%%
+\input docstrip.tex
+\askforoverwritefalse
+\keepsilent
+\preamble
+
+This file is part of the package fistrum for use with LaTeX2e.
+
+Function: Access to 150 paragraphs of pecadorrr text.
+
+This program may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+Please send error reports and suggestions for improvements to
+ https://github.com/daviddavo/fistrum
+
+\endpreamble
+\postamble
+\endpostamble
+
+\generate{\file{fistrum.sty}{\from{fistrum.dtx}{package}}}
+
+\newread\fistread
+\newread\fistwrite
+\newcount\parno
+\newif\ifinpar
+\def\empty{}%
+\def\line{}%
+\edef\lb{\string{}%
+\edef\rb{\string}}%
+\begingroup\lccode`\?=`\%
+\lowercase{\endgroup\def\pc{?}}%
+\def\wline{\immediate\write\fistwrite}%
+\def\genfistrum#1#2#3{%
+ \begingroup
+ \def\inFileName{fistrum-#1.txt}%
+ \def\outFileName{#2.ftd.tex}%
+ \openin\fistread\inFileName\space
+ \immediate\openout\fistwrite\outFileName\space
+ \inparfalse
+ \parno=0
+ \endlinechar=-1
+ \def\~{ }%
+ \def\ReferenceLines{%
+ \MetaPrefix ^^J%
+ \MetaPrefix\~The original source files were:^^J%
+ \MetaPrefix ^^J%
+ \MetaPrefix\~\inFileName^^J}%
+ \immediate\write\fistwrite{\defaultpreamble}%
+ \immediate\write\fistwrite{\string\SetFistrumLanguage{#3}}%
+ \genfistrumaux\genfistrumaux
+ \closein\fistread
+ \immediate\closeout\fistwrite
+ \endgroup}
+\def\genfistrumaux#1\genfistrumaux{%
+ \ifeof\fistread\let\line\empty
+ \else \read\fistread to \line \fi
+ \toks0{#1}%
+ \ifx\line\empty
+ \ifinpar
+ \wline{\the\toks0 \rb\pc^^J\pc}%
+ \inparfalse
+ \fi
+ \else
+ \ifinpar
+ \wline{\the\toks0 }%
+ \else
+ \inpartrue
+ \advance\parno by 1
+ \wline{\string\NewFistrumPar\lb\pc\~{\the\parno}}%
+ \fi
+ \fi
+ \ifeof\fistread\expandafter\genfistrumend\fi
+ \expandafter\genfistrumaux\line\genfistrumaux}
+\def\genfistrumend#1\genfistrumaux#2\genfistrumaux{}
+
+\genfistrum{la}{fistrum-la}{latin}
+\genfistrum{es}{fistrum-es}{spanish}
+
+\catcode`\ =13 \edef {\space}%
+\Msg{****************************************************}
+\Msg{* *}
+\Msg{* To finish the installation you have to move the *}
+\Msg{* following files into a directory searched *}
+\Msg{* by TeX: *}
+\Msg{* *}
+\Msg{* fistrum.sty *}
+\Msg{* fistrum-es.ftd.tex *}
+\Msg{* fistrum-la.ftd.tex *}
+\Msg{* *}
+\Msg{* To produce the documentation run the file *}
+\Msg{* fistrum.dtx through XeLaTeX or LuaLaTeX. *}
+\Msg{* *}
+\Msg{* Happy TeXing! *}
+\Msg{* *}
+\Msg{****************************************************}
+
+\endbatchfile