From 54decfc8ad66cfabc7cc847becf9cb7af759894c Mon Sep 17 00:00:00 2001 From: ming Date: Sat, 5 Oct 2024 14:55:40 +0800 Subject: [PATCH] update to authors-block --- MS/AC.qmd | 6 +- MS/MS.qmd | 61 +++--- MS/SM.qmd | 5 +- .../kapsner/authors-block/_extension.yml | 13 ++ .../kapsner/authors-block/authors-block.lua | 64 ++++++ .../authors-block/from_author_info_blocks.lua | 197 ++++++++++++++++++ .../authors-block/from_scholarly_metadata.lua | 59 ++++++ _extensions/kapsner/authors-block/utils.lua | 62 ++++++ _quarto.yml | 4 +- 9 files changed, 429 insertions(+), 42 deletions(-) create mode 100644 _extensions/kapsner/authors-block/_extension.yml create mode 100644 _extensions/kapsner/authors-block/authors-block.lua create mode 100644 _extensions/kapsner/authors-block/from_author_info_blocks.lua create mode 100644 _extensions/kapsner/authors-block/from_scholarly_metadata.lua create mode 100644 _extensions/kapsner/authors-block/utils.lua diff --git a/MS/AC.qmd b/MS/AC.qmd index 18411b2..474004c 100644 --- a/MS/AC.qmd +++ b/MS/AC.qmd @@ -1,13 +1,9 @@ --- format: elsevier-html: - filters: - - author-info-blocks css: _extensions/inst/css/style.css docx: reference-doc: _extensions/inst/word/MS.docx - filters: - - author-info-blocks elsevier-pdf: latex-clean: false header-includes: @@ -23,6 +19,8 @@ format: formatting: preprint model: 1p cite-style: authoryear +filters: + - authors-block --- # CRediT authorship contribution statement {-} diff --git a/MS/MS.qmd b/MS/MS.qmd index 6565ed0..42b34b3 100644 --- a/MS/MS.qmd +++ b/MS/MS.qmd @@ -14,41 +14,38 @@ format: elsevier-html: css: _extensions/inst/css/style.css keep-md: true - dplyr::filters: - - author-info-blocks epub: default docx: reference-doc: _extensions/inst/word/MS.docx - dplyr::filters: - - author-info-blocks -# elsevier-pdf: -# keep-tex: false -# keep-md: false -# include-in-header: "./_extensions/quarto-journals/elsevier/partials/revision.tex" -# latex-clean: false -# header-includes: -# # - \usepackage{threeparttable} -# # - \usepackage{fontspec} -# # - \usepackage{endfloat} -# - \setmainfont{Calibri} -# - \usepackage[UTF8, scheme=plain]{ctex} -# - \usepackage{float} -# - \usepackage[normalem]{ulem} -# - \usepackage[doublespacing]{setspace} -# - \usepackage{lineno} -# - \linenumbers -# journal: -# formatting: preprint # preprint | review | doublebind -# model: 1p -# cite-style: authoryear -# # graphical-abstract: "![](../figures/GA3.pdf)" -# # highlights: -# # - A comprehensive model was contructed to evaluate the risk of odor occurrences -# # - Turbidity distribution determine underwater light and MIB-producing *Planktothrix* -# # - Increasing flowrate increases turbidity that can control *Planktothrix* and MIB -# # - Odor control based on flow regulation in source water is "green" and fundamental -# filters: -# - latex-environment + elsevier-pdf: + keep-tex: false + keep-md: false + include-in-header: "./_extensions/quarto-journals/elsevier/partials/revision.tex" + latex-clean: false + header-includes: + # - \usepackage{threeparttable} + # - \usepackage{fontspec} + # - \usepackage{endfloat} + - \setmainfont{Calibri} + - \usepackage[UTF8, scheme=plain]{ctex} + - \usepackage{float} + - \usepackage[normalem]{ulem} + - \usepackage[doublespacing]{setspace} + - \usepackage{lineno} + - \linenumbers + journal: + formatting: preprint # preprint | review | doublebind + model: 1p + cite-style: authoryear + # graphical-abstract: "![](../figures/GA3.pdf)" + # highlights: + # - A comprehensive model was contructed to evaluate the risk of odor occurrences + # - Turbidity distribution determine underwater light and MIB-producing *Planktothrix* + # - Increasing flowrate increases turbidity that can control *Planktothrix* and MIB + # - Odor control based on flow regulation in source water is "green" and fundamental +filters: + - latex-environment + - authors-block commands: [clab] --- diff --git a/MS/SM.qmd b/MS/SM.qmd index 2ef37a3..c6a96d8 100644 --- a/MS/SM.qmd +++ b/MS/SM.qmd @@ -5,13 +5,9 @@ bibliography: [../BB/Ref.bib, ../BB/localRef.bib] csl: _extensions/inst/tex/elsevier-harvard.csl format: elsevier-html: - filters: - - author-info-blocks css: _extensions/inst/css/style.css docx: reference-doc: _extensions/inst/word/MS.docx - filters: - - author-info-blocks elsevier-pdf: classoption: [nopreprintline] revision: true @@ -35,6 +31,7 @@ format: - \linenumbers filters: - latex-environment + - authors-block commands: [clab] --- diff --git a/_extensions/kapsner/authors-block/_extension.yml b/_extensions/kapsner/authors-block/_extension.yml new file mode 100644 index 0000000..194f33b --- /dev/null +++ b/_extensions/kapsner/authors-block/_extension.yml @@ -0,0 +1,13 @@ +title: Authors-block +authors: + - name: Lorenz A. Kapsner + orcid: 0000-0003-1866-860X + - name: Albert Krewinkel + orcid: 0000-0002-9455-0796 + - name: Robert Winkler +version: 0.2.1 +quarto-required: ">=1.3.0" +contributes: + filters: + - authors-block.lua + diff --git a/_extensions/kapsner/authors-block/authors-block.lua b/_extensions/kapsner/authors-block/authors-block.lua new file mode 100644 index 0000000..c7cc6c5 --- /dev/null +++ b/_extensions/kapsner/authors-block/authors-block.lua @@ -0,0 +1,64 @@ +--[[ +authors-block – affiliations block extension for quarto + +Copyright (c) 2023 Lorenz A. Kapsner + +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' + +-- [import] +local from_utils = require "utils" +local normalize_affiliations = from_utils.normalize_affiliations +local normalize_authors = from_utils.normalize_authors +local normalize_latex_authors = from_utils.normalize_latex_authors + +local from_authors = require "from_author_info_blocks" +local default_marks = from_authors.default_marks +local create_equal_contributors_block = from_authors.create_equal_contributors_block +local create_affiliations_blocks = from_authors.create_affiliations_blocks +local create_correspondence_blocks = from_authors.create_correspondence_blocks +local is_corresponding_author = from_authors.is_corresponding_author +local author_inline_generator = from_authors.author_inline_generator +local create_authors_inlines = from_authors.create_authors_inlines +-- [/import] + +-- This is the main-part +function Pandoc(doc) + local meta = doc.meta + local body = List:new{} + + local mark = function (mark_name) return default_marks[mark_name] end + + body:extend(create_equal_contributors_block(meta.authors, mark) or {}) + body:extend(create_affiliations_blocks(meta.affiliations) or {}) + body:extend(create_correspondence_blocks(meta.authors, mark) or {}) + body:extend(doc.blocks) + + for _i, author in ipairs(meta.authors) do + author.test = is_corresponding_author(author) + end + + meta.affiliations = normalize_affiliations(meta.affiliations) + meta.author = meta.authors:map(normalize_authors(meta.affiliations)) + + -- Overwrite authors with formatted values. We use a single, formatted + -- string for most formats. LaTeX output, however, looks nicer if we + -- provide a authors as a list. + meta.author = pandoc.MetaInlines(create_authors_inlines(meta.author, mark)) + -- Institute info is now baked into the affiliations block. + meta.affiliations = nil + + return pandoc.Pandoc(body, meta) +end diff --git a/_extensions/kapsner/authors-block/from_author_info_blocks.lua b/_extensions/kapsner/authors-block/from_author_info_blocks.lua new file mode 100644 index 0000000..79edb1c --- /dev/null +++ b/_extensions/kapsner/authors-block/from_author_info_blocks.lua @@ -0,0 +1,197 @@ +-- https://github.com/pandoc/lua-filters/commit/ca72210b453cc0d045360e0ae36448d019d7dfbf +--[[ +affiliation-blocks – generate title components + +Copyright © 2017–2021 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. +]] + +-- from @kapsner +-- [import] +local from_utils = require "utils" +local has_key = from_utils.has_key +-- [/import] +local M = {} + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +local List = require 'pandoc.List' +local utils = require 'pandoc.utils' +local stringify = utils.stringify + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +local default_marks +local default_marks = { + corresponding_author = FORMAT == 'latex' + and {pandoc.RawInline('latex', '*')} + or {pandoc.Str '✉'}, + equal_contributor = FORMAT == 'latex' + and {pandoc.RawInline('latex', '$\\dagger{}$')} + or {pandoc.Str '*'}, +} +M.default_marks = default_marks + +-- modified by @kapsner +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +local function is_equal_contributor(author) + if has_key(author, "attributes") then + return author.attributes["equal-contributor"] + end + return nil +end + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +--- Create equal contributors note. +local function create_equal_contributors_block(authors, mark) + local has_equal_contribs = List:new(authors):find_if(is_equal_contributor) + if not has_equal_contribs then + return nil + end + local contributors = { + pandoc.Superscript(mark'equal_contributor'), + pandoc.Space(), + pandoc.Str 'These authors contributed equally to this work.' + } + return List:new{pandoc.Para(contributors)} +end +M.create_equal_contributors_block = create_equal_contributors_block + + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +local function intercalate(lists, elem) + local result = List:new{} + for i = 1, (#lists - 1) do + result:extend(lists[i]) + result:extend(elem) + end + if #lists > 0 then + result:extend(lists[#lists]) + end + return result +end + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +--- Check whether the given author is a corresponding author +local function is_corresponding_author(author) + if has_key(author, "attributes") then + if author.attributes["corresponding"] then + return author.email + end + end + return nil +end +M.is_corresponding_author = is_corresponding_author + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +--- Generate a block element containing the correspondence information +local function create_correspondence_blocks(authors, mark) + local corresponding_authors = List:new{} + for _, author in ipairs(authors) do + if is_corresponding_author(author) then + local mailto = 'mailto:' .. utils.stringify(author.email) + local author_with_mail = List:new( + -- modified by @kapsner + author.name.literal .. List:new{pandoc.Space(), pandoc.Str '<'} .. + author.email .. List:new{pandoc.Str '>'} + ) + local link = pandoc.Link(author_with_mail, mailto) + table.insert(corresponding_authors, {link}) + end + end + if #corresponding_authors == 0 then + return nil + end + local correspondence = List:new{ + pandoc.Superscript(mark'corresponding_author'), + pandoc.Space(), + pandoc.Str'Correspondence:', + pandoc.Space() + } + local sep = List:new{pandoc.Str',', pandoc.Space()} + return { + pandoc.Para(correspondence .. intercalate(corresponding_authors, sep)) + } +end +M.create_correspondence_blocks = create_correspondence_blocks + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +--- Create inlines for a single author (includes all author notes) +local function author_inline_generator (get_mark) + return function (author) + local author_marks = List:new{} + -- modified by @kapsner + if has_key(author, "attributes") then + if author.attributes["equal-contributor"] then + author_marks[#author_marks + 1] = get_mark 'equal_contributor' + end + end + local idx_str + for _, idx in ipairs(author.affiliations) do + if type(idx) ~= 'table' then + idx_str = tostring(idx) + else + idx_str = stringify(idx) + end + author_marks[#author_marks + 1] = {pandoc.Str(idx_str)} + end + if is_corresponding_author(author) then + author_marks[#author_marks + 1] = get_mark 'corresponding_author' + end + -- modified by @kapsner + if FORMAT:match 'latex' then + author.name.literal[#author.name.literal + 1] = pandoc.Superscript(intercalate(author_marks, {pandoc.Str ','})) + return author + else + local res = List.clone(author.name.literal) + res[#res + 1] = pandoc.Superscript(intercalate(author_marks, {pandoc.Str ','})) + return res + end + end +end +M.author_inline_generator = author_inline_generator + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +--- Generate a list of inlines containing all authors. +local function create_authors_inlines(authors, mark) + local inlines_generator = author_inline_generator(mark) + local inlines = List:new(authors):map(inlines_generator) + local and_str = List:new{pandoc.Space(), pandoc.Str'and', pandoc.Space()} + + local last_author = inlines[#inlines] + inlines[#inlines] = nil + local result = intercalate(inlines, {pandoc.Str ',', pandoc.Space()}) + if #authors > 1 then + result:extend(List:new{pandoc.Str ","} .. and_str) + end + result:extend(last_author) + return result +end +M.create_authors_inlines = create_authors_inlines + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/author-info-blocks/author-info-blocks.lua +--- Generate a block list all affiliations, marked with arabic numbers. +local function create_affiliations_blocks(affiliations) + local affil_lines = List:new(affiliations):map( + function (affil, i) + local num_inlines = List:new{ + pandoc.Superscript{pandoc.Str(affil.number)}, + pandoc.Space() + } + return num_inlines .. affil.name + end + ) + return {pandoc.Para(intercalate(affil_lines, {pandoc.LineBreak()}))} +end +M.create_affiliations_blocks = create_affiliations_blocks + +return M diff --git a/_extensions/kapsner/authors-block/from_scholarly_metadata.lua b/_extensions/kapsner/authors-block/from_scholarly_metadata.lua new file mode 100644 index 0000000..0ff7e81 --- /dev/null +++ b/_extensions/kapsner/authors-block/from_scholarly_metadata.lua @@ -0,0 +1,59 @@ +--[[ +ScholarlyMeta – normalize author/affiliation meta variables + +Copyright (c) 2017-2021 Albert Krewinkel, Robert Winkler + +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 M = {} + + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/scholarly-metadata/scholarly-metadata.lua +--- Returns a function which checks whether an object has the given ID. +local function has_id(id) + return function(x) return x.id == id end +end + + +-- taken from https://github.com/pandoc/lua-filters/blob/1660794b991c3553968beb993f5aabb99b317584/scholarly-metadata/scholarly-metadata.lua +--- Resolve institute placeholders to full named objects +local function resolve_institutes(institute, known_institutes) + local unresolved_institutes + if institute == nil then + unresolved_institutes = {} + elseif type(institute) == "string" or type(institute) == "number" then + unresolved_institutes = {institute} + else + unresolved_institutes = institute + end + + local result = List:new{} + for i, inst in ipairs(unresolved_institutes) do + -- this has been modified by @kapsner + --result[i] = + -- known_institutes[tonumber(inst)] or + -- known_institutes:find_if(has_id(pandoc.utils.stringify(inst))) or + -- to_named_object(inst) + intermed_val = known_institutes:find_if(has_id(stringify(inst))) + result[i] = pandoc.MetaString(stringify(intermed_val.index)) + end + return result +end +M.resolve_institutes = resolve_institutes + +return M \ No newline at end of file diff --git a/_extensions/kapsner/authors-block/utils.lua b/_extensions/kapsner/authors-block/utils.lua new file mode 100644 index 0000000..d0103ca --- /dev/null +++ b/_extensions/kapsner/authors-block/utils.lua @@ -0,0 +1,62 @@ +--[[ +authors-block – affiliations block extension for quarto + +Copyright (c) 2023 Lorenz A. Kapsner + +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 + +-- [import] +local from_scholarly = require "from_scholarly_metadata" +local resolve_institutes = from_scholarly.resolve_institutes +-- [/import] + +local M = {} + +-- from @kapsner +local function normalize_affiliations(affiliations) + local affiliations_norm = List:new(affiliations):map( + function(affil, i) + affil.index = pandoc.MetaInlines(pandoc.Str(tostring(i))) + affil.id = pandoc.MetaString(stringify(affil.id)) + return affil + end + ) + return affiliations_norm +end +M.normalize_affiliations = normalize_affiliations + +-- from https://stackoverflow.com/a/2282547 +local function has_key(set, key) + return set[key] ~= nil +end +M.has_key = has_key + +-- from @kapsner +local function normalize_authors(affiliations) + return function(auth) + auth.id = pandoc.MetaString(stringify(auth.name)) + auth.affiliations = resolve_institutes( + auth.affiliations, + affiliations + ) + return auth + end +end +M.normalize_authors = normalize_authors + +return M diff --git a/_quarto.yml b/_quarto.yml index feadb72..70582de 100644 --- a/_quarto.yml +++ b/_quarto.yml @@ -125,8 +125,8 @@ website: file: MS/MS.qmd - text: "Supplementary Materials" file: MS/SM.qmd - - text: "Revision Notes" - file: MS/RN.qmd + # - text: "Revision Notes" + # file: MS/RN.qmd - text: "Slides" file: SD/index.qmd - text: "Other"