From 4fb18d462c72cb54d8212eaeb532b4a54a0df4b7 Mon Sep 17 00:00:00 2001 From: Egon Willighagen Date: Mon, 13 Mar 2023 14:48:35 +0100 Subject: [PATCH 1/3] Example CiTO annotation --- example/paper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/paper.md b/example/paper.md index 7dcd5fb..c82d674 100644 --- a/example/paper.md +++ b/example/paper.md @@ -34,7 +34,7 @@ tags: # Summary This article describes the features of the Journal of Open Source -Software [@smith2018] publishing pipeline. The publishing method +Software [@usesMethodIn:smith2018] publishing pipeline. The publishing method is similar to the model described by @krewinkel2017, in that Markdown is used as the input format. The author-provided files serves as the source for all generated publishing artifacts. From 1ea11856c95b4ec4a4148b3db550010dd45fa595 Mon Sep 17 00:00:00 2001 From: Egon Willighagen Date: Thu, 16 Mar 2023 20:27:13 +0100 Subject: [PATCH 2/3] Hooked in extraction of the CiTO annotation --- data/filters/extract-cito.lua | 246 ++++++++++++++++++++++++++++++++++ scripts/entrypoint.sh | 1 + 2 files changed, 247 insertions(+) create mode 100644 data/filters/extract-cito.lua diff --git a/data/filters/extract-cito.lua b/data/filters/extract-cito.lua new file mode 100644 index 0000000..69f3650 --- /dev/null +++ b/data/filters/extract-cito.lua @@ -0,0 +1,246 @@ +-- Copyright © 2017–2021 Albert Krewinkel, Robert Winkler +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. + +local _version = '1.0.0' +local properties_and_aliases = { + agreesWith = { + 'agreeWith', + 'agree_with', + 'agrees_with', + }, + citation = { + }, + cites = { + }, + citesAsAuthority = { + 'asAuthority', + 'cites_as_authority', + 'as_authority', + 'authority' + }, + citesAsDataSource = { + "asDataSource", + "dataSource", + 'cites_as_data_source', + "as_data_source", + "data_source" + }, + citesAsEvidence = { + 'asEvidence', + 'cites_as_evidence', + 'as_evidence', + 'evidence' + }, + citesAsMetadataDocument = { + 'asMetadataDocument', + 'metadataDocument', + 'cites_as_metadata_document', + 'as_metadata_document', + 'metadata_document', + 'metadata' + }, + citesAsPotentialSolution = { + 'cites_as_potential_solution', + 'potentialSolution', + 'potential_solution', + 'solution' + }, + citesAsRecommendedReading = { + 'asRecommendedReading', + 'recommendedReading', + 'cites_as_recommended_reading', + 'as_recommended_reading', + 'recommended_reading' + }, + citesAsRelated = { + 'cites_as_related', + 'related', + }, + citesAsSourceDocument = { + 'cites_as_source_document', + 'sourceDocument', + 'source_document' + }, + citesForInformation = { + 'cites_for_information', + 'information', + }, + compiles = { + }, + confirms = { + }, + containsAssertionFrom = { + }, + corrects = { + }, + credits = { + }, + critiques = { + }, + derides = { + }, + describes = { + }, + disagreesWith = { + 'disagrees_with', + 'disagree', + 'disagrees' + }, + discusses = { + }, + disputes = { + }, + documents = { + }, + extends = { + }, + includesExcerptFrom = { + 'excerptFrom', + 'excerpt', + 'excerpt_from', + 'includes_excerpt_from', + }, + includesQuotationFrom = { + 'quotationFrom', + 'includes_quotation_from', + 'quotation', + 'quotation_from' + }, + linksTo = { + 'links_to', + 'link' + }, + obtainsBackgroundFrom = { + 'backgroundFrom', + 'obtains_background_from', + 'background', + 'background_from' + }, + providesDataFor = { + }, + obtainsSupportFrom = { + }, + qualifies = { + }, + parodies = { + }, + refutes = { + }, + repliesTo = { + 'replies_to', + }, + retracts = { + }, + reviews = { + }, + ridicules = { + }, + speculatesOn = { + }, + supports = { + }, + updates = { + }, + usesConclusionsFrom = { + 'uses_conclusions_from' + }, + usesDataFrom = { + 'dataFrom', + 'uses_data_from', + 'data', + 'data_from' + }, + usesMethodIn = { + 'methodIn', + 'uses_method_in', + 'method', + 'method_in' + }, +} + +local default_cito_property = 'citation' + +--- Map from cito aliases to the actual cito property. +local properties_by_alias = {} +for property, aliases in pairs(properties_and_aliases) do + -- every property is an alias for itself + properties_by_alias[property] = property + for _, alias in pairs(aliases) do + properties_by_alias[alias] = property + end +end + +--- Split citation ID into cito property and the actual citation ID. If +--- the ID does not seem to contain a CiTO property, the +--- `default_cito_property` will be returned, together with the +--- unchanged input ID. +local function split_cito_from_id (citation_id) + local split_citation_id = {} + local cito_props = {} + local id_started = false + + for part in citation_id:gmatch('[^:]+') do + if not id_started and properties_by_alias[part] then + table.insert(cito_props, properties_by_alias[part]) + else + id_started = true + end + + if id_started then + table.insert(split_citation_id, 1, part) + end + end + + if next(split_citation_id) == nill then + table.insert(split_citation_id, table.remove(cito_props)) + end + + return cito_props, table.concat(split_citation_id, ':') +end + +--- CiTO properties by citation. +local function store_cito (cito_cites, prop, cite_id) + if not prop then + return + end + if not cito_cites[cite_id] then + cito_cites[cite_id] = {} + end + table.insert(cito_cites[cite_id], prop) +end + + +--- Returns a Cite filter function which extracts CiTO information and +--- add it to the given collection table. +local function extract_cito (cito_cites) + return function (cite) + for k, citation in pairs(cite.citations) do + local cito_props, cite_id = split_cito_from_id(citation.id) + for l, cito_prop in pairs(cito_props) do + store_cito(cito_cites, cito_prop, cite_id) + end + citation.id = cite_id + end + return cite + end +end + +--- Lists of citation IDs, indexed by CiTO properties. +local properties_by_citation = {} + +return { + { + Cite = extract_cito(properties_by_citation) + }, + { + Meta = function (meta) + meta.citation_properties = properties_by_citation + meta.bibliography = meta.bibliography or + meta.cito_bibliography or + meta['cito-bibliography'] + return meta + end + } +} diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 4fddaee..b6ba4d0 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -98,6 +98,7 @@ for format in $(printf "%s" "$outformats" | sed -e 's/,/ /g'); do # Note that the output file must be defined in the format's defaults file. /usr/local/bin/pandoc \ --data-dir="$OPENJOURNALS_PATH"/data \ + --lua-filter="$OPENJOURNALS_PATH"/data/filters/extract-cito.lua \ --defaults=shared \ --defaults="${format}" \ --defaults="$OPENJOURNALS_PATH"/"${JOURNAL}"/defaults.yaml \ From 3db00d7f8b07ff2a390bbfe94701adb8c753011b Mon Sep 17 00:00:00 2001 From: Egon Willighagen Date: Thu, 16 Mar 2023 21:58:20 +0100 Subject: [PATCH 3/3] Output the cito annotation in the reference list --- data/defaults/pdf.yaml | 2 +- data/filters/insert-cito-in-ref.lua | 55 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 data/filters/insert-cito-in-ref.lua diff --git a/data/defaults/pdf.yaml b/data/defaults/pdf.yaml index 54448a7..b24fbb1 100644 --- a/data/defaults/pdf.yaml +++ b/data/defaults/pdf.yaml @@ -8,7 +8,7 @@ filters: - type: lua path: draft.lua - type: lua - path: self-citation.lua + path: insert-cito-in-ref.lua variables: # styling options colorlinks: true diff --git a/data/filters/insert-cito-in-ref.lua b/data/filters/insert-cito-in-ref.lua new file mode 100644 index 0000000..1bec92a --- /dev/null +++ b/data/filters/insert-cito-in-ref.lua @@ -0,0 +1,55 @@ +-- Copyright © 2021 Albert Krewinkel +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. + +local List = require 'pandoc.List' +local utils = require 'pandoc.utils' +local citation_properties + +local function meta_citation_properties (meta) + citation_properties = meta.citation_properties +end + +local function cito_properties(cite_id) + local props = citation_properties[cite_id] + if not props then return {} end + + -- remove duplicates + local deduplicated_props = List() + local seen = {} + for _, prop in ipairs(props) do + if not seen[prop] then + deduplicated_props:insert(prop) + seen[prop] = true + end + end + + return List(deduplicated_props):map( + function (x) + return pandoc.Strong{ + pandoc.Space(), + pandoc.Str '[cito:', + pandoc.Str(utils.stringify(x)), + pandoc.Str ']' + } + end + ) +end + +local function add_cito (div) + local cite_id = div.identifier:match 'ref%-(.*)' + if cite_id and div.classes:includes 'csl-entry' then + for k, v in ipairs( div.content ) do + if k == 1 then + v.content:extend(cito_properties(cite_id)) + return div + end + end + end +end + +return { + {Meta = meta_citation_properties}, + {Div = add_cito}, +}