cup-pdfで生成されたPDFからテキストをコピー/貼り付ける方法は?

cup-pdfで生成されたPDFからテキストをコピー/貼り付ける方法は?

Ubuntu 16.04のプリンタを使用してLibreOffice WriterでPDFを生成すると、cups-pdf結果の文書は大丈夫に見えますが、テキストが壊れてコピー/貼り付けができなくなります。

LO Writerの「PDFにエクスポート」ボタンを使用して同じ文書を印刷すると、コピー/貼り付けが正しく機能するため、この質問はcup-pdfに制限されます。

この問題を解決するには、cup-pdfプリンタで特別な設定(エンコードなど)を設定する必要がありますか?

答え1

私は同じ動作を確認しました。これは長い間持続した「バグ」[1] [2]であり、「cups-pdf」の作成者はそれをバグと見なしていないため、既存のパッチはアップストリームでは使用されません。

Ubuntuの場合、上記のPPAを使用すると機能しますが、今はテストできません。

もともとSlackwareを使用している人なら、より多くのスキルが必要です。 Slackware 14.2およびCUPS-PDF 3.0.1 [4]、[7]の場合、パッチ[5] [6]は機能しません。古すぎる。盲目的な試行錯誤の間に、私は実現可能な解決策を確立しようとしました[8]。

手動でインストールし、新しい「cups-pdf」をファイルごとに非常に慎重にインストールする必要があります。 SlackBuildとinstall.shを機能させるために提供することはできません。私のスキルが足りません。しかし、実際に問題はついに消えた。

既存のPDFプリンタを削除し、手動で提供されているCUPS-PDF_opt.ppdを使用してプリンタを追加するか、オプションでCUPS-PDF.ppdを削除する必要があります。

[1]https://www.linuxquestions.org/questions/linux-software-2/cannot-copy-text-from-pdfs-created-with-cups-pdf-4175440557/

[2]https://github.com/alexivkin/CUPS-PDF-to-PDF

[サム]https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=658004

[4]https://slackbuilds.org/repository/14.2/office/cups-pdf/

[5]https://bugs.launchpad.net/ubuntu/+source/cups-pdf/+bug/820820/+attachment/3878188/+files/04_add_pdf_passthrough_support.patch

[6]https://launchpadlibrarian.net/153781216/04_add_pdf_passthrough_support.patch

[7]https://bugs.launchpad.net/ubuntu/+source/cups-pdf/+bug/820820

[8]

--- a/extra/CUPS-PDF_noopt.ppd
+++ b/extra/CUPS-PDF_noopt.ppd
@@ -31,7 +31,8 @@
*ModelName:     "Generic CUPS-PDF Printer"
*ShortNickName: "Generic CUPS-PDF Printer"
*NickName:      "Generic CUPS-PDF Printer (no options)"
-*1284DeviceID:  "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:POSTSCRIPT;"
+*1284DeviceID:  "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;"
+*cupsFilter:    "application/pdf 0 -"
*% cupsFilter:    "application/vnd.cups-postscript 0 pstitleiconv"
*PSVersion: "(2017.000) 0"
*LanguageLevel: "2"
--- a/extra/CUPS-PDF_opt.ppd
+++ b/extra/CUPS-PDF_opt.ppd
@@ -31,7 +31,8 @@
*ModelName:     "Generic CUPS-PDF Printer"
*ShortNickName: "Generic CUPS-PDF Printer"
*NickName:      "Generic CUPS-PDF Printer (w/ options)"
-*1284DeviceID:  "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:POSTSCRIPT;"
+*1284DeviceID:  "MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;"
+*cupsFilter:    "application/pdf 0 -"
*% cupsFilter:    "application/vnd.cups-postscript 0 pstitleiconv"
*PSVersion: "(2017.000) 0"
*LanguageLevel: "2"
--- a/src/cups-pdf.c
+++ b/src/cups-pdf.c
@@ -60,6 +60,7 @@
extern int errno;

static FILE *logfp=NULL;
+int input_is_pdf=0;

static void log_event(short type, char message[], char *detail) {
    time_t secs;
@@ -427,7 +427,7 @@
    int len;
    cp_string setup;

-  printf("file cups-pdf:/ \"Virtual PDF Printer\" \"CUPS-PDF\" \"MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:POSTSCRIPT;\"\n");
+  printf("file cups-pdf:/ \"Virtual PDF Printer\" \"CUPS-PDF\" \"MFG:Generic;MDL:CUPS-PDF Printer;DES:Generic CUPS-PDF Printer;CLS:PRINTER;CMD:PDF,POSTSCRIPT;\"\n");

    if ((dir = opendir(CP_CONFIG_PATH)) != NULL) {
        while ((config_ent = readdir(dir)) != NULL) {
@@ -460,6 +461,7 @@
    cp_string buffer;
    int rec_depth,is_title=0;
    FILE *fpdest;
+  size_t bytes = 0; 

    if (fpsrc == NULL) {
        log_event(CPERROR, "failed to open source stream", NULL);
@@ -483,14 +485,39 @@
        log_event(CPSTATUS, "***Experimental Option: FixNewlines");
    else
        log_event(CPDEBUG, "using traditional fgets");
-  while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) {
+  while ((bytes = fread(buffer, sizeof(char), 4, fpsrc)) > 0) {
+    if (!strncmp(buffer, "%PDF", 4)) {
+      log_event(CPDEBUG, "found beginning of PDF code", buffer);
+      input_is_pdf=1;
+      break;
+    }
        if (!strncmp(buffer, "%!", 2) && strncmp(buffer, "%!PS-AdobeFont", 14)) {
            log_event(CPDEBUG, "found beginning of postscript code: %s", buffer);
            break;
        }
    }
-  log_event(CPDEBUG, "now extracting postscript code");
-  (void) fputs(buffer, fpdest);
+  log_event(CPDEBUG, "now extracting code");
+  fwrite(buffer, sizeof(char), bytes, fpdest);
+  if (input_is_pdf) {
+    while((bytes = fread(buffer, sizeof(char), BUFSIZE, fpsrc)) > 0)
+      fwrite(buffer, sizeof(char), bytes, fpdest);
+/* Commented out because decoding of utf16 PDF strings isn't implemented.
+    rewind(fpsrc);
+    while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) {
+      if (!is_title) {
+        char *begin = strstr(buffer, "/Title");
+        if (begin) {
+          char *end = strstr(begin, ">");
+          if (end) {
+            strncpy(title, begin+6, BUFSIZE);
+            log_event(CPDEBUG, "found title in PDF code", title);
+            is_title=1;
+          }
+        }
+      }
+    }*/
+  }
+  else {
    while (fgets2(buffer, BUFSIZE, fpsrc) != NULL) {
        (void) fputs(buffer, fpdest);
        if (!is_title && !rec_depth)
@@ -513,6 +540,7 @@
            }
        }
    }
+  }
    (void) fclose(fpdest);
    (void) fclose(fpsrc);
    log_event(CPDEBUG, "all data written to spoolfile: %s", spoolfile);
@@ -761,7 +789,12 @@
            (void) fclose(logfp);
        return 5;
    }
-  snprintf(gscall, size, Conf_GSCall, Conf_GhostScript, Conf_PDFVer, outfile, spoolfile);
+  if (input_is_pdf) {
+    snprintf(gscall, size, "cp %s %s", spoolfile, outfile);
+  }
+  else {
+    snprintf(gscall, size, Conf_GSCall, Conf_GhostScript, Conf_PDFVer, outfile, spoolfile);
+  }
    log_event(CPDEBUG, "ghostscript commandline built: %s", gscall);

    (void) unlink(outfile);

答え2

その場合は、この方法を試してみることもできます。 LibreofficeでPDFエクスポート機能をどのように使用しますか?その後、その時点から印刷したり、cup-pdfまたは任意のものを使用できます。

答え3

本当の問題はCUPS-PDFにないと思います。 Ghostscriptでもできません。答えを見つけたと思います...

一度見てください。私のワークフローは次のとおりです。

  • クラウドにサーバーがあり、cupとcup-pdfが正しく実行されています。
  • 私のコンピュータにIPPプリンタ(xxx.com:631/printer/My-Cups-Pdf-Printer)をインストールしました。
  • これで、すべてのアプリケーションのすべての文書をMy-Cups-Pdf-Printerに印刷できるようになり、ファイルはPDFに変換されてクラウドサーバーに保存されます。
  • わかりました...これは完璧に動作します。

今奇妙な部分は次のとおりです。

  • 後処理を活用して印刷後にいくつかの作業を行うために、PDFファイル(my-file.pdf)をMy-Cups-Pdf-Printerに「再印刷」したいとしましょう。
  • Chrome、Safari、Preview.app、AdobeReader.appからmy-file.pdfを印刷できます。
  • Preview.app、chrome、safariを使用して同じファイル(my-file.pdf)を印刷すると、pdfファイルが生成されます。検索不可能カップ-pdfに。
  • ただし、AdobeReader.appを使用して同じファイル(my-file.pdf)を印刷すると、pdfファイルが生成されます。検索可能カップ-pdfに。

問題は、AbobeReader.app(Chrome拡張ではない)にすべてのフォントエンコーディングが正しく含まれることです。 Safari、Chrome、Preview.appなどのアプリケーションのオペレーティングシステムで使用されるデフォルトのプリンタシステムには、このコマンドは含まれていません。結果は、フォントエンコード、場所に関する正しい指示がないPDFです。

問題はGhostscript(gs GSCall)にあるようです。しかし、そうではありません。問題はCUPS-PDFにありません。ゴーストスクリプトでも...

問題は、オペレーティングシステムのプリンタシステムがPSファイルを生成し、それをIPPプリンタ(My-Cups-Pdf-Printer)に送信する方法です。

誰かが問題がGhostscriptのバグかもしれないと思っていましたが、それも間違っていました。https://bugs.ghostscript.com/show_bug.cgi?id=692450

Ghostscriptを使ってコマンドラインからPSファイルをPDFに手動で変換してみましたが、同じ結果が得られました。 AdobeReaderでPSファイルが作成されます。検索可能テキスト。 Chrome、Safari、Preview.appのPSファイルは検索不可能テキスト。

MacOSとWindowsでも同じ状況が発生します。 AdobeReaderで印刷された両方のPDFファイル検索可能最後に、Ghostscriptとcup-pdfにPDFがあります。

他の人がPDFファイルをバイパスすることで、CUPS-PDFでこの問題を「修正」した方法が他のワークフローシナリオで機能する可能性があります(https://github.com/alexivkin/CUPS-PDF-to-PDF?tab=readme-ov-file)Ghostscriptに送信する前にcup-pdfのPDFファイルをバイパスするためです。

したがって、実際にはPS(プリンタのPostScriptファイル)を扱っていません。この場合、すでに単純なPDFファイルで作業しています。

関連情報