relaton-render 3.0.0.pre.alpha.17 → 3.0.0.pre.alpha.19
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 +34 -5
- data/lib/relaton/render/iso690/elements/creator.rb +28 -5
- data/lib/relaton/render/iso690/elements/series.rb +1 -1
- data/lib/relaton/render/iso690/elements/title.rb +8 -2
- data/lib/relaton/render/iso690/renderer.rb +17 -0
- data/lib/relaton/render/iso690/style/name_form.rb +9 -0
- data/lib/relaton/render/iso690/template.rb +15 -5
- 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: 14efa687d6e0316dd88f104203593084e6eefc7e16f7d7f42729f2c4c8e79ffb
|
|
4
|
+
data.tar.gz: ef2d1156dba8ad76bec04286e4748d05940692bb74ca5d7b2eb1a368425caa47
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eed19567e724a4103caca36f279df1dd559e7b9f1b495e51ee082c35b06b39b2440de8603815f443a9f29f36a962c59237814bdfa627e6f4812b9a4132268223
|
|
7
|
+
data.tar.gz: b67866542a100599e55a2107889b2a5a5f994113a62e40dde8a32e2e7da5fbc5f4cc38e03c55a3edb16bb1f3b934587490b9f21551aaaf708291da5435f347b9
|
|
@@ -32,9 +32,24 @@ module Relaton
|
|
|
32
32
|
# A flavor names its own CitationStyle instance (name or YAML path)
|
|
33
33
|
options[:style] and renderer_opts[:style] = options[:style]
|
|
34
34
|
@renderer = Iso690::Renderer.new(**renderer_opts)
|
|
35
|
+
@renderer_opts = renderer_opts
|
|
36
|
+
@renderers_by_lang = {}
|
|
35
37
|
warn_general_config if options[:config]
|
|
36
38
|
end
|
|
37
39
|
|
|
40
|
+
# A collection's items may each declare their own language; the
|
|
41
|
+
# renderer localizes by language, so a reference renders in its
|
|
42
|
+
# own language within a document of another (the 1.x plateau
|
|
43
|
+
# per-reference behaviour)
|
|
44
|
+
def renderer_for(lang)
|
|
45
|
+
return @renderer if lang.nil? || lang == @lang
|
|
46
|
+
|
|
47
|
+
@renderers_by_lang[lang] ||= Iso690::Renderer.new(
|
|
48
|
+
**@renderer_opts.merge(lang: lang,
|
|
49
|
+
script: %w(ja ko zh).include?(lang) ? nil : "Latn")
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
38
53
|
def render(model, embedded: false, **opts)
|
|
39
54
|
model = to_model(model)
|
|
40
55
|
text =
|
|
@@ -57,15 +72,20 @@ module Relaton
|
|
|
57
72
|
items = facade_bibitems(bib) or return nil
|
|
58
73
|
disambiguators = date_disambiguators(items)
|
|
59
74
|
items.each_with_object({}).with_index do |(item, m), i|
|
|
75
|
+
renderer = renderer_for(Array(item.language).first)
|
|
60
76
|
ref = begin
|
|
61
|
-
|
|
77
|
+
renderer.render(item, disambiguator: disambiguators[item.id])
|
|
62
78
|
rescue ::Relaton::Render::Unrenderable
|
|
63
79
|
next
|
|
64
80
|
end
|
|
65
81
|
m[item.id] = {
|
|
66
82
|
id: item.id, ord: i,
|
|
83
|
+
author: renderer.in_text_author(item),
|
|
67
84
|
formattedref: terminate_reference(ref, item),
|
|
68
|
-
citation: citation_renderings(item, ref
|
|
85
|
+
citation: citation_renderings(item, ref, renderer,
|
|
86
|
+
type: type,
|
|
87
|
+
disambiguator:
|
|
88
|
+
disambiguators[item.id]),
|
|
69
89
|
}
|
|
70
90
|
end
|
|
71
91
|
end
|
|
@@ -116,10 +136,14 @@ module Relaton
|
|
|
116
136
|
"#{ref}."
|
|
117
137
|
end
|
|
118
138
|
|
|
119
|
-
|
|
120
|
-
|
|
139
|
+
# The style-keyed capsule ("citation" => { author_date: "..." })
|
|
140
|
+
# is what isodoc's styled erefs consume (their style attribute
|
|
141
|
+
# names the key)
|
|
142
|
+
def citation_renderings(item, ref, renderer, type: "author-date",
|
|
143
|
+
disambiguator: nil)
|
|
144
|
+
short = renderer.citation(item)
|
|
121
145
|
short = if short.empty?
|
|
122
|
-
|
|
146
|
+
renderer.render_short(item, FIRST_DELIM)
|
|
123
147
|
else
|
|
124
148
|
short
|
|
125
149
|
end
|
|
@@ -128,6 +152,11 @@ module Relaton
|
|
|
128
152
|
full: ref,
|
|
129
153
|
default: item.docidentifier.first&.content.to_s,
|
|
130
154
|
short: short,
|
|
155
|
+
author_date: renderer.author_date_citation(
|
|
156
|
+
item, disambiguator: disambiguator,
|
|
157
|
+
),
|
|
158
|
+
author: renderer.in_text_author(item),
|
|
159
|
+
title: renderer.title_citation(item),
|
|
131
160
|
}
|
|
132
161
|
end
|
|
133
162
|
|
|
@@ -73,14 +73,37 @@ module Relaton
|
|
|
73
73
|
# at the style's et-al threshold the cite truncates
|
|
74
74
|
# ("Aluffi <em>et al.</em>")
|
|
75
75
|
def in_text
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
surname = name_form.surname_upcase ? raw.upcase : raw
|
|
80
|
-
name = completename(person) || surname || ""
|
|
76
|
+
return in_text_etal if in_text_etal?
|
|
77
|
+
|
|
78
|
+
name = creators.first ? in_text_name(creators.first) : ""
|
|
81
79
|
etal? ? "#{name} <em>et al.</em>" : name
|
|
82
80
|
end
|
|
83
81
|
|
|
82
|
+
# The in-text cite truncates at its own threshold: at
|
|
83
|
+
# inTextEtalCount creators it shows the first
|
|
84
|
+
# inTextEtalDisplay surnames ("Aluffi <em>et al.</em>")
|
|
85
|
+
def in_text_etal
|
|
86
|
+
names = creators.first(name_form.in_text_etal_display)
|
|
87
|
+
.map { |c| in_text_name(c) }
|
|
88
|
+
"#{join(names)} <em>et al.</em>"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# The in-text cite names by surname alone (the 1.x
|
|
92
|
+
# authorcitetemplate), never by initials
|
|
93
|
+
def in_text_name(contributor)
|
|
94
|
+
person = contributor.person or return org_name(contributor)
|
|
95
|
+
complete = completename(person)
|
|
96
|
+
return complete unless complete.nil?
|
|
97
|
+
|
|
98
|
+
raw = surname(person).to_s
|
|
99
|
+
name_form.surname_upcase ? raw.upcase : raw
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def in_text_etal?
|
|
103
|
+
count = name_form.in_text_etal_count
|
|
104
|
+
count.positive? && creators.size >= count
|
|
105
|
+
end
|
|
106
|
+
|
|
84
107
|
def etal?
|
|
85
108
|
count = name_form.etal_count
|
|
86
109
|
count.positive? && creators.size >= count
|
|
@@ -52,7 +52,7 @@ module Relaton
|
|
|
52
52
|
# back to the style-wide form
|
|
53
53
|
def series_form
|
|
54
54
|
variant = @style.per_type
|
|
55
|
-
.find { |t| t.type ==
|
|
55
|
+
.find { |t| t.type == @style.kind_for(@model.type) }
|
|
56
56
|
variant&.series || @style.templates.series
|
|
57
57
|
end
|
|
58
58
|
end
|
|
@@ -11,11 +11,17 @@ module Relaton
|
|
|
11
11
|
!main_title.empty?
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
# The citation capsule's plain title (the 1.x citetemplate's
|
|
15
|
+
# "{{ title }}"): the same resolution, no style markers
|
|
16
|
+
def plain
|
|
17
|
+
main_title
|
|
18
|
+
end
|
|
19
|
+
|
|
14
20
|
def render
|
|
15
21
|
text = main_title
|
|
16
22
|
return text if analytic? && @short
|
|
17
23
|
if !@short &&
|
|
18
|
-
(form = @style.title_form_for(
|
|
24
|
+
(form = @style.title_form_for(@style.kind_for(@model.type)))
|
|
19
25
|
# the kind's own form carries the whole emphasis
|
|
20
26
|
return ::Relaton::Render::Iso690::Template.new(form)
|
|
21
27
|
.evaluate("title" => Template::Field[!text.empty?, text])
|
|
@@ -31,7 +37,7 @@ module Relaton
|
|
|
31
37
|
# serial carries the emphasis
|
|
32
38
|
def analytic?
|
|
33
39
|
%w[component_part serial_part]
|
|
34
|
-
.include?(
|
|
40
|
+
.include?(@style.kind_for(@model.type))
|
|
35
41
|
end
|
|
36
42
|
|
|
37
43
|
# A typed main title wins; an untyped title is main by
|
|
@@ -82,6 +82,23 @@ module Relaton
|
|
|
82
82
|
elements: @elements).in_text
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
+
# The author-date in-text capsule ("Aluffi <em>et al.</em>
|
|
86
|
+
# 2022a"): the in-text creator and the disambiguated date
|
|
87
|
+
def author_date_citation(model, disambiguator: nil)
|
|
88
|
+
f = Fields.new(model, style: @style, i18n: @i18n,
|
|
89
|
+
disambiguator: disambiguator,
|
|
90
|
+
elements: @elements).to_h
|
|
91
|
+
[in_text_author(model), f["disambiguateddate"].text]
|
|
92
|
+
.reject(&:empty?).join(" ")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# The title citation ("{{ title }}" in the 1.x citetemplate):
|
|
96
|
+
# the title element's plain form, no style markers
|
|
97
|
+
def title_citation(model)
|
|
98
|
+
Elements.build(:title, model, style: @style, i18n: @i18n,
|
|
99
|
+
elements: @elements).plain
|
|
100
|
+
end
|
|
101
|
+
|
|
85
102
|
# The in-text author key (the principal creator's surname, as
|
|
86
103
|
# the citation renders it): the batch disambiguation groups by
|
|
87
104
|
# it
|
|
@@ -46,6 +46,13 @@ module Relaton
|
|
|
46
46
|
# first etalDisplay names with "et al." (0 disables)
|
|
47
47
|
attribute :etal_count, :integer, default: 0
|
|
48
48
|
attribute :etal_display, :integer, default: 0
|
|
49
|
+
# The in-text cite truncates separately from the creator
|
|
50
|
+
# list: at this many creators it shows the first
|
|
51
|
+
# inTextEtalDisplay names with "et al." (0 disables; IEEE
|
|
52
|
+
# cites 3+ as "Aluffi et al." while listing 6 in the
|
|
53
|
+
# bibliography)
|
|
54
|
+
attribute :in_text_etal_count, :integer, default: 0
|
|
55
|
+
attribute :in_text_etal_display, :integer, default: 1
|
|
49
56
|
# Editor lists carry the role marker ("(Eds.)")
|
|
50
57
|
attribute :editors_marked, :boolean, default: -> { true }
|
|
51
58
|
|
|
@@ -65,6 +72,8 @@ module Relaton
|
|
|
65
72
|
map "subsequentSurnameUpcase", to: :subsequent_surname_upcase
|
|
66
73
|
map "etalCount", to: :etal_count
|
|
67
74
|
map "etalDisplay", to: :etal_display
|
|
75
|
+
map "inTextEtalCount", to: :in_text_etal_count
|
|
76
|
+
map "inTextEtalDisplay", to: :in_text_etal_display
|
|
68
77
|
map "editorsMarked", to: :editors_marked
|
|
69
78
|
end
|
|
70
79
|
end
|
|
@@ -102,15 +102,25 @@ module Relaton
|
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
-
# A literal
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
105
|
+
# A literal is the trailing separator of the element that
|
|
106
|
+
# precedes it: it renders when that element renders and a
|
|
107
|
+
# later element renders, and it is the FIRST literal of its
|
|
108
|
+
# gap (the 1.x segment join — absent elements between two
|
|
109
|
+
# present ones leave the single separator that follows the
|
|
110
|
+
# earlier present element; an absent slot directly before a
|
|
111
|
+
# present one, as "{{date}}{{disambiguator}}, {{access}}",
|
|
112
|
+
# does not swallow it). A leading literal (no slot precedes
|
|
113
|
+
# it) attaches to the first slot, emitting only when that
|
|
114
|
+
# slot is present.
|
|
109
115
|
def bridged?(index, present)
|
|
110
116
|
first_slot = @chunks.index { |(kind, _)| kind == :slot }
|
|
111
117
|
return present.include?(first_slot) if index < first_slot
|
|
112
118
|
|
|
113
|
-
present.
|
|
119
|
+
left = present.select { |i| i < index }.max
|
|
120
|
+
left && present.any? { |i| i > index } &&
|
|
121
|
+
!@chunks[(left + 1)...index].any? do |(kind, _)|
|
|
122
|
+
kind == :text
|
|
123
|
+
end
|
|
114
124
|
end
|
|
115
125
|
|
|
116
126
|
# A template's paired literal ("({{production}})") closes even
|