我希望我的铸造清单不包含可复制的文本。我发现了这一点:
但经过几个小时的尝试,我无法将其与我的文档集成。我使用的是一个简单的 LaTeXreport
文档,可以使用 XeTeX 或 LuaLaTeX 构建它。
示例文档:
% lualatex -shell-escape minted.tex
\begin{filecontents*}{test.rb}
# this should not be copyable
def hello
"world"
end
\end{filecontents*}
\documentclass[12pt,twoside,openright,a4paper]{report}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
\usepackage[dvipsnames]{xcolor}
\usepackage{minted}
\setmainfont{Times New Roman}
\definecolor{bg}{rgb}{0.95,0.95,0.95}
\begin{document}
\chapter{Foo}
\section{Bar}
This should be copyable.
\inputminted[linenos, numbersep=5pt, tabsize=2, bgcolor=bg]{ruby}{test.rb}
And this again should be copyable.
\end{document}
我希望复制的文本看起来像:
Chapter 1 Foo
1.1 Bar
This should be copyable.
And this again should be copyable.
答案1
首先,我完全同意 Jesse Knight 的观点:
- 你们学院提出这个要求的人是个虐待狂
但是如果您使用 LuaTeX,您可以通过创建特殊的字体功能来破坏 PDF 文件中的字形到 unicode 映射:
% lualatex -shell-escape minted.tex
\begin{filecontents*}{test.rb}
# this should not be copyable
def hello
"world"
end
\end{filecontents*}
\documentclass[12pt,twoside,openright,a4paper]{report}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
\usepackage[dvipsnames]{xcolor}
\usepackage{minted}
\setmainfont{Times New Roman}
\usepackage{luacode}
\begin{luacode*}
local function nocopy(tfmdata)
for _, c in next, tfmdata.characters do
c.tounicode = nil
end
end
fonts.handlers.otf.features.register {
name = "nocopy",
description = "disallow copying for this font",
manipulators = {
base = nocopy,
node = nocopy,
plug = nocopy,
}
}
\end{luacode*}
\setmonofont[RawFeature=nocopy]{Latin Modern Mono}
\definecolor{bg}{rgb}{0.95,0.95,0.95}
\begin{document}
\chapter{Foo}
\section{Bar}
This should be copyable.
\inputminted[linenos, numbersep=5pt, tabsize=2, bgcolor=bg]{ruby}{test.rb}
And this again should be copyable.
\end{document}
使用这种方法,您不能在可复制和不可复制的部分使用相同的字体,因此如果您一次加载带有任何字体nocopy
和一次不带有任何字体,则只会遵守第一个设置。
如果您不想影响“常规” \texttt 文本和逐字材料,您可以为铸造块选择特殊字体:
% lualatex -shell-escape minted.tex
\begin{filecontents*}{test.rb}
# this should not be copyable
def hello
"world"
end
\end{filecontents*}
\documentclass[12pt,twoside,openright,a4paper]{report}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
\usepackage[dvipsnames]{xcolor}
\usepackage{minted}
\setmainfont{Times New Roman}
\usepackage{luacode}
\begin{luacode*}
local function nocopy(tfmdata)
for _, c in next, tfmdata.characters do
c.tounicode = nil
end
end
fonts.handlers.otf.features.register {
name = "nocopy",
description = "disallow copying for this font",
manipulators = {
base = nocopy,
node = nocopy,
plug = nocopy,
}
}
\end{luacode*}
\newfontfamily\nocopyfont[RawFeature=nocopy]{Courier New}
\renewcommand\myFont{\nocopyfont}
\fvset{fontfamily=myFont}
\definecolor{bg}{rgb}{0.95,0.95,0.95}
\begin{document}
\chapter{Foo}
\section{Bar}
This should be copyable.
\inputminted[linenos, numbersep=5pt, tabsize=2, bgcolor=bg]{ruby}{test.rb}
And this again should be copyable (\texttt{This too}).
{
\tracingall\nocopyfont
}
\end{document}
答案2
解决方案
也许是我迄今为止最大的一次黑客攻击...
main.tex
:编译以--shell-escape
允许\write18
表彰
\documentclass[12pt,twoside,openright,a4paper]{report}
\usepackage{graphicx}
\newcommand{\nocopycode}[2]{%
\immediate\write18{./code.sh #1 #2}
\\[\textfloatsep]
\includegraphics[width=\linewidth]{{#2}.png}%
\\[\textfloatsep]
}
\usepackage{listings}
\begin{document}
\chapter{Foo}
\section{Bar}
This should be copyable.
\nocopycode{ruby}{hello.rb}
And this again should be copyable.
\end{document}
code.sh
:你可能必须chmod +x code.sh
允许脚本执行
echo \\def\\xstyle{$1} \\def\\xfile{$2} > code-config.tex
pdflatex -interaction=nonstopmode code.tex
convert -trim -density 300 code.pdf $2.png
code.tex
:convert
哪里图像魔法
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\lstset{
basicstyle=\ttfamily,
backgroundcolor=\color{lightgray},
}
\input{code-config.tex}
\begin{document}
\pagenumbering{gobble}
\lstinputlisting[language={\xstyle}]{\xfile}
\end{document}
... 生产main.pdf
:
笔记:
- 随意尝试,
code.tex
获得你喜欢的造型 - 您可能会发现代码图像中存在混叠伪影,我们无能为力
- 如果你有很多代码,你的文档大小将会很大
- 不要让我在 Windows 上实现这个功能
- 你们学院提出这个要求的人是个虐待狂
答案3
如果我处于你的情况,我会遵循以下 3 个步骤:
- 将排版好的列表导出为 pdf(如果适合同一页则为独立文件,如果列表跨越多页则使用另一个文档类),
- 运行 ghostscript 将文本转换为矢量路径,
- 在minted环境的位置导入ghostscript生成的矢量路径pdf。
这是一个示例(独立):
- 步骤 1:假设我们在一个独立文件中拥有所有铸造的代码(可能还有其他方法可以将内联代码导出到单独的 pdf,但我不知道如何操作)
% minted.tex
\documentclass{standalone}
\usepackage{minted}
\begin{document}
\begin{minipage}[t]{0.5\textwidth}
\begin{minted}{bash}
echo "Hello, world!"
\end{minted}
\end{minipage}
\end{document}
运行你最喜欢的 latex 引擎,我使用了>>lualatex --shell-escape minted.tex
。它将生成如下内容的 minted.pdf:
- 使用命令运行以下脚本:
>>./fonttopath.sh minted.pdf mintedpath.pdf
% fonttopath.sh
#!/bin/sh
if [ "x$1" = "x" -o "x$2" = "x" ]; then
echo Usage: `basename "$0"` "<input.pdf>" "<output.pdf>" >&2
exit 1
fi
gs -o "$2" -sDEVICE=pdfwrite -dNOCACHE -dNoOutputFonts -dNOSUBSTDEVICECOLORS -c 60000000 setvmthreshold -f "$1"
- 在您计划保存铸造代码的位置导入 mintedpath.pdf。*
此解决方案的优点:1. 不会对任何内容进行栅格化;2. 与导出和导入 jpeg 等图像格式相比,文件大小会更小;3. 打印质量不会下降;4. 根据您的评论要求,这也适用于跨多页的长代码块,为此使用 documentclass 如 article 而不是 standalone,并将页面的几何形状设置为与您的报告相匹配。 Ghostscript 可以将跨页的 pdf 转换为跨多页的等效矢量路径 pdf,然后可以将其导入,就像您在 latex 代码中添加另一个 pdf 文档一样。
- 注意:根据 pdf 查看器的不同,您可能仍然可以选择这些矢量路径,但尝试将它们粘贴到文字处理器或编辑器中,您会发现它不会复制任何文本(因为此时没有剩余文本)。