I have written a custom latex .cls
file to establish a typesetting workflow for the scientific journals of my research institute. The texts should be written in Markdown and then be processed with pandoc
to LaTeX.
I already have an elaborated pandoc template to produce the LaTeX preambel etc. So far its working great.
But for the figures I need the caption from the Markdown file to be set with \sidecaption
instead of \caption
in LaTeX, as well as with an optional argument (short-caption) for the image attribution in the list of figures.
To get the latter working I use the following template from a GitHub discussion in the pandoc repo:
PANDOC_VERSION:must_be_at_least '3.1'
if FORMAT:match 'latex' then
function Figure(f)
local short = f.content[1].content[1].attributes['short-caption']
if short and not f.caption.short then
f.caption.short = pandoc.Inlines(short)
end
return f
end
end
That works without any flaws.
But now I need to figure out how to change the LaTeX macro used for the caption. The older approach of pre pandoc version 3.0 posted by @tarleb is really intuitive and I could have easily adapted it to my needs. But since pandoc 3.0 there is the new complex figures approach and, so far, I couldn't figure out how to change the LaTeX macro used for the captions with this new behaviour.
I tried something like that (Adapted from here:
if FORMAT:match 'latex' then
function RawBlock (raw)
local caption = raw.text:match('\\caption')
if caption then
raw:gsub('\\caption', '\\sidecaption')
end
return raw
end
end
But nothing happened.
The main challenge for me are my more-or-less non-existing lua skills. I just never had to use it for my daily tasks. I thought about using awk
or sed
to edit the .tex
file itself using a regex-substitution, but that should remain an absolute stopgap, since it makes the whole workflow less portable.
Thus, I'm hoping for a hint/a solution in form of a pandoc-lua script which 1. helps me to achieve the goal, and 2. improve my understanding of lua and the complex figures approach for similar future tasks.
Edit
The plain LaTeX solution suggested by Julien is not a real option. The \caption
macro is very complex in the backend and cannot be copied on the fly via \let
, \NewCommandCopy
or something similar. Even after doing so with e.g. \NewCommandCopy{\oldcaption}{\caption}
and then setting \RenewDocumentCommand{\caption}{o m}{\sidecaption[#1]{#2}}
nothing changes and the definition of \caption
, checked with \meaning
or something similar, stays the same as before (even \DeclareDocumentCommand
doesn't work).
In the end, it might be possible to somehow change the \caption
macro itself. But the effort might not be worth the result (and its more of a question for TeX.SE).
There must be a simpler solution using Lua. Maybe the writer option also suggested by Julien is worth a try. But for that, my missing Lua skills remain as an obstacle. Right now, I'm using a sed script, which works just fine. But it limits the usage to Unix-Systems. Thus, a plain pandoc solution still is the goal to go.
There seems to be no easy way to alter or substitute the \caption
macro with a Lua filter converting from Markdown to Latex using pandoc, because the Latex control sequence used for the caption is kind of hardcoded in the Haskell Latex writer.
But there is another Lua solution using Lua(la)tex
which enables the processing of Lua code directly from within the tex document. Therefore, I included the following lines into my custom Latex template called with the --template
flag in pandoc:
\ifLuaTeX
\usepackage{luacode}
\begin{luacode*}
local count = 0
function replace_caption_with_sidecaption(line)
if string.find(line, "\\begin{figure}.*") then
in_figure_env = true
end
if string.find(line, "\\end{figure}") then
in_figure_env = false
end
if in_figure_env and string.find(line, "^(%s*)\\caption") then
if count == 0 then
line = line:gsub("\\caption", "\\sidecaption", 1)
local count = count + 1
end
end
return line
end
\end{luacode*}
\directlua{luatexbase.add_to_callback("process_input_buffer", replace_caption_with_sidecaption, "replace_caption_with_sidecaption")}
\fi
This code substitutes evert \caption
string with \sidecaption
as long as it is located inside a figure
environment and there the first macro of the line.
It works great, but, of course, makes Lualatex
the mandatory compilation program.