Pandoc: Add variables containing current date, current time and pandoc-version

Created on 3 Jul 2017  Â·  24Comments  Â·  Source: jgm/pandoc

I'm using Pandoc 1.19.2.1 on Windows 7. It's a nice product. I'd like to ask for global variables to be used in any input file type, but I happen to use Markdown to create EPUB files. Some variables I'd like are:

  1. %%pandoc_version%% = replaces variable %%pandoc_version%% with actual pandoc version like "1.19.2.1" but without the double quotes.
  2. %%current_date%% = replaces variable with the current date the output document was created. This is not the same as the file date on the source file. This is the date pandoc was run to create the output file, in my case, the EPUB2 file. In this variable the current date is in the same format as the operating system locale.
  3. %%current_date_yyyymmdd%% = replaces current date with this format: YYYYMMDD.
  4. %%current_time%% = replace variable with current time in whatever format is set for the OS locale.
  5. %%current_time_hhmm%% = replace variable with the current time the output document (like EPUB) was created, time in this format: hhmm.
  6. %%current_time_hhmmss%% = replace variable with the current time in this format: hhmmss.

Thank you!

enhancement

Most helpful comment

Can I ask for a change to allow Pandoc to use variables inside the body of the document, like in the Markdown?

All 24 comments

I'm not sure on %%pandoc_version%%. I thought of providing an online pandoc service and it could expose a (small?) security risk if users are easily able to determine which pandoc version is running. On the other hand, they may find it out with information from Github's issue tracker too.

You can always do something like

-V pandocversion="$(pandoc --version | head -1)" -V current_date="$(date +%Y-%m-%d%n)"

and so on. This way you have complete flexibility to set the variables as you wish.

Hello, I tried to use the variables like this but it isn't working. I have some commands in a DOS/cmd .bat file. Here's my pandoc command line in the .bat file:

pandoc -o %outname% -f markdown+backtick_code_blocks -t epub --toc -V pandocversion="$(pandoc --version)" -V curdate="$(date -T)" infile.md

Note that since I'm using the Windows 8 cmd.exe, some switches may be different on the date command, and I don't have a head util that works without a third party library dll.

Here's my example Markdown file called infile.md.

title:
- type: main
  text: My title
- type: subtitle
  text: EPUB v1.01
creator: 
- role: author
  text: by John Smith
rights: (c) 2017
...

Created on $curdate$ with

$pandocversion$

# Introduction

In the epub, the $curdate$ and $pandocversion$ just appear in italic, they are not replace with the actual date or pandoc version.

I figured out how to put the output of a command in a .bat file variable but it won't pass to pandoc. Here's my batch file so far:

@echo off
set outname=test.epub
set tempfile=%TEMP%/test.txt

rem You must redirect command output to a temp file, then
rem read the temp file via 'set /p'.
date /T > %tempfile%
set /p curdate=<%tempfile%
echo Date is: %curdate%

pandoc -v > %tempfile%
set /p pandocver=<%tempfile%
echo P ver is: %pandocver%
del %tempfile%

del %outname%
echo on
pandoc -o %outname% -f markdown+backtick_code_blocks -t epub -V pandocversion="%pandocver%" -V curdate="%curdate%" test.md 

Could someone point me in the right direction? Did I not turn an extension on? Am I using variables improperly in the Markdown? I'd prefer to have the variables in the Markdown, so the reader sees the values.

I'm going through the pandoc user guide and not finding any information yet.

My suggestion was for use in a unix shell. I don't know how to do the same thing in Windows, but I'm sure there's a way. You'd have to consult someone who knows more about Windows.

+++ bulrush15 [Jul 22 17 13:19 ]:

Hello, I tried to use the variables like this but it isn't working.
Here's my command line in DOS/cmd.exe:

pandoc -o %outname% -f markdown+backtick_code_blocks -t epub --toc -V
pandocversion="$(pandoc --version)" -V curdate="$(date -T)" infile.md

Note that since I'm using the Windows 8 cmd.exe, some switches may be
different on the date command, and I don't have a head util that works
without a third party library dll.

Here's my example Markdown file.

title:

  • type: main
    text: My title
  • type: subtitle
    text: EPUB v1.01
    creator:
  • role: author
    text: by John Smith
    rights: (c) 2017
    ...
    Created on $curdate$ with

$pandocversion$

Introduction

In the epub, the $curdate$ and $pandocversion$ just appear in italic,
they are not replace with the actual date or pandoc version.

Yes, the substitution of variables only works in templates.
These are in the body of your Markdown document.

Can I ask for a change to allow Pandoc to use variables inside the body of the document, like in the Markdown?

You can put variables into your document and use a filter:
http://scorreia.com/software/panflute/code.html#panflute.base.Element.replace_keyword

Although I do think having some of the proposed variables available to templates would be useful.

Hm. I don't know Python but I do know Perl. I could use some Perl one-liners to translate my variables to, say, a date in the Markdown just before I have Pandoc process the file.

I changed the title of this issue. I don't know how to use templates. Is there a step-by-step website to show beginners like me how to use Pandoc templates? The Pandoc user doc wasn't very clear.

Here is an example using the Ruby based filter library paru: https://github.com/htdebeer/paru/blob/master/examples/filters/add_today.rb — this adds metadata date which is used by several of the default templates:

Can I ask for a change to allow Pandoc to use variables inside the body of the document, like in the Markdown?

I'm looking for this as well, since Pandoc doesn't feature this already, as far as I know.

I would love to declare variables and call them from within a single Markdown document without the need for templates. To clarify, if Pandoc were to incorporate a feature where calling the following variable in a Markdown file ...

pagetitle: Foobar 123
---

# $pagetitle$

... resulted in the following when converted to HTML (rendered inside a browser):

Foobar 123

It would be an absolutely splendid feature to have.

All, never mind. I see that there's an open issue/request for what I was describing at #1950.

Sounds like you want something like this, which can be done with a lua filter easily enough:
https://pandoc.org/lua-filters.html#replacing-placeholders-with-their-metadata-value

The same approach could add the date or pandoc version.

Slightly improved version of above filter so it also works if the variable borders on punctuation like %this%! and for meta values passed via the command line:

local List = require 'pandoc.List'
local vars = {}

function get_vars (meta)
  for k, v in pairs(meta) do
    if v.t == 'MetaInlines' then
      vars['%' .. k .. '%'] = {table.unpack(v)}
    elseif type(v) == 'string' then
      vars['%' .. k .. '%'] = {pandoc.Str(v)}
    end
  end
end

function separate_variables (str)
  local s, last_end = str.text, 0
  local result = List:new()
  local var_start, var_end, prefix, var
  repeat
    var_start, var_end = s:find('%%%a+%%', last_end)
    if var_start then
      result:extend {
        pandoc.Str(s:sub(last_end + 1, var_start - 1)),
        pandoc.Str(s:sub(var_start, var_end))
      }
      last_end = var_end
    else
      table.insert(result, pandoc.Str(s:sub(last_end + 1, -1)))
    end
  until var_start == nil or last_end >= #s
  return result
end

function replace (el)
  return vars[el.text] or nil
end

return {{Meta = get_vars}, {Str = separate_variables}, {Str = replace}}

Note also that PANDOC_VERSION is available to lua filters as a global variable and could be used to populate a pandoc-version variable. The filter could also define variables for the current date and time.

Note also that a more robust approach might be to do the variables this way:

<?pandoc-version?> <?current-date?>

These will be parsed as raw HTML elements, so we avoid the trouble separating them from adjacent strings.

have a look at http://pandoc.org/MANUAL.html#templates

From the manual:

Templates contain variables, which allow for the inclusion of arbitrary information at any point in the file. They may be set at the command line using the -V/--variable option.

I don't see any examples in the manual of how to set a variable on the DOS command line for Pandoc. Can someone add that to the manual? I would have to use the --variable in order to grab the current date and time from cmd.exe. So what could the syntax of setting variables via --variable be?

  1. --variable:mydate=%date%
  2. --variable mydate=%date%
  3. --variable mydate %date%

Either 2 or --variable mydate:%date% should work. It's possible you'll need double quotes around %date% -- I'm sorry, I don't really know how Windows command line works.

If this doesn't work, you could fall back to this Lua filter. That method requires an additional filter file, but gives you more options to format the date.

I feel this issue can be closed, as ways to accomplish what the issue author needed have been show using templates and using (lua) filters. And insofar as discussion of non-template + non-filters solutions go, the (older) issue https://github.com/jgm/pandoc/issues/1950 supersedes this, as that is not just about a specific list of global variables, but about variables in general.

Agreed. Closing in favor of #1950 for the handling of variables in input documents.

Was this page helpful?
0 / 5 - 0 ratings