我如何才能让 minted 中包含的源代码可复制?

我如何才能让 minted 中包含的源代码可复制?

是否可以使用 minted 制作可复制的源代码?

下面是一个最简单的例子,我如何包含源代码(完全,用最少的java代码,GitHub):

\documentclass{beamer}
\usepackage[utf8]{inputenc} % this is needed for german umlauts
\usepackage[ngerman]{babel} % this is needed for german umlauts
\usepackage[T1]{fontenc}    % this is needed for correct output of umlauts in pdf
\usepackage{minted}         % needed for the inclusion of source code

\begin{document}
    \section{Section}
    \subsection{MySubSection}
    \begin{frame}{Blubtitle}
        \inputminted[linenos=true, numbersep=5pt, tabsize=4, fontsize=\small]{java}{IataCode.java}
    \end{frame}
\end{document}

当我复制结果时,我得到了这个:

public class IataCode {
public static void printIATACodes(String[] myArray) {
for (int i = 0; i < myArray.length; i++) {
System.out.println(myArray[i]);
}
}
7
public static void main(String[] args) {
String[] iataCodes = new String[4];
// Flughafen München
iataCodes[0] = "MUC";
// Flughafen Berlin Brandenburg
iataCodes[1] = "BER";
// Flughafen Augsburg
iataCodes[2] = "AGB";
printIATACodes(iataCodes);
}
8
9
10
11
12
13
14
15
16
17
18
}

但我想得到这个:

public class IataCode {
    public static void printIATACodes(String[] myArray) {
        for (int i = 0; i < myArray.length; i++) {
            System.out.println(myArray[i]);
        }
    }

    public static void main(String[] args) {
        String[] iataCodes = new String[4];
        // Flughafen München
        iataCodes[0] = "MUC";
        // Flughafen Berlin Brandenburg
        iataCodes[1] = "BER";
        // Flughafen Augsburg
        iataCodes[2] = "AGB";
        printIATACodes(iataCodes);
    }
}

所以,我基本上想知道我是否能实现(看编译的 PDF 和最小源代码示例你也可以亲自尝试一下 minted。

答案1

我可以帮忙设置行号,但不能帮忙设置缩进。我不确定是否可以在 PDF 中指定(至少以独立于查看器的方式)也应复制缩进。您可以考虑将源代码文件附加到 PDF(例如,请参阅attachfileattachfile2软件包embedfile)。

行号是由fancyvrb包生成的,而不是minted包本身生成的,因此需要accsupp对 进行修补fancyvrb,类似于listings链接答案中的 的修补。没有style像 中的行号那样的键listings,但fancyvrb手册建议修改\theFancyVerbLine宏。这是我在下面采取的方法(我只是覆盖了现有的定义而不是修补):

\documentclass{beamer}
\usepackage[utf8]{inputenc} % this is needed for german umlauts
\usepackage[ngerman]{babel} % this is needed for german umlauts
\usepackage[T1]{fontenc}    % this is needed for correct output of umlauts in pdf
\usepackage{minted}         % needed for the inclusion of source code

% from http://tex.stackexchange.com/questions/57151/how-do-i-prevent-conflicts-between-accsupp-and-hyperref
\usepackage{accsupp}
\newcommand\emptyaccsupp[1]{\BeginAccSupp{ActualText={}}#1\EndAccSupp{}}


%default definition is: \def\theFancyVerbLine{\rmfamily\tiny\arabic{FancyVerbLine}}
\let\theHFancyVerbLine\theFancyVerbLine% don't apply our patch to hyperref's version
\def\theFancyVerbLine{\rmfamily\tiny\emptyaccsupp{\arabic{FancyVerbLine}}}

\begin{document}
    \section{Section}
    \subsection{MySubSection}
    \begin{frame}{Blubtitle}
        \inputminted[linenos=true, numbersep=5pt, tabsize=4, fontsize=\small]{java}{IataCode.java}
    \end{frame}
\end{document}

答案2

如果替代方案accsupp不能按预期发挥作用。

这个想法是用不会被复制的(可扩展的)数字矢量图像来代替行号。

首先,创建 10 个文件num0.tex, num1.tex, ..., num9.tex

\documentclass[border=0.15pt]{standalone} % small border to prevent cutoff for 2,3,6,8,9
\begin{document}
\tiny 0
\end{document}
\documentclass[border=0.15pt]{standalone} % small border to prevent cutoff for 2,3,6,8,9
\begin{document}
\tiny 1
\end{document}

ETC。

使用 pdflatex 编译它们全部,然后使用 Ghostscript 将它们转换为轮廓:

gs -dNoOutputFonts -sDEVICE=pdfwrite -o vec0.pdf num0.pdf

ETC。

然后重新定义\theFancyVerbLine用正则表达式替换每个数字\includegraphics{vecN}

\documentclass{article}
\usepackage{minted}
\usepackage{graphicx}
\begin{document}

\ExplSyntaxOn
\RenewDocumentCommand{\theFancyVerbLine}{}
{
    \tl_set:Nx \l_tmpa_tl { \arabic{FancyVerbLine} }
    \regex_replace_all:nnN { (\d) } { \c{includegraphics}\cB{ vec\1 \cE} } \l_tmpa_tl
    \tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff

\begin{minted}[linenos]{java}
public class IataCode {
    public static void printIATACodes(String[] myArray) {
        for (int i = 0; i < myArray.length; i++) {
            System.out.println(myArray[i]);
        }
    }

    public static void main(String[] args) {
        String[] iataCodes = new String[4];
        // Flughafen München
        iataCodes[0] = "MUC";
        // Flughafen Berlin Brandenburg
        iataCodes[1] = "BER";
        // Flughafen Augsburg
        iataCodes[2] = "AGB";
        printIATACodes(iataCodes);
    }
}
\end{minted}
\end{document}

缺点是数字的字距会丢失。另一个缺点是,如果不重新执行整个过程,您将无法设置数字的样式。

选定部分代码的截图:

在此处输入图片描述

答案3

我移植了我的答案https://tex.stackexchange.com/a/680651/250119针对listings包到minted包。该答案解释了它的工作原理等。

\documentclass{article}
\usepackage{minted}
\usepackage{graphicx}
\usepackage{tikz}
\begin{document}


\RenewDocumentCommand\theFancyVerbLine{}{%
    \tikz[remember picture] \coordinate (line\the\value{FancyVerbLine});% remember this location
    % --
    \rmfamily\tiny\phantom{\arabic{FancyVerbLine}}% leave space equal to the line number itself
    % \tiny must be outside any group so that it applies to the following \kern
    % --
    \xappto\typesetPendingLineNumbers{\actualTypesetLineNumber{\the\value{FancyVerbLine}}}% remember to typeset it later
}

% this command must be robust because it's used inside \xappto
\NewDocumentCommand\actualTypesetLineNumber{m}{%
    \node [anchor=south west, inner sep=0pt] at (line#1){\rmfamily\tiny#1};% actually typeset it now, need to copy the \tiny here
}

\AddToHook{env/minted/begin}{%
    \gdef\typesetPendingLineNumbers{}%
}

\AddToHook{env/minted/after}{%
    \begin{tikzpicture}[remember picture, overlay]%
    \typesetPendingLineNumbers
    \end{tikzpicture}%
}

\begin{minted}[linenos]{java}
public class IataCode {
    public static void printIATACodes(String[] myArray) {
        for (int i = 0; i < myArray.length; i++) {
            System.out.println(myArray[i]);
        }
    }

    public static void main(String[] args) {
        String[] iataCodes = new String[4];
        // Flughafen München
        iataCodes[0] = "MUC";
        // Flughafen Berlin Brandenburg
        iataCodes[1] = "BER";
        // Flughafen Augsburg
        iataCodes[2] = "AGB";
        printIATACodes(iataCodes);
    }
}
\end{minted}

\RenewDocumentCommand\theFancyVerbLine{}{\rmfamily \tiny \arabic {FancyVerbLine}}  % default definition

\begin{minted}[linenos]{java}
public class IataCode {
    public static void printIATACodes(String[] myArray) {
        for (int i = 0; i < myArray.length; i++) {
            System.out.println(myArray[i]);
        }
    }

    public static void main(String[] args) {
        String[] iataCodes = new String[4];
        // Flughafen München
        iataCodes[0] = "MUC";
        // Flughafen Berlin Brandenburg
        iataCodes[1] = "BER";
        // Flughafen Augsburg
        iataCodes[2] = "AGB";
        printIATACodes(iataCodes);
    }
}
\end{minted}
\end{document}

相关内容