relaton-render 3.0.0.pre.alpha.5 → 3.0.0.pre.alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/relaton/render/general.rb +15 -5
- data/lib/relaton/render/iso690/element.rb +28 -4
- data/lib/relaton/render/iso690/elements/component_part.rb +3 -1
- data/lib/relaton/render/iso690/elements/creator.rb +11 -4
- data/lib/relaton/render/iso690/elements/production.rb +17 -1
- data/lib/relaton/render/iso690/renderer.rb +8 -4
- data/lib/relaton/render/iso690/style/name_form.rb +19 -0
- data/lib/relaton/render/iso690/style/scheme.rb +1 -1
- data/lib/relaton/render/iso690/style/template_map.rb +2 -0
- data/lib/relaton/render/iso690/style/type_template.rb +4 -0
- data/lib/relaton/render/iso690/style.rb +2 -1
- data/lib/relaton/render/iso690/template.rb +3 -0
- data/lib/relaton/render/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1765d54a70d5e79ba48d03c848135bad61bfb6f27e439cb142e869054e06b181
|
|
4
|
+
data.tar.gz: 9d8636b1838f06a8d119ad2052e7c7b7c47f81f6e9d176ca414fb76b1cbc0698
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d4907031dd0d8e1180b3e25221000d58498d5bd18468bf743d372fc84ca79d878518f3b4c966d7faa7dfb3b36c4c5a61fef82d5c508295e3167dfb9cb722485a
|
|
7
|
+
data.tar.gz: 832213c7c17a9b58dee06a8953c75f30a41b23e568a3ff936cf32d4167a69b69eebe74d9bfbd31b0e7cd22ac3964da999aeb05f2bbd7e30b86473d656b458067
|
|
@@ -63,15 +63,25 @@ module Relaton
|
|
|
63
63
|
end
|
|
64
64
|
m[item.id] = {
|
|
65
65
|
id: item.id, ord: i, formattedref: ref,
|
|
66
|
-
citation:
|
|
67
|
-
full: ref,
|
|
68
|
-
default: item.docidentifier.first&.content.to_s,
|
|
69
|
-
short: @renderer.citation(item),
|
|
70
|
-
},
|
|
66
|
+
citation: citation_renderings(item, ref),
|
|
71
67
|
}
|
|
72
68
|
end
|
|
73
69
|
end
|
|
74
70
|
|
|
71
|
+
# isodoc's styled citations consume these keys: the default is the
|
|
72
|
+
# authoritative identifier; the short cite is the style's citation,
|
|
73
|
+
# falling back to the reference rendering (the 1.x short-cite)
|
|
74
|
+
def citation_renderings(item, ref)
|
|
75
|
+
short = @renderer.citation(item)
|
|
76
|
+
short = ref if short.empty?
|
|
77
|
+
|
|
78
|
+
{
|
|
79
|
+
full: ref,
|
|
80
|
+
default: item.docidentifier.first&.content.to_s,
|
|
81
|
+
short: short,
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
|
|
75
85
|
# isodoc's pref_ref_code_parse reads
|
|
76
86
|
# data[:authoritative_identifier] to build biblio-tag identifiers
|
|
77
87
|
# (presentation_function/docid.rb). Returns [data, self] as the
|
|
@@ -48,8 +48,12 @@ module Relaton
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def org_name(contributor)
|
|
51
|
+
shown = ->(n) do
|
|
52
|
+
text = localized(n)
|
|
53
|
+
@style.scheme.name_form.org_upcase ? text.upcase : text
|
|
54
|
+
end
|
|
51
55
|
name = Array(contributor.organization&.name)
|
|
52
|
-
.map
|
|
56
|
+
.map(&shown).join(", ")
|
|
53
57
|
abbrev = localized(contributor.organization&.abbreviation)
|
|
54
58
|
return name if name.empty? || abbrev.empty?
|
|
55
59
|
|
|
@@ -76,26 +80,46 @@ module Relaton
|
|
|
76
80
|
|
|
77
81
|
""
|
|
78
82
|
end.reject(&:empty?)
|
|
79
|
-
|
|
80
|
-
return
|
|
83
|
+
sep = @style.scheme.name_form.initials_separator.to_s
|
|
84
|
+
return reinitials(localized(person.name&.formatted_initials),
|
|
85
|
+
sep) if parts.empty?
|
|
86
|
+
return parts.map { |p| "#{p[0]}." }.join(sep) if initials?
|
|
81
87
|
|
|
82
88
|
parts.join(" ")
|
|
83
89
|
end
|
|
84
90
|
|
|
91
|
+
# Declared initials are a list in string form; rejoin them with
|
|
92
|
+
# the style's separator
|
|
93
|
+
def reinitials(raw, sep)
|
|
94
|
+
raw.split(/\s+/).reject(&:empty?).join(sep)
|
|
95
|
+
end
|
|
96
|
+
|
|
85
97
|
def initials?
|
|
86
98
|
@style.scheme.name_form.initials
|
|
87
99
|
end
|
|
88
100
|
|
|
89
101
|
def join_names(names)
|
|
102
|
+
oxford = @i18n.label("oxford_comma")
|
|
103
|
+
if serial_list? && names.size > 1 && !oxford.empty?
|
|
104
|
+
return "#{names[0..-2].join(', ')}#{oxford} " \
|
|
105
|
+
"#{@i18n.label('and')} #{names.last}"
|
|
106
|
+
end
|
|
107
|
+
|
|
90
108
|
case names.size
|
|
91
109
|
when 0 then ""
|
|
92
110
|
when 1 then names.first
|
|
93
111
|
when 2 then names.join(" #{@i18n.label('and')} ")
|
|
94
112
|
else
|
|
95
|
-
"#{names[0..-2].join(', ')}#{
|
|
113
|
+
"#{names[0..-2].join(', ')}#{oxford} " \
|
|
96
114
|
"#{@i18n.label('and')} #{names.last}"
|
|
97
115
|
end
|
|
98
116
|
end
|
|
117
|
+
|
|
118
|
+
# Serial list style: the oxford comma appears at every gap of a
|
|
119
|
+
# name list, including between two names
|
|
120
|
+
def serial_list?
|
|
121
|
+
@style.scheme.name_form.list_style == "serial"
|
|
122
|
+
end
|
|
99
123
|
end
|
|
100
124
|
end
|
|
101
125
|
end
|
|
@@ -69,7 +69,9 @@ module Relaton
|
|
|
69
69
|
|
|
70
70
|
surname = person_surname(person)
|
|
71
71
|
given = person_given(person)
|
|
72
|
-
if
|
|
72
|
+
if @style.scheme.name_form.inverted_all
|
|
73
|
+
@style.render_name(surname: surname, given: given)
|
|
74
|
+
elsif first
|
|
73
75
|
[surname, given].reject(&:empty?).join(", ")
|
|
74
76
|
else
|
|
75
77
|
[given, surname].reject(&:empty?).join(" ")
|
|
@@ -15,19 +15,26 @@ module Relaton
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def render
|
|
18
|
+
joined = if (form = @style.templates.creators) && !form.empty?
|
|
19
|
+
::Relaton::Render::Iso690::Template.new(form).evaluate(
|
|
20
|
+
"names" => Template::Field[true, join(names)],
|
|
21
|
+
)
|
|
22
|
+
else
|
|
23
|
+
join(names)
|
|
24
|
+
end
|
|
18
25
|
case role_placement
|
|
19
26
|
when "afterPeriod"
|
|
20
27
|
# the in-slot trailing space separates the (eds.) marker
|
|
21
28
|
# from the next element, which follows directly in the
|
|
22
29
|
# template; a lone editor is unmarked
|
|
23
30
|
if editors? && creators.size > 1
|
|
24
|
-
"#{period(
|
|
31
|
+
"#{period(joined)} (#{role_word}) "
|
|
25
32
|
else
|
|
26
|
-
"#{period(
|
|
33
|
+
"#{period(joined)} "
|
|
27
34
|
end
|
|
28
35
|
else
|
|
29
36
|
marker = editors? && creators.size > 1 ? " (#{role_word})" : ''
|
|
30
|
-
"#{
|
|
37
|
+
"#{joined}#{marker}"
|
|
31
38
|
end
|
|
32
39
|
end
|
|
33
40
|
|
|
@@ -96,7 +103,7 @@ module Relaton
|
|
|
96
103
|
def personal_name(person, first:)
|
|
97
104
|
surname = surname(person).to_s
|
|
98
105
|
given = given_names(person)
|
|
99
|
-
if first && !name_form.given_name_first
|
|
106
|
+
if (first || name_form.inverted_all) && !name_form.given_name_first
|
|
100
107
|
@style.render_name(surname: surname, given: given)
|
|
101
108
|
else
|
|
102
109
|
[given, surname.upcase].reject(&:empty?).join(" ")
|
|
@@ -9,14 +9,30 @@ module Relaton
|
|
|
9
9
|
# organization contributors.
|
|
10
10
|
class Production < Element
|
|
11
11
|
def present?
|
|
12
|
-
!places.empty? || !publishers.empty?
|
|
12
|
+
!places.empty? || !publishers.empty? || no_place_declared?
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def render
|
|
16
|
+
return no_place_production if places.empty? && no_place_declared?
|
|
17
|
+
|
|
16
18
|
[places.join("; "), publishers.join("; ")]
|
|
17
19
|
.reject(&:empty?).join(@i18n.punct_fetch("production_sep", ": "))
|
|
18
20
|
end
|
|
19
21
|
|
|
22
|
+
# The no-place placeholder keeps the production separator even
|
|
23
|
+
# when no publisher follows ("n.p.: n.d.")
|
|
24
|
+
def no_place_production
|
|
25
|
+
label = @i18n.label("no_place")
|
|
26
|
+
return "" if label.empty? || label == "no_place"
|
|
27
|
+
|
|
28
|
+
pubs = publishers.join("; ")
|
|
29
|
+
pubs.empty? ? "#{label}:" : "#{label}: #{pubs}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def no_place_declared?
|
|
33
|
+
@style.type_template_for(item_kind)&.no_place == true
|
|
34
|
+
end
|
|
35
|
+
|
|
20
36
|
private
|
|
21
37
|
|
|
22
38
|
def places
|
|
@@ -25,8 +25,11 @@ module Relaton
|
|
|
25
25
|
def initialize(style: DEFAULT_STYLE, lang: "en", script: "Latn",
|
|
26
26
|
labels: {})
|
|
27
27
|
@style = Style.load(style)
|
|
28
|
-
@i18n = I18n.load(lang)
|
|
28
|
+
@i18n = I18n.load(lang)
|
|
29
29
|
@i18n.overlay_hash!(labels) unless labels.empty?
|
|
30
|
+
# The style instance is the citation-style authority: its
|
|
31
|
+
# declared strings win over the caller's generic i18n hash
|
|
32
|
+
@i18n.overlay!(@style.scheme.locale)
|
|
30
33
|
@script = script
|
|
31
34
|
end
|
|
32
35
|
|
|
@@ -43,9 +46,10 @@ module Relaton
|
|
|
43
46
|
end
|
|
44
47
|
|
|
45
48
|
def home_docid?(model)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
types = Array(@style.scheme.home_docid_type)
|
|
50
|
+
return false if types.empty?
|
|
51
|
+
|
|
52
|
+
Array(model.docidentifier).any? { |d| types.include?(d.type) }
|
|
49
53
|
end
|
|
50
54
|
|
|
51
55
|
# In-text form: SURNAME, year + disambiguator (name-and-date)
|
|
@@ -17,12 +17,31 @@ module Relaton
|
|
|
17
17
|
# A completename is rendered, not decomposed; styles that
|
|
18
18
|
# upcase inverted names may declare the completename treatment
|
|
19
19
|
attribute :completename_upcase, :boolean, default: -> { false }
|
|
20
|
+
# Every personal name takes the inverted form (surname first),
|
|
21
|
+
# not just the principal creator
|
|
22
|
+
attribute :inverted_all, :boolean, default: -> { false }
|
|
23
|
+
# "serial": the oxford comma appears at every gap of the
|
|
24
|
+
# creator list, including between two names
|
|
25
|
+
attribute :list_style, :string, default: ""
|
|
26
|
+
# Organization names take the inverted form's casing; small-cap
|
|
27
|
+
# styles keep the declared case
|
|
28
|
+
attribute :org_upcase, :boolean, default: -> { true }
|
|
29
|
+
# The inverted form's surname casing: the name-date convention
|
|
30
|
+
# upcases; small-cap styles keep the declared case
|
|
31
|
+
attribute :surname_upcase, :boolean, default: -> { true }
|
|
32
|
+
# Initials are a list; this separates them ("J. K." vs "J.K.")
|
|
33
|
+
attribute :initials_separator, :string, default: " "
|
|
20
34
|
|
|
21
35
|
key_value do
|
|
22
36
|
map "initials", to: :initials
|
|
23
37
|
map "givenNameFirst", to: :given_name_first
|
|
24
38
|
map "rolePlacement", to: :role_placement
|
|
25
39
|
map "completenameUpcase", to: :completename_upcase
|
|
40
|
+
map "invertedAll", to: :inverted_all
|
|
41
|
+
map "listStyle", to: :list_style
|
|
42
|
+
map "orgUpcase", to: :org_upcase
|
|
43
|
+
map "surnameUpcase", to: :surname_upcase
|
|
44
|
+
map "initialsSeparator", to: :initials_separator
|
|
26
45
|
end
|
|
27
46
|
end
|
|
28
47
|
end
|
|
@@ -10,7 +10,7 @@ module Relaton
|
|
|
10
10
|
attribute :system, :string, default: "name-date"
|
|
11
11
|
attribute :name_form, NameForm, default: -> { NameForm.new }
|
|
12
12
|
attribute :locale, Locale, default: -> { Locale.new }
|
|
13
|
-
attribute :home_docid_type, :string
|
|
13
|
+
attribute :home_docid_type, :string, collection: true
|
|
14
14
|
|
|
15
15
|
key_value do
|
|
16
16
|
map "system", to: :system
|
|
@@ -15,6 +15,7 @@ module Relaton
|
|
|
15
15
|
attribute :name, :string, default: "{{surname}}, {{givenNames}}"
|
|
16
16
|
attribute :series, :string, default: ""
|
|
17
17
|
attribute :uri, :string, default: ""
|
|
18
|
+
attribute :creators, :string, default: ""
|
|
18
19
|
|
|
19
20
|
key_value do
|
|
20
21
|
map "titleOpen", to: :title_open
|
|
@@ -24,6 +25,7 @@ module Relaton
|
|
|
24
25
|
map "name", to: :name
|
|
25
26
|
map "series", to: :series
|
|
26
27
|
map "uri", to: :uri
|
|
28
|
+
map "creators", to: :creators
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
@@ -13,6 +13,9 @@ module Relaton
|
|
|
13
13
|
attribute :title, :string
|
|
14
14
|
attribute :home, :boolean
|
|
15
15
|
attribute :fallbacks, :hash, default: -> { {} }
|
|
16
|
+
# Render the style's no_place label when the publisher has no
|
|
17
|
+
# place (the book-family templates of some flavors)
|
|
18
|
+
attribute :no_place, :boolean
|
|
16
19
|
|
|
17
20
|
key_value do
|
|
18
21
|
map "type", to: :type
|
|
@@ -21,6 +24,7 @@ module Relaton
|
|
|
21
24
|
map "title", to: :title
|
|
22
25
|
map "home", to: :home
|
|
23
26
|
map "fallbacks", to: :fallbacks
|
|
27
|
+
map "noPlace", to: :no_place
|
|
24
28
|
end
|
|
25
29
|
end
|
|
26
30
|
end
|
|
@@ -69,8 +69,9 @@ module Relaton
|
|
|
69
69
|
# First-creator name form: the style's declared name template with
|
|
70
70
|
# the surname upcased, per the name-and-date convention.
|
|
71
71
|
def render_name(surname:, given:)
|
|
72
|
+
shown = scheme.name_form.surname_upcase ? surname.upcase : surname
|
|
72
73
|
Template.new(templates.name).evaluate(
|
|
73
|
-
"surname" => Template::Field[!
|
|
74
|
+
"surname" => Template::Field[!shown.empty?, shown],
|
|
74
75
|
"givennames" => Template::Field[!given.empty?, given],
|
|
75
76
|
)
|
|
76
77
|
end
|
|
@@ -57,6 +57,9 @@ module Relaton
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def terminate(body)
|
|
60
|
+
# An element ending in a colon carries its own separator: the
|
|
61
|
+
# following sentence period collapses (1.x punctuation cleanup)
|
|
62
|
+
body = body.gsub(/:\s*\.\s*/, ": ")
|
|
60
63
|
return body if @terminator.strip.empty?
|
|
61
64
|
return body if body.rstrip.end_with?(@terminator.strip)
|
|
62
65
|
|