-
Notifications
You must be signed in to change notification settings - Fork 2
/
author-info-blocks.lua
executable file
·176 lines (158 loc) · 5.81 KB
/
author-info-blocks.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
--[[
affiliation-blocks – generate title components
Copyright © 2017–2020 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 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 '*'},
}
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
--- Check whether the given author is a corresponding author
local function is_corresponding_author(author)
return author.correspondence and author.email
end
--- 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{}
if author.equal_contributor then
author_marks[#author_marks + 1] = get_mark 'equal_contributor'
end
local idx_str
for _, idx in ipairs(author.institute) 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
local res = List.clone(author.name)
res[#res + 1] = pandoc.Superscript(intercalate(author_marks, {pandoc.Str ','}))
return res
end
end
local function is_equal_contributor (author)
return author.equal_contributor
end
--- 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
--- 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(tostring(i))},
pandoc.Space()
}
return num_inlines .. affil.name
end
)
return {pandoc.Para(intercalate(affil_lines, {pandoc.LineBreak()}))}
end
--- 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:' .. pandoc.utils.stringify(author.email)
local author_with_mail = List:new(
author.name .. 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
--- 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
return {
{
Pandoc = function (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(doc.meta.author, mark) or {})
body:extend(create_affiliations_blocks(doc.meta.institute) or {})
body:extend(create_correspondence_blocks(doc.meta.author, mark) or {})
body:extend(doc.blocks)
-- 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 = FORMAT:match 'latex'
and pandoc.MetaList(doc.meta.author):map(author_inline_generator(mark))
or pandoc.MetaInlines(create_authors_inlines(doc.meta.author, mark))
-- Institute info is now baked into the affiliations block.
meta.institute = nil
return pandoc.Pandoc(body, meta)
end
}
}