summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/fvextra
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/fvextra')
-rw-r--r--macros/latex/contrib/fvextra/fvextra.dtx855
-rw-r--r--macros/latex/contrib/fvextra/fvextra.ins5
-rw-r--r--macros/latex/contrib/fvextra/fvextra.pdfbin823961 -> 867095 bytes
3 files changed, 639 insertions, 221 deletions
diff --git a/macros/latex/contrib/fvextra/fvextra.dtx b/macros/latex/contrib/fvextra/fvextra.dtx
index 22b6b02720..612c885839 100644
--- a/macros/latex/contrib/fvextra/fvextra.dtx
+++ b/macros/latex/contrib/fvextra/fvextra.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2016-2019 by Geoffrey M. Poore <gpoore@gmail.com>
+% Copyright (C) 2016-2022 by Geoffrey M. Poore <gpoore@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>
- [2019/02/04 v1.4 fvextra - extensions and patches for fancyvrb]
+ [2022/11/30 v1.5 fvextra - extensions and patches for fancyvrb]
%</package>
%
%<*driver>
@@ -230,7 +230,7 @@
%</driver>
% \fi
%
-% \CheckSum{4882}
+% \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
@@ -249,6 +249,19 @@
% Right brace \} Tilde \~}
%
%
+% \begin{changelog}{v1.5}{2022/11/30}
+% \item Added \cmd{\FancyVerbFormatInline} for customizing the formatting of inline verbatim, such as \cmd{\Verb}. This parallels \cmd{\FancyVerbFormatLine} and \cmd{\FancyVerbFormatText}.
+% \item Added line breaking option \Verb{breaknonspaceingroup}. When \cmd{commandchars} is used to allow macros within verbatim, this inserts breaks within groups \Verb{{...}}.
+% \item Added \cmd{\FVExtraUnexpandedReadStarOArgMArgBVArg} to support reimplementation of \cmd{\mintinline} for \pkg{minted}.
+% \item Added \cmd{VerbEnv} environment, which is an environment variant of \cmd{\Verb}. This supports reimplementation of \cmd{\mintinline} for \pkg{minted}.
+% \item \cmd{breakbefore} and \cmd{breakafter} now support the escaped comma \cmd{\,} (\#15).
+% \item Fixed unintended line breaks after hyphens under LuaTeX (\#14).
+% \item Added documentation on Pandoc compatibility (\#11).
+% \item Replaced \Verb{breakbeforegroup} with \Verb{breakbeforeinrun}, and replaced \Verb{breakaftergroup} with \Verb{breakafterinrun}. With the introduction of \Verb{breaknonspaceingroup}, ``\Verb{group}'' is now reserved for referring to TeX groups \Verb{{...}}.
+% \item Removed dependency on \Verb{ifthen} package.
+% \item \Verb{breakautoindent} now works correctly with Pygments output that treats leading whitespace as a separate token or as part of a token.
+% \end{changelog}
+%
% \begin{changelog}{v1.4}{2019/02/04}
% \item Reimplemented \texttt{\string\Verb}. It now works as expected inside other commands (with a few limitations), including in movable arguments, and is compatible with \texttt{hyperref} for things like PDF bookmarks. It now supports \texttt{breaklines} and relevant line-breaking options.
% \item Reimplemented \texttt{\string\SaveVerb} and \texttt{\string\UseVerb} to be equivalent to the new \texttt{\string\Verb}. The new option \texttt{retokenize} allows saved verbatim material to be retokenized under new \texttt{commandchars} and \texttt{codes} when it is inserted with \texttt{\string\UseVerb}.
@@ -353,11 +366,39 @@
%
% \fvextra\ may be used as a drop-in replacement for \fancyvrb. It will load \fancyvrb\ if it has not yet been loaded, and then proceeds to patch \fancyvrb\ and define additional features.
%
-% The \pkg{upquote} package is loaded to give correct backticks (\texttt{\textasciigrave}) and typewriter single quotation marks (\texttt{\textquotesingle}). When this is not desirable within a given environment, use the option |curlyquotes|. \fvextra\ modifies the behavior of these and other symbols in typeset math within verbatim, so that they will behave as expected (\cref{sec:patch:math}). \fvextra\ uses the \pkg{lineno} package for working with automatic line breaks. \pkg{lineno} gives a warning when the \pkg{csquotes} package is loaded before it, so \fvextra\ should be loaded before \pkg{csquotes}. The \pkg{ifthen} and \pkg{etoolbox} packages are required. \pkg{color} or \pkg{xcolor} should be loaded manually to use color-dependent features.
+% The \pkg{upquote} package is loaded to give correct backticks (\texttt{\textasciigrave}) and typewriter single quotation marks (\texttt{\textquotesingle}). When this is not desirable within a given environment, use the option |curlyquotes|. \fvextra\ modifies the behavior of these and other symbols in typeset math within verbatim, so that they will behave as expected (\cref{sec:patch:math}). \fvextra\ uses the \pkg{lineno} package for working with automatic line breaks. \pkg{lineno} gives a warning when the \pkg{csquotes} package is loaded before it, so \fvextra\ should be loaded before \pkg{csquotes}. The \pkg{etoolbox} package is required. \pkg{color} or \pkg{xcolor} should be loaded manually to use color-dependent features.
%
% While \fvextra\ attempts to minimize changes to the \fancyvrb\ internals, in some cases it completely overwrites \fancyvrb\ macros with new definitions. New definitions typically follow the original definitions as much as possible, but code that depends on the details of the original \fancyvrb\ implementation may be incompatible with \fvextra.
%
%
+% \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.
+%
+%\vspace{2ex}
+%\hrule
+%\vspace{2ex}
+%\noindent\begin{minipage}{\linewidth}
+%\begin{Verbatim}[gobble=1]
+%---
+%header-includes:
+% - |
+% ```{=latex}
+% \usepackage{fvextra}
+% \DefineVerbatimEnvironment{Highlighting}{Verbatim}{
+% commandchars=\\\{\},
+% breaklines, breaknonspaceingroup, breakanywhere}
+% ```
+%---
+%\end{Verbatim}
+%\end{minipage}
+%\vspace{2ex}
+%\hrule
+%\vspace{2ex}
+%
+%
%
%
% \section{General options}
@@ -571,7 +612,7 @@
%
% \section{General commands}
%
-% \subsection{Inline formatting with \cmd{\fvinlineset}}
+% \subsection{Inline-only settings with \cmd{\fvinlineset}}
% \DescribeMacro{\fvinlineset\marg{options}}
%
% 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}.
@@ -579,12 +620,21 @@
% 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{Line and text formatting}
+% \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.
+%
+%
+% \subsection{Custom formatting for environments like \cmd{Verbatim} with \cmd{\FancyVerbFormatLine} and \cmd{\FancyVerbFormatText}}
%
% \DescribeMacro{\FancyVerbFormatLine}
% \DescribeMacro{\FancyVerbFormatText}
%
-% \fancyvrb\ defines |\FancyVerbFormatLine|, which can be used to apply custom formatting to each individual line of text. By default, it takes a line as an argument and inserts it with no modification. This is equivalent to |\newcommand{\FancyVerbFormatLine}[1]{#1}|.\footnote{The actual definition in \fancyvrb\ is |\def\FancyVerbFormatLine#1{\FV@ObeyTabs{#1}}|. This is problematic because redefining the macro could easily eliminate |\FV@ObeyTabs|, which governs tab expansion. \fvextra\ redefines the macro to |\def\FancyVerbFormatLine#1{#1}| and patches all parts of \fancyvrb\ that use |\FancyVerbFormatLine| so that |\FV@ObeyTabs| is explicitly inserted at the appropriate points.}
+% \fancyvrb\ defines |\FancyVerbFormatLine|, which can be used to apply custom formatting to each individual line of text in environments like \cmd{Verbatim}. By default, it takes a line as an argument and inserts it with no modification. This is equivalent to |\newcommand{\FancyVerbFormatLine}[1]{#1}|.\footnote{The actual definition in \fancyvrb\ is |\def\FancyVerbFormatLine#1{\FV@ObeyTabs{#1}}|. This is problematic because redefining the macro could easily eliminate |\FV@ObeyTabs|, which governs tab expansion. \fvextra\ redefines the macro to |\def\FancyVerbFormatLine#1{#1}| and patches all parts of \fancyvrb\ that use |\FancyVerbFormatLine| so that |\FV@ObeyTabs| is explicitly inserted at the appropriate points.}
%
% \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.
%
@@ -637,7 +687,7 @@
%
% \subsection{\cmd{\SaveVerb}}
%
-% \DescribeMacro{\SaveVerb*\oarg{options}\marg{name}\meta{delim~char~or~\{}\meta{text}\meta{delim~char~or~\}}}
+% \DescribeMacro{\SaveVerb\oarg{options}\marg{name}\meta{delim~char~or~\{}\meta{text}\meta{delim~char~or~\}}}
%
% \cmd{\SaveVerb} is reimplemented so that it is equivalent to the reimplemented \cmd{\Verb}. Like the new \cmd{\Verb}, it accepts \meta{text} delimited by a pair of curly braces |{...}|. It supports \cmd{\fvinlineset}. It also adds support for the new |retokenize| option for \cmd{\UseVerb}.
%
@@ -688,8 +738,19 @@
% \end{description}
%
%
+% \subsection{\cmd{VerbEnv}}
+% \DescribeMacro{\begin\{VerbEnv\}\oarg{options}\\$\langle$\textit{single line}$\rangle$\\\cmd{\end{VerbEnv}}}
%
+% This is an environment variant of \cmd{\Verb}. The environment must contain only a single line of text, and the closing \cmd{\end{VerbEnv}} must be on a line by itself. The $\langle$\textit{options}$\rangle$ and $\langle$\textit{single line}$\rangle$ are read and then passed on to \cmd{\Verb} internally for actual typesetting.
%
+% 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}
%
%
% \section{Line breaking}
@@ -697,6 +758,8 @@
%
% Automatic line breaking may be turned on with |breaklines=true|. By default, breaks only occur at spaces. Breaks may be allowed anywhere with |breakanywhere|, or only before or after specified characters with |breakbefore| and |breakafter|. Many options are provided for customizing breaks. A good place to start is the description of |breaklines|.
%
+% When a line is broken, the result must fit on a single page. There is no support for breaking a line across multiple pages.
+%
%
% \subsection{Line breaking options}
%
@@ -705,9 +768,9 @@
% \begin{optionlist}
%
% \item[breakafter (string) (\meta{none})]
-% Break lines after specified characters, not just at spaces, when |breaklines=true|. For example, |breakafter=-/| would allow breaks after any hyphens or slashes. Special characters given to |breakafter| should be backslash-escaped (usually |#|, |{|, |}|, |%|, |[|, |]|; the backslash |\| may be obtained via |\\| and the space via |\space|).\footnote{|breakafter| expands each token it is given once, so when it is given a macro like |\%|, the macro should expand to a literal character that will appear in the text to be typeset. \fvextra\ defines special character escapes that are activated for |breakafter| so that this will work with common escapes. The only exception to token expansion is non-ASCII characters under pdfTeX; these should appear literally. |breakafter| is not catcode-sensitive.}
+% Break lines after specified characters, not just at spaces, when |breaklines=true|. For example, |breakafter=-/| would allow breaks after any hyphens or slashes. Special characters given to |breakafter| should be backslash-escaped (usually |#|, |{|, |}|, |%|, |[|, |]|, and the comma |,|; the backslash |\| may be obtained via |\\| and the space via |\space|).\footnote{|breakafter| expands each token it is given once, so when it is given a macro like |\%|, the macro should expand to a literal character that will appear in the text to be typeset. \fvextra\ defines special character escapes that are activated for |breakafter| so that this will work with common escapes. The only exception to token expansion is non-ASCII characters under pdfTeX; these should appear literally. |breakafter| is not catcode-sensitive.}
%
-% For an alternative, see |breakbefore|. When |breakbefore| and |breakafter| are used for the same character, |breakbeforegroup| and |breakaftergroup| must both have the same setting.
+% 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.
%
@@ -718,8 +781,8 @@
% \end{longexample}
%
%
-% \item[breakaftergroup (boolean) (true)]
-% When |breakafter| is used, group all adjacent identical characters together, and only allow a break after the last character. When |breakbefore| and |breakafter| are used for the same character, |breakbeforegroup| and |breakaftergroup| must both have the same setting.
+% \item[breakafterinrun (boolean) (false)]
+% When |breakafter| is used, insert breaks within runs of identical characters. If |false|, treat sequences of identical characters as a unit that cannot contain breaks. When |breakbefore| and |breakafter| are used for the same character, |breakbeforeinrun| and |breakafterinrun| must both have the same setting.
%
%
% \item[breakaftersymbolpre (string) (\string\,\string\footnotesize\string\ensuremath\{\_\string\rfloor\}, \,\footnotesize\ensuremath{_\rfloor})]
@@ -755,9 +818,9 @@
%
%
% \item[breakbefore (string) (\meta{none})]
-% Break lines before specified characters, not just at spaces, when |breaklines=true|. For example, |breakbefore=A| would allow breaks before capital A's. Special characters given to |breakbefore| should be backslash-escaped (usually |#|, |{|, |}|, |%|, |[|, |]|; the backslash |\| may be obtained via |\\| and the space via |\space|).\footnote{|breakbefore| expands each token it is given once, so when it is given a macro like |\%|, the macro should expand to a literal character that will appear in the text to be typeset. \fvextra\ defines special character escapes that are activated for |breakbefore| so that this will work with common escapes. The only exception to token expansion is non-ASCII characters under pdfTeX; these should appear literally. |breakbefore| is not catcode-sensitive.}
+% Break lines before specified characters, not just at spaces, when |breaklines=true|. For example, |breakbefore=A| would allow breaks before capital A's. Special characters given to |breakbefore| should be backslash-escaped (usually |#|, |{|, |}|, |%|, |[|, |]|, and the comma |,|; the backslash |\| may be obtained via |\\| and the space via |\space|).\footnote{|breakbefore| expands each token it is given once, so when it is given a macro like |\%|, the macro should expand to a literal character that will appear in the text to be typeset. \fvextra\ defines special character escapes that are activated for |breakbefore| so that this will work with common escapes. The only exception to token expansion is non-ASCII characters under pdfTeX; these should appear literally. |breakbefore| is not catcode-sensitive.}
%
-% For an alternative, see |breakafter|. When |breakbefore| and |breakafter| are used for the same character, |breakbeforegroup| and |breakaftergroup| must both have the same setting.
+% 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.
%
@@ -768,8 +831,8 @@
% \end{longexample}
%
%
-% \item[breakbeforegroup (boolean) (true)]
-% When |breakbefore| is used, group all adjacent identical characters together, and only allow a break before the first character. When |breakbefore| and |breakafter| are used for the same character, |breakbeforegroup| and |breakaftergroup| must both have the same setting.
+% \item[breakbeforeinrun (boolean) (false)]
+% When |breakbefore| is used, insert breaks within runs of identical characters. If |false|, treat sequences of identical characters as a unit that cannot contain breaks. When |breakbefore| and |breakafter| are used for the same character, |breakbeforeinrun| and |breakafterinrun| must both have the same setting.
%
%
% \item[breakbeforesymbolpre (string) (\string\,\string\footnotesize\string\ensuremath\{\_\string\rfloor\}, \,\footnotesize\ensuremath{_\rfloor})]
@@ -788,7 +851,7 @@
%
%
% \item[breaklines (boolean) (false)]
-% Automatically break long lines.
+% 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.
%
@@ -831,6 +894,12 @@
% \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|.
+%
+% |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|.
+%
+%
% \item[breaksymbol (string) (breaksymbolleft)]
% Alias for |breaksymbolleft|.
%
@@ -1255,7 +1324,6 @@
% \subsection{Required packages}
% The \pkg{upquote} package performs some font checks when it is loaded to determine whether \pkg{textcomp} is needed, but errors can result if the font is changed later in the preamble, so duplicate the package's font check at the end of the preamble. Also check for a package order issue with \pkg{lineno} and \pkg{csquotes}.
% \begin{macrocode}
-\RequirePackage{ifthen}
\RequirePackage{etoolbox}
\RequirePackage{fancyvrb}
\RequirePackage{upquote}
@@ -1547,6 +1615,25 @@
%
% \subsubsection{Tokenization and lookahead}
%
+%
+% \begin{macro}{\FVExtra@ifnextcharAny}
+% A version of |\@ifnextchar| that can detect any character, including catcode 10 spaces. This is an exact copy of the definition from |latex.ltx|, modified with the ``|\let\reserved@d= #1%|'' (note space!) trick from \pkg{amsgen}.
+% \begin{macrocode}
+\long\def\FVExtra@ifnextcharAny#1#2#3{%
+ \let\reserved@d= #1%
+ \def\reserved@a{#2}%
+ \def\reserved@b{#3}%
+ \futurelet\@let@token\FVExtra@ifnchAny}
+\def\FVExtra@ifnchAny{%
+ \ifx\@let@token\reserved@d
+ \expandafter\reserved@a
+ \else
+ \expandafter\reserved@b
+ \fi}
+% \end{macrocode}
+% \end{macro}
+
+%
% \begin{macro}{\FVExtra@ifnextcharVArg}
% This is a wrapper for \cmd{\@ifnextchar} from |latex.ltx| (|ltdefns.dtx|) that tokenizes lookaheads under a mostly verbatim catcode regime rather than the current catcode regime. This is important when looking ahead for stars |*| and optional argument delimiters~|[|, because if these are not present when looking ahead for a verbatim argument, then the first thing tokenized will be the verbatim argument's delimiting character. Ideally, the delimiter should be tokenized under a verbatim catcode regime. This is necessary for instance if the delimiter is \cmd{\active} and \cmd{\outer}.
%
@@ -1597,19 +1684,9 @@
%
%
% \begin{macro}{\FVExtraReadOArgBeforeVEnv}
-% Read an optional argument that comes before the contents of a verbatim environment, after the |\begin{|\meta{environment}|}| but before the start of the next line where the verbatim content begins. Note that this is not needed when an environment takes a mandatory argument that follows the optional argument.
+% Read an optional argument at the start of a verbatim environment, after the |\begin{|\meta{environment}|}| but before the start of the next line where the verbatim content begins. Check for extraneous content after the optional argument and discard the following newline. Note that this is not needed when an environment takes a mandatory argument that follows the optional argument.
%
-% The case with only an optional argument is tricky because the default behavior of \cmd{\@ifnextchar} is to read into the next line looking for the optional argument. Setting |^^M| \cmd{\active} prevents this. That does mean, though, that the end-of-line token will have to be read and removed later as an \cmd{\active} |^^M|. See the definition of \cmd{\FV@BeginScanning} in \fancyvrb\ for an example of doing this:
-% \begin{quote}
-%\begin{verbatim}
-%\begingroup
-%\catcode`\^^M=\active
-% \gdef\FV@BeginScanning#1^^M{%
-% \def\@tempa{#1}\ifx\@tempa\@empty\else\FV@BadBeginError\fi%
-% \FV@GetLine}%
-%\endgroup
-%\end{verbatim}
-% \end{quote}
+% The case with only an optional argument is tricky because the default behavior of \cmd{\@ifnextchar} is to read into the next line looking for the optional argument. Setting |^^M| as \cmd{\active} prevents this. That does mean, though, that the end-of-line token will have to be read and removed later as an \cmd{\active} |^^M|.
%
% \cmd{\@ifnextchar} is used instead of \cmd{\FVExtra@ifnextcharVArg} because the latter is not needed since there is an explicit, required delimiter (|^^M|) before the actual start of verbatim content. Lookahead can never tokenize verbatim content under an incorrect catcode regime.
% \begin{macrocode}
@@ -1617,8 +1694,26 @@
\begingroup
\catcode`\^^M=\active
\@ifnextchar[%
- {\endgroup\FV@ReadOArgContinue{#2}}%
- {\endgroup\FV@ReadOArgContinue{#2}[#1]}}
+ {\endgroup\FVExtraReadOArgBeforeVEnv@i{#2}}%
+ {\endgroup\FVExtraReadOArgBeforeVEnv@i{#2}[#1]}}
+\def\FVExtraReadOArgBeforeVEnv@i#1[#2]{%
+ \begingroup
+ \catcode`\^^M=\active
+ \FVExtraReadOArgBeforeVEnv@ii{#1}{#2}}
+\begingroup
+\catcode`\^^M=\active%
+\gdef\FVExtraReadOArgBeforeVEnv@ii#1#2#3^^M{%
+ \endgroup%
+ \FVExtraReadOArgBeforeVEnv@iii{#1}{#2}{#3}}%
+\endgroup%
+\def\FVExtraReadOArgBeforeVEnv@iii#1#2#3{%
+ \if\relax\detokenize{#3}\relax
+ \else
+ \PackageError{fvextra}%
+ {Discarded invalid text while checking for optional argument of verbatim environment}%
+ {Discarded invalid text while checking for optional argument of verbatim environment}%
+ \fi
+ #1{#2}}
% \end{macrocode}
% \end{macro}
%
@@ -1906,6 +2001,22 @@
% \end{macro}
%
%
+% \begin{macro}{\FVExtraUnexpandedReadStarOArgMArgBVArg}
+% Read arguments for a command that has a mandatory argument before a verbatim argument, such as \pkg{minted}'s \cmd{\mintinline}.
+% \begin{macrocode}
+\def\FVExtraUnexpandedReadStarOArgMArgBVArg#1#{%
+ \FV@UnexpandedReadStarOArgMArgBVArg@i{#1}}
+\def\FV@UnexpandedReadStarOArgMArgBVArg@i#1#2#3{%
+ \FVExtraAlwaysUnexpanded{\FVExtraUnexpandedReadStarOArgMArgBVArg#1{#2}{#3}}}
+\FVExtrapdfstringdefDisableCommands{%
+ \makeatletter
+ \def\FV@UnexpandedReadStarOArgMArgBVArg@i#1#2#3{%
+ \FVExtraPDFStringVerbatimDetokenize{#3}}%
+ \makeatother}
+% \end{macrocode}
+% \end{macro}
+%
+%
%
%
% \subsubsection{Converting detokenized tokens into PDF strings}
@@ -3063,9 +3174,11 @@
\edef\FV@dollarchar{\string$}
\edef\FV@ampchar{\string&}
\edef\FV@underscorechar{\string_}
+\edef\FV@caretchar{\string^}
\edef\FV@tildechar{\string~}
\edef\FV@leftsquarebracket{\string[}
\edef\FV@rightsquarebracket{\string]}
+\edef\FV@commachar{\string,}
\newcommand{\FV@EscChars}{%
\let\#\FV@hashchar
\let\%\@percentchar
@@ -3074,11 +3187,13 @@
\let\$\FV@dollarchar
\let\&\FV@ampchar
\let\_\FV@underscorechar
+ \let\^\FV@caretchar
\let\\\@backslashchar
\let~\FV@tildechar
\let\~\FV@tildechar
\let\[\FV@leftsquarebracket
\let\]\FV@rightsquarebracket
+ \let\,\FV@commachar
} %$ <- highlighting
% \end{macrocode}
% \end{macro}
@@ -3136,6 +3251,15 @@
% \end{macro}
%
%
+% \subsubsection{\cmd{\FancyVerbFormatInline}}
+% This allows customization of inline verbatim material. It is the inline equivalent of \cmd{\FancyVerbFormatLine} and \cmd{\FancyVerbFormatText}.
+% \begin{macro}{\FancyVerbFormatInline}
+% \begin{macrocode}
+\def\FancyVerbFormatInline#1{#1}
+% \end{macrocode}
+% \end{macro}
+%
+%
% \subsubsection{\texttt{\textbackslash Verb}}
%
% \cmd{\Verb} is reimplemented so that it functions as well as possible when used within other commands.
@@ -3212,12 +3336,12 @@
% \begin{macro}{\FVC@Verb@Extra@ii}
% \begin{macrocode}
\def\FVC@Verb@Extra@ii#1{%
- \ifFV@BreakLines
+ \ifFV@breaklines
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
- {\FancyVerbBreakStart#1\FancyVerbBreakStop}%
+ {\FV@InsertBreaks{\FancyVerbFormatInline}{#1}}%
{\mbox{#1}}%
\endgroup}
% \end{macrocode}
@@ -3362,12 +3486,12 @@
% \begin{macro}{\FV@UseVerb@Extra}
% \begin{macrocode}
\def\FV@UseVerb@Extra#1{%
- \ifFV@BreakLines
+ \ifFV@breaklines
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
- {\FancyVerbBreakStart#1\FancyVerbBreakStop}%
+ {\FV@InsertBreaks{\FancyVerbFormatInline}{#1}}%
{\mbox{#1}}%
\endgroup}
% \end{macrocode}
@@ -3425,18 +3549,127 @@
% \begin{macro}{\FVC@EscVerb@ii}
% \begin{macrocode}
\def\FVC@EscVerb@ii#1{%
- \ifFV@BreakLines
+ \ifFV@breaklines
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
- {\FancyVerbBreakStart#1\FancyVerbBreakStop}%
+ {\FV@InsertBreaks{\FancyVerbFormatInline}{#1}}%
{\mbox{#1}}%
\endgroup}
% \end{macrocode}
% \end{macro}
%
%
+% \subsubsection{\cmd{VerbEnv}}
+% Environment variant of \cmd{\Verb}. Depending on how this is used in the future, it may be worth improving error message and error recovery functionality, using techniques from \pkg{fancyvrb}.
+% \begin{macro}{\VerbEnv}
+% \begin{macrocode}
+\def\VerbEnv{%
+ \ifcsname @currenvir\endcsname
+ \ifx\@currenvir\@empty
+ \PackageError{fvextra}{VerbEnv is an environment}{VerbEnv is an environment}%
+ \else
+ \ifx\@currenvir\relax
+ \PackageError{fvextra}{VerbEnv is an environment}{VerbEnv is an environment}%
+ \fi
+ \fi
+ \else
+ \PackageError{fvextra}{VerbEnv is an environment}{VerbEnv is an environment}%
+ \fi
+ \VerbatimEnvironment
+ \FVExtraReadOArgBeforeVEnv{\expandafter\VerbEnv@i\expandafter{\FV@EnvironName}}}
+\def\VerbEnv@i#1#2{%
+ \begingroup
+ \let\do\@makeother\FVExtraDoSpecials
+ \catcode`\ =\active
+ \catcode`\^^I=\active
+ \catcode`\^^M=\active
+ \VerbEnv@ii{#1}{#2}}
+\begingroup
+\catcode`\!=0
+\catcode`\<=1
+\catcode`\>=2
+!catcode`!\=12
+!catcode`!{=12
+!catcode`!}=12
+!catcode`!^^M=!active%
+!gdef!VerbEnv@ii#1#2#3^^M<%
+ !endgroup%
+ !def!VerbEnv@CheckLine##1\end{#1}##2!FV@Sentinel<%
+ !if!relax!detokenize<##2>!relax%
+ !else%
+ !PackageError<fvextra><Missing environment contents><Missing environment contents>%
+ !let!VerbEnv@iii!VerbEnv@iii@Error%
+ !fi>%
+ !VerbEnv@CheckLine#3\end{#1}!FV@Sentinel%
+ !VerbEnv@iii<#1><#2><#3>>%
+!endgroup%
+\def\VerbEnv@iii@Error#1#2#3{}
+\def\VerbEnv@iii#1#2#3{%
+ \begingroup
+ \let\do\@makeother\FVExtraDoSpecials
+ \catcode`\ =10\relax
+ \catcode`\^^M=\active
+ \VerbEnv@iv{#1}{#2}{#3}}
+\begingroup
+\catcode`\!=0
+\catcode`\<=1
+\catcode`\>=2
+!catcode`!\=12
+!catcode`!{=12
+!catcode`!}=12
+!catcode`!^^M=!active%
+!gdef!VerbEnv@iv#1#2#3#4^^M<%
+ !endgroup%
+ !def!VerbEnv@CheckEndDelim##1\end{#1}##2!FV@Sentinel<%
+ !if!relax!detokenize<##2>!relax%
+ !PackageError<fvextra><Missing end for environment !FV@EnvironName><Add environment end>%
+ !let!VerbEnv@v!VerbEnv@v@Error%
+ !else%
+ !VerbEnv@CheckEndLeading##1!FV@Sentinel%
+ !VerbEnv@CheckEndTrailing##2!FV@Sentinel%
+ !fi>%
+ !def!VerbEnv@CheckEndTrailing##1\end{#1}!FV@Sentinel<%
+ !if!relax!detokenize<##1>!relax%
+ !else%
+ !PackageError<fvextra>%
+ <Discarded text after end of environment !FV@EnvironName>%
+ <Discarded text after end of environment !FV@EnvironName>%
+ !let!VerbEnv@v!VerbEnv@v@Error%
+ !fi>%
+ !VerbEnv@CheckEndDelim#4\end{#1}!FV@Sentinel%
+ !VerbEnv@v<#2><#3>>%
+!endgroup
+\def\VerbEnv@CheckEndLeading{%
+ \FVExtra@ifnextcharAny\@sptoken%
+ {\VerbEnv@CheckEndLeading@Continue}%
+ {\ifx\@let@token\FV@Sentinel
+ \expandafter\VerbEnv@CheckEndLeading@End
+ \else
+ \expandafter\VerbEnv@CheckEndLeading@EndError
+ \fi}}
+\def\VerbEnv@CheckEndLeading@Continue#1{%
+ \VerbEnv@CheckEndLeading}
+\def\VerbEnv@CheckEndLeading@End#1\FV@Sentinel{}
+\def\VerbEnv@CheckEndLeading@EndError{%
+ \PackageError{fvextra}%
+ {Discarded text before end of environment \FV@EnvironName}%
+ {Discarded text before end of environment \FV@EnvironName}%
+ \let\VerbEnv@v\VerbEnv@v@Error}
+\def\VerbEnv@v@Error#1#2{}
+\def\VerbEnv@v#1#2{%
+ \Verb[#1]{#2}%
+ \expandafter\end\expandafter{\FV@EnvironName}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\endVerbEnv}
+% \begin{macrocode}
+\def\endVerbEnv{\global\let\FV@EnvironName\relax}
+% \end{macrocode}
+% \end{macro}
+%
+%
%
%
% \subsection{Patches}
@@ -3608,7 +3841,7 @@
% \begin{macro}{FV@ObeyTabs@Whitespace@Tab}
% In a group where runs of whitespace characters are collected, we need to keep track of whether a tab has been found, so we can avoid expansion and the associated |\hbox| for spaces without tabs.
% \begin{macrocode}
-\newboolean{FV@ObeyTabs@Whitespace@Tab}
+\newbool{FV@ObeyTabs@Whitespace@Tab}
% \end{macrocode}
% \end{macro}
%
@@ -4470,26 +4703,43 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{FV@BreakLines}
+% \begin{macro}{FV@breaklines}
% Turn line breaking on or off. The |\FV@ListProcessLine| from \fancyvrb\ is |\let| to a (patched) version of the original or a version that supports line breaks.
% \begin{macrocode}
-\newboolean{FV@BreakLines}
+\newbool{FV@breaklines}
\define@booleankey{FV}{breaklines}%
- {\FV@BreakLinestrue
- \let\FV@ListProcessLine\FV@ListProcessLine@Break}%
- {\FV@BreakLinesfalse
- \let\FV@ListProcessLine\FV@ListProcessLine@NoBreak}
+ {\booltrue{FV@breaklines}%
+ \let\FV@ListProcessLine\FV@ListProcessLine@Break}%
+ {\boolfalse{FV@breaklines}%
+ \let\FV@ListProcessLine\FV@ListProcessLine@NoBreak}
\AtEndOfPackage{\fvset{breaklines=false}}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\FV@BreakLinesLuaTeXHook}
+% Fix hyphen handling under LuaTeX. |\automatichyphenmode=2| would work for environments, but doesn't seem to work inline. Instead, the active hyphen is redefined to |\mbox{-}|.
+%
+% This is needed before |\@noligs| is ever used, so it is placed in |\FV@FormattingPrep@PreHook|.
+% \begin{macrocode}
+\def\FV@BreakLinesLuaTeXHook{%
+ \expandafter\def\expandafter\@noligs\expandafter{\@noligs
+ \begingroup\lccode`\~=`\-\lowercase{\endgroup\def~}{\leavevmode\kern\z@\mbox{-}}}}
+\ifcsname directlua\endcsname
+ \ifx\directlua\relax
+ \else
+ \FV@AddToHook\FV@FormattingPrep@PreHook\FV@BreakLinesLuaTeXHook
+ \fi
+\fi
+% \end{macrocode}
+% \end{macro}
+%
%
% \begin{macro}{\FV@BreakLinesIndentationHook}
% A hook for performing on-the-fly indentation calculations when |breaklines=true|. This is used for all |*NChars| related indentation. It is important to use |\FV@FormattingPrep@PostHook| because it is always invoked \emph{after} any font-related settings.
% \begin{macrocode}
\def\FV@BreakLinesIndentationHook{}
\g@addto@macro\FV@FormattingPrep@PostHook{%
- \ifFV@BreakLines
+ \ifFV@breaklines
\FV@BreakLinesIndentationHook
\fi}
% \end{macrocode}
@@ -4516,12 +4766,12 @@
% \end{macro}
%
%
-% \begin{macro}{FV@BreakAutoIndent}
+% \begin{macro}{FV@breakautoindent}
% Auto indentation of continuation lines to indentation of original line. Adds to |\FV@BreakIndent|.
% \begin{macrocode}
-\newboolean{FV@BreakAutoIndent}
+\newbool{FV@breakautoindent}
\define@booleankey{FV}{breakautoindent}%
- {\FV@BreakAutoIndenttrue}{\FV@BreakAutoIndentfalse}
+ {\booltrue{FV@breakautoindent}}{\boolfalse{FV@breakautoindent}}
\fvset{breakautoindent=true}
% \end{macrocode}
% \end{macro}
@@ -4675,25 +4925,26 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\FV@Break@Token}
-% Macro that controls token handling between |\FancyVerbBreakStart| and |\FancyVerbBreakStop|. Initially |\let| to |\relax|; later |\let| to |\FV@Break@AnyToken| or |\FV@Break@BeforeAfterToken| as appropriate. There is no need to |\let\FV@Break@Token\relax| when |breakanywhere|, |breakbefore|, and |breakafter| are not in use. In that case, |\FancyVerbBreakStart| and |\FancyVerbBreakStop| are |\let| to |\relax|, and |\FV@Break@Token| is never invoked.
+% \begin{macro}{\FV@Break@DefaultToken}
+% Macro that controls default token handling between |\FancyVerbBreakStart| and |\FancyVerbBreakStop|. Initially |\let| to |\FV@Break@NBToken|, which does not insert breaks. Later |\let| to |\FV@Break@AnyToken| or |\FV@Break@BeforeAfterToken| if |breakanywhere| or |breakbefore|/|breakafter| are in use.
% \begin{macrocode}
-\let\FV@Break@Token\relax
+\let\FV@Break@DefaultToken\FV@Break@NBToken
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{FV@BreakAnywhere}
+% \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.
% \begin{macrocode}
-\newboolean{FV@BreakAnywhere}
+\newbool{FV@breakanywhere}
\define@booleankey{FV}{breakanywhere}%
- {\FV@BreakAnywheretrue
+ {\booltrue{FV@breakanywhere}%
\let\FancyVerbBreakStart\FV@Break
\let\FancyVerbBreakStop\FV@EndBreak
- \let\FV@Break@Token\FV@Break@AnyToken}%
- {\FV@BreakAnywherefalse
+ \let\FV@Break@DefaultToken\FV@Break@AnyToken}%
+ {\boolfalse{FV@breakanywhere}%
\let\FancyVerbBreakStart\relax
- \let\FancyVerbBreakStop\relax}
+ \let\FancyVerbBreakStop\relax
+ \let\FV@Break@DefaultToken\FV@Break@NBToken}
\fvset{breakanywhere=false}
% \end{macrocode}
% \end{macro}
@@ -4706,24 +4957,25 @@
\ifstrempty{#1}%
{\let\FV@BreakBefore\@empty
\let\FancyVerbBreakStart\relax
- \let\FancyVerbBreakStop\relax}%
+ \let\FancyVerbBreakStop\relax
+ \let\FV@Break@DefaultToken\FV@Break@NBToken}%
{\def\FV@BreakBefore{#1}%
\let\FancyVerbBreakStart\FV@Break
\let\FancyVerbBreakStop\FV@EndBreak
- \let\FV@Break@Token\FV@Break@BeforeAfterToken}%
+ \let\FV@Break@DefaultToken\FV@Break@BeforeAfterToken}%
}
\fvset{breakbefore={}}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{FV@BreakBeforeGroup}
-% Determine whether breaking before specified characters is always allowed before each individual character, or is only allowed before the first in a group of identical characters.
+% \begin{macro}{FV@breakbeforeinrun}
+% Determine whether breaking before specified characters is always allowed before each individual character, or is only allowed before the first in a run of identical characters.
% \begin{macrocode}
-\newboolean{FV@BreakBeforeGroup}
-\define@booleankey{FV}{breakbeforegroup}%
- {\FV@BreakBeforeGrouptrue}%
- {\FV@BreakBeforeGroupfalse}%
-\fvset{breakbeforegroup=true}
+\newbool{FV@breakbeforeinrun}
+\define@booleankey{FV}{breakbeforeinrun}%
+ {\booltrue{FV@breakbeforeinrun}}%
+ {\boolfalse{FV@breakbeforeinrun}}%
+\fvset{breakbeforeinrun=false}
% \end{macrocode}
% \end{macro}
%
@@ -4770,24 +5022,25 @@
\ifstrempty{#1}%
{\let\FV@BreakAfter\@empty
\let\FancyVerbBreakStart\relax
- \let\FancyVerbBreakStop\relax}%
+ \let\FancyVerbBreakStop\relax
+ \let\FV@Break@DefaultToken\FV@Break@NBToken}%
{\def\FV@BreakAfter{#1}%
\let\FancyVerbBreakStart\FV@Break
\let\FancyVerbBreakStop\FV@EndBreak
- \let\FV@Break@Token\FV@Break@BeforeAfterToken}%
+ \let\FV@Break@DefaultToken\FV@Break@BeforeAfterToken}%
}
\fvset{breakafter={}}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{FV@BreakAfterGroup}
-% Determine whether breaking after specified characters is always allowed after each individual character, or is only allowed after groups of identical characters.
+% \begin{macro}{FV@breakafterinrun}
+% Determine whether breaking after specified characters is always allowed after each individual character, or is only allowed after the last in a run of identical characters.
% \begin{macrocode}
-\newboolean{FV@BreakAfterGroup}
-\define@booleankey{FV}{breakaftergroup}%
- {\FV@BreakAfterGrouptrue}%
- {\FV@BreakAfterGroupfalse}%
-\fvset{breakaftergroup=true}
+\newbool{FV@breakafterinrun}
+\define@booleankey{FV}{breakafterinrun}%
+ {\booltrue{FV@breakafterinrun}}%
+ {\boolfalse{FV@breakafterinrun}}%
+\fvset{breakafterinrun=false}
% \end{macrocode}
% \end{macro}
%
@@ -4810,16 +5063,16 @@
}%
\def\FV@BreakAfter@Process@i##1{%
\ifcsname FV@BreakBefore@Token\detokenize{##1}\endcsname
- \ifthenelse{\boolean{FV@BreakBeforeGroup}}%
- {\ifthenelse{\boolean{FV@BreakAfterGroup}}%
+ \ifbool{FV@breakbeforeinrun}%
+ {\ifbool{FV@breakafterinrun}%
{}%
{\PackageError{fvextra}%
- {Conflicting breakbeforegroup and breakaftergroup for "\detokenize{##1}"}%
- {Conflicting breakbeforegroup and breakaftergroup for "\detokenize{##1}"}}}%
- {\ifthenelse{\boolean{FV@BreakAfterGroup}}%
+ {Conflicting breakbeforeinrun and breakafterinrun for "\detokenize{##1}"}%
+ {Conflicting breakbeforeinrun and breakafterinrun for "\detokenize{##1}"}}}%
+ {\ifbool{FV@breakafterinrun}%
{\PackageError{fvextra}%
- {Conflicting breakbeforegroup and breakaftergroup for "\detokenize{##1}"}%
- {Conflicting breakbeforegroup and breakaftergroup for "\detokenize{##1}"}}%
+ {Conflicting breakbeforeinrun and breakafterinrun for "\detokenize{##1}"}%
+ {Conflicting breakbeforeinrun and breakafterinrun for "\detokenize{##1}"}}%
{}}%
\fi
\g@addto@macro\FV@BreakAfter@Def{%
@@ -4944,6 +5197,20 @@
% \end{macro}
%
%
+% \begin{macro}{breaknonspaceingroup}
+% \begin{macro}{FV@breaknonspaceingroup}
+% When inserting breaks, insert breaks within groups (typically |{...}| but depends on |commandchars|) instead of skipping over them. This isn't the default because it is incompabile with many macros since it inserts breaks into all arguments. For those cases, redefining macros to use |\FancyVerbBreakStart...\FancyVerbBreakStop| to insert breaks is better.
+% \begin{macrocode}
+\newbool{FV@breaknonspaceingroup}
+\define@booleankey{FV}{breaknonspaceingroup}%
+ {\booltrue{FV@breaknonspaceingroup}}%
+ {\boolfalse{FV@breaknonspaceingroup}}
+\fvset{breaknonspaceingroup=false}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
% \subsubsection{Line breaking implementation}
%
% \paragraph{Helper macros}
@@ -4972,26 +5239,29 @@
% \begin{macro}{\FV@GetLineIndent}
% A macro that takes a line and determines the indentation, storing the indentation chars in |\FV@LineIndentChars|.
% \begin{macrocode}
-\def\FV@CleanRemainingChars#1\FV@Undefined{}
-\def\FV@GetLineIndent{\afterassignment\FV@CheckIndentChar\let\FV@NextChar=}
-\def\FV@CheckIndentChar{%
- \ifx\FV@NextChar\FV@Undefined\relax
- \let\FV@Next=\relax
- \else
- \ifx\FV@NextChar\FV@FVSpaceToken\relax
- \g@addto@macro{\FV@LineIndentChars}{\FV@FVSpaceToken}%
- \let\FV@Next=\FV@GetLineIndent
- \else
- \ifx\FV@NextChar\FV@FVTabToken\relax
- \g@addto@macro{\FV@LineIndentChars}{\FV@FVTabToken}%
- \let\FV@Next=\FV@GetLineIndent
+\def\FV@GetLineIndent{%
+ \@ifnextchar\FV@Sentinel
+ {\FV@GetLineIndent@End}%
+ {\ifx\@let@token\FV@FVSpaceToken
+ \let\FV@Next\FV@GetLineIndent@Whitespace
+ \else\ifx\@let@token\FV@FVTabToken
+ \let\FV@Next\FV@GetLineIndent@Whitespace
+ \else\ifcsname FV@PYG@Redefed\endcsname
+ \ifx\@let@token\FV@PYG@Redefed
+ \let\FV@Next\FV@GetLineIndent@Pygments
\else
- \let\FV@Next=\FV@CleanRemainingChars
+ \let\FV@Next\FV@GetLineIndent@End
\fi
- \fi
- \fi
- \FV@Next
-}
+ \else
+ \let\FV@Next\FV@GetLineIndent@End
+ \fi\fi\fi
+ \FV@Next}}
+\def\FV@GetLineIndent@End#1\FV@Sentinel{}
+\def\FV@GetLineIndent@Whitespace#1{%
+ \expandafter\def\expandafter\FV@LineIndentChars\expandafter{\FV@LineIndentChars#1}%
+ \FV@GetLineIndent}
+\def\FV@GetLineIndent@Pygments#1#2#3{%
+ \FV@GetLineIndent#3}
% \end{macrocode}
% \end{macro}
%
@@ -5019,82 +5289,227 @@
%
% \paragraph{Line scanning and break insertion macros}\hfill\\
%
-% \noindent The strategy here is to scan a line token-by-token, and insert breaks at appropriate points. An alternative would be to make characters active, and have them expand to literal versions of themselves plus appropriate breaks. Both approaches have advantages and drawbacks. A catcode-based approach could work, but in general would require redefining some existing active characters to insert both appropriate breaks and their original definitions. The current approach works regardless of catcodes. It is also convenient for working with macros that expand to single characters, such as those created in highlighting code with Pygments (which is used by \pkg{minted} and \pkg{pythontex}). In that case, working with active characters would not be enough, and scanning for macros (or redefining them) is necessary. With the current approach, working with more complex macros is also straightforward. Adding support for line breaks within a macro simply requires wrapping macro contents with |\FancyVerbBreakStart...\FancyVerbBreakStop|. A catcode-based approach could require |\scantokens| or a similar retokenization in some cases, but would have the advantage that in other cases no macro redefinition would be needed.
+% \noindent The strategy here is to scan through text token by token, inserting potential breaks at appropriate points. The final text with breaks inserted is stored in |\FV@BreakBuffer|, which is ultimately passed on to a wrapper macro like |\FancyVerbFormatText| or |\FancyVerbFormatInline|.
%
-% \begin{macro}{\FV@Break}
-% The entry macro for breaking lines, either anywhere or before/after specified characters. The current line (or argument) will be scanned token by token/group by group, and accumulated (with added potential breaks) in |\FV@TmpLine|. After scanning is complete, |\FV@TmpLine| will be inserted. It would be possible to insert each token/group into the document immediately after it is scanned, instead of accumulating them in a ``buffer.'' But that would interfere with macros. Even in the current approach, macros that take optional arguments are problematic.\footnote{Through a suitable definition that tracks the current state and looks for square brackets, this might be circumvented. Then again, in verbatim contexts, macro use should be minimal, so the restriction to macros without optional arguments should generally not be an issue.} The last token is tracked with |\FV@LastToken|, to allow lookbehind when breaking by groups of identical characters. |\FV@LastToken| is |\let| to |\FV@Undefined| any time the last token was something that shouldn't be compared against (for example, a non-empty group), and it is not reset whenever the last token may be ignored (for example, |{}|). When setting |\FV@LastToken|, it is vital always to use |\let\FV@LastToken=...| so that |\let\FV@LastToken==| will work (so that the equals sign |=| won't break things).
+% If user macros insert breaks via |\FancyVerbBreakStart...\FancyVerbBreakStop|, this invokes an additional scanning/insertion pass within each macro after expansion. The scanning/insertion only applies to the part of the expanded macros wrapped in |\FancyVerbBreakStart...\FancyVerbBreakStop|. At the time this occurs, during macro processing, text will already be wrapped in a wrapper macro like |\FancyVerbFormatText| or |\FancyVerbFormatInline|. That is, the built-in break insertion occurs before any typesetting, but user macro break insertion occurs during typesetting.
+%
+% Token comparison is currently based on |\ifx|. This is sufficient for verbatim text but a comparison based on |\detokenize| might be better for cases when |commandchars| is in use. For example, with |commandchars| characters other than the curly braces |{}| might be the group tokens.
+%
+% It would be possible to insert each token/group into the document immediately after it is scanned, instead of accumulating them in a ``buffer.'' But that would interfere with macros. Even in the current approach, macros that take optional arguments are problematic, since with some settings breaks will interference with optional arguments.\footnote{Through a suitable definition that tracks the current state and looks for square brackets, this might be circumvented. Then again, in verbatim contexts, macro use should be minimal, so the restriction to macros without optional arguments should generally not be an issue.}
%
-% The current definition of |\FV@Break@Token| is swapped for a UTF-8 compatible one under pdfTeX when necessary. The standard macros are defined next, since they make the algorithms simpler to understand. The more complex |UTF| variants are defined later.
+% The last token is tracked with |\FV@LastToken|, to allow lookbehind when breaking by groups of identical characters. |\FV@LastToken| is |\let| to |\FV@Undefined| any time the last token was something that shouldn't be compared against (for example, a non-empty group), and it is not reset whenever the last token may be ignored (for example, |{}|). When setting |\FV@LastToken|, it is vital always to use |\let\FV@LastToken=...| so that |\let\FV@LastToken==| will work (so that the equals sign |=| won't break things).
+%
+% \begin{macro}{FV@BreakBufferDepth}
+% Track buffer depth while inserting breaks. Some macros and command sequences require recursive processing. For example, groups |{...}| (with |commandchars| and |breaknonspaceingroup|), math, and nested |\FancyVerbBreakStart...\FancyVerbBreakStop|. Depth starts at zero. The current buffer at depth $n$ is always |\FV@BreakBuffer|, with other buffers |\FV@BreakBuffer<n>| etc.\ named via |\csname| to allow for the integer.
% \begin{macrocode}
-\def\FV@Break{%
- \def\FV@TmpLine{}%
+\newcounter{FV@BreakBufferDepth}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\FV@BreakBuffer@Append}
+% Append to |\FV@BreakBuffer|.
+% \begin{macrocode}
+\def\FV@BreakBuffer@Append#1{%
+ \expandafter\def\expandafter\FV@BreakBuffer\expandafter{\FV@BreakBuffer#1}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\FV@BreakBufferStart}
+% Create a new buffer, either at the beginning of scanning or during recursion. The single mandatory argument is the macro for handling tokens, which is |\let| to |\FV@Break@Token|. An intermediate |\FV@BreakBufferStart@i| is used to optimize |\ifx| comparisons for |\FV@BreakBufferStart| during scanning.
+%
+% For recursion, |\FV@BreakBuffer<n>| and |\FV@Break@Token<n>| store the state (buffer and token handling macro) immediately prior to recusion with depth |<n>|.
+% \begin{macrocode}
+\def\FV@BreakBufferStart{%
+ \FV@BreakBufferStart@i}
+\def\FV@BreakBufferStart@i#1{%
+ \ifnum\value{FV@BreakBufferDepth}>0\relax
+ \expandafter\let\csname FV@BreakBuffer\arabic{FV@BreakBufferDepth}\endcsname
+ \FV@BreakBuffer
+ \expandafter\let\csname FV@Break@Token\arabic{FV@BreakBufferDepth}\endcsname
+ \FV@Break@Token
+ \fi
+ \def\FV@BreakBuffer{}%
+ \let\FV@Break@Token=#1%
+ \stepcounter{FV@BreakBufferDepth}%
\let\FV@LastToken=\FV@Undefined
- \ifFV@pdfTeXinputenc
- \ifdefstring{\inputencodingname}{utf8}%
- {\ifx\FV@Break@Token\FV@Break@AnyToken
- \let\FV@Break@Token\FV@Break@AnyToken@UTF
- \else
- \ifx\FV@Break@Token\FV@Break@BeforeAfterToken
- \let\FV@Break@Token\FV@Break@BeforeAfterToken@UTF
- \fi
- \fi}%
- {}%
+ \FV@Break@Scan}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{FV@UserMacroBreaks}
+% Whether a user macro is inserting breaks, as opposed to \pkg{fvextra}'s standard scanning routine. When breaks come from \pkg{fvextra}, |\FV@BreakBufferStop| does nothing with |\FV@BreakBuffer| at buffer depth 0, since |\FV@InsertBreaks| handles buffer insertion. When breaks come from user macros, |\FV@BreakBufferStop| needs to insert |\FV@BreakBuffer| at buffer depth 0.
+% \begin{macrocode}
+\newbool{FV@UserMacroBreaks}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\FV@BreakBufferStop}
+% Complete the current buffer. The single mandatory argument is a wrapper macro for |\FV@BreakBuffer|'s contents (for example, insert recursively scanned group into braces |{...}|). If the mandatory argument is empty, no wrapper is used.
+%
+% 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.
+% \begin{macrocode}
+\def\FV@BreakBufferStop{%
+ \FV@BreakBufferStop@i}
+\def\FV@BreakBufferStop@i#1{%
+ \addtocounter{FV@BreakBufferDepth}{-1}%
+ \let\FV@LastToken=\FV@Undefined
+ \ifnum\value{FV@BreakBufferDepth}<0\relax
+ \PackageError{fvextra}%
+ {Line break insertion error (extra \string\FancyVerbBreakStop?)}%
+ {Line break insertion error (extra \string\FancyVerbBreakStop?)}%
+ \def\FV@BreakBuffer{}%
\fi
- \FV@Break@Scan
-}
+ \ifnum\value{FV@BreakBufferDepth}>0\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {\expandafter\FV@BreakBufferStop@ii\expandafter{\FV@BreakBuffer}{#1}}%
+ {\ifbool{FV@UserMacroBreaks}%
+ {\expandafter\let\expandafter\FV@BreakBuffer\expandafter\FV@Undefined\FV@BreakBuffer}%
+ {}}}
+\def\FV@BreakBufferStop@ii#1#2{%
+ \ifstrempty{#2}%
+ {\FV@BreakBufferStop@iii{#1}}%
+ {\expandafter\FV@BreakBufferStop@iii\expandafter{#2{#1}}}}
+\def\FV@BreakBufferStop@iii#1{%
+ \expandafter\let\expandafter\FV@BreakBufferUpLevel
+ \csname FV@BreakBuffer\arabic{FV@BreakBufferDepth}\endcsname
+ \expandafter\def\expandafter\FV@BreakBuffer\expandafter{\FV@BreakBufferUpLevel#1}%
+ \expandafter\let\expandafter\FV@Break@Token
+ \csname FV@Break@Token\arabic{FV@BreakBufferDepth}\endcsname
+ \FV@Break@Scan}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\FV@InsertBreaks}
+% This inserts breaks within text (|#2|) and stores the result in |\FV@BreakBuffer|. Then it invokes a macro (|#1|) on the result. That allows |\FancyVerbFormatInline| and |\FancyVerbFormatText| to operate on the final text (with breaks) directly, rather than being given text without breaks or text wrapped with macros that will (potentially recursively) insert breaks. (Breaks inserted by user macros are not yet present, though, since they are only inserted---potentially recursively---during macro processing.)
+%
+% The initial |\ifx| skips break insertion when break insertion is turned off (|\FancyVerbBreakStart| is |\relax|).
+%
+% The current definition of |\FV@Break@Token| is swapped for a UTF-8 compatible one under pdfTeX when necessary. In what follows, the default macros are defined after |\FV@Break|, since they make the algorithms simpler to understand. The more complex |UTF| variants are defined afterward.
+% \begin{macrocode}
+\def\FV@InsertBreaks#1#2{%
+ \ifx\FancyVerbBreakStart\relax
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {#1{#2}}%
+ {\ifFV@pdfTeXinputenc
+ \ifdefstring{\inputencodingname}{utf8}%
+ {\ifx\FV@Break@DefaultToken\FV@Break@AnyToken
+ \let\FV@Break@DefaultToken\FV@Break@AnyToken@UTF
+ \else
+ \ifx\FV@Break@DefaultToken\FV@Break@BeforeAfterToken
+ \let\FV@Break@DefaultToken\FV@Break@BeforeAfterToken@UTF
+ \fi
+ \fi}%
+ {}%
+ \fi
+ \setcounter{FV@BreakBufferDepth}{0}%
+ \boolfalse{FV@UserMacroBreaks}%
+ \FancyVerbBreakStart#2\FancyVerbBreakStop
+ \setcounter{FV@BreakBufferDepth}{0}%
+ \booltrue{FV@UserMacroBreaks}%
+ \expandafter\FV@InsertBreaks@i\expandafter{\FV@BreakBuffer}{#1}}}
+\def\FV@InsertBreaks@i#1#2{%
+ \let\FV@BreakBuffer\FV@Undefined
+ #2{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\FV@Break}
+% The entry macro for break insertion. Whatever is delimited (after expansion) by |\FV@Break...\FV@EndBreak| will be scanned token by token/group by group, and accumulated (with any added breaks) in |\FV@BreakBuffer|. After scanning is complete, |\FV@BreakBuffer| will be inserted.
+% \begin{macrocode}
+\def\FV@Break{%
+ \FV@BreakBufferStart{\FV@Break@DefaultToken}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\FV@EndBreak}
% \begin{macrocode}
-\def\FV@EndBreak{\FV@TmpLine}
+\def\FV@EndBreak{%
+ \FV@BreakBufferStop{}}
% \end{macrocode}
% \end{macro}
%
+%
% \begin{macro}{\FV@Break@Scan}
% Look ahead via |\@ifnextchar|. Don't do anything if we're at the end of the region to be scanned. Otherwise, invoke a macro to deal with what's next based on whether it is math, or a group, or something else.
%
-% This and some following macros are defined inside of groups, to ensure proper catcodes.
+% This and some following macros are defined inside of groups to ensure proper catcodes.
+%
+% The check against |\FV@BreakBufferStart| should typically not be necessary; it is included for completeness and to allow for future extensions and customization. |\FV@BreakBufferStart| is only inserted raw (rather than wrapped in |\FancyVerbBreakStart|) in token processing macros, where it initiates (or restarts) scanning and is not itself scanned.
+%
% \begin{macrocode}
\begingroup
-\catcode`\$=3%
+\catcode`\$=3
\gdef\FV@Break@Scan{%
- \@ifnextchar\FV@EndBreak%
+ \@ifnextchar\FancyVerbBreakStart%
{}%
- {\ifx\@let@token$\relax
+ {\ifx\@let@token\FancyVerbBreakStop
+ \let\FV@Break@Next\relax
+ \else\ifx\@let@token\FV@BreakBufferStart
+ \let\FV@Break@Next\relax
+ \else\ifx\@let@token\FV@BreakBufferStop
+ \let\FV@Break@Next\relax
+ \else\ifx\@let@token$
\let\FV@Break@Next\FV@Break@Math
+ \else\ifx\@let@token\bgroup
+ \let\FV@Break@Next\FV@Break@Group
\else
- \ifx\@let@token\bgroup\relax
- \let\FV@Break@Next\FV@Break@Group
- \else
- \let\FV@Break@Next\FV@Break@Token
- \fi
- \fi
- \FV@Break@Next}%
-}
+ \let\FV@Break@Next\FV@Break@Token
+ \fi\fi\fi\fi\fi
+ \FV@Break@Next}}
\endgroup
% \end{macrocode}
% \end{macro}
%
+%
% \begin{macro}{\FV@Break@Math}
-% Grab an entire math span, and insert it into |\FV@TmpLine|. Due to grouping, this works even when math contains things like |\text{$x$}|. After dealing with the math span, continue scanning.
+% Grab an entire math span, and insert it into |\FV@BreakBuffer|. Due to grouping, this works even when math contains things like |\text{$x$}|. After dealing with the math span, continue scanning.
% \begin{macrocode}
\begingroup
\catcode`\$=3%
\gdef\FV@Break@Math$#1${%
- \g@addto@macro{\FV@TmpLine}{$#1$}%
- \let\FV@LastToken=\FV@Undefined
- \FV@Break@Scan}
+ \FV@BreakBufferStart{\FV@Break@NBToken}#1\FV@BreakBufferStop{\FV@Break@MathTemplate}}
+\gdef\FV@Break@MathTemplate#1{$#1$}
\endgroup
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\FV@Break@Group}
-% Grab the group, and insert it into |\FV@TmpLine| (as a group) before continuing scanning.
+% Grab the group, and insert it into |\FV@BreakBuffer| (as a group) before continuing scanning.
% \begin{macrocode}
\def\FV@Break@Group#1{%
- \g@addto@macro{\FV@TmpLine}{{#1}}%
- \ifstrempty{#1}{}{\let\FV@LastToken=\FV@Undefined}%
+ \ifstrempty{#1}%
+ {\FV@BreakBuffer@Append{{}}%
+ \FV@Break@Scan}%
+ {\ifbool{FV@breaknonspaceingroup}%
+ {\FV@BreakBufferStart{\FV@Break@DefaultToken}%
+ #1\FV@BreakBufferStop{\FV@Break@GroupTemplate}}%
+ {\FV@BreakBufferStart{\FV@Break@NBToken}%
+ #1\FV@BreakBufferStop{\FV@Break@GroupTemplate}}}}
+\def\FV@Break@GroupTemplate#1{{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\FV@Break@NBToken}
+% Append token to buffer while adding no breaks (|NB|) and reset last token.
+% \begin{macrocode}
+\def\FV@Break@NBToken#1{%
+ \FV@BreakBuffer@Append{#1}%
+ \let\FV@Break@LastToken=\FV@Undefined
\FV@Break@Scan}
% \end{macrocode}
% \end{macro}
@@ -5113,7 +5528,7 @@
%\catcode`\+=12%
%\gdef\FV@Break...
% \ifcat\noexpand#1a%
-% \g@addto@macro{\FV@TmpLine}...
+% \FV@BreakBuffer@Append...
% \else
%...
%\endgroup
@@ -5122,7 +5537,7 @@
%
% \begin{macrocode}
\def\FV@Break@AnyToken#1{%
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakAnywhereBreak#1}%
+ \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}%
\FV@Break@Scan}
% \end{macrocode}
% \end{macro}
@@ -5131,6 +5546,8 @@
% Deal with breaking around only specified tokens. This is a bit trickier. We only break if a macro corresponding to the token exists. We also need to check whether the specified token should be grouped, that is, whether breaks are allowed between identical characters. All of this has to be written carefully so that nothing is accidentally inserted into the stream for future scanning.
%
% Dealing with tokens followed by empty groups (for example, |\x{}|) is particularly challenging when we want to avoid breaks between identical characters. When a token is followed by a group, we need to save the current token for later reference (|\x| in the example), then capture and save the following group, and then---only if the group was empty---see if the following token is identical to the old saved token.
+%
+% The |\csname @let@token\endcsname| prevents issues if |\@let@token| is ever |\else| or |\fi|.
% \begin{macrocode}
\def\FV@Break@BeforeAfterToken#1{%
\ifcsname FV@BreakBefore@Token\detokenize{#1}\endcsname
@@ -5145,75 +5562,72 @@
\FV@Break@Next{#1}%
}
\def\FV@Break@BeforeAfterTokenNoBreak#1{%
- \g@addto@macro{\FV@TmpLine}{#1}%
+ \FV@BreakBuffer@Append{#1}%
\let\FV@LastToken=#1%
\FV@Break@Scan}
\def\FV@Break@BeforeTokenBreak#1{%
- \ifthenelse{\boolean{FV@BreakBeforeGroup}}%
+ \ifbool{FV@breakbeforeinrun}%
+ {\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname
+ \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}%
+ \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan
+ \def\FV@RescanToken{#1}%
+ \else
+ \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}%
+ \let\FV@Break@Next\FV@Break@Scan
+ \let\FV@LastToken=#1%
+ \fi}%
{\ifx#1\FV@LastToken\relax
\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname
\let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan
\def\FV@RescanToken{#1}%
\else
- \g@addto@macro{\FV@TmpLine}{#1}%
+ \FV@BreakBuffer@Append{#1}%
\let\FV@Break@Next\FV@Break@Scan
\let\FV@LastToken=#1%
\fi
\else
\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakBeforeBreak}%
+ \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}%
\let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan
\def\FV@RescanToken{#1}%
\else
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakBeforeBreak#1}%
+ \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}%
\let\FV@Break@Next\FV@Break@Scan
\let\FV@LastToken=#1%
\fi
\fi}%
- {\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakBeforeBreak}%
- \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan
- \def\FV@RescanToken{#1}%
- \else
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakBeforeBreak#1}%
- \let\FV@Break@Next\FV@Break@Scan
- \let\FV@LastToken=#1%
- \fi}%
\FV@Break@Next}
\def\FV@Break@BeforeTokenBreak@AfterRescan{%
\expandafter\FV@Break@AfterTokenBreak\FV@RescanToken}
\def\FV@Break@AfterTokenBreak#1{%
\let\FV@LastToken=#1%
\@ifnextchar\FV@FVSpaceToken%
- {\g@addto@macro{\FV@TmpLine}{#1}\FV@Break@Scan}%
- {\ifthenelse{\boolean{FV@BreakAfterGroup}}%
+ {\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
- \g@addto@macro{\FV@TmpLine}{#1}%
+ \FV@BreakBuffer@Append{#1}%
\let\FV@Break@Next\FV@Break@Scan
\else
- \ifx\@let@token\bgroup\relax
- \g@addto@macro{\FV@TmpLine}{#1}%
+ \expandafter\ifx\csname @let@token\endcsname\bgroup\relax
+ \FV@BreakBuffer@Append{#1}%
\let\FV@Break@Next\FV@Break@AfterTokenBreak@Group
\else
- \g@addto@macro{\FV@TmpLine}{#1\FancyVerbBreakAfterBreak}%
+ \FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}%
\let\FV@Break@Next\FV@Break@Scan
\fi
\fi}%
- {\g@addto@macro{\FV@TmpLine}{#1\FancyVerbBreakAfterBreak}%
- \let\FV@Break@Next\FV@Break@Scan}%
\FV@Break@Next}%
}
\def\FV@Break@AfterTokenBreak@Group#1{%
- \g@addto@macro{\FV@TmpLine}{{#1}}%
\ifstrempty{#1}%
- {\let\FV@Break@Next\FV@Break@AfterTokenBreak@Group@i}%
- {\let\FV@Break@Next\FV@Break@Scan\let\FV@LastToken=\FV@Undefined}%
- \FV@Break@Next}
-\def\FV@Break@AfterTokenBreak@Group@i{%
- \@ifnextchar\FV@LastToken%
- {\FV@Break@Scan}%
- {\g@addto@macro{\FV@TmpLine}{\FancyVerbBreakAfterBreak}%
- \FV@Break@Scan}}
+ {\FV@BreakBuffer@Append{{}}%
+ \@ifnextchar\FV@LastToken%
+ {\FV@Break@Scan}%
+ {\FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}%
+ \FV@Break@Scan}}%
+ {\FV@Break@Group{#1}}}
% \end{macrocode}
% \end{macro}
%
@@ -5289,16 +5703,16 @@
\expandafter\FV@BreakAfter@Process@ii\expandafter{##1}}%
\def\FV@BreakAfter@Process@ii##1{%
\ifcsname FV@BreakBefore@Token\detokenize{##1}\endcsname
- \ifthenelse{\boolean{FV@BreakBeforeGroup}}%
- {\ifthenelse{\boolean{FV@BreakAfterGroup}}%
+ \ifbool{FV@breakbeforeinrun}%
+ {\ifbool{FV@breakafterinrun}%
{}%
{\PackageError{fvextra}%
- {Conflicting breakbeforegroup and breakaftergroup for "\detokenize{##1}"}%
- {Conflicting breakbeforegroup and breakaftergroup for "\detokenize{##1}"}}}%
- {\ifthenelse{\boolean{FV@BreakAfterGroup}}%
+ {Conflicting breakbeforeinrun and breakafterinrun for "\detokenize{##1}"}%
+ {Conflicting breakbeforeinrun and breakafterinrun for "\detokenize{##1}"}}}%
+ {\ifbool{FV@breakafterinrun}%
{\PackageError{fvextra}%
- {Conflicting breakbeforegroup and breakaftergroup for "\detokenize{##1}"}%
- {Conflicting breakbeforegroup and breakaftergroup for "\detokenize{##1}"}}%
+ {Conflicting breakbeforeinrun and breakafterinrun for "\detokenize{##1}"}%
+ {Conflicting breakbeforeinrun and breakafterinrun for "\detokenize{##1}"}}%
{}}%
\fi
\g@addto@macro\FV@BreakAfter@Def{%
@@ -5318,7 +5732,7 @@
%
%
% \begin{macro}{\FV@Break@AnyToken@UTF}
-% Instead of just adding each token to |\FV@TmpLine| with a preceding break, also check for multi-byte code points and capture the remaining bytes when they are encountered.
+% Instead of just adding each token to |\FV@BreakBuffer| with a preceding break, also check for multi-byte code points and capture the remaining bytes when they are encountered.
% \begin{macrocode}
\def\FV@Break@AnyToken@UTF#1{%
\ifcsname FV@U8:\detokenize{#1}\endcsname
@@ -5330,7 +5744,7 @@
\FV@Break@Next{#1}%
}
\def\FV@Break@AnyToken@UTF@i#1{%
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakAnywhereBreak#1}%
+ \FV@BreakBuffer@Append{\FancyVerbBreakAnywhereBreak#1}%
\FV@Break@Scan}
% \end{macrocode}
% \end{macro}
@@ -5362,57 +5776,57 @@
\FV@Break@Next{#1}%
}
\def\FV@Break@BeforeAfterTokenNoBreak@UTF#1{%
- \g@addto@macro{\FV@TmpLine}{#1}%
+ \FV@BreakBuffer@Append{#1}%
\def\FV@LastToken{#1}%
\FV@Break@Scan}
\def\FV@Break@BeforeTokenBreak@UTF#1{%
\def\FV@CurrentToken{#1}%
- \ifthenelse{\boolean{FV@BreakBeforeGroup}}%
+ \ifbool{FV@breakbeforeinrun}%
+ {\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname
+ \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}%
+ \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan@UTF
+ \def\FV@RescanToken{#1}%
+ \else
+ \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}%
+ \let\FV@Break@Next\FV@Break@Scan
+ \def\FV@LastToken{#1}%
+ \fi}%
{\ifx\FV@CurrentToken\FV@LastToken\relax
\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname
\let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan@UTF
\def\FV@RescanToken{#1}%
\else
- \g@addto@macro{\FV@TmpLine}{#1}%
+ \FV@BreakBuffer@Append{#1}%
\let\FV@Break@Next\FV@Break@Scan
\def\FV@LastToken{#1}%
\fi
\else
\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakBeforeBreak}%
+ \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak}%
\let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan@UTF
\def\FV@RescanToken{#1}%
\else
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakBeforeBreak#1}%
+ \FV@BreakBuffer@Append{\FancyVerbBreakBeforeBreak#1}%
\let\FV@Break@Next\FV@Break@Scan
\def\FV@LastToken{#1}%
\fi
\fi}%
- {\ifcsname FV@BreakAfter@Token\detokenize{#1}\endcsname
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakBeforeBreak}%
- \let\FV@Break@Next\FV@Break@BeforeTokenBreak@AfterRescan@UTF
- \def\FV@RescanToken{#1}%
- \else
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakBeforeBreak#1}%
- \let\FV@Break@Next\FV@Break@Scan
- \def\FV@LastToken{#1}%
- \fi}%
\FV@Break@Next}
\def\FV@Break@BeforeTokenBreak@AfterRescan@UTF{%
\expandafter\FV@Break@AfterTokenBreak@UTF\expandafter{\FV@RescanToken}}
\def\FV@Break@AfterTokenBreak@UTF#1{%
\def\FV@LastToken{#1}%
\@ifnextchar\FV@FVSpaceToken%
- {\g@addto@macro{\FV@TmpLine}{#1}\FV@Break@Scan}%
- {\ifthenelse{\boolean{FV@BreakAfterGroup}}%
- {\g@addto@macro{\FV@TmpLine}{#1}%
+ {\FV@BreakBuffer@Append{#1}\FV@Break@Scan}%
+ {\ifbool{FV@breakafterinrun}%
+ {\FV@BreakBuffer@Append{#1\FancyVerbBreakAfterBreak}%
+ \let\FV@Break@Next\FV@Break@Scan}%
+ {\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}%
- {\g@addto@macro{\FV@TmpLine}{#1\FancyVerbBreakAfterBreak}%
- \let\FV@Break@Next\FV@Break@Scan}%
\FV@Break@Next}%
}
\def\FV@Break@AfterTokenBreak@UTF@i#1{%
@@ -5423,30 +5837,27 @@
\def\FV@NextToken{#1}%
\ifx\FV@LastToken\FV@NextToken
\else
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakAfterBreak}%
+ \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}%
\fi
\let\FV@Break@Next\FV@Break@Scan
\fi
\FV@Break@Next#1}
\def\FV@Break@AfterTokenBreak@Group@UTF#1{%
- \g@addto@macro{\FV@TmpLine}{{#1}}%
\ifstrempty{#1}%
- {\let\FV@Break@Next\FV@Break@AfterTokenBreak@Group@UTF@i}%
- {\let\FV@Break@Next\FV@Break@Scan\let\FV@LastToken=\FV@Undefined}%
- \FV@Break@Next}
-\def\FV@Break@AfterTokenBreak@Group@UTF@i{%
- \@ifnextchar\bgroup%
- {\FV@Break@Scan}%
- {\FV@Break@AfterTokenBreak@Group@UTF@ii}}
-\def\FV@Break@AfterTokenBreak@Group@UTF@ii#1{%
+ {\FV@BreakBuffer@Append{{}}%
+ \@ifnextchar\bgroup
+ {\FV@Break@Group}%
+ {\FV@Break@AfterTokenBreak@Group@UTF@i}}%
+ {\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
- \let\FV@UTF@octets@after\FV@Break@AfterTokenBreak@Group@UTF@ii
+ \let\FV@UTF@octets@after\FV@Break@AfterTokenBreak@Group@UTF@i
\else
\def\FV@NextToken{#1}%
\ifx\FV@LastToken\FV@NextToken
\else
- \g@addto@macro{\FV@TmpLine}{\FancyVerbBreakAfterBreak}%
+ \FV@BreakBuffer@Append{\FancyVerbBreakAfterBreak}%
\fi
\let\FV@Break@Next\FV@Break@Scan
\fi
@@ -5508,9 +5919,9 @@
\savebox{\FV@LineBox}{%
\advance\FV@LineWidth by -\FV@BreakIndent
\hbox to \FV@BreakIndent{\hfill}%
- \ifthenelse{\boolean{FV@BreakAutoIndent}}%
+ \ifbool{FV@breakautoindent}%
{\let\FV@LineIndentChars\@empty
- \FV@GetLineIndent#1\FV@Undefined
+ \FV@GetLineIndent#1\FV@Sentinel
\savebox{\FV@LineIndentBox}{\FV@LineIndentChars}%
\hbox to \wd\FV@LineIndentBox{\hfill}%
\advance\FV@LineWidth by -\wd\FV@LineIndentBox
@@ -5529,12 +5940,11 @@
\noindent\hspace*{-\FV@BreakIndent}%
\ifdefempty{\FancyVerbBreakSymbolLeft}{}{%
\hspace*{-\FV@BreakSymbolIndentLeft}}%
- \ifthenelse{\boolean{FV@BreakAutoIndent}}%
+ \ifbool{FV@breakautoindent}%
{\hspace*{-\wd\FV@LineIndentBox}}%
{}%
\FV@BreakByTokenAnywhereHook
- \strut\FancyVerbFormatText{%
- \FancyVerbBreakStart #1\FancyVerbBreakStop}\nobreak\strut
+ \strut\FV@InsertBreaks{\FancyVerbFormatText}{#1}\nobreak\strut
\end{internallinenumbers*}
}%
\ifdefempty{\FancyVerbBreakSymbolRight}{}%
@@ -5569,6 +5979,8 @@
\setcounter{FV@TrueTabCounter}{0}%
\fi
\sbox{\FV@LineBox}{%
+ \let\FancyVerbBreakStart\relax
+ \let\FancyVerbBreakStop\relax
\FancyVerbFormatLine{%
%\FancyVerbHighlightLine %<-- Default definition using \rlap breaks breaking
{\FV@ObeyTabs{\FancyVerbFormatText{#1}}}}}%
@@ -5596,6 +6008,8 @@
\let\FV@Tab\FV@TrueTab
\fi
\else
+ \let\FancyVerbBreakStart\relax
+ \let\FancyVerbBreakStop\relax
\FV@LeftListNumber
\FV@LeftListFrame
\FancyVerbFormatLine{%
@@ -5790,6 +6204,8 @@
% In the |breakbytoken| cases, an |\hbox| is used to prevent breaks within the macro (breaks could occur at spaces even without |\FancyVerbBreakStart|). The |breakbytokenanywhere| case is similar but a little tricky. |\FV@BreakByTokenAnywhereHook|, which is inside |\FV@SaveLineBox| where line breaking occurs, is used to define |\FV@BreakByTokenAnywhereBreak| so that it will ``do nothing'' the first time it is used and on subsequent invocations become |\FancyVerbBreakByTokenAnywhereBreak|. Because the hook is within the |internallinenumbers*| environment, the redefinition doesn't escape, and the default global definition of |\FV@BreakByTokenAnywhereBreak| as |\relax| is not affected. We don't want the actual break to appear before the first Pygments macro in case it might cause a spurious break after leading whitespace. But we must have breaks \emph{before} Pygments macros because otherwise lookahead would be necessary.
%
% An intermediate variable |\FV@PYG| is defined to avoid problems in case |#1|$=$|#2|. There is also a check for a non-existant |#2| (|\PYG|\meta{style\_name} may not be created until a later compile in the \pkg{pythontex} case); if |#2| does not exist, fall back to |#1|. For the existance check, |\ifx...\relax| must be used instead of |\ifcsname|, because |#2| will be a macro, and will typically be created with |\csname...\endcsname| which will |\let| the macro to |\relax| if it doesn't already exist.
+%
+% |\FV@PYG@Redefed| is |\let| to the Pygments macro that appears literally (after redefinition), so that it can be detected elsewhere to allow for special processing, such as in |breakautoindent|.
% \begin{macrocode}
\def\FV@VerbatimPygments#1#2{%
\edef\FV@PYG@Literal{\expandafter\FV@DetokMacro@StripSpace\detokenize{#1}}%
@@ -5798,9 +6214,9 @@
\def\FV@BreakAfterPrep@PygmentsHook{%
\expandafter\FV@BreakAfterPrep@Pygments\expandafter{\FV@PYG@Literal}}%
\ifx#2\relax
- \let\FV@PYG#1%
+ \let\FV@PYG=#1\relax
\else
- \let\FV@PYG#2%
+ \let\FV@PYG=#2\relax
\fi
\ifbool{FV@breakbytoken}%
{\ifbool{FV@breakbytokenanywhere}%
@@ -5814,6 +6230,7 @@
\leavevmode\hbox{\FV@PYG{##1}{##2}}}}}%
{\def#1##1##2{%
\FV@PYG{##1}{\FancyVerbBreakStart##2\FancyVerbBreakStop}}}%
+ \let\FV@PYG@Redefed=#1\relax
}
\let\FV@BreakByTokenAnywhereBreak\relax
\def\FV@DetokMacro@StripSpace#1 {#1}
diff --git a/macros/latex/contrib/fvextra/fvextra.ins b/macros/latex/contrib/fvextra/fvextra.ins
index f51badf010..f36b3c4715 100644
--- a/macros/latex/contrib/fvextra/fvextra.ins
+++ b/macros/latex/contrib/fvextra/fvextra.ins
@@ -1,4 +1,4 @@
-%% Copyright (C) 2016-2017 by Geoffrey M. Poore <gpoore@gmail.com>
+%% Copyright (C) 2016-2022 by Geoffrey M. Poore <gpoore@gmail.com>
%% --------------------------------------------------------------------------
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
@@ -18,6 +18,7 @@
\input docstrip.tex
\keepsilent
+\askforoverwritefalse
\usedir{tex/latex/fvextra}
@@ -25,7 +26,7 @@
This is a generated file.
-Copyright (C) 2016-2017 by Geoffrey M. Poore <gpoore@gmail.com>
+Copyright (C) 2016-2022 by Geoffrey M. Poore <gpoore@gmail.com>
--------------------------------------------------------------------------
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/fvextra/fvextra.pdf b/macros/latex/contrib/fvextra/fvextra.pdf
index 2ab6b4c164..d66fe66d14 100644
--- a/macros/latex/contrib/fvextra/fvextra.pdf
+++ b/macros/latex/contrib/fvextra/fvextra.pdf
Binary files differ