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,228 +0,0 @@
1
- # require_relative "../utils/utils"
2
- require_relative "liquid"
3
- require "singleton"
4
- require "metanorma-utils"
5
-
6
- module Relaton
7
- module Render
8
- module Template
9
- class CacheManager
10
- include Singleton
11
-
12
- attr_accessor :mutex
13
-
14
- Hash.include ::Metanorma::Utils::Hash
15
- Array.include ::Metanorma::Utils::Array
16
-
17
- def initialize
18
- @cache = {}
19
- @mutex = Mutex.new
20
- end
21
-
22
- def store(key, value)
23
- @cache[key] = value
24
- end
25
-
26
- def retrieve(key)
27
- @cache[key]
28
- end
29
-
30
- def clear
31
- @cache.clear
32
- end
33
- end
34
-
35
- class General
36
- attr_reader :template_raw
37
-
38
- def initialize(opt = {})
39
- @htmlentities = HTMLEntities.new
40
- @templatecache = CacheManager.instance
41
- @liquid_env = create_liquid_environment
42
- parse_options(opt)
43
- end
44
-
45
- def parse_options(opt)
46
- # opt = Utils::sym_keys(opt)
47
- opt = opt.symbolize_all_keys
48
- @i18n = opt[:i18n]
49
- @template_raw = opt[:template].dup
50
- @template =
51
- case opt[:template]
52
- when Hash
53
- opt[:template].transform_values { |x| template_process(x) }
54
- when Array then opt[:template].map { |x| template_process(x) }
55
- else { default: template_process(opt[:template]) }
56
- end
57
- end
58
-
59
- def create_liquid_environment
60
- env = ::Liquid::Environment.new
61
- env.register_filter(::Relaton::Render::Template::CustomFilters)
62
- env
63
- end
64
-
65
- # denote start and end of variable,
66
- # so that we can detect empty variables in postprocessing
67
- VARIABLE_DELIM = "%%".freeze
68
-
69
- # denote citation components which get delimited by period conventionally
70
- COMPONENT_DELIM = Regexp.quote("$$$").freeze
71
-
72
- # escape < >
73
- LT_DELIM = "\u0019".freeze
74
- GT_DELIM = "\u001a".freeze
75
-
76
- # use tab internally for non-spacing delimiter
77
- NON_SPACING_DELIM = "\t".freeze
78
-
79
- def punct_field?(name)
80
- name or return false
81
- name = name.tr("'", '"')
82
- %w(labels["punct"]["open-title"] labels["punct"]["close-title"]
83
- labels["punct"]["open-secondary-title"]
84
- labels["punct"]["close-secondary-title"]).include?(name)
85
- end
86
-
87
- def template_process(template)
88
- template.is_a?(String) or return template
89
- t = nil
90
- @templatecache.mutex.synchronize do
91
- unless t = @templatecache.retrieve(template)
92
- t = ::Liquid::Template
93
- .parse(add_field_delim_to_template(template), environment: @liquid_env)
94
- @templatecache.store(template, t)
95
- end
96
- end
97
- t
98
- end
99
-
100
- def add_field_delim_to_template(template)
101
- t = template.split(/(\{\{|\}\})/).each_slice(4).map do |a|
102
- unless !a[2] || punct_field?(a[2]&.strip)
103
- a[1] = "#{VARIABLE_DELIM}{{"
104
- a[3] = "}}#{VARIABLE_DELIM}"
105
- end
106
- a.join
107
- end.join.tr("\t", " ")
108
- t.gsub(/\}\}#{VARIABLE_DELIM}\|/o, "}}#{VARIABLE_DELIM}#{NON_SPACING_DELIM}")
109
- .gsub(/\|#{VARIABLE_DELIM}\{\{/o, "#{NON_SPACING_DELIM}#{VARIABLE_DELIM}{{")
110
- end
111
-
112
- # hash is what to render, which can be entire bib entry,
113
- # or a subset of it like names
114
- # context is information for selecting i18n, which is entire bib entry,
115
- # potentially enhanced
116
- def render(hash, context)
117
- t = template_select(hash) or return nil # TODO select on context?
118
- i = @i18n.select(context)
119
- i18nsettings = { "labels" => i.get, "lang" => i.lang,
120
- "script" => i.script, "locale" => i.locale }
121
- ret = template_clean(t.render(liquid_hash(hash.merge(i18nsettings))))
122
- bib_delim = i.get.dig("punct", "biblio-field-delimiter") || ". "
123
- template_components(ret, bib_delim, context)
124
- end
125
-
126
- def template_select(_hash)
127
- @template[:default]
128
- end
129
-
130
- def template_clean(str)
131
- str = str.gsub(/&#x3c;/i, LT_DELIM).gsub(/&#x3e;/i, GT_DELIM)
132
- str = template_clean1(@htmlentities.decode(str))
133
- /[[:alnum:]]/.match?(str) or return nil
134
- str.strip.gsub(/#{LT_DELIM}/o, "&#x3c;")
135
- .gsub(/#{GT_DELIM}/o, "&#x3e;")
136
- .gsub(/&(?!#\S+?;)/, "&#x26;")
137
- end
138
-
139
- def template_clean1(str)
140
- str = strip_empty_variables(str)
141
- str.gsub(/([,:;]\s*)+<\/esc>([,:;])(\s|_|$)/, "\\2</esc>\\3")
142
- .gsub(/([,:;]\s*)+([,:;](\s|_|$))/, "\\2")
143
- .gsub(/([,.:;]\s*)+<\/esc>([.])(\s|_|$)/, "\\2</esc>\\3") # move outside
144
- .gsub(/([,.:;]\s*)+([.](\s|_|$))/, "\\2") # move outside
145
- .gsub(/([,:;]\s*)+<\/esc>(,)(\s|_|$)/, "\\2</esc>\\3")
146
- .gsub(/([,:;]\s*)+(,(\s|_|$))/, "\\2")
147
- .gsub(/([,:;]\s*)+(#{COMPONENT_DELIM})/o, "\\2")
148
- .gsub(/(:\s+)(&\s)/, "\\2")
149
- .gsub(/\s+([,.:;)])/, "\\1") # trim around $$$
150
- .sub(/^\s*[,.:;]\s*/, "") # no init $$$
151
- .sub(/[,:;]\s*$/, "")
152
- .gsub(/(?<!\\)_/, " ")
153
- .gsub("\\_", "_")
154
- .gsub(/(?<!#{COMPONENT_DELIM})#{NON_SPACING_DELIM}(?!#{COMPONENT_DELIM})/o, "") # preserve NON_SPACING_DELIM near $$$
155
- .gsub(/[\n\r ]+/, " ")
156
- .gsub(/<(\/)?esc>/i, "<\\1esc>")
157
- end
158
-
159
- # get rid of all empty variables, and any text around them,
160
- # including component delimiters:
161
- # [{{}}]$$$ => ""
162
- # [{{}}] $$$ => " $$$"
163
- def strip_empty_variables(str)
164
- str.gsub(/\S*#{VARIABLE_DELIM}#{VARIABLE_DELIM}\S*/o, "")
165
- .gsub(/#{VARIABLE_DELIM}/o, "")
166
- end
167
-
168
- # delim = punct.biblio-field-terminator must not be i18n'ised:
169
- # .</esc>. deletes first .
170
- # .</esc>。does not delete first .
171
- # So we do not want to pass delim in as .,
172
- # and then have it i18n to 。after we are done parsing
173
- #
174
- # Do not strip any delimiters from final field in string
175
- #
176
- # if delim = ". " , then: ({{ series }}$$$|) => (series1.)
177
- def template_components(str, delim, context)
178
- str or return str
179
- delimrstrip, delimre, delimrstripre = template_components_prep(delim)
180
- ret = template_components_split(str, delimre)
181
- delim != delimrstrip and # "." in field followed by ". " in delim
182
- ret = remove_double_period(ret, delimrstripre)
183
- context[:citestyle] == "short" and
184
- ret[0] += "<span class='fmt-first-biblio-delim'/>"
185
- ret.join(delim).gsub(/#{delim}\|/, delimrstrip)
186
- end
187
-
188
- def template_components_split(str, delimre)
189
- ret = str.gsub(NON_SPACING_DELIM, "|").split(/#{COMPONENT_DELIM}/o)
190
- .map(&:strip).reject(&:empty?)
191
- ret[0...-1].map do |s|
192
- s.sub(/#{delimre}$/, "").sub(%r[#{delimre}(</[^>]+>)$], "\\1")
193
- end + [ret.last]
194
- end
195
-
196
- def remove_double_period(ret, delimrstripre)
197
- ret[0...-1].map do |s|
198
- s.sub(/#{delimrstripre}$/, "")
199
- .sub(%r[#{delimrstripre}(</[^>]+>)$], "\\1")
200
- end + [ret.last]
201
- end
202
-
203
- def template_components_prep(delim)
204
- [delim.rstrip, Regexp.quote(delim),
205
- # if delim is esc'd, ignore the escs in the preceding span
206
- Regexp.quote(delim.rstrip.gsub(%r{</?esc>}, ""))]
207
- end
208
-
209
- # need non-breaking spaces in fields: "Updated:_nil" ---
210
- # we want the "Updated:" deleted,
211
- # even if it's multiple words, as in French Mise_à_jour.
212
- def liquid_hash(hash)
213
- case hash
214
- when Hash
215
- hash.map { |k, v| [k.to_s, liquid_hash(v)] }.to_h
216
- when Array
217
- hash.map { |v| liquid_hash(v) }
218
- when String
219
- hash.empty? ? nil : hash.gsub("_", "\\_").tr(" ", "_")
220
- else hash
221
- end
222
- end
223
- end
224
- end
225
- end
226
- end
227
-
228
- require_relative "subclasses"