ミントリストからのテキストのコピーを無効にする

ミントリストからのテキストのコピーを無効にする

作成したリストにコピー可能なテキストを含めないようにしたいのですが、次のものを見つけました:

コピーできないテキストを含む 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.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 つの手順に従います。

  1. タイプセットされたリストを PDF にエクスポートします (同じページに収まる場合はスタンドアロン、リストが複数ページにまたがる場合は別のドキュメントクラスを使用します)。
  2. ゴーストスクリプトを実行してテキストをベクターパスに変換します。
  3. Ghostscript によって生成されたベクター パス pdf を minted 環境の位置にインポートします。

次に例を示します (スタンドアロンの場合)。

  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}

お気に入りの LaTeX エンジンを実行します>>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 をインポートします。*

このソリューションの利点: 1. ラスタライズされない、2. JPEG などの画像形式のエクスポートとインポートに比べてファイル サイズが小さくなる、3. 印刷品質が低下しない、4. コメントでリクエストされているように、これは複数ページにまたがる長いコード ブロックにも機能します。そのためには、スタンドアロンではなく article などのドキュメントクラスを使用し、ページのジオメトリをレポートのジオメトリと一致するように設定します。Ghostscript は、複数ページにまたがる PDF を、複数ページにまたがる同等のベクター パス PDF に変換できます。その後、LaTeX コードに別の PDF ドキュメントを追加する場合と同じようにインポートできます。

  • 注: PDF ビューアによっては、これらのベクター パスを選択できる場合もありますが、ワード プロセッサまたはエディターに貼り付けてみると、テキストがコピーされないことがわかります (この時点ではテキストが残っていないため)。

関連情報