relaton-render 0.1.0 → 0.3.1

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.
@@ -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]}&#x2013;#{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]}&#x2013;#{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 }}_{{ labels['extent']['volume'] }}, {{ page }}_{{ labels['extent']['page'] }}"
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: "{{ labels['extent']['volume'] }}_{{ volume }}, {{ labels['extent']['page'] }}_{{ page }}"
19
- # TODO: software extent
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 | capitalize }}. ({{ series }}.) {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. {{extent}}."
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 | capitalize }}. ({{ series }}.) {{place}}: {{publisher}}. {{date}}. {{extent}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
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 | capitalize }}. {{place}}: {{publisher}}. {{date}}. {{extent}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
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 | capitalize }}. {{ extent }}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
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 | capitalize }}. {{place}}: {{publisher}}. {{date}}. {{ extent }}. {{ standardidentifier | first }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
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
- # 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: ""
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
- require_relative "../isodoc/i18n"
6
- require_relative "../utils/utils"
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, :lang, :script, :edition, :edition_number,
13
- :date
12
+ :extenttemplate, :sizetemplate, :lang, :script, :i18n,
13
+ :edition, :edition_number, :date
14
14
 
15
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::/, "")
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 = Iso690Parse.new
29
- @nametemplate = Iso690NameTemplate
41
+ @parse = @parseklass.new(lang: @lang, script: @script)
42
+ @nametemplate = @nametemplateklass
30
43
  .new(template: opt["nametemplate"], i18n: @i18n)
31
- @seriestemplate = Iso690SeriesTemplate
44
+ @seriestemplate = @seriestemplateklass
32
45
  .new(template: opt["seriestemplate"], i18n: @i18n)
33
- @journaltemplate = Iso690SeriesTemplate
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 = i18n(opt["language"], opt["script"])
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 = Iso690Template.new(template: opt["template"],
51
- i18n: @i18n)
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
- Iso690ExtentTemplate
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 i18n(lang = "en", script = "Latn")
76
- ::IsoDoc::I18n.new(lang, script)
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
- docxml = Nokogiri::XML(bib)
81
- docxml.remove_namespaces!
82
- parse(docxml.root, embedded: embedded)
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.at("./formattedref") and
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(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
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 = Fields.new(renderer: self).compound_fields_format(data)
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