在 minted 中的任意字符处断行

在 minted 中的任意字符处断行

考虑任何包含minted不包含任何空格的大字符串的代码片段,例如:

\documentclass{article}
\usepackage{minted}
\setminted{breaklines}
\begin{document}
\begin{minted}{xml}
<?xml version="1.0"?>
abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabra
<project name="Package tcolorbox" default="documentation" basedir=".">
<description>
Apache Ant build file (http://ant.apache.org/)
</description>
</project>
\end{minted}
\end{document}

文档指出,使用选项 时breaklines,仅当出现空格时才会插入换行符。我的问题是:有没有办法扩展此原则,以便随时允许换行。即,字符串abra..在跨越 时会中断\textwidth

答案1

截至 2019 年 10 月,其他答案均不适用于我。经过研究,我发现 minted 已通过以下选项实现了此功能breakanywhere允许在任意位置换行

答案2

代码设置在Verbatim包的环境中fancyvrb。该breaklines功能是包的附加功能minted。过长的行在宏中处理\FV@SaveLineBox。示例修补了此宏以添加对正常连字的支持。在字体中,\ttfamily连字通常通过负数禁用\hyphenchar,请参阅问题\ttfamily不使用连字符破折号进行连字”

使用不可见的连字符(OT1T1编码):

\documentclass{article}
\usepackage{minted}
\usepackage{ragged2e}
\setminted{breaklines}
%\usepackage[T1]{fontenc}
%\usepackage{lmodern}

\usepackage{etoolbox}
\makeatletter
\patchcmd{\FV@SaveLineBox}{%
  \strut#1\strut
}{%
  \hyphenchar\font=%
    % Invisible hyphen:
    \if\expandafter\@car\f@encoding\relax\@nil O 255 \else 23 \fi
    % Visible hyphen:
    % `\- %
  \strut
  \nobreak % prevent line break by next \hspace
  \hspace{0pt}% allow hyphenation of first word
  #1%
  \nobreak % without the following \strut would prevent hyphenation of previous word
  \strut
}{}{%
  \errmessage{\noexpand\FV@SaveLineBox could not be patched}%
}
\makeatother

\begin{document}
\begin{minted}{xml}
<?xml version="1.0"?>
abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraab
<project name="Package tcolorbox" default="documentation" basedir=".">
  <description>
    Apache Ant build file (http://ant.apache.org/)
  </description>
</project>
\end{minted}
\end{document}

结果带有不可见的连字符

并且带有可见的连字符 ( \hyphenchar\font=`\-):

结果带有可见的连字符

因此,解决方案不会在每个字符处断行,而是遵循当前语言的连字模式。

答案3

这是一种扫描每一行并尝试在所有可能的位置插入潜在断点的方法,使用\discretionary。当长字符串是自然语言并且具有现有的连字模式时,Heiko Oberdiek 的方法可能会更好。但它似乎最多允许一个断点,并且不会中断混合字母和数字的字符串。如果您使用 verbatim 进行花哨的操作,我的方法会更脆弱,尽管典型的东西(mathescape 等)似乎有效。

所有代码都是作为 的扩展编写的fancyvrb。此代码的改进版本可能会出现在minted和的下一个版本中pythontex。最终,我计划将此代码和其他代码分离到一个扩展和修补 的包中fancyvrb

\documentclass[11pt]{article}

\usepackage[T1]{fontenc}

\usepackage{minted}
\setminted{style=default}

\makeatletter

%%%% First, a general solution for verbatim text, potentially with mathescape.
%%%% This doesn't allow breaks within macro args, because we can't know in
%%%% general (at least not without a lot of work) if a macro arg needs to be
%%%% left literal or have potential breaks inserted.
%%%% This reads a line into a temp macro, inserting potential break points.

%Characters inserted at break
\def\FancyVerbBreakChars{\discretionary{-}{}{}}

\def\FV@BreakAnywhere{%
  \def\FV@Tmp{}%
  \FV@BreakAnywhere@i
}

\def\FV@EndBreakAnywhere{\FV@Tmp}

\begingroup
\catcode`\$=3%
\gdef\FV@BreakAnywhere@i{%
  \@ifnextchar\FV@EndBreakAnywhere%
   {}%
   {\ifx\@let@token$\relax
      \let\FV@BreakAnywhere@Next\FV@BreakAnywhere@Math
    \else
      \ifx\@let@token\bgroup\relax
        \let\FV@BreakAnywhere@Next\FV@BreakAnywhere@Group
      \else
        \let\FV@BreakAnywhere@Next\FV@BreakAnywhere@Token
      \fi
    \fi
    \FV@BreakAnywhere@Next}%
}

\gdef\FV@BreakAnywhere@Math$#1${%
  \g@addto@macro{\FV@Tmp}{$#1$}%
  \FV@BreakAnywhere@i}
\endgroup

\def\FV@BreakAnywhere@Group#1{%
  \g@addto@macro{\FV@Tmp}{{#1}}%
  \FV@BreakAnywhere@i
}

\begingroup
\catcode`\a=11%
\catcode`\+=12%
\gdef\FV@BreakAnywhere@Token#1{%
  \ifcat\noexpand#1a\g@addto@macro{\FV@Tmp}{\FancyVerbBreakChars#1}%
  \else
    \ifcat\noexpand#1+\g@addto@macro{\FV@Tmp}{\FancyVerbBreakChars#1}%
    \else
      \g@addto@macro{\FV@Tmp}{#1}%
    \fi
  \fi
  \FV@BreakAnywhere@i
}
\endgroup

\patchcmd{\FV@SaveLineBox}%
 {\strut#1\strut}%
 {\strut\FV@BreakAnywhere#1\FV@EndBreakAnywhere\strut}%
 {}%
 {\errmessage{\noexpand\FV@SaveLineBox could not be patched}}


%%%% Next, a way to allow breaks in macro args.
%%%% This is needed for the Pygments style macros.
%%%% This is basically just a wrapper for what's already been defined,
%%%% used again as needed within macros.

\let\FancyVerbBreakAnywhereStart\FV@BreakAnywhere
\let\FancyVerbBreakAnywhereStop\FV@EndBreakAnywhere

% This assumes `default` Pygments style
% This needs `\setminted{style=default}` in the preamble, so that the
% style macros will already exist.
% Don't try breaks in Pygments `esc`apes, since they may contain 
% arbitrary LaTeX that my approach can't handle.
\let\OldPYG\PYGdefault
\def\PYGdefault#1#2{%
  \ifstrequal{#1}{esc}%
    {\OldPYG{#1}{#2}}
    {\OldPYG{#1}{\FancyVerbBreakAnywhereStart #2\FancyVerbBreakAnywhereStop}}}

\makeatother


\begin{document}


\begin{minted}[breaklines]{xml}
<?xml version="1.0"?>
abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabra
<project name="Package tcolorbox" default="documentation" basedir=".">
<description>
Apache Ant build file (http://ant.apache.org/)
</description>
</project>
\end{minted}


\begin{minted}[breaklines]{xml}
<?xml version="1.0"?>
abracadabraabracadabra34534abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabra34534abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabra34534abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabra
<project name="Package tcolorboxtcolorboxtcolorboxtcolorboxtcolorboxtcolorbox" default="documentation" basedir=".">
<description>
Apache Ant build file (http://ant.apache.org/)
</description>
</project>
\end{minted}


\begin{minted}[breaklines]{xml}
<?xml version="1.0"?>
abracadabraabracadabra34534abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabra34534abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabra34534abracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabraabracadabra
<project name="Package tcolorboxtcolorboxtcolorboxtcolorboxtcolorboxtcolorboxtcolorbox" default="documentation" basedir=".">
<description>
Apache Ant build file (http://ant.apache.org/)
</description>
</project>
\end{minted}

\end{document}

以下是原始代码块:

在此处输入图片描述

下面是第一个字符串更长的代码,其中混合了字母和数字。project标签中的一个字符串也更长,但由于有一个空格,因此在正常换行后仍然可以放在一行中。

在此处输入图片描述

现在标签中的字符串project太长,必须在字符之间断开。

在此处输入图片描述

答案4

Minted 通过 breaksymbol = =\small\carriagereturn 提供此类中断。此 breaksymbol 定义要中断的符号。因此,您可以在任何需要中断的地方使用此符号。例如,我们使用回车符。您可以在需要中断的地方放置回车符。

\usepackage{minted}
\usepackage{dingbat}

\begin{document}

\begin{minted}[breaklines, breaksymbolleft=\carriagereturn]{xml}
<?xml version="1.0"?>
abracadabraabracadabraabracadabr
aabracadabraabracadabraabracadab
raabracadabraabracadabraabracada
braabracadabra
<project name="Package tcolorbox" default="documentation" basedir=".">
<description>
Apache Ant build file (http://ant.apache.org/)
</description>
</project>
\end{minted}
\end{document}

相关内容