From 33f2990d24f3022051ee0a802c4baa6771009555 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 20 Nov 2023 20:48:17 +0000 Subject: fvextra (20nov23) git-svn-id: svn://tug.org/texlive/trunk@68915 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/fvextra/fvextra.pdf | Bin 867095 -> 905184 bytes Master/texmf-dist/source/latex/fvextra/fvextra.dtx | 902 ++++++++++++++++++--- Master/texmf-dist/tex/latex/fvextra/fvextra.sty | 433 ++++++++-- 3 files changed, 1166 insertions(+), 169 deletions(-) diff --git a/Master/texmf-dist/doc/latex/fvextra/fvextra.pdf b/Master/texmf-dist/doc/latex/fvextra/fvextra.pdf index d66fe66d149..54b8e27fddb 100644 Binary files a/Master/texmf-dist/doc/latex/fvextra/fvextra.pdf and b/Master/texmf-dist/doc/latex/fvextra/fvextra.pdf differ diff --git a/Master/texmf-dist/source/latex/fvextra/fvextra.dtx b/Master/texmf-dist/source/latex/fvextra/fvextra.dtx index 612c8858398..edd5d3599e8 100644 --- a/Master/texmf-dist/source/latex/fvextra/fvextra.dtx +++ b/Master/texmf-dist/source/latex/fvextra/fvextra.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2016-2022 by Geoffrey M. Poore +% Copyright (C) 2016-2023 by Geoffrey M. Poore % --------------------------------------------------------------------------- % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 @@ -26,7 +26,7 @@ %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{fvextra} %<*package> - [2022/11/30 v1.5 fvextra - extensions and patches for fancyvrb] + [2023/11/19 v1.6 fvextra - extensions and patches for fancyvrb] % % %<*driver> @@ -64,6 +64,27 @@ \usepackage{environ} +\usepackage{tcolorbox} +\tcbuselibrary{listings} +% strip leading percent symbols +\def\tcbverbatimwrite#1{% + \@bsphack + \tcb@set@verbatim@finish% + \tcb@allocate@tcb@out% + \immediate\openout\tcb@out #1 + \tcb@verbatim@begin@hook% + \let\do\@makeother\dospecials + \tcb@verbatim@change@percent\catcode`\^^M\active \catcode`\^^I=12 + \def\verbatim@processline{% + \immediate\write\tcb@out + {\expandafter\@gobble\the\verbatim@line}}% + \verbatim@start}% + +% fix redefinition by tcolorbox +\def\verbatim@processline{% + \expandafter\check@percent\the\verbatim@line\par} + + \usepackage{hyperref} \hypersetup{ pdftitle=The fvextra package: extensions and patches for fancyvrb, @@ -209,9 +230,10 @@ \g@addto@macro\changestext{\end{itemize}}% } \newcommand{\PrintChangelog}{% - \addcontentsline{toc}{section}{Version History} - \section*{Version History}% - \label{sec:version-history} + %\addcontentsline{toc}{section}{Changelog} + %\section*{Changelog}% + \section{Changelog}% + \label{sec:changelog} \begin{description}% \changestext \end{description}% @@ -230,23 +252,21 @@ % % \fi % -% \CheckSum{5254} -% -% \CharacterTable -% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z -% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z -% Digits \0\1\2\3\4\5\6\7\8\9 -% Exclamation \! Double quote \" Hash (number) \# -% Dollar \$ Percent \% Ampersand \& -% Acute accent \' Left paren \( Right paren \) -% Asterisk \* Plus \+ Comma \, -% Minus \- Point \. Solidus \/ -% Colon \: Semicolon \; Less than \< -% Equals \= Greater than \> Question mark \? -% Commercial at \@ Left bracket \[ Backslash \\ -% Right bracket \] Circumflex \^ Underscore \_ -% Grave accent \` Left brace \{ Vertical bar \| -% Right brace \} Tilde \~} +% +% \begin{changelog}{v1.6}{2023/11/19} +% \item Added new environment \Verb{VerbatimWrite}. This is similar to \Verb{fancyvrb}'s \Verb{VerbatimOut}, except that it allows for writing to a file multiple times and guarantees truly verbatim output via \Verb{\detokenize}. +% \item Added new environment \Verb{VerbatimBuffer}. This stores the contents of an environment verbatim in a ``buffer,'' a sequence of numbered macros each of which contains one line of the environment. The ``buffered'' lines can then be looped over for further processing or later use. +% \item Added new command \Verb{\VerbatimInsertBuffer}. This inserts an existing buffer created by \Verb{VerbatimBuffer} as a \Verb{Verbatim} environment. +% \item Redefined visible space \Verb{\FancyVerbSpace} so that it now has the correct width. It had previously been redefined as \Verb{\textvisiblespace}, but that was slightly too narrrow. +% \item Added option \Verb{spacebreak}. This determines the line break that is inserted around spaces when \Verb{showspaces=true} or \Verb{breakcollapsespaces=false}, by defining the new macro \Verb{\FancyVerbSpaceBreak}. +% \item \Verb{breakbefore}, \Verb{breakafter}, and \Verb{breakanywhere} now produce plain breaks around spaces when \Verb{showspaces=true}, instead of breaks with a break symbol at the end of wrapped lines. \Verb{\FancyVerbBreakAnywhereBreak}, \Verb{\FancyVerbBreakBeforeBreak}, and \Verb{\FancyVerbBreakAfterBreak} are no longer inserted next to spaces. Instead, \Verb{\FancyVerbSpaceBreak} is inserted or (depending on options) \Verb{\FV@Space} is defined to include \Verb{\FancyVerbSpaceBreak}. +% \item Added option \Verb{breakcollapsespaces}. When \Verb{true} (default), a line break within a run of regular spaces (\Verb{showspaces=false}) replaces all spaces with a single break, and the wrapped line after the break starts with a non-space character. When \Verb{false}, a line break within a run of regular spaces preserves all spaces, and the wrapped line after the break may start with one or more spaces. This causes regular spaces to behave exactly like the visible spaces produced with \Verb{showspaces}; both give identical line breaks, with the only difference being the appearance of spaces. +% \item \Verb{breaklines} now automatically enables breaks after space characters when \Verb{showspaces=true}. +% \item Reimplemented definition of \Verb{\FV@Space} to work with new space options. +% \item Added documentation about how reimplemented commands handle the \Verb{codes} option differently compared to \fancyvrb\ (\#17). +% \item Starred commands such as \Verb{\Verb*} now use both visible spaces and visible tabs instead of just visible spaces. This is more similar to the current behavior of \Verb{\verb*}, except that \Verb{\verb*} converts tabs into visible spaces (\#19). +% \item The \Verb{mathescape} option now resets the ampersand \Verb{&} catcode (\#18). +% \end{changelog} % % % \begin{changelog}{v1.5}{2022/11/30} @@ -355,7 +375,7 @@ % % Additional verbatim features would be nice, but since \fancyvrb\ has remained almost unchanged for so long, a major upgrade could be problematic. There are likely many existing documents that tweak or patch \fancyvrb\ internals in a way that relies on the existing implementation. At the same time, creating a completely new verbatim package would require a major time investment and duplicate much of \fancyvrb\ that remains perfectly functional. Perhaps someday there will be an amazing new verbatim package. Until then, we have \fvextra. % -% \fvextra\ is an add-on package that gives \fancyvrb\ several additional features, including automatic line breaking. Because \fvextra\ patches and overwrites some of the \fancyvrb\ internals, it may not be suitable for documents that rely on the details of the original \fancyvrb\ implementation. \fvextra\ tries to maintain the default \fancyvrb\ behavior in most cases. All reimplementations (\cref{sec:reimplemented-cmd-env}), patches (\cref{sec:patch}), and modifications to \fancyvrb\ defaults (\cref{sec:modifications}) are documented. In most cases, there are options to switch back to original implementations or original default behavior. +% \fvextra\ is an add-on package that gives \fancyvrb\ several additional features, including automatic line breaking. Because \fvextra\ patches and overwrites some of the \fancyvrb\ internals, it may not be suitable for documents that rely on the details of the original \fancyvrb\ implementation. \fvextra\ tries to maintain the default \fancyvrb\ behavior in most cases. All reimplementations (\cref{sec:reimplemented-cmd}), patches (\cref{sec:patch}), and modifications to \fancyvrb\ defaults (\cref{sec:modifications}) are documented. In most cases, there are options to switch back to original implementations or original default behavior. % % Some features of \fvextra\ were originally created as part of the \pkg{pythontex} and \pkg{minted} packages. \fancyvrb-related patches and extensions that currently exist in those packages will gradually be migrated into \fvextra. % @@ -372,7 +392,7 @@ % % % \subsection{Pandoc compatibility} -% +% % \pkg{fvextra} supports line breaking in \href{https://pandoc.org/}{Pandoc} \LaTeX\ output that includes highlighted source code. Enabling basic line breaking at spaces is as simple as adding |\usepackage{fvextra}| and |\fvset{breaklines}| to the Pandoc Markdown |header-includes|. % % By default, more advanced line breaking features such as |breakanywhere|, |breakbefore|, and |breakafter| will not work with Pandoc highlighted output, due to the presence of the syntax highlighting macros. This can be fixed by using |breaknonspaceingroup|, which enables all line breaking features within macros. For example, the following YAML metadata in a Markdown document would redefine the Pandoc |Highlighting| environment to enable line breaking anywhere. @@ -480,9 +500,13 @@ % % % \item[mathescape (boolean) (false)] -% This causes everything between dollar signs |$...$| to be typeset as math. The caret |^| and underscore |_| have their normal math meanings. +% This causes everything between dollar signs |$...$| to be typeset as math. The ampersand |&|, caret |^|, and underscore |_| have their normal math meanings. % -% This is equivalent to |codes={\catcode`$=3\catcode`^=7\catcode`_=8}|. |mathescape| is always applied \emph{before} |codes|, so that |codes| can be used to override some of these definitions. +% This is equivalent to +% \begin{Verbatim}[gobble=2] +% codes={\catcode`\$=3\catcode`\&=4\catcode`\^=7\catcode`\_=8} +% \end{Verbatim} +% |mathescape| is always applied \emph{before} |codes|, so that |codes| can be used to override some of these definitions. % % Note that \fvextra\ provides several patches that make math mode within verbatim as close to normal math mode as possible (\cref{sec:patch:math}). % @@ -526,10 +550,14 @@ % This only applies to the reimplemented \cmd{\UseVerb}, when paired with the reimplemented \cmd{\SaveVerb}. It may be extended to environments (\cmd{\UseVerbatim}, etc.\@) in the future, if the relevant commands and environments are reimplemented. % % -% \item[space (macro) (\string\textvisiblespace, \textvisiblespace)] +% \item[space (macro) ({\ttfamily\FancyVerbSpace})] % Redefine the visible space character. Note that this is only used if |showspaces=true|. The color of the character may be set with |spacecolor|. % % +% \item[spacebreak (macro) (\Verb{\discretionary{}{}{}})] +% This determines the break that is inserted around spaces when |breaklines=true| and one or more of the following conditions applies: |breakcollapsespaces=false|, |showspaces=true|, or the space is affected by |breakbefore| or |breakafter|. If it is redefined, it should typically be similar to |\FancyVerbBreakAnywhereBreak|, |\FancyVerbBreakBeforeBreak|, and |\FancyVerbBreakAfterBreak| to obtain consistent breaks. +% +% % \item[spacecolor (string) (none)] % Set the color of visible spaces. By default (|none|), they take the color of their surroundings. % @@ -617,13 +645,13 @@ % % This is like \cmd{\fvset}, except that options only apply to commands that typeset inline verbatim, like \cmd{\Verb} and \cmd{\EscVerb}. Settings from \cmd{\fvinlineset} override those from \cmd{\fvset}. % -% Note that \cmd{\fvinlineset} only works with commands that are reimplemented, patched, or defined by \fvextra; it is not compatible with the original \fancyvrb\ definitions. +% Note that \cmd{\fvinlineset} only works with commands that are reimplemented, patched, or defined by \fvextra; it is not compatible with the original \fancyvrb\ definitions. % % % \subsection{Custom formatting for inline commands like \cmd{\Verb} with \cmd{\FancyVerbFormatInline}} % % \DescribeMacro{\FancyVerbFormatInline} -% +% % This can be used to apply custom formatting to inline verbatim text created with commands like \cmd{\Verb}. It only works with commands that are reimplemented, patched, or defined by \fvextra; it is not compatible with the original \fancyvrb\ definitions. The default definition does nothing; it is equivalent to |\newcommand{\FancyVerbFormatInline}[1]{#1}|. % % This is the inline equivalent of \cmd{\FancyVerbFormatLine} and \cmd{\FancyVerbFormatText}. In the inline context, there is no need to distinguish between entire line formatting and only text formatting, so only \cmd{\FancyVerbFormatInline} exists. @@ -656,19 +684,22 @@ % % % -% \section{Reimplemented commands and environments} -% \label{sec:reimplemented-cmd-env} +% \section{Reimplemented commands} +% \label{sec:reimplemented-cmd} % % \fvextra\ reimplements parts of \fancyvrb. These new implementations stay close to the original definitions while allowing for new features that otherwise would not be possible. Reimplemented versions are used by default. The original implementations may be used via |\fvset{extra=false}| or by using |extra=false| in the optional arguments to a command or environment. % +% Reimplemented commands restrict the scope of catcode-related options compared to the original \fancyvrb\ versions. This prevents catcode-related options from interfering with new features such as |\FancyVerbFormatInline|. With \fvextra, the |codes| option should only be used for catcode modifications. Including non-catcode commands in |codes| will typically have no effect, unlike with \fancyvrb. If you want to customize verbatim content using general commands, consider |formatcom|. +% % \subsection{\cmd{\Verb}} % \DescribeMacro{\Verb*\oarg{options}\meta{delim~char~or~\{}\meta{text}\meta{delim~char~or~\}}} % % The new \cmd{\Verb} works as expected (with a few limitations) inside other commands. It even works in movable arguments (for example, in \cmd{\section}), and is compatible with \pkg{hyperref} for generating PDF strings (for example, PDF bookmarks). The \fancyvrb\ definition did work inside some other commands, but essentially functioned as \cmd{\texttt} in that context. % -% \cmd{\Verb} is compatible with |breaklines| and the relevant line-breaking options. +% \cmd{\Verb} is compatible with |breaklines| and the relevant line-breaking options. +% +% Like the original \fancyvrb\ implementation, the new \cmd{\Verb} can be starred (|\Verb*|) and accepts optional arguments. While \fancyvrb's starred command |\Verb*| is a shortcut for |showspaces|, \fvextra's |\Verb*| is a shortcut for both |showspaces| and |showtabs|. This is more similar to the current behavior of \LaTeX's \Verb{\verb*}, except that \Verb{\verb*} converts tabs into visible spaces instead of displaying them as visible tabs. % -% Like the original \fancyvrb\ implementation, the new \cmd{\Verb} can be starred (|*|) as a shortcut for |showspaces|, and accepts optional arguments. % \begin{description} % \item[Delimiters] A repeated character like normal \cmd{\verb}, or a pair of curly braces |{...}|. If curly braces are used, then \meta{text} cannot contain unpaired curly braces. Note that curly braces should be preferred when using \cmd{\Verb} inside other commands, and curly braces are \emph{required} when \cmd{\Verb} is in a movable argument, such as in a \cmd{\section}. Non-ASCII characters now work as delimiters under pdfTeX with \pkg{inputenc} using UTF-8.\footnote{Under pdfTeX, non-ASCII code points are processed at the byte rather than code point level, so \cmd{\Verb} must treat a sequence of multiple bytes as the delimiter.} For example, \Verb{\VerbĀ§verbĀ§} now works as expected. % \item[Limitations inside other commands] While the new \cmd{\Verb} does work inside arbitrary other commands, there are a few limitations. @@ -710,7 +741,7 @@ % \item |\UseVerb[retokenize, commandchars=\\\{\}]{save}| $\Rightarrow$ \UseVerb[retokenize, commandchars=\\\{\}]{save} % \end{itemize} % -% +% % % % @@ -752,6 +783,156 @@ % AFTER % \end{example} % +% \cmd{VerbEnv} is not implemented using the typical \fancyvrb\ environment implementation style, so it is not compatible with |\RecustomVerbatimEnvironment|. +% +% +% \subsection{\cmd{VerbatimWrite}} +% \DescribeMacro{\begin\{VerbatimWrite\}\oarg{opt}\\$\langle$\textit{lines}$\rangle$\\\cmd{\end{VerbatimWrite}}} +% +% This writes environment contents verbatim to an external file. It is similar to \fancyvrb's |VerbatimOut|, except that (1) it allows writing to a file multiple times (multiple environments can write to the same file) and (2) by default it uses |\detokenize| to guarantee truly verbatim output. +% +% By default, all \fancyvrb\ options except for |VerbatimWrite|-specific options are ignored. This can be customized on a per-environment basis via environment optional arguments. +% +% ~ +% +% \noindent Options defined specifically for \cmd{VerbatimWrite}: +% +% \begin{optionlist} +% \item[writefilehandle (file handle) (\meta{none})] +% File handle for writing. For example, +% \begin{Verbatim}[gobble=2] +% \newwrite\myfile +% \immediate\openout\myfile=myfile.txt\relax +% +% \begin{VerbatimWrite}[writefilehandle=\myfile] +% ... +% \end{VerbatimWrite} +% +% \immediate\closeout\myfile +% \end{Verbatim} +% +% \item[writer (macro) (\cmd{\FancyVerbDefaultWriter})] +% This is the macro that processes each line of text in the environment and then writes it to file. This is the default implementation: +% \begin{Verbatim}[gobble=2] +% \def\FancyVerbDefaultWriter#1{% +% \immediate\write\FancyVerbWriteFileHandle{\detokenize{#1}}} +% \end{Verbatim} +% \end{optionlist} +% +% +% \subsection{\cmd{VerbatimBuffer}} +% \DescribeMacro{\begin\{VerbatimBuffer\}\oarg{opt}\\$\langle$\textit{lines}$\rangle$\\\cmd{\end{VerbatimBuffer}}} +% +% This environment stores its contents verbatim in a ``buffer,'' a sequence of numbered macros each of which contains one line of the environment. The ``buffered'' lines can then be looped over for further processing or later use. This is similar to \fancyvrb's |SaveVerbatim|, which saves an environment for later use. |VerbatimBuffer| offers additional flexibility by capturing truly verbatim environment contents using |\detokenize| and saving environment contents in a format designed for further processing. +% +% By default, all \fancyvrb\ options except for |VerbatimBuffer|-specific options are ignored. This can be customized on a per-environment basis via environment optional arguments. +% +% Below is an extended example that demonstrates what is possible with |VerbatimBuffer| combined with |\VerbatimInsertBuffer|. This uses |\ifdefstring| from the \pkg{etoolbox} package. +% \begin{itemize} +% \item |\setformatter| defines an empty |\formatter| macro. Then it loops over the lines in a buffer looking for a line containing only the text ``red''. If this is found, it redefines |\formatter| to |\color{red}|. |FancyVerbBufferIndex| is a counter that is always available for buffer looping. |FancyVerbBufferLength| is the default counter containing the buffer length (number of lines). |\FancyVerbBufferLineName| contains the base name for buffer line macros (default |FancyVerbBufferLine|). +% \item |afterbuffer| involves two steps: (1) |\setformatter| loops through the buffer and defines |\formatter| based on the buffer contents, and (2) |\VerbatimInsertBuffer| typesets the buffer, using |formatcom=\formatter| to format the text based on whether any line contains only the text ``red''. +% \end{itemize} +% +%\begin{tcblisting}{oversize=5em} +%\def\setformatter{% +% \def\formatter{}% +% \setcounter{FancyVerbBufferIndex}{1}% +% \loop\unless\ifnum\value{FancyVerbBufferIndex}>\value{FancyVerbBufferLength}\relax +% \expandafter\let\expandafter\bufferline +% \csname\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname +% \ifdefstring{\bufferline}{red}{\def\formatter{\color{red}}}{}% +% \stepcounter{FancyVerbBufferIndex}% +% \repeat} +% +%\begin{VerbatimBuffer}[ +% afterbuffer={\setformatter\VerbatimInsertBuffer[formatcom=\formatter]} +%] +%first +%second +%red +%\end{VerbatimBuffer} +%\end{tcblisting} +% +% Here is the same example, but rewritten to use a global buffer with custom buffer names instead. +% +%\begin{tcblisting}{oversize=5em} +%\begin{VerbatimBuffer}[globalbuffer, bufferlinename=exbuff, bufferlengthname=exbuff] +%first +%second +%red +%\end{VerbatimBuffer} +% +%\def\formatter{} +%\setcounter{FancyVerbBufferIndex}{1} +%\loop\unless\ifnum\value{FancyVerbBufferIndex}>\value{exbuff}\relax +% \expandafter\let\expandafter\bufferline +% \csname exbuff\arabic{FancyVerbBufferIndex}\endcsname +% \ifdefstring{\bufferline}{red}{\def\formatter{\color{red}}}{} +% \stepcounter{FancyVerbBufferIndex} +%\repeat +% +%\VerbatimInsertBuffer[ +% formatcom=\formatter, +% bufferlinename=exbuff, +% bufferlengthname=exbuff +%] +%\end{tcblisting} +% +% ~ +% +% \noindent Options defined specifically for \cmd{VerbatimBuffer}: +% +% \begin{optionlist} +% \item[afterbuffer (macro) (\meta{none})] +% Macro or macros invoked at the end of the environment, after all lines of the environment have been buffered. This is outside the |\begingroup...\endgroup| that wraps verbatim processing, so \fancyvrb\ settings are no longer active. However, the buffer line macros and the buffer length counter are still accessible. +% +% \item[bufferer (macro) (\Verb{\FancyVerbDefaultBufferer})] +% This is the macro that adds lines to the buffer. The default is designed to create a truly verbatim buffer via |\detokenize|. This can be customized if you wish to use \fancyvrb\ options related to catcodes to create a buffer that is only partially verbatim (that contains macros). +% \begin{Verbatim}[gobble=2, fontsize=\small] +% \def\FancyVerbDefaultBufferer#1{% +% \expandafter\xdef\csname\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname{% +% \detokenize{#1}}} +% \end{Verbatim} +% A custom |bufferer| must take a single argument |#1| (a line of the environment text) and ultimately store the processed line in a macro called +% \begin{Verbatim}[gobble=2] +% \csname\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname +% \end{Verbatim} +% This macro must be defined globally, so |\xdef| or |\gdef| is necessary (this does not interfere with scoping from |globalbuffer|). Otherwise, there are no restrictions. The |\xdef| and |\detokenize| in the default definition guarantee that the buffer consists only of the literal text from the environment, but this is not required for a custom |bufferer|. +% +% \item[bufferlengthname (string) (FancyVerbBufferLength)] +% Name of the counter (|\newcounter|) storing the length of the buffer. This is the number of lines stored. +% +% \item[bufferlinename (string) (FancyVerbBufferLine)] +% The base name of the buffer line macros. The default is |FancyVerbBufferLine|, which will result in buffer macros |\FancyVerbBufferLine| with integer |n| greater than or equal to one and less than or equal to the number of lines (one-based indexing). Since buffer macro names contain a number, they must be accessed differently than typical macros: +% \begin{Verbatim}[gobble=2] +% \csname FancyVerbBufferLine\endcsname +% \@nameuse{FancyVerbBufferLine} +% \end{Verbatim} +% Typically the buffer macros will be looped over with a counter that is incremented, in which case || should be the counter value |\arabic{}|. +% +% \item[buffername (string) (\meta{none})] +% Shortcut for setting |bufferlengthname| and |bufferlinename| simultaneously, using the same root name. This sets |bufferlengthname| to |length| and |bufferlinename| to |line|. +% +% \item[globalbuffer (bool) (false)] +% This determines whether buffer line macros are defined globally, that is, whether they are accessible after the end of the |VerbatimBuffer| environment. It does not affect any |afterbuffer| macro, since that is invoked inside the environment. |globalbuffer| also determines whether the buffer length counter contains the buffer length or is reset to zero after the end of the |VerbatimBuffer| environment. +% +% When buffered lines are used immediately, consider using |afterbuffer| instead of |globalbuffer|. When buffered lines must be used later in a document, consider using |globalbuffer| with custom (and perhaps unique) |bufferlinename| and |bufferlengthname|. +% +% When |globalbuffer=false|, at the end of the environment all buffer line macros based on the current |bufferlinename| are ``deleted'' (|\let| to an undefined macro), and the buffer length counter from |bufferlengthname| is set to zero. This means that a |VerbatimBuffer| environment with |globalbuffer=false| will clear the buffer created by any previous |VerbatimBuffer| that had |globalbuffer=true| and shared the same |bufferlinename|. +% \end{optionlist} +% +% +% \subsection{\cmd{\VerbatimInsertBuffer}} +% \DescribeMacro{\VerbatimInsertBuffer\oarg{options}} +% +% This inserts an existing buffer created by |VerbatimBuffer| as a |Verbatim| environment. It customizes |Verbatim| internals to function with a buffer in a command context. See the |VerbatimBuffer| documentation for an example of usage. +% +% Options related to catcodes cause the buffer to be retokenized during typesetting. That is, the \fancyvrb\ options used for |\VerbatimInsertBuffer| are not restricted by those that were in effect when |VerbatimBuffer| originally created the buffer, so long as the buffer contains a complete representation of the original |VerbatimBuffer| environment contents. +% +% |\VerbatimInsertBuffer| is not implemented using the typical \fancyvrb\ command and environment implementation styles, so it is not compatible with |\RecustomVerbatimCommand| or |\RecustomVerbatimEnvironment|. +% +% +% % % \section{Line breaking} % \label{sec:breaklines} @@ -772,7 +953,7 @@ % % For an alternative, see |breakbefore|. When |breakbefore| and |breakafter| are used for the same character, |breakbeforeinrun| and |breakafterinrun| must both have the same setting. % -% Note that when |commandchars| or |codes| are used to include macros within verbatim content, breaks will not occur within mandatory macro arguments by default. Depending on settings, macros that take optional arguments may not work unless the entire macro including arguments is wrapped in a group (curly braces |{}|, or other characters specified with |commandchars|). See \cref{sec:breaklines:advanced} for details. +% Note that when |commandchars| or |codes| are used to include macros within verbatim content, breaks will not occur within mandatory macro arguments by default. Depending on settings, macros that take optional arguments may not work unless the entire macro including arguments is wrapped in a group (curly braces |{}|, or other characters specified with |commandchars|). See \cref{sec:breaklines:advanced} for details, and consider |breaknonspaceingroup| as a solution in simple cases. % % \begin{longexample} % \begin{Verbatim}[breaklines, breakafter=d] @@ -786,17 +967,17 @@ % % % \item[breakaftersymbolpre (string) (\string\,\string\footnotesize\string\ensuremath\{\_\string\rfloor\}, \,\footnotesize\ensuremath{_\rfloor})] -% The symbol inserted pre-break for breaks inserted by |breakafter|. +% The symbol inserted pre-break for breaks inserted by |breakafter|. This does not apply to breaks inserted next to spaces; see |spacebreak|. % % % \item[breakaftersymbolpost (string) (\meta{none})] -% The symbol inserted post-break for breaks inserted by |breakafter|. +% The symbol inserted post-break for breaks inserted by |breakafter|. This does not apply to breaks inserted next to spaces; see |spacebreak|. % % % \item[breakanywhere (boolean) (false)] % Break lines anywhere, not just at spaces, when |breaklines=true|. % -% Note that when |commandchars| or |codes| are used to include macros within verbatim content, breaks will not occur within mandatory macro arguments by default. Depending on settings, macros that take optional arguments may not work unless the entire macro including arguments is wrapped in a group (curly braces |{}|, or other characters specified with |commandchars|). See \cref{sec:breaklines:advanced} for details. +% Note that when |commandchars| or |codes| are used to include macros within verbatim content, breaks will not occur within mandatory macro arguments by default. Depending on settings, macros that take optional arguments may not work unless the entire macro including arguments is wrapped in a group (curly braces |{}|, or other characters specified with |commandchars|). See \cref{sec:breaklines:advanced} for details, and consider |breaknonspaceingroup| as a solution in simple cases. % % \begin{longexample} % \begin{Verbatim}[breaklines, breakanywhere] @@ -806,11 +987,11 @@ % % % \item[breakanywheresymbolpre (string) (\string\,\string\footnotesize\string\ensuremath\{\_\string\rfloor\}, \,\footnotesize\ensuremath{_\rfloor})] -% The symbol inserted pre-break for breaks inserted by |breakanywhere|. +% The symbol inserted pre-break for breaks inserted by |breakanywhere|. This does not apply to breaks inserted next to spaces; see |spacebreak|. % % % \item[breakanywheresymbolpost (string) (\meta{none})] -% The symbol inserted post-break for breaks inserted by |breakanywhere|. +% The symbol inserted post-break for breaks inserted by |breakanywhere|. This does not apply to breaks inserted next to spaces; see |spacebreak|. % % % \item[breakautoindent (boolean) (true)] @@ -822,7 +1003,7 @@ % % For an alternative, see |breakafter|. When |breakbefore| and |breakafter| are used for the same character, |breakbeforeinrun| and |breakafterinrun| must both have the same setting. % -% Note that when |commandchars| or |codes| are used to include macros within verbatim content, breaks will not occur within mandatory macro arguments by default. Depending on settings, macros that take optional arguments may not work unless the entire macro including arguments is wrapped in a group (curly braces |{}|, or other characters specified with |commandchars|). See \cref{sec:breaklines:advanced} for details. +% Note that when |commandchars| or |codes| are used to include macros within verbatim content, breaks will not occur within mandatory macro arguments by default. Depending on settings, macros that take optional arguments may not work unless the entire macro including arguments is wrapped in a group (curly braces |{}|, or other characters specified with |commandchars|). See \cref{sec:breaklines:advanced} for details, and consider |breaknonspaceingroup| as a solution in simple cases. % % \begin{longexample} % \begin{Verbatim}[breaklines, breakbefore=A] @@ -836,11 +1017,15 @@ % % % \item[breakbeforesymbolpre (string) (\string\,\string\footnotesize\string\ensuremath\{\_\string\rfloor\}, \,\footnotesize\ensuremath{_\rfloor})] -% The symbol inserted pre-break for breaks inserted by |breakbefore|. +% The symbol inserted pre-break for breaks inserted by |breakbefore|. This does not apply to breaks inserted next to spaces; see |spacebreak|. % % % \item[breakbeforesymbolpost (string) (\meta{none})] -% The symbol inserted post-break for breaks inserted by |breakbefore|. +% The symbol inserted post-break for breaks inserted by |breakbefore|. This does not apply to breaks inserted next to spaces; see |spacebreak|. +% +% +% \item[breakcollapsespaces (bool) (true)] +% When \Verb{true} (default), a line break within a run of regular spaces (\Verb{showspaces=false}) replaces all spaces with a single break, and the wrapped line after the break starts with a non-space character. When \Verb{false}, a line break within a run of regular spaces preserves all spaces, and the wrapped line after the break may start with one or more spaces. This causes regular spaces to behave exactly like the visible spaces produced with \Verb{showspaces}; both give identical line breaks, with the only difference being the appearance of spaces. % % % \item[breakindent (dimension) (\meta{breakindentnchars})] @@ -853,7 +1038,7 @@ % \item[breaklines (boolean) (false)] % Automatically break long lines. When a line is broken, the result must fit on a single page. There is no support for breaking a line across multiple pages.\footnote{Following the implementation in \pkg{fancyvrb}, each line is typeset within an |\hbox|, so page breaks are not possible.} % -% By default, automatic breaks occur at spaces. Use |breakanywhere| to enable breaking anywhere; use |breakbefore| and |breakafter| for more fine-tuned breaking. +% By default, automatic breaks occur at spaces (even when |showspaces=true|). Use |breakanywhere| to enable breaking anywhere; use |breakbefore| and |breakafter| for more fine-tuned breaking. % % \begin{example} % ...text. @@ -885,17 +1070,17 @@ % \end{longexample} % \endgroup % -% Automatic line breaks will not work with |showspaces=true| unless you use |breakanywhere|, or use |breakbefore| or |breakafter| with |\space|. For example, +% Beginning in version 1.6, automatic line breaks work with |showspaces=true| by default. Defining |breakbefore| or |breakafter| for |\space| is no longer necessary. For example, % % \begin{longexample} -% \begin{Verbatim}[breaklines, showspaces, breakafter=\space] +% \begin{Verbatim}[breaklines, showspaces] % some_string = 'Some Text That Goes On And On For So Long That It Could Never Fit' % \end{Verbatim} % \end{longexample} % % % \item[breaknonspaceingroup (boolean) (false)] -% By using |commandchars|, it is possible to include \LaTeX\ commands within otherwise verbatim text. In these cases, there can be groups (typically |{...}| but depends on |commandchars|) within verbatim. Spaces within groups are treated as potential line break locations when |breaklines=true|, but by default no other break locations are inserted (|breakbefore|, |breakafter|, |breakanywhere|). This is because inserting non-space break locations can interfere with command functionality. For example, in |\textcolor{red}{text}|, breaks shouldn't be inserted within |red|. +% By using |commandchars|, it is possible to include \LaTeX\ commands within otherwise verbatim text. In these cases, there can be groups (typically |{...}| but depends on |commandchars|) within verbatim. Spaces within groups are treated as potential line break locations when |breaklines=true|, but by default no other break locations are inserted (|breakbefore|, |breakafter|, |breakanywhere|). This is because inserting non-space break locations can interfere with command functionality. For example, in |\textcolor{red}{text}|, breaks shouldn't be inserted within |red|. % % |breaknonspaceingroup| allows non-space breaks to be inserted within groups. This option should only be used when |commandchars| is including \LaTeX\ commands that do not take optional arguments and only take mandatory arguments that are typeset. Something like |\textit{text}| is fine, but |\textcolor{red}{text}| is not because one of the mandatory arguments is not typeset but rather provides a setting. For more complex commands, it is typically better to redefine them to insert breaks in appropriate locations using |\FancyVerbBreakStart...\FancyVerbBreakStop|. % @@ -953,6 +1138,11 @@ % \item[breaksymbolseprightnchars (integer) (2)] % Allows |breaksymbolsepright| to be specified as an integer number of characters rather than as a dimension (assumes a fixed-width font). % +% +% \item[spacebreak (macro) (\Verb{\discretionary{}{}{}})] +% This determines the break that is inserted around spaces when |breaklines=true| and one or more of the following conditions applies: |breakcollapsespaces=false|, |showspaces=true|, or the space is affected by |breakbefore| or |breakafter|. If it is redefined, it should typically be similar to |\FancyVerbBreakAnywhereBreak|, |\FancyVerbBreakBeforeBreak|, and |\FancyVerbBreakAfterBreak| to obtain consistent breaks. +% +% % \end{optionlist} % % @@ -1073,7 +1263,7 @@ % \DescribeMacro{\FancyVerbBreakBeforeBreak} % \DescribeMacro{\FancyVerbBreakAfterBreak} % -% These macros govern the behavior of breaks introduced by |breakanywhere|, |breakbefore|, and |breakafter|. Breaks introduced by the default |breaklines| when |showspaces=false| are standard breaks following spaces. No special commands are provided for working with them; the normal \LaTeX\ commands for breaking should suffice. +% These macros govern the behavior of breaks introduced by |breakanywhere|, |breakbefore|, and |breakafter|. These do not apply to breaks inserted next to spaces; see |spacebreak|. % % By default, these macros use |\discretionary|. |\discretionary| takes three arguments: commands to insert before the break, commands to insert after the break, and commands to insert if there is no break. For example, the default definition of |\FancyVerbBreakAnywhereBreak|: % @@ -1138,7 +1328,7 @@ % \subsection{Visible spaces} % \label{sec:patch:visible-space} % -% The command |\FancyVerbSpace| defines the visible space when |showspaces=true|. The default \fancyvrb\ definition allows a font command to escape under some circumstances, so that all following text is forced to be teletype font. The command is redefined to use |\textvisiblespace|. +% The command |\FancyVerbSpace| defines the visible space when |showspaces=true|. The default \fancyvrb\ definition allows a font command to escape under some circumstances, so that all following text is forced to be teletype font. The command is redefined following \url{https://tex.stackexchange.com/a/120231/10742}. % % % \subsection{\texttt{obeytabs} with visible tabs and with tabs inside macro arguments} @@ -1241,7 +1431,7 @@ % % % \subsection{Command lookahead tokenization} -% +% % \cmd{\FV@Command} is used internally by commands like \cmd{\Verb} to read stars (|*|) and optional arguments (|[...]|) before invoking the core of the command. This is redefined so that lookahead tokenizes under a verbatim catcode regime. The original definition could prevent commands like \cmd{\Verb} from using characters like |%| as delimiters, because the lookahead for a star and optional argument could read the |%| and give it its normal meaning of comment character. The new definition fixes this, so that commands like \cmd{\Verb} behave as closely to \cmd{\verb} as possible. % % @@ -1305,7 +1495,7 @@ % % \DescribeMacro{\FancyVerbSpace} % -% This defines the visible space character (\texttt{\FancyVerbSpace}) that is used when |showspaces=true|. The default definition (as patched by \fvextra, \cref{sec:patch:visible-space}) is |\textvisiblespace|. While this may be redefined directly, \fvextra\ also defines a new option |space|. +% This defines the visible space character (\texttt{\FancyVerbSpace}) that is used when |showspaces=true|. The default definition (as patched by \fvextra, \cref{sec:patch:visible-space}) follows \url{https://tex.stackexchange.com/a/120231/10742}. While this may be redefined directly, \fvextra\ also defines a new option |space|. % % % @@ -1346,8 +1536,26 @@ % % \subsubsection{\fancyvrb\ space and tab tokens} % +% \begin{macro}{\FV@ActiveSpaceToken} +% Active space for |\ifx| token comparisons. +% \begin{macrocode} +\begingroup +\catcode`\ =\active% +\gdef\FV@ActiveSpaceToken{ }% +\endgroup% +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\FV@SpaceCatTen} +% Space with catcode 10. Used instead of \Verb[showspaces]{\ } and |\space| in some contexts to avoid issues in the event that these are redefined. +% \begin{macrocode} +\edef\FV@SpaceCatTen{\detokenize{ }} +% \end{macrocode} +% \end{macro} +% +% % \begin{macro}{\FV@FVSpaceToken} -% Macro with the same definition as \fancyvrb's active space. Useful for |\ifx| comparisons with |\@ifnextchar| lookaheads. +% Macro with the same definition as \fancyvrb's active space. Useful for |\ifx| comparisons, such as |\@ifnextchar| lookaheads. % \begin{macrocode} \def\FV@FVSpaceToken{\FV@Space} % \end{macrocode} @@ -1355,13 +1563,14 @@ % % % \begin{macro}{\FV@FVTabToken} -% Macro with the same definition as \fancyvrb's active tab. Useful for |\ifx| comparisons with |\@ifnextchar| lookaheads. +% Macro with the same definition as \fancyvrb's active tab. Useful for |\ifx| comparisons, such as |\@ifnextchar| lookaheads. % \begin{macrocode} \def\FV@FVTabToken{\FV@Tab} % \end{macrocode} % \end{macro} % % +% % \subsubsection{ASCII processing} % % \begin{macro}{\FVExtraDoSpecials} @@ -2153,7 +2362,7 @@ % \begin{itemize} % \item \cmd{\FV@VDetok@Scan} searches for spaces to replace. After any spaces in \meta{tokens} have been handled, the space in \Verb*|^^C \FV@| triggers space processing. When \cmd{\FV@VDetok@Scan} detects the sentinel macro \cmd{\FV@}, scanning stops. % \item The |{}| protects the beginning of \meta{tokens}, so that if \meta{tokens} is a group, its braces won't be gobbled. Later, the inserted |{}| must be stripped so that it does not become part the processed \meta{tokens}. -% \item |^^C| is a convenient separator between \meta{tokens} and the rest of the sentinel sequence. +% \item |^^C| is a convenient separator between \meta{tokens} and the rest of the sentinel sequence. % \begin{itemize} % \item Since \cmd{\FV@VDetok@Scan} has delimited arguments, a leading catcode 10 space in \meta{tokens} will be preserved automatically. Preserving a trailing catcode 10 space is much easier if it is immediately adjacent to a non-space character in the sentinel sequence; two adjacent catcode 10 spaces would be difficult to handle with macro pattern matching. However, the sentinel sequence must contain a catcode 10 space, so the sentinel sequence must contain at least 3 tokens. % \item Since |^^C| is not a control word, it does not gobble following spaces. That makes it much easier to assemble macro arguments that contain a catcode 10 space. This is useful because the sentinel sequence \Verb*|^^C \FV@| may have to be inserted into processing multiple times (for example, in recursive handling of groups). @@ -2287,7 +2496,7 @@ {\expandafter\FV@VDetok@ScanToken@i\detokenize{#1}^^C \FV@}} % \end{macrocode} % \end{macro} -% +% % \begin{macro}{\FV@VDetok@ScanToken@i} % If |#2| is empty, then there are no spaces in the detokenized token, so it is either an \cmd{\active} character other than the space, or a two-character sequence of the form || where the second character is not a space. Thus, |#1| contains \meta{detokenized}|^^C|. Otherwise, |#1| contains \meta{detokenized\_without\_space}, and |#2| may be discarded since it contains \Verb*|^^C \FV@|. (If the detokenized token contains a space, it is always at the end.) % \begin{macrocode} @@ -2489,7 +2698,7 @@ {\expandafter\FV@PDFStrVDetok@ScanToken@i\detokenize{#1}^^C \FV@}} % \end{macrocode} % \end{macro} -% +% % \begin{macro}{\FV@PDFStrVDetok@ScanToken@i} % \begin{macrocode} \gdef\FV@PDFStrVDetok@ScanToken@i#1 #2\FV@{% @@ -2586,7 +2795,7 @@ % \begin{macro}{\FVExtraEscapedVerbatimDetokenize} % This is a variant of \cmd{\FVExtraVerbatimDetokenize} that treats character sequences of the form |\| as escapes for ||. It is primarily intended for making |\| escapes for ||, but allowing arbitrary escapes simplifies the default behavior and implementation. This is useful in constructing nearly verbatim commands that can be used inside other commands, because the backslash escapes allow for characters like |#| and |%|, as well as making possible multiple adjacent spaces via \Verb*|\ |. It should be applied to arguments that are read verbatim insofar as is possible, except that the backslash |\| should have its normal meaning (catcode 0). Most of the implementation is identical to that for \cmd{\FVExtraVerbatimDetokenize}. Only the token processing requires modification to handle backslash escapes. % -% It is possible to restrict escapes to ASCII symbols and punctuation. See \cmd{\FVExtraDetokenizeREscVArg}. The disadvantage of restricting escapes is that it prevents functioning in an expansion-only context (unless you want to use undefined macros as a means of raising errors). The advantage is that it eliminates ambiguity introduced by allowing arbitrary escapes. Backslash escapes of characters with catcode 11 (ASCII letters, |[A-Za-z]|) are typically not necessary, and introduce ambiguity because something like |\x| will gobble following spaces since it will be tokenized originally as a control word. +% It is possible to restrict escapes to ASCII symbols and punctuation. See \cmd{\FVExtraDetokenizeREscVArg}. The disadvantage of restricting escapes is that it prevents functioning in an expansion-only context (unless you want to use undefined macros as a means of raising errors). The advantage is that it eliminates ambiguity introduced by allowing arbitrary escapes. Backslash escapes of characters with catcode 11 (ASCII letters, |[A-Za-z]|) are typically not necessary, and introduce ambiguity because something like |\x| will gobble following spaces since it will be tokenized originally as a control word. % \begin{macrocode} \gdef\FVExtraEscapedVerbatimDetokenize#1{% \FV@EscVDetok@Scan{}#1^^C \FV@} @@ -2697,7 +2906,7 @@ {\expandafter\FV@EscVDetok@ScanToken@i\detokenize{#1}^^C \FV@}} % \end{macrocode} % \end{macro} -% +% % \begin{macro}{\FV@EscVDetok@ScanToken@i} % \begin{macrocode} \gdef\FV@EscVDetok@ScanToken@i#1 #2\FV@{% @@ -2937,7 +3146,7 @@ {\expandafter\FV@PDFStrEscVDetok@ScanToken@i\detokenize{#1}^^C \FV@}} % \end{macrocode} % \end{macro} -% +% % \begin{macro}{\FV@PDFStrEscVDetok@ScanToken@i} % \begin{macrocode} \gdef\FV@PDFStrEscVDetok@ScanToken@i#1 #2\FV@{% @@ -3321,7 +3530,7 @@ {\FVC@Verb@Extra@i}} % \end{macrocode} % \end{macro} -% +% % \begin{macro}{\FVC@Verb@Extra@i} % \begin{macrocode} \def\FVC@Verb@Extra@i{% @@ -3458,7 +3667,7 @@ \fi} % \end{macrocode} % \end{macro} -% +% % % \begin{macro}{\FVC@UseVerb@Extra} % \begin{macrocode} @@ -3537,7 +3746,7 @@ % \end{macro} % % \begin{macro}{\FVC@EscVerb@i} -% \begin{macrocode} +% \begin{macrocode} \def\FVC@EscVerb@i#1{% \begingroup \FV@UseInlineKeyValues\FV@UseKeyValues\FV@FormattingPrep @@ -3671,6 +3880,276 @@ % % % +% \subsubsection{\cmd{VerbatimWrite}} +% +% This environment writes its contents to a file verbatim. Differences from \fancyvrb's |VerbatimOut|: +% \begin{itemize} +% \item Multiple |VerbatimWrite| environments can write to the same file. The file is set via the |writefilehandle| option. This does mean that the user is responsible for creating a new file handle via |\newwrite| and then ideally invoking |\closeout| at the appropriate time. +% \item By default, text is really written verbatim. This is accomplished by a combination of setting catcodes to 12 (other) and |\detokenize|. This can be customized using the new |writer| option, which defines a macro that performs any processing on each line before writing it to file. By default, all \fancyvrb\ options except for |VerbatimWrite|-specific options are ignored. This can be customized on a per-environment basis via environment optional arguments. +% \end{itemize} +% +% \begin{macro}{writefilehandle, \FancyVerbWriteFileHandle} +% Set file handle for |VerbatimWrite|. +% \begin{macrocode} +\define@key{FV}{writefilehandle}{% + \FV@SetWrite#1\FV@Sentinel} +\def\FV@SetWrite#1#2\FV@Sentinel{% + \let\FancyVerbWriteFileHandle\relax + \if\relax\detokenize{#2}\relax + \let\FancyVerbWriteFileHandle#1\relax + \fi + \ifx\FancyVerbWriteFileHandle\relax + \PackageError{fvextra}% + {Missing or invalid file handle for write}% + {Need file handle from \string\newwrite}% + \fi} +\let\FancyVerbWriteFileHandle\relax +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{writer, \FV@Writer} +% Define writer macro that processes each line before writing. +% \begin{macrocode} +\define@key{FV}{writer}{% + \let\FV@Writer#1\relax} +\def\FancyVerbDefaultWriter#1{% + \immediate\write\FancyVerbWriteFileHandle{\detokenize{#1}}} +\fvset{writer=\FancyVerbDefaultWriter} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{VerbatimWrite} +% The environment implementation follows standard \fancyvrb\ environment style. +% +% A special write counter is used to track line numbers while avoiding incrementing the regular counter that is used for typeset code. Some macros do nothing with the default |writer|, but are needed to enable \fancyvrb\ options when a custom |writer| is used in conjuction with optional environment arguments. These include |\FancyVerbDefineActive|, |\FancyVerbFormatCom|, and |\FV@DefineTabOut|. +% \begin{macrocode} +\newcounter{FancyVerbWriteLine} +\def\VerbatimWrite{% + \FV@Environment + {codes=,commandchars=none,commentchar=none,defineactive,% + gobble=0,formatcom=,firstline,lastline}% + {VerbatimWrite}} +\def\FVB@VerbatimWrite{% + \@bsphack + \begingroup + \setcounter{FancyVerbWriteLine}{0}% + \let\c@FancyVerbLine\c@FancyVerbWriteLine + \FV@UseKeyValues + \FV@DefineWhiteSpace + \def\FV@Space{\space}% + \FV@DefineTabOut + \let\FV@ProcessLine\FV@Writer + \let\FV@FontScanPrep\relax + \let\@noligs\relax + \FancyVerbDefineActive + \FancyVerbFormatCom + \FV@Scan} +\def\FVE@VerbatimWrite{% + \endgroup + \@esphack} +\def\endVerbatimWrite{\FVE@VerbatimWrite} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsubsection{\cmd{VerbatimBuffer}} +% +% This environment stores its contents verbatim in a ``buffer,'' a sequence of numbered macros each of which contains one line of the environment. The ``buffered'' lines can then be looped over for further processing or later use. +% +% By default, all \fancyvrb\ options except for |VerbatimBuffer|-specific options are ignored. This can be customized on a per-environment basis via environment optional arguments. +% +% \begin{macro}{afterbuffer, \FV@afterbuffer} +% Macro that is inserted after the last line of the environment is buffered, immediately before the environment ends. +% \begin{macrocode} +\define@key{FV}{afterbuffer}{% + \def\FV@afterbuffer{#1}} +\fvset{afterbuffer=} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{FancyVerbBufferIndex} +% Current index in buffer during buffering. This is given a |\FancyVerb*| macro name since it may be accessed by the user in defining custom |bufferer|. +% \begin{macrocode} +\newcounter{FancyVerbBufferIndex} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{bufferer, \FV@Bufferer, \FancyVerbDefaultBufferer} +% This is the macro that adds lines to the buffer. The default is designed to create a truly verbatim buffer via |\detokenize|. +% \begin{macrocode} +\define@key{FV}{bufferer}{% + \let\FV@Bufferer=#1\relax} +\def\FancyVerbDefaultBufferer#1{% + \expandafter\xdef\csname\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname{% + \detokenize{#1}}} +\fvset{bufferer=\FancyVerbDefaultBufferer} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{bufferlengthname, \FV@bufferlengthname} +% Name of counter storing the length of the buffer. +% \begin{macrocode} +\define@key{FV}{bufferlengthname}{% + \ifcsname c@#1\endcsname + \else + \newcounter{#1}% + \fi + \def\FV@bufferlengthname{#1}} +\fvset{bufferlengthname=FancyVerbBufferLength} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{bufferlinename, \FancyVerbBufferLineName} +% Base name of buffer line macros. This is given a |\FancyVerb*| macro name since it may be accessed by the user in defining custom |bufferer|. +% \begin{macrocode} +\define@key{FV}{bufferlinename}{% + \def\FancyVerbBufferLineName{#1}} +\fvset{bufferlinename=FancyVerbBufferLine} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{buffername} +% Shortcut for setting |bufferlengthname| and |bufferlinename|. +% \begin{macrocode} +\define@key{FV}{buffername}{% + \fvset{bufferlengthname=#1length,bufferlinename=#1line}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{globalbuffer, FV@globalbuffer} +% Whether buffer macros and the buffer length counter are defined globally. +% \begin{macrocode} +\newbool{FV@globalbuffer} +\define@booleankey{FV}{globalbuffer}% + {\booltrue{FV@globalbuffer}}% + {\boolfalse{FV@globalbuffer}} +\fvset{globalbuffer=false} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{VerbatimBuffer} +% The environment implementation follows standard \fancyvrb\ environment style. +% +% A special buffer counter is used to track line numbers while avoiding incrementing the regular counter that is used for typeset code. Some macros do nothing with the default |bufferer|, but are needed to enable \fancyvrb\ options when a custom |bufferer| is used in conjuction with optional environment arguments. These include |\FancyVerbDefineActive| and |\FancyVerbFormatCom|. Since counters are global, the location of |\setcounter| at the end of the environment relative to |\begingroup...\endgroup| is not important. +% \begin{macrocode} +\newcounter{FancyVerbBufferLine} +\newcounter{FV@oldbufferlength} +\newbool{FV@globalbuffer@tmp} +\let\FV@bufferlengthname@tmp\relax +\let\FancyVerbBufferLineName@tmp\relax +\let\FV@afterbuffer@tmp\relax +\def\VerbatimBuffer{% + \FV@Environment + {codes=,commandchars=none,commentchar=none,defineactive,% + gobble=0,formatcom=,firstline,lastline}% + {VerbatimBuffer}} +\def\FVB@VerbatimBuffer{% + \@bsphack + \begingroup + \setcounter{FancyVerbBufferLine}{0}% + \let\c@FancyVerbLine\c@FancyVerbBufferLine + \setcounter{FancyVerbBufferIndex}{0}% + \setcounter{FV@oldbufferlength}{\expandafter\value\expandafter{\FV@bufferlengthname}}% + \expandafter\setcounter\expandafter{\FV@bufferlengthname}{0}% + \FV@UseKeyValues + \ifbool{FV@globalbuffer}% + {\global\booltrue{FV@globalbuffer@tmp}}% + {\global\boolfalse{FV@globalbuffer@tmp}}% + \global\let\FV@bufferlengthname@tmp\FV@bufferlengthname + \global\let\FancyVerbBufferLineName@tmp\FancyVerbBufferLineName + \global\let\FV@afterbuffer@tmp\FV@afterbuffer + \FV@DefineWhiteSpace + \def\FV@ProcessLine{\stepcounter{FancyVerbBufferIndex}\FV@Bufferer}% + \let\FV@FontScanPrep\relax + \let\@noligs\relax + \FancyVerbDefineActive + \FancyVerbFormatCom + \FV@Scan} +\def\FVE@VerbatimBuffer{% + \endgroup + \@esphack + \expandafter\setcounter\expandafter{\FV@bufferlengthname@tmp}% + {\value{FancyVerbBufferIndex}}% + \setcounter{FancyVerbBufferIndex}{0}% + \begingroup + \FV@afterbuffer@tmp + \endgroup + \ifbool{FV@globalbuffer@tmp}% + {}% + {\ifnum\value{FV@oldbufferlength}>% + \expandafter\value\expandafter{\FV@bufferlengthname@tmp}\relax + \expandafter\setcounter\expandafter{\FV@bufferlengthname@tmp}% + {\value{FV@oldbufferlength}}% + \fi + \loop\unless\ifnum\expandafter\value\expandafter{\FV@bufferlengthname@tmp}=0\relax + \expandafter\global\expandafter\let\csname + \FancyVerbBufferLineName@tmp + \expandafter\arabic\expandafter{\FV@bufferlengthname@tmp}% + \endcsname\FV@Undefined + \expandafter\addtocounter\expandafter{\FV@bufferlengthname@tmp}{-1}% + \repeat}} +\def\endVerbatimBuffer{\FVE@VerbatimBuffer} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsubsection{\cmd{\VerbatimInsertBuffer}} +% \begin{macro}{\VerbatimInsertBuffer} +% This inserts an existing buffer created by |VerbatimBuffer| as a |Verbatim| environment. It customizes |Verbatim| internals to function with a buffer in a command context. +% \begin{macrocode} +\newcommand{\VerbatimInsertBuffer}[1][]{% + \begingroup + \def\FV@KeyValues{#1}% + \def\FV@Scan{% + \FV@CatCodes + \xdef\FV@EnvironName{Verbatim}% + \ifnum\expandafter\value\expandafter{\FV@bufferlengthname}=\z@\relax + \PackageError{fvextra}% + {Buffer length counter \FV@bufferlengthname\space is invalid or zero}% + {}% + \let\FV@GetLine\relax + \fi + \FV@GetLine}% + \let\FV@CheckScan\relax + \setcounter{FancyVerbBufferIndex}{1}% + \def\VerbatimInsertBuffer@def@FV@Line##1{% + \FVExtraRetokenizeVArg{\def\FV@Line}{}{##1}} + \def\FancyVerbGetLine{% + \ifnum\value{FancyVerbBufferIndex}>% + \expandafter\value\expandafter{\FV@bufferlengthname}\relax + \global\let\FV@EnvironName\relax + \let\next\relax + \else + \ifcsname \FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname + \expandafter\let\expandafter\FV@Line@Buffer + \csname\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname + \expandafter\VerbatimInsertBuffer@def@FV@Line\expandafter{\FV@Line@Buffer}% + \def\next{\FV@PreProcessLine\FV@GetLine}% + \stepcounter{FancyVerbBufferIndex}% + \else + \def\next{% + \PackageError{fvextra}% + {Buffer with line macro named + "\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}" does not exist}% + {Check bufferlinename, bufferlengthname, and globalbuffer settings}% + }% + \fi + \fi + \next}% + \FVB@Verbatim + \FVE@Verbatim + \setcounter{FancyVerbBufferIndex}{0}% + \endgroup} +% \end{macrocode} +% \end{macro} +% +% +% % % \subsection{Patches} % \label{sec:impl:patches} @@ -3695,7 +4174,7 @@ % \begin{macrocode} \def\FV@Command#1#2{% \FVExtra@ifstarVArg - {\def\FV@KeyValues{#1,showspaces}\FV@@Command{#2}}% + {\def\FV@KeyValues{#1,showspaces,showtabs}\FV@@Command{#2}}% {\def\FV@KeyValues{#1}\FV@@Command{#2}}} % \end{macrocode} % \end{macro} @@ -3745,9 +4224,15 @@ %\begin{verbatim} %{\catcode`\ =12 \gdef\FancyVerbSpace{\tt }} %\end{verbatim} -% The command is redefined in more robust and standard \LaTeX\ form. +% |\textvisiblespace| is not an alternative because it does not have the correct width. The redefinition follows \url{https://tex.stackexchange.com/a/120231/10742}. % \begin{macrocode} -\def\FancyVerbSpace{\textvisiblespace} +\def\FancyVerbSpace{% + \makebox[0.5em]{% + \kern.07em + \vrule height.3ex + \hrulefill + \vrule height.3ex + \kern.07em}} % \end{macrocode} % \end{macro} % @@ -4128,8 +4613,20 @@ % \end{macro} % % +% \begin{macro}{showspaces, FV@showspaces} +% Reimplement |showspaces| with a bool to work with new space options. +% \begin{macrocode} +\newbool{FV@showspaces} +\define@booleankey{FV}{showspaces}% + {\booltrue{FV@showspaces}}% + {\boolfalse{FV@showspaces}} +\fvset{showspaces=false} +% \end{macrocode} +% \end{macro} +% +% % \begin{macro}{space} -% Redefine |\FancyVerbSpace|. +% Redefine |\FancyVerbSpace|, which is the visible space. % \begin{macrocode} \define@key{FV}{space}{\def\FancyVerbSpace{#1}} % \end{macrocode} @@ -4145,21 +4642,73 @@ {\ifstrequal{#1}{none}% {\let\FV@SpaceColor\relax}% {\def\FV@SpaceColor{\textcolor{#1}}}}} -\define@booleankey{FV}{showspaces}% - {\def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}}}% - {\def\FV@Space{\ }} -\fvset{spacecolor=none, showspaces=false} +\fvset{spacecolor=none} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{spacebreak, \FancyVerbSpaceBreak} +% Line break for spaces that is inserted when spaces are visible (|showspaces=true|) or when breaks around spaces are handled specially (|breakcollapsespaces=false|). Not used for regular spaces under default conditions. +% \begin{macrocode} +\define@key{FV}{spacebreak}{% + \def\FancyVerbSpaceBreak{#1}} +\fvset{spacebreak=\discretionary{}{}{}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{breakcollapsespaces, FV@breakcollapsespaces} +% When a line break occurs within a sequence of regular space characters (|showspaces=false|), collapse the spaces into a single space and then replace it with the break. When this is |true|, a sequence of spaces will cause at most a single line break, and the first character on the wrapped line after the break will be a non-space character. When this is |false|, a sequence of spaces may result in multiple line breaks. Each wrapped line besides the last will contain only spaces. The final wrapped line may contain leading spaces before any non-space character(s). +% \begin{macrocode} +\newbool{FV@breakcollapsespaces} +\define@booleankey{FV}{breakcollapsespaces}% + {\booltrue{FV@breakcollapsespaces}}% + {\boolfalse{FV@breakcollapsespaces}}% +\fvset{breakcollapsespaces=true} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\FV@DefFVSpace} +% Redefine |\FV@Space| based on \pkg{fvextra} options that affect spaces. +% +% This must be added to |\FV@FormattingPrep@PreHook|, but only after |breakbefore| and |breakafter| macros are defined. Hence the |\AtEndOfPackage|. +% \begin{macrocode} +\def\FV@DefFVSpace{% + \ifbool{FV@showspaces}% + {\ifbool{FV@breaklines}% + {\ifcsname FV@BreakBefore@Token\FV@SpaceCatTen\endcsname + \def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}}% + \else\ifcsname FV@BreakAfter@Token\FV@SpaceCatTen\endcsname + \def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}}% + \else + \def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}\FancyVerbSpaceBreak}% + \fi\fi}% + {\def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}}}}% + {\ifbool{FV@breaklines}% + {\ifcsname FV@BreakBefore@Token\FV@SpaceCatTen\endcsname + \def\FV@Space{\mbox{\FV@SpaceCatTen}}% + \else\ifcsname FV@BreakAfter@Token\FV@SpaceCatTen\endcsname + \def\FV@Space{\mbox{\FV@SpaceCatTen}}% + \else + \ifbool{FV@breakcollapsespaces}% + {\def\FV@Space{\FV@SpaceCatTen}}% + {\def\FV@Space{\mbox{\FV@SpaceCatTen}\FancyVerbSpaceBreak}}% + \fi\fi}% + {\def\FV@Space{\FV@SpaceCatTen}}}}% +\AtEndOfPackage{% + \g@addto@macro\FV@FormattingPrep@PreHook{\FV@DefFVSpace}} % \end{macrocode} % \end{macro} % % % \begin{macro}{mathescape} -% Give |$|, |^|, and |_| their normal catcodes to allow normal typeset math. +% Give |$|, |&|, |^|, and |_| their normal catcodes to allow normal typeset math. % \begin{macrocode} \define@booleankey{FV}{mathescape}% {\let\FancyVerbMathEscape\FV@MathEscape}% {\let\FancyVerbMathEscape\relax} -\def\FV@MathEscape{\catcode`\$=3\catcode`\^=7\catcode`\_=8\relax} +\def\FV@MathEscape{\catcode`\$=3\catcode`\&=4\catcode`\^=7\catcode`\_=8\relax} \FV@AddToHook\FV@CatCodesHook\FancyVerbMathEscape \fvset{mathescape=false} % \end{macrocode} @@ -4728,7 +5277,7 @@ \ifx\directlua\relax \else \FV@AddToHook\FV@FormattingPrep@PreHook\FV@BreakLinesLuaTeXHook - \fi + \fi \fi % \end{macrocode} % \end{macro} @@ -4932,8 +5481,9 @@ % \end{macrocode} % \end{macro} % +% % \begin{macro}{FV@breakanywhere} -% Allow line breaking (almost) anywhere. Set |\FV@Break| and |\FV@EndBreak| to be used, and |\let| |\FV@Break@Token| to the appropriate macro. +% Allow line breaking (almost) anywhere. Set |\FV@Break| and |\FV@EndBreak| to be used, and |\let| |\FV@Break@DefaultToken| to the appropriate macro. % \begin{macrocode} \newbool{FV@breakanywhere} \define@booleankey{FV}{breakanywhere}% @@ -5352,7 +5902,7 @@ % % For \pkg{fvextra}'s standard scanning: If this is the main buffer (depth 0), stop scanning---which ultimately allows |\FV@BreakBuffer| to be handled by |\FV@InsertBreaks|. For user macros: Insert |\FV@BreakBuffer| at buffer depth 0. Otherwise for both cases: Append the current buffer to the previous buffer, and continue scanning. % -% An intermediate |\FV@BreakBufferStop@i| is used to optimize |\ifx| comparisons for |\FV@BreakBufferStop| during scanning. +% An intermediate |\FV@BreakBufferStop@i| is used to optimize |\ifx| comparisons for |\FV@BreakBufferStop| during scanning. % \begin{macrocode} \def\FV@BreakBufferStop{% \FV@BreakBufferStop@i} @@ -5509,7 +6059,7 @@ % \begin{macrocode} \def\FV@Break@NBToken#1{% \FV@BreakBuffer@Append{#1}% - \let\FV@Break@LastToken=\FV@Undefined + \let\FV@LastToken=\FV@Undefined \FV@Break@Scan} % \end{macrocode} % \end{macro} @@ -5537,8 +6087,21 @@ % % \begin{macrocode} \def\FV@Break@AnyToken#1{% - \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}% - \FV@Break@Scan} + \ifx\FV@FVSpaceToken#1\relax + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\let\FV@LastToken=#1\FV@BreakBuffer@Append{#1}\FV@Break@Scan}% + {\ifx\FV@LastToken\FV@FVSpaceToken + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\let\FV@LastToken=#1% + \FV@BreakBuffer@Append{#1}\FV@Break@Scan}% + {\let\FV@LastToken=#1% + \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}\FV@Break@Scan}}} % \end{macrocode} % \end{macro} % @@ -5568,11 +6131,19 @@ \def\FV@Break@BeforeTokenBreak#1{% \ifbool{FV@breakbeforeinrun}% {\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \fi \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan \def\FV@RescanToken{#1}% \else - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak#1}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \fi \let\FV@Break@Next\FV@Break@Scan \let\FV@LastToken=#1% \fi}% @@ -5587,11 +6158,19 @@ \fi \else \ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \fi \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan \def\FV@RescanToken{#1}% \else - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak#1}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \fi \let\FV@Break@Next\FV@Break@Scan \let\FV@LastToken=#1% \fi @@ -5602,32 +6181,58 @@ \def\FV@Break@AfterTokenBreak#1{% \let\FV@LastToken=#1% \@ifnextchar\FV@FVSpaceToken% - {\FV@BreakBuffer@Append{#1}\FV@Break@Scan}% - {\ifbool{FV@breakafterinrun}% - {\FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% - \let\FV@Break@Next\FV@Break@Scan}% - {\ifx\@let@token#1\relax + {\ifx#1\FV@FVSpaceToken + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\FV@Break@AfterTokenBreak@i{#1}}% + {\FV@BreakBuffer@Append{#1}% + \FV@Break@Scan}}% + {\FV@Break@AfterTokenBreak@i{#1}}} +\def\FV@Break@AfterTokenBreak@i#1{% + \ifbool{FV@breakafterinrun}% + {\ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{#1\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% + \fi + \let\FV@Break@Next\FV@Break@Scan}% + {\ifx\@let@token#1\relax + \FV@BreakBuffer@Append{#1}% + \let\FV@Break@Next\FV@Break@Scan + \else + \expandafter\ifx\csname @let@token\endcsname\bgroup\relax \FV@BreakBuffer@Append{#1}% - \let\FV@Break@Next\FV@Break@Scan + \let\FV@Break@Next\FV@Break@AfterTokenBreak@Group \else - \expandafter\ifx\csname @let@token\endcsname\bgroup\relax - \FV@BreakBuffer@Append{#1}% - \let\FV@Break@Next\FV@Break@AfterTokenBreak@Group + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{#1\FancyVerbSpaceBreak}% \else \FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% - \let\FV@Break@Next\FV@Break@Scan \fi - \fi}% - \FV@Break@Next}% + \let\FV@Break@Next\FV@Break@Scan + \fi + \fi}% + \FV@Break@Next } \def\FV@Break@AfterTokenBreak@Group#1{% \ifstrempty{#1}% {\FV@BreakBuffer@Append{{}}% \@ifnextchar\FV@LastToken% {\FV@Break@Scan}% - {\FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + {\ifx\FV@LastToken\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi \FV@Break@Scan}}% - {\FV@Break@Group{#1}}} + {\ifx\FV@LastToken\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi + \FV@Break@Group{#1}}} % \end{macrocode} % \end{macro} % @@ -5744,8 +6349,23 @@ \FV@Break@Next{#1}% } \def\FV@Break@AnyToken@UTF@i#1{% - \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}% - \FV@Break@Scan} + \def\FV@CurrentToken{#1}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken\relax + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\let\FV@LastToken\FV@CurrentToken + \FV@BreakBuffer@Append{#1}\FV@Break@Scan}% + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\let\FV@LastToken\FV@CurrentToken + \FV@BreakBuffer@Append{#1}\FV@Break@Scan}% + {\let\FV@LastToken\FV@CurrentToken + \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}\FV@Break@Scan}}} % \end{macrocode} % \end{macro} % @@ -5783,11 +6403,19 @@ \def\FV@CurrentToken{#1}% \ifbool{FV@breakbeforeinrun}% {\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \fi \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan@UTF \def\FV@RescanToken{#1}% \else - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak#1}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \fi \let\FV@Break@Next\FV@Break@Scan \def\FV@LastToken{#1}% \fi}% @@ -5802,11 +6430,19 @@ \fi \else \ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \fi \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan@UTF \def\FV@RescanToken{#1}% \else - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak#1}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \fi \let\FV@Break@Next\FV@Break@Scan \def\FV@LastToken{#1}% \fi @@ -5817,27 +6453,43 @@ \def\FV@Break@AfterTokenBreak@UTF#1{% \def\FV@LastToken{#1}% \@ifnextchar\FV@FVSpaceToken% - {\FV@BreakBuffer@Append{#1}\FV@Break@Scan}% - {\ifbool{FV@breakafterinrun}% - {\FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% - \let\FV@Break@Next\FV@Break@Scan}% + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\FV@Break@AfterTokenBreak@UTF@i{#1}}% {\FV@BreakBuffer@Append{#1}% - \ifx\@let@token\bgroup\relax - \let\FV@Break@Next\FV@Break@AfterTokenBreak@Group@UTF - \else - \let\FV@Break@Next\FV@Break@AfterTokenBreak@UTF@i - \fi}% - \FV@Break@Next}% -} + \FV@Break@Scan}}% + {\FV@Break@AfterTokenBreak@UTF@i{#1}}} \def\FV@Break@AfterTokenBreak@UTF@i#1{% + \ifbool{FV@breakafterinrun}% + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{#1\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% + \fi + \let\FV@Break@Next\FV@Break@Scan}% + {\FV@BreakBuffer@Append{#1}% + \expandafter\ifx\csname @let@token\endcsname\bgroup\relax + \let\FV@Break@Next\FV@Break@AfterTokenBreak@Group@UTF + \else + \let\FV@Break@Next\FV@Break@AfterTokenBreak@UTF@ii + \fi}% + \FV@Break@Next} +\def\FV@Break@AfterTokenBreak@UTF@ii#1{% \ifcsname FV@U8:\detokenize{#1}\endcsname \expandafter\let\expandafter\FV@Break@Next\csname FV@U8:\detokenize{#1}\endcsname - \let\FV@UTF@octets@after\FV@Break@AfterTokenBreak@UTF@i + \let\FV@UTF@octets@after\FV@Break@AfterTokenBreak@UTF@ii \else \def\FV@NextToken{#1}% \ifx\FV@LastToken\FV@NextToken \else - \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi \fi \let\FV@Break@Next\FV@Break@Scan \fi @@ -5846,9 +6498,19 @@ \ifstrempty{#1}% {\FV@BreakBuffer@Append{{}}% \@ifnextchar\bgroup - {\FV@Break@Group}% + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi + \FV@Break@Group}% {\FV@Break@AfterTokenBreak@Group@UTF@i}}% - {\FV@Break@Group{#1}}} + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi + \FV@Break@Group{#1}}} \def\FV@Break@AfterTokenBreak@Group@UTF@i#1{% \ifcsname FV@U8:\detokenize{#1}\endcsname \expandafter\let\expandafter\FV@Break@Next\csname FV@U8:\detokenize{#1}\endcsname @@ -5857,7 +6519,11 @@ \def\FV@NextToken{#1}% \ifx\FV@LastToken\FV@NextToken \else - \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi \fi \let\FV@Break@Next\FV@Break@Scan \fi diff --git a/Master/texmf-dist/tex/latex/fvextra/fvextra.sty b/Master/texmf-dist/tex/latex/fvextra/fvextra.sty index 93f61af57a0..c28d864ad41 100644 --- a/Master/texmf-dist/tex/latex/fvextra/fvextra.sty +++ b/Master/texmf-dist/tex/latex/fvextra/fvextra.sty @@ -20,7 +20,7 @@ %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{fvextra} - [2022/11/30 v1.5 fvextra - extensions and patches for fancyvrb] + [2023/11/19 v1.6 fvextra - extensions and patches for fancyvrb] \RequirePackage{etoolbox} \RequirePackage{fancyvrb} \RequirePackage{upquote} @@ -34,6 +34,11 @@ \@ifpackageloaded{csquotes}% {\PackageWarning{fvextra}{csquotes should be loaded after fvextra, % to avoid a warning from the lineno package}}{} +\begingroup +\catcode`\ =\active% +\gdef\FV@ActiveSpaceToken{ }% +\endgroup% +\edef\FV@SpaceCatTen{\detokenize{ }} \def\FV@FVSpaceToken{\FV@Space} \def\FV@FVTabToken{\FV@Tab} \def\FVExtraDoSpecials{% @@ -1183,9 +1188,179 @@ \Verb[#1]{#2}% \expandafter\end\expandafter{\FV@EnvironName}} \def\endVerbEnv{\global\let\FV@EnvironName\relax} +\define@key{FV}{writefilehandle}{% + \FV@SetWrite#1\FV@Sentinel} +\def\FV@SetWrite#1#2\FV@Sentinel{% + \let\FancyVerbWriteFileHandle\relax + \if\relax\detokenize{#2}\relax + \let\FancyVerbWriteFileHandle#1\relax + \fi + \ifx\FancyVerbWriteFileHandle\relax + \PackageError{fvextra}% + {Missing or invalid file handle for write}% + {Need file handle from \string\newwrite}% + \fi} +\let\FancyVerbWriteFileHandle\relax +\define@key{FV}{writer}{% + \let\FV@Writer#1\relax} +\def\FancyVerbDefaultWriter#1{% + \immediate\write\FancyVerbWriteFileHandle{\detokenize{#1}}} +\fvset{writer=\FancyVerbDefaultWriter} +\newcounter{FancyVerbWriteLine} +\def\VerbatimWrite{% + \FV@Environment + {codes=,commandchars=none,commentchar=none,defineactive,% + gobble=0,formatcom=,firstline,lastline}% + {VerbatimWrite}} +\def\FVB@VerbatimWrite{% + \@bsphack + \begingroup + \setcounter{FancyVerbWriteLine}{0}% + \let\c@FancyVerbLine\c@FancyVerbWriteLine + \FV@UseKeyValues + \FV@DefineWhiteSpace + \def\FV@Space{\space}% + \FV@DefineTabOut + \let\FV@ProcessLine\FV@Writer + \let\FV@FontScanPrep\relax + \let\@noligs\relax + \FancyVerbDefineActive + \FancyVerbFormatCom + \FV@Scan} +\def\FVE@VerbatimWrite{% + \endgroup + \@esphack} +\def\endVerbatimWrite{\FVE@VerbatimWrite} +\define@key{FV}{afterbuffer}{% + \def\FV@afterbuffer{#1}} +\fvset{afterbuffer=} +\newcounter{FancyVerbBufferIndex} +\define@key{FV}{bufferer}{% + \let\FV@Bufferer=#1\relax} +\def\FancyVerbDefaultBufferer#1{% + \expandafter\xdef\csname\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname{% + \detokenize{#1}}} +\fvset{bufferer=\FancyVerbDefaultBufferer} +\define@key{FV}{bufferlengthname}{% + \ifcsname c@#1\endcsname + \else + \newcounter{#1}% + \fi + \def\FV@bufferlengthname{#1}} +\fvset{bufferlengthname=FancyVerbBufferLength} +\define@key{FV}{bufferlinename}{% + \def\FancyVerbBufferLineName{#1}} +\fvset{bufferlinename=FancyVerbBufferLine} +\define@key{FV}{buffername}{% + \fvset{bufferlengthname=#1length,bufferlinename=#1line}} +\newbool{FV@globalbuffer} +\define@booleankey{FV}{globalbuffer}% + {\booltrue{FV@globalbuffer}}% + {\boolfalse{FV@globalbuffer}} +\fvset{globalbuffer=false} +\newcounter{FancyVerbBufferLine} +\newcounter{FV@oldbufferlength} +\newbool{FV@globalbuffer@tmp} +\let\FV@bufferlengthname@tmp\relax +\let\FancyVerbBufferLineName@tmp\relax +\let\FV@afterbuffer@tmp\relax +\def\VerbatimBuffer{% + \FV@Environment + {codes=,commandchars=none,commentchar=none,defineactive,% + gobble=0,formatcom=,firstline,lastline}% + {VerbatimBuffer}} +\def\FVB@VerbatimBuffer{% + \@bsphack + \begingroup + \setcounter{FancyVerbBufferLine}{0}% + \let\c@FancyVerbLine\c@FancyVerbBufferLine + \setcounter{FancyVerbBufferIndex}{0}% + \setcounter{FV@oldbufferlength}{\expandafter\value\expandafter{\FV@bufferlengthname}}% + \expandafter\setcounter\expandafter{\FV@bufferlengthname}{0}% + \FV@UseKeyValues + \ifbool{FV@globalbuffer}% + {\global\booltrue{FV@globalbuffer@tmp}}% + {\global\boolfalse{FV@globalbuffer@tmp}}% + \global\let\FV@bufferlengthname@tmp\FV@bufferlengthname + \global\let\FancyVerbBufferLineName@tmp\FancyVerbBufferLineName + \global\let\FV@afterbuffer@tmp\FV@afterbuffer + \FV@DefineWhiteSpace + \def\FV@ProcessLine{\stepcounter{FancyVerbBufferIndex}\FV@Bufferer}% + \let\FV@FontScanPrep\relax + \let\@noligs\relax + \FancyVerbDefineActive + \FancyVerbFormatCom + \FV@Scan} +\def\FVE@VerbatimBuffer{% + \endgroup + \@esphack + \expandafter\setcounter\expandafter{\FV@bufferlengthname@tmp}% + {\value{FancyVerbBufferIndex}}% + \setcounter{FancyVerbBufferIndex}{0}% + \begingroup + \FV@afterbuffer@tmp + \endgroup + \ifbool{FV@globalbuffer@tmp}% + {}% + {\ifnum\value{FV@oldbufferlength}>% + \expandafter\value\expandafter{\FV@bufferlengthname@tmp}\relax + \expandafter\setcounter\expandafter{\FV@bufferlengthname@tmp}% + {\value{FV@oldbufferlength}}% + \fi + \loop\unless\ifnum\expandafter\value\expandafter{\FV@bufferlengthname@tmp}=0\relax + \expandafter\global\expandafter\let\csname + \FancyVerbBufferLineName@tmp + \expandafter\arabic\expandafter{\FV@bufferlengthname@tmp}% + \endcsname\FV@Undefined + \expandafter\addtocounter\expandafter{\FV@bufferlengthname@tmp}{-1}% + \repeat}} +\def\endVerbatimBuffer{\FVE@VerbatimBuffer} +\newcommand{\VerbatimInsertBuffer}[1][]{% + \begingroup + \def\FV@KeyValues{#1}% + \def\FV@Scan{% + \FV@CatCodes + \xdef\FV@EnvironName{Verbatim}% + \ifnum\expandafter\value\expandafter{\FV@bufferlengthname}=\z@\relax + \PackageError{fvextra}% + {Buffer length counter \FV@bufferlengthname\space is invalid or zero}% + {}% + \let\FV@GetLine\relax + \fi + \FV@GetLine}% + \let\FV@CheckScan\relax + \setcounter{FancyVerbBufferIndex}{1}% + \def\VerbatimInsertBuffer@def@FV@Line##1{% + \FVExtraRetokenizeVArg{\def\FV@Line}{}{##1}} + \def\FancyVerbGetLine{% + \ifnum\value{FancyVerbBufferIndex}>% + \expandafter\value\expandafter{\FV@bufferlengthname}\relax + \global\let\FV@EnvironName\relax + \let\next\relax + \else + \ifcsname \FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname + \expandafter\let\expandafter\FV@Line@Buffer + \csname\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}\endcsname + \expandafter\VerbatimInsertBuffer@def@FV@Line\expandafter{\FV@Line@Buffer}% + \def\next{\FV@PreProcessLine\FV@GetLine}% + \stepcounter{FancyVerbBufferIndex}% + \else + \def\next{% + \PackageError{fvextra}% + {Buffer with line macro named + "\FancyVerbBufferLineName\arabic{FancyVerbBufferIndex}" does not exist}% + {Check bufferlinename, bufferlengthname, and globalbuffer settings}% + }% + \fi + \fi + \next}% + \FVB@Verbatim + \FVE@Verbatim + \setcounter{FancyVerbBufferIndex}{0}% + \endgroup} \def\FV@Command#1#2{% \FVExtra@ifstarVArg - {\def\FV@KeyValues{#1,showspaces}\FV@@Command{#2}}% + {\def\FV@KeyValues{#1,showspaces,showtabs}\FV@@Command{#2}}% {\def\FV@KeyValues{#1}\FV@@Command{#2}}} \def\FV@@Command#1{% \FVExtra@ifnextcharVArg[% @@ -1210,7 +1385,13 @@ \expandafter\protected\expandafter\def\@tempc{\FV@Command{#4}{#3}}}% \expandafter\@tempb\@tempa}% {#1{#2}{\FV@Command{#4}{#3}}}}} -\def\FancyVerbSpace{\textvisiblespace} +\def\FancyVerbSpace{% + \makebox[0.5em]{% + \kern.07em + \vrule height.3ex + \hrulefill + \vrule height.3ex + \kern.07em}} \newcounter{FV@TrueTabGroupLevel} \def\FV@@ObeyTabs#1{% \let\FV@Space@Orig\FV@Space @@ -1383,6 +1564,11 @@ {\def\FV@TabChar{\FV@TabColor{\FancyVerbTab}}}% {\let\FV@TabChar\relax} \fvset{tabcolor=none, showtabs=false} +\newbool{FV@showspaces} +\define@booleankey{FV}{showspaces}% + {\booltrue{FV@showspaces}}% + {\boolfalse{FV@showspaces}} +\fvset{showspaces=false} \define@key{FV}{space}{\def\FancyVerbSpace{#1}} \define@key{FV}{spacecolor}% {\ifstrempty{#1}% @@ -1390,14 +1576,43 @@ {\ifstrequal{#1}{none}% {\let\FV@SpaceColor\relax}% {\def\FV@SpaceColor{\textcolor{#1}}}}} -\define@booleankey{FV}{showspaces}% - {\def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}}}% - {\def\FV@Space{\ }} -\fvset{spacecolor=none, showspaces=false} +\fvset{spacecolor=none} +\define@key{FV}{spacebreak}{% + \def\FancyVerbSpaceBreak{#1}} +\fvset{spacebreak=\discretionary{}{}{}} +\newbool{FV@breakcollapsespaces} +\define@booleankey{FV}{breakcollapsespaces}% + {\booltrue{FV@breakcollapsespaces}}% + {\boolfalse{FV@breakcollapsespaces}}% +\fvset{breakcollapsespaces=true} +\def\FV@DefFVSpace{% + \ifbool{FV@showspaces}% + {\ifbool{FV@breaklines}% + {\ifcsname FV@BreakBefore@Token\FV@SpaceCatTen\endcsname + \def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}}% + \else\ifcsname FV@BreakAfter@Token\FV@SpaceCatTen\endcsname + \def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}}% + \else + \def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}\FancyVerbSpaceBreak}% + \fi\fi}% + {\def\FV@Space{\FV@SpaceColor{\FancyVerbSpace}}}}% + {\ifbool{FV@breaklines}% + {\ifcsname FV@BreakBefore@Token\FV@SpaceCatTen\endcsname + \def\FV@Space{\mbox{\FV@SpaceCatTen}}% + \else\ifcsname FV@BreakAfter@Token\FV@SpaceCatTen\endcsname + \def\FV@Space{\mbox{\FV@SpaceCatTen}}% + \else + \ifbool{FV@breakcollapsespaces}% + {\def\FV@Space{\FV@SpaceCatTen}}% + {\def\FV@Space{\mbox{\FV@SpaceCatTen}\FancyVerbSpaceBreak}}% + \fi\fi}% + {\def\FV@Space{\FV@SpaceCatTen}}}}% +\AtEndOfPackage{% + \g@addto@macro\FV@FormattingPrep@PreHook{\FV@DefFVSpace}} \define@booleankey{FV}{mathescape}% {\let\FancyVerbMathEscape\FV@MathEscape}% {\let\FancyVerbMathEscape\relax} -\def\FV@MathEscape{\catcode`\$=3\catcode`\^=7\catcode`\_=8\relax} +\def\FV@MathEscape{\catcode`\$=3\catcode`\&=4\catcode`\^=7\catcode`\_=8\relax} \FV@AddToHook\FV@CatCodesHook\FancyVerbMathEscape \fvset{mathescape=false} \define@booleankey{FV}{beameroverlays}% @@ -2132,11 +2347,24 @@ \def\FV@Break@GroupTemplate#1{{#1}} \def\FV@Break@NBToken#1{% \FV@BreakBuffer@Append{#1}% - \let\FV@Break@LastToken=\FV@Undefined + \let\FV@LastToken=\FV@Undefined \FV@Break@Scan} \def\FV@Break@AnyToken#1{% - \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}% - \FV@Break@Scan} + \ifx\FV@FVSpaceToken#1\relax + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\let\FV@LastToken=#1\FV@BreakBuffer@Append{#1}\FV@Break@Scan}% + {\ifx\FV@LastToken\FV@FVSpaceToken + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\let\FV@LastToken=#1% + \FV@BreakBuffer@Append{#1}\FV@Break@Scan}% + {\let\FV@LastToken=#1% + \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}\FV@Break@Scan}}} \def\FV@Break@BeforeAfterToken#1{% \ifcsname FV@BreakBefore@Token\detokenize{#1}\endcsname \let\FV@Break@Next\FV@Break@BeforeTokenBreak @@ -2156,11 +2384,19 @@ \def\FV@Break@BeforeTokenBreak#1{% \ifbool{FV@breakbeforeinrun}% {\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \fi \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan \def\FV@RescanToken{#1}% \else - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak#1}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \fi \let\FV@Break@Next\FV@Break@Scan \let\FV@LastToken=#1% \fi}% @@ -2175,11 +2411,19 @@ \fi \else \ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \fi \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan \def\FV@RescanToken{#1}% \else - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak#1}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \fi \let\FV@Break@Next\FV@Break@Scan \let\FV@LastToken=#1% \fi @@ -2190,32 +2434,58 @@ \def\FV@Break@AfterTokenBreak#1{% \let\FV@LastToken=#1% \@ifnextchar\FV@FVSpaceToken% - {\FV@BreakBuffer@Append{#1}\FV@Break@Scan}% - {\ifbool{FV@breakafterinrun}% - {\FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% - \let\FV@Break@Next\FV@Break@Scan}% - {\ifx\@let@token#1\relax + {\ifx#1\FV@FVSpaceToken + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\FV@Break@AfterTokenBreak@i{#1}}% + {\FV@BreakBuffer@Append{#1}% + \FV@Break@Scan}}% + {\FV@Break@AfterTokenBreak@i{#1}}} +\def\FV@Break@AfterTokenBreak@i#1{% + \ifbool{FV@breakafterinrun}% + {\ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{#1\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% + \fi + \let\FV@Break@Next\FV@Break@Scan}% + {\ifx\@let@token#1\relax + \FV@BreakBuffer@Append{#1}% + \let\FV@Break@Next\FV@Break@Scan + \else + \expandafter\ifx\csname @let@token\endcsname\bgroup\relax \FV@BreakBuffer@Append{#1}% - \let\FV@Break@Next\FV@Break@Scan + \let\FV@Break@Next\FV@Break@AfterTokenBreak@Group \else - \expandafter\ifx\csname @let@token\endcsname\bgroup\relax - \FV@BreakBuffer@Append{#1}% - \let\FV@Break@Next\FV@Break@AfterTokenBreak@Group + \ifx#1\FV@FVSpaceToken + \FV@BreakBuffer@Append{#1\FancyVerbSpaceBreak}% \else \FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% - \let\FV@Break@Next\FV@Break@Scan \fi - \fi}% - \FV@Break@Next}% + \let\FV@Break@Next\FV@Break@Scan + \fi + \fi}% + \FV@Break@Next } \def\FV@Break@AfterTokenBreak@Group#1{% \ifstrempty{#1}% {\FV@BreakBuffer@Append{{}}% \@ifnextchar\FV@LastToken% {\FV@Break@Scan}% - {\FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + {\ifx\FV@LastToken\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi \FV@Break@Scan}}% - {\FV@Break@Group{#1}}} + {\ifx\FV@LastToken\FV@FVSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi + \FV@Break@Group{#1}}} \ifFV@pdfTeXinputenc \def\FV@BreakBeforePrep@UTF{% \ifx\FV@BreakBefore\@empty\relax @@ -2304,8 +2574,23 @@ \FV@Break@Next{#1}% } \def\FV@Break@AnyToken@UTF@i#1{% - \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}% - \FV@Break@Scan} + \def\FV@CurrentToken{#1}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken\relax + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\let\FV@LastToken\FV@CurrentToken + \FV@BreakBuffer@Append{#1}\FV@Break@Scan}% + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\let\FV@LastToken\FV@CurrentToken + \FV@BreakBuffer@Append{#1}\FV@Break@Scan}% + {\let\FV@LastToken\FV@CurrentToken + \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}\FV@Break@Scan}}} \def\FV@Break@BeforeAfterToken@UTF#1{% \ifcsname FV@U8:\detokenize{#1}\endcsname \expandafter\let\expandafter\FV@Break@Next\csname FV@U8:\detokenize{#1}\endcsname @@ -2335,11 +2620,19 @@ \def\FV@CurrentToken{#1}% \ifbool{FV@breakbeforeinrun}% {\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \fi \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan@UTF \def\FV@RescanToken{#1}% \else - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak#1}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \fi \let\FV@Break@Next\FV@Break@Scan \def\FV@LastToken{#1}% \fi}% @@ -2354,11 +2647,19 @@ \fi \else \ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}% + \fi \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan@UTF \def\FV@RescanToken{#1}% \else - \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \ifx\FV@CurrentToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak#1}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}% + \fi \let\FV@Break@Next\FV@Break@Scan \def\FV@LastToken{#1}% \fi @@ -2369,27 +2670,43 @@ \def\FV@Break@AfterTokenBreak@UTF#1{% \def\FV@LastToken{#1}% \@ifnextchar\FV@FVSpaceToken% - {\FV@BreakBuffer@Append{#1}\FV@Break@Scan}% - {\ifbool{FV@breakafterinrun}% - {\FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% - \let\FV@Break@Next\FV@Break@Scan}% + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\FV@Break@AfterTokenBreak@UTF@i{#1}}% {\FV@BreakBuffer@Append{#1}% - \ifx\@let@token\bgroup\relax - \let\FV@Break@Next\FV@Break@AfterTokenBreak@Group@UTF - \else - \let\FV@Break@Next\FV@Break@AfterTokenBreak@UTF@i - \fi}% - \FV@Break@Next}% -} + \FV@Break@Scan}}% + {\FV@Break@AfterTokenBreak@UTF@i{#1}}} \def\FV@Break@AfterTokenBreak@UTF@i#1{% + \ifbool{FV@breakafterinrun}% + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{#1\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}% + \fi + \let\FV@Break@Next\FV@Break@Scan}% + {\FV@BreakBuffer@Append{#1}% + \expandafter\ifx\csname @let@token\endcsname\bgroup\relax + \let\FV@Break@Next\FV@Break@AfterTokenBreak@Group@UTF + \else + \let\FV@Break@Next\FV@Break@AfterTokenBreak@UTF@ii + \fi}% + \FV@Break@Next} +\def\FV@Break@AfterTokenBreak@UTF@ii#1{% \ifcsname FV@U8:\detokenize{#1}\endcsname \expandafter\let\expandafter\FV@Break@Next\csname FV@U8:\detokenize{#1}\endcsname - \let\FV@UTF@octets@after\FV@Break@AfterTokenBreak@UTF@i + \let\FV@UTF@octets@after\FV@Break@AfterTokenBreak@UTF@ii \else \def\FV@NextToken{#1}% \ifx\FV@LastToken\FV@NextToken \else - \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi \fi \let\FV@Break@Next\FV@Break@Scan \fi @@ -2398,9 +2715,19 @@ \ifstrempty{#1}% {\FV@BreakBuffer@Append{{}}% \@ifnextchar\bgroup - {\FV@Break@Group}% + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi + \FV@Break@Group}% {\FV@Break@AfterTokenBreak@Group@UTF@i}}% - {\FV@Break@Group{#1}}} + {\ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi + \FV@Break@Group{#1}}} \def\FV@Break@AfterTokenBreak@Group@UTF@i#1{% \ifcsname FV@U8:\detokenize{#1}\endcsname \expandafter\let\expandafter\FV@Break@Next\csname FV@U8:\detokenize{#1}\endcsname @@ -2409,7 +2736,11 @@ \def\FV@NextToken{#1}% \ifx\FV@LastToken\FV@NextToken \else - \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \ifx\FV@LastToken\FV@ActiveSpaceToken + \FV@BreakBuffer@Append{\FancyVerbSpaceBreak}% + \else + \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}% + \fi \fi \let\FV@Break@Next\FV@Break@Scan \fi -- cgit v1.2.3