summaryrefslogtreecommitdiff
path: root/paper/lua-filters/multiple-bibliographies
diff options
context:
space:
mode:
Diffstat (limited to 'paper/lua-filters/multiple-bibliographies')
-rw-r--r--paper/lua-filters/multiple-bibliographies/Makefile6
-rw-r--r--paper/lua-filters/multiple-bibliographies/README.md33
-rw-r--r--paper/lua-filters/multiple-bibliographies/expected.native14
-rw-r--r--paper/lua-filters/multiple-bibliographies/multiple-bibliographies.lua110
-rw-r--r--paper/lua-filters/multiple-bibliographies/primary.bib10
-rw-r--r--paper/lua-filters/multiple-bibliographies/sample.md17
-rw-r--r--paper/lua-filters/multiple-bibliographies/secondary.bib10
7 files changed, 200 insertions, 0 deletions
diff --git a/paper/lua-filters/multiple-bibliographies/Makefile b/paper/lua-filters/multiple-bibliographies/Makefile
new file mode 100644
index 0000000..a42ce28
--- /dev/null
+++ b/paper/lua-filters/multiple-bibliographies/Makefile
@@ -0,0 +1,6 @@
+test: sample.md multiple-bibliographies.lua
+ @pandoc --lua-filter=multiple-bibliographies.lua \
+ --standalone --to=native $< 2>/dev/null \
+ | diff -u - expected.native
+
+.PHONY: test
diff --git a/paper/lua-filters/multiple-bibliographies/README.md b/paper/lua-filters/multiple-bibliographies/README.md
new file mode 100644
index 0000000..0111ee6
--- /dev/null
+++ b/paper/lua-filters/multiple-bibliographies/README.md
@@ -0,0 +1,33 @@
+# multiple-bibliographies
+
+This filter allows to create multiple bibliographies using
+`pandoc-citeproc`. The content of each bibliography is controlled
+via YAML values and the file in which a bibliographic entry is
+specified.
+
+## Usage
+
+Instead of using the usual *bibliography* metadata field, all
+bibliographies must be defined via a separate field of the scheme
+*bibliographyX*, e.g.
+
+ ---
+ bibliography_main: main-bibliography.bib
+ bibliography_software: software.bib
+ ---
+
+The placement of bibliographies is controlled via special divs.
+
+ # References
+
+ ::: {#refs_main}
+ :::
+
+ # Software
+
+ ::: {#refs_software}
+ :::
+
+Each refsX div should have a matching bibliographyX entry in the
+header. These divs are filled with citations from the respective
+bib-file.
diff --git a/paper/lua-filters/multiple-bibliographies/expected.native b/paper/lua-filters/multiple-bibliographies/expected.native
new file mode 100644
index 0000000..a7ead12
--- /dev/null
+++ b/paper/lua-filters/multiple-bibliographies/expected.native
@@ -0,0 +1,14 @@
+Pandoc (Meta {unMeta = fromList [("bibliography_recommended_reading",MetaInlines [Str "secondary.bib"]),("bibliography_sources",MetaInlines [Str "primary.bib"]),("nocite",MetaInlines [Cite [Citation {citationId = "Knu86", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 0}] [Str "@Knu86"],Str ",",Space,Cite [Citation {citationId = "Bae", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 0}] [Str "@Bae"]]),("title",MetaInlines [Str "Multiple",Space,Str "Bibliographies",Space,Str "Demo"])]})
+[Para [Cite [Citation {citationId = "Nie72", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 1}] [Str "Nietzsche",Space,Str "(1872)"],Str ",",Space,Cite [Citation {citationId = "Bel", citationPrefix = [], citationSuffix = [], citationMode = AuthorInText, citationNoteNum = 0, citationHash = 2}] [Str "Bellori",Space,Str "(1672)"]]
+,Header 1 ("references",[],[]) [Str "References"]
+,Div ("refs_sources",[],[])
+ [Div ("ref-Bel",[],[])
+ [Para [Str "Bellori.",Space,Str "1672.",Space,Emph [Str "Le",Space,Str "Vite",Space,Str "de\8217",Space,Str "Pittori,",Space,Str "Scultori",Space,Str "E",Space,Str "Architetti",Space,Str "Moderni"],Str "."]]
+ ,Div ("ref-Nie72",[],[])
+ [Para [Str "Nietzsche,",Space,Str "Friedrich.",Space,Str "1872.",Space,Emph [Str "Die",Space,Str "Geburt",Space,Str "Der",Space,Str "Trag\246die",Space,Str "Aus",Space,Str "Dem",Space,Str "Geiste",Space,Str "Der",Space,Str "Musik"],Str "."]]]
+,Header 1 ("recommended-reading",[],[]) [Str "Recommended",Space,Str "Reading"]
+,Div ("refs_recommended_reading",[],[])
+ [Div ("ref-Bae",[],[])
+ [Para [Str "B\228tschmann,",Space,Str "Oskar.",Space,Str "1985.",Space,Emph [Str "Pygmalion",Space,Str "Als",Space,Str "Betrachter"],Str "."]]
+ ,Div ("ref-Knu86",[],[])
+ [Para [Str "Knuth,",Space,Str "Donald",Space,Str "E.",Space,Str "1986.",Space,Emph [Str "The",Space,Str "Texbook"],Str "."]]]]
diff --git a/paper/lua-filters/multiple-bibliographies/multiple-bibliographies.lua b/paper/lua-filters/multiple-bibliographies/multiple-bibliographies.lua
new file mode 100644
index 0000000..934e6ea
--- /dev/null
+++ b/paper/lua-filters/multiple-bibliographies/multiple-bibliographies.lua
@@ -0,0 +1,110 @@
+--[[
+multiple-bibliographies – create multiple bibliographies
+
+Copyright © 2018-2019 Albert Krewinkel
+
+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'
+local utils = require 'pandoc.utils'
+local stringify = utils.stringify
+local run_json_filter = utils.run_json_filter
+
+--- Collection of all cites in the document
+local all_cites = {}
+--- Document meta value
+local doc_meta = pandoc.Meta{}
+
+--- Div used by pandoc-citeproc to insert the bibliography.
+local refs_div = pandoc.Div({}, pandoc.Attr('refs'))
+
+local supports_quiet_flag = (function ()
+ local version = pandoc.pipe('pandoc-citeproc', {'--version'}, '')
+ local major, minor, patch = version:match 'pandoc%-citeproc (%d+)%.(%d+)%.?(%d*)'
+ major, minor, patch = tonumber(major), tonumber(minor), tonumber(patch)
+ return major > 0
+ or minor > 14
+ or (minor == 14 and patch >= 5)
+end)()
+
+--- Resolve citations in the document by combining all bibliographies
+-- before running pandoc-citeproc on the full document.
+local function resolve_doc_citations (doc)
+ -- combine all bibliographies
+ local meta = doc.meta
+ local orig_bib = meta.bibliography
+ meta.bibliography = pandoc.MetaList{orig_bib}
+ for name, value in pairs(meta) do
+ if name:match('^bibliography_') then
+ table.insert(meta.bibliography, value)
+ end
+ end
+ -- add dummy div to catch the created bibliography
+ table.insert(doc.blocks, refs_div)
+ -- resolve all citations
+ doc = run_json_filter(doc, 'pandoc-citeproc')
+ -- remove catch-all bibliography
+ table.remove(doc.blocks)
+ -- restore bibliography to original value
+ doc.meta.bibliography = orig_bib
+ return doc
+end
+
+--- Explicitly create a new meta object with all fields relevant for
+--- pandoc-citeproc.
+local function meta_for_pandoc_citeproc (bibliography)
+ -- We could just indiscriminately copy all meta fields, but let's be
+ -- explicit about what's important.
+ local fields = {
+ 'bibliography', 'references', 'csl', 'citation-style',
+ 'link-citations', 'citation-abbreviations', 'lang',
+ 'suppress-bibliography', 'reference-section-title',
+ 'notes-after-punctuation', 'nocite'
+ }
+ local new_meta = pandoc.Meta{}
+ for _, field in ipairs(fields) do
+ new_meta[field] = doc_meta[field]
+ end
+ new_meta.bibliography = bibliography
+ return new_meta
+end
+
+--- Create a bibliography for a given topic. This acts on all divs whose
+-- ID starts with "refs", followed by nothing but underscores and
+-- alphanumeric characters.
+local function create_topic_bibliography (div)
+ local name = div.identifier:match('^refs([_%w]*)$')
+ local bibfile = name and doc_meta['bibliography' .. name]
+ if not bibfile then
+ return nil
+ end
+ local tmp_blocks = {pandoc.Para(all_cites), refs_div}
+ local tmp_meta = meta_for_pandoc_citeproc(bibfile)
+ local tmp_doc = pandoc.Pandoc(tmp_blocks, tmp_meta)
+ local filter_args = {FORMAT, supports_quiet_flag and '-q' or nil}
+ local res = run_json_filter(tmp_doc, 'pandoc-citeproc', filter_args)
+ -- First block of the result contains the dummy paragraph, second is
+ -- the refs Div filled by pandoc-citeproc.
+ div.content = res.blocks[2].content
+ return div
+end
+
+return {
+ {
+ -- Collect all citations and the doc's Meta value for other filters.
+ Cite = function (c) all_cites[#all_cites + 1] = c end,
+ Meta = function (m) doc_meta = m end,
+ },
+ { Pandoc = resolve_doc_citations },
+ { Div = create_topic_bibliography },
+}
diff --git a/paper/lua-filters/multiple-bibliographies/primary.bib b/paper/lua-filters/multiple-bibliographies/primary.bib
new file mode 100644
index 0000000..8c9decc
--- /dev/null
+++ b/paper/lua-filters/multiple-bibliographies/primary.bib
@@ -0,0 +1,10 @@
+@book{Bel,
+ author = {Bellori},
+ title = {Le vite de' pittori, scultori e architetti moderni},
+ year = {1672},
+}
+@book{Nie72,
+ author = {Nietzsche, Friedrich},
+ title = {Die Geburt der Tragödie aus dem Geiste der Musik},
+ year = {1872},
+}
diff --git a/paper/lua-filters/multiple-bibliographies/sample.md b/paper/lua-filters/multiple-bibliographies/sample.md
new file mode 100644
index 0000000..d4ab2eb
--- /dev/null
+++ b/paper/lua-filters/multiple-bibliographies/sample.md
@@ -0,0 +1,17 @@
+---
+title: Multiple Bibliographies Demo
+bibliography_sources: primary.bib
+bibliography_recommended_reading: secondary.bib
+nocite: '@Knu86, @Bae'
+---
+@Nie72, @Bel
+
+# References
+
+::: {#refs_sources}
+:::
+
+# Recommended Reading
+
+::: {#refs_recommended_reading}
+:::
diff --git a/paper/lua-filters/multiple-bibliographies/secondary.bib b/paper/lua-filters/multiple-bibliographies/secondary.bib
new file mode 100644
index 0000000..45e6306
--- /dev/null
+++ b/paper/lua-filters/multiple-bibliographies/secondary.bib
@@ -0,0 +1,10 @@
+@book{Bae,
+ author = {Bätschmann, Oskar},
+ title = {Pygmalion als Betrachter},
+ year = {1985}
+}
+@book{Knu86,
+ author = {Knuth, Donald E.},
+ year = {1986},
+ title = {The \TeX book},
+}