Deaktivieren Sie das Kopieren von Text aus der geprägten Liste

Deaktivieren Sie das Kopieren von Text aus der geprägten Liste

Ich möchte, dass meine erstellten Angebote keinen kopierbaren Text enthalten. Ich habe Folgendes gefunden:

Ist es möglich, ein PDF mit nicht kopierbarem Text zu erstellen?

Aber nach einigen Stunden des Ausprobierens gelingt es mir nicht, es in mein Dokument zu integrieren. Ich verwende ein einfaches LaTeX- reportDokument und kann es entweder mit XeTeX oder LuaLaTeX erstellen.

Beispieldokument:

% 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}

Dokumentieren

So soll der kopierte Text aussehen:

Chapter 1 Foo
1.1 Bar
This should be copyable.

And this again should be copyable.

Antwort1

Erstens stimme ich Jesse Knight voll und ganz zu:

  • Wer diese Forderung an Ihrer Fakultät gestellt hat, ist ein Sadist

Wenn Sie jedoch LuaTeX verwenden, können Sie die Glyph-Unicode-Zuordnung in der PDF-Datei zerstören, indem Sie eine spezielle Schriftartfunktion erstellen:

% 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}

Bei diesem Ansatz können Sie nicht dieselbe Schriftart im kopierbaren und im nicht kopierbaren Teil verwenden. Wenn Sie also eine beliebige Schriftart einmal mit nocopyund einmal ohne laden, wird nur die erste Einstellung berücksichtigt.

Wenn Sie den „normalen“ \texttt-Text und das wörtliche Material nicht beeinträchtigen möchten, können Sie für geprägte Blöcke eine spezielle Schriftart auswählen:

% 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}

Antwort2

Lösung

Vielleicht mein bisher größter Hack ...

main.tex: kompilieren mit --shell-escapeum zu ermöglichen\write18empfehlen

\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: Möglicherweise müssen Sie chmod +x code.shdie Ausführung des Skripts zulassen

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: Woconvert istBildmagie

\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}

... produziert main.pdf:

Ausgabe

Anmerkungen:

  • Probieren Sie es aus, code.texum den Stil zu finden, der Ihnen gefällt
  • Möglicherweise haben Sie Aliasing-Artefakte in den Codebildern, wir können nicht viel tun
  • Wenn Sie viel Code haben, wird Ihr Dokument groß sein
  • Bitten Sie mich nicht, dies unter Windows zum Laufen zu bringen
  • Wer diese Forderung an Ihrer Fakultät gestellt hat, ist ein Sadist

Antwort3

Wenn ich in Ihrer Situation wäre, würde ich diese 3 Schritte befolgen:

  1. Exportieren Sie die gesetzte, geprägte Auflistung in ein PDF (eigenständig, wenn es auf dieselbe Seite passt, oder verwenden Sie eine andere Dokumentklasse, wenn die Auflistung mehrere Seiten umfasst).
  2. Führen Sie Ghostscript aus, um Text in Vektorpfade umzuwandeln.
  3. Importieren Sie den von Ghostscript erstellten Vektorpfad-PDF an der Position der geprägten Umgebung.

Hier ist ein Beispiel (mit Standalone):

  1. Schritt 1: Nehmen wir an, wir haben jeden geprägten Code in einer eigenständigen Datei (es gibt möglicherweise andere Möglichkeiten, Inline-Code in eine separate PDF-Datei zu exportieren, ich weiß nicht wie)
% 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}

Führen Sie Ihre bevorzugte Latex-Engine aus. Ich habe verwendet >>lualatex --shell-escape minted.tex. Sie erzeugt eine Datei minted.pdf, die folgendermaßen aussieht: kopierbarer Text

  1. Führen Sie das folgende Skript mit dem Befehl aus:>>./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. Importieren Sie mintedpath.pdf an die Stelle, an der Sie Ihren geprägten Code haben wollten.*

Vorteil dieser Lösung: 1. Es wird nichts gerastert, 2. Die Dateigröße ist kleiner als beim Exportieren und Importieren von Bildformaten wie JPEG usw., 3. Die Druckqualität verschlechtert sich nicht,4. Wie in Ihren Kommentaren gefordert, funktioniert dies auch für lange Codeblöcke, die sich über mehrere Seiten erstrecken. Verwenden Sie dazu eine Dokumentklasse wie „Artikel“ statt „Standalone“ und legen Sie die Geometrie der Seite so fest, dass sie mit der Ihres Berichts übereinstimmt. Ghostscript kann ein seitenübergreifendes PDF in ein äquivalentes, mehrseitiges Vektorpfad-PDF konvertieren, das dann importiert werden kann, als ob Sie ein weiteres PDF-Dokument in Ihren Latex-Code einfügen würden.

  • Hinweis: Je nach PDF-Viewer können Sie diese Vektorpfade möglicherweise noch auswählen, aber versuchen Sie, sie in ein Textverarbeitungsprogramm oder einen Editor einzufügen, um festzustellen, dass kein Text kopiert wird (da an dieser Stelle kein Text übrig ist).

verwandte Informationen