relaton-render 1.3.0 → 1.4.0.pre.alpha.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +15 -2
  3. data/lib/relaton/render/iso690/element.rb +43 -0
  4. data/lib/relaton/render/iso690/elements/component_part.rb +50 -0
  5. data/lib/relaton/render/iso690/elements/creator.rb +129 -0
  6. data/lib/relaton/render/iso690/elements/edition.rb +47 -0
  7. data/lib/relaton/render/iso690/elements/identifier.rb +32 -0
  8. data/lib/relaton/render/iso690/elements/location.rb +27 -0
  9. data/lib/relaton/render/iso690/elements/medium.rb +27 -0
  10. data/lib/relaton/render/iso690/elements/numeration.rb +26 -0
  11. data/lib/relaton/render/iso690/elements/production.rb +36 -0
  12. data/lib/relaton/render/iso690/elements/pub_date.rb +51 -0
  13. data/lib/relaton/render/iso690/elements/series.rb +40 -0
  14. data/lib/relaton/render/iso690/elements/title.rb +30 -0
  15. data/lib/relaton/render/iso690/elements.rb +40 -0
  16. data/lib/relaton/render/iso690/fields.rb +53 -0
  17. data/lib/relaton/render/iso690/i18n/en.yml +13 -0
  18. data/lib/relaton/render/iso690/i18n/fr.yml +14 -0
  19. data/lib/relaton/render/iso690/i18n.rb +53 -0
  20. data/lib/relaton/render/iso690/identifier_kinds.rb +34 -0
  21. data/lib/relaton/render/iso690/index_renderer.rb +57 -0
  22. data/lib/relaton/render/iso690/kinds.rb +43 -0
  23. data/lib/relaton/render/iso690/renderer.rb +52 -0
  24. data/lib/relaton/render/iso690/style/locale.rb +44 -0
  25. data/lib/relaton/render/iso690/style/name_form.rb +21 -0
  26. data/lib/relaton/render/iso690/style/scheme.rb +23 -0
  27. data/lib/relaton/render/iso690/style/sort_rule.rb +25 -0
  28. data/lib/relaton/render/iso690/style/template_map.rb +28 -0
  29. data/lib/relaton/render/iso690/style/type_template.rb +21 -0
  30. data/lib/relaton/render/iso690/style.rb +76 -0
  31. data/lib/relaton/render/iso690/styles/author-date.yml +28 -0
  32. data/lib/relaton/render/iso690/template.rb +72 -0
  33. data/lib/relaton/render/iso690.rb +22 -0
  34. data/lib/relaton/render/version.rb +1 -1
  35. data/lib/relaton-render.rb +3 -7
  36. data/relaton-render.gemspec +2 -19
  37. metadata +35 -249
  38. data/lib/relaton/render/fields/date.rb +0 -48
  39. data/lib/relaton/render/fields/fields.rb +0 -266
  40. data/lib/relaton/render/general/citations.rb +0 -178
  41. data/lib/relaton/render/general/config.yml +0 -129
  42. data/lib/relaton/render/general/render.rb +0 -316
  43. data/lib/relaton/render/general/render_classes.rb +0 -132
  44. data/lib/relaton/render/general/uri.rb +0 -57
  45. data/lib/relaton/render/i18n/i18n.rb +0 -40
  46. data/lib/relaton/render/parse/parse.rb +0 -152
  47. data/lib/relaton/render/parse/parse_contributors.rb +0 -184
  48. data/lib/relaton/render/parse/parse_extract.rb +0 -200
  49. data/lib/relaton/render/parse/parse_id.rb +0 -128
  50. data/lib/relaton/render/template/liquid.rb +0 -48
  51. data/lib/relaton/render/template/subclasses.rb +0 -123
  52. data/lib/relaton/render/template/template.rb +0 -228
@@ -1,178 +0,0 @@
1
- module Relaton
2
- module Render
3
- class Citations
4
- def initialize(opt = {})
5
- # invoking i18n hash, but we preference the specific renderer's i18n
6
- @i18n = opt[:i18n]
7
- @lang = opt[:lang] # document lang and script
8
- @script = opt[:script]
9
- # hash of renderers, to be applied to specific citation by selector
10
- @renderer = opt[:renderer]
11
- end
12
-
13
- def renderer(_cite)
14
- @renderer[:default]
15
- end
16
-
17
- # takes array of { id, type, author, date, ord, data }
18
- def render(ret)
19
- cites = citations(ret)
20
- enhance_data(cites)
21
- cites.each_key do |k|
22
- cites[k] = render1(cites[k])
23
- end
24
- cites
25
- end
26
-
27
- def enhance_data(cites)
28
- ret = extract_uris_for_lookup(cites)
29
- ret.empty? and return
30
- # functionality removed: date needs to be given explicitly
31
- # @renderer.urls_exist_concurrent(ret.keys).each do |k, v|
32
- # ret[k].each { |u| add_date_accessed(cites[u], k, v) }
33
- # end
34
- end
35
-
36
- def extract_uris_for_lookup(cites)
37
- cites.each_with_object({}) do |(k, v), m|
38
- u = extract_uri_for_lookup(v) or next
39
- m[u] ||= []
40
- m[u] << k
41
- end
42
- end
43
-
44
- def extract_uri_for_lookup(cite)
45
- t = renderer(cite).renderer(cite[:type] || "misc").template_raw
46
- c = cite[:data]
47
- t.is_a?(String) or return
48
- (/\{\{\s*date_accessed\s*\}\}/.match?(t) &&
49
- /\{\{\s*uri\s*\}\}/.match?(t) &&
50
- c[:uri_raw] && !c[:date_accessed]) or return
51
- c[:uri_raw]
52
- end
53
-
54
- def add_date_accessed(cite, uri, status)
55
- r = renderer(cite)
56
- if status
57
- cite[:data][:date_accessed] = { on: ::Date.today.to_s }
58
- cite[:data] = r.fieldsklass.new(renderer: r)
59
- .compound_fields_format(cite[:data])
60
- else
61
- r.url_warn(uri)
62
- end
63
- end
64
-
65
- def render1(cit)
66
- ref, ref1, r = render1_prep(cit)
67
- i = @i18n.select(cit[:data])
68
- cit[:formattedref] =
69
- r.valid_parse(i.l10n(ref1))
70
- cit[:citation][:full] = r.valid_parse(i.l10n(ref))
71
- %i(type data renderer).each { |x| cit.delete(x) }
72
- cit
73
- end
74
-
75
- def use_terminator?(ref, final, _cit)
76
- !ref || ref.empty? and return false
77
- !ref.end_with?(final)
78
- end
79
-
80
- def render1_prep(cit)
81
- r = renderer(cit)
82
- ref = r.renderer(cit[:type] || "misc").render(cit[:data], cit[:data])
83
- final = @i18n.select(cit[:data]).get
84
- .dig("punct", "biblio-terminator") || "."
85
- ref1 = ref
86
- use_terminator?(ref, final, cit) and ref1 += final
87
- [ref, ref1, r]
88
- end
89
-
90
- # TODO: configure how multiple ids are joined, from template?
91
- def citations(ret)
92
- ret = disambig_author_date_citations(ret)
93
- ret.each_value do |b|
94
- i = @i18n.select(b[:data])
95
- b[:citation][:default] =
96
- i.l10n(b[:data][:authoritative_identifier]&.first || "")
97
- d = b[:data].merge(citestyle: "short")
98
- b[:citation][:short] = i.l10n(renderer(b).citeshorttemplate.render(d, d))
99
- citations_iterate_cite_styles(b, i)
100
- end
101
- ret
102
- end
103
-
104
- def citations_iterate_cite_styles(bib, i18n)
105
- r = renderer(bib)
106
- r.citetemplate.citation_styles.each do |style|
107
- bib[:citation][style] =
108
- i18n.l10n(r.citetemplate
109
- .render(bib.merge(citestyle: style)
110
- .merge(bib[:data]), bib[:data]))
111
- end
112
- end
113
-
114
- # takes array of { id, type, author, date, ord, data }
115
- def disambig_author_date_citations(ret)
116
- author_date_to_hash(suffix_date(sort_ord(author_date_breakdown(ret))))
117
- end
118
-
119
- def author_date_breakdown(ret)
120
- ret.each_with_object({}) do |b, m|
121
- m[b[:author]] ||= {}
122
- m[b[:author]][b[:date]] ||= []
123
- m[b[:author]][b[:date]] << b
124
- end
125
- end
126
-
127
- def sort_ord(ret)
128
- ret.each do |author, v|
129
- v.each_key do |date|
130
- ret[author][date].sort_by! { |a| a[:ord] }
131
- end
132
- end
133
- end
134
-
135
- def suffix_date(ret)
136
- ret.each do |k, v|
137
- v.each do |k1, v1|
138
- s = v1.reject { |b| b[:date].nil? }.size
139
- s.zero? || k.nil? and next
140
- suffix_date1(ret, k, k1, s)
141
- copy_date_fields(ret, k, k1)
142
- end
143
- end
144
- ret
145
- end
146
-
147
- def suffix_date1(ret, key1, key2, size)
148
- size > 1 or return
149
- ret[key1][key2].each_with_index do |b, i|
150
- b[:date].nil? and next
151
- b[:disambiguated_date] = b[:date] + ("a".ord + i).chr.to_s
152
- end
153
- end
154
-
155
- def copy_date_fields(ret, key1, key2)
156
- ret[key1][key2].each do |b|
157
- b[:date].nil? and next
158
- b[:data][:date] = b[:date]
159
- b[:disambiguated_date] ||= b[:date]
160
- b[:data][:disambiguated_date] = b[:disambiguated_date]
161
- end
162
- end
163
-
164
- def author_date_to_hash(ret)
165
- ret.each_with_object({}) do |(_k, v), m|
166
- v.each_value do |v1|
167
- v1.each do |b|
168
- m[b[:id]] = { author: @i18n.select(b[:data]).l10n(b[:author]),
169
- date: b[:disambiguated_date] || b[:date],
170
- citation: {},
171
- data: b[:data], type: b[:type] }
172
- end
173
- end
174
- end
175
- end
176
- end
177
- end
178
- end
@@ -1,129 +0,0 @@
1
- nametemplate:
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['author_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['author_and'] }} {% if nonpersonal[2] %}{{ nonpersonal[2] }}{% else %}{%if given[2]%}{{given[2]}} {{middle[2]}}{%else%}{{initials[2] | join: ' '}}.{%endif%} {{surname[2] | upcase}}{% endif %}"
5
- # disabled the following: they should be provided in inheriting calls
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
- # etal_count: 5
8
-
9
- authorcitetemplate:
10
- one: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] }}{% endif %}"
11
- two: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] }}{% endif %} {{ labels['author_and'] }} {% if nonpersonal[1] %}{{ nonpersonal[1] }}{% else %}{{surname[1] }}{% endif %}"
12
- more: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] }}{% endif %}, {% if nonpersonal[1] %}{{ nonpersonal[1] }}{% else %}{{surname[1] }}{% endif %} {{ labels['author_and'] }} {% if nonpersonal[2] %}{{ nonpersonal[2] }}{% else %}{{surname[2] }}{% endif %}"
13
- # disabled the following: they should be provided in inheriting calls
14
- # etal: "{% if nonpersonal[0] %}{{ nonpersonal[0] }}{% else %}{{surname[0] }}{% endif %}, {% if nonpersonal[1] %}{{ nonpersonal[1] }}{% else %}{{surname[1] }}{% endif %} <em>et al.</em>"
15
- # etal_count: 5
16
-
17
- seriestemplate: "{% if series_formatted %}{{ series_formatted }}{%else%}{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %} ({{series_run}}) {{series_num}}|({{series_partnumber}}){%endif%}"
18
- journaltemplate: "<em>{% if series_abbr %}{{series_abbr}}{% else %}{{series_title}}{% endif %}</em> ({{series_run}}) {{ labels['volume'] }}_{{series_num}} {{ labels['part'] }}_{{series_partnumber}}"
19
-
20
- extenttemplate:
21
- book: "{{ volume }}, {{ page }}"
22
- booklet: book
23
- proceedings: book
24
- journal: book
25
- standard: book
26
- techreport: book
27
- inbook: "{{ volume }}: {{ page }}"
28
- article: "{{ volume }} {{issue}} , {{ page }}, {{ duration }}"
29
- misc: "{{ volume }} {{issue}} , {{ page }}, {{ duration }}"
30
- sizetemplate:
31
- dataset: "{{ data }}"
32
- electronic resource: dataset
33
- webresource: dataset
34
- misc: "{{ volume }}, {{ issue }}, {{ page }}, {{ data }}, {{ duration }}"
35
-
36
- language: en
37
- script: Latn
38
-
39
- citetemplate:
40
- author_date: "{{ author }} {{ disambiguated_date}}"
41
- author_date_br: "{{ author }} ({{ disambiguated_date}})"
42
- author: "{{ author }}"
43
- date: "{{ disambiguated_date }}"
44
- reference_tag: "{{ biblio_tag }}"
45
- title: "{{ title }}"
46
- title_reference_tag: "{{ title }} {{ biblio_tag }}"
47
- short:
48
- book: "{{ creatornames }} ({{role}}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} [{{medium}}] $$$ {{ edition | capitalize_first }}$$$ ({{ series }}$$$|) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{size}}$$$ {{extent}}$$$"
49
- booklet: book
50
- manual: book
51
- proceedings: book
52
- inbook: "{{ creatornames }} ({{role}}) $$$ {{labels['punct']['open-secondary-title']}}{{ title }}{{labels['punct']['close-secondary-title']}} $$$ {{ labels['in_document'] | capitalize }}: {{ host_creatornames}} ({{ host_role}}) : {{labels['punct']['open-title']}}{{host_title}}{{labels['punct']['close-title']}} [{{medium}}] $$$ {{ edition | capitalize_first }}$$$ ({{ series }}$$$|) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}$$$ {{date}}$$$ {{size}}$$$ {{extent}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$"
53
- inproceedings: inbook
54
- incollection: inbook
55
- journal: "{{labels['punct']['open-title']}}{{ title}}{{labels['punct']['close-title']}} [{{medium}}] $$$ {{ edition | capitalize_first }}$$$ {{place}}: {{publisher}}$$$ {{date}}$$$ {{size}}$$$ {{extent}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$"
56
- article: "{{ creatornames }} ({{role}}) $$$ {{labels['punct']['open-secondary-title']}}{{ title }}{{labels['punct']['close-secondary-title']}}$$$ {{ series }} [{{medium}}] $$$ {{ edition | capitalize_first }}$$$ {{size}}$$$ {{ extent }}$$$ {{place}}: {{publisher}}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$"
57
- software: "{{ creatornames }} ({{ role}}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ labels['version'] | capitalize }}_{{ edition_raw }}$$$ {{medium | capitalize}}$$$ {{place}}: {{publisher}}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{size}}$$$ {{ extent}}$$$"
58
- electronic resource: software
59
- standard: "{{ creatornames }} ({{ role}}) $$$ {{ authoritative_identifier | join: '|' }}: {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ medium | capitalize }}$$$ {{ edition | capitalize_first }}$$$ {{ place }}: {{ publisher }}$$$ {{date}}$$$ {{size}}$$$ {{ extent }}$$$ {{ other_identifier | join: '$$$ ' }}"
60
- techreport: standard
61
- dataset: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ labels['version'] | capitalize }}_{{ edition_raw }}$$$ {{medium | capitalize }}$$$ {{ labels['in_series'] | capitalize }}:_{{series}}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{ size }}$$$ {{ extent}}$$$"
62
- website: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ labels['version'] | capitalize }}_{{ edition_raw }}$$$ {{medium | capitalize }}$$$ {{ place }}: {{ publisher }}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$"
63
- webresource: website
64
- unpublished: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ medium | capitalize }}$$$ {{ date }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$"
65
- thesis: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ medium | capitalize }}$$$ {{ place }}: {{ publisher }}$$$ {{ date }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$"
66
- misc: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ date }}$$$"
67
- map: misc
68
- audiovisual: misc
69
- film: misc
70
- video: misc
71
- broadcast: misc
72
- graphic_work: misc
73
- music: misc
74
- performance: misc
75
- patent: misc
76
- archival: misc
77
- social_media: misc
78
- alert: misc
79
- message: misc
80
- conversation: misc
81
- internal: misc
82
-
83
- template:
84
- book: "{{ creatornames }} ({{role}}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} [{{medium}}] $$$ {{ edition | capitalize_first }}$$$ ({{ series }}$$$|) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$ {{size}}$$$ {{extent}}$$$"
85
- # TODO: omitted: author ids, subsidiary titles, subsidiary creators, rights metadata, distributor, item attributes, relationships
86
- booklet: book
87
- manual: book
88
- proceedings: book
89
- inbook: "{{ creatornames }} ({{role}}) $$$ {{labels['punct']['open-secondary-title']}}{{ title }}{{labels['punct']['close-secondary-title']}} $$$ {{ labels['in_document'] | capitalize }}: {{ host_creatornames}} ({{ host_role}}) : {{labels['punct']['open-title']}}{{host_title}}{{labels['punct']['close-title']}} [{{medium}}] $$$ {{ edition | capitalize_first }}$$$ ({{ series }}$$$|) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}$$$ {{date}}$$$ {{size}}$$$ {{extent}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$"
90
- inproceedings: inbook
91
- incollection: inbook
92
- # TODO: omitted: author ids, additional info for component part, subsidiary titles of host resource, rights metadata, distributor, relationships
93
- journal: "{{labels['punct']['open-title']}}{{ title}}{{labels['punct']['close-title']}} [{{medium}}] $$$ {{ edition | capitalize_first }}$$$ {{place}}: {{publisher}}$$$ {{date}}$$$ {{size}}$$$ {{extent}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$"
94
- # TODO subsidiary titles, rights metadata, item attributes, relationships
95
- article: "{{ creatornames }} ({{role}}) $$$ {{labels['punct']['open-secondary-title']}}{{ title }}{{labels['punct']['close-secondary-title']}}$$$ {{ series }} [{{medium}}] $$$ {{ edition | capitalize_first }}$$$ {{size}}$$$ {{ extent }}$$$ {{place}}: {{publisher}}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$"
96
- # TODO: omitted: author ids, subsidiary titles, rights metadata, distributor, item attributes, relationships; newspapers
97
- software: "{{ creatornames }} ({{ role}}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ labels['version'] | capitalize }}_{{ edition_raw }}$$$ {{medium | capitalize}}$$$ {{place}}: {{publisher}}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{size}}$$$ {{ extent}}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$ "
98
- # TODO: omitted: author ids, subsidiary titles, subsidiary creators, copyright, license, distributor, system requirements, relationships
99
- electronic resource: software
100
- standard: "{{ creatornames }} ({{ role}}) $$$ {{ authoritative_identifier | join: '|' }}: {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ medium | capitalize }}$$$ {{ edition | capitalize_first }}$$$ {{ place }}: {{ publisher }}$$$ {{date}}$$$ {{size}}$$$ {{ extent }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$"
101
- # TODO: omitted: author ids, subsidiary titles, rights metadata, distributor, persistent identifier, item attributes, relationships
102
- techreport: standard
103
- dataset: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ labels['version'] | capitalize }}_{{ edition_raw }}$$$ {{medium | capitalize }}$$$ {{ labels['in_series'] | capitalize }}:_{{series}}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ {{ size }}$$$ {{ extent}}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$ "
104
- # TODO: omitted: author ids, system requirements, host archive, copyright, license, data source, distributor, usage instructions, relationships, provenance
105
- website: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ labels['version'] | capitalize }}_{{ edition_raw }}$$$ {{medium | capitalize }}$$$ {{ place }}: {{ publisher }}$$$ {{date}}$$$ {{ labels['updated'] | capitalize }}:_{{date_updated}}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$ "
106
- # TODO: omitted: author ids, page title, system requirements, subsidiary creator, rights metadata, distributor, persistent identifier, archive location, archive date and time, relationships
107
- webresource: website
108
- # TODO: component part
109
- unpublished: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ medium | capitalize }}$$$ {{ date }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$"
110
- # TODO: omitted: author ids, subsidiary titles, subsidiary creators, host archive, item attributes, relationships
111
- presentation: unpublished
112
- thesis: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ medium | capitalize }}$$$ {{ place }}: {{ publisher }}$$$ {{ date }}$$$ {{ labels['at_url'] | capitalize}}:_{{ access_location }}$$$ {{ authoritative_identifier | join: '$$$ ' }}$$$ {{ other_identifier | join: '$$$ ' }}$$$ {{ uri }}$$$ [{{ labels['viewed'] }}:_{{date_accessed}}]$$$"
113
- misc: "{{ creatornames }} ({{ role }}) $$$ {{labels['punct']['open-title']}}{{ title }}{{labels['punct']['close-title']}} $$$ {{ date }}$$$ {{ uri }}$$$"
114
- # following are # unsupported types:
115
- map: misc
116
- audiovisual: misc
117
- film: misc
118
- video: misc
119
- broadcast: misc
120
- graphic_work: misc
121
- music: misc
122
- performance: misc
123
- patent: misc
124
- archival: misc
125
- social_media: misc
126
- alert: misc
127
- message: misc
128
- conversation: misc
129
- internal: misc
@@ -1,316 +0,0 @@
1
- require_relative "render_classes"
2
- require_relative "citations"
3
- require_relative "uri"
4
- require "yaml"
5
- require "liquid"
6
- require "date"
7
- require "relaton/bib"
8
- require "metanorma-utils"
9
- require_relative "../template/template"
10
- require_relative "../../../isodoc/i18n"
11
-
12
- module Relaton
13
- module Render
14
- class General
15
- Hash.include ::Metanorma::Utils::Hash
16
- Array.include ::Metanorma::Utils::Array
17
-
18
- attr_reader :template, :journaltemplate, :seriestemplate, :nametemplate,
19
- :authorcitetemplate, :extenttemplate, :sizetemplate,
20
- :citetemplate, :citeshorttemplate, :lang, :script, :i18n,
21
- :edition, :date, :fieldsklass, :dateklass, :config
22
-
23
- def initialize(opt = {})
24
- options = init_options(opt)
25
- @type = self.class.name.downcase.split("::").last
26
- klass_initialize(options)
27
- root_initalize(options)
28
- render_initialize(options)
29
- @parse ||= options["parse"]
30
- init_misc
31
- end
32
-
33
- def init_options(opt)
34
- opt = opt.stringify_all_keys
35
- @override_file ||= opt["config"]
36
- @config = config_override(read_config)
37
- @config.merge(opt)
38
- end
39
-
40
- def init_misc
41
- @semaphore = Mutex.new
42
- @urlcache = {}
43
- @url_warned = {}
44
- end
45
-
46
- def read_config
47
- YAML.load_file(File.join(File.dirname(__FILE__), "config.yml"))
48
- end
49
-
50
- def config_override(ret)
51
- new = {}
52
- @override_file and new = YAML.load_file(@override_file)
53
- ret.deep_merge(new)
54
- end
55
-
56
- def klass_initialize(options)
57
- @nametemplateklass = Relaton::Render::Template::Name
58
- @authorcitetemplateklass = Relaton::Render::Template::AuthorCite
59
- @citetemplateklass = Relaton::Render::Template::Cite
60
- @citeshorttemplateklass = Relaton::Render::Template::Cite
61
- @seriestemplateklass = Relaton::Render::Template::Series
62
- @extenttemplateklass = Relaton::Render::Template::Extent
63
- @sizetemplateklass = Relaton::Render::Template::Size
64
- @generaltemplateklass = Relaton::Render::Template::General
65
- @fieldsklass = Relaton::Render::Fields
66
- @dateklass = Relaton::Render::Date
67
- @parseklass = Relaton::Render::Parse
68
- @i18nklass = options["i18nklass"] || Relaton::Render::I18n
69
- @citeklass = Relaton::Render::Citations
70
- end
71
-
72
- def root_initalize(opt)
73
- i18n_initialize(opt)
74
- @parse = @parseklass.new(lang: @lang, script: @script, i18n: @i18n)
75
- @nametemplate = @nametemplateklass
76
- .new(template: opt["nametemplate"], i18n: @i18n)
77
- @citetemplate, @citeshorttemplate = citerenderers(opt)
78
- @authorcitetemplate = @authorcitetemplateklass
79
- &.new(template: opt["authorcitetemplate"], i18n: @i18n)
80
- @seriestemplate = @seriestemplateklass
81
- .new(template: opt["seriestemplate"], i18n: @i18n)
82
- @journaltemplate = @seriestemplateklass
83
- .new(template: opt["journaltemplate"], i18n: @i18n)
84
- @extenttemplate = extentrenderers(opt)
85
- @sizetemplate = sizerenderers(opt)
86
- end
87
-
88
- def i18n_initialize(opt)
89
- @lang = opt["language"]
90
- @script = opt["script"]
91
- @locale = opt["locale"]
92
- default_i18n = opt["i18n"] ||
93
- i18n_klass(language: @lang, script: @script, locale: @locale,
94
- i18nhash: opt["i18nhash"])
95
- @i18n = @i18nklass.new(opt.merge({ "i18n" => default_i18n }))
96
- i18n_default_strs(opt)
97
- end
98
-
99
- # avoid using these, they are document-set not citation-specific
100
- def i18n_default_strs(opt)
101
- @edition = opt["edition"] || @i18n.select(nil).edition
102
- @date = opt["date"] || @i18n.select(nil).get["date_formats"] ||
103
- { "month_year" => "yMMMM", "day_month_year" => "to_long_s",
104
- "date_time" => "to_long_s" }
105
- end
106
-
107
- def render_initialize(opt)
108
- case opt["template"]
109
- when String
110
- @template = @generaltemplateklass
111
- .new(template: opt["template"], i18n: @i18n)
112
- when Hash
113
- @render = renderers(opt)
114
- end
115
- end
116
-
117
- def renderers(opt)
118
- template_hash_fill(opt["template"]).each_with_object({}) do |(k, v), m|
119
- @type == "general" || @type == k or next
120
- m[k] = self.class.subclass(k)
121
- .new(template: v, parse: @parse, i18n_multi: @i18n.config,
122
- language: @lang, script: @script, i18nklass: @i18nklass)
123
- end
124
- end
125
-
126
- def extentrenderers(opt)
127
- @extenttemplateklass
128
- .new(template: template_hash_fill(opt["extenttemplate"]), i18n: @i18n)
129
- end
130
-
131
- def sizerenderers(opt)
132
- @sizetemplateklass
133
- .new(template: template_hash_fill(opt["sizetemplate"]), i18n: @i18n)
134
- end
135
-
136
- def citerenderers(opt)
137
- s = opt["citetemplate"]["short"]
138
- r = opt["citetemplate"].reject { |k, _| k == "short" }
139
- short = @citetemplateklass
140
- &.new(template: template_hash_fill(s), i18n: @i18n)
141
- ret = @citetemplateklass
142
- &.new(template: r, i18n: @i18n)
143
- [ret, short]
144
- end
145
-
146
- def default_template
147
- "{{creatornames}}. {{title}}. {{disambiguated_date}}."
148
- end
149
-
150
- def i18n_klass(language: "en", script: "Latn", locale: nil, i18nhash: nil)
151
- ::IsoDoc::RelatonRenderI18n.new(language, script, locale: locale,
152
- i18nhash: i18nhash)
153
- end
154
-
155
- def render(bib, embedded: false, terminator: true)
156
- bib = xml2relaton(bib)
157
- f = bib.formattedref and
158
- return embedded ? f.content : fmtref(f.content)
159
- ret = render1(bib, terminator) or return nil
160
- embedded and return ret
161
- fmtref(ret)
162
- end
163
-
164
- def xml2relaton(bib)
165
- bib.is_a?(Relaton::Bib::ItemData) and return bib
166
- xml = xml_string2noko(bib)
167
- bib = xml.to_xml(encoding: "UTF-8", indent: 0,
168
- save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
169
- .gsub(/ xmlns="[^"]*"/, "")
170
- Relaton::Bib::Bibitem.from_xml(bib)
171
- end
172
-
173
- def xml_string2noko(bib)
174
- case bib
175
- when String
176
- xml = Nokogiri::XML(bib)
177
- xml.errors.empty? or return bib
178
- xml.root
179
- when Nokogiri::XML::Element
180
- bib
181
- when Nokogiri::XML::Document
182
- bib.root
183
- end
184
- end
185
-
186
- def fmtref(doc)
187
- "<formattedref>#{doc}</formattedref>"
188
- end
189
-
190
- def renderer(type)
191
- ret = @template || @render[type]&.template or
192
- raise "No renderer defined for #{type}"
193
- @type == "general" || @type == type or
194
- raise "No renderer defined for #{type}"
195
- ret
196
- end
197
-
198
- # <esc> in field can get capitalised in filters
199
- def esc_cleanup(text)
200
- text.gsub(/<esc>/i, "<esc>").gsub(/<\/esc>/i, "</esc>")
201
- end
202
-
203
- def render1(doc, terminator)
204
- obj, str = render_single_bibitem(doc)
205
- out = [str] + also_pub_as(doc)
206
- ret1 = out.join(@i18n.select(obj).get["punct"]["biblio-field-delimiter"] || ". ")
207
- ret = @i18n.select(obj).l10n(esc_cleanup(ret1)
208
- .gsub(".</esc>.", ".</esc>").gsub(".. ", ". "))
209
- final = @i18n.select(obj).get["punct"]["biblio-terminator"] || "."
210
- terminator && !ret.end_with?(final) && !ret.empty? and ret += final
211
- ret
212
- end
213
-
214
- def also_pub_as(doc)
215
- r = Array(doc.relation).select { |x| x.type == "hasRepresentation" }
216
- r.map do |x|
217
- _, out = render_single_bibitem(x.bibitem)
218
- @i18n.select(nil).also_pub_as + out
219
- end
220
- end
221
-
222
- def render_single_bibitem(doc)
223
- data_liquid, r = parse(doc)
224
- out = liquid(data_liquid, r)
225
- [data_liquid, out]
226
- end
227
-
228
- def liquid(data_liquid, renderer)
229
- valid_parse(renderer.render(data_liquid, data_liquid))
230
- end
231
-
232
- def parse(doc)
233
- doc = xml2relaton(doc)
234
- r = renderer(doc.type || "misc")
235
- data = @parse.extract(doc)
236
- enhance_data(data, r.template_raw)
237
- data_liquid = @fieldsklass.new(renderer: self)
238
- .compound_fields_format(data)
239
- [data_liquid, r]
240
- end
241
-
242
- def valid_parse(ret)
243
- @i18n.select(nil).get["no_date"] == ret and return nil
244
- ret&.gsub(/\+\+\+(.+?)\+\+\+/, '\1')
245
- end
246
-
247
- # expect array of Relaton objects, in sorted order
248
- # enhance_data is skipped here, and is done in batch inside Citations
249
- def render_all(bib, type: "author-date")
250
- bib = sanitise_citations_input(bib) or return
251
- @citeklass.new(type: type, renderer: citation_renderers,
252
- i18n: @i18n, lang: @lang, script: @script)
253
- .render(citations1(bib))
254
- end
255
-
256
- def citation_renderers
257
- { default: self }
258
- end
259
-
260
- def sanitise_citations_input(bib)
261
- bib.is_a?(Array) and return bib
262
- bib.is_a?(String) and return sanitise_citations_input_string(bib)
263
- end
264
-
265
- def sanitise_citations_input_string(bib)
266
- p = Nokogiri::XML(bib) or return
267
- (p.errors.empty? && p.root.at("./bibitem")) or return nil
268
- p.root.xpath("./bibitem").each_with_object([]) do |b, m|
269
- m << Relaton::Bib::Bibitem.from_xml(b.to_xml)
270
- end
271
- end
272
-
273
- def citations1(bib)
274
- bib.each_with_object([]).with_index do |(b, m), i|
275
- data_liquid = @fieldsklass.new(renderer: self)
276
- .compound_fields_format(@parse.extract(b))
277
- m << { author: data_liquid[:authorcite], date: data_liquid[:date],
278
- ord: i, id: b.id, data: data_liquid, type: b.type }
279
- end
280
- end
281
-
282
- # add to liquid data based on template
283
- def enhance_data(_data, template)
284
- template.is_a?(String) or return
285
- # add_date_accessed(data, template)
286
- end
287
-
288
- # functionality removed: date needs to be given explicitly
289
- def add_date_accessed(data, template)
290
- (/\{\{\s*date_accessed\s*\}\}/.match?(template) &&
291
- /\{\{\s*uri\s*\}\}/.match?(template) &&
292
- data[:uri_raw] && !data[:date_accessed]) or return
293
- if url_exist?(data[:uri_raw])
294
- data[:date_accessed] = { on: ::Date.today.to_s }
295
- else url_warn(data[:uri_raw])
296
- end
297
- end
298
-
299
- def url_warn(uri)
300
- @url_warned[uri] and return
301
- warn "BIBLIOGRAPHY WARNING: cannot access #{uri}"
302
- @url_warned[uri] = true
303
- end
304
-
305
- private
306
-
307
- def template_hash_fill(templates)
308
- BIBTYPE.each_with_object({}) do |type, m|
309
- template = templates[type] || templates["misc"] || default_template
310
- BIBTYPE.include?(template) and template = templates[template]
311
- m[type] = template
312
- end
313
- end
314
- end
315
- end
316
- end