metanorma-core 0.2.1 → 0.2.2

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: 314a93ed63df1389dfb3e950e63d7ebff4ccf3c1a0e1698d678ddb898ab9fc47
4
- data.tar.gz: 4ef731b709d7f26820209291edea8d576992d457f0161dae1cc3d4c810433f5f
3
+ metadata.gz: 7e0fe54371f36297eba65fd7cea8649359c7ca0f50195f388d48c82266bc220f
4
+ data.tar.gz: a18e98b49080a74314677f7aae1b382ae64083e4b9ce21c773959cc9e94439b2
5
5
  SHA512:
6
- metadata.gz: 03ed6bb9d50427ca61a7659458c8e154329566a968e3cf80f9bf4a9e46c859358bbab811ab1d76481f13797525f6651e80fb2d565eeb0408f41979ae10658c1b
7
- data.tar.gz: 5e69aa811a9385a9938e0707a37334c51929e880633b707fe32590c599787ebe2bd8c5fc6d96e08d948da149079d7bbf52a119441ca27e3d504279286c76ca10
6
+ metadata.gz: 6d0a9c5cc7e45bbdfd7c4eafda1028e66c8a904c7d7550d95248d966034215a3a2a2baee6a7bcf54b9aedab8ae984e11e4751f70f4bd9fbff8319bdca56f18f7
7
+ data.tar.gz: 4b0244d3496a619dccc2dd2ae4dbfb449b84a86949bd51d052c486a148ba2f321643cfd1fb00c857061ded783fb532c6734fbfe34282e11f3bbb5bdc8d62dd2d
data/.rubocop.yml CHANGED
@@ -1,8 +1,31 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
1
3
  inherit_from:
2
4
  - https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
5
+ # .rubocop_todo.yml MUST be the last entry. inherit_from is last-wins:
6
+ # if listed before oss-guides, the shared config's stricter Metrics/
7
+ # (MethodLength, BlockLength, etc.) rules override the todo's per-file
8
+ # grandfathering, and the todo becomes inert on those cops. Empirically
9
+ # verified on suma 2026-07-06: with todo listed first, 34 Metrics/* offenses
10
+ # remained; moved last, cleared. Every gem in the metanorma-org fleet
11
+ # already ships a `.rubocop_todo.yml` on its live tree (audited 2026-07-06,
12
+ # 54/54 have it), so this reference is safe to emit unconditionally.
13
+ - .rubocop_todo.yml
14
+
15
+ # Rubocop plugins enabled centrally so every metanorma-org gem picks them up
16
+ # on cimas sync — best practice belongs at the shared-template layer, not
17
+ # per-repo. Per ronaldtse feedback on metanorma/ci#332.
18
+ plugins:
19
+ - rubocop-rspec
20
+ - rubocop-performance
21
+ - rubocop-rake
3
22
 
4
23
  # local repo-specific modifications
5
24
  # ...
6
25
 
7
26
  AllCops:
8
- TargetRubyVersion: 3.4
27
+ # 3.3 matches the org-wide minimum being pushed via #274 (Raise minimum
28
+ # Ruby version to 3.3 due to EOL of 3.2 on 2026-03-31). Was 3.4 before
29
+ # this commit — 3.4 was above the org's stated minimum and would have
30
+ # applied Rubocop rules that fail-close on gems still targeting 3.3.
31
+ TargetRubyVersion: 3.3
data/Gemfile CHANGED
@@ -7,5 +7,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}" }
7
7
  gemspec
8
8
 
9
9
  gem "gem-release"
10
+ # top-level, not the gemspec development group: the release job installs
11
+ # without development/test, and bundle exec rake release needs rake
12
+ gem "rake"
10
13
 
11
14
  eval_gemfile("Gemfile.devel") rescue nil
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  module Core
3
- VERSION = "0.2.1".freeze
3
+ VERSION = "0.2.2".freeze
4
4
  end
5
5
  end
@@ -115,7 +115,7 @@ module Metanorma
115
115
  # attribute is bare (no value).
116
116
  EMPTY_ADOC_OPTIONS_DEFAULT_FALSE =
117
117
  %w(hierarchical-assets break-up-urls-in-tables toc-figures
118
- toc-tables toc-recommendations).freeze
118
+ toc-tables toc-recommendations toc-examples).freeze
119
119
 
120
120
  # Convert an Asciidoc-style attribute name (kebab-case, possibly
121
121
  # ending in +-override+ or +-pdf+) into the Ruby symbol used in
@@ -43,6 +43,33 @@ module Metanorma
43
43
  }
44
44
  end
45
45
 
46
+ # Per-format "document model" publishing specs. Override in a flavor to
47
+ # register injected reader + transformer classes for a document-model
48
+ # output leg (Presentation/Semantic XML -> reader -> transformer -> XML),
49
+ # so the flavor declares two classes rather than re-implementing the
50
+ # read/transform/serialise chain in {#output}. The classes need not live
51
+ # in the +Metanorma::+ tree.
52
+ #
53
+ # Each value is a Hash with keys:
54
+ # :reader - responds to +.from_xml(String)+ -> model
55
+ # (required)
56
+ # :transformer - responds to +.new(model, options)+; the
57
+ # instance responds to +#transform+ -> target,
58
+ # and the target responds to +#to_xml+
59
+ # (required)
60
+ # :to_xml_options - Hash splatted into +target.to_xml(**opts)+
61
+ # (default +{}+)
62
+ # :strip_default_namespace - strip +xmlns="..."+ before +from_xml+
63
+ # (default +false+)
64
+ # :post_process - callable +(xml, transformer, options)+
65
+ # -> xml (default identity)
66
+ #
67
+ # @return [Hash{Symbol => Hash}] format symbol -> spec. Empty by default,
68
+ # so flavors that do not use this leg are unaffected.
69
+ def document_transformers
70
+ {}
71
+ end
72
+
46
73
  # Convert an input file to Metanorma semantic XML by routing it
47
74
  # through the {Metanorma::Input::Asciidoc} processor with this
48
75
  # processor's Asciidoctor backend. Override for non-Asciidoc
@@ -87,19 +114,75 @@ module Metanorma
87
114
  options[:output_formats] ||= output_formats
88
115
  end
89
116
 
90
- # Default output-writer: dump the rendered output string to a
91
- # UTF-8 file. Override for binary formats (Word, PDF) that need
92
- # different post-processing.
117
+ # Default output-writer. If +format+ is registered in
118
+ # {#document_transformers}, render it through the document-model leg
119
+ # ({#render_via_document_model}); otherwise dump the rendered output
120
+ # string to a UTF-8 file. Flavors override this for binary formats
121
+ # (Word, PDF) that need different post-processing, calling +super+ for
122
+ # the document-model and passthrough cases.
93
123
  #
94
- # @param isodoc_node [String] rendered output content.
95
- # @param _inname [String] source filename (unused at this base level).
124
+ # @param isodoc_node [String, nil] rendered output content, or the
125
+ # semantic XML string on the document-model semantic leg.
126
+ # @param inname [String] source filename.
96
127
  # @param outname [String] destination path.
97
- # @param _format [Symbol] output format (unused at this base level).
98
- # @param _options [Hash] processor options (unused at this base level).
99
- # @return [Integer] bytes written (Ruby's +File#write+ return).
100
- def output(isodoc_node, _inname, outname, _format, _options = {})
101
- File.open(outname, "w:UTF-8") { |f| f.write(isodoc_node) }
128
+ # @param format [Symbol] output format.
129
+ # @param options [Hash] processor options.
130
+ # @return [Object] bytes written (passthrough) or the serialised XML
131
+ # string (document-model leg).
132
+ def output(isodoc_node, inname, outname, format, options = {})
133
+ options_preprocess(options)
134
+ if document_transformers.key?(format)
135
+ render_via_document_model(isodoc_node, inname, outname, format,
136
+ options)
137
+ else
138
+ File.open(outname, "w:UTF-8") { |f| f.write(isodoc_node) }
139
+ end
140
+ end
141
+
142
+ # Render a document-model output leg: read the input XML into a model via
143
+ # the registered reader, transform it, serialise, optionally post-process,
144
+ # and write. The input XML comes from +isodoc_node+ (semantic leg) or,
145
+ # when that is nil, from reading +inname+ (presentation leg) — so both
146
+ # {#use_presentation_xml} settings are supported transparently. The driver
147
+ # is duck-typed: it never names a concrete reader/transformer/target-model
148
+ # gem, keeping those out of metanorma-core's dependencies.
149
+ #
150
+ # @param isodoc_node [String, nil] semantic XML string, or nil on the
151
+ # presentation leg.
152
+ # @param inname [String] input filename (read on the presentation leg).
153
+ # @param outname [String, nil] destination path; written when non-nil.
154
+ # @param format [Symbol] output-format symbol; must be a key of
155
+ # {#document_transformers}.
156
+ # @param options [Hash] processor options, passed to the transformer and
157
+ # post-processor.
158
+ # @return [String] the serialised (and post-processed) output XML.
159
+ def render_via_document_model(isodoc_node, inname, outname, format, options)
160
+ spec = document_transformers.fetch(format)
161
+ xml = document_model_input_xml(isodoc_node, inname)
162
+ xml = xml.gsub(/\sxmlns="[^"]*"/, "") if spec[:strip_default_namespace]
163
+ transformer = spec.fetch(:transformer)
164
+ .new(spec.fetch(:reader).from_xml(xml), options)
165
+ out = transformer.transform.to_xml(**(spec[:to_xml_options] || {}))
166
+ if (post = spec[:post_process])
167
+ out = post.call(out, transformer, options)
168
+ end
169
+ File.open(outname, "w:UTF-8") { |f| f.write(out) } if outname
170
+ out
171
+ end
172
+
173
+ # Resolve the input XML string from whichever leg fired: the semantic
174
+ # leg passes the XML as +isodoc_node+; the presentation leg passes nil
175
+ # and the presentation-XML file path as +inname+.
176
+ #
177
+ # @param isodoc_node [String, nil] semantic XML string, or nil.
178
+ # @param inname [String] presentation-XML file path (used when node nil).
179
+ # @return [String] the input XML.
180
+ def document_model_input_xml(isodoc_node, inname)
181
+ return isodoc_node if isodoc_node
182
+
183
+ File.read(inname, encoding: "UTF-8")
102
184
  end
185
+ private :document_model_input_xml
103
186
 
104
187
  # Read processor-relevant options from the input file's header
105
188
  # via {Metanorma::Input::Asciidoc#extract_options}, merging in
@@ -23,10 +23,10 @@ Gem::Specification.new do |spec|
23
23
  f.match(%r{^(test|spec|features|bin|.github)/}) \
24
24
  || f.match(%r{Rakefile|bin/rspec})
25
25
  end
26
- spec.required_ruby_version = Gem::Requirement.new(">= 3.1.0")
26
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.3.0")
27
27
 
28
28
  spec.add_dependency "asciidoctor"
29
- spec.add_dependency "metanorma-taste", "~> 1.0.0"
29
+ spec.add_dependency "metanorma-taste", "~> 1.1.0"
30
30
  spec.add_dependency "metanorma-utils"
31
31
  spec.add_dependency "nokogiri"
32
32
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-25 00:00:00.000000000 Z
11
+ date: 2026-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.0
33
+ version: 1.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.0.0
40
+ version: 1.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: metanorma-utils
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -192,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
192
192
  requirements:
193
193
  - - ">="
194
194
  - !ruby/object:Gem::Version
195
- version: 3.1.0
195
+ version: 3.3.0
196
196
  required_rubygems_version: !ruby/object:Gem::Requirement
197
197
  requirements:
198
198
  - - ">="