Skip to content

Instantly share code, notes, and snippets.

@tarleb
Created May 10, 2018 21:01
Show Gist options
  • Select an option

  • Save tarleb/55652d5b79b5ce19dc3481510e38243a to your computer and use it in GitHub Desktop.

Select an option

Save tarleb/55652d5b79b5ce19dc3481510e38243a to your computer and use it in GitHub Desktop.
-- jsonld.lua
--
-- Copyright (c) 2017-2018 Albert Krewinkel, Robert Winkler
--
-- This program is free software; you can redistribute it and/or modify it
-- under the terms of the GNU public license version 2 or later.
-- See the LICENSE file for details.
-- USAGE:
-- The filters cito.lua and scholarly-metadata.lua must be run before this filter.
--
-- DEPENDENCIES:
-- * pandoc-citeproc must be installed and in the PATH;
-- * dkjson.lua must be either in the same directory or somewhere in LUA_PATH.
local SCRIPT_DIR = PANDOC_SCRIPT_FILE:gsub('/[^/]*$', '')
package.path = SCRIPT_DIR .. '/?.lua;' .. package.path
local json = require "dkjson"
local List = require 'pandoc.List'
local stringify = pandoc.utils.stringify
local function Organizations(orgs)
local orgs_json = {}
for i, org in ipairs(orgs) do
orgs_json[i] = {
["@type"] = "Organization",
["name"] = org.name and stringify(org.name),
['url'] = org.url and stringify(org.url),
}
end
return orgs_json
end
local function Authors(authors)
local authors_json = pandoc.MetaList{}
for i, author in ipairs(authors) do
authors_json[i] = {
['@type'] = "Person",
['@id'] = authors[i].orcid and
("https://orcid.org/" .. stringify(authors[i].orcid)),
["name"] = author.name and stringify(author.name),
["affiliation"] = author.institute and Organizations(author.institute),
['email'] = author.email and stringify(author.email),
['url'] = author.url and stringify(author.url),
}
end
return authors_json
end
local function Cito (bibjson, cites_by_cito_property)
function find_citation(id)
-- sloooow
for i = 1, #bibjson do
if bibjson[i].id == id then
return bibjson[i]
end
end
end
local result = {}
local bibentry, citation_ld
for citation_type, typed_citation_ids in pairs(cites_by_cito_property) do
for i = 1, #typed_citation_ids do
bibentry = find_citation(typed_citation_ids[i])
if bibentry and bibentry.DOI then
citation_ld = {
["@id"] = "http://dx.doi.org/" .. bibentry.DOI
}
cito_type_str = "cito:" .. citation_type
if not result[cito_type_str] then
result[cito_type_str] = {}
end
table.insert(result[cito_type_str], citation_ld)
end
end
end
return result
end
local function Citations (bibjson, citation_ids)
function find_citation(id)
-- sloooow
for i = 1, #bibjson do
if bibjson[i].id == id then
return bibjson[i]
end
end
end
function CitationSchema(record)
local type
if record.type == "report" then
type = "Report"
elseif record.type == "article-journal" then
type = "ScholarlyArticle"
else
type = "Article"
end
local authors = {}
if record.author then
for i = 1, #record.author do
local name = {
record.author[i].family,
record.author[i].given
}
authors[i] = {
name = table.concat(name, ", ")
}
end
end
return {
["@context"] = {
["@vocab"] = "http://schema.org/",
["title"] = "headline",
["page"] = "pagination",
["date"] = "datePublished",
["publisher"] = "publisher",
["author"] = "author",
},
["@type"] = type,
["@id"] = record.DOI and ("http://dx.doi.org/" .. record.DOI),
["title"] = record.title,
["author"] = Authors(authors),
["date"] = record.issued and
record.issued["date-parts"] and
table.concat(record.issued["date-parts"][1], "-"),
["publisher"] = record.publisher and
{ ["@type"] = "Organization", ["name"] = record.publisher },
["page"] = record.page,
}
end
local res = {}
for cit_id, _ in pairs(citation_ids) do
local citation_record = find_citation(cit_id)
if citation_record then
res[#res + 1] = CitationSchema(citation_record)
end
end
return res
end
function json_ld(meta)
local default_image = "https://upload.wikimedia.org/wikipedia/commons/f/fa/Globe.svg"
local accessible_for_free
if meta.accessible_for_free ~= nil then
accessible_for_free = meta.accessible_for_free
else
accessible_for_free = true
end
local context = {
["@vocab"] = "http://schema.org/",
["cito"] = "http://purl.org/spar/cito/",
["author"] = "author",
["name"] = "name",
["title"] = "headline",
["subtitle"] = "alternativeTitle",
["publisher"] = "publisher",
["date"] = "datePublished",
["isFree"] = accessible_for_free and "isAccessibleForFree" or nil,
["image"] = "image",
["citation"] = "citation",
}
local citation_ids = {}
for _, ids in pairs(meta.cito_cites) do
for _, id in ipairs(ids) do citation_ids[id] = true end
end
local result = {
["@context"] = context,
["@type"] = "ScholarlyArticle",
["author"] = Authors(meta.author),
["name"] = stringify(meta.title),
["title"] = stringify(meta.title),
["subtitle"] = meta.subtitle and stringify(meta.subtitle),
["date"] = meta.date and stringify(meta.date) or os.date("%Y-%m-%d"),
-- -- ["image"] = meta.image or default_image,
["isFree"] = accessible_for_free,
["citation"] = Citations(meta.bibliography_records, citation_ids),
}
for k, v in pairs(Cito(meta.bibliography_records, meta.cito_cites)) do
result[k] = v
end
return result
end
local function bibliography(bibfilename)
if not bibfilename then
return {}
end
local bibfile = io.popen("pandoc-citeproc --bib2json " .. bibfilename, "r")
local jsonstr = bibfile:read("*a")
bibfile:close()
return json.decode(jsonstr)
end
local function institute_resolver (institutes)
return function (inst_idx)
return institutes[tonumber(pandoc.utils.stringify(inst_idx))]
end
end
function Pandoc(doc)
local meta = doc.meta
local resolve_institute = function (inst_idx)
return meta.institute[tonumber(inst_idx)]
end
for _, author in ipairs(meta.author) do
if author.institute then
author.institute = List.map(author.institute, resolve_institute)
end
end
meta.bibliography_records = bibliography(meta.bibliography)
local jsonld = json_ld(meta)
io.stdout:write(json.encode(jsonld))
return pandoc.Pandoc({})
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment