metanorma 2.2.9 → 2.3.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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +14 -0
  3. data/lib/metanorma/collection/collection.rb +46 -104
  4. data/lib/metanorma/collection/config/config.rb +5 -0
  5. data/lib/metanorma/collection/config/converters.rb +1 -0
  6. data/lib/metanorma/collection/config/manifest.rb +23 -0
  7. data/lib/metanorma/collection/document/document.rb +35 -13
  8. data/lib/metanorma/collection/filelookup/base.rb +43 -0
  9. data/lib/metanorma/collection/filelookup/filelookup.rb +168 -69
  10. data/lib/metanorma/collection/filelookup/filelookup_sectionsplit.rb +49 -10
  11. data/lib/metanorma/collection/filelookup/utils.rb +93 -0
  12. data/lib/metanorma/collection/helpers.rb +82 -0
  13. data/lib/metanorma/collection/manifest/manifest.rb +14 -3
  14. data/lib/metanorma/collection/multilingual/multilingual.rb +1 -1
  15. data/lib/metanorma/collection/renderer/filelocation.rb +162 -0
  16. data/lib/metanorma/collection/renderer/fileparse.rb +9 -6
  17. data/lib/metanorma/collection/renderer/fileprocess.rb +56 -42
  18. data/lib/metanorma/collection/renderer/navigation.rb +15 -1
  19. data/lib/metanorma/collection/renderer/render_word.rb +8 -4
  20. data/lib/metanorma/collection/renderer/renderer.rb +104 -10
  21. data/lib/metanorma/collection/renderer/svg.rb +54 -7
  22. data/lib/metanorma/collection/renderer/utils.rb +58 -22
  23. data/lib/metanorma/collection/sectionsplit/collection.rb +14 -5
  24. data/lib/metanorma/collection/sectionsplit/sectionsplit.rb +20 -7
  25. data/lib/metanorma/collection/util/disambig_files.rb +4 -5
  26. data/lib/metanorma/collection/util/util.rb +106 -6
  27. data/lib/metanorma/collection/xrefprocess/xrefprocess.rb +2 -2
  28. data/lib/metanorma/compile/compile.rb +2 -2
  29. data/lib/metanorma/compile/compile_options.rb +23 -11
  30. data/lib/metanorma/compile/flavor.rb +11 -4
  31. data/lib/metanorma/compile/render.rb +1 -0
  32. data/lib/metanorma/input/asciidoc.rb +1 -1
  33. data/lib/metanorma/util/fontist_helper.rb +5 -6
  34. data/lib/metanorma/version.rb +1 -1
  35. data/metanorma.gemspec +4 -14
  36. metadata +28 -150
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f949939db63522ce80839447f7a4a2c860f2b6c1a8a8bef299bb12e5a375f23c
4
- data.tar.gz: cd92ed471004f16de40d4c0e02bc457a7a2492a4b0a92729a1b36d312eef2672
3
+ metadata.gz: 19c34c2ef752fa708266aa2ace4d50d685ddd1c6089425988c44a6bd597c1c1c
4
+ data.tar.gz: 96b255a5cee296cfce50666c4a9e5f90807c61a2242626d60335e33d435d5570
5
5
  SHA512:
6
- metadata.gz: f85234d7dea81dda16e4c66d1f883666bd1f9b7382ab6bd20770e75f3dc04ad940d78a54a49c2df7dfc25859f1434f5559233ce8c2eb585761397b7fcb0d22af
7
- data.tar.gz: 4bddae518329cebca7cf762666c0d769243524a40c595f3ea7e94db33fad26fc3daaf26598c73a85b3ab12d13cd974a5a89ce7a1548ef679bec00156de8e6608
6
+ metadata.gz: 34240a210ea5f8570f4d3cc422f6fe6e42884dbfef72efb9f19c3087ded496230c5be8565e2d9f3ba2d42d5d7b991da75bad1fa637cc433c5893b86ee41888cb
7
+ data.tar.gz: eba23b08ef0b0eeb3ea6753bd73695ad84702d1ce5a7f1059f480873989f500e30ccd70bd8318f7570429e8d7f13ca6b4d2d4e6fe413c2bfd3799820472039ca
data/Gemfile CHANGED
@@ -11,3 +11,17 @@ begin
11
11
  rescue StandardError
12
12
  nil
13
13
  end
14
+
15
+ gem "debug"
16
+ gem "equivalent-xml"
17
+ #gem "metanorma-iho"
18
+ #gem "metanorma-iso", ">= 3.2.0"
19
+ gem "mnconvert"
20
+ gem "pry"
21
+ gem "rake", "~> 13.0"
22
+ gem "rspec", "~> 3.0"
23
+ gem "rspec-command", "~> 1.0"
24
+ gem "rubocop", "~> 1"
25
+ gem "rubocop-performance"
26
+ gem "sassc-embedded", "~> 1"
27
+ gem "simplecov", "~> 0.15"
@@ -4,6 +4,7 @@ require_relative "util/util"
4
4
  require_relative "util/disambig_files"
5
5
  require_relative "config/config"
6
6
  require_relative "config/manifest"
7
+ require_relative "helpers"
7
8
 
8
9
  module Metanorma
9
10
  class FileNotFoundException < StandardError; end
@@ -12,12 +13,13 @@ module Metanorma
12
13
 
13
14
  # Metanorma collection of documents
14
15
  class Collection
15
- attr_reader :file
16
+ attr_reader :file, :prefatory, :final
16
17
 
17
18
  # @return [Array<String>] documents-inline to inject the XML into
18
19
  # the collection manifest; documents-external to keeps them outside
19
- attr_accessor :directives, :documents, :bibdatas, :coverpage, :dirname
20
- attr_accessor :disambig, :manifest, :bibdata, :compile, :config
20
+ attr_accessor :directives, :documents, :bibdatas, :coverpage,
21
+ :coverpage_pdf_portfolio, :dirname,
22
+ :disambig, :manifest, :bibdata, :compile, :config
21
23
 
22
24
  # @param file [String] path to source file
23
25
  # @param config [Metanorma::Collection::Config]
@@ -64,6 +66,7 @@ module Metanorma
64
66
  def initialize_directives
65
67
  d = @directives.each_with_object({}) { |x, m| m[x.key] = x.value }
66
68
  @coverpage = d["coverpage"]
69
+ @coverpage_pdf_portfolio = d["coverpage-pdf-portfolio"]
67
70
  @coverpage_style = d["coverpage-style"]
68
71
  @flavor = d["flavor"]
69
72
  if (@documents.any? || @manifest) && !d.key?("documents-inline") &&
@@ -109,39 +112,55 @@ module Metanorma
109
112
  warn opts[:output_folder]
110
113
  end
111
114
 
112
- # @return [String, nil]
113
- attr_reader :prefatory, :final
114
-
115
- # @return [String]
116
- def dummy_header
117
- <<~DUMMY
118
- = X
119
- A
120
-
121
- DUMMY
122
- end
123
-
124
115
  # @param elm [String] 'prefatory' or 'final'
125
116
  # @param builder [Nokogiri::XML::Builder]
126
117
  def content_to_xml(elm, builder)
127
118
  (cnt = send(elm)) or return
128
- @compile.load_flavor(flavor)
129
- out = sections(dummy_header + cnt.strip)
119
+ @compile.load_flavor(Util::taste2flavor(flavor))
120
+ out = prefatory_parse(Util::asciidoc_dummy_header + cnt.strip)
130
121
  builder.send("#{elm}-content") { |b| b << out }
131
122
  end
132
123
 
133
124
  # @param cnt [String] prefatory/final content
134
125
  # @return [String] XML
135
- def sections(cnt)
136
- c = Asciidoctor.convert(cnt, backend: flavor.to_sym, header_footer: true)
126
+ def prefatory_parse(cnt)
127
+ x = prefatory_parse_semantic(cnt)
128
+ _, filepath = Util::nokogiri_to_temp(x, "foo", ".presentation.xml")
129
+ c1 = Util::isodoc_create(Util::taste2flavor(@flavor), @manifest.lang,
130
+ @manifest.script, x,
131
+ presxml: true).convert(filepath, nil, true)
132
+ presxml = Nokogiri::XML(c1)
133
+ prefatory_extract_xml(presxml)
134
+ end
135
+
136
+ def prefatory_extract_xml(presxml)
137
+ body = presxml.at("//xmlns:sections")
138
+ body.at("//xmlns:p[@class = 'zzSTDTitle1']")&.remove
139
+ body.text.to_s.strip.empty? and body = presxml.at("//xmlns:preface")
140
+ body.at("//xmlns:clause[@type = 'toc']")&.remove
141
+ body.children.to_xml
142
+ end
143
+
144
+ def prefatory_parse_semantic(cnt)
145
+ c = Asciidoctor.convert(cnt, backend: Util::taste2flavor(flavor).to_sym,
146
+ header_footer: true)
137
147
  x = Nokogiri::XML(c)
138
148
  x.xpath("//xmlns:clause").each { |n| n["unnumbered"] = true }
139
- file = Tempfile.new(%w(foo presentation.xml))
140
- file.write(x.to_xml(indent: 0))
141
- file.close
142
- c1 = Util::isodoc_create(@flavor, @manifest.lang, @manifest.script, x, presxml: true)
143
- .convert(file.path, nil, true)
144
- Nokogiri::XML(c1).at("//xmlns:sections").children.to_xml
149
+ b = x.at("//xmlns:bibdata")
150
+ prefatory_parse_fix_bibdata(b)
151
+ b.children = ::Metanorma::Standoc::Cleanup::MergeBibitems
152
+ .new(b.to_xml, @bibdata.to_xml(bibdata: true)).merge.to_noko.children
153
+ x
154
+ end
155
+
156
+ # Stop standoc ownerless copyright from breaking Relaton parse of bibdata
157
+ def prefatory_parse_fix_bibdata(bibdata)
158
+ if cop = bibdata.at("//xmlns:copyright")
159
+ cop.at("./xmlns:owner") or
160
+ cop.children.first.previous =
161
+ "<owner><organization><name>SDO</name></organization></owner>"
162
+ end
163
+ bibdata
145
164
  end
146
165
 
147
166
  # @param builder [Nokogiri::XML::Builder]
@@ -160,6 +179,7 @@ module Metanorma
160
179
  b.attachment Vectory::Utils::datauri(doc.file)
161
180
  else
162
181
  doc.to_xml b
182
+ b.parent.children.first["flavor"] = Util::taste2flavor(flavor)
163
183
  end
164
184
  end
165
185
  end
@@ -173,89 +193,11 @@ module Metanorma
173
193
  def fetch_flavor
174
194
  docid = @bibdata.docidentifier.first or return
175
195
  f = docid.type.downcase || docid.id.sub(/\s.*$/, "").downcase or return
196
+ f = Util::taste2flavor(f)
176
197
  require ::Metanorma::Compile.new.stdtype2flavor_gem(f)
177
198
  f
178
199
  rescue LoadError
179
200
  nil
180
201
  end
181
-
182
- class << self
183
- # @param Block [Proc]
184
- # @note allow user-specific function to run in pre-parse model stage
185
- def set_pre_parse_model(&block)
186
- @pre_parse_model_proc = block
187
- end
188
-
189
- # @param Block [Proc]
190
- # @note allow user-specific function to resolve identifier
191
- def set_identifier_resolver(&block)
192
- @identifier_resolver = block
193
- end
194
-
195
- # @param Block [Proc]
196
- # @note allow user-specific function to resolve fileref
197
- # NOTE: MUST ALWAYS RETURN PATH relative to working directory
198
- # (initial YAML file location). @fileref_resolver.call(ref_folder, fileref)
199
- # fileref is not what is in the YAML, but the resolved path
200
- # relative to the working directory
201
- def set_fileref_resolver(&block)
202
- @fileref_resolver = block
203
- end
204
-
205
- def unset_fileref_resolver
206
- @fileref_resolver = nil
207
- end
208
-
209
- # @param collection_model [Hash{String=>String}]
210
- def pre_parse_model(collection_model)
211
- @pre_parse_model_proc or return
212
- @pre_parse_model_proc.call(collection_model)
213
- end
214
-
215
- # @param identifier [String]
216
- # @return [String]
217
- def resolve_identifier(identifier)
218
- @identifier_resolver or return identifier
219
- @identifier_resolver.call(identifier)
220
- end
221
-
222
- # @param fileref [String]
223
- # @return [String]
224
- def resolve_fileref(ref_folder, fileref)
225
- warn ref_folder
226
- warn fileref
227
- unless @fileref_resolver
228
- (Pathname.new fileref).absolute? or
229
- fileref = File.join(ref_folder, fileref)
230
- return fileref
231
- end
232
-
233
- @fileref_resolver.call(ref_folder, fileref)
234
- end
235
-
236
- # @param filepath
237
- # @raise [FileNotFoundException]
238
- def check_file_existence(filepath)
239
- unless File.exist?(filepath)
240
- error_message = "#{filepath} not found!"
241
- ::Metanorma::Util.log("[metanorma] Error: #{error_message}", :error)
242
- raise FileNotFoundException.new error_message.to_s
243
- end
244
- end
245
-
246
- def parse(file)
247
- # need @dirname initialised before collection object initialisation
248
- @dirname = File.expand_path(File.dirname(file))
249
- config = case file
250
- when /\.xml$/
251
- ::Metanorma::Collection::Config::Config.from_xml(File.read(file))
252
- when /.ya?ml$/
253
- y = YAML.safe_load(File.read(file))
254
- pre_parse_model(y)
255
- ::Metanorma::Collection::Config::Config.from_yaml(y.to_yaml)
256
- end
257
- new(file: file, config: config)
258
- end
259
- end
260
202
  end
261
203
  end
@@ -20,6 +20,7 @@ module Metanorma
20
20
  attribute :directive, Directive, collection: true
21
21
  attribute :manifest, Manifest
22
22
  attribute :coverpage, :string, default: -> { "cover.html" }
23
+ attribute :coverpage_pdf_portfolio, :string
23
24
  attribute :format, :string, collection: true, default: -> { [:html] }
24
25
  attribute :output_folder, :string
25
26
  attribute :compile, CompileOptions
@@ -37,6 +38,8 @@ module Metanorma
37
38
  map "format", to: :format, render_default: true
38
39
  map "output_folder", to: :output_folder
39
40
  map "coverpage", to: :coverpage, render_default: true
41
+ map "coverpage-pdf-portfolio", to: :coverpage_pdf_portfolio,
42
+ render_default: true
40
43
  map "compile", to: :compile, render_default: true
41
44
  map "prefatory-content", to: :prefatory_content
42
45
  map "final-content", to: :final_content
@@ -54,6 +57,8 @@ module Metanorma
54
57
  map_element "format", to: :format, render_default: true
55
58
  map_element "output_folder", to: :output_folder
56
59
  map_element "coverpage", to: :coverpage, render_default: true
60
+ map_element "coverpage-pdf-portfolio", to: :coverpage_pdf_portfolio,
61
+ render_default: true
57
62
  map_element "compile", to: :compile, render_default: true
58
63
  map_element "prefatory-content",
59
64
  to: :prefatory_content,
@@ -46,6 +46,7 @@ module Metanorma
46
46
  end
47
47
 
48
48
  def nop_to_yaml(model, doc); end
49
+ def nop_to_xml(model, parent, doc); end
49
50
 
50
51
  def documents_from_xml(model, value)
51
52
  model.documents = value
@@ -25,10 +25,15 @@ module Metanorma
25
25
  attribute :index, :boolean, default: -> { true }
26
26
  attribute :entry, Manifest, collection: true
27
27
  attribute :file, :string
28
+ attribute :pdffile, :string
28
29
  attribute :format, :string, collection: true
30
+ attribute :output_filename, :string
31
+ attribute :sectionsplit_filename, :string
32
+ attribute :sectionsplit_output, :boolean
29
33
 
30
34
  yaml do
31
35
  map "identifier", to: :identifier
36
+ map "pdf-file", to: :pdffile
32
37
  map "type", to: :type
33
38
  map "level", to: :level,
34
39
  with: { from: :level_from_yaml, to: :nop_to_yaml }
@@ -48,6 +53,9 @@ module Metanorma
48
53
  map "bibdata", to: :bibdata, with: { from: :bibdata_from_yaml,
49
54
  to: :bibdata_to_yaml }
50
55
  map "format", to: :format, render_default: true
56
+ map "output-filename", to: :output_filename
57
+ map "sectionsplit-filename", to: :sectionsplit_filename
58
+ map "sectionsplit-output", to: :sectionsplit_output
51
59
  end
52
60
 
53
61
  xml do
@@ -57,6 +65,7 @@ module Metanorma
57
65
  map_attribute "sectionsplit", to: :sectionsplit
58
66
  map_attribute "index", to: :index
59
67
  map_attribute "url", to: :url
68
+ map_attribute "pdf-file", to: :pdffile
60
69
  map_attribute "fileref", to: :file
61
70
  map_element "identifier", to: :identifier, render_default: true
62
71
  map_element "type", to: :type
@@ -65,6 +74,12 @@ module Metanorma
65
74
  map_element "bibdata", to: :bibdata, with: { from: :bibdata_from_xml,
66
75
  to: :bibdata_to_xml }
67
76
  map_element "entry", to: :entry
77
+ map_element "output-filename", to: :output_filename,
78
+ with: { from: :output_filename_from_xml,
79
+ to: :nop_to_xml }
80
+ map_element "sectionsplit-filename", to: :sectionsplit_filename,
81
+ with: { from: :sectionsplit_filename_from_xml,
82
+ to: :nop_to_xml }
68
83
  end
69
84
 
70
85
  def entry_from_xml(model, node)
@@ -78,6 +93,14 @@ module Metanorma
78
93
  end
79
94
  end
80
95
 
96
+ def output_filename_from_xml(model, node)
97
+ model.output_filename ||= node.content
98
+ end
99
+
100
+ def sectionsplit_filename_from_xml(model, node)
101
+ model.sectionsplit_filename ||= node.content
102
+ end
103
+
81
104
  def level_from_yaml(model, value)
82
105
  model.type ||= value
83
106
  end
@@ -49,25 +49,47 @@ module Metanorma
49
49
  private
50
50
 
51
51
  def mn2relaton_parser(tag)
52
- case tag.sub(/-standard/, "")
53
- when "bipm" then ::RelatonBipm::XMLParser
54
- when "bsi" then ::RelatonBsi::XMLParser
55
- when "ietf" then ::RelatonIetf::XMLParser
56
- when "iho" then ::RelatonIho::XMLParser
57
- when "itu" then ::RelatonItu::XMLParser
58
- when "iec" then ::RelatonIec::XMLParser
59
- when "iso" then ::RelatonIsoBib::XMLParser
60
- when "nist" then ::RelatonNist::XMLParser
61
- when "ogc" then ::RelatonOgc::XMLParser
62
- else ::RelatonBib::XMLParser
52
+ case tag
53
+ when "bipm"
54
+ require "relaton_bipm" unless defined?(::RelatonBipm::XMLParser)
55
+ ::RelatonBipm::XMLParser
56
+ when "bsi"
57
+ require "relaton_bsi" unless defined?(::RelatonBsi::XMLParser)
58
+ ::RelatonBsi::XMLParser
59
+ when "ietf"
60
+ require "relaton_ietf" unless defined?(::RelatonIetf::XMLParser)
61
+ ::RelatonIetf::XMLParser
62
+ when "iho"
63
+ require "relaton_iho" unless defined?(::RelatonIho::XMLParser)
64
+ ::RelatonIho::XMLParser
65
+ when "itu"
66
+ require "relaton_itu" unless defined?(::RelatonItu::XMLParser)
67
+ ::RelatonItu::XMLParser
68
+ when "iec"
69
+ require "relaton_iec" unless defined?(::RelatonIec::XMLParser)
70
+ ::RelatonIec::XMLParser
71
+ when "iso"
72
+ require "relaton_iso" unless defined?(::RelatonIsoBib::XMLParser)
73
+ ::RelatonIsoBib::XMLParser
74
+ when "nist"
75
+ require "relaton_nist" unless defined?(::RelatonNist::XMLParser)
76
+ ::RelatonNist::XMLParser
77
+ when "ogc"
78
+ require "relaton_ogc" unless defined?(::RelatonOgc::XMLParser)
79
+ ::RelatonOgc::XMLParser
80
+ else
81
+ ::RelatonBib::XMLParser
63
82
  end
83
+ rescue LoadError => e
84
+ warn "Warning: Failed to load relaton gem for '#{tag}': #{e.message}. Falling back to RelatonBib::XMLParser"
85
+ ::RelatonBib::XMLParser
64
86
  end
65
87
 
66
88
  # #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
67
89
  # @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
68
90
  def from_xml(xml)
69
91
  b = xml.at("//xmlns:bibitem|//xmlns:bibdata")
70
- r = mn2relaton_parser(xml.root.name)
92
+ r = mn2relaton_parser(xml.root["flavor"])
71
93
  # Relaton doesn't understand Pres XML tags
72
94
  b.xpath("//xmlns:fmt-identifier").each(&:remove)
73
95
  r.from_xml(b.to_xml)
@@ -127,7 +149,7 @@ module Metanorma
127
149
  if @raw
128
150
  builder.parent.add_child(@bibitem.root)
129
151
  else
130
- builder.send("#{type}-standard") do |b|
152
+ builder.send("metanorma") do |b|
131
153
  b << @bibitem.to_xml(bibdata: true)
132
154
  end
133
155
  end
@@ -0,0 +1,43 @@
1
+ module Metanorma
2
+ class Collection
3
+ class FileLookup
4
+ # are references to the file to be linked to a file in the collection,
5
+ # or externally? Determines whether file suffix anchors are to be used
6
+ def url?(ident)
7
+ data = get(ident) or return false
8
+ data[:url]
9
+ end
10
+
11
+ def key(ident)
12
+ @c.decode(ident).gsub(/(\p{Zs})+/, " ")
13
+ .sub(/^metanorma-collection /, "")
14
+ end
15
+
16
+ def keys
17
+ @files.keys
18
+ end
19
+
20
+ def get(ident, attr = nil)
21
+ if attr then @files[key(ident)][attr]
22
+ else @files[key(ident)]
23
+ end
24
+ end
25
+
26
+ def set(ident, attr, value)
27
+ @files[key(ident)][attr] = value
28
+ end
29
+
30
+ def each
31
+ @files.each
32
+ end
33
+
34
+ def each_with_index
35
+ @files.each_with_index
36
+ end
37
+
38
+ def ns(xpath)
39
+ @isodoc.ns(xpath)
40
+ end
41
+ end
42
+ end
43
+ end