summaryrefslogtreecommitdiff
path: root/paper/lua-filters/table-short-captions/table-short-captions.lua
diff options
context:
space:
mode:
Diffstat (limited to 'paper/lua-filters/table-short-captions/table-short-captions.lua')
-rw-r--r--paper/lua-filters/table-short-captions/table-short-captions.lua160
1 files changed, 160 insertions, 0 deletions
diff --git a/paper/lua-filters/table-short-captions/table-short-captions.lua b/paper/lua-filters/table-short-captions/table-short-captions.lua
new file mode 100644
index 0000000..6f4970b
--- /dev/null
+++ b/paper/lua-filters/table-short-captions/table-short-captions.lua
@@ -0,0 +1,160 @@
+---LaTeXTableShortCapts – enable `.unlisted` and `short-caption=""` properties
+-- for Pandoc conversion to LaTeX
+
+--[[
+Copyright (c) 2019 Blake Riley
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+]]
+local List = require 'pandoc.List'
+
+-- don't do anything unless we target latex
+if FORMAT ~= "latex" then
+ return {}
+end
+
+--- Code for injection into the LaTeX header,
+-- to overwrite a macro in longtable captions.
+longtable_caption_mod = [[
+% -- begin:latex-table-short-captions --
+\makeatletter\AtBeginDocument{%
+\def\LT@c@ption#1[#2]#3{% % Overwrite the workhorse macro used in formatting a longtable caption.
+ \LT@makecaption#1\fnum@table{#3}%
+ \@ifundefined{pandoctableshortcapt}
+ {\def\@tempa{#2}} % Use default behaviour: argument in square brackets
+ {\let\@tempa\pandoctableshortcapt} % If defined (even if blank), use to override
+ \ifx\@tempa\@empty\else % If @tempa is blank, no lot entry! Otherwise, @tempa becomes the lot title.
+ {\let\\\space
+ \addcontentsline{lot}{table}{\protect\numberline{\thetable}{\@tempa}}}%
+ \fi}
+}\makeatother
+% -- end:latex-table-short-captions --
+]]
+
+--- Creates a def shortcaption block to be placed before the table
+-- @tparam ?string sc : The short-caption property value
+-- @treturn Plain : The def shortcaption block
+local function defshortcapt(sc)
+ local scblock = List:new{}
+ scblock:extend {pandoc.RawInline('tex', "\\def\\pandoctableshortcapt{")}
+ if sc then
+ scblock:extend (pandoc.read(sc).blocks[1].c)
+ end
+ scblock:extend {pandoc.RawInline('tex', "}")}
+ if not sc then
+ scblock:extend {pandoc.RawInline('tex', " % .unlisted")}
+ end
+ return pandoc.Plain(scblock)
+end
+
+--- The undef shortcaption block to be placed after the table
+local undefshortcapt = pandoc.RawBlock('tex', "\\let\\pandoctableshortcapt\\relax")
+
+--- Parses a mock "Table Attr".
+-- We use the Attr of an empty Span as if it were Table Attr.
+-- This function extracts what is needed to build a short-caption.
+-- @tparam Attr attr : The Attr of the property Span in the table caption
+-- @treturn ?string : The identifier
+-- @treturn ?string : The "short-caption" property, if present.
+-- @treturn bool : Whether ".unlisted" appeared in the classes
+local function parse_table_attrs(attr)
+ -- Find label
+ local label = nil
+ if attr.identifier and (#attr.identifier > 0) then
+ label = attr.identifier
+ end
+
+ -- Look for ".unlisted" in classes
+ local unlisted = false
+ if attr.classes:includes("unlisted") then
+ unlisted = true
+ end
+
+ -- If not unlisted, then find the property short-caption.
+ local short_caption = nil
+ if not unlisted then
+ if (attr.attributes["short-caption"]) and
+ (#attr.attributes["short-caption"] > 0) then
+ short_caption = attr.attributes['short-caption']
+ end
+ end
+
+ return label, short_caption, unlisted
+end
+
+--- Wraps a table with shortcaption code
+-- @tparam Table tbl : The table with {}-wrapped properties in the caption
+-- @treturn List[Blocks] : The table with {label} in the caption,
+-- optionally wrapped in shortcaption code
+function rewrite_longtable_caption(tbl)
+ -- Escape if there is no caption present.
+ if not tbl.caption then
+ return nil
+ end
+
+ -- Try find the properties block
+ local is_properties_span = function (inl)
+ return (inl.t) and (inl.t == "Span") -- is span
+ and (inl.content) and (#inl.content == 0) -- is empty span
+ end
+ local propspan, idx = tbl.caption:find_if(is_properties_span)
+
+ -- If we couldn't find properties, escape.
+ if not propspan then
+ return nil
+ end
+
+ -- Otherwise, parse it all
+ local label, short_caption, unlisted = parse_table_attrs(propspan.attr)
+
+ -- Excise the span from the caption
+ tbl.caption[idx] = nil
+
+ -- Put label back into caption for pandoc-crossref
+ if label then
+ tbl.caption:extend {pandoc.Str("{#"..label.."}")}
+ end
+
+ -- Place new table
+ local result = List:new{}
+ if short_caption or unlisted then
+ result:extend {defshortcapt(short_caption)}
+ end
+ result:extend {tbl}
+ if short_caption or unlisted then
+ result:extend {undefshortcapt}
+ end
+ return result
+end
+
+--- Inserts longtable_caption_mod into the header_includes
+-- @tparam Meta meta : The document metadata
+-- @treturn Meta : The document metadata, with replacement LaTeX macro
+-- in header_includes
+function add_longtable_caption_mod(meta)
+ local header_includes = -- test ? a : b
+ (meta['header-includes'] and meta['header-includes'].t == 'MetaList')
+ and meta['header-includes']
+ or pandoc.MetaList{meta['header-includes']}
+ header_includes[#header_includes + 1] =
+ pandoc.MetaBlocks{pandoc.RawBlock('tex', longtable_caption_mod)}
+ meta['header-includes'] = header_includes
+ return meta
+end
+
+return {
+ {
+ Meta = add_longtable_caption_mod,
+ Table = rewrite_longtable_caption,
+ }
+}