Files
2026-05-21 13:37:53 +08:00

92 lines
2.9 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
--- Modified from https://github.com/bcdavasconcelos/citetools/blob/main/_extensions/citetools/citation-backlinks.lua
--- Todo: even with link-citations and link-fields turned off, citation-backlinks still adds a single backlink to each reference in the final bibliography div.
--- citation-backlinks.lua adds citation backlinks to the bibliography
-- https://github.com/tarleb/citation-backlinks
--- Copyright: © 20222024 John MacFarlane and Albert Krewinkel and Bernardo Vasconcelos
--- License: MIT see LICENSE for details
-- Makes sure users know if their pandoc version is too old for this
-- filter.
PANDOC_VERSION:must_be_at_least '2.17'
-- cites is a table mapping citation item identifiers
-- to an array of cite identifiers
local cites = {}
-- counter for cite identifiers
local cite_number = 1
local function with_label(s, el)
if FORMAT == "latex" then
return { pandoc.RawInline("latex", "\\label{" .. s .. "}"), el }
end
if FORMAT == "typst" then
return { el, pandoc.RawInline("typst", " #label(\"" .. s .. "\")") }
end
if FORMAT == "docx" or FORMAT == "html" then
return { el }
end
end
function Cite(el)
local cite_id = "cite_" .. cite_number
cite_number = cite_number + 1
for _, citation in ipairs(el.citations) do
-- Only process the citation if they are cited in the text, excluding 'nocite'!!
if citation.mode == 'NormalCitation' then
if cites[citation.id] then
table.insert(cites[citation.id], cite_id)
else
cites[citation.id] = { cite_id }
end
end
end
if FORMAT == "typst" then
return pandoc.Span(with_label(cite_id, el))
else
return pandoc.Span(with_label(cite_id, el), pandoc.Attr(cite_id))
end
end
function append_inline(blocks, inlines)
local last = blocks[#blocks]
if last.t == 'Para' or last.t == 'Plain' then
-- append to last block
last.content:extend(inlines)
else
-- append as additional block
blocks[#blocks + 1] = pandoc.Plain(inlines)
end
return blocks
end
function Div(el)
local citation_id = el.identifier:match("ref%-(.+)")
local tex_return_link = pandoc.RawInline("latex", "\\Acrobatmenu{GoBack}{$\\hookleftarrow$}")
if citation_id then
local backlinks = pandoc.Inlines { pandoc.Space(), pandoc.Str("[") }
if FORMAT == "latex" then
table.insert(backlinks, tex_return_link)
end
for i, cite_id in ipairs(cites[citation_id] or {}) do
local marker = pandoc.Str(i)
if FORMAT == "latex" then
marker = pandoc.RawInline("latex", "\\pageref{" .. cite_id .. "}")
end
if #backlinks > 2 then
table.insert(backlinks, pandoc.Str(","))
table.insert(backlinks, pandoc.Space())
end
table.insert(backlinks, pandoc.Link(marker, "#" .. cite_id))
end
if #backlinks > 2 then
append_inline(el.content, backlinks .. { pandoc.Str("]") })
end
return el
end
end