relaton-render 0.1.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +64 -19
- data/lib/isodoc/i18n.rb +12 -3
- data/lib/isodoc-yaml/i18n-ar.yaml +29 -0
- data/lib/isodoc-yaml/i18n-de.yaml +27 -0
- data/lib/isodoc-yaml/i18n-en.yaml +14 -5
- data/lib/isodoc-yaml/i18n-es.yaml +28 -0
- data/lib/isodoc-yaml/i18n-fr.yaml +28 -0
- data/lib/isodoc-yaml/i18n-ru.yaml +13 -5
- data/lib/isodoc-yaml/i18n-zh-Hans.yaml +28 -0
- data/lib/relaton/render/fields/date.rb +45 -0
- data/lib/relaton/render/fields/fields.rb +212 -0
- data/lib/relaton/{config.yml → render/general/config.yml} +36 -31
- data/lib/relaton/{render.rb → render/general/render.rb} +52 -33
- data/lib/relaton/{render_classes.rb → render/general/render_classes.rb} +4 -1
- data/lib/relaton/render/parse/parse.rb +62 -0
- data/lib/relaton/render/parse/parse_contributors.rb +105 -0
- data/lib/relaton/render/parse/parse_extract.rb +188 -0
- data/lib/relaton/render/template/liquid.rb +15 -0
- data/lib/relaton/render/template/template.rb +183 -0
- data/lib/{utils → relaton/render/utils}/utils.rb +0 -0
- data/lib/relaton/{version.rb → render/version.rb} +1 -1
- data/lib/relaton-render.rb +5 -4
- data/relaton-render.gemspec +4 -1
- metadata +42 -12
- data/lib/parse/parse.rb +0 -54
- data/lib/parse/parse_contributors.rb +0 -96
- data/lib/parse/parse_extract.rb +0 -155
- data/lib/relaton/render_fields.rb +0 -151
- data/lib/template/template.rb +0 -152
@@ -0,0 +1,212 @@
|
|
1
|
+
require_relative "date"
|
2
|
+
|
3
|
+
module Relaton
|
4
|
+
module Render
|
5
|
+
class Fields
|
6
|
+
def initialize(options)
|
7
|
+
@r = options[:renderer]
|
8
|
+
end
|
9
|
+
|
10
|
+
def compound_fields_format(hash)
|
11
|
+
name_fields_format(hash)
|
12
|
+
role_fields_format(hash)
|
13
|
+
date_fields_format(hash)
|
14
|
+
edition_fields_format(hash)
|
15
|
+
misc_fields_format(hash)
|
16
|
+
end
|
17
|
+
|
18
|
+
def name_fields_format(hash)
|
19
|
+
hash[:place] = nameformat(hash[:place_raw]&.map do |x|
|
20
|
+
{ nonpersonal: x }
|
21
|
+
end)
|
22
|
+
[%i(creatornames creators), %i(host_creatornames host_creators),
|
23
|
+
%i(publisher publisher_raw), %i(distributor distributor_raw)]
|
24
|
+
.each do |k|
|
25
|
+
hash[k[0]] = nameformat(hash[k[1]])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def role_fields_format(hash)
|
30
|
+
hash[:role] = role_inflect(hash[:creators], hash[:role_raw])
|
31
|
+
hash[:host_role] =
|
32
|
+
role_inflect(hash[:host_creators], hash[:host_role_raw])
|
33
|
+
end
|
34
|
+
|
35
|
+
def edition_fields_format(hash)
|
36
|
+
hash[:edition] = editionformat(hash[:edition_raw])
|
37
|
+
hash[:draft] = draftformat(hash[:draft_raw], hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
def misc_fields_format(hash)
|
41
|
+
hash[:series] = seriesformat(hash)
|
42
|
+
hash[:medium] = mediumformat(hash[:medium_raw])
|
43
|
+
hash[:extent] = extentformat(hash[:extent_raw], hash)
|
44
|
+
hash[:size] = sizeformat(hash[:size_raw], hash)
|
45
|
+
hash[:uri] = uriformat(hash[:uri_raw])
|
46
|
+
hash
|
47
|
+
end
|
48
|
+
|
49
|
+
def date_fields_format(hash)
|
50
|
+
[%i(date date), %i(date_updated date_updated),
|
51
|
+
%i(date_accessed date_accessed)].each do |k|
|
52
|
+
hash[k[0]] = dateformat(hash[k[1]], hash)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# TODO is not being i18n-alised
|
57
|
+
def mediumformat(hash)
|
58
|
+
return nil if hash.nil?
|
59
|
+
|
60
|
+
%w(content genre form carrier size scale).each_with_object([]) do |i, m|
|
61
|
+
m << hash[i] if hash[i]
|
62
|
+
m
|
63
|
+
end.compact.join(", ")
|
64
|
+
end
|
65
|
+
|
66
|
+
def seriesformat(hash)
|
67
|
+
parts = %i(series_title series_abbr series_num series_partnumber
|
68
|
+
series_run series_formatted)
|
69
|
+
series_out = parts.each_with_object({}) do |i, m|
|
70
|
+
m[i] = hash[i]
|
71
|
+
end
|
72
|
+
t = hash[:type] == "article" ? @r.journaltemplate : @r.seriestemplate
|
73
|
+
t.render(series_out)
|
74
|
+
end
|
75
|
+
|
76
|
+
def nameformat(names)
|
77
|
+
return names if names.nil?
|
78
|
+
|
79
|
+
parts = %i(surname initials given middle nonpersonal)
|
80
|
+
names_out = names.each_with_object({}) do |n, m|
|
81
|
+
parts.each do |i|
|
82
|
+
m[i] ||= []
|
83
|
+
m[i] << n[i]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
@r.nametemplate.render(names_out)
|
87
|
+
end
|
88
|
+
|
89
|
+
def role_inflect(contribs, role)
|
90
|
+
return nil if role.nil? || contribs.size.zero? ||
|
91
|
+
%w(author publisher).include?(role)
|
92
|
+
|
93
|
+
number = contribs.size > 1 ? "pl" : "sg"
|
94
|
+
@r.i18n.get[role][number] || role
|
95
|
+
end
|
96
|
+
|
97
|
+
def editionformat(edn)
|
98
|
+
return edn unless /^\d+$/.match?(edn)
|
99
|
+
|
100
|
+
num = edn
|
101
|
+
@r.edition_number and num = edn.to_i.localize(tw_cldr_lang)
|
102
|
+
.to_rbnf_s(*@r.edition_number)
|
103
|
+
@r.edition.sub(/%/, num)
|
104
|
+
end
|
105
|
+
|
106
|
+
def draftformat(num, _hash)
|
107
|
+
return nil if num.nil?
|
108
|
+
return nil if num.is_a?(Hash) && num[:status].nil? && num[:iteration].nil?
|
109
|
+
|
110
|
+
@r.i18n.draft.sub(/%/, num)
|
111
|
+
end
|
112
|
+
|
113
|
+
def extentformat(extent, hash)
|
114
|
+
extent.map do |e|
|
115
|
+
e1 = e.transform_values { |v| v.is_a?(Hash) ? range(v) : v }
|
116
|
+
ret = e.each_with_object({}) do |(k, v), m|
|
117
|
+
extentformat1(k, v, m, e1)
|
118
|
+
m
|
119
|
+
end
|
120
|
+
@r.extenttemplate.render(ret.merge(type: hash[:type]))
|
121
|
+
end.join("; ")
|
122
|
+
end
|
123
|
+
|
124
|
+
def extentformat1(key, val, hash, norm_hash)
|
125
|
+
if %i(volume page).include?(key)
|
126
|
+
hash["#{key}_raw".to_sym] = norm_hash[key]
|
127
|
+
hash[key] = pagevolformat(norm_hash[key], val, key.to_s, false)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def range(hash)
|
132
|
+
if hash[:on] then hash[:on]
|
133
|
+
elsif hash.has_key?(:from) && hash[:from].nil? then nil
|
134
|
+
elsif hash[:from]
|
135
|
+
hash[:to] ? "#{hash[:from]}–#{hash[:to]}" : hash[:from]
|
136
|
+
else hash
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def sizeformat(size, hash)
|
141
|
+
return nil unless size
|
142
|
+
|
143
|
+
ret = size.transform_values { |v| @r.i18n.l10n(v.join(" + ")) }
|
144
|
+
.each_with_object({}) do |(k, v), m|
|
145
|
+
sizeformat1(k, v, m)
|
146
|
+
m
|
147
|
+
end
|
148
|
+
@r.sizetemplate.render(ret.merge(type: hash[:type]))
|
149
|
+
end
|
150
|
+
|
151
|
+
def sizeformat1(key, val, hash)
|
152
|
+
case key
|
153
|
+
when "volume"
|
154
|
+
hash[:volume_raw] = val
|
155
|
+
hash[:volume] = pagevolformat(val, nil, "volume", true)
|
156
|
+
when "page"
|
157
|
+
hash[:page_raw] = val
|
158
|
+
hash[:page] = pagevolformat(val, nil, "page", true)
|
159
|
+
when "data" then hash[:data] = val
|
160
|
+
when "duration" then hash[:duration] = val
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def pagevolformat(value, value_raw, type, is_size)
|
165
|
+
return nil if value.nil?
|
166
|
+
|
167
|
+
num = "pl"
|
168
|
+
if is_size
|
169
|
+
value == "1" and num = "sg"
|
170
|
+
else
|
171
|
+
value_raw[:to] or num = "sg"
|
172
|
+
end
|
173
|
+
@r.i18n.l10n(@r.i18n.get[is_size ? "size" : "extent"][type][num]
|
174
|
+
.sub(/%/, value))
|
175
|
+
end
|
176
|
+
|
177
|
+
def date_range(hash)
|
178
|
+
if hash[:from]
|
179
|
+
"#{hash[:from]}–#{hash[:to]}"
|
180
|
+
else range(hash)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def dateformat(date, _hash)
|
185
|
+
return nil if date.nil?
|
186
|
+
|
187
|
+
%i(from to on).each do |k|
|
188
|
+
date[k] = ::Relaton::Render::Date.new(date[k], renderer: @r).render
|
189
|
+
end
|
190
|
+
date_range(date)
|
191
|
+
end
|
192
|
+
|
193
|
+
def uriformat(uri)
|
194
|
+
return nil if uri.nil? || uri.empty?
|
195
|
+
|
196
|
+
"<link target='#{uri}'>#{uri}</link>"
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
200
|
+
|
201
|
+
def tw_cldr_lang
|
202
|
+
if @r.lang != "zh"
|
203
|
+
@r.lang.to_sym
|
204
|
+
elsif @r.script == "Hant"
|
205
|
+
:"zh-tw"
|
206
|
+
else
|
207
|
+
:"zh-cn"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -1,45 +1,49 @@
|
|
1
1
|
nametemplate:
|
2
|
-
one: "{{surname[0] | upcase }}, {{given[0]}} {{middle[0}}"
|
3
|
-
two: "{{surname[0] | upcase}}, {{given[0]}} {{middle[0]}} {{ labels['and'] }} {{given[1]}} {{middle[1]}} {{surname[1] | upcase}}"
|
4
|
-
more: "{{surname[0] | upcase}}, {{given[0]}} {{middle[0}} , {{given[1]}} {{middle[1]}} {{surname[1] | upcase}} {{ labels['and'] }} {{given[2]}} {{middle[2]}} {{surname[2] | upcase}}"
|
2
|
+
one: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] | upcase }} ,_{%if given[0]%}{{given[0]}} {{middle[0]}}{%else%}{{initials[0] | join: '. '}}.{%endif%}{% endif %}"
|
3
|
+
two: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] | upcase}} ,_{%if given[0]%}{{given[0]}} {{middle[0]}}{%else%}{{initials[0] | join: '. '}}.{%endif%}{% endif %} {{ labels['and'] }} {% if nonpersonal[1] %}{{ nonpersonal[1] }}{% else %}{%if given[1]%}{{given[1]}} {{middle[1]}}{%else%}{{initials[1] | join: '. '}}.{%endif%} {{surname[1] | upcase}}{% endif %}"
|
4
|
+
more: "{% 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 %} {{ labels['and'] }} {% if nonpersonal[2] %}{{ nonpersonal[2] }}{% else %}{%if given[2]%}{{given[2]}} {{middle[2]}}{%else%}{{initials[2] | join: '. '}}.{%endif%} {{surname[2] | upcase}}{% endif %}"
|
5
5
|
# disabled the following: they should be provided in inheriting calls
|
6
|
-
# etal: "{{surname[0] | upcase}}, {{given[0]}} {{middle[0]}}, {{given[1]}} {{middle[1]}} {{surname[1] | upcase}} <em>et al.</em>"
|
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
|
-
seriestemplate: "{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %} ({{series_run}}) {{series_num}}|({{series_partnumber}})"
|
8
|
+
seriestemplate: "{% if series_formatted %}{{ series_formatted }}{%else%}{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %} ({{series_run}}) {{series_num}}|({{series_partnumber}}){%endif%}"
|
9
9
|
journaltemplate: "<em>{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %}</em> ({{series_run}}) {{ labels['volume'] }}_{{series_num}} {{ labels['part'] }}_{{series_partnumber}}"
|
10
10
|
extenttemplate:
|
11
|
-
book: "{{ volume }}
|
11
|
+
book: "{{ volume }}, {{ page }}"
|
12
12
|
booklet: book
|
13
13
|
proceedings: book
|
14
14
|
journal: book
|
15
15
|
standard: book
|
16
16
|
techreport: book
|
17
17
|
inbook: "{{ volume }}: {{ page }}"
|
18
|
-
misc: "{{
|
19
|
-
|
18
|
+
misc: "{{ volume }}, {{ page }}, {{ duration }}"
|
19
|
+
sizetemplate:
|
20
|
+
dataset: "{{ data }}"
|
21
|
+
electronic resource: dataset
|
22
|
+
webresource: dataset
|
23
|
+
misc: "{{ volume }}, {{ page }}, {{ data }}, {{ duration }}"
|
20
24
|
language: en
|
21
25
|
script: Latn
|
22
26
|
template:
|
23
|
-
book: "{{ creatornames }} ({{role}}) . <em>{{ title }}</em> [{{medium}}] . {{ edition |
|
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}}."
|
24
28
|
# TODO: omitted: author ids, subsidiary titles, subsidiary creators, rights metadata, distributor, item attributes, relationships
|
25
29
|
booklet: book
|
26
30
|
manual: book
|
27
31
|
proceedings: book
|
28
|
-
inbook: "{{ creatornames }} ({{role}}) . {{ title }} . {{ labels['in'] | capitalize }}: {{ host_creatornames}} ({{ host_role}}) : <em>{{host_title}}</em> [{{medium}}] . {{ edition |
|
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}}]."
|
29
33
|
inproceedings: inbook
|
30
34
|
incollection: inbook
|
31
35
|
# TODO: omitted: author ids, additional info for component part, subsidiary titles of host resource, rights metadata, distributor, relationships
|
32
|
-
journal: "<em>{{ title}}</em> [{{medium}}] . {{ edition |
|
36
|
+
journal: "<em>{{ title}}</em> [{{medium}}] . {{ edition | capitalize_first }}. {{place}}: {{publisher}}. {{date}}. {{size}}. {{extent}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
33
37
|
# TODO subsidiary titles, rights metadata, item attributes, relationships
|
34
|
-
article: "{{ creatornames }} ({{role}}) . {{ title }}. {{ series }} [{{medium}}] . {{ edition |
|
38
|
+
article: "{{ creatornames }} ({{role}}) . {{ title }}. {{ series }} [{{medium}}] . {{ edition | capitalize_first }}. {{size}}. {{ extent }}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
35
39
|
# TODO: omitted: author ids, subsidiary titles, rights metadata, distributor, item attributes, relationships; newspapers
|
36
|
-
software: "{{ creatornames }} ({{ role}}) . <em>{{ title }}</em> . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize}}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ extent}}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
|
40
|
+
software: "{{ creatornames }} ({{ role}}) . <em>{{ title }}</em> . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize}}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{size}}. {{ extent}}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
|
37
41
|
# TODO: omitted: author ids, subsidiary titles, subsidiary creators, copyright, license, distributor, system requirements, relationships
|
38
42
|
electronic resource: software
|
39
|
-
standard: "{{ creatornames }} ({{ role}}) . <em>{{ title }}</em> . {{ labels['in'] | capitalize }}:_{{ series_title }}. {{ medium | capitalize }}. {{ edition |
|
43
|
+
standard: "{{ creatornames }} ({{ role}}) . <em>{{ title }}</em> . {{ labels['in'] | capitalize }}:_{{ series_title }}. {{ medium | capitalize }}. {{ edition | capitalize_first }}. {{place}}: {{publisher}}. {{date}}. {{size}}. {{ extent }}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
40
44
|
# TODO: omitted: author ids, subsidiary titles, rights metadata, distributor, persistent identifier, item attributes, relationships
|
41
45
|
techreport: standard
|
42
|
-
dataset: "{{ creatornames }} ({{ role }}) . <em>{{ title }}</em> . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize }}. {{ labels['in'] | capitalize }}:_{{series}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ extent}}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
|
46
|
+
dataset: "{{ creatornames }} ({{ role }}) . <em>{{ title }}</em> . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize }}. {{ labels['in'] | capitalize }}:_{{series}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ size }}. {{ extent}}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
|
43
47
|
# TODO: omitted: author ids, system requirements, host archive, copyright, license, data source, distributor, usage instructions, relationships, provenance
|
44
48
|
website: "{{ creatornames }} ({{ role }}) . <em>{{ title }}</em> . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize }}. {{ place }}: {{ publisher }}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
|
45
49
|
# TODO: omitted: author ids, page title, system requirements, subsidiary creator, rights metadata, distributor, persistent identifier, archive location, archive date and time, relationships
|
@@ -49,19 +53,20 @@ template:
|
|
49
53
|
# TODO: omitted: author ids, subsidiary titles, subsidiary creators, host archive, item attributes, relationships
|
50
54
|
presentation: unpublished
|
51
55
|
thesis: "{{ creatornames }} ({{ role }}) . <em>{{ title }}</em> . {{ medium | capitalize }}. {{ place }}: {{ publisher }}. {{ date }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. {{ standardidentifier | first }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
52
|
-
|
53
|
-
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
56
|
+
misc: "{{ creatornames }} ({{ role }}) . <em>{{ title }}</em> . {{ date }}."
|
57
|
+
# following are # unsupported types:
|
58
|
+
map: misc
|
59
|
+
audiovisual: misc
|
60
|
+
film: misc
|
61
|
+
video: misc
|
62
|
+
broadcast: misc
|
63
|
+
graphic_work: misc
|
64
|
+
music: misc
|
65
|
+
performance: misc
|
66
|
+
patent: misc
|
67
|
+
archival: misc
|
68
|
+
social_media: misc
|
69
|
+
alert: misc
|
70
|
+
message: misc
|
71
|
+
conversation: misc
|
72
|
+
internal: misc
|
@@ -1,44 +1,58 @@
|
|
1
1
|
require_relative "render_classes"
|
2
|
-
require_relative "render_fields"
|
3
2
|
require "yaml"
|
4
3
|
require "liquid"
|
5
|
-
|
6
|
-
require_relative "../
|
4
|
+
require "relaton_bib"
|
5
|
+
require_relative "../template/template"
|
6
|
+
require_relative "../../../isodoc/i18n"
|
7
7
|
|
8
8
|
module Relaton
|
9
9
|
module Render
|
10
10
|
class General
|
11
11
|
attr_reader :template, :journaltemplate, :seriestemplate, :nametemplate,
|
12
|
-
:extenttemplate, :
|
13
|
-
:date
|
12
|
+
:extenttemplate, :sizetemplate, :lang, :script, :i18n,
|
13
|
+
:edition, :edition_number, :date
|
14
14
|
|
15
15
|
def initialize(opt = {})
|
16
|
-
options =
|
17
|
-
|
18
|
-
|
19
|
-
@type = self.class.name.downcase.sub(/relaton::render::/, "")
|
16
|
+
options = read_config.merge(Utils::string_keys(opt))
|
17
|
+
@type = self.class.name.downcase.split("::").last
|
18
|
+
klass_initialize(options)
|
20
19
|
root_initalize(options)
|
21
20
|
render_initialize(options)
|
22
21
|
@parse ||= options["parse"]
|
23
22
|
@i18n ||= options["i18n"]
|
24
23
|
end
|
25
24
|
|
25
|
+
def read_config
|
26
|
+
YAML.load_file(File.join(File.dirname(__FILE__), "config.yml"))
|
27
|
+
end
|
28
|
+
|
29
|
+
def klass_initialize(_options)
|
30
|
+
@nametemplateklass = Relaton::Render::Template::Name
|
31
|
+
@seriestemplateklass = Relaton::Render::Template::Series
|
32
|
+
@extenttemplateklass = Relaton::Render::Template::Extent
|
33
|
+
@sizetemplateklass = Relaton::Render::Template::Size
|
34
|
+
@generaltemplateklass = Relaton::Render::Template::General
|
35
|
+
@fieldsklass = Relaton::Render::Fields
|
36
|
+
@parseklass = Relaton::Render::Parse
|
37
|
+
end
|
38
|
+
|
26
39
|
def root_initalize(opt)
|
27
40
|
i18n_initialize(opt)
|
28
|
-
@parse =
|
29
|
-
@nametemplate =
|
41
|
+
@parse = @parseklass.new(lang: @lang, script: @script)
|
42
|
+
@nametemplate = @nametemplateklass
|
30
43
|
.new(template: opt["nametemplate"], i18n: @i18n)
|
31
|
-
@seriestemplate =
|
44
|
+
@seriestemplate = @seriestemplateklass
|
32
45
|
.new(template: opt["seriestemplate"], i18n: @i18n)
|
33
|
-
@journaltemplate =
|
46
|
+
@journaltemplate = @seriestemplateklass
|
34
47
|
.new(template: opt["journaltemplate"], i18n: @i18n)
|
35
48
|
@extenttemplate = extentrenderers(opt)
|
49
|
+
@sizetemplate = sizerenderers(opt)
|
36
50
|
end
|
37
51
|
|
38
52
|
def i18n_initialize(opt)
|
39
53
|
@lang = opt["language"]
|
40
54
|
@script = opt["script"]
|
41
|
-
@i18n =
|
55
|
+
@i18n = i18n_klass(opt["language"], opt["script"])
|
42
56
|
@edition_number = opt["edition_number"] || @i18n.edition_number
|
43
57
|
@edition = opt["edition"] || @i18n.edition
|
44
58
|
@date = opt["date"] || @i18n.date
|
@@ -47,8 +61,8 @@ module Relaton
|
|
47
61
|
def render_initialize(opt)
|
48
62
|
case opt["template"]
|
49
63
|
when String
|
50
|
-
@template =
|
51
|
-
|
64
|
+
@template = @generaltemplateklass
|
65
|
+
.new(template: opt["template"], i18n: @i18n)
|
52
66
|
when Hash
|
53
67
|
@render = renderers(opt)
|
54
68
|
end
|
@@ -64,48 +78,53 @@ module Relaton
|
|
64
78
|
end
|
65
79
|
|
66
80
|
def extentrenderers(opt)
|
67
|
-
|
81
|
+
@extenttemplateklass
|
68
82
|
.new(template: template_hash_fill(opt["extenttemplate"]), i18n: @i18n)
|
69
83
|
end
|
70
84
|
|
85
|
+
def sizerenderers(opt)
|
86
|
+
@sizetemplateklass
|
87
|
+
.new(template: template_hash_fill(opt["sizetemplate"]), i18n: @i18n)
|
88
|
+
end
|
89
|
+
|
71
90
|
def default_template
|
72
91
|
"{{creatornames}}. {{title}}. {{date}}."
|
73
92
|
end
|
74
93
|
|
75
|
-
def
|
76
|
-
::IsoDoc::
|
94
|
+
def i18n_klass(lang = "en", script = "Latn")
|
95
|
+
::IsoDoc::RelatonRenderI18n.new(lang, script)
|
77
96
|
end
|
78
97
|
|
79
98
|
def render(bib, embedded: false)
|
80
|
-
|
81
|
-
|
82
|
-
|
99
|
+
if bib.is_a?(String) && Nokogiri::XML(bib).errors.empty?
|
100
|
+
bib = RelatonBib::XMLParser.from_xml bib
|
101
|
+
end
|
102
|
+
parse(bib, embedded: embedded)
|
83
103
|
end
|
84
104
|
|
85
105
|
def parse(doc, embedded: false)
|
86
|
-
f = doc.
|
106
|
+
f = doc.formattedref and
|
87
107
|
return embedded ? f.children.to_xml : doc.to_xml
|
88
108
|
|
89
|
-
ret = parse1(doc)
|
109
|
+
ret = parse1(doc) or return nil
|
90
110
|
embedded and return ret
|
91
111
|
"<formattedref>#{ret}</formattedref>"
|
92
112
|
end
|
93
113
|
|
94
|
-
def renderer(
|
95
|
-
|
96
|
-
raise "No renderer defined for #{
|
97
|
-
|
98
|
-
|
99
|
-
raise "No renderer defined for #{doc['type']}"
|
100
|
-
end
|
114
|
+
def renderer(type)
|
115
|
+
ret = @template || @render[type]&.template or
|
116
|
+
raise "No renderer defined for #{type}"
|
117
|
+
@type == "general" || @type == type or
|
118
|
+
raise "No renderer defined for #{type}"
|
101
119
|
|
102
120
|
ret
|
103
121
|
end
|
104
122
|
|
105
123
|
def parse1(doc)
|
106
|
-
r = renderer(doc)
|
124
|
+
r = renderer(doc.type || "misc")
|
107
125
|
data = @parse.extract(doc)
|
108
|
-
data_liquid =
|
126
|
+
data_liquid = @fieldsklass.new(renderer: self)
|
127
|
+
.compound_fields_format(data)
|
109
128
|
@i18n.l10n(r.render(data_liquid))
|
110
129
|
end
|
111
130
|
|
@@ -5,7 +5,7 @@ module Relaton
|
|
5
5
|
standard unpublished map electronic_resource audiovisual film video
|
6
6
|
broadcast software graphic_work music patent inbook incollection
|
7
7
|
inproceedings journal website webresource dataset archival social_media
|
8
|
-
alert message conversation misc).freeze
|
8
|
+
alert message conversation misc internal).freeze
|
9
9
|
|
10
10
|
class General
|
11
11
|
singleton_class.send(:attr_reader, :descendants)
|
@@ -122,5 +122,8 @@ module Relaton
|
|
122
122
|
|
123
123
|
class Misc < General
|
124
124
|
end
|
125
|
+
|
126
|
+
class Internal < General
|
127
|
+
end
|
125
128
|
end
|
126
129
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require "twitter_cldr"
|
3
|
+
require_relative "parse_contributors"
|
4
|
+
require_relative "parse_extract"
|
5
|
+
|
6
|
+
module Relaton
|
7
|
+
module Render
|
8
|
+
class Parse
|
9
|
+
def initialize(options)
|
10
|
+
@lang = options[:lang] || "en"
|
11
|
+
@script = options[:script] || "Latn"
|
12
|
+
end
|
13
|
+
|
14
|
+
def extract(doc)
|
15
|
+
host = host(doc)
|
16
|
+
simple_xml2hash(doc).merge(simple_or_host_xml2hash(doc, host))
|
17
|
+
.merge(host_xml2hash(host))
|
18
|
+
.merge(series_xml2hash(doc, host))
|
19
|
+
end
|
20
|
+
|
21
|
+
def simple_xml2hash(doc)
|
22
|
+
creators, role = creatornames(doc)
|
23
|
+
{ type: type(doc), title: title(doc), extent_raw: extent(doc),
|
24
|
+
size_raw: size(doc),
|
25
|
+
standardidentifier: standardidentifier(doc), uri_raw: uri(doc),
|
26
|
+
status: status(doc), creators: creators, role_raw: role }
|
27
|
+
end
|
28
|
+
|
29
|
+
def simple_or_host_xml2hash(doc, host)
|
30
|
+
{ edition_raw: edition(doc, host), medium_raw: medium(doc, host),
|
31
|
+
place_raw: place(doc, host), publisher_raw: publisher(doc, host),
|
32
|
+
distributor_raw: distributor(doc, host), draft_raw: draft(doc, host),
|
33
|
+
access_location: access_location(doc, host),
|
34
|
+
date: date(doc, host), date_updated: date_updated(doc, host),
|
35
|
+
date_accessed: date_accessed(doc, host) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def host_xml2hash(host)
|
39
|
+
creators, role = creatornames(host)
|
40
|
+
{ host_creators: creators, host_role_raw: role,
|
41
|
+
host_title: title(host) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def series_xml2hash(doc, host)
|
45
|
+
series = series(doc)
|
46
|
+
host and series ||= series(host)
|
47
|
+
series_xml2hash1(series, doc)
|
48
|
+
end
|
49
|
+
|
50
|
+
def series_xml2hash1(series, doc)
|
51
|
+
return {} unless series
|
52
|
+
|
53
|
+
{ series_formatted: series_formatted(series, doc),
|
54
|
+
series_title: series_title(series, doc),
|
55
|
+
series_abbr: series_abbr(series, doc),
|
56
|
+
series_run: series_run(series, doc),
|
57
|
+
series_num: series_num(series, doc),
|
58
|
+
series_partnumber: series_partnumber(series, doc) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Relaton
|
2
|
+
module Render
|
3
|
+
class Parse
|
4
|
+
def extract_orgname(org)
|
5
|
+
org.name&.first&.content
|
6
|
+
end
|
7
|
+
|
8
|
+
def extract_personname(person)
|
9
|
+
surname = person.name.surname || person.name.completename
|
10
|
+
given, middle, initials = given_and_middle_name(person)
|
11
|
+
{ surname: surname.content,
|
12
|
+
given: given,
|
13
|
+
middle: middle,
|
14
|
+
initials: initials }
|
15
|
+
end
|
16
|
+
|
17
|
+
def given_and_middle_name(person)
|
18
|
+
forenames = person.name.forename.map(&:content)
|
19
|
+
initials = person.name.initial.map(&:content)
|
20
|
+
.map { |x| x.sub(/\.$/, "") }
|
21
|
+
forenames.empty? and initials.empty? and return [nil, nil, nil]
|
22
|
+
initials.empty? and initials = forenames.map { |x| x[0] }
|
23
|
+
[forenames.first, forenames[1..-1], initials]
|
24
|
+
end
|
25
|
+
|
26
|
+
def extractname(contributor)
|
27
|
+
org = contributor.entity if contributor.entity
|
28
|
+
.is_a?(RelatonBib::Organization)
|
29
|
+
person = contributor.entity if contributor.entity
|
30
|
+
.is_a?(RelatonBib::Person)
|
31
|
+
return { nonpersonal: extract_orgname(org) } if org
|
32
|
+
return extract_personname(person) if person
|
33
|
+
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def contributor_role(contributors)
|
38
|
+
return nil unless contributors.length.positive?
|
39
|
+
|
40
|
+
desc = contributors[0].role.first.description.join("\n")
|
41
|
+
type = contributors[0].role.first.type
|
42
|
+
desc.empty? ? type : desc
|
43
|
+
end
|
44
|
+
|
45
|
+
def creatornames(doc)
|
46
|
+
cr = creatornames1(doc)
|
47
|
+
cr.empty? and return [nil, nil]
|
48
|
+
[cr.map { |x| extractname(x) }, contributor_role(cr)]
|
49
|
+
end
|
50
|
+
|
51
|
+
def creatornames1(doc)
|
52
|
+
cr = []
|
53
|
+
return [] if doc.nil?
|
54
|
+
|
55
|
+
%w(author performer adapter translator editor publisher distributor)
|
56
|
+
.each do |r|
|
57
|
+
add = pick_contributor(doc, r)
|
58
|
+
next if add.nil?
|
59
|
+
|
60
|
+
cr = add and break
|
61
|
+
end
|
62
|
+
cr.nil? and cr = doc.contributor
|
63
|
+
cr
|
64
|
+
end
|
65
|
+
|
66
|
+
def datepick(date)
|
67
|
+
return nil if date.nil?
|
68
|
+
|
69
|
+
on = date.on
|
70
|
+
from = date.from
|
71
|
+
to = date.to
|
72
|
+
return { on: on } if on
|
73
|
+
return { from: from, to: to } if from
|
74
|
+
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def date1(date)
|
79
|
+
%w(published issued circulated).each do |t|
|
80
|
+
ret = date.detect { |x| x.type == t } and
|
81
|
+
return ret
|
82
|
+
end
|
83
|
+
date.first
|
84
|
+
end
|
85
|
+
|
86
|
+
def date(doc, host)
|
87
|
+
ret = date1(doc.date)
|
88
|
+
host and ret ||= date1(host.date)
|
89
|
+
datepick(ret)
|
90
|
+
end
|
91
|
+
|
92
|
+
def date_updated(doc, host)
|
93
|
+
ret = doc.date.detect { |x| x.type == "updated" }
|
94
|
+
host and ret ||= host.date.detect { |x| x.type == "updated" }
|
95
|
+
datepick(ret)
|
96
|
+
end
|
97
|
+
|
98
|
+
def date_accessed(doc, host)
|
99
|
+
ret = doc.date.detect { |x| x.type == "accessed" }
|
100
|
+
host and ret ||= host.date.detect { |x| x.type == "accessed" }
|
101
|
+
datepick(ret)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|