metanorma 1.7.6 → 2.0.0

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -1
  3. data/lib/metanorma/array_monkeypatch.rb +9 -0
  4. data/lib/metanorma/asciidoctor_extensions/glob_include_processor.rb +13 -11
  5. data/lib/metanorma/collection/collection.rb +225 -0
  6. data/lib/metanorma/collection/config/bibdata.rb +12 -0
  7. data/lib/metanorma/collection/config/compile_options.rb +13 -0
  8. data/lib/metanorma/collection/config/config.rb +163 -0
  9. data/lib/metanorma/collection/config/converters.rb +30 -0
  10. data/lib/metanorma/collection/config/directive.rb +10 -0
  11. data/lib/metanorma/collection/config/manifest.rb +88 -0
  12. data/lib/metanorma/collection/document/document.rb +133 -0
  13. data/lib/metanorma/collection/filelookup/filelookup.rb +250 -0
  14. data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +87 -0
  15. data/lib/metanorma/collection/manifest/manifest.rb +237 -0
  16. data/lib/metanorma/collection/renderer/fileparse.rb +247 -0
  17. data/lib/metanorma/collection/renderer/fileprocess.rb +173 -0
  18. data/lib/metanorma/collection/renderer/navigation.rb +133 -0
  19. data/lib/metanorma/collection/renderer/render_word.rb +133 -0
  20. data/lib/metanorma/collection/renderer/renderer.rb +157 -0
  21. data/lib/metanorma/collection/renderer/utils.rb +183 -0
  22. data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +218 -0
  23. data/lib/metanorma/collection/util/disambig_files.rb +37 -0
  24. data/lib/metanorma/collection/util/util.rb +72 -0
  25. data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +222 -0
  26. data/lib/metanorma/{compile.rb → compile/compile.rb} +17 -11
  27. data/lib/metanorma/{compile_options.rb → compile/compile_options.rb} +9 -5
  28. data/lib/metanorma/{compile_validate.rb → compile/compile_validate.rb} +1 -1
  29. data/lib/metanorma/{extract.rb → compile/extract.rb} +2 -2
  30. data/lib/metanorma/{config.rb → config/config.rb} +1 -1
  31. data/lib/metanorma/input/asciidoc.rb +3 -3
  32. data/lib/metanorma/input/base.rb +1 -5
  33. data/lib/metanorma/processor/processor.rb +54 -0
  34. data/lib/metanorma/processor.rb +1 -49
  35. data/lib/metanorma/{registry.rb → registry/registry.rb} +0 -1
  36. data/lib/metanorma/shale_monkeypatch.rb +15 -0
  37. data/lib/metanorma/util/fontist_helper.rb +130 -0
  38. data/lib/metanorma/util/util.rb +45 -0
  39. data/lib/metanorma/util/worker_pool.rb +39 -0
  40. data/lib/metanorma/version.rb +1 -1
  41. data/lib/metanorma.rb +13 -8
  42. data/metanorma.gemspec +2 -1
  43. metadata +51 -26
  44. data/Gemfile.devel +0 -2
  45. data/lib/metanorma/collection.rb +0 -243
  46. data/lib/metanorma/collection_fileparse.rb +0 -254
  47. data/lib/metanorma/collection_fileprocess.rb +0 -157
  48. data/lib/metanorma/collection_manifest.rb +0 -139
  49. data/lib/metanorma/collection_render_utils.rb +0 -169
  50. data/lib/metanorma/collection_render_word.rb +0 -131
  51. data/lib/metanorma/collection_renderer.rb +0 -230
  52. data/lib/metanorma/document.rb +0 -133
  53. data/lib/metanorma/files_lookup.rb +0 -208
  54. data/lib/metanorma/files_lookup_sectionsplit.rb +0 -84
  55. data/lib/metanorma/fontist_utils.rb +0 -122
  56. data/lib/metanorma/sectionsplit.rb +0 -216
  57. data/lib/metanorma/sectionsplit_links.rb +0 -189
  58. data/lib/metanorma/util.rb +0 -127
  59. data/lib/metanorma/worker_pool.rb +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f574203232cd03cda37b838dadb48b3c1b6a8f5c77e014baa361d520c7849690
4
- data.tar.gz: d13191d73999401fc80e40eac105a1561d7275e423e86eb61a1c6bb29b660145
3
+ metadata.gz: 40466d3eca9782461819ef5828d00dcdc4203e000cc0a6762e658ac75fab81c2
4
+ data.tar.gz: ff68a9e27dd193c8e1263bcb1200f76d87eaf10363ef4c4eb32b9719e9b82eee
5
5
  SHA512:
6
- metadata.gz: 128ccdcbb3366e183dce6e0e2de0a6b68be1275fd5d159ac4c6326daa3be1ceba039e810a65f569260d2315f8e1f295c0a524717b43acc88bafc02b076edf3f9
7
- data.tar.gz: 01562ff056874fb738098f843952a80de45aa71d9bfac65b61209233b8942bb77ab3bc43fbc2572a74e87d68b8e8f9b0002f4a1643853be10d19ecc39206cce4
6
+ metadata.gz: 77388c12e9b2067cd0e319cdacc3ea914984e5185ce130ea5b6dbc893ab4d1d851294b7f3833811235b3952b50c98ad4830614c87a472dac9a26dc644b48f031
7
+ data.tar.gz: 749c67ae8b9c967a0a2446847fb04fc9b045d5f42d4046a66aa79ce0abd5dc373545af2a1520559fa3fb0db4065a51aa2f043fcbe3007b84990ab89b99a286b9
data/Gemfile CHANGED
@@ -6,4 +6,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}" }
6
6
 
7
7
  gemspec
8
8
 
9
- eval_gemfile("Gemfile.devel") rescue nil
9
+ begin
10
+ eval_gemfile("Gemfile.devel")
11
+ rescue StandardError
12
+ nil
13
+ end
@@ -0,0 +1,9 @@
1
+ # TODO sidesteps bibdata redefinition of filter, will remove
2
+
3
+ module Metanorma
4
+ module ArrayMonkeypatch
5
+ class ::Array
6
+ alias filter select
7
+ end
8
+ end
9
+ end
@@ -1,16 +1,18 @@
1
- module Metanorma::AsciidoctorExtensions
2
- class GlobIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
3
- def process(_doc, reader, target_glob, attributes)
4
- Dir[File.join reader.dir, target_glob].sort.reverse_each do |target|
5
- content = IO.readlines target
6
- content.unshift "" unless attributes["adjoin-option"]
7
- reader.push_include content, target, target, 1, attributes
1
+ module Metanorma
2
+ module AsciidoctorExtensions
3
+ class GlobIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
4
+ def process(_doc, reader, target_glob, attributes)
5
+ Dir[File.join reader.dir, target_glob].sort.reverse_each do |target|
6
+ content = File.readlines target
7
+ content.unshift "" unless attributes["adjoin-option"]
8
+ reader.push_include content, target, target, 1, attributes
9
+ end
10
+ reader
8
11
  end
9
- reader
10
- end
11
12
 
12
- def handles?(target)
13
- target.include? "*"
13
+ def handles?(target)
14
+ target.include? "*"
15
+ end
14
16
  end
15
17
  end
16
18
  end
@@ -0,0 +1,225 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "relaton"
4
+ require "relaton/cli"
5
+ require "metanorma-utils"
6
+ require_relative "util/util"
7
+ require_relative "util/disambig_files"
8
+ require_relative "config/config"
9
+ require_relative "config/manifest"
10
+
11
+ module Metanorma
12
+ class FileNotFoundException < StandardError; end
13
+
14
+ class AdocFileNotFoundException < StandardError; end
15
+
16
+ # Metanorma collection of documents
17
+ class Collection
18
+ attr_reader :file
19
+
20
+ # @return [Array<String>] documents-inline to inject the XML into
21
+ # the collection manifest; documents-external to keeps them outside
22
+ attr_accessor :directives, :documents, :bibdatas, :coverpage, :dirname
23
+ attr_accessor :disambig, :manifest, :bibdata, :compile, :config
24
+
25
+ # @param file [String] path to source file
26
+ # @param config [Metanorma::Collection::Config]
27
+ # @param documents [Hash<String, Metanorma::Collection::Document>]
28
+ def initialize(**args)
29
+ @file = args[:file]
30
+ @dirname = File.expand_path(File.dirname(@file)) # feeds @manifest
31
+ @documents = args[:documents] || {} # feeds initialize_directives
32
+ @bibdatas = args[:documents] || {}
33
+ initialize_vars
34
+ initialize_config(args[:config])
35
+ initialize_directives
36
+ @documents.merge! @manifest.documents
37
+ @bibdatas.merge! @manifest.documents
38
+ @documents.transform_keys { |k| Util::key(k) }
39
+ @bibdatas.transform_keys { |k| Util::key(k) }
40
+ end
41
+
42
+ def initialize_vars
43
+ @compile = Metanorma::Compile.new # feeds @manifest
44
+ @log = Metanorma::Utils::Log.new
45
+ @disambig = Util::DisambigFiles.new
46
+ end
47
+
48
+ def initialize_config(config)
49
+ @config = config
50
+ @directives = config.directive || [] # feeds initialize_directives
51
+ @bibdata = config.bibdata
52
+ @prefatory = config.prefatory_content
53
+ @final = config.final_content
54
+ @manifest = ::Metanorma::Collection::Manifest
55
+ .new(config.manifest, self, @dirname) # feeds initialize_directives
56
+ end
57
+
58
+ def initialize_directives
59
+ d = @directives.each_with_object({}) { |x, m| m[x.key] = x.value }
60
+ @coverpage = d["coverpage"]
61
+ @coverpage_style = d["coverpage-style"]
62
+ if (@documents.any? || @manifest) && !d.key?("documents-inline") &&
63
+ !d.key?("documents-external")
64
+ @directives << ::Metanorma::Collection::Config::Directive
65
+ .new(key: "documents-inline")
66
+ end
67
+ end
68
+
69
+ def clean_exit
70
+ @log.write(File.join(@dirname,
71
+ "#{File.basename(@file, '.*')}.err.html"))
72
+ end
73
+
74
+ # @return [String] XML
75
+ def to_xml
76
+ c = ::Metanorma::Collection::Config::Config
77
+ .new(directive: @directives, bibdata: @bibdata,
78
+ manifest: @manifest.config, documents: @documents,
79
+ prefatory_content: @prefatory, final_content: @final)
80
+ c.collection = self
81
+ c.to_xml # .sub("<metanorma-collection", "<metanorma-collection xmlns='http://metanorma.org'")
82
+ end
83
+
84
+ def render(opts)
85
+ ::Metanorma::Collection::Renderer.render self, opts.merge(log: @log)
86
+ clean_exit
87
+ end
88
+
89
+ # @return [String, nil]
90
+ attr_reader :prefatory, :final
91
+
92
+ # @return [String]
93
+ def dummy_header
94
+ <<~DUMMY
95
+ = X
96
+ A
97
+
98
+ DUMMY
99
+ end
100
+
101
+ # @param elm [String] 'prefatory' or 'final'
102
+ # @param builder [Nokogiri::XML::Builder]
103
+ def content_to_xml(elm, builder)
104
+ (cnt = send(elm)) or return
105
+ @compile.load_flavor(doctype)
106
+ out = sections(dummy_header + cnt.strip)
107
+ builder.send("#{elm}-content") { |b| b << out }
108
+ end
109
+
110
+ # @param cnt [String] prefatory/final content
111
+ # @return [String] XML
112
+ def sections(cnt)
113
+ c = Asciidoctor.convert(cnt, backend: doctype.to_sym, header_footer: true)
114
+ Nokogiri::XML(c, &:huge).at("//xmlns:sections").children.to_xml
115
+ end
116
+
117
+ # @param builder [Nokogiri::XML::Builder]
118
+ def doccontainer(builder)
119
+ # Array(@directives).include? "documents-inline" or return
120
+ @directives.detect { |d| d.key == "documents-inline" } or return
121
+ documents.each_with_index do |(_, d), i|
122
+ doccontainer1(builder, d, i)
123
+ end
124
+ end
125
+
126
+ def doccontainer1(builder, doc, idx)
127
+ id = format("doc%<index>09d", index: idx)
128
+ builder.send(:"doc-container", id: id) do |b|
129
+ if doc.attachment
130
+ doc.bibitem and b << doc.bibitem.root.to_xml
131
+ b.attachment Vectory::Utils::datauri(doc.file)
132
+ else
133
+ doc.to_xml b
134
+ end
135
+ end
136
+ end
137
+
138
+ def doctype
139
+ @doctype ||= fetch_doctype || "standoc"
140
+ end
141
+
142
+ def fetch_doctype
143
+ docid = @bibdata.docidentifier.first
144
+ docid or return
145
+ docid.type&.downcase || docid.id&.sub(/\s.*$/, "")&.downcase
146
+ end
147
+
148
+ class << self
149
+ # @param Block [Proc]
150
+ # @note allow user-specific function to run in pre-parse model stage
151
+ def set_pre_parse_model(&block)
152
+ @pre_parse_model_proc = block
153
+ end
154
+
155
+ # @param Block [Proc]
156
+ # @note allow user-specific function to resolve identifier
157
+ def set_identifier_resolver(&block)
158
+ @identifier_resolver = block
159
+ end
160
+
161
+ # @param Block [Proc]
162
+ # @note allow user-specific function to resolve fileref
163
+ # NOTE: MUST ALWAYS RETURN PATH relative to working directory
164
+ # (initial YAML file location). @fileref_resolver.call(ref_folder, fileref)
165
+ # fileref is not what is in the YAML, but the resolved path
166
+ # relative to the working directory
167
+ def set_fileref_resolver(&block)
168
+ @fileref_resolver = block
169
+ end
170
+
171
+ def unset_fileref_resolver
172
+ @fileref_resolver = nil
173
+ end
174
+
175
+ # @param collection_model [Hash{String=>String}]
176
+ def pre_parse_model(collection_model)
177
+ @pre_parse_model_proc or return
178
+ @pre_parse_model_proc.call(collection_model)
179
+ end
180
+
181
+ # @param identifier [String]
182
+ # @return [String]
183
+ def resolve_identifier(identifier)
184
+ @identifier_resolver or return identifier
185
+ @identifier_resolver.call(identifier)
186
+ end
187
+
188
+ # @param fileref [String]
189
+ # @return [String]
190
+ def resolve_fileref(ref_folder, fileref)
191
+ unless @fileref_resolver
192
+ (Pathname.new fileref).absolute? or
193
+ fileref = File.join(ref_folder, fileref)
194
+ return fileref
195
+ end
196
+
197
+ @fileref_resolver.call(ref_folder, fileref)
198
+ end
199
+
200
+ # @param filepath
201
+ # @raise [FileNotFoundException]
202
+ def check_file_existence(filepath)
203
+ unless File.exist?(filepath)
204
+ error_message = "#{filepath} not found!"
205
+ ::Metanorma::Util.log("[metanorma] Error: #{error_message}", :error)
206
+ raise FileNotFoundException.new error_message.to_s
207
+ end
208
+ end
209
+
210
+ def parse(file)
211
+ # need @dirname initialised before collection object initialisation
212
+ @dirname = File.expand_path(File.dirname(file))
213
+ config = case file
214
+ when /\.xml$/
215
+ ::Metanorma::Collection::Config::Config.from_xml(File.read(file))
216
+ when /.ya?ml$/
217
+ y = YAML.safe_load(File.read(file))
218
+ pre_parse_model(y)
219
+ ::Metanorma::Collection::Config::Config.from_yaml(y.to_yaml)
220
+ end
221
+ new(file: file, config: config)
222
+ end
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,12 @@
1
+ require "relaton"
2
+ require "shale"
3
+
4
+ module Metanorma
5
+ class Collection
6
+ module Config
7
+ class Bibdata < ::Shale::Mapper
8
+ model ::RelatonBib::BibliographicItem
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ require "shale"
2
+
3
+ module Metanorma
4
+ class Collection
5
+ module Config
6
+ class CompileOptions < ::Shale::Mapper
7
+ attribute :no_install_fonts, ::Shale::Type::Boolean,
8
+ default: -> { true }
9
+ attribute :agree_to_terms, ::Shale::Type::Boolean, default: -> { true }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,163 @@
1
+ require "shale"
2
+ require_relative "../../shale_monkeypatch"
3
+ require_relative "../../array_monkeypatch"
4
+ require_relative "compile_options"
5
+ require_relative "converters"
6
+ require_relative "bibdata"
7
+ require_relative "directive"
8
+ require_relative "manifest"
9
+
10
+ module Metanorma
11
+ class Collection
12
+ module Config
13
+ require "shale/adapter/nokogiri"
14
+ ::Shale.xml_adapter = ::Shale::Adapter::Nokogiri
15
+
16
+ class Config < ::Shale::Mapper
17
+ attr_accessor :path, :collection, :from_xml
18
+
19
+ attribute :bibdata, Bibdata
20
+ attribute :directive, Directive, collection: true
21
+ attribute :manifest, Manifest
22
+ attribute :format, ::Shale::Type::String, collection: true,
23
+ default: -> { [:html] }
24
+ attribute :output_folder, ::Shale::Type::String
25
+ attribute :coverpage, ::Shale::Type::String, default: -> {
26
+ "cover.html"
27
+ }
28
+ attribute :compile, CompileOptions
29
+ attribute :prefatory_content, ::Shale::Type::String
30
+ attribute :final_content, ::Shale::Type::String
31
+ attribute :documents, Bibdata, collection: true
32
+ attribute :xmlns, ::Shale::Type::String, default: -> { "http://metanorma.org" }
33
+
34
+ yaml do
35
+ map "directives", using: { from: :directives_from_yaml,
36
+ to: :directives_to_yaml }
37
+ map "bibdata", using: { from: :bibdata_from_yaml,
38
+ to: :bibdata_to_yaml }
39
+ map "manifest", to: :manifest
40
+ map "format", to: :format
41
+ map "output_folder", to: :output_folder
42
+ map "coverpage", to: :coverpage
43
+ map "compile", to: :compile
44
+ map "prefatory-content", to: :prefatory_content
45
+ map "final-content", to: :final_content
46
+ end
47
+
48
+ xml do
49
+ root "metanorma-collection"
50
+ # namespace "http://metanorma.org", "m"
51
+ # map_attribute "xmlns", to: :xmlns
52
+ map_element "bibdata", using: { from: :bibdata_from_xml,
53
+ to: :bibdata_to_xml }
54
+ map_element "directive", using: { from: :directive_from_xml,
55
+ to: :directive_to_xml }
56
+ map_element "entry", using: { from: :manifest_from_xml,
57
+ to: :manifest_to_xml }
58
+ map_element "format", to: :format
59
+ map_element "output_folder", to: :output_folder
60
+ map_element "coverpage", to: :coverpage
61
+ map_element "compile", to: :compile
62
+ map_element "prefatory-content", using: { from: :prefatory_from_xml,
63
+ to: :prefatory_to_xml }
64
+ map_element "doc-container",
65
+ using: { from: :documents_from_xml,
66
+ to: :documents_to_xml }
67
+ map_element "final-content", using: { from: :final_from_xml,
68
+ to: :final_to_xml }
69
+ end
70
+
71
+ def manifest_from_xml(model, node)
72
+ model.manifest = Manifest.from_xml(node.to_xml)
73
+ end
74
+
75
+ def manifest_to_xml(model, parent, doc)
76
+ model.collection&.manifest&.clean_manifest(model.manifest)
77
+ doc.add_element(parent, model.manifest.to_xml)
78
+ end
79
+
80
+ def prefatory_from_xml(model, node)
81
+ model.prefatory_content = node.to_xml
82
+ end
83
+
84
+ def prefatory_to_xml(model, parent, doc)
85
+ content_to_xml(model, parent, doc, "prefatory")
86
+ end
87
+
88
+ def final_to_xml(model, parent, doc)
89
+ content_to_xml(model, parent, doc, "final")
90
+ end
91
+
92
+ def content_to_xml(model, parent, doc, type)
93
+ x = model.send("#{type}_content") or return
94
+ n = Nokogiri::XML(x)
95
+ elem = if n.elements.size == 1 then n.root
96
+ else
97
+ b = Nokogiri::XML::Builder.new
98
+ model.collection.content_to_xml(type, b)
99
+ b.parent.elements.first
100
+ end
101
+ doc.add_element(parent, elem)
102
+ end
103
+
104
+ def final_from_xml(model, node)
105
+ model.final_content = node.to_xml
106
+ end
107
+
108
+ def directive_from_xml(model, node)
109
+ model.directive ||= []
110
+ model.directive << Directive.from_xml(node.to_xml)
111
+ end
112
+
113
+ def directive_to_xml(model, parent, doc)
114
+ Array(model.directive).each do |e|
115
+ elem = e.to_xml
116
+ doc.add_element(parent, elem)
117
+ end
118
+ end
119
+
120
+ def directives_from_yaml(model, value)
121
+ model.directive = value&.each_with_object([]) do |v, m|
122
+ m << case v
123
+ when String then Directive.new(key: v)
124
+ when Hash
125
+ k = v.keys.first
126
+ Directive.new(key: k, value: v[k])
127
+ end
128
+ end
129
+ end
130
+
131
+ def directives_to_yaml(model, doc)
132
+ doc["directives"] = model.directive.each_with_object([]) do |d, m|
133
+ m << { d.key => d.value }
134
+ end
135
+ end
136
+
137
+ def documents_from_xml(model, value)
138
+ x = if value.is_a?(Shale::Adapter::Nokogiri::Node)
139
+ value.content
140
+ else Nokogiri::XML(value)
141
+ end
142
+ model.documents = x.xpath(".//bibdata")
143
+ .each_with_object([]) do |b, m|
144
+ m << Bibdata.from_xml(b.to_xml)
145
+ end
146
+ end
147
+
148
+ def documents_to_xml(model, parent, doc)
149
+ b = Nokogiri::XML::Builder.new do |xml|
150
+ xml.document do |m|
151
+ model.collection.doccontainer(m) or return
152
+ end
153
+ end
154
+ b.parent.elements.first.elements.each do |x|
155
+ doc.add_element(parent, x)
156
+ end
157
+ end
158
+
159
+ include Converters
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,30 @@
1
+ require "relaton-cli"
2
+
3
+ module Metanorma
4
+ class Collection
5
+ module Config
6
+ module Converters
7
+ def bibdata_from_yaml(model, value)
8
+ value and !value.empty? or return
9
+ model.bibdata = Relaton::Cli::YAMLConvertor.convert_single_file(value)
10
+ end
11
+
12
+ def bibdata_to_yaml(model, doc)
13
+ doc["bibdata"] = model.bibdata&.to_hash
14
+ end
15
+
16
+ def bibdata_from_xml(model, node)
17
+ model.bibdata = Relaton::Cli.parse_xml(node.content)
18
+ end
19
+
20
+ def bibdata_to_xml(model, parent, doc)
21
+ b = model.bibdata or return
22
+ elem = b.to_xml(bibdata: true, date_format: :full)
23
+ doc.add_element(parent, elem)
24
+ end
25
+
26
+ def nop_to_yaml(model, doc); end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,10 @@
1
+ module Metanorma
2
+ class Collection
3
+ module Config
4
+ class Directive < ::Shale::Mapper
5
+ attribute :key, ::Shale::Type::String
6
+ attribute :value, ::Shale::Type::String
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,88 @@
1
+ require "shale"
2
+ require_relative "../../shale_monkeypatch"
3
+ require_relative "../../array_monkeypatch"
4
+ require_relative "converters"
5
+ require_relative "bibdata"
6
+
7
+ module Metanorma
8
+ class Collection
9
+ module Config
10
+ require "shale/adapter/nokogiri"
11
+ ::Shale.xml_adapter = ::Shale::Adapter::Nokogiri
12
+
13
+ class Manifest < ::Shale::Mapper
14
+ attribute :identifier, ::Shale::Type::String,
15
+ default: -> { UUIDTools::UUID.random_create.to_s }
16
+ attribute :id, ::Shale::Type::String
17
+ attribute :bibdata, Bibdata
18
+ attribute :type, ::Shale::Type::String
19
+ attribute :title, ::Shale::Type::String
20
+ attribute :url, ::Shale::Type::String
21
+ attribute :attachment, ::Shale::Type::Boolean
22
+ attribute :sectionsplit, ::Shale::Type::Boolean
23
+ attribute :index, ::Shale::Type::Boolean, default: -> { true }
24
+ attribute :entry, Manifest, collection: true
25
+ attribute :file, ::Shale::Type::String
26
+
27
+ yaml do
28
+ map "identifier", to: :identifier
29
+ map "type", to: :type
30
+ map "level", using: { from: :level_from_yaml, to: :nop_to_yaml }
31
+ map "title", to: :title
32
+ map "url", to: :url
33
+ map "attachment", to: :attachment
34
+ map "sectionsplit", to: :sectionsplit
35
+ map "index", to: :index
36
+ map "file", to: :file
37
+ map "fileref", using: { from: :fileref_from_yaml, to: :nop_to_yaml }
38
+ map "entry", to: :entry
39
+ map "docref", using: { from: :docref_from_yaml, to: :nop_to_yaml }
40
+ map "manifest", using: { from: :docref_from_yaml, to: :nop_to_yaml }
41
+ map "bibdata", using: { from: :bibdata_from_yaml,
42
+ to: :bibdata_to_yaml }
43
+ end
44
+
45
+ xml do
46
+ root "entry"
47
+ map_attribute "id", to: :id
48
+ map_attribute "attachment", to: :attachment
49
+ map_attribute "sectionsplit", to: :sectionsplit
50
+ map_attribute "index", to: :index
51
+ map_attribute "url", to: :url
52
+ map_attribute "fileref", to: :file
53
+ map_element "identifier", to: :identifier
54
+ map_element "type", to: :type
55
+ map_element "title", to: :title
56
+ map_element "bibdata", using: { from: :bibdata_from_xml,
57
+ to: :bibdata_to_xml }
58
+ map_element "entry", to: :entry # using: { from: :entry_from_xml, to: :entry_to_xml }
59
+ end
60
+
61
+ def entry_from_xml(model, node)
62
+ model.entry = Manifest.from_xml(node.content)
63
+ end
64
+
65
+ def entry_to_xml(model, parent, doc)
66
+ Array(model.entry).each do |e|
67
+ elem = e.to_xml
68
+ doc.add_element(parent, elem)
69
+ end
70
+ end
71
+
72
+ def level_from_yaml(model, value)
73
+ model.type ||= value
74
+ end
75
+
76
+ def fileref_from_yaml(model, value)
77
+ model.file ||= value
78
+ end
79
+
80
+ def docref_from_yaml(model, value)
81
+ model.entry = Manifest.from_yaml(value.to_yaml)
82
+ end
83
+
84
+ include Converters
85
+ end
86
+ end
87
+ end
88
+ end