是否可以使用 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(例如,请参阅attachfile
和attachfile2
软件包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}