relaton-render 3.0.0.pre.alpha.4 → 3.0.0.pre.alpha.6
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/iso690/element.rb +18 -2
- data/lib/relaton/render/iso690/elements/component_part.rb +5 -2
- data/lib/relaton/render/iso690/elements/creator.rb +23 -4
- data/lib/relaton/render/iso690/elements/production.rb +8 -1
- data/lib/relaton/render/iso690/elements/series.rb +2 -1
- data/lib/relaton/render/iso690/elements/title.rb +7 -3
- data/lib/relaton/render/iso690/fields.rb +12 -1
- data/lib/relaton/render/iso690/identifier_kinds.rb +6 -2
- data/lib/relaton/render/iso690/renderer.rb +4 -3
- data/lib/relaton/render/iso690/style/name_form.rb +15 -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 +2 -0
- data/lib/relaton/render/iso690/style.rb +11 -1
- 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: 6e6e4911053aee3915882fcee48c182f8bf0d1ca2c879e7201bb0d19cfd48e4b
|
|
4
|
+
data.tar.gz: 60b845d08886130df02eaef46bfe5811996f208aaab13093fb660221f5f50799
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 855419eacf8dc6f71a4c9eaef6b23341328bee50a1a59b0c2138d62420b3295d59176a83d3cac5c52a0c2cb989558ebced170badaf8732f04449fb5a5047cc6d
|
|
7
|
+
data.tar.gz: 38ace39e42d57252a8eb994cc4ec4a82ea56a5bd6476025db679b6b4a42c6c676b77908d6d076f06442e30768bb406104e284daed8e85dd73dfbb8f7c66aa7fc
|
|
@@ -29,6 +29,14 @@ module Relaton
|
|
|
29
29
|
value&.content.to_s
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# Localizable values scoped to the render language: the variants
|
|
33
|
+
# declared in that language, or all of them when none matches
|
|
34
|
+
def titles_in_lang(values)
|
|
35
|
+
titles = Array(values)
|
|
36
|
+
in_lang = titles.select { |t| Array(t.language).include?(@i18n.lang) }
|
|
37
|
+
in_lang.empty? ? titles : in_lang
|
|
38
|
+
end
|
|
39
|
+
|
|
32
40
|
def contributors(role)
|
|
33
41
|
Array(@model.contributor).select { |c| has_role?(c, role) }
|
|
34
42
|
end
|
|
@@ -68,12 +76,20 @@ module Relaton
|
|
|
68
76
|
|
|
69
77
|
""
|
|
70
78
|
end.reject(&:empty?)
|
|
71
|
-
|
|
72
|
-
return
|
|
79
|
+
sep = @style.scheme.name_form.initials_separator.to_s
|
|
80
|
+
return reinitials(localized(person.name&.formatted_initials),
|
|
81
|
+
sep) if parts.empty?
|
|
82
|
+
return parts.map { |p| "#{p[0]}." }.join(sep) if initials?
|
|
73
83
|
|
|
74
84
|
parts.join(" ")
|
|
75
85
|
end
|
|
76
86
|
|
|
87
|
+
# Declared initials are a list in string form; rejoin them with
|
|
88
|
+
# the style's separator
|
|
89
|
+
def reinitials(raw, sep)
|
|
90
|
+
raw.split(/\s+/).reject(&:empty?).join(sep)
|
|
91
|
+
end
|
|
92
|
+
|
|
77
93
|
def initials?
|
|
78
94
|
@style.scheme.name_form.initials
|
|
79
95
|
end
|
|
@@ -40,7 +40,8 @@ module Relaton
|
|
|
40
40
|
def host_title_text
|
|
41
41
|
return localized(relation&.description) if host.nil?
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
titles_in_lang(host.title).map { |t| localized(t) }
|
|
44
|
+
.join(" ").strip
|
|
44
45
|
end
|
|
45
46
|
|
|
46
47
|
def host_title
|
|
@@ -68,7 +69,9 @@ module Relaton
|
|
|
68
69
|
|
|
69
70
|
surname = person_surname(person)
|
|
70
71
|
given = person_given(person)
|
|
71
|
-
if
|
|
72
|
+
if @style.scheme.name_form.inverted_all
|
|
73
|
+
@style.render_name(surname: surname, given: given)
|
|
74
|
+
elsif first
|
|
72
75
|
[surname, given].reject(&:empty?).join(", ")
|
|
73
76
|
else
|
|
74
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(" ")
|
|
@@ -108,9 +115,21 @@ module Relaton
|
|
|
108
115
|
end
|
|
109
116
|
|
|
110
117
|
def join(names)
|
|
118
|
+
oxford = @i18n.label("oxford_comma")
|
|
119
|
+
if serial_list? && names.size > 1 && !oxford.empty?
|
|
120
|
+
return "#{names[0..-2].join(', ')}#{oxford} " \
|
|
121
|
+
"#{@i18n.label('and')} #{names.last}"
|
|
122
|
+
end
|
|
123
|
+
|
|
111
124
|
join_names(names)
|
|
112
125
|
end
|
|
113
126
|
|
|
127
|
+
# Serial list style: every gap takes the serial form, even
|
|
128
|
+
# between two names
|
|
129
|
+
def serial_list?
|
|
130
|
+
@style.scheme.name_form.list_style == "serial"
|
|
131
|
+
end
|
|
132
|
+
|
|
114
133
|
def editors?
|
|
115
134
|
!creators.empty? && creators.all? { |c| has_role?(c, "editor") }
|
|
116
135
|
end
|
|
@@ -13,10 +13,17 @@ module Relaton
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def render
|
|
16
|
-
[
|
|
16
|
+
[place_text, publishers.join("; ")]
|
|
17
17
|
.reject(&:empty?).join(@i18n.punct_fetch("production_sep", ": "))
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
def place_text
|
|
21
|
+
return places.join("; ") unless places.empty?
|
|
22
|
+
|
|
23
|
+
label = @i18n.label("no_place")
|
|
24
|
+
label == "no_place" ? "" : label
|
|
25
|
+
end
|
|
26
|
+
|
|
20
27
|
private
|
|
21
28
|
|
|
22
29
|
def places
|
|
@@ -33,10 +33,14 @@ module Relaton
|
|
|
33
33
|
.include?(Kinds.kind_for(@model.type))
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
# A typed main title wins; an untyped title is main by
|
|
37
|
+
# default, but yields to a typed one
|
|
36
38
|
def main_title
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
titles = Array(@model.title)
|
|
40
|
+
mains = titles.select { |x| x.type == "main" }
|
|
41
|
+
mains = titles.select { |x| x.type.nil? } if mains.empty?
|
|
42
|
+
mains = titles if mains.empty?
|
|
43
|
+
localized(titles_in_lang(mains).first)
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
end
|
|
@@ -35,7 +35,18 @@ module Relaton
|
|
|
35
35
|
def element_field(slot)
|
|
36
36
|
element = Elements.build(slot, @model, style: @style, i18n: @i18n)
|
|
37
37
|
text = element.render.to_s
|
|
38
|
-
|
|
38
|
+
if element.present? && !text.empty?
|
|
39
|
+
return Template::Field[true, text]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
fallback = @style.fallback_for(item_kind, slot)
|
|
43
|
+
return Template::Field[true, fallback] if fallback
|
|
44
|
+
|
|
45
|
+
Template::Field[false, ""]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def item_kind
|
|
49
|
+
Kinds.kind_for(@model.type)
|
|
39
50
|
end
|
|
40
51
|
|
|
41
52
|
def name_fields
|
|
@@ -16,15 +16,19 @@ module Relaton
|
|
|
16
16
|
"MRN" => ->(content) { content },
|
|
17
17
|
}.freeze
|
|
18
18
|
|
|
19
|
+
# Flavor-registered kinds, consulted before the built-ins; the
|
|
20
|
+
# registry is process-wide by design
|
|
21
|
+
OVERRIDES = {}
|
|
22
|
+
|
|
19
23
|
class << self
|
|
20
24
|
def register(type, kind)
|
|
21
|
-
|
|
25
|
+
OVERRIDES[type] = kind
|
|
22
26
|
kind
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
def render(docidentifier)
|
|
26
30
|
content = docidentifier.content.to_s
|
|
27
|
-
kind = KINDS[docidentifier.type]
|
|
31
|
+
kind = OVERRIDES[docidentifier.type] || KINDS[docidentifier.type]
|
|
28
32
|
kind ? kind.call(content) : content
|
|
29
33
|
end
|
|
30
34
|
end
|
|
@@ -43,9 +43,10 @@ module Relaton
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def home_docid?(model)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
types = Array(@style.scheme.home_docid_type)
|
|
47
|
+
return false if types.empty?
|
|
48
|
+
|
|
49
|
+
Array(model.docidentifier).any? { |d| types.include?(d.type) }
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
# In-text form: SURNAME, year + disambiguator (name-and-date)
|
|
@@ -17,12 +17,27 @@ 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
|
+
# The inverted form's surname casing: the name-date convention
|
|
27
|
+
# upcases; small-cap styles keep the declared case
|
|
28
|
+
attribute :surname_upcase, :boolean, default: -> { true }
|
|
29
|
+
# Initials are a list; this separates them ("J. K." vs "J.K.")
|
|
30
|
+
attribute :initials_separator, :string, default: " "
|
|
20
31
|
|
|
21
32
|
key_value do
|
|
22
33
|
map "initials", to: :initials
|
|
23
34
|
map "givenNameFirst", to: :given_name_first
|
|
24
35
|
map "rolePlacement", to: :role_placement
|
|
25
36
|
map "completenameUpcase", to: :completename_upcase
|
|
37
|
+
map "invertedAll", to: :inverted_all
|
|
38
|
+
map "listStyle", to: :list_style
|
|
39
|
+
map "surnameUpcase", to: :surname_upcase
|
|
40
|
+
map "initialsSeparator", to: :initials_separator
|
|
26
41
|
end
|
|
27
42
|
end
|
|
28
43
|
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
|
|
@@ -12,6 +12,7 @@ module Relaton
|
|
|
12
12
|
attribute :series, :string
|
|
13
13
|
attribute :title, :string
|
|
14
14
|
attribute :home, :boolean
|
|
15
|
+
attribute :fallbacks, :hash, default: -> { {} }
|
|
15
16
|
|
|
16
17
|
key_value do
|
|
17
18
|
map "type", to: :type
|
|
@@ -19,6 +20,7 @@ module Relaton
|
|
|
19
20
|
map "series", to: :series
|
|
20
21
|
map "title", to: :title
|
|
21
22
|
map "home", to: :home
|
|
23
|
+
map "fallbacks", to: :fallbacks
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
end
|
|
@@ -52,6 +52,15 @@ module Relaton
|
|
|
52
52
|
candidates.first&.template || templates.reference
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
def type_template_for(type)
|
|
56
|
+
per_type.find { |t| t.type == type.to_s }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# The absent-slot replacement text declared for a type, when any
|
|
60
|
+
def fallback_for(type, slot)
|
|
61
|
+
type_template_for(type)&.fallbacks&.[](slot.to_s)
|
|
62
|
+
end
|
|
63
|
+
|
|
55
64
|
def title_form_for(type)
|
|
56
65
|
per_type.lazy.select { |t| t.type == type.to_s }
|
|
57
66
|
.find { |t| t.title && !t.title.empty? }&.title
|
|
@@ -60,8 +69,9 @@ module Relaton
|
|
|
60
69
|
# First-creator name form: the style's declared name template with
|
|
61
70
|
# the surname upcased, per the name-and-date convention.
|
|
62
71
|
def render_name(surname:, given:)
|
|
72
|
+
shown = scheme.name_form.surname_upcase ? surname.upcase : surname
|
|
63
73
|
Template.new(templates.name).evaluate(
|
|
64
|
-
"surname" => Template::Field[!
|
|
74
|
+
"surname" => Template::Field[!shown.empty?, shown],
|
|
65
75
|
"givennames" => Template::Field[!given.empty?, given],
|
|
66
76
|
)
|
|
67
77
|
end
|