禁止從已建立的清單複製文本

禁止從已建立的清單複製文本

我希望我創建的列表沒有可複製的文字。我發現了這個:

是否可以產生包含不可複製文字的 PDF?

但經過幾個小時的試驗後,我無法將其與我的文件整合。我正在使用一個簡單的 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

首先,我完全同意傑西奈特的看法:

  • 在你們學院提出這個要求的人都是虐待狂

但如果您使用 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.texconvert哪裡影像魔法

\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 個步驟:

  1. 將排版產生的清單匯出為 pdf(如果適合同一頁面,則單獨使用;如果清單跨越多個頁面,則使用另一個文件類別),
  2. 運行 Ghostscript 將文字轉換為向量路徑,
  3. 在鑄造環境的位置匯入由 Ghostscript 產生的向量路徑 pdf。

這是一個範例(獨立):

  1. 步驟 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}

運行你最喜歡的乳膠引擎,我用過>>lualatex --shell-escape minted.tex。它將產生看起來像這樣的 minted.pdf: 可複製的文本

  1. 使用命令運行以下腳本:>>./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"
  1. 將 mintedpath.pdf 匯入到您計劃放置 Minted 程式碼的位置。

此解決方案的優點:1. 不會光柵化任何內容,2. 與匯出和匯入 jpeg 等影像格式相比,檔案大小會更小,3. 列印品質不會降低,4.根據您的評論中的要求,這也適用於跨多個頁面的長代碼塊,因為使用像文章這樣的文檔類而不是獨立的,並設置頁面的幾何形狀以匹配您的報告的幾何形狀。 Ghostscript 可以將跨頁的 pdf 轉換為跨多個頁面的等效向量路徑 pdf,然後可以將其匯入,就像您在 Latex 程式碼中新增另一個 pdf 文件一樣。

  • 注意:根據 pdf 檢視器,您可能仍然可以選擇這些向量路徑,但嘗試將它們貼到文字處理器或編輯器中,以意識到它不會複製任何文字(因為此時沒有留下任何文字)。

相關內容