relaton-render 0.3.8 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +67 -4
- data/lib/isodoc-yaml/i18n-ar.yaml +8 -0
- data/lib/isodoc-yaml/i18n-de.yaml +8 -0
- data/lib/isodoc-yaml/i18n-en.yaml +8 -1
- data/lib/isodoc-yaml/i18n-es.yaml +9 -0
- data/lib/isodoc-yaml/i18n-fr.yaml +8 -0
- data/lib/isodoc-yaml/i18n-ru.yaml +9 -0
- data/lib/isodoc-yaml/i18n-zh-Hans.yaml +8 -0
- data/lib/relaton/render/fields/fields.rb +31 -9
- data/lib/relaton/render/general/citations.rb +90 -0
- data/lib/relaton/render/general/config.yml +11 -4
- data/lib/relaton/render/general/render.rb +42 -2
- data/lib/relaton/render/parse/parse.rb +2 -1
- data/lib/relaton/render/parse/parse_extract.rb +5 -1
- data/lib/relaton/render/template/template.rb +3 -0
- data/lib/relaton/render/version.rb +1 -1
- data/relaton-render.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adb92be3ce06dd2d7d1f2c940826ffcb94b061e0beeef81ccc745f85d10aed42
|
4
|
+
data.tar.gz: a7333f5a5d1154c8dcbe85135955595530bab40b584ac34a5f1febe67882d3b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7fb788d09f5ad3ccc820d52c171522498ad3f46782754aac07ce91e85b1c318864848be6df9391d0ec099a7b9a50afc21d1c069d07692a7c2a9b88505514f5b
|
7
|
+
data.tar.gz: 1f35895353ef8fdc5db0b71dd8cb7f8bf6bcf2ecf49ef06ebfa754391ac4b29e4268a14295febc1fceb4226c970e5f849c8c35597b42a16b00d5ff0ee36c1e62
|
data/README.adoc
CHANGED
@@ -13,7 +13,21 @@ a configuration, and generates a https://www.metanorma.org[Metanorma] XML render
|
|
13
13
|
----
|
14
14
|
input = "<bibitem type='...'>....</bibitem>"
|
15
15
|
|
16
|
-
Relaton::Render::General.new(template: ..., nametemplate: ..., seriestemplate: ..., language: "en", script: "Latn")
|
16
|
+
r = Relaton::Render::General.new(template: ..., nametemplate: ..., seriestemplate: ..., language: "en", script: "Latn")
|
17
|
+
|
18
|
+
r.render(input) == "Author1 and Author2 2000. Title &c."
|
19
|
+
|
20
|
+
bibliography = "<references><bibitem id=''>...</bibitem>...<bibitem id=''>...</bibitem></references>"
|
21
|
+
|
22
|
+
r.render_all(bibliography, type: "author-cite") ==
|
23
|
+
|
24
|
+
{ bibitem["id"] :
|
25
|
+
{ author: "Author1 and Author2",
|
26
|
+
date: "2000a",
|
27
|
+
citation: "Author1 and Author2 2000a",
|
28
|
+
formattedref: "Author1 and Author2 2000a. Title &c."
|
29
|
+
}
|
30
|
+
}
|
17
31
|
----
|
18
32
|
|
19
33
|
The gem processes either Relaton XML, or native Relaton classes.
|
@@ -31,6 +45,7 @@ The parameters are:
|
|
31
45
|
`script`:: in ISO-15124
|
32
46
|
`template`:: templates for rendering different bibliographic types
|
33
47
|
`nametemplate`:: templates for rendering personal names
|
48
|
+
`authorcitetemplate`:: templates for rendering names for the purpose of author-date citations
|
34
49
|
`seriestemplate`:: template for rendering series
|
35
50
|
`journaltemplate`:: template for rendering journals in article citations
|
36
51
|
`extenttemplate`:: templates for rendering extents
|
@@ -39,6 +54,42 @@ The parameters are:
|
|
39
54
|
`date`:: default date format (from Twitter CLDR)
|
40
55
|
`i18nhash`:: Metanorma internationalisation hash
|
41
56
|
|
57
|
+
== Functionality
|
58
|
+
|
59
|
+
=== Rendering single reference
|
60
|
+
|
61
|
+
Given an Relaton bibitem object (or equivalent Relaton XML), `render(input)` will output a formatted reference for that
|
62
|
+
bibitem, following the rules laid out in the configuration. That output can be inserted into the `<formattedref>` element
|
63
|
+
of the bibitem by the calling code, and used as the authoritative rendering of the citation.
|
64
|
+
|
65
|
+
This method does not address how the bibliographic item is to be cited, and does not differentiate citations with the same
|
66
|
+
author and date. It should not be used for rendering of references aligned to the author-date citation system.
|
67
|
+
|
68
|
+
=== Rendering multiple references
|
69
|
+
|
70
|
+
Given a collection of Relaton bibitem objects (or equivalent Relaton XML, wrapped in `<references>`),
|
71
|
+
`render_all(bibliography, type: type)`
|
72
|
+
will output a hash of objects, with information to be used both for rendering references, and for generating citations.
|
73
|
+
This method addresses the disambiguation of citiations, and changes to rendering of references reflecting that disambiguation.
|
74
|
+
For that reason, this method should be used for references using the author-date citation system.
|
75
|
+
|
76
|
+
The `type` argument of `render_all` reflects the citation system to be used.
|
77
|
+
|
78
|
+
* If it is set to "author-date", citations with the same author and date will be disambiguated from each other
|
79
|
+
by appending a letter to the date, in the order in which they occur in `bibliography`. (That means that any fixed sorting
|
80
|
+
of references needs to be applied before the bibliography is presented to the method.)
|
81
|
+
* If it is set to nil (as is the default), no such disambiguation occurs.
|
82
|
+
|
83
|
+
The hash maps from the anchor of each bibitem (`bibitem/@id`), to an object containing the following fields:
|
84
|
+
|
85
|
+
`formattedref`:: the formatted reference, as output by `render(input)`, but with the date of the citation disambiguated
|
86
|
+
if called with `type: "author-date"`.
|
87
|
+
`citation`:: the citation for the reference (Author-Date if called with `type: "author-date"`; `docidentifier` if called with `type: nil`).
|
88
|
+
`author`:: the author designation for the reference (if called with `type: "author-date"`)
|
89
|
+
`date`:: the date designation for the reference, with disambiguating letter if necessary (if called with `type: "author-date"`).
|
90
|
+
The author and date are differentiated so that consumers can separate them in citations -- e.g. "Jones (1996) claims",
|
91
|
+
"(Jones 1996, 1997)".
|
92
|
+
|
42
93
|
== Configuration
|
43
94
|
|
44
95
|
=== Templates
|
@@ -99,6 +150,7 @@ drawn from the bibliographic item:
|
|
99
150
|
| title | ./title | | |
|
100
151
|
| edition | ./edition | | Y | If numeric value, is given internationalised rendering of "nth edition", as set in edition_numbering. Otherwise, the textual content of the tag is given.
|
101
152
|
| edition_raw | ./edition | | Y | The strict textual content of the tag is given.
|
153
|
+
| edition_num | ./edition[@number] | | Y |
|
102
154
|
| medium | ./medium | | Y |
|
103
155
|
| place | ./place | | Y |
|
104
156
|
| publisher | ./contributor[role/@type = 'publisher']/organization/name | | Y |
|
@@ -109,6 +161,7 @@ drawn from the bibliographic item:
|
|
109
161
|
| access_location | ./accessLocation | | Y |
|
110
162
|
| extent | ./extent | Y | | Render with standard abbreviations for pp, vols, with n-dash, with delimiting of multiple locations
|
111
163
|
| creatornames | ./contributor[role/@type = 'author'] \| ./contributor[role/@type = 'performer'] \| ./contributor[role/@type = 'adapter'] \| ./contributor[role/@type = 'translator'] \| ./contributor[role/@type = 'editor'] \| ./contributor[role/@type = 'publisher'] \| ./contributor[role/@type = 'distributor'] \| ./contributor | Y | | <<nametemplate,`nametemplate`>> applied to each name; joining template from internationalisation applied to multiple names
|
164
|
+
| authorcite | ./contributor[role/@type = 'author'] \| ./contributor[role/@type = 'performer'] \| ./contributor[role/@type = 'adapter'] \| ./contributor[role/@type = 'translator'] \| ./contributor[role/@type = 'editor'] \| ./contributor[role/@type = 'publisher'] \| ./contributor[role/@type = 'distributor'] \| ./contributor | Y | | <<authorcitetemplate,`authorcitetemplate`>> applied to each name; joining template from internationalisation applied to multiple names
|
112
165
|
| role | ./contributor[role/description] \| ./contributor[role/@type] | | |
|
113
166
|
| date | ./date[@type = 'issued'] \| ./date[@type = 'circulated'] \| ./date | | Y |
|
114
167
|
| date_updated | ./date[@type = 'updated'] | | Y |
|
@@ -121,6 +174,8 @@ drawn from the bibliographic item:
|
|
121
174
|
| labels | | | text to be looked up in internationalisation configuration files: "edition", "In", "At", "Vol", "Vols", "p.", "pp"
|
122
175
|
|===
|
123
176
|
|
177
|
+
Missing dates and places of publication are rendered as "n.d." and "n.p." or the equivalent internationalisation (`no_date`, `no_place` in the internationalisation YAML files.) However, missing dates are left as nil in standards, as undated standards indicate that the citation applies to the latest version of the standard, and not that the date is unknown.
|
178
|
+
|
124
179
|
Many fields are populated either by the description of the bibliographic item itself, or by the description of the item containing it (the _host_ item: `./relation[@type = 'includedIn']/bibitem`). For example, in a paper included in an edited volume, the edition will typically be given for the editor volume, rather than for the paper. Those fields are indicated by "Can come from host" in the table.
|
125
180
|
|
126
181
|
The Liquid templates use the filters defined in Liquid, such as `upcase`. We have defined some custom filters:
|
@@ -188,6 +243,12 @@ For example:
|
|
188
243
|
|
189
244
|
In the case of `more`, the `(name)[1]` entries are repeated for all additional authors above 2 and before the final author.
|
190
245
|
|
246
|
+
[[authorcitetemplate]]
|
247
|
+
=== Author citation templates
|
248
|
+
|
249
|
+
The `authorcitetemplate` is a subclass of the name template, configured for rendering author names for author-date citations.
|
250
|
+
That means that it typically selects only surnames for rendering.
|
251
|
+
|
191
252
|
[[seriestemplate]]
|
192
253
|
=== Series template
|
193
254
|
|
@@ -223,11 +284,11 @@ The extent of a bibliographic item may be expressed differently depending on the
|
|
223
284
|
|
224
285
|
To capture this, a separate template is supplied under `extenttemplate` for each bibliographic item type. For those types where none is supplied, the template given for `misc` is used as the default.
|
225
286
|
|
226
|
-
The template draws on the defined types of locality of extents; the most common of these is `
|
287
|
+
The template draws on the defined types of locality of extents; the most common of these is `volume`, `issue` (within volume; "number" for journals), and `page`. Locality types are the fields used in the Liquid templates; for example:
|
227
288
|
|
228
289
|
....
|
229
290
|
{
|
230
|
-
article: "{{ volume_raw }}: {{ page_raw }}"
|
291
|
+
article: "{{ volume_raw }}|({{ issue_raw }}) : {{ page_raw }}"
|
231
292
|
misc: "{{ volume }}, {{ page }}"
|
232
293
|
}
|
233
294
|
....
|
@@ -237,7 +298,7 @@ The internationalisation files define a singular and a plural version of the loc
|
|
237
298
|
* The plural label is always used if the extent is a range (with a `<from>` and `<to>`).
|
238
299
|
* The singular label is used if the extent is not a range (_pp. 2–4_ vs. _p. 3_).
|
239
300
|
* The internationalisation files include a slot where the number or number range is inserted, indicated by `%`, since this varies by language. (For instance, English has `pp. %`, whereas Chinese has `第%页`.)
|
240
|
-
* The number of the volume or page, without accompanying labels, is given in `volume_raw` and `page_raw`.
|
301
|
+
* The number of the volume, issue/number, or page, without accompanying labels, is given in `volume_raw`, `issue_raw`, and `page_raw`.
|
241
302
|
|
242
303
|
=== Size template
|
243
304
|
|
@@ -252,6 +313,8 @@ The template draws on the defined types of locality of extents; the following ar
|
|
252
313
|
|
253
314
|
| volume | ./medium/size[@type = 'volume'] | With internationalisation of label
|
254
315
|
| volume_raw | ./medium/size[@type = 'volume'] |
|
316
|
+
| issue | ./medium/size[@type = 'issue'] | With internationalisation of label
|
317
|
+
| issue_raw | ./medium/size[@type = 'issue'] |
|
255
318
|
| page | ./medium/size[@type = 'page'] | With internationalisation of label
|
256
319
|
| page_raw | ./medium/size[@type = 'page'] |
|
257
320
|
| data | ./medium/size[@type = 'data'] | Unit of size is included in value
|
@@ -4,6 +4,8 @@ and: و
|
|
4
4
|
updated: محدث
|
5
5
|
viewed: ينظر
|
6
6
|
version: الإصدار
|
7
|
+
no_date: بدون تاريخ
|
8
|
+
no_place: بدون مدينة
|
7
9
|
date_formats:
|
8
10
|
month_year: yMMMM
|
9
11
|
day_month_year: to_long_s
|
@@ -23,6 +25,9 @@ extent:
|
|
23
25
|
volume:
|
24
26
|
sg: "% المجلد"
|
25
27
|
pl: "% المجلدين"
|
28
|
+
issue:
|
29
|
+
sg: "% عدد"
|
30
|
+
pl: "% عدد"
|
26
31
|
size:
|
27
32
|
page:
|
28
33
|
sg: "ص %"
|
@@ -30,6 +35,9 @@ size:
|
|
30
35
|
volume:
|
31
36
|
sg: "المجلد %"
|
32
37
|
pl: "المجلدين %"
|
38
|
+
issue:
|
39
|
+
sg: "% عدد"
|
40
|
+
pl: "% عدد"
|
33
41
|
inflection:
|
34
42
|
الطبعة:
|
35
43
|
gender: f
|
@@ -4,6 +4,8 @@ and: und
|
|
4
4
|
updated: aktualisiert
|
5
5
|
viewed: angesehen
|
6
6
|
version: Version
|
7
|
+
no_date: o.J.
|
8
|
+
no_place: o.O.
|
7
9
|
date_formats:
|
8
10
|
month_year: yMMMM
|
9
11
|
day_month_year: to_long_s
|
@@ -22,6 +24,9 @@ extent:
|
|
22
24
|
volume:
|
23
25
|
sg: "Bd. %"
|
24
26
|
pl: "Bde. %"
|
27
|
+
issue:
|
28
|
+
sg: "Nr. %"
|
29
|
+
pl: "Nr. %"
|
25
30
|
size:
|
26
31
|
page:
|
27
32
|
sg: "% S."
|
@@ -29,6 +34,9 @@ size:
|
|
29
34
|
volume:
|
30
35
|
sg: "% Bd."
|
31
36
|
pl: "% Bde."
|
37
|
+
issue:
|
38
|
+
sg: "% Nr."
|
39
|
+
pl: "% Nr."
|
32
40
|
inflection:
|
33
41
|
Auflage:
|
34
42
|
gender: f
|
@@ -4,6 +4,8 @@ and: and
|
|
4
4
|
updated: updated
|
5
5
|
viewed: viewed
|
6
6
|
version: version
|
7
|
+
no_date: n.d.
|
8
|
+
no_place: n.p.
|
7
9
|
date_formats:
|
8
10
|
month_year: yMMMM
|
9
11
|
day_month_year: to_long_s
|
@@ -23,6 +25,9 @@ extent:
|
|
23
25
|
volume:
|
24
26
|
sg: "vol. %"
|
25
27
|
pl: "vols. %"
|
28
|
+
issue:
|
29
|
+
sg: "no. %"
|
30
|
+
pl: "nos. %"
|
26
31
|
size:
|
27
32
|
page:
|
28
33
|
sg: "% p."
|
@@ -30,4 +35,6 @@ size:
|
|
30
35
|
volume:
|
31
36
|
sg: "% vol."
|
32
37
|
pl: "% vols."
|
33
|
-
|
38
|
+
issue:
|
39
|
+
sg: "% no."
|
40
|
+
pl: "% nos."
|
@@ -4,6 +4,8 @@ and: y
|
|
4
4
|
updated: actualizado
|
5
5
|
viewed: visto
|
6
6
|
version: versión
|
7
|
+
no_date: s.f.
|
8
|
+
no_place: s.l.
|
7
9
|
date_formats:
|
8
10
|
month_year: yMMMM
|
9
11
|
day_month_year: to_long_s
|
@@ -25,6 +27,9 @@ extent:
|
|
25
27
|
volume:
|
26
28
|
sg: "vol. %"
|
27
29
|
pl: "vols. %"
|
30
|
+
issue:
|
31
|
+
sg: "núm. %"
|
32
|
+
pl: "núms. %"
|
28
33
|
size:
|
29
34
|
page:
|
30
35
|
sg: "% pág."
|
@@ -32,6 +37,10 @@ size:
|
|
32
37
|
volume:
|
33
38
|
sg: "% vol."
|
34
39
|
pl: "% vols."
|
40
|
+
issue:
|
41
|
+
sg: "% núm."
|
42
|
+
pl: "% núms."
|
43
|
+
|
35
44
|
inflection:
|
36
45
|
edición:
|
37
46
|
gender: f
|
@@ -4,6 +4,8 @@ and: et
|
|
4
4
|
updated: mise à jour
|
5
5
|
viewed: vu
|
6
6
|
version: version
|
7
|
+
no_date: s.d.
|
8
|
+
no_place: s.l.
|
7
9
|
date_formats:
|
8
10
|
month_year: yMMMM
|
9
11
|
day_month_year: to_long_s
|
@@ -27,6 +29,9 @@ extent:
|
|
27
29
|
volume:
|
28
30
|
sg: "vol. %"
|
29
31
|
pl: "vol. %"
|
32
|
+
issue:
|
33
|
+
sg: "nᵒ %"
|
34
|
+
pl: "nᵒˢ %"
|
30
35
|
size:
|
31
36
|
page:
|
32
37
|
sg: "% p."
|
@@ -34,6 +39,9 @@ size:
|
|
34
39
|
volume:
|
35
40
|
sg: "% vol."
|
36
41
|
pl: "% vol."
|
42
|
+
issue:
|
43
|
+
sg: "% nᵒ"
|
44
|
+
pl: "% nᵒˢ"
|
37
45
|
inflection:
|
38
46
|
édition:
|
39
47
|
gender: f
|
@@ -4,6 +4,8 @@ and: и
|
|
4
4
|
updated: обновлен
|
5
5
|
viewed: просмотрено
|
6
6
|
version: версия
|
7
|
+
no_date: б.г.
|
8
|
+
no_place: б.м.
|
7
9
|
date_formats:
|
8
10
|
month_year: yMMMM
|
9
11
|
day_month_year: to_long_s
|
@@ -29,6 +31,10 @@ extent:
|
|
29
31
|
volume:
|
30
32
|
sg: "т. %"
|
31
33
|
pl: "тт. %"
|
34
|
+
issue:
|
35
|
+
sg: "шт. %"
|
36
|
+
pl: "шт. %"
|
37
|
+
|
32
38
|
size:
|
33
39
|
page:
|
34
40
|
sg: "% стр."
|
@@ -36,6 +42,9 @@ size:
|
|
36
42
|
volume:
|
37
43
|
sg: "% т."
|
38
44
|
pl: "% тт."
|
45
|
+
issue:
|
46
|
+
sg: "% шт."
|
47
|
+
pl: "% шт."
|
39
48
|
inflection:
|
40
49
|
издание:
|
41
50
|
gender: n
|
@@ -4,6 +4,8 @@ and: 和
|
|
4
4
|
updated: 更新
|
5
5
|
viewed: 看过
|
6
6
|
version: 版本
|
7
|
+
no_date: 无日期
|
8
|
+
no_place: 无出版地
|
7
9
|
date_formats:
|
8
10
|
month_year: yMMMM
|
9
11
|
day_month_year: to_long_s
|
@@ -23,6 +25,9 @@ extent:
|
|
23
25
|
volume:
|
24
26
|
sg: "第%卷"
|
25
27
|
pl: "第%卷"
|
28
|
+
issue:
|
29
|
+
sg: "第%期"
|
30
|
+
pl: "第%期"
|
26
31
|
size:
|
27
32
|
page:
|
28
33
|
sg: "%页"
|
@@ -30,3 +35,6 @@ size:
|
|
30
35
|
volume:
|
31
36
|
sg: "%卷"
|
32
37
|
pl: "%卷"
|
38
|
+
issue:
|
39
|
+
sg: "%期"
|
40
|
+
pl: "%期"
|
@@ -16,15 +16,19 @@ module Relaton
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def name_fields_format(hash)
|
19
|
-
hash[:place] = nameformat(hash[:place_raw]&.map do |x|
|
20
|
-
{ nonpersonal: x }
|
21
|
-
end)
|
22
19
|
[%i(creatornames creators), %i(host_creatornames host_creators),
|
23
20
|
%i(publisher publisher_raw), %i(distributor distributor_raw)]
|
24
21
|
.each do |k|
|
25
22
|
hash[k[0]] = nameformat(hash[k[1]])
|
26
23
|
end
|
27
24
|
hash[:publisher_abbrev] = hash[:publisher_abbrev_raw]&.join(", ")
|
25
|
+
hash[:authorcite] = authorciteformat(hash[:creators])
|
26
|
+
place_format(hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
def place_format(hash)
|
30
|
+
hash[:place] =
|
31
|
+
nameformat(hash[:place_raw].map { |x| { nonpersonal: x } })
|
28
32
|
end
|
29
33
|
|
30
34
|
def role_fields_format(hash)
|
@@ -34,7 +38,7 @@ module Relaton
|
|
34
38
|
end
|
35
39
|
|
36
40
|
def edition_fields_format(hash)
|
37
|
-
hash[:edition] = editionformat(hash[:edition_raw])
|
41
|
+
hash[:edition] = editionformat(hash[:edition_raw], hash[:edition_num])
|
38
42
|
hash[:draft] = draftformat(hash[:draft_raw], hash)
|
39
43
|
end
|
40
44
|
|
@@ -51,6 +55,8 @@ module Relaton
|
|
51
55
|
[%i(date date), %i(date_updated date_updated),
|
52
56
|
%i(date_accessed date_accessed)].each do |k|
|
53
57
|
hash[k[0]] = dateformat(hash[k[1]], hash)
|
58
|
+
k[0] == :date && hash[:type] != "standard" and
|
59
|
+
hash[k[0]] ||= @r.i18n.get["no_date"]
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
@@ -87,6 +93,19 @@ module Relaton
|
|
87
93
|
@r.nametemplate.render(names_out)
|
88
94
|
end
|
89
95
|
|
96
|
+
def authorciteformat(names)
|
97
|
+
return names if names.nil?
|
98
|
+
|
99
|
+
parts = %i(surname initials given middle nonpersonal)
|
100
|
+
names_out = names.each_with_object({}) do |n, m|
|
101
|
+
parts.each do |i|
|
102
|
+
m[i] ||= []
|
103
|
+
m[i] << n[i]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
@r.authorcitetemplate.render(names_out)
|
107
|
+
end
|
108
|
+
|
90
109
|
def role_inflect(contribs, role)
|
91
110
|
return nil if role.nil? || contribs.size.zero? ||
|
92
111
|
%w(author publisher).include?(role)
|
@@ -95,11 +114,11 @@ module Relaton
|
|
95
114
|
@r.i18n.get[role][number] || role
|
96
115
|
end
|
97
116
|
|
98
|
-
def editionformat(edn)
|
99
|
-
return edn unless /^\d+$/.match?(edn)
|
117
|
+
def editionformat(edn, num)
|
118
|
+
return edn unless num || /^\d+$/.match?(edn)
|
100
119
|
|
101
|
-
|
102
|
-
@r.edition_ordinal.sub(/%(Spellout|Ordinal)?/,
|
120
|
+
ret = edition_translate1(num || edn.to_i)
|
121
|
+
@r.edition_ordinal.sub(/%(Spellout|Ordinal)?/, ret)
|
103
122
|
end
|
104
123
|
|
105
124
|
def edition_translate1(num)
|
@@ -133,7 +152,7 @@ module Relaton
|
|
133
152
|
end
|
134
153
|
|
135
154
|
def extentformat1(key, val, hash, norm_hash)
|
136
|
-
if %i(volume page).include?(key)
|
155
|
+
if %i(volume issue page).include?(key)
|
137
156
|
hash["#{key}_raw".to_sym] = norm_hash[key]
|
138
157
|
hash[key] = pagevolformat(norm_hash[key], val, key.to_s, false)
|
139
158
|
end
|
@@ -164,6 +183,9 @@ module Relaton
|
|
164
183
|
when "volume"
|
165
184
|
hash[:volume_raw] = val
|
166
185
|
hash[:volume] = pagevolformat(val, nil, "volume", true)
|
186
|
+
when "issue"
|
187
|
+
hash[:issue_raw] = val
|
188
|
+
hash[:issue] = pagevolformat(val, nil, "issue", true)
|
167
189
|
when "page"
|
168
190
|
hash[:page_raw] = val
|
169
191
|
hash[:page] = pagevolformat(val, nil, "page", true)
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Relaton
|
2
|
+
module Render
|
3
|
+
class Citations
|
4
|
+
def initialize(opt = {})
|
5
|
+
@type = opt[:type]
|
6
|
+
@i18n = opt[:i18n]
|
7
|
+
@renderer = opt[:renderer]
|
8
|
+
end
|
9
|
+
|
10
|
+
# takes array of { id, type, author, date, ord, data_liquid }
|
11
|
+
def render(ret)
|
12
|
+
cites = citations(ret)
|
13
|
+
cites.each_key do |k|
|
14
|
+
cites[k] = render1(cites[k])
|
15
|
+
end
|
16
|
+
cites
|
17
|
+
end
|
18
|
+
|
19
|
+
def render1(cit)
|
20
|
+
r = @renderer.renderer(cit[:type] || "misc")
|
21
|
+
cit[:formattedref] =
|
22
|
+
@renderer.valid_parse(@i18n.l10n(r.render(cit[:data_liquid])))
|
23
|
+
%i(type data_liquid).each { |x| cit.delete(x) }
|
24
|
+
cit
|
25
|
+
end
|
26
|
+
|
27
|
+
def citations(ret)
|
28
|
+
case @type
|
29
|
+
when "author-date" then disambig_author_date_citations(ret)
|
30
|
+
when nil then generic_citation(ret)
|
31
|
+
else raise "Unimplemented citation type"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def generic_citation(ret)
|
36
|
+
ret.each_with_object({}) do |b, m|
|
37
|
+
m[b[:id]] = { data_liquid: b[:data_liquid], type: b[:type],
|
38
|
+
citation: b[:data_liquid][:docidentifier] }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# takes array of { id, type, author, date, ord, data_liquid }
|
43
|
+
def disambig_author_date_citations(ret)
|
44
|
+
to_hash(suffix_date(sort_ord(breakdown(ret))))
|
45
|
+
end
|
46
|
+
|
47
|
+
def breakdown(ret)
|
48
|
+
ret.each_with_object({}) do |b, m|
|
49
|
+
m[b[:author]] ||= {}
|
50
|
+
m[b[:author]][b[:date]] ||= []
|
51
|
+
m[b[:author]][b[:date]] << b
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def sort_ord(ret)
|
56
|
+
ret.each do |author, v|
|
57
|
+
v.each_key do |date|
|
58
|
+
ret[author][date].sort! { |a, b| a[:ord] <=> b[:ord] }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def suffix_date(ret)
|
64
|
+
ret.each_value do |v|
|
65
|
+
v.each_value do |v1|
|
66
|
+
next if v1.size < 2
|
67
|
+
|
68
|
+
v1.each_with_index do |b, i|
|
69
|
+
b[:date] += ("a".ord + i).chr.to_s
|
70
|
+
b[:data_liquid][:date] = b[:date]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
ret
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_hash(ret)
|
78
|
+
ret.each_with_object({}) do |(_k, v), m|
|
79
|
+
v.each do |_k1, v1|
|
80
|
+
v1.each do |b|
|
81
|
+
m[b[:id]] = { author: b[:author], date: b[:date],
|
82
|
+
citation: "#{b[:author]} #{b[:date]}",
|
83
|
+
data_liquid: b[:data_liquid], type: b[:type] }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -5,6 +5,13 @@ nametemplate:
|
|
5
5
|
# disabled the following: they should be provided in inheriting calls
|
6
6
|
# etal: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] | upcase}} ,_{%if given[0]%}{{given[0]}} {{middle[0]}}{%else%}{{initials[0] | join: '. '}}.{%endif%}{% endif %}, {% if nonpersonal[1] %}{{ nonpersonal[1] }}{% else %}{%if given[1]%}{{given[1]}} {{middle[1]}}{%else%}{{initials[1] | join: '. '}}.{%endif%} {{surname[1] | upcase}}{% endif %} <em>et al.</em>"
|
7
7
|
# etal_count: 5
|
8
|
+
authorcitetemplate:
|
9
|
+
one: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] }}{% endif %}"
|
10
|
+
two: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] }}{% endif %} {{ labels['and'] }} {% if nonpersonal[1] %}{{ nonpersonal[1] }}{% else %}{{surname[1] }}{% endif %}"
|
11
|
+
more: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] }}{% endif %}, {% if nonpersonal[1] %}{{ nonpersonal[1] }}{% else %}{{surname[1] }}{% endif %} {{ labels['and'] }} {% if nonpersonal[2] %}{{ nonpersonal[2] }}{% else %}{{surname[2] }}{% endif %}"
|
12
|
+
# disabled the following: they should be provided in inheriting calls
|
13
|
+
# etal: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] }}{% endif %}, {% if nonpersonal[1] %}{{ nonpersonal[1] }}{% else %}{{surname[1] }}{% endif %} <em>et al.</em>"
|
14
|
+
# etal_count: 5
|
8
15
|
seriestemplate: "{% if series_formatted %}{{ series_formatted }}{%else%}{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %} ({{series_run}}) {{series_num}}|({{series_partnumber}}){%endif%}"
|
9
16
|
journaltemplate: "<em>{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %}</em> ({{series_run}}) {{ labels['volume'] }}_{{series_num}} {{ labels['part'] }}_{{series_partnumber}}"
|
10
17
|
extenttemplate:
|
@@ -15,21 +22,21 @@ extenttemplate:
|
|
15
22
|
standard: book
|
16
23
|
techreport: book
|
17
24
|
inbook: "{{ volume }}: {{ page }}"
|
18
|
-
misc: "{{ volume }}, {{ page }}, {{ duration }}"
|
25
|
+
misc: "{{ volume }} {{issue}} , {{ page }}, {{ duration }}"
|
19
26
|
sizetemplate:
|
20
27
|
dataset: "{{ data }}"
|
21
28
|
electronic resource: dataset
|
22
29
|
webresource: dataset
|
23
|
-
misc: "{{ volume }}, {{ page }}, {{ data }}, {{ duration }}"
|
30
|
+
misc: "{{ volume }}, {{ issue }}, {{ page }}, {{ data }}, {{ duration }}"
|
24
31
|
language: en
|
25
32
|
script: Latn
|
26
33
|
template:
|
27
|
-
book: "{{ creatornames }} ({{role}}) . <em>{{ title }}</em> [{{medium}}] . {{ edition | capitalize_first }}. ({{ series }}.) {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. {{size}}. {{extent}}."
|
34
|
+
book: "{{ creatornames }} ({{role}}) . <em>{{ title }}</em> [{{medium}}] . {{ edition | capitalize_first }}. ({{ series }}.) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. {{size}}. {{extent}}."
|
28
35
|
# TODO: omitted: author ids, subsidiary titles, subsidiary creators, rights metadata, distributor, item attributes, relationships
|
29
36
|
booklet: book
|
30
37
|
manual: book
|
31
38
|
proceedings: book
|
32
|
-
inbook: "{{ creatornames }} ({{role}}) . {{ title }} . {{ labels['in'] | capitalize }}: {{ host_creatornames}} ({{ host_role}}) : <em>{{host_title}}</em> [{{medium}}] . {{ edition | capitalize_first }}. ({{ series }}.) {{place}}: {{publisher}}. {{date}}. {{size}}. {{extent}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
39
|
+
inbook: "{{ creatornames }} ({{role}}) . {{ title }} . {{ labels['in'] | capitalize }}: {{ host_creatornames}} ({{ host_role}}) : <em>{{host_title}}</em> [{{medium}}] . {{ edition | capitalize_first }}. ({{ series }}.) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}. {{date}}. {{size}}. {{extent}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
33
40
|
inproceedings: inbook
|
34
41
|
incollection: inbook
|
35
42
|
# TODO: omitted: author ids, additional info for component part, subsidiary titles of host resource, rights metadata, distributor, relationships
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "render_classes"
|
2
|
+
require_relative "citations"
|
2
3
|
require "yaml"
|
3
4
|
require "liquid"
|
4
5
|
require "relaton_bib"
|
@@ -9,7 +10,8 @@ module Relaton
|
|
9
10
|
module Render
|
10
11
|
class General
|
11
12
|
attr_reader :template, :journaltemplate, :seriestemplate, :nametemplate,
|
12
|
-
:
|
13
|
+
:authorcitetemplate, :extenttemplate, :sizetemplate,
|
14
|
+
:lang, :script, :i18n,
|
13
15
|
:edition, :edition_ordinal, :date
|
14
16
|
|
15
17
|
def initialize(opt = {})
|
@@ -27,6 +29,7 @@ module Relaton
|
|
27
29
|
|
28
30
|
def klass_initialize(_options)
|
29
31
|
@nametemplateklass = Relaton::Render::Template::Name
|
32
|
+
@authorcitetemplateklass = Relaton::Render::Template::AuthorCite
|
30
33
|
@seriestemplateklass = Relaton::Render::Template::Series
|
31
34
|
@extenttemplateklass = Relaton::Render::Template::Extent
|
32
35
|
@sizetemplateklass = Relaton::Render::Template::Size
|
@@ -40,6 +43,8 @@ module Relaton
|
|
40
43
|
@parse = @parseklass.new(lang: @lang, script: @script)
|
41
44
|
@nametemplate = @nametemplateklass
|
42
45
|
.new(template: opt["nametemplate"], i18n: @i18n)
|
46
|
+
@authorcitetemplate = @authorcitetemplateklass
|
47
|
+
.new(template: opt["authorcitetemplate"], i18n: @i18n)
|
43
48
|
@seriestemplate = @seriestemplateklass
|
44
49
|
.new(template: opt["seriestemplate"], i18n: @i18n)
|
45
50
|
@journaltemplate = @seriestemplateklass
|
@@ -128,7 +133,42 @@ module Relaton
|
|
128
133
|
data = @parse.extract(doc)
|
129
134
|
data_liquid = @fieldsklass.new(renderer: self)
|
130
135
|
.compound_fields_format(data)
|
131
|
-
@i18n.l10n(r.render(data_liquid))
|
136
|
+
valid_parse(@i18n.l10n(r.render(data_liquid)))
|
137
|
+
end
|
138
|
+
|
139
|
+
def valid_parse(ret)
|
140
|
+
@i18n.get["no_date"] == ret and return nil
|
141
|
+
ret
|
142
|
+
end
|
143
|
+
|
144
|
+
# expect array of Relaton objects, in sorted order
|
145
|
+
def render_all(bib, type: "author-date")
|
146
|
+
bib = sanitise_citations_input(bib) or return
|
147
|
+
Citations.new(type: type, renderer: self, i18n: @i18n)
|
148
|
+
.render(citations1(bib))
|
149
|
+
end
|
150
|
+
|
151
|
+
def sanitise_citations_input(bib)
|
152
|
+
bib.is_a?(Array) and return bib
|
153
|
+
bib.is_a?(String) and return sanitise_citations_input_string(bib)
|
154
|
+
end
|
155
|
+
|
156
|
+
def sanitise_citations_input_string(bib)
|
157
|
+
p = Nokogiri::XML(bib) or return
|
158
|
+
(p.errors.empty? && p.root.at("./bibitem")) or return nil
|
159
|
+
|
160
|
+
p.root.xpath("./bibitem").each_with_object([]) do |b, m|
|
161
|
+
m << RelatonBib::XMLParser.from_xml(b.to_xml)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def citations1(bib)
|
166
|
+
bib.each_with_object([]).with_index do |(b, m), i|
|
167
|
+
data_liquid = @fieldsklass.new(renderer: self)
|
168
|
+
.compound_fields_format(@parse.extract(b))
|
169
|
+
m << { author: data_liquid[:authorcite], date: data_liquid[:date],
|
170
|
+
ord: i, id: b.id, data_liquid: data_liquid, type: b.type }
|
171
|
+
end
|
132
172
|
end
|
133
173
|
|
134
174
|
private
|
@@ -27,7 +27,8 @@ module Relaton
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def simple_or_host_xml2hash(doc, host)
|
30
|
-
{ edition_raw: edition(doc, host),
|
30
|
+
{ edition_raw: edition(doc, host), edition_num: edition_num(doc, host),
|
31
|
+
medium_raw: medium(doc, host),
|
31
32
|
place_raw: place(doc, host), publisher_raw: publisher(doc, host),
|
32
33
|
publisher_abbrev_raw: publisher_abbrev(doc, host),
|
33
34
|
distributor_raw: distributor(doc, host), draft_raw: draft(doc, host),
|
@@ -33,7 +33,11 @@ module Relaton
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def edition(doc, host)
|
36
|
-
doc.edition || host&.edition
|
36
|
+
doc.edition&.content || host&.edition&.content
|
37
|
+
end
|
38
|
+
|
39
|
+
def edition_num(doc, host)
|
40
|
+
doc.edition&.number || host&.edition&.number
|
37
41
|
end
|
38
42
|
|
39
43
|
def place(doc, host)
|
data/relaton-render.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_dependency "isodoc-i18n"
|
32
32
|
spec.add_dependency "liquid", "~> 4"
|
33
33
|
spec.add_dependency "nokogiri"
|
34
|
-
spec.add_dependency "relaton-bib", ">= 1.
|
34
|
+
spec.add_dependency "relaton-bib", ">= 1.12.0"
|
35
35
|
spec.add_dependency "twitter_cldr"
|
36
36
|
spec.add_dependency "tzinfo-data" # we need this for windows only
|
37
37
|
#spec.metadata["rubygems_mfa_required"] = "true"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relaton-render
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -142,14 +142,14 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 1.
|
145
|
+
version: 1.12.0
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 1.
|
152
|
+
version: 1.12.0
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: twitter_cldr
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,6 +206,7 @@ files:
|
|
206
206
|
- lib/relaton-render.rb
|
207
207
|
- lib/relaton/render/fields/date.rb
|
208
208
|
- lib/relaton/render/fields/fields.rb
|
209
|
+
- lib/relaton/render/general/citations.rb
|
209
210
|
- lib/relaton/render/general/config.yml
|
210
211
|
- lib/relaton/render/general/render.rb
|
211
212
|
- lib/relaton/render/general/render_classes.rb
|
@@ -236,7 +237,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
237
|
- !ruby/object:Gem::Version
|
237
238
|
version: '0'
|
238
239
|
requirements: []
|
239
|
-
rubygems_version: 3.3.
|
240
|
+
rubygems_version: 3.3.16
|
240
241
|
signing_key:
|
241
242
|
specification_version: 4
|
242
243
|
summary: Rendering of ISO 690 XML
|