读取插入的 PDF 页面的元数据?

读取插入的 PDF 页面的元数据?

我只使用 lualatex,因此特定于编译器的答案就可以了。

考虑这个伪代码-MWE。包含的 PDF 始终是一页:

\documentclass{article}
\usepackage{pdfpages}
\def\includepdfifgood#1{
  % This is where I test the pdfproducer string in #1.
  % If wrong pdfproducer, compile halts with error message. Otherwise:
  \includepdf{#1}
}
\begin{document}
\includepdfifgood{something.pdf}
\end{document}

包含的页面必须是先前 lualatex 编译的输出。在先前的编译中,我可以(例如)设置pdfproducer为自定义字符串。我知道如何做到这一点。

所以,我需要做的是检查pdfproducer并接受或拒绝该文件。

我为什么要这样做:PDF/X(和 PDF/A)有严格的要求。如果此类文档中包含经过适当预处理的 PDF 页面,则它仍然可以是 PDF/X 或 PDF/A。否则,合规性可能会失败(而 TeX 不知道它失败了)。我知道如何进行预处理。现在我需要确保只有经过预处理的页面才允许进入另一个 PDF。

EDIT2:当我问这个问题时,我想到的是 PDF Producer 字符串。事实证明,Producer 字符串并不是最好的选择,因为当 Producer 更改版本号时,它可能会更改(例如)。最好使用用户可以直接设置的内容,例如标题、作者、主题或关键字。幸运的是,接受的代码适用于任何标准信息字典条目。无需修改它,因为在 luacode 中,它producer只是一个局部变量名,即使您正在寻找作者或其他任何东西,它也可以工作。

编辑:在先前的问题,我在 luacode 中得到了一个很棒的答案,我已经在使用它了。我问这个问题的理由是一样的,但情况不同。唉,我对 Lua 的了解还不够多,无法编辑链接的答案,否则我早就这么做了。

EDIT2:已将接受的答案充分利用!在novel软件包的 1.50 版本中,创建 CMYK 240% PDF/X-1a:2001 彩色封面图的过程已通过批处理/bash 脚本自动完成。首先,使用 ImageMagick 和 Ghostscript 将 RGB 图像(或 PDF)转换为不使用 TeX 的 CMYK 240% PDF(FlateDecode)。此 PDF 不是 PDF/X。但是,使用pdfmarkGhostscript 的功能,它在 PDF 信息字典中有一个自定义标签。然后,LuaLaTeX(带有novel)将该文件处理为 PDF/X-1a:2001。它会检查自定义标签,并且仅在检测到标签时才执行该过程。这就是它知道图像处于正确颜色空间中的方式,因为没有嵌入任何配置文件。结果已使用 Adob​​e Acrobat Pro 进行了验证(我相信,到目前为止,这是唯一可以做到这一点的程序)。

答案1

您可以使用以下代码来验证 Info 字典中的条目:

\documentclass{scrartcl}
\usepackage{luacode,pdfpages}
\begin{luacode*}
  function utf16to8(u16str)
    local result = ""
    local i = 1
    if #u16str % 2 == 1 then
      print("ERROR")
      return
    end
    while i < #u16str do
      local high, low = u16str:byte(i, i + 1)
      i = i + 2
      local current = bit32.replace(low, high, 8, 8)
      if bit32.band(high, 0xFC) == 0xD8 then
        current = bit32.replace(0, current, 10, 10)
        if i > #u16str then
          print("ERROR")
          return
        end
        high, low = u16str:byte(i, i + 1)
        i = i + 2
        current = bit32.replace(current, bit32.replace(low, high, 8, 8), 0, 10) + 0x10000
      elseif bit32.band(high, 0xFC) == 0xDC then
        print("ERROR")
        return
      end
      result = result .. unicode.utf8.char(current)
    end
    return result
  end
  function normalize_string(str)
    if str:sub(1,2) == "\xFE\xFF" then
      return utf16to8(str:sub(3))
    else
      return str
    end
  end
  function check_pdf_info(name, field, expected)
    local doc = epdf.open(name);
    if doc == nil then
      tex.sprint(luatexbase.catcodetables['latex-package'],
          "\\errmessage{Could not open " .. name .. "}{}{}\\@gobbletwo")
    else
      local producer = doc:getDocInfo():dictLookup(field)
      if not producer:isNull() and normalize_string(producer:getString()) == expected then
        tex.sprint(luatexbase.catcodetables['latex-package'], '\\@firstoftwo')
      else
        tex.sprint(luatexbase.catcodetables['latex-package'], '\\@secondoftwo')
      end
    end
  end
\end{luacode*}
\newcommand\PDFVerifyInfoFieldTF[3]{\directlua{check_pdf_info("\luaescapestring{#1}", "\luaescapestring{#2}", "\luaescapestring{#3}")}}
\begin{document}
\PDFVerifyInfoFieldTF{some_file.pdf}{Producer}{pdfTeX-1.40.8}{%
  \includepdf[pages=-]{some_file.pdf}%
}{%
  \errmessage{some_file.tex has the wrong producer}%
}
\end{document}

可能的字段:

  • 制片人:例如pdfTeX-1.40.18LuaTeX-1.0.4
  • 创建者:例如TeXLaTeX with hyperref package
  • 作者
  • 标题
  • 主题
  • 关键词
  • PTEX.全横幅: 例如This is LuaTeX, Version 1.0.4 (TeX Live 2017/Arch Linux))
  • 创建日期或者修改日期在这种情况下,这两个可能不是很有用。

相关内容