relaton-render 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,152 @@
1
+ require_relative "../utils/utils"
2
+
3
+ module Relaton
4
+ module Render
5
+ class Iso690Template
6
+ def initialize(opt = {})
7
+ opt = Utils::sym_keys(opt)
8
+ @i18n = opt[:i18n]
9
+ @template_raw = opt[:template].dup
10
+ @template =
11
+ case opt[:template]
12
+ when Hash
13
+ opt[:template].transform_values { |x| template_process(x) }
14
+ when Array then opt[:template].map { |x| template_process(x) }
15
+ else { default: template_process(opt[:template]) }
16
+ end
17
+ end
18
+
19
+ # denote start and end of field,
20
+ # so that we can detect empty fields in postprocessing
21
+ FIELD_DELIM = "\u0018".freeze
22
+
23
+ # use tab internally for non-spacing delimiter
24
+ NON_SPACING_DELIM = "\t".freeze
25
+
26
+ def template_process(template)
27
+ t = template.gsub(/\{\{/, "#{FIELD_DELIM}{{")
28
+ .gsub(/\}\}/, "}}#{FIELD_DELIM}")
29
+ .gsub(/\t/, " ")
30
+ t1 = t.split(/(\{\{.+?\}\})/).map do |n|
31
+ n.include?("{{") ? n : n.gsub(/(?<!\\)\|/, "\t")
32
+ end.join
33
+ Liquid::Template.parse(t1)
34
+ end
35
+
36
+ def render(hash)
37
+ template_clean(template_select(hash)
38
+ .render(liquid_hash(hash.merge("labels" => @i18n.get))))
39
+ end
40
+
41
+ def template_select(_hash)
42
+ @template[:default]
43
+ end
44
+
45
+ # use tab internally for non-spacing delimiter
46
+ def template_clean(str)
47
+ str = str.gsub(/\S*#{FIELD_DELIM}#{FIELD_DELIM}\S*/o, "")
48
+ .gsub(/#{FIELD_DELIM}/o, "")
49
+ .gsub(/_/, " ")
50
+ .gsub(/([,:;]\s*)+([,:;](\s|$))/, "\\2")
51
+ .gsub(/([,.:;]\s*)+([.](\s|$))/, "\\2")
52
+ .gsub(/(:\s+)(&\s)/, "\\2")
53
+ .gsub(/\s+([,.:;])/, "\\1")
54
+ .gsub(/#{NON_SPACING_DELIM}/o, "").gsub(/\s+/, " ")
55
+ str.strip
56
+ end
57
+
58
+ def liquid_hash(hash)
59
+ case hash
60
+ when Hash
61
+ hash.map { |k, v| [k.to_s, liquid_hash(v)] }.to_h
62
+ when Array
63
+ hash.map { |v| liquid_hash(v) }
64
+ when String
65
+ hash.empty? ? nil : hash
66
+ else hash
67
+ end
68
+ end
69
+ end
70
+
71
+ class Iso690SeriesTemplate < Iso690Template
72
+ end
73
+
74
+ class Iso690ExtentTemplate < Iso690Template
75
+ def template_select(hash)
76
+ t = @template_raw[hash[:type].to_sym]
77
+ hash.each do |k, _v|
78
+ next unless hash[:orig][k].is_a?(Hash)
79
+
80
+ num = number(hash[:type], hash[:orig][k])
81
+ t = t.gsub(/labels\[['"]extent['"]\]\[['"]#{k}['"]\]/,
82
+ "\\0['#{num}']")
83
+ end
84
+ t = t.gsub(/labels\[['"]extent['"]\]\[['"][^\]'"]+['"]\](?!\[)/,
85
+ "\\0['sg']")
86
+ template_process(t)
87
+ end
88
+
89
+ def number(type, value)
90
+ return "pl" if value[:to]
91
+ return "sg" if %w(article incollection inproceedings inbook)
92
+ .include?(type) || value[:host_title]
93
+
94
+ value[:from] == "1" ? "sg" : "pl"
95
+ end
96
+ end
97
+
98
+ class Iso690NameTemplate < Iso690Template
99
+ def initialize(opt = {})
100
+ @etal_count = opt[:template]["etal_count"]
101
+ opt[:template].delete("etal_count")
102
+ super
103
+ end
104
+
105
+ def template_select(names)
106
+ case names[:surname].size
107
+ when 1 then @template[:one]
108
+ when 2 then @template[:two]
109
+ when 3 then @template[:more]
110
+ else
111
+ if @etal_count && names.size >= @etal_count
112
+ @template[:etal]
113
+ else expand_nametemplate(@template_raw[:more], names.size)
114
+ end
115
+ end
116
+ end
117
+
118
+ # assumes that template contains, consecutively and not interleaved,
119
+ # ...[0], ...[1], ...[2]
120
+ def expand_nametemplate(template, size)
121
+ t = nametemplate_split(template)
122
+ mid = (1..size - 1).each_with_object([]) do |i, m|
123
+ m << t[1].gsub(/\[1\]/, "[#{i}]")
124
+ end
125
+ template_process(t[0] + mid.join + t[2].gsub(/\[2\]/, "[#{size}]"))
126
+ end
127
+
128
+ def nametemplate_split(template)
129
+ curr = 0
130
+ prec = ""
131
+ t = template.split(/(\{\{.+?\}\})/)
132
+ .each_with_object(["", "", ""]) do |n, m|
133
+ m, curr, prec = nametemplate_split1(n, m, curr, prec)
134
+ m
135
+ end
136
+ t[-1] += prec
137
+ t
138
+ end
139
+
140
+ def nametemplate_split1(elem, acc, curr, prec)
141
+ if match = /\{\{.+?\[(\d)\]/.match(elem)
142
+ curr += 1 if match[1].to_i > curr
143
+ acc[curr] += prec
144
+ prec = ""
145
+ acc[curr] += elem
146
+ else prec += elem
147
+ end
148
+ [acc, curr, prec]
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,27 @@
1
+ module Relaton
2
+ module Render
3
+ module Utils
4
+ def self.string_keys(hash)
5
+ case hash
6
+ when Hash
7
+ hash.each_with_object({}) do |(k, v), ret|
8
+ ret[k.to_s] = string_keys(v)
9
+ end
10
+ when Array then hash.map { |n| string_keys(n) }
11
+ else hash
12
+ end
13
+ end
14
+
15
+ def self.sym_keys(hash)
16
+ case hash
17
+ when Hash
18
+ hash.each_with_object({}) do |(k, v), ret|
19
+ ret[k.to_sym] = sym_keys(v)
20
+ end
21
+ when Array then hash.map { |n| sym_keys(n) }
22
+ else hash
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "relaton/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "relaton-render"
7
+ spec.version = Relaton::Render::VERSION
8
+ spec.authors = ["Ribose Inc."]
9
+ spec.email = ["open.source@ribose.com"]
10
+
11
+ spec.summary = "Rendering of ISO 690 XML"
12
+ spec.description = "Rendering of ISO 690 XML"
13
+ spec.homepage = "https://github.com/relaton/relaton-render"
14
+ spec.license = "BSD-2-Clause"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
23
+
24
+ spec.add_development_dependency "bundler"
25
+ spec.add_development_dependency "debug"
26
+ spec.add_development_dependency "equivalent-xml", "~> 0.6"
27
+ spec.add_development_dependency "rake", ">= 12.3.3"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ spec.add_development_dependency "simplecov"
30
+
31
+ spec.add_dependency "isodoc-i18n"
32
+ spec.add_dependency "liquid", "~> 4"
33
+ spec.add_dependency "nokogiri"
34
+ spec.add_dependency "twitter_cldr"
35
+ end
metadata ADDED
@@ -0,0 +1,213 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: relaton-render
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ribose Inc.
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: debug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: equivalent-xml
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 12.3.3
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 12.3.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: isodoc-i18n
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: liquid
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '4'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '4'
125
+ - !ruby/object:Gem::Dependency
126
+ name: nokogiri
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: twitter_cldr
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Rendering of ISO 690 XML
154
+ email:
155
+ - open.source@ribose.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".github/workflows/rake.yml"
161
+ - ".hound.yml"
162
+ - ".rubocop.yml"
163
+ - Gemfile
164
+ - LICENSE.txt
165
+ - README.adoc
166
+ - Rakefile
167
+ - bin/console
168
+ - bin/rspec
169
+ - bin/setup
170
+ - lib/isodoc-yaml/i18n-ar.yaml
171
+ - lib/isodoc-yaml/i18n-de.yaml
172
+ - lib/isodoc-yaml/i18n-en.yaml
173
+ - lib/isodoc-yaml/i18n-es.yaml
174
+ - lib/isodoc-yaml/i18n-fr.yaml
175
+ - lib/isodoc-yaml/i18n-ru.yaml
176
+ - lib/isodoc-yaml/i18n-zh-Hans.yaml
177
+ - lib/isodoc/i18n.rb
178
+ - lib/parse/parse.rb
179
+ - lib/parse/parse_contributors.rb
180
+ - lib/parse/parse_extract.rb
181
+ - lib/relaton-render.rb
182
+ - lib/relaton/config.yml
183
+ - lib/relaton/render.rb
184
+ - lib/relaton/render_classes.rb
185
+ - lib/relaton/render_fields.rb
186
+ - lib/relaton/version.rb
187
+ - lib/template/template.rb
188
+ - lib/utils/utils.rb
189
+ - relaton-render.gemspec
190
+ homepage: https://github.com/relaton/relaton-render
191
+ licenses:
192
+ - BSD-2-Clause
193
+ metadata: {}
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: 2.5.0
203
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ requirements: []
209
+ rubygems_version: 3.3.9
210
+ signing_key:
211
+ specification_version: 4
212
+ summary: Rendering of ISO 690 XML
213
+ test_files: []