texlive[74460] Master/texmf-dist: fvextra (5mar25)

commits+karl at tug.org commits+karl at tug.org
Wed Mar 5 22:32:09 CET 2025


Revision: 74460
          https://tug.org/svn/texlive?view=revision&revision=74460
Author:   karl
Date:     2025-03-05 22:32:08 +0100 (Wed, 05 Mar 2025)
Log Message:
-----------
fvextra (5mar25)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/fvextra/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/fvextra/fvextra.pdf
    trunk/Master/texmf-dist/source/latex/fvextra/fvextra.dtx
    trunk/Master/texmf-dist/source/latex/fvextra/fvextra.ins
    trunk/Master/texmf-dist/tex/latex/fvextra/fvextra.sty

Modified: trunk/Master/texmf-dist/doc/latex/fvextra/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/fvextra/CHANGELOG.md	2025-03-05 21:31:58 UTC (rev 74459)
+++ trunk/Master/texmf-dist/doc/latex/fvextra/CHANGELOG.md	2025-03-05 21:32:08 UTC (rev 74460)
@@ -1,6 +1,25 @@
 # Changelog
 
 
+## v1.12.0 (2025/03/04)
+
+*  Added command `\IterateBuffer` for iterating over buffers and applying a
+   macro to each line.
+
+*  Added command `\BufferMdfivesum` that calculates the MD5 sum of the current
+   buffer.
+
+*  Added command `\WriteBuffer` that writes a buffer to file.  This is the
+   buffer equivalent of `VerbatimWrite`.
+
+*  Added new options for `\InsertBuffer`:  `wrapperenvname`, `wrapperenvopt`,
+   `wrapperenvarg`.  Improved implementation of `\InsertBuffer` to eliminate
+   temp macros.
+
+*  Optimized line breaking for very long lines (#28).
+
+
+
 ## v1.11.0 (2025/02/09)
 
 *  Added command `\InsertBuffer`.  This inserts an existing buffer created

Modified: trunk/Master/texmf-dist/doc/latex/fvextra/fvextra.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/fvextra/fvextra.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/fvextra/fvextra.dtx	2025-03-05 21:31:58 UTC (rev 74459)
+++ trunk/Master/texmf-dist/source/latex/fvextra/fvextra.dtx	2025-03-05 21:32:08 UTC (rev 74460)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2016-2024 by Geoffrey M. Poore <gpoore at gmail.com>
+% Copyright (C) 2016-2025 by Geoffrey M. Poore <gpoore at gmail.com>
 % ---------------------------------------------------------------------------
 % 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 @@
 %<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
 %<package>\ProvidesPackage{fvextra}
 %<*package>
-    [2025/02/09 v1.11.0 fvextra - extensions and patches for fancyvrb]
+    [2025/03/04 v1.12.0 fvextra - extensions and patches for fancyvrb]
 %</package>
 %
 %<*driver>
@@ -64,7 +64,7 @@
 
 \usepackage{environ}
 
-\usepackage{tcolorbox}
+\usepackage[many]{tcolorbox}
 \tcbuselibrary{listings}
 \tcbset{verbatim ignore percent}
 
@@ -217,40 +217,65 @@
  {\par}
 
 
+\CustomVerbatimEnvironment{VerbatimVerbatim}{Verbatim}{}
+\CustomVerbatimEnvironment{VerbatimVerbatimBuffer}{VerbatimBuffer}{}
+
 \newenvironment{example}
-  {\VerbatimEnvironment
-   \begin{VerbatimOut}[gobble=4]{example.out}}
-  {\end{VerbatimOut}%
-   \vspace{1ex}%
-   \setlength{\parindent}{0pt}%
-   \setlength{\fboxsep}{1em}%
-   \fcolorbox{DarkGreen}{white}{\begin{minipage}{0.5\linewidth}%
-     \VerbatimInput{example.out}%
-   \end{minipage}%
-   \hspace{0.025\linewidth}%
-   {\color{DarkGreen}\vrule}%
-   \hspace{0.025\linewidth}%
-   \begin{minipage}{0.4\linewidth}%
-     \input{example.out}%
-   \end{minipage}%
-   }\vspace{1ex}}
+ {\VerbatimEnvironment
+  \begin{VerbatimVerbatimBuffer}[
+    buffername=fvexample,
+    gobble=1,
+    afterbuffer={%
+      \vspace{1ex}%
+      \setlength{\parindent}{0pt}%
+      \setlength{\fboxsep}{1em}%
+      \fcolorbox{DarkGreen}{white}{%
+        \begin{minipage}{0.5\linewidth}%
+        \VerbatimInsertBuffer[buffername=fvexample]%
+        \end{minipage}%
+        \hspace{0.025\linewidth}%
+        {\color{DarkGreen}\vrule}%
+        \hspace{0.025\linewidth}%
+        \begin{minipage}{0.4\linewidth}%
+        \InsertBuffer[buffername=fvexample]%
+        \end{minipage}}%
+      \vspace{1ex}%
+    }]}
+  {\end{VerbatimVerbatimBuffer}}
 
 \newenvironment{longexample}
   {\VerbatimEnvironment
-   \begin{VerbatimOut}[gobble=4]{example.out}}
-  {\end{VerbatimOut}%
-   \vspace{1ex}%
-   \setlength{\parindent}{0pt}%
-   \setlength{\fboxsep}{1em}%
-   \fcolorbox{DarkGreen}{white}{\begin{minipage}{0.94\linewidth}%
-     \VerbatimInput{example.out}%
-     {\color{DarkGreen}\hrulefill}
-     \setlength{\fboxsep}{3pt}%
-     \input{example.out}%
-   \end{minipage}%
-   }\vspace{1ex}}
+   \begin{VerbatimVerbatimBuffer}[
+    buffername=fvexample,
+    gobble=1,
+    afterbuffer={%
+      \vspace{1ex}%
+      \setlength{\parindent}{0pt}%
+      \setlength{\fboxsep}{1em}%
+      \fcolorbox{DarkGreen}{white}{%
+        \begin{minipage}{0.94\linewidth}%
+        \VerbatimInsertBuffer[buffername=fvexample]%
+        {\color{DarkGreen}\hrulefill}%
+        \setlength{\fboxsep}{3pt}%
+        \InsertBuffer[buffername=fvexample]%
+        \end{minipage}}%
+      \vspace{1ex}%
+    }]}
+  {\end{VerbatimVerbatimBuffer}}
 
-\CustomVerbatimEnvironment{VerbatimVerbatim}{Verbatim}{}
+\newenvironment{tcbexample}
+ {\VerbatimEnvironment
+  \begin{VerbatimVerbatimBuffer}[
+    gobble=1,
+    buffername=tcbexample,
+    afterbuffer={
+      \begin{tcolorbox}[oversize=5em]
+      \VerbatimInsertBuffer[buffername=tcbexample]
+      \tcbline
+      \InsertBuffer[buffername=tcbexample]
+      \end{tcolorbox}
+    }]}
+ {\end{VerbatimVerbatimBuffer}}
 
 
 \edef\hashchar{\string#}
@@ -432,17 +457,17 @@
 % \item[curlyquotes (boolean) (false)]
 % Unlike \fancyvrb, \pkg{fvextra} requires the \pkg{upquote} package, so the backtick (\texttt{\textasciigrave}) and typewriter single quotation mark (\texttt{\textquotesingle}) always appear literally by default, instead of becoming the left and right curly single quotation marks (\texttt{`'}).  This option allows these characters to be replaced by the curly quotation marks when that is desirable.
 %
-% \begin{example}
-%   \begin{Verbatim}
-%   `quoted text'
-%   \end{Verbatim}
-% \end{example}
+%\begin{example}
+%\begin{Verbatim}
+%`quoted text'
+%\end{Verbatim}
+%\end{example}
 %
-% \begin{example}
-%   \begin{Verbatim}[curlyquotes]
-%   `quoted text'
-%   \end{Verbatim}
-% \end{example}
+%\begin{example}
+%\begin{Verbatim}[curlyquotes]
+%`quoted text'
+%\end{Verbatim}
+%\end{example}
 %
 %
 % \item[extra (boolean) (true)]
@@ -464,15 +489,15 @@
 %
 % \begingroup
 % \fvset{xleftmargin=2em}
-% \begin{longexample}
-%   \begin{Verbatim}[numbers=left, highlightlines={1, 3-4}]
-%   First line
-%   Second line
-%   Third line
-%   Fourth line
-%   Fifth line
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[numbers=left, highlightlines={1, 3-4}]
+%First line
+%Second line
+%Third line
+%Fourth line
+%Fifth line
+%\end{Verbatim}
+%\end{longexample}
 % \endgroup
 %
 % The actual highlighting is performed by a set of commands.  These may be customized for additional fine-tuning of highlighting.  See the default definition of |\FancyVerbHighlightLineFirst| as a starting point.
@@ -511,15 +536,15 @@
 %
 % \begingroup
 % \fvset{xleftmargin=2em}
-% \begin{longexample}
-%   \begin{Verbatim}[numbers=left, stepnumber=2,
-%                    numberfirstline]
-%   First line
-%   Second line
-%   Third line
-%   Fourth line
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[numbers=left, stepnumber=2,
+%                 numberfirstline]
+%First line
+%Second line
+%Third line
+%Fourth line
+%\end{Verbatim}
+%\end{longexample}
 % \endgroup
 %
 %
@@ -528,14 +553,14 @@
 %
 % \begingroup
 % \fvset{xleftmargin=1.5em, xrightmargin=1.5em}
-% \begin{example}
-%   \begin{Verbatim}[numbers=both]
-%   First line
-%   Second line
-%   Third line
-%   Fourth line
-%   \end{Verbatim}
-% \end{example}
+%\begin{example}
+%\begin{Verbatim}[numbers=both]
+%First line
+%Second line
+%Third line
+%Fourth line
+%\end{Verbatim}
+%\end{example}
 % \endgroup
 %
 %
@@ -556,12 +581,12 @@
 % \item[spacecolor (string) (none)]
 % Set the color of visible spaces.  By default (|none|), they take the color of their surroundings.
 %
-% \begin{longexample}
-%   \color{gray}
-%   \begin{Verbatim}[showspaces, spacecolor=red]
-%   One  two  three
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\color{gray}
+%\begin{Verbatim}[showspaces, spacecolor=red]
+%One  two  three
+%\end{Verbatim}
+%\end{longexample}
 %
 %
 % \item[stepnumberfromfirst (boolean) (false)]
@@ -569,15 +594,15 @@
 %
 % \begingroup
 % \fvset{xleftmargin=2em}
-% \begin{longexample}
-%   \begin{Verbatim}[numbers=left, stepnumber=2,
-%                    stepnumberfromfirst]
-%   First line
-%   Second line
-%   Third line
-%   Fourth line
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[numbers=left, stepnumber=2,
+%                 stepnumberfromfirst]
+%First line
+%Second line
+%Third line
+%Fourth line
+%\end{Verbatim}
+%\end{longexample}
 % \endgroup
 %
 %
@@ -588,15 +613,15 @@
 %
 % \begingroup
 % \fvset{xleftmargin=2em}
-% \begin{longexample}
-%   \begin{Verbatim}[numbers=left, stepnumber=2,
-%                    firstnumber=4, stepnumberoffsetvalues]
-%   First line
-%   Second line
-%   Third line
-%   Fourth line
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[numbers=left, stepnumber=2,
+%                 firstnumber=4, stepnumberoffsetvalues]
+%First line
+%Second line
+%Third line
+%Fourth line
+%\end{Verbatim}
+%\end{longexample}
 % \endgroup
 %
 %
@@ -666,18 +691,17 @@
 % \fvextra\ introduces line breaking, which complicates line formatting.  We might want to apply formatting to the entire line, including line breaks, line continuation symbols, and all indentation, including any extra indentation provided by line breaking.  Or we might want to apply formatting only to the actual text of the line.  \fvextra\ leaves |\FancyVerbFormatLine| as applying to the entire line, and introduces a new command |\FancyVerbFormatText| that only applies to the text part of the line.\footnote{When |breaklines=true|, each line is wrapped in a |\parbox|.  |\FancyVerbFormatLine| is outside the |\parbox|, and |\FancyVerbFormatText| is inside.}   By default, |\FancyVerbFormatText| inserts the text unmodified.  When it is customized, it should not use boxes that do not allow line breaks to avoid conflicts with line breaking code.
 %
 % \begingroup
-% \let\originput\input
-% \renewcommand{\input}[1]{\fvset{xrightmargin=2em}\originput{#1}}
-% \begin{longexample}
-%   \renewcommand{\FancyVerbFormatLine}[1]{%
-%     \fcolorbox{DarkBlue}{LightGray}{#1}}
-%   \renewcommand{\FancyVerbFormatText}[1]{\textcolor{Green}{#1}}
+% \fvset{xrightmargin=2em}
+%\begin{longexample}
+%\renewcommand{\FancyVerbFormatLine}[1]{%
+%  \fcolorbox{DarkBlue}{LightGray}{#1}}
+%\renewcommand{\FancyVerbFormatText}[1]{\textcolor{Green}{#1}}
 %
-%   \begin{Verbatim}[breaklines]
-%   Some text that proceeds for a while and finally wraps onto another line
-%   Some more text
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{Verbatim}[breaklines]
+%Some text that proceeds for a while and finally wraps onto another line
+%Some more text
+%\end{Verbatim}
+%\end{longexample}
 % \endgroup
 %
 %
@@ -779,12 +803,12 @@
 %
 % While \cmd{VerbEnv} can be used by document authors, it is primarily intended for package creators.  For example, it is used in \pkg{minted} to implement \cmd{\mintinline}.  In that case, highlighted code is always generated within a \cmd{Verbatim} environment.  It is possible to process this as inline rather than block verbatim by \cmd{\let}ting \cmd{\Verbatim} to \cmd{\VerbEnv}.
 %
-% \begin{example}
-%   BEFORE\begin{VerbEnv}
-%   _inline_
-%   \end{VerbEnv}
-%   AFTER
-% \end{example}
+%\begin{example}
+%BEFORE\begin{VerbEnv}
+%_inline_
+%\end{VerbEnv}
+%AFTER
+%\end{example}
 %
 % \cmd{VerbEnv} is not implemented using the typical \fancyvrb\ environment implementation style, so it is not compatible with |\RecustomVerbatimEnvironment|.
 %
@@ -823,29 +847,28 @@
 % \end{optionlist}
 %
 %
-% \subsection{\cmd{VerbatimBuffer}}
+%
+% \subsection{Buffers}
+%
+% \subsubsection{\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.
+% 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 iterated  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.
+% Below is an extended example that demonstrates what is possible with |VerbatimBuffer| combined with various buffer commands.  This uses |\ifstrequal| 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 macro that is always available for buffer looping.  |\FancyVerbBufferLength| is the default macro containing the buffer length (number of lines).  |\FancyVerbBufferLineName| contains the base name for buffer line macros (default |FancyVerbBufferLine|).
+% \item |\setformatter| defines an empty |\formatter| macro.  Then it defines a |\lineprocessor| macro that takes a buffer line as an argument.  If this line contains only the text ``red'', then |\lineprocessor| redefines |\formatter| to |\color{red}| and invokes |\IterateBufferBreak| to stop iteration over the buffer.  Finally, |\IterateBuffer| is used to apply |\lineprocessor| to each line in the buffer, until the final line is reached or |\IterateBufferBreak| is invoked.
 % \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}
+%\begin{tcbexample}
 %\def\setformatter{%
 %  \def\formatter{}%
-%  \def\FancyVerbBufferIndex{1}%
-%  \loop\unless\ifnum\FancyVerbBufferIndex>\FancyVerbBufferLength\relax
-%    \expandafter\let\expandafter\bufferline
-%      \csname\FancyVerbBufferLineName\FancyVerbBufferIndex\endcsname
-%    \ifdefstring{\bufferline}{red}{\def\formatter{\color{red}}}{}%
-%    \edef\FancyVerbBufferIndex{\the\numexpr\FancyVerbBufferIndex+1\relax}%
-%  \repeat}
+%  \def\lineprocessor##1{%
+%    \ifstrequal{##1}{red}{\def\formatter{\color{red}}\IterateBufferBreak}{}}%
+%  \IterateBuffer{\lineprocessor}}
 %
 %\begin{VerbatimBuffer}[
 %  afterbuffer={\setformatter\VerbatimInsertBuffer[formatcom=\formatter]}
@@ -854,12 +877,12 @@
 %second
 %red
 %\end{VerbatimBuffer}
-%\end{tcblisting}
+%\end{tcbexample}
 %
-% Here is the same example, but rewritten to use a global buffer with custom buffer names instead.
+% Here is the same example, but rewritten to use a global buffer with custom buffer name instead.
 %
-%\begin{tcblisting}{oversize=5em}
-%\begin{VerbatimBuffer}[globalbuffer, bufferlinename=exbuff, bufferlengthname=exbufflen]
+%\begin{tcbexample}
+%\begin{VerbatimBuffer}[globalbuffer, buffername=exbuff]
 %first
 %second
 %red
@@ -866,20 +889,12 @@
 %\end{VerbatimBuffer}
 %
 %\def\formatter{}
-%\def\FancyVerbBufferIndex{1}
-%\loop\unless\ifnum\FancyVerbBufferIndex>\exbufflen\relax
-%  \expandafter\let\expandafter\bufferline
-%    \csname exbuff\FancyVerbBufferIndex\endcsname
-%  \ifdefstring{\bufferline}{red}{\def\formatter{\color{red}}}{}
-%  \edef\FancyVerbBufferIndex{\the\numexpr\FancyVerbBufferIndex+1\relax}
-%\repeat
+%\def\lineprocessor#1{%
+%  \ifstrequal{#1}{red}{\def\formatter{\color{red}}\IterateBufferBreak}{}}
+%\IterateBuffer[buffername=exbuff]{\lineprocessor}
 %
-%\VerbatimInsertBuffer[
-%  formatcom=\formatter,
-%  bufferlinename=exbuff,
-%  bufferlengthname=exbufflen
-%]
-%\end{tcblisting}
+%\VerbatimInsertBuffer[buffername=exbuff, formatcom=\formatter]
+%\end{tcbexample}
 %
 % ~
 %
@@ -889,7 +904,7 @@
 % \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 macro are still accessible even when |globalbuffer=false|.
 %
-% When |afterbuffer| is used to typeset the buffer, the typeset buffer may contain |VerbatimBuffer| or environments based on it.  Typically, nested buffering should be avoided for a given buffer; a different buffer should be used at each level of nesting.  Otherwise, for nested |VerbatimBuffer| environments, the buffer will contain the contents of the outermost |VerbatimBuffer| environment concatenated with the contents of nested environments.  
+% When |afterbuffer| is used to typeset the buffer, the typeset buffer may contain |VerbatimBuffer| or environments based on it.  Typically, nested buffering should be avoided for a given buffer; a different buffer should be used at each level of nesting.  Otherwise, for nested |VerbatimBuffer| environments, the buffer will contain the contents of the outermost |VerbatimBuffer| environment concatenated with the contents of nested environments.
 %
 % The current buffer depth is available in |\FancyVerbBufferDepth|.  This has a value of |0| outside of any |VerbatimBuffer| environments, a value of |1| within the outermost |VerbatimBuffer| environment, and so forth.  This can be used to automatically generate a unique |buffername| at a given nesting depth.
 %
@@ -933,7 +948,7 @@
 % \end{optionlist}
 %
 %
-% \subsection{\cmd{\VerbatimInsertBuffer}}
+% \subsubsection{\cmd{\VerbatimInsertBuffer}}
 % \DescribeMacro{\VerbatimInsertBuffer\oarg{options}}
 %
 % This inserts an existing buffer created by |VerbatimBuffer| as a verbatim environment.  The |Verbatim| environment is used by default, but this can be customized by setting |insertenvname|.  |\VerbatimInsertBuffer| modifies |Verbatim| and |BVerbatim| internals to function with a buffer in a command context.  See the |VerbatimBuffer| documentation for an example of usage.
@@ -951,18 +966,29 @@
 % \end{optionlist}
 %
 %
-% \subsection{\cmd{\VerbatimClearBuffer}}
+% \subsubsection{\cmd{\VerbatimClearBuffer}}
 % \DescribeMacro{\VerbatimClearBuffer\oarg{options}}
 %
 % Clear an existing buffer created with \cmd{VerbatimBuffer}.  |\global\let| all buffer line macros to an undefined macro and set the buffer length macro to zero.
 %
 %
-% \subsection{\cmd{\InsertBuffer}}
+% \subsubsection{\cmd{\InsertBuffer}}
 % \DescribeMacro{\InsertBuffer\oarg{options}}
-% This inserts an existing buffer created with |VerbatimBuffer| so that it is interpreted as \LaTeX.  The result is essentially the same as if the buffered text had been included literally at the insertion point.
+% This inserts an existing buffer created with |VerbatimBuffer| so that it is interpreted as \LaTeX.  The result is essentially the same as if the buffered text had been included literally at the insertion point.  The buffer is processed with |\scantokens|.
 %
-% Internally, this processes the buffer with |\scantokens|.  For typesetting verbatim text, |\VerbatimInsertBuffer| with the |insertenvname| option should typically be used instead of creating a buffer that begins/ends with a verbatim environment, and then using |\InsertBuffer| to typeset that buffer.  The implementation of |\VerbatimInsertBuffer| is significantly more efficient for purely verbatim content.
+% For typesetting verbatim text, |\InsertBuffer| with the |wrapperenv| option set to a verbatim environment can be used as an alternative to |\VerbatimInsertBuffer|.  Both typically have similar performance.
 %
+% \begin{optionlist}
+% \item[wrapperenvname (string) (\meta{none})]
+% Name of environment used to wrap the buffer.  This is inserted within the |\scantokens| that is used to process the buffer, so if |wrapperenvname| is set to a verbatim environment, then it will cause the buffer to be typeset verbatim.  This is useful for non-\pkg{fancyvrb} verbatim environments that are not supported by |\VerbatimInsertBuffer|.
+%
+% \item[wrapperenvopt (string) (\meta{none})]
+% Optional argument |[|\meta{opt}|]| passed to wrapper environment |wrapperenvname|.
+%
+% \item[wrapperenvarg (string) (\meta{none})]
+% Mandatory argument |{|\meta{arg}|}| passed to wrapper environment |wrapperenvname|.
+% \end{optionlist}
+%
 %\begin{tcblisting}{oversize=5em}
 %\begin{VerbatimBuffer}[buffername=ins, globalbuffer]
 %Text.  Math $f(x)$.  Verb \Verb|~#\{}|.
@@ -976,13 +1002,40 @@
 %\end{tcblisting}
 %
 %
-% \subsection{\cmd{\ClearBuffer}}
+% \subsubsection{\cmd{\ClearBuffer}}
 % \DescribeMacro{\ClearBuffer\oarg{options}}
 % Alias for \cmd{\VerbatimClearBuffer}.
 %
 %
+% \subsubsection{\cmd{\BufferMdfivesum}}
+% \DescribeMacro{\BufferMdfivesum}
+% Calculate the MD5 sum of the current buffer, using |\pdf at mdfivesum| from \pkg{pdftexcmds}.
 %
+% |\BufferMdfivesum| operates on the current buffer.  Because it is fully expandable, it cannot take an optional argument to switch buffers.  To switch buffers, use something like |\fvset{buffername=...}| before |\BufferMdfivesum|.
 %
+%\begin{tcblisting}{oversize=5em}
+%\begin{VerbatimBuffer}[afterbuffer=\xdef\bufferhash{\BufferMdfivesum}]
+%Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+%eiusmod tempor incididunt ut labore et dolore magna aliqua.
+%\end{VerbatimBuffer}
+%
+%\texttt{\bufferhash}
+%\end{tcblisting}
+%
+%
+% \subsubsection{\cmd{\IterateBuffer}}
+% \DescribeMacro{\IterateBuffer\oarg{options}\marg{macro}}
+%
+% \noindent Iterate over buffer from beginning to end, invoking \meta{macro} on each line.  \meta{macro} must be a macro or sequence of macros that consumes a single brace-delimited argument, which is the current line in the buffer.  |\IterateBufferBreak| is available to break iteration immediately after the current \meta{macro} invocation completes.  During iteration, |\FancyVerbBufferLengthName|, |\FancyVerbBufferLineName|, and |\FancyVerbBufferIndex| can be used to access the name of the current buffer and index within it.
+%
+%
+% \subsubsection{\cmd{\WriteBuffer}}
+% \DescribeMacro{\WriteBuffer\oarg{options}}
+% This writes the current buffer to an external file, using the |writefilehandle| and |writer| options from |VerbatimWrite|.  It is the buffer equivalent of |VerbatimWrite|.
+%
+%
+%
+%
 % \section{Line breaking}
 % \label{sec:breaklines}
 %
@@ -1004,11 +1057,11 @@
 %
 % 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]
-%   some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[breaklines, breakafter=d]
+%some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
+%\end{Verbatim}
+%\end{longexample}
 %
 %
 % \item[breakafterinrun (boolean) (false)]
@@ -1028,11 +1081,11 @@
 %
 % 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]
-%   some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[breaklines, breakanywhere]
+%some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
+%\end{Verbatim}
+%\end{longexample}
 %
 %
 % \item[breakanywheresymbolpre (string) (\string\,\string\footnotesize\string\ensuremath\{\_\string\rfloor\}, \,\footnotesize\ensuremath{_\rfloor})]
@@ -1065,11 +1118,11 @@
 %
 % 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]
-%   some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[breaklines, breakbefore=A]
+%some_string = 'SomeTextThatGoesOnAndOnForSoLongThatItCouldNeverFitOnOneLine'
+%\end{Verbatim}
+%\end{longexample}
 %
 %
 % \item[breakbeforeinrun (boolean) (false)]
@@ -1104,13 +1157,13 @@
 %
 % 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.
-%   \begin{Verbatim}[breaklines]
-%   def f(x):
-%       return 'Some text ' + str(x)
-%   \end{Verbatim}
-% \end{example}
+%\begin{example}
+%...text.
+%\begin{Verbatim}[breaklines]
+%def f(x):
+%    return 'Some text ' + str(x)
+%\end{Verbatim}
+%\end{example}
 %
 % To customize the indentation of broken lines, see |breakindent| and |breakautoindent|.  To customize the line continuation symbols, use |breaksymbolleft| and |breaksymbolright|.  To customize the separation between the continuation symbols and the text, use |breaksymbolsepleft| and |breaksymbolsepright|.  To customize the extra indentation that is supplied to make room for the break symbols, use |breaksymbolindentleft| and |breaksymbolindentright|.  Since only the left-hand symbol is used by default, it may also be modified using the alias options |breaksymbol|, |breaksymbolsep|, and |breaksymbolindent|.
 %
@@ -1118,29 +1171,29 @@
 %
 % \begingroup
 % \fvset{breaklines, xleftmargin=1em, xrightmargin=1em}
-% \begin{longexample}
-%   \begin{Verbatim}[breaklines,
-%                    breakautoindent=false,
-%                    breaksymbolleft=\raisebox{0.8ex}{
-%                      \small\reflectbox{\carriagereturn}},
-%                    breaksymbolindentleft=0pt,
-%                    breaksymbolsepleft=0pt,
-%                    breaksymbolright=\small\carriagereturn,
-%                    breaksymbolindentright=0pt,
-%                    breaksymbolsepright=0pt]
-%   def f(x):
-%       return 'Some text ' + str(x) + ' some more text ' + str(x) + ' even more text that goes on for a while'
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[breaklines,
+%                 breakautoindent=false,
+%                 breaksymbolleft=\raisebox{0.8ex}{
+%                   \small\reflectbox{\carriagereturn}},
+%                 breaksymbolindentleft=0pt,
+%                 breaksymbolsepleft=0pt,
+%                 breaksymbolright=\small\carriagereturn,
+%                 breaksymbolindentright=0pt,
+%                 breaksymbolsepright=0pt]
+%def f(x):
+%    return 'Some text ' + str(x) + ' some more text ' + str(x) + ' even more text that goes on for a while'
+%\end{Verbatim}
+%\end{longexample}
 % \endgroup
 %
 % 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]
-%   some_string = 'Some Text That Goes On And On For So Long That It Could Never Fit'
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\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)]
@@ -1296,11 +1349,11 @@
 % Then you would discover that line breaking does not occur:
 %
 % \newcommand{\mycmd}[1]{\_before:#1:after\_}
-% \begin{longexample}
-%   \begin{Verbatim}[commandchars=\\\{\}, breaklines, breakafter=a]
-%   \mycmd{1}\mycmd{2}\mycmd{3}\mycmd{4}\mycmd{5}
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[commandchars=\\\{\}, breaklines, breakafter=a]
+%\mycmd{1}\mycmd{2}\mycmd{3}\mycmd{4}\mycmd{5}
+%\end{Verbatim}
+%\end{longexample}
 %
 % Now redefine the macro:
 %\begin{verbatim}
@@ -1310,11 +1363,11 @@
 % This is the result:
 %
 % \renewcommand{\mycmd}[1]{\FancyVerbBreakStart\_before:#1:after\_\FancyVerbBreakStop}
-% \begin{longexample}
-%   \begin{Verbatim}[commandchars=\\\{\}, breaklines, breakafter=a]
-%   \mycmd{1}\mycmd{2}\mycmd{3}\mycmd{4}\mycmd{5}
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[commandchars=\\\{\}, breaklines, breakafter=a]
+%\mycmd{1}\mycmd{2}\mycmd{3}\mycmd{4}\mycmd{5}
+%\end{Verbatim}
+%\end{longexample}
 %
 % Instead of completely redefining macros, it may be more convenient to use |\let|.  For example,
 %\begin{verbatim}
@@ -1457,11 +1510,11 @@
 % \let\FancyVerbMathSpace\FV at Space
 % \makeatother
 % \renewcommand*{\familydefault}{\ttdefault}
-% \begin{longexample}
-%   \begin{Verbatim}[commandchars=\\\{\}, mathescape]
-%   Verbatim $\displaystyle\frac{1}{  x^2    +    y^2  }$ verbatim
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[commandchars=\\\{\}, mathescape]
+%Verbatim $\displaystyle\frac{1}{  x^2    +    y^2  }$ verbatim
+%\end{Verbatim}
+%\end{longexample}
 % \endgroup
 %
 % \fvextra\ patches this by redefining \fancyvrb's space character within math mode so that it behaves as expected:
@@ -1480,11 +1533,11 @@
 %
 % The result of these modifications is a math mode that very closely mimics the behavior of normal math mode outside of verbatim material.
 %
-% \begin{longexample}
-%   \begin{Verbatim}[commandchars=\\\{\}, mathescape]
-%   Verbatim $\displaystyle f'''(x) = \text{``Some quoted text---''}$
-%   \end{Verbatim}
-% \end{longexample}
+%\begin{longexample}
+%\begin{Verbatim}[commandchars=\\\{\}, mathescape]
+%Verbatim $\displaystyle f'''(x) = \text{``Some quoted text---''}$
+%\end{Verbatim}
+%\end{longexample}
 %
 %
 %
@@ -1587,6 +1640,7 @@
 %    \begin{macrocode}
 \RequirePackage{etoolbox}
 \RequirePackage{fancyvrb}
+\RequirePackage{pdftexcmds}
 \RequirePackage{upquote}
 \AtEndPreamble{%
   \ifx\encodingdefault\upquote at OTone
@@ -4249,7 +4303,7 @@
   \xdef\FV at EnvironName{\FV at VerbatimInsertEnvName}%
   \ifnum\FV at bufferlengthmacro=\z@\relax
     \PackageError{fvextra}%
-     {Buffer length macro \expandafter\string\FV at bufferlengthmacro\space 
+     {Buffer length macro \expandafter\string\FV at bufferlengthmacro\space
       is invalid or zero}%
      {}%
     \let\FV at GetLine\relax
@@ -4327,18 +4381,33 @@
 %
 %
 % \subsubsection{\cmd{\InsertBuffer}}
-% \begin{macro}{\InsertBuffer}
+% \begin{macro}{\InsertBuffer, wrapperenvname, wrapperenvopt, wrapperenvarg}
 % This inserts an existing buffer created with |VerbatimBuffer| so that it is interpreted as \LaTeX.  The result is essentially the same as if the buffered text had been included literally at the insertion point.
 %    \begin{macrocode}
+\define at key{FV}{wrapperenvname}{%
+  \def\FV at WrapperEnvName{#1}%
+  \ifx\FV at WrapperEnvName\@empty
+    \let\FV at WrapperEnvName\relax
+  \fi}
+\fvset{wrapperenvname=}
+\define at key{FV}{wrapperenvopt}{%
+  \def\FV at WrapperEnvOpt{#1}%
+  \ifx\FV at WrapperEnvOpt\@empty
+    \let\FV at WrapperEnvOpt\relax
+  \fi}
+\fvset{wrapperenvopt=}
+\define at key{FV}{wrapperenvarg}{%
+  \def\FV at WrapperEnvArg{#1}%
+  \ifx\FV at WrapperEnvArg\@empty
+    \let\FV at WrapperEnvArg\relax
+  \fi}
+\fvset{wrapperenvarg=}
 \newcommand{\InsertBuffer}[1][]{%
   \begingroup
   \def\FV at KeyValues{#1}%
   \FV at UseKeyValues
-  \global\let\FV at tmpbufferlengthmacro\FV at bufferlengthmacro
-  \global\let\FV at tmpbufferlinename\FancyVerbBufferLineName
-  \endgroup
-  \ifnum\FV at tmpbufferlengthmacro<1
-    \expandafter\@gobble
+  \ifnum\FV at bufferlengthmacro<1
+    \expandafter\endgroup\expandafter\@gobble
   \else
     \expandafter\@firstofone
   \fi
@@ -4345,23 +4414,40 @@
   \InsertBuffer at i}
 \def\InsertBuffer at i{%
   \InsertBuffer at expandbuffer
-  \expandafter\InsertBuffer at cleanup\expandafter\scantokens\expandafter{%
-    \FV at expandedbuffer\unskip\noexpand}\relax}
+  \expandafter\endgroup\expandafter\scantokens\expandafter{%
+    \FV at expandedbuffer\noexpand}\relax}
 \def\InsertBuffer at expandbuffer{%
-  \edef\FV at expandedbuffer{\InsertBuffer at expandbufferlines{1}}}
+  \edef\FV at expandedbuffer{%
+    \ifx\FV at WrapperEnvName\relax
+    \else
+      \unexpanded\expandafter\expandafter\expandafter{%
+        \expandafter\string\expandafter\begin\expandafter{\FV at WrapperEnvName}}%
+      \ifx\FV at WrapperEnvOpt\relax
+      \else
+        \unexpanded\expandafter{\expandafter[\FV at WrapperEnvOpt]}%
+      \fi
+      \ifx\FV at WrapperEnvArg\relax
+      \else
+        \unexpanded\expandafter{\expandafter{\FV at WrapperEnvArg}}%
+      \fi
+      \unexpanded{^^J}%
+    \fi
+    \InsertBuffer at expandbufferlines{1}%
+    \ifx\FV at WrapperEnvName\relax
+      \unskip
+    \else
+      \unexpanded\expandafter\expandafter\expandafter{%
+        \expandafter\string\expandafter\end\expandafter{\FV at WrapperEnvName}^^J}%
+    \fi}}
 \def\InsertBuffer at expandbufferlines#1{%
   \unexpanded\expandafter\expandafter\expandafter{%
-    \csname\FV at tmpbufferlinename#1\endcsname^^J}%
-  \ifnum\FV at tmpbufferlengthmacro=#1
+    \csname\FancyVerbBufferLineName#1\endcsname^^J}%
+  \ifnum\FV at bufferlengthmacro=#1
     \expandafter\@gobble
   \else
     \expandafter\@firstofone
   \fi
   {\expandafter\InsertBuffer at expandbufferlines\expandafter{\the\numexpr#1+1\relax}}}
-\def\InsertBuffer at cleanup{%
-  \global\let\FV at tmpbufferlengthmacro\FV at Undefined
-  \global\let\FV at tmpbufferlinename\FV at Undefined
-  \global\let\FV at expandedbuffer\FV at Undefined}
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4371,12 +4457,115 @@
 % Clear an existing buffer.  Alias for |\VerbatimClearBuffer|.
 %    \begin{macrocode}
 \let\ClearBuffer\VerbatimClearBuffer
-%    \end{macrocode} 
+%    \end{macrocode}
 % \end{macro}
 %
 %
+% \subsubsection{\cmd{\BufferMdfivesum}}
+% \begin{macro}{\BufferMdfivesum}
+% Calculate the MD5 sum of the current buffer.
+%    \begin{macrocode}
+\def\BufferMdfivesum{%
+  \pdf at mdfivesum{%
+    \ifnum\FV at bufferlengthmacro<1
+      \expandafter\@gobble
+    \else
+      \expandafter\@firstofone
+    \fi
+    {\BufferMdfivesum at i{1}}}}
+\def\BufferMdfivesum at i#1{%
+  \csname\FancyVerbBufferLineName#1\endcsname^^J%
+  \ifnum\FV at bufferlengthmacro=#1
+    \expandafter\@gobble
+  \else
+    \expandafter\@firstofone
+  \fi
+  {\expandafter\BufferMdfivesum at i\expandafter{\the\numexpr#1+1\relax}}}
+%    \end{macrocode}
+% \end{macro}
 %
 %
+% \subsubsection{\cmd{\IterateBuffer}, \cmd{\IterateBufferBreak}}
+% \begin{macro}{\IterateBuffer, \IterateBufferBreak}
+% Loop over buffer, applying a macro to each line.
+%    \begin{macrocode}
+\newcommand{\IterateBuffer}[2][]{%
+  \if\relax\detokenize{#1}\relax
+  \else
+    \let\FancyVerbBufferLengthName at beforeiter\FancyVerbBufferLengthName
+    \let\FV at bufferlengthmacro@beforeiter\FV at bufferlengthmacro
+    \let\FancyVerbBufferLineName at beforeiter\FancyVerbBufferLineName
+    \begingroup
+    \def\FV at KeyValues{#1}%
+    \FV at UseKeyValues
+    \global\let\FancyVerbBufferLengthName at iter\FancyVerbBufferLengthName
+    \global\let\FV at bufferlengthmacro@iter\FV at bufferlengthmacro
+    \global\let\FancyVerbBufferLineName at iter\FancyVerbBufferLineName
+    \endgroup
+    \let\FancyVerbBufferLengthName\FancyVerbBufferLengthName at iter
+    \let\FV at bufferlengthmacro\FV at bufferlengthmacro@iter
+    \let\FancyVerbBufferLineName\FancyVerbBufferLineName at iter
+    \global\let\FancyVerbBufferLengthName at iter\FV at Undefined
+    \global\let\FV at bufferlengthmacro@iter\FV at Undefined
+    \global\let\FancyVerbBufferLineName at iter\FV at Undefined
+  \fi
+  \gdef\FancyVerbBufferIndex{1}%
+  \def\FV at IterateBuffer@cmd{#2}%
+  \def\IterateBufferBreak{\xdef\FancyVerbBufferIndex{\FV at bufferlengthmacro}}%
+  \loop\unless\ifnum\FancyVerbBufferIndex>\FV at bufferlengthmacro\relax
+    \expandafter\let\expandafter\FV at IterateBuffer@line
+      \csname\FancyVerbBufferLineName\FancyVerbBufferIndex\endcsname
+    \expandafter\FV at IterateBuffer@cmd\expandafter{\FV at IterateBuffer@line}%
+    \xdef\FancyVerbBufferIndex{\the\numexpr\FancyVerbBufferIndex+1\relax}%
+  \repeat
+  \gdef\FancyVerbBufferIndex{0}%
+  \let\FV at IterateBuffer@cmd\FV at Undefined
+  \let\IterateBufferBreak\FV at Undefined
+  \let\FV at IterateBuffer@line\FV at Undefined
+  \if\relax\detokenize{#1}\relax
+  \else
+    \let\FancyVerbBufferLengthName\FancyVerbBufferLengthName at beforeiter
+    \let\FV at bufferlengthmacro\FV at bufferlengthmacro@beforeiter
+    \let\FancyVerbBufferLineName\FancyVerbBufferLineName at beforeiter
+    \let\FancyVerbBufferLengthName at beforeiter\FV at Undefined
+    \let\FV at bufferlengthmacro@beforeiter\FV at Undefined
+    \let\FancyVerbBufferLineName at beforeiter\FV at Undefined
+  \fi}
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\WriteBuffer}
+% Buffer equivalent of |VerbatimWrite|.
+%    \begin{macrocode}
+\def\WriteBuffer{%
+  \FV at Command{}{WriteBuffer}}
+\def\FVC at WriteBuffer{%
+  \@bsphack
+  \begingroup
+  \setcounter{FancyVerbWriteLine}{0}%
+  \let\c at FancyVerbLine\c at FancyVerbWriteLine
+  \FV at UseKeyValues
+  \FV at DefineWhiteSpace
+  \def\FV at Space{\space}%
+  \FV at DefineTabOut
+  \gdef\FancyVerbBufferIndex{1}%
+  \loop\unless\ifnum\FancyVerbBufferIndex>\FV at bufferlengthmacro\relax
+    \stepcounter{FancyVerbWriteLine}%
+    \expandafter\let\expandafter\FV at WriteBuffer@line
+      \csname\FancyVerbBufferLineName\FancyVerbBufferIndex\endcsname
+    \expandafter\FV at Writer\expandafter{\FV at WriteBuffer@line}%
+    \xdef\FancyVerbBufferIndex{\the\numexpr\FancyVerbBufferIndex+1\relax}%
+  \repeat
+  \gdef\FancyVerbBufferIndex{0}%
+  \endgroup
+  \@esphack} 
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
 % \subsection{Patches}
 % \label{sec:impl:patches}
 %
@@ -5325,7 +5514,7 @@
     \FancyVerbBackgroundColorVPhantom\strut
   \else
     \savebox{\FV at bgcolorstructbox}{\hbox{\FancyVerbBackgroundColorVPhantom\strut}}%
-    \vrule height \ht\FV at bgcolorstructbox 
+    \vrule height \ht\FV at bgcolorstructbox
            depth \dimexpr\dp\FV at bgcolorstructbox+\FV at backgroundcolorboxoverlap\relax
            width 0pt\relax
   \fi\fi}
@@ -7190,8 +7379,9 @@
     \let\FV at TrueTabSaveWidth\relax
   \fi
   \ifnum
-    \FV at iffp{\the\wd\FV at LineBox}>{\FV at LineWidth}{1}{0}% width greater than line
-    \FV at iffp{\the\wd\FV at LineBox}<{0}{1}{0}% width overflows
+    \FV at iffp{\the\wd\FV at LineBox}>{\FV at LineWidth}%
+     {1}% width greater than line
+     {\FV at iffp{\the\wd\FV at LineBox}<{0}{1}{0}}% width overflows
     >0
   \relax
     \setcounter{FancyVerbLineBreakLast}{0}%

Modified: trunk/Master/texmf-dist/source/latex/fvextra/fvextra.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/fvextra/fvextra.ins	2025-03-05 21:31:58 UTC (rev 74459)
+++ trunk/Master/texmf-dist/source/latex/fvextra/fvextra.ins	2025-03-05 21:32:08 UTC (rev 74460)
@@ -1,4 +1,4 @@
-%% Copyright (C) 2016-2024 by Geoffrey M. Poore <gpoore at gmail.com>
+%% Copyright (C) 2016-2025 by Geoffrey M. Poore <gpoore at gmail.com>
 %% --------------------------------------------------------------------------
 %% 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 @@
 
 This is a generated file.
 
-Copyright (C) 2016-2024 by Geoffrey M. Poore <gpoore at gmail.com>
+Copyright (C) 2016-2025 by Geoffrey M. Poore <gpoore at gmail.com>
 --------------------------------------------------------------------------
 This work may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3

Modified: trunk/Master/texmf-dist/tex/latex/fvextra/fvextra.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/fvextra/fvextra.sty	2025-03-05 21:31:58 UTC (rev 74459)
+++ trunk/Master/texmf-dist/tex/latex/fvextra/fvextra.sty	2025-03-05 21:32:08 UTC (rev 74460)
@@ -8,7 +8,7 @@
 %% 
 %% This is a generated file.
 %% 
-%% Copyright (C) 2016-2024 by Geoffrey M. Poore <gpoore at gmail.com>
+%% Copyright (C) 2016-2025 by Geoffrey M. Poore <gpoore at gmail.com>
 %% --------------------------------------------------------------------------
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3
@@ -20,9 +20,10 @@
 %% 
 \NeedsTeXFormat{LaTeX2e}[1999/12/01]
 \ProvidesPackage{fvextra}
-    [2025/02/09 v1.11.0 fvextra - extensions and patches for fancyvrb]
+    [2025/03/04 v1.12.0 fvextra - extensions and patches for fancyvrb]
 \RequirePackage{etoolbox}
 \RequirePackage{fancyvrb}
+\RequirePackage{pdftexcmds}
 \RequirePackage{upquote}
 \AtEndPreamble{%
   \ifx\encodingdefault\upquote at OTone
@@ -1442,15 +1443,30 @@
   \repeat
   \gdef\FancyVerbBufferIndex{0}%
   \endgroup}
+\define at key{FV}{wrapperenvname}{%
+  \def\FV at WrapperEnvName{#1}%
+  \ifx\FV at WrapperEnvName\@empty
+    \let\FV at WrapperEnvName\relax
+  \fi}
+\fvset{wrapperenvname=}
+\define at key{FV}{wrapperenvopt}{%
+  \def\FV at WrapperEnvOpt{#1}%
+  \ifx\FV at WrapperEnvOpt\@empty
+    \let\FV at WrapperEnvOpt\relax
+  \fi}
+\fvset{wrapperenvopt=}
+\define at key{FV}{wrapperenvarg}{%
+  \def\FV at WrapperEnvArg{#1}%
+  \ifx\FV at WrapperEnvArg\@empty
+    \let\FV at WrapperEnvArg\relax
+  \fi}
+\fvset{wrapperenvarg=}
 \newcommand{\InsertBuffer}[1][]{%
   \begingroup
   \def\FV at KeyValues{#1}%
   \FV at UseKeyValues
-  \global\let\FV at tmpbufferlengthmacro\FV at bufferlengthmacro
-  \global\let\FV at tmpbufferlinename\FancyVerbBufferLineName
-  \endgroup
-  \ifnum\FV at tmpbufferlengthmacro<1
-    \expandafter\@gobble
+  \ifnum\FV at bufferlengthmacro<1
+    \expandafter\endgroup\expandafter\@gobble
   \else
     \expandafter\@firstofone
   \fi
@@ -1457,24 +1473,121 @@
   \InsertBuffer at i}
 \def\InsertBuffer at i{%
   \InsertBuffer at expandbuffer
-  \expandafter\InsertBuffer at cleanup\expandafter\scantokens\expandafter{%
-    \FV at expandedbuffer\unskip\noexpand}\relax}
+  \expandafter\endgroup\expandafter\scantokens\expandafter{%
+    \FV at expandedbuffer\noexpand}\relax}
 \def\InsertBuffer at expandbuffer{%
-  \edef\FV at expandedbuffer{\InsertBuffer at expandbufferlines{1}}}
+  \edef\FV at expandedbuffer{%
+    \ifx\FV at WrapperEnvName\relax
+    \else
+      \unexpanded\expandafter\expandafter\expandafter{%
+        \expandafter\string\expandafter\begin\expandafter{\FV at WrapperEnvName}}%
+      \ifx\FV at WrapperEnvOpt\relax
+      \else
+        \unexpanded\expandafter{\expandafter[\FV at WrapperEnvOpt]}%
+      \fi
+      \ifx\FV at WrapperEnvArg\relax
+      \else
+        \unexpanded\expandafter{\expandafter{\FV at WrapperEnvArg}}%
+      \fi
+      \unexpanded{^^J}%
+    \fi
+    \InsertBuffer at expandbufferlines{1}%
+    \ifx\FV at WrapperEnvName\relax
+      \unskip
+    \else
+      \unexpanded\expandafter\expandafter\expandafter{%
+        \expandafter\string\expandafter\end\expandafter{\FV at WrapperEnvName}^^J}%
+    \fi}}
 \def\InsertBuffer at expandbufferlines#1{%
   \unexpanded\expandafter\expandafter\expandafter{%
-    \csname\FV at tmpbufferlinename#1\endcsname^^J}%
-  \ifnum\FV at tmpbufferlengthmacro=#1
+    \csname\FancyVerbBufferLineName#1\endcsname^^J}%
+  \ifnum\FV at bufferlengthmacro=#1
     \expandafter\@gobble
   \else
     \expandafter\@firstofone
   \fi
   {\expandafter\InsertBuffer at expandbufferlines\expandafter{\the\numexpr#1+1\relax}}}
-\def\InsertBuffer at cleanup{%
-  \global\let\FV at tmpbufferlengthmacro\FV at Undefined
-  \global\let\FV at tmpbufferlinename\FV at Undefined
-  \global\let\FV at expandedbuffer\FV at Undefined}
 \let\ClearBuffer\VerbatimClearBuffer
+\def\BufferMdfivesum{%
+  \pdf at mdfivesum{%
+    \ifnum\FV at bufferlengthmacro<1
+      \expandafter\@gobble
+    \else
+      \expandafter\@firstofone
+    \fi
+    {\BufferMdfivesum at i{1}}}}
+\def\BufferMdfivesum at i#1{%
+  \csname\FancyVerbBufferLineName#1\endcsname^^J%
+  \ifnum\FV at bufferlengthmacro=#1
+    \expandafter\@gobble
+  \else
+    \expandafter\@firstofone
+  \fi
+  {\expandafter\BufferMdfivesum at i\expandafter{\the\numexpr#1+1\relax}}}
+\newcommand{\IterateBuffer}[2][]{%
+  \if\relax\detokenize{#1}\relax
+  \else
+    \let\FancyVerbBufferLengthName at beforeiter\FancyVerbBufferLengthName
+    \let\FV at bufferlengthmacro@beforeiter\FV at bufferlengthmacro
+    \let\FancyVerbBufferLineName at beforeiter\FancyVerbBufferLineName
+    \begingroup
+    \def\FV at KeyValues{#1}%
+    \FV at UseKeyValues
+    \global\let\FancyVerbBufferLengthName at iter\FancyVerbBufferLengthName
+    \global\let\FV at bufferlengthmacro@iter\FV at bufferlengthmacro
+    \global\let\FancyVerbBufferLineName at iter\FancyVerbBufferLineName
+    \endgroup
+    \let\FancyVerbBufferLengthName\FancyVerbBufferLengthName at iter
+    \let\FV at bufferlengthmacro\FV at bufferlengthmacro@iter
+    \let\FancyVerbBufferLineName\FancyVerbBufferLineName at iter
+    \global\let\FancyVerbBufferLengthName at iter\FV at Undefined
+    \global\let\FV at bufferlengthmacro@iter\FV at Undefined
+    \global\let\FancyVerbBufferLineName at iter\FV at Undefined
+  \fi
+  \gdef\FancyVerbBufferIndex{1}%
+  \def\FV at IterateBuffer@cmd{#2}%
+  \def\IterateBufferBreak{\xdef\FancyVerbBufferIndex{\FV at bufferlengthmacro}}%
+  \loop\unless\ifnum\FancyVerbBufferIndex>\FV at bufferlengthmacro\relax
+    \expandafter\let\expandafter\FV at IterateBuffer@line
+      \csname\FancyVerbBufferLineName\FancyVerbBufferIndex\endcsname
+    \expandafter\FV at IterateBuffer@cmd\expandafter{\FV at IterateBuffer@line}%
+    \xdef\FancyVerbBufferIndex{\the\numexpr\FancyVerbBufferIndex+1\relax}%
+  \repeat
+  \gdef\FancyVerbBufferIndex{0}%
+  \let\FV at IterateBuffer@cmd\FV at Undefined
+  \let\IterateBufferBreak\FV at Undefined
+  \let\FV at IterateBuffer@line\FV at Undefined
+  \if\relax\detokenize{#1}\relax
+  \else
+    \let\FancyVerbBufferLengthName\FancyVerbBufferLengthName at beforeiter
+    \let\FV at bufferlengthmacro\FV at bufferlengthmacro@beforeiter
+    \let\FancyVerbBufferLineName\FancyVerbBufferLineName at beforeiter
+    \let\FancyVerbBufferLengthName at beforeiter\FV at Undefined
+    \let\FV at bufferlengthmacro@beforeiter\FV at Undefined
+    \let\FancyVerbBufferLineName at beforeiter\FV at Undefined
+  \fi}
+\def\WriteBuffer{%
+  \FV at Command{}{WriteBuffer}}
+\def\FVC at WriteBuffer{%
+  \@bsphack
+  \begingroup
+  \setcounter{FancyVerbWriteLine}{0}%
+  \let\c at FancyVerbLine\c at FancyVerbWriteLine
+  \FV at UseKeyValues
+  \FV at DefineWhiteSpace
+  \def\FV at Space{\space}%
+  \FV at DefineTabOut
+  \gdef\FancyVerbBufferIndex{1}%
+  \loop\unless\ifnum\FancyVerbBufferIndex>\FV at bufferlengthmacro\relax
+    \stepcounter{FancyVerbWriteLine}%
+    \expandafter\let\expandafter\FV at WriteBuffer@line
+      \csname\FancyVerbBufferLineName\FancyVerbBufferIndex\endcsname
+    \expandafter\FV at Writer\expandafter{\FV at WriteBuffer@line}%
+    \xdef\FancyVerbBufferIndex{\the\numexpr\FancyVerbBufferIndex+1\relax}%
+  \repeat
+  \gdef\FancyVerbBufferIndex{0}%
+  \endgroup
+  \@esphack}
 \def\FV at Command#1#2{%
   \FVExtra at ifstarVArg
    {\def\FV at KeyValues{#1,showspaces,showtabs}\FV@@Command{#2}}%
@@ -3175,8 +3288,9 @@
     \let\FV at TrueTabSaveWidth\relax
   \fi
   \ifnum
-    \FV at iffp{\the\wd\FV at LineBox}>{\FV at LineWidth}{1}{0}% width greater than line
-    \FV at iffp{\the\wd\FV at LineBox}<{0}{1}{0}% width overflows
+    \FV at iffp{\the\wd\FV at LineBox}>{\FV at LineWidth}%
+     {1}% width greater than line
+     {\FV at iffp{\the\wd\FV at LineBox}<{0}{1}{0}}% width overflows
     >0
   \relax
     \setcounter{FancyVerbLineBreakLast}{0}%



More information about the tex-live-commits mailing list.