将最后修改日期放在由 markdown + hyperref + javascript + fancyhdr 生成的 PDF 表单上?

将最后修改日期放在由 markdown + hyperref + javascript + fancyhdr 生成的 PDF 表单上?

这是我的 pandoc 版本:

pandoc --version
pandoc 2.3.1
Compiled with pandoc-types 1.17.5.1, texmath 0.11.1.1, skylighting 0.7.3
Default user data directory: /Users/vle/.pandoc
Copyright (C) 2006-2018 John MacFarlane
Web:  http://pandoc.org
This is free software; see the source for copying conditions.
There is no warranty, not even for merchantability or fitness
for a particular purpose.

以及测试markdown文档(testjs.md):

---
title: "Test Javascript"
geometry: "left=2.5cm,right=2cm,top=2cm,bottom=2cm"
output: pdf_document
header-includes:
    - \usepackage{hyperref}
    - \usepackage{fancyhdr}
    - \pagestyle{fancy}
    - \fancyhead[LE,LO]{Last Modified Date \TextField[name=opendate, calculate={var OpenDate = this.getField("opendate"); OpenDate.value = new Date();}]{}}
    - \fancyfoot[CO,CE]{Template Version \today}
    - \fancyfoot[LE,RO]{\thepage}

---

# Section

## Header :
*Try to set the current date when the PDF file is open*

\TextField[name=datefield,%
              width = \hsize,%
              height = 3cm,%
              multiline=true,%
              bordercolor= ,%
              % color = 1 1 1,%
              calculate={var d = this.getField("datefield"); d.value = new Date();}
              ]{}

\pagebreak

## Header :
*Try to set the current date when the PDF file is open*

\TextField[name=datefield1,%
              width = \hsize,%
              height = 3cm,%
              multiline=true,%
              bordercolor= ,%
              % color = 1 1 1,%
              calculate={var e = this.getField("datefield"); e.value = new Date();}
              ]{}

\pagebreak

## Header :
*Try to set the current date when the PDF file is open*

\TextField[name=datefield2,%
              width = \hsize,%
              height = 3cm,%
              multiline=true,%
              bordercolor= ,%
              % color = 1 1 1,%
              calculate={var f = this.getField("datefield"); f.value = new Date();}
              ]{}

渲染命令:

pandoc --number-section -o testjs.pdf testjs.md

在 macOS 上的 Acrobat Professional DC 中打开的输出 PDF 如下所示: 在此处输入图片描述

问题:

  1. “上次修改日期”标题字段的文本字段中未显示日期。
  2. 所有三个页面正文的文本字段中均未显示日期。

  3. 由于文本字段名称冲突,第 3 页上的文本字段“上次修改日期”未出现。

我该如何解决这些问题?

更新:

我想我找到了一些线索:一定有一些事件触发 javascript 来更新字段。因此,更实际的问题是如何在某些onsave事件或onclick某些表单按钮上更新标题。我更喜欢onsave保存整个文档并更新时间戳。

答案1

我找不到独自完成此事的方法hyperref

使用存在两个问题hyperref

  1. 表单字段应该包含在一个Form环境中,而我在尝试从 JavaScript 设置字段内容时遇到了问题,因为没有这样做(就像在您的 MWE 中一样)。添加此环境会让 Adob​​e Reader 认为这是一个真正的 PDF 表单,这似乎有点奇怪。
  2. hyperref不提供对 Acrobatwillsave文档事件的访问权限,而这是您情况下最自然的事件。

为了解决第一个问题,我建议使用pdfcomment包并使用FreeText注释而不是表单文本字段。

幸运的是,第二个问题很容易解决。

尝试一下这个 MWE。虽然很简单latex,但你可以让它适应你的pandocMarkDown 工作流程。

它有什么作用?

  • 将选项传递en-USdatetime2pdfcomment似乎默认使用该iso选项)。
  • 设置FreeText注释标志使其只读(pdfcomment硬编码它们以仅打开打印)。
  • 编写在文档即将保存时运行的 JavaScript 代码。该代码获取文档中的所有注释并将内容设置为当前日期。(这并不那么聪明,并且假设唯一的注释是日期戳注释。如果有其他注释,您可以相当轻松地使其更聪明。)
  • 用于\pdfcatalog设置文档willsave事件来调用我们的代码。
  • FreeText使用看起来漂亮的注释并将\pdfcomment其初始化为\today
  • 设置标题。

它似乎可以很好地处理多页。

\documentclass{book}
\PassOptionsToPackage{en-US}{datetime2}
\usepackage{pdfcomment}
\makeatletter
% Set FreeText annotation flags to Print (bit 3) and ReadOnly (bit 7)
\patchcmd{\pc@annot@freetext}
  {/F 4}
  {/F 68}
  {}
  {}
\def\willsavecode{%
  this.syncAnnotScan ();
  var annots = this.getAnnots ();
  for (var i = 0; i < annots.length; i++)
    annots[i].contents = util.printd ("mmmm d, yyyy", new Date ());
}
\pdfcatalog{/AA<</WS<</S/JavaScript/JS(\Hy@escapestring{\willsavecode})>>>>}
\makeatother
\newcommand*{\datestamp}{%
  \pdffreetextcomment[%
    width=6cm,
    height=\normalbaselineskip,
    hoffset=1em,
    voffset=-\dp\strutbox,
    linewidth=0pt,
    color=,
    fontsize=10pt]{\today}}
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhead[LE,LO]{Last Modified Date: \datestamp}
\fancyfoot[CO,CE]{Template Version: \today}
\fancyfoot[LE,RO]{\thepage}
\begin{document}
Filler text.
\end{document}

相关内容