relaton-render 0.1.0
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 +7 -0
- data/.github/workflows/rake.yml +15 -0
- data/.hound.yml +5 -0
- data/.rubocop.yml +10 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +25 -0
- data/README.adoc +241 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/rspec +18 -0
- data/bin/setup +8 -0
- data/lib/isodoc/i18n.rb +24 -0
- data/lib/isodoc-yaml/i18n-ar.yaml +2 -0
- data/lib/isodoc-yaml/i18n-de.yaml +2 -0
- data/lib/isodoc-yaml/i18n-en.yaml +22 -0
- data/lib/isodoc-yaml/i18n-es.yaml +2 -0
- data/lib/isodoc-yaml/i18n-fr.yaml +2 -0
- data/lib/isodoc-yaml/i18n-ru.yaml +23 -0
- data/lib/isodoc-yaml/i18n-zh-Hans.yaml +2 -0
- data/lib/parse/parse.rb +54 -0
- data/lib/parse/parse_contributors.rb +96 -0
- data/lib/parse/parse_extract.rb +155 -0
- data/lib/relaton/config.yml +67 -0
- data/lib/relaton/render.rb +123 -0
- data/lib/relaton/render_classes.rb +126 -0
- data/lib/relaton/render_fields.rb +151 -0
- data/lib/relaton/version.rb +5 -0
- data/lib/relaton-render.rb +6 -0
- data/lib/template/template.rb +152 -0
- data/lib/utils/utils.rb +27 -0
- data/relaton-render.gemspec +35 -0
- metadata +213 -0
@@ -0,0 +1,155 @@
|
|
1
|
+
class Iso690Parse
|
2
|
+
def title(doc)
|
3
|
+
doc&.at("./title")&.text
|
4
|
+
end
|
5
|
+
|
6
|
+
def medium(doc, host)
|
7
|
+
x = doc.at("./medium") || host&.at("./medium") or return nil
|
8
|
+
|
9
|
+
%w(content genre form carrier size scale).each_with_object([]) do |i, m|
|
10
|
+
m << x.at("./#{i}")&.text
|
11
|
+
end.compact.join(", ")
|
12
|
+
end
|
13
|
+
|
14
|
+
def blank?(text)
|
15
|
+
text.nil? || text.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
def edition(doc, host)
|
19
|
+
x = doc.at("./edition") || host&.at("./edition") or return nil
|
20
|
+
|
21
|
+
x.text
|
22
|
+
end
|
23
|
+
|
24
|
+
def place(doc, host)
|
25
|
+
x = doc.at("./place") || host&.at("./place") or return nil
|
26
|
+
|
27
|
+
x.text
|
28
|
+
end
|
29
|
+
|
30
|
+
def publisher(doc, host)
|
31
|
+
x = doc.at("./contributor[role/@type = 'publisher']/organization/name") ||
|
32
|
+
host&.at("./contributor[role/@type = 'publisher']/organization/name") or
|
33
|
+
return nil
|
34
|
+
x.text
|
35
|
+
end
|
36
|
+
|
37
|
+
def distributor(doc, host)
|
38
|
+
x = doc.at("./contributor[role/@type = 'distributor']/organization/name") ||
|
39
|
+
host&.at("./contributor[role/@type = 'distributor']/organization/name") or
|
40
|
+
return nil
|
41
|
+
x.text
|
42
|
+
end
|
43
|
+
|
44
|
+
def series_title(doc)
|
45
|
+
doc&.at("./title")&.text || doc&.at("./formattedref")&.text
|
46
|
+
end
|
47
|
+
|
48
|
+
def series_abbr(doc)
|
49
|
+
doc&.at("./abbreviation")&.text
|
50
|
+
end
|
51
|
+
|
52
|
+
def series_num(doc)
|
53
|
+
doc&.at("./number")&.text
|
54
|
+
end
|
55
|
+
|
56
|
+
def series_partnumber(doc)
|
57
|
+
doc&.at("./partnumber")&.text
|
58
|
+
end
|
59
|
+
|
60
|
+
def series_run(doc)
|
61
|
+
doc&.at("./run")&.text
|
62
|
+
end
|
63
|
+
|
64
|
+
def standardidentifier(doc)
|
65
|
+
doc.xpath("./docidentifier").each_with_object([]) do |id, ret|
|
66
|
+
ret << id.text unless %w(metanorma metanorma-ordinal).include? id["type"]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def uri(doc)
|
71
|
+
uri = doc.at("./uri[@type = 'doi']") || doc.at("./uri[@type = 'uri']") ||
|
72
|
+
doc.at("./uri[@type = 'src']") || doc.at("./uri")
|
73
|
+
uri&.text
|
74
|
+
end
|
75
|
+
|
76
|
+
def access_location(doc, host)
|
77
|
+
x = doc.at("./accessLocation") || host&.at("./accessLocation") or
|
78
|
+
return nil
|
79
|
+
x.text
|
80
|
+
end
|
81
|
+
|
82
|
+
def included(type)
|
83
|
+
["article", "inbook", "incollection", "inproceedings"].include? type
|
84
|
+
end
|
85
|
+
|
86
|
+
def wrap(text, startdelim = " ", enddelim = ".")
|
87
|
+
return "" if blank?(text)
|
88
|
+
|
89
|
+
"#{startdelim}#{text}#{enddelim}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def type(doc)
|
93
|
+
type = doc.at("./@type") and return type&.text
|
94
|
+
doc.at("./relation[@type = 'includedIn']") and return "inbook"
|
95
|
+
"book"
|
96
|
+
end
|
97
|
+
|
98
|
+
def extent1(localities)
|
99
|
+
localities.each_with_object({}) do |l, ret|
|
100
|
+
ret[(l["type"] || "page").to_sym] = {
|
101
|
+
from: l.at("./referenceFrom")&.text,
|
102
|
+
to: l.at("./referenceTo")&.text,
|
103
|
+
}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def extent0(elem, acc, ret1)
|
108
|
+
case elem.name
|
109
|
+
when "localityStack"
|
110
|
+
acc << ret1
|
111
|
+
ret1 = {}
|
112
|
+
acc << extent1(elem.elements)
|
113
|
+
when "locality" then ret1.merge!(extent1([elem]))
|
114
|
+
when "referenceFrom" then ret1.merge!(extent1([elem.parent]))
|
115
|
+
end
|
116
|
+
[acc, ret1]
|
117
|
+
end
|
118
|
+
|
119
|
+
def extent(doc)
|
120
|
+
ret1 = {}
|
121
|
+
ret = doc.xpath("./extent").each_with_object([]) do |e, acc|
|
122
|
+
e.elements.each do |l|
|
123
|
+
acc, ret1 = extent0(l, acc, ret1)
|
124
|
+
break if l.name == "referenceFrom"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
ret << ret1
|
128
|
+
ret.reject(&:empty?)
|
129
|
+
end
|
130
|
+
|
131
|
+
def draft(doc)
|
132
|
+
dr = doc&.at("./status/stage")&.text
|
133
|
+
|
134
|
+
iterord = iter_ordinal(doc)
|
135
|
+
status = status_print(dr)
|
136
|
+
status = "#{iterord} #{status}" if iterord
|
137
|
+
status
|
138
|
+
end
|
139
|
+
|
140
|
+
def iter_ordinal(isoxml)
|
141
|
+
return nil unless isoxml.at(("./status/iteration"))
|
142
|
+
|
143
|
+
iter = isoxml.at(("./status/iteration"))&.text || "1"
|
144
|
+
iter.to_i.localize.to_rbnf_s("SpelloutRules",
|
145
|
+
"spellout-ordinal").capitalize
|
146
|
+
end
|
147
|
+
|
148
|
+
def status_print(status)
|
149
|
+
status
|
150
|
+
end
|
151
|
+
|
152
|
+
def status(doc)
|
153
|
+
doc&.at("./status/stage")&.text
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,67 @@
|
|
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}}"
|
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>"
|
7
|
+
# etal_count: 5
|
8
|
+
seriestemplate: "{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %} ({{series_run}}) {{series_num}}|({{series_partnumber}})"
|
9
|
+
journaltemplate: "<em>{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %}</em> ({{series_run}}) {{ labels['volume'] }}_{{series_num}} {{ labels['part'] }}_{{series_partnumber}}"
|
10
|
+
extenttemplate:
|
11
|
+
book: "{{ volume }}_{{ labels['extent']['volume'] }}, {{ page }}_{{ labels['extent']['page'] }}"
|
12
|
+
booklet: book
|
13
|
+
proceedings: book
|
14
|
+
journal: book
|
15
|
+
standard: book
|
16
|
+
techreport: book
|
17
|
+
inbook: "{{ volume }}: {{ page }}"
|
18
|
+
misc: "{{ labels['extent']['volume'] }}_{{ volume }}, {{ labels['extent']['page'] }}_{{ page }}"
|
19
|
+
# TODO: software extent
|
20
|
+
language: en
|
21
|
+
script: Latn
|
22
|
+
template:
|
23
|
+
book: "{{ creatornames }} ({{role}}) . <em>{{ title }}</em> [{{medium}}] . {{ edition | capitalize }}. ({{ series }}.) {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. {{extent}}."
|
24
|
+
# TODO: omitted: author ids, subsidiary titles, subsidiary creators, rights metadata, distributor, item attributes, relationships
|
25
|
+
booklet: book
|
26
|
+
manual: book
|
27
|
+
proceedings: book
|
28
|
+
inbook: "{{ creatornames }} ({{role}}) . {{ title }} . {{ labels['in'] | capitalize }}: {{ host_creatornames}} ({{ host_role}}) : <em>{{host_title}}</em> [{{medium}}] . {{ edition | capitalize }}. ({{ series }}.) {{place}}: {{publisher}}. {{date}}. {{extent}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
29
|
+
inproceedings: inbook
|
30
|
+
incollection: inbook
|
31
|
+
# 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 | capitalize }}. {{place}}: {{publisher}}. {{date}}. {{extent}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
33
|
+
# TODO subsidiary titles, rights metadata, item attributes, relationships
|
34
|
+
article: "{{ creatornames }} ({{role}}) . {{ title }}. {{ series }} [{{medium}}] . {{ edition | capitalize }}. {{ extent }}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
35
|
+
# 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}}]. "
|
37
|
+
# TODO: omitted: author ids, subsidiary titles, subsidiary creators, copyright, license, distributor, system requirements, relationships
|
38
|
+
electronic resource: software
|
39
|
+
standard: "{{ creatornames }} ({{ role}}) . <em>{{ title }}</em> . {{ labels['in'] | capitalize }}:_{{ series_title }}. {{ medium | capitalize }}. {{ edition | capitalize }}. {{place}}: {{publisher}}. {{date}}. {{ extent }}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
40
|
+
# TODO: omitted: author ids, subsidiary titles, rights metadata, distributor, persistent identifier, item attributes, relationships
|
41
|
+
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}}]. "
|
43
|
+
# TODO: omitted: author ids, system requirements, host archive, copyright, license, data source, distributor, usage instructions, relationships, provenance
|
44
|
+
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
|
+
# TODO: omitted: author ids, page title, system requirements, subsidiary creator, rights metadata, distributor, persistent identifier, archive location, archive date and time, relationships
|
46
|
+
webresource: website
|
47
|
+
# TODO: component part
|
48
|
+
unpublished: "{{ creatornames }} ({{ role }}) . <em>{{ title }}</em> . {{ medium | capitalize }}. {{ date }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. {{ standardidentifier | first }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
49
|
+
# TODO: omitted: author ids, subsidiary titles, subsidiary creators, host archive, item attributes, relationships
|
50
|
+
presentation: unpublished
|
51
|
+
thesis: "{{ creatornames }} ({{ role }}) . <em>{{ title }}</em> . {{ medium | capitalize }}. {{ place }}: {{ publisher }}. {{ date }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. {{ standardidentifier | first }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
|
52
|
+
# unsupported types:
|
53
|
+
# map: ""
|
54
|
+
# audiovisual: ""
|
55
|
+
# film: ""
|
56
|
+
# video: ""
|
57
|
+
# broadcast: ""
|
58
|
+
# graphic_work: ""
|
59
|
+
# music: ""
|
60
|
+
# performance: "" (not in Relaton)
|
61
|
+
# patent: ""
|
62
|
+
# archival: ""
|
63
|
+
# social_media: ""
|
64
|
+
# alert: ""
|
65
|
+
# message: ""
|
66
|
+
# conversation: ""
|
67
|
+
# misc: ""
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require_relative "render_classes"
|
2
|
+
require_relative "render_fields"
|
3
|
+
require "yaml"
|
4
|
+
require "liquid"
|
5
|
+
require_relative "../isodoc/i18n"
|
6
|
+
require_relative "../utils/utils"
|
7
|
+
|
8
|
+
module Relaton
|
9
|
+
module Render
|
10
|
+
class General
|
11
|
+
attr_reader :template, :journaltemplate, :seriestemplate, :nametemplate,
|
12
|
+
:extenttemplate, :lang, :script, :edition, :edition_number,
|
13
|
+
:date
|
14
|
+
|
15
|
+
def initialize(opt = {})
|
16
|
+
options = YAML.load_file(File.join(File.dirname(__FILE__),
|
17
|
+
"config.yml"))
|
18
|
+
.merge(Utils::string_keys(opt))
|
19
|
+
@type = self.class.name.downcase.sub(/relaton::render::/, "")
|
20
|
+
root_initalize(options)
|
21
|
+
render_initialize(options)
|
22
|
+
@parse ||= options["parse"]
|
23
|
+
@i18n ||= options["i18n"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def root_initalize(opt)
|
27
|
+
i18n_initialize(opt)
|
28
|
+
@parse = Iso690Parse.new
|
29
|
+
@nametemplate = Iso690NameTemplate
|
30
|
+
.new(template: opt["nametemplate"], i18n: @i18n)
|
31
|
+
@seriestemplate = Iso690SeriesTemplate
|
32
|
+
.new(template: opt["seriestemplate"], i18n: @i18n)
|
33
|
+
@journaltemplate = Iso690SeriesTemplate
|
34
|
+
.new(template: opt["journaltemplate"], i18n: @i18n)
|
35
|
+
@extenttemplate = extentrenderers(opt)
|
36
|
+
end
|
37
|
+
|
38
|
+
def i18n_initialize(opt)
|
39
|
+
@lang = opt["language"]
|
40
|
+
@script = opt["script"]
|
41
|
+
@i18n = i18n(opt["language"], opt["script"])
|
42
|
+
@edition_number = opt["edition_number"] || @i18n.edition_number
|
43
|
+
@edition = opt["edition"] || @i18n.edition
|
44
|
+
@date = opt["date"] || @i18n.date
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_initialize(opt)
|
48
|
+
case opt["template"]
|
49
|
+
when String
|
50
|
+
@template = Iso690Template.new(template: opt["template"],
|
51
|
+
i18n: @i18n)
|
52
|
+
when Hash
|
53
|
+
@render = renderers(opt)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def renderers(opt)
|
58
|
+
template_hash_fill(opt["template"]).each_with_object({}) do |(k, v), m|
|
59
|
+
@type == "general" || @type == k or next
|
60
|
+
m[k] = General.subclass(k)
|
61
|
+
.new(template: v, parse: @parse, i18n: @i18n,
|
62
|
+
language: @lang, script: @script)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def extentrenderers(opt)
|
67
|
+
Iso690ExtentTemplate
|
68
|
+
.new(template: template_hash_fill(opt["extenttemplate"]), i18n: @i18n)
|
69
|
+
end
|
70
|
+
|
71
|
+
def default_template
|
72
|
+
"{{creatornames}}. {{title}}. {{date}}."
|
73
|
+
end
|
74
|
+
|
75
|
+
def i18n(lang = "en", script = "Latn")
|
76
|
+
::IsoDoc::I18n.new(lang, script)
|
77
|
+
end
|
78
|
+
|
79
|
+
def render(bib, embedded: false)
|
80
|
+
docxml = Nokogiri::XML(bib)
|
81
|
+
docxml.remove_namespaces!
|
82
|
+
parse(docxml.root, embedded: embedded)
|
83
|
+
end
|
84
|
+
|
85
|
+
def parse(doc, embedded: false)
|
86
|
+
f = doc.at("./formattedref") and
|
87
|
+
return embedded ? f.children.to_xml : doc.to_xml
|
88
|
+
|
89
|
+
ret = parse1(doc)
|
90
|
+
embedded and return ret
|
91
|
+
"<formattedref>#{ret}</formattedref>"
|
92
|
+
end
|
93
|
+
|
94
|
+
def renderer(doc)
|
95
|
+
unless ret = @template || @render[doc["type"]]&.template
|
96
|
+
raise "No renderer defined for #{doc['type']}"
|
97
|
+
end
|
98
|
+
unless @type == "general" || @type == doc["type"]
|
99
|
+
raise "No renderer defined for #{doc['type']}"
|
100
|
+
end
|
101
|
+
|
102
|
+
ret
|
103
|
+
end
|
104
|
+
|
105
|
+
def parse1(doc)
|
106
|
+
r = renderer(doc)
|
107
|
+
data = @parse.extract(doc)
|
108
|
+
data_liquid = Fields.new(renderer: self).compound_fields_format(data)
|
109
|
+
@i18n.l10n(r.render(data_liquid))
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def template_hash_fill(templates)
|
115
|
+
BIBTYPE.each_with_object({}) do |type, m|
|
116
|
+
template = templates[type] || templates["misc"] || default_template
|
117
|
+
BIBTYPE.include?(template) and template = templates[template]
|
118
|
+
m[type] = template
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Relaton
|
2
|
+
module Render
|
3
|
+
BIBTYPE =
|
4
|
+
%w(article book booklet manual proceedings presentation thesis techreport
|
5
|
+
standard unpublished map electronic_resource audiovisual film video
|
6
|
+
broadcast software graphic_work music patent inbook incollection
|
7
|
+
inproceedings journal website webresource dataset archival social_media
|
8
|
+
alert message conversation misc).freeze
|
9
|
+
|
10
|
+
class General
|
11
|
+
singleton_class.send(:attr_reader, :descendants)
|
12
|
+
@descendants = {}
|
13
|
+
|
14
|
+
def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
|
15
|
+
type = subclass.name.downcase.sub(/relaton::render::/, "")
|
16
|
+
General.descendants[type] = subclass
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.subclass(type)
|
20
|
+
@descendants[type]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Book < General
|
25
|
+
end
|
26
|
+
|
27
|
+
class Journal < General
|
28
|
+
end
|
29
|
+
|
30
|
+
class Booklet < General
|
31
|
+
end
|
32
|
+
|
33
|
+
class Manual < General
|
34
|
+
end
|
35
|
+
|
36
|
+
class Proceedings < General
|
37
|
+
end
|
38
|
+
|
39
|
+
class Presentation < General
|
40
|
+
end
|
41
|
+
|
42
|
+
class Thesis < General
|
43
|
+
end
|
44
|
+
|
45
|
+
class Techreport < General
|
46
|
+
end
|
47
|
+
|
48
|
+
class Standard < General
|
49
|
+
end
|
50
|
+
|
51
|
+
class Unpublished < General
|
52
|
+
end
|
53
|
+
|
54
|
+
class Map < General
|
55
|
+
end
|
56
|
+
|
57
|
+
class Electronic_resource < General
|
58
|
+
end
|
59
|
+
|
60
|
+
class Software < Electronic_resource
|
61
|
+
end
|
62
|
+
|
63
|
+
class Webresource < Electronic_resource
|
64
|
+
end
|
65
|
+
|
66
|
+
class Website < Webresource
|
67
|
+
end
|
68
|
+
|
69
|
+
class Dataset < Electronic_resource
|
70
|
+
end
|
71
|
+
|
72
|
+
class Social_media < Electronic_resource
|
73
|
+
end
|
74
|
+
|
75
|
+
class Alert < Social_media
|
76
|
+
end
|
77
|
+
|
78
|
+
class Message < Social_media
|
79
|
+
end
|
80
|
+
|
81
|
+
class Audiovisual < General
|
82
|
+
end
|
83
|
+
|
84
|
+
class Film < Audiovisual
|
85
|
+
end
|
86
|
+
|
87
|
+
class Video < Audiovisual
|
88
|
+
end
|
89
|
+
|
90
|
+
class Broadcast < Audiovisual
|
91
|
+
end
|
92
|
+
|
93
|
+
class Graphic_work < General
|
94
|
+
end
|
95
|
+
|
96
|
+
class Music < General
|
97
|
+
end
|
98
|
+
|
99
|
+
class Patent < General
|
100
|
+
end
|
101
|
+
|
102
|
+
class Hosted < General
|
103
|
+
end
|
104
|
+
|
105
|
+
class Article < Hosted
|
106
|
+
end
|
107
|
+
|
108
|
+
class InBook < Hosted
|
109
|
+
end
|
110
|
+
|
111
|
+
class InCollection < Hosted
|
112
|
+
end
|
113
|
+
|
114
|
+
class InProceedings < Hosted
|
115
|
+
end
|
116
|
+
|
117
|
+
class Archival < General
|
118
|
+
end
|
119
|
+
|
120
|
+
class Conversation < General
|
121
|
+
end
|
122
|
+
|
123
|
+
class Misc < General
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module Relaton
|
2
|
+
module Render
|
3
|
+
class Fields
|
4
|
+
def initialize(options)
|
5
|
+
@r = options[:renderer]
|
6
|
+
end
|
7
|
+
|
8
|
+
def compound_fields_format(hash)
|
9
|
+
name_fields_format(hash)
|
10
|
+
role_fields_format(hash)
|
11
|
+
date_fields_format(hash)
|
12
|
+
misc_fields_format(hash)
|
13
|
+
end
|
14
|
+
|
15
|
+
def name_fields_format(hash)
|
16
|
+
hash[:creatornames] = nameformat(hash[:creators])
|
17
|
+
hash[:host_creatornames] = nameformat(hash[:host_creators])
|
18
|
+
end
|
19
|
+
|
20
|
+
def role_fields_format(hash)
|
21
|
+
hash[:role] = role_inflect(hash[:creators], hash[:role_raw])
|
22
|
+
hash[:host_role] =
|
23
|
+
role_inflect(hash[:host_creators], hash[:host_role_raw])
|
24
|
+
end
|
25
|
+
|
26
|
+
def misc_fields_format(hash)
|
27
|
+
hash[:series] = seriesformat(hash)
|
28
|
+
hash[:edition] = editionformat(hash[:edition_raw])
|
29
|
+
hash[:extent] = extentformat(hash[:extent_raw], hash)
|
30
|
+
hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def date_fields_format(hash)
|
34
|
+
hash[:date] = dateformat(hash[:date], hash)
|
35
|
+
hash[:date_updated] = dateformat(hash[:date_updated], hash)
|
36
|
+
hash[:date_accessed] = dateformat(hash[:date_accessed], hash)
|
37
|
+
end
|
38
|
+
|
39
|
+
def seriesformat(hash)
|
40
|
+
parts = %i(series_title series_abbr series_num series_partnumber
|
41
|
+
series_run)
|
42
|
+
series_out = parts.each_with_object({}) do |i, m|
|
43
|
+
m[i] = hash[i]
|
44
|
+
end
|
45
|
+
t = hash[:type] == "article" ? @r.journaltemplate : @r.seriestemplate
|
46
|
+
t.render(series_out)
|
47
|
+
end
|
48
|
+
|
49
|
+
def nameformat(names)
|
50
|
+
return names if names.nil?
|
51
|
+
|
52
|
+
parts = %i(surname initials given middle)
|
53
|
+
names_out = names.each_with_object({}) do |n, m|
|
54
|
+
parts.each do |i|
|
55
|
+
m[i] ||= []
|
56
|
+
m[i] << n[i]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
@r.nametemplate.render(names_out)
|
60
|
+
end
|
61
|
+
|
62
|
+
def role_inflect(contribs, role)
|
63
|
+
return nil if role.nil? || contribs.size.zero?
|
64
|
+
|
65
|
+
number = contribs.size > 1 ? "pl" : "sg"
|
66
|
+
@r.i18n.get[role][number] || role
|
67
|
+
end
|
68
|
+
|
69
|
+
def editionformat(edn)
|
70
|
+
return edn unless /^\d+$/.match?(edn)
|
71
|
+
|
72
|
+
num = edn.to_i.localize(@r.lang.to_sym)
|
73
|
+
.to_rbnf_s(*@r.edition_number)
|
74
|
+
@r.edition.sub(/%/, num)
|
75
|
+
end
|
76
|
+
|
77
|
+
def extentformat(extent, hash)
|
78
|
+
extent.map do |e|
|
79
|
+
extent_out = e.merge(type: hash[:type],
|
80
|
+
host_title: hash[:host_title])
|
81
|
+
.transform_values do |v|
|
82
|
+
v.is_a?(Hash) ? range(v) : v
|
83
|
+
end
|
84
|
+
@r.extenttemplate.render(extent_out.merge(orig: e))
|
85
|
+
end.join("; ")
|
86
|
+
end
|
87
|
+
|
88
|
+
def range(hash)
|
89
|
+
if hash[:on] then hash[:on]
|
90
|
+
elsif hash.has_key?(:from) && hash[:from].nil? then nil
|
91
|
+
elsif hash[:from]
|
92
|
+
hash[:to] ? "#{hash[:from]}–#{hash[:to]}" : hash[:from]
|
93
|
+
else hash
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def date_range(hash)
|
98
|
+
if hash[:from]
|
99
|
+
"#{hash[:from]}–#{hash[:to]}"
|
100
|
+
else range(hash)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def dateformat(date, hash)
|
105
|
+
return nil if date.nil?
|
106
|
+
|
107
|
+
%i(from to on).each do |k|
|
108
|
+
date[k] = daterender(date[k], hash)
|
109
|
+
end
|
110
|
+
date_range(date)
|
111
|
+
end
|
112
|
+
|
113
|
+
def daterender(date, _hash)
|
114
|
+
return date if date.nil? || /^\d+$/.match?(date)
|
115
|
+
|
116
|
+
daterender1(date, dategranularity(date), hash)
|
117
|
+
end
|
118
|
+
|
119
|
+
def daterender1(date, format, _hash)
|
120
|
+
datef = dateparse(date, format, @r.lang.to_sym)
|
121
|
+
case @r.date[format]
|
122
|
+
when "to_full_s", "to_long_s", "to_medium_s", "to_short_s"
|
123
|
+
datef.send @r.date[format]
|
124
|
+
else
|
125
|
+
datef.to_additional_s(@r.date[format])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def dategranularity(date)
|
132
|
+
case date
|
133
|
+
when /^\d+-\d+$/ then "month_year"
|
134
|
+
when /^\d+-\d+-\d+$/ then "day_month_year"
|
135
|
+
else "date_time"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def dateparse(date, format, lang)
|
140
|
+
case format
|
141
|
+
when "date_time" then DateTime.parse(date)
|
142
|
+
.localize(lang, timezone: "Zulu")
|
143
|
+
when "day_month_year" then DateTime.parse(date)
|
144
|
+
.localize(lang, timezone: "Zulu").to_date
|
145
|
+
when "month_year" then Date.parse(date)
|
146
|
+
.localize(lang, timezone: "Zulu").to_date
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|