metanorma 2.2.1 → 2.2.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d66c44fc8123332b449ee23540a8e0d009aa19b5a34f408bca97375f85223b0
4
- data.tar.gz: 0227a49a94646c2bd0197fb5d49eabc237a6eb51350809a3f8436c601f41d41c
3
+ metadata.gz: ab41d7fdd92143add890202f0e64c0c88216c7936e603a0efd7a41df02b833c3
4
+ data.tar.gz: '09fc660fdf0eddeb88ee0094560113a2d05504767c0b6c220a63be6be7e80eea'
5
5
  SHA512:
6
- metadata.gz: 503d2edd8d015e341949ab4de920abb7668bc1b13fb7d97697026fddad1ab11d9f94138257cffdd3b57ac32873d606cbe05689bcf8b9e8f7fb3baa19289a7d76
7
- data.tar.gz: 41ba35a1a2ad8d740c9b7e3409f0297665c1746e3e461d2b26e2b203d66b09e26fc6bc9f1afebbe26134806a699ac8aa36350d28548629a08a2ae036aa3aa0e3
6
+ metadata.gz: 82c0f8b50777b5cf34262690a6e860d189c5eecf4b5365375ef24872e847d8c04d4624731155407d89b86d3d6839ce0295b3c3c44d76a350139555ff3c8d47fa
7
+ data.tar.gz: a7f8736e34eb0bc5ab76092ab9eeaae682f1058d52f634bc8d06f45cfa26982ef97813584430af5eb262317b6fdde7baf065c2c077645727f4a32dd569974479
data/README.adoc CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  image:https://img.shields.io/gem/v/metanorma.svg["Gem Version", link="https://rubygems.org/gems/metanorma"]
4
4
  image:https://github.com/metanorma/metanorma/workflows/rake/badge.svg["Build Status", link="https://github.com/metanorma/metanorma/actions?workflow=rake"]
5
- image:https://codeclimate.com/github/metanorma/metanorma/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/metanorma"]
5
+ // image:https://codeclimate.com/github/metanorma/metanorma/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/metanorma"]
6
6
  image:https://img.shields.io/github/issues-pr-raw/metanorma/metanorma.svg["Pull Requests", link="https://github.com/metanorma/metanorma/pulls"]
7
7
  image:https://img.shields.io/github/commits-since/metanorma/metanorma/latest.svg["Commits since latest",link="https://github.com/metanorma/metanorma/releases"]
8
8
 
@@ -26,7 +26,6 @@ module Metanorma
26
26
  @disambig = Util::DisambigFiles.new
27
27
  @manifest = parent.manifest
28
28
  read_files(@manifest.entry, parent.manifest)
29
- #warn pp @files
30
29
  end
31
30
 
32
31
  def read_files(entries, parent)
@@ -11,7 +11,6 @@ module Metanorma
11
11
  # warn "metanorma compile -x html #{f.path}"
12
12
  def file_compile(file, filename, identifier)
13
13
  @files.get(identifier, :sectionsplit) and return
14
- #require "debug"; binding.b
15
14
  opts = {
16
15
  format: :asciidoc,
17
16
  extension_keys: @files.get(identifier, :format),
@@ -181,9 +181,12 @@ module Metanorma
181
181
  # collection manifest
182
182
  def coverpage
183
183
  @coverpage or return
184
+
185
+ @coverpage_path = Util::rel_path_resolve(@dirname, @coverpage)
184
186
  warn "\n\n\n\n\nCoverpage: #{DateTime.now.strftime('%H:%M:%S')}"
187
+
185
188
  File.open(File.join(@outdir, "index.html"), "w:UTF-8") do |f|
186
- f.write @isodoc.populate_template(File.read(@coverpage))
189
+ f.write @isodoc.populate_template(File.read(@coverpage_path))
187
190
  end
188
191
  end
189
192
  end
@@ -11,21 +11,31 @@ module Metanorma
11
11
  end
12
12
 
13
13
  def svgmap_resolve(docxml, docid, presxml)
14
+ ids, docxml, isodoc, tag = svgmap_resolve_prep(docxml, docid, presxml)
15
+ docxml.xpath(ns("//svgmap//#{tag}")).each do |e|
16
+ svgmap_resolve_eref(e, isodoc, docxml, ids, presxml)
17
+ end
18
+ svgmap_fmt_prefix_remove(docxml)
19
+ Vectory::SvgMapping.new(docxml, "").call
20
+ docxml.xpath(ns("//svgmap")).each { |s| isodoc.svgmap_extract(s) }
21
+ end
22
+
23
+ def svgmap_resolve_prep(docxml, docid, presxml)
14
24
  ids = @files.get(docid, :ids)
15
25
  docxml = svg_unnest(svg_datauri(docxml, docid))
16
26
  isodoc = IsoDoc::PresentationXMLConvert.new({})
17
27
  isodoc.bibitem_lookup(docxml)
18
28
  tag = presxml ? "fmt-eref" : "eref"
19
- docxml.xpath(ns("//svgmap//#{tag}")).each do |e|
20
- svgmap_resolve_eref(e, isodoc, docxml, ids, presxml)
21
- end
22
- docxml.xpath(ns("//svgmap/target")).each do |t| # undo Presentation XML: Vectory takes eref not fmt-eref
29
+ [ids, docxml, isodoc, tag]
30
+ end
31
+
32
+ # undo Presentation XML update: Vectory takes eref not fmt-eref
33
+ def svgmap_fmt_prefix_remove(docxml)
34
+ docxml.xpath(ns("//svgmap/target")).each do |t|
23
35
  n = t.at(ns(".//fmt-link | .//fmt-xref | .//fmt-eref")) or next
24
36
  n.name = n.name.sub(/^fmt-/, "")
25
37
  t.children = n
26
38
  end
27
- Vectory::SvgMapping.new(docxml, "").call
28
- docxml.xpath(ns("//svgmap")).each { |s| isodoc.svgmap_extract(s) }
29
39
  end
30
40
 
31
41
  def svg_unnest(docxml)
@@ -72,7 +72,7 @@ module Metanorma
72
72
  def block?(node)
73
73
  %w(p table formula admonition ol ul dl figure quote sourcecode example
74
74
  pre note pagebreak hr bookmark requirement recommendation permission
75
- svgmap inputform toc passthrough review imagemap).include?(node.name)
75
+ svgmap inputform toc passthrough annotation imagemap).include?(node.name)
76
76
  end
77
77
 
78
78
  def conflate_floatingtitles(nodes)
@@ -151,7 +151,7 @@ module Metanorma
151
151
  def create_sectionfile(xml, out, file, chunks, parentnode)
152
152
  ins = out.at(ns("//metanorma-extension")) || out.at(ns("//bibdata"))
153
153
  sectionfile_insert(ins, chunks, parentnode)
154
- sectionfile_fn_filter(sectionfile_review_filter(out))
154
+ sectionfile_fn_filter(sectionfile_annotation_filter(out))
155
155
  Metanorma::Collection::XrefProcess::xref_process(out, xml, @key,
156
156
  @ident, @isodoc, true)
157
157
  outname = "#{file}.xml"
@@ -211,34 +211,35 @@ module Metanorma
211
211
  fnlabel.children = @isodoc_presxml.fn_body_label(fnbody)
212
212
  end
213
213
 
214
- # map fmt-review-body/@id = fmt-review-{start/end}/@target
215
- # to fmt-review-{stary/end}
216
- def sectionfile_review_filter_prep(xml)
217
- xml.xpath(ns("//fmt-review-start | //fmt-review-end"))
214
+ # map fmt-annotation-body/@id = fmt-annotation-{start/end}/@target
215
+ # to fmt-annotation-{start/end}
216
+ def sectionfile_annotation_filter_prep(xml)
217
+ xml.xpath(ns("//fmt-annotation-start | //fmt-annotation-end"))
218
218
  .each_with_object({}) do |f, m|
219
219
  m[f["target"]] ||= []
220
220
  m[f["target"]] << f
221
221
  end
222
222
  end
223
223
 
224
- def sectionfile_review_filter(xml)
225
- ids = sectionfile_review_filter_prep(xml)
226
- xml.root.xpath(ns("./review-container/fmt-review-body")).each do |f|
224
+ def sectionfile_annotation_filter(xml)
225
+ ids = sectionfile_annotation_filter_prep(xml)
226
+ xml.root.xpath(ns("./annotation-container/fmt-annotation-body"))
227
+ .each do |f|
227
228
  ids.has_key?(f["id"]) or f.remove
228
229
  end
229
- xml.root.xpath(ns("./review-container/fmt-review-body"))
230
+ xml.root.xpath(ns("./annotation-container/fmt-annotation-body"))
230
231
  .each_with_index do |fnbody, i|
231
- sectionfile_review_filter_renumber(fnbody, i, ids)
232
+ sectionfile_annotation_filter_renumber(fnbody, i, ids)
232
233
  end
233
234
  xml
234
235
  end
235
236
 
236
- def sectionfile_review_filter_renumber(fnbody, _idx, ids)
237
+ def sectionfile_annotation_filter_renumber(fnbody, _idx, ids)
237
238
  ids[fnbody["id"]].each do |f|
238
239
  case f.name
239
- when "fmt-review-start"
240
+ when "fmt-annotation-start"
240
241
  f.children = @isodoc_presxml.comment_bookmark_start_label(f)
241
- when "fmt-review-end"
242
+ when "fmt-annotation-end"
242
243
  f.children = @isodoc_presxml.comment_bookmark_end_label(f)
243
244
  end
244
245
  end
@@ -184,7 +184,7 @@ module Metanorma
184
184
  end
185
185
 
186
186
  def process_input_adoc_overrides(attrs, options)
187
- @registry.tastes.available_tastes.include?(options[:supplied_type]) or
187
+ Metanorma::TasteRegister.instance.available_tastes.include?(options[:supplied_type]) or
188
188
  return
189
189
  c = Metanorma::TasteRegister.get(options[:supplied_type])
190
190
  c.process_input_adoc_overrides(attrs, options)
@@ -36,8 +36,8 @@ module Metanorma
36
36
  # @param xml [Nokogiri::XML::Document] the XML document
37
37
  # @return [String] the cleaned sourcecode
38
38
  def clean_sourcecode(xml)
39
- xml.xpath(".//callout | .//annotation | .//xmlns:callout | "\
40
- ".//xmlns:annotation").each(&:remove)
39
+ xml.xpath(".//callout | .//callout-annotation | .//xmlns:callout | "\
40
+ ".//xmlns:callout-annotation").each(&:remove)
41
41
  xml.xpath(".//br | .//xmlns:br").each { |x| x.replace("\n") }
42
42
  a = xml.at("./body | ./xmlns:body") and xml = a
43
43
  HTMLEntities.new.decode(xml.children.to_xml)
@@ -7,45 +7,160 @@ class Error < StandardError
7
7
  end
8
8
 
9
9
  module Metanorma
10
+ # Central registry for managing Metanorma processors, flavors, and their aliases
11
+ #
12
+ # This singleton class provides a centralized registry for:
13
+ # - Metanorma processors (document format processors)
14
+ # - Flavor aliases (mapping legacy/alternative names to canonical flavors)
15
+ # - Taste configurations (via TasteRegister integration)
16
+ #
17
+ # The registry maintains backward compatibility with legacy flavor names while
18
+ # integrating with the modern TasteRegister system for dynamic taste management.
19
+ #
20
+ # @example Basic usage
21
+ # registry = Metanorma::Registry.instance
22
+ #
23
+ # # Register a processor
24
+ # registry.register(MyProcessor)
25
+ #
26
+ # # Look up flavor aliases
27
+ # registry.alias(:csd) # => :cc
28
+ #
29
+ # # Register custom aliases
30
+ # registry.register_alias(:my_flavor, :iso)
31
+ #
32
+ # @example Finding processors
33
+ # processor = registry.find_processor(:iso)
34
+ # formats = registry.output_formats
35
+ # backends = registry.supported_backends
10
36
  class Registry
11
37
  include Singleton
12
38
 
13
39
  attr_reader :processors, :tastes
14
40
 
15
- # TODO: make aliases configurable
41
+ # Default legacy aliases for backward compatibility
42
+ # Maps old flavor names to their canonical equivalents
43
+ DEFAULT_ALIASES = { csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa }.freeze
44
+
45
+ # Initialize the registry with processors, tastes, and aliases
46
+ #
47
+ # Sets up the registry by:
48
+ # 1. Initializing empty processors hash
49
+ # 2. Connecting to the TasteRegister instance
50
+ # 3. Initializing custom aliases with defaults
16
51
  def initialize
17
52
  @processors = {}
18
53
  @tastes = Metanorma::TasteRegister.instance
19
- tastealiases = @tastes.available_tastes.each_with_object({}) do |x, m|
20
- m[x] = @tastes.taste_info(x)[:base_flavor]
21
- end
22
- @aliases = { csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa }
23
- .merge tastealiases
54
+ @custom_aliases = DEFAULT_ALIASES.dup
24
55
  end
25
56
 
57
+ # Look up the canonical flavor name for a given alias
58
+ #
59
+ # Checks aliases in priority order:
60
+ # 1. Custom registered aliases (highest priority)
61
+ # 2. Taste-based aliases from TasteRegister
62
+ # 3. Returns nil if no alias found
63
+ #
64
+ # @param flavour [Symbol, String, nil] The flavor alias to look up
65
+ # @return [Symbol, nil] The canonical flavor name, or nil if no alias exists
66
+ #
67
+ # @example
68
+ # registry.alias(:csd) # => :cc (from DEFAULT_ALIASES)
69
+ # registry.alias(:icc) # => :iso (from taste configuration)
70
+ # registry.alias(:unknown) # => nil
71
+ # registry.alias(nil) # => nil
26
72
  def alias(flavour)
27
- @aliases[flavour]
73
+ return nil if flavour.nil?
74
+
75
+ flavour_sym = flavour.to_sym
76
+
77
+ # Check custom aliases first (includes defaults)
78
+ return @custom_aliases[flavour_sym] if @custom_aliases.key?(flavour_sym)
79
+
80
+ # Then check taste aliases
81
+ taste_aliases = @tastes.aliases
82
+ taste_aliases[flavour_sym]
83
+ end
84
+
85
+ # Register a custom alias mapping
86
+ #
87
+ # Allows runtime registration of flavor aliases. Custom aliases take precedence
88
+ # over taste-based aliases, allowing overrides of taste configurations.
89
+ #
90
+ # @param alias_name [Symbol, String] The alias name to register
91
+ # @param target_flavor [Symbol, String] The canonical flavor it should map to
92
+ #
93
+ # @example
94
+ # registry.register_alias(:my_custom, :iso)
95
+ # registry.alias(:my_custom) # => :iso
96
+ #
97
+ # # Override a taste alias
98
+ # registry.register_alias(:icc, :custom_iso)
99
+ def register_alias(alias_name, target_flavor)
100
+ @custom_aliases[alias_name.to_sym] = target_flavor.to_sym
28
101
  end
29
102
 
103
+ # Register a Metanorma processor
104
+ #
105
+ # Registers a processor class and automatically creates aliases for all its
106
+ # short names. The last short name is considered the canonical name.
107
+ #
108
+ # @param processor [Class] A processor class that inherits from Metanorma::Processor
109
+ # @raise [Error] If the processor doesn't inherit from Metanorma::Processor
110
+ # @return [Array<Symbol>] Array of short names for the processor
111
+ #
112
+ # @example
113
+ # registry.register(Metanorma::ISO::Processor)
114
+ # # Registers processor and creates aliases for all its short names
30
115
  def register(processor)
31
- processor < ::Metanorma::Processor or raise Error
32
- p = processor.new
33
- # p.short[-1] is the canonical name
34
- short = Array(p.short)
35
- @processors[short[-1]] = p
36
- short.each { |s| @aliases[s] = short[-1] }
37
- Array(p.short)
38
- Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered", :info)
116
+ unless processor < ::Metanorma::Processor
117
+ raise Error, "Processor must inherit from Metanorma::Processor"
118
+ end
119
+
120
+ # The last short name is the canonical name
121
+ processor_instance = processor.new
122
+ short_names = Array(processor_instance.short)
123
+ canonical_name = short_names.last
124
+
125
+ # Register processor with canonical name
126
+ @processors[canonical_name] = processor_instance
127
+
128
+ # Create aliases for all short names pointing to canonical name
129
+ short_names.each { |name| @custom_aliases[name] = canonical_name }
130
+
131
+ Util.log("[metanorma] processor \"#{short_names.first}\" registered", :info)
132
+ short_names
39
133
  end
40
134
 
135
+ # Find a registered processor by its short name
136
+ #
137
+ # @param short [Symbol, String] The short name of the processor to find
138
+ # @return [Metanorma::Processor, nil] The processor instance, or nil if not found
139
+ #
140
+ # @example
141
+ # processor = registry.find_processor(:iso)
142
+ # processor = registry.find_processor("iso")
41
143
  def find_processor(short)
42
144
  @processors[short.to_sym]
43
145
  end
44
146
 
147
+ # Get list of all supported backend names
148
+ #
149
+ # @return [Array<Symbol>] Array of registered processor backend names
150
+ #
151
+ # @example
152
+ # registry.supported_backends # => [:iso, :iec, :itu, ...]
45
153
  def supported_backends
46
154
  @processors.keys
47
155
  end
48
156
 
157
+ # Get output formats supported by each registered processor
158
+ #
159
+ # @return [Hash<Symbol, Hash>] Hash mapping processor names to their output formats
160
+ #
161
+ # @example
162
+ # registry.output_formats
163
+ # # => { iso: { html: "html", pdf: "pdf", ... }, iec: { ... }, ... }
49
164
  def output_formats
50
165
  @processors.inject({}) do |acc, (k, v)|
51
166
  acc[k] = v.output_formats
@@ -53,6 +168,13 @@ module Metanorma
53
168
  end
54
169
  end
55
170
 
171
+ # Get XML root tags for processors with Asciidoctor backends
172
+ #
173
+ # @return [Hash<Symbol, String>] Hash mapping processor names to their XML root tags
174
+ #
175
+ # @example
176
+ # registry.root_tags
177
+ # # => { iso: "iso-standard", iec: "iec-standard", ... }
56
178
  def root_tags
57
179
  @processors.inject({}) do |acc, (k, v)|
58
180
  if v.asciidoctor_backend
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "2.2.1".freeze
2
+ VERSION = "2.2.3".freeze
3
3
  end
data/metanorma.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_runtime_dependency "fontist", ">= 1.14.3"
30
30
  spec.add_runtime_dependency "htmlentities"
31
31
  spec.add_runtime_dependency "isodoc", ">= 3.0.0"
32
- spec.add_runtime_dependency "metanorma-taste"
32
+ spec.add_runtime_dependency "metanorma-taste", "~> 0.1.0"
33
33
  spec.add_runtime_dependency "mn2pdf", "~> 2"
34
34
  spec.add_runtime_dependency "nokogiri"
35
35
 
@@ -38,7 +38,7 @@ Gem::Specification.new do |spec|
38
38
  # spec.add_dependency "metanorma-standoc"
39
39
 
40
40
  spec.add_development_dependency "debug"
41
- spec.add_development_dependency "equivalent-xml", "~> 0.6"
41
+ spec.add_development_dependency "equivalent-xml"
42
42
  spec.add_development_dependency "metanorma-iso"
43
43
  spec.add_development_dependency "mnconvert"
44
44
  spec.add_development_dependency "pry"
@@ -49,5 +49,5 @@ Gem::Specification.new do |spec|
49
49
  spec.add_development_dependency "rubocop-performance"
50
50
  spec.add_development_dependency "sassc-embedded", "~> 1"
51
51
  spec.add_development_dependency "simplecov", "~> 0.15"
52
- spec.add_development_dependency "xml-c14n"
52
+ spec.add_development_dependency "canon"
53
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-23 00:00:00.000000000 Z
11
+ date: 2025-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: metanorma-taste
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: 0.1.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: 0.1.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: mn2pdf
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -140,16 +140,16 @@ dependencies:
140
140
  name: equivalent-xml
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
143
+ - - ">="
144
144
  - !ruby/object:Gem::Version
145
- version: '0.6'
145
+ version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - "~>"
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
- version: '0.6'
152
+ version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: metanorma-iso
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -291,7 +291,7 @@ dependencies:
291
291
  - !ruby/object:Gem::Version
292
292
  version: '0.15'
293
293
  - !ruby/object:Gem::Dependency
294
- name: xml-c14n
294
+ name: canon
295
295
  requirement: !ruby/object:Gem::Requirement
296
296
  requirements:
297
297
  - - ">="