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.
@@ -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