rfcxml 0.4.2 → 0.4.4

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: 503aee54b71c3f54fdb6b0fe202b6b4d444e6b8e9a37f9a764e4fe1c6a579bdb
4
- data.tar.gz: 320c1c22d864595249496e13b7b65ed1d85c5dc39f9e2d3659a8d21b9189a911
3
+ metadata.gz: b07f133b9638c1df8c2361ff54f3ee361e2fd2e8c2681f018794899453d3bde1
4
+ data.tar.gz: 3d0c2e184d39e1e8ed0485b7ebc782eb4942ae0cf90e2315d5d628794ec3ea20
5
5
  SHA512:
6
- metadata.gz: ffb1d8ec0b4fadc8e8935de090d0b4761f5b1a485d0327eaba7262368199fcac2fb49a6aafd019eecdbb0e6bf6436fc428faaef5eb3ce96d9f4a9b84a60145e4
7
- data.tar.gz: c30eabc921018fbc976275e344c0e95c20607af406ab26c4e5edd0f6d73bae4d03a8b18da099e6d82648797c7b57bb15b9477c45558c84ad9ae23445ff46f1e4
6
+ metadata.gz: 0b233d9d03d7d0ec1a3ca548d2d8c35e89025a6609beca56f4db3c2cd815c7de3f7ed6b37fc2bd9309fcc04e35b066d490788adb8e90b78d0deea6efe56a45c4
7
+ data.tar.gz: fc11ed7f9524f70aaa629bd8246dcdd83454f34766d043683b213519f6d467fa1ff9b188f77ae82527eb93fb2781476446916ab16b9f42ae2e6bcd326d88ac13
@@ -59,21 +59,12 @@ jobs:
59
59
  run: |
60
60
  echo "Testing all RFC XML files..."
61
61
  ruby scripts/roundtrip_test.rb "$XML_DIR"
62
- continue-on-error: true
63
- id: roundtrip
64
62
 
65
63
  - name: Upload test results
66
64
  if: always()
67
65
  uses: actions/upload-artifact@v4
68
66
  with:
69
67
  name: roundtrip-results
70
- path: |
71
- *.log
68
+ path: tmp/roundtrip-results-*/
72
69
  retention-days: 30
73
- if-no-files-found: ignore
74
-
75
- - name: Check results
76
- if: steps.roundtrip.outcome == 'failure'
77
- run: |
78
- echo "::error::Some RFC XML files failed round-trip testing"
79
- exit 1
70
+ if-no-files-found: warn
data/.gitignore CHANGED
@@ -14,3 +14,5 @@
14
14
  .rspec_status
15
15
 
16
16
  Gemfile.lock
17
+ TODO*
18
+ .claude/worktrees/
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-04-22 22:54:22 UTC using RuboCop version 1.86.1.
3
+ # on 2026-05-01 09:55:57 UTC using RuboCop version 1.86.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -11,7 +11,40 @@ Gemspec/RequiredRubyVersion:
11
11
  Exclude:
12
12
  - 'rfcxml.gemspec'
13
13
 
14
- # Offense count: 20
14
+ # Offense count: 1
15
+ # This cop supports safe autocorrection (--autocorrect).
16
+ # Configuration parameters: EnforcedStyleAlignWith.
17
+ # SupportedStylesAlignWith: either, start_of_block, start_of_line
18
+ Layout/BlockAlignment:
19
+ Exclude:
20
+ - 'spec/v3/cref_spec.rb'
21
+
22
+ # Offense count: 1
23
+ # This cop supports safe autocorrection (--autocorrect).
24
+ Layout/BlockEndNewline:
25
+ Exclude:
26
+ - 'spec/v3/cref_spec.rb'
27
+
28
+ # Offense count: 4
29
+ # This cop supports safe autocorrection (--autocorrect).
30
+ # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
31
+ # SupportedHashRocketStyles: key, separator, table
32
+ # SupportedColonStyles: key, separator, table
33
+ # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
34
+ Layout/HashAlignment:
35
+ Exclude:
36
+ - 'lib/rfcxml/v3/td.rb'
37
+ - 'spec/v3/rfc_pi_spec.rb'
38
+
39
+ # Offense count: 2
40
+ # This cop supports safe autocorrection (--autocorrect).
41
+ # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
42
+ # SupportedStylesAlignWith: start_of_line, relative_to_receiver
43
+ Layout/IndentationWidth:
44
+ Exclude:
45
+ - 'spec/v3/cref_spec.rb'
46
+
47
+ # Offense count: 28
15
48
  # This cop supports safe autocorrection (--autocorrect).
16
49
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
17
50
  # URISchemes: http, https
@@ -20,7 +53,17 @@ Layout/LineLength:
20
53
  - 'lib/rfcxml/v3/li.rb'
21
54
  - 'lib/rfcxml/v3/rfc.rb'
22
55
  - 'scripts/roundtrip_test.rb'
56
+ - 'spec/v3/cref_spec.rb'
23
57
  - 'spec/v3/document_creation_spec.rb'
58
+ - 'spec/v3/rfc_pi_spec.rb'
59
+ - 'spec/v3/td_spec.rb'
60
+
61
+ # Offense count: 2
62
+ # This cop supports safe autocorrection (--autocorrect).
63
+ # Configuration parameters: AllowInHeredoc.
64
+ Layout/TrailingWhitespace:
65
+ Exclude:
66
+ - 'spec/v3/rfc_pi_spec.rb'
24
67
 
25
68
  # Offense count: 4
26
69
  Lint/NoReturnInBeginEndBlocks:
@@ -59,31 +102,51 @@ Metrics/PerceivedComplexity:
59
102
  - 'lib/rfcxml/v3/rfc.rb'
60
103
  - 'scripts/roundtrip_test.rb'
61
104
 
105
+ # Offense count: 1
106
+ # Configuration parameters: MinSize.
107
+ Performance/CollectionLiteralInLoop:
108
+ Exclude:
109
+ - 'scripts/roundtrip_test.rb'
110
+
62
111
  # Offense count: 1
63
112
  # Configuration parameters: IgnoredMetadata.
64
113
  RSpec/DescribeClass:
65
114
  Exclude:
66
115
  - 'spec/v3/document_creation_spec.rb'
67
116
 
68
- # Offense count: 11
117
+ # Offense count: 20
69
118
  # Configuration parameters: CountAsOne.
70
119
  RSpec/ExampleLength:
71
120
  Max: 29
72
121
 
73
- # Offense count: 11
122
+ # Offense count: 25
74
123
  RSpec/MultipleExpectations:
75
124
  Max: 9
76
125
 
77
- # Offense count: 3
126
+ # Offense count: 6
78
127
  # Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
79
128
  # SupportedInflectors: default, active_support
80
129
  RSpec/SpecFilePathFormat:
81
130
  Exclude:
82
131
  - 'spec/v3/author_spec.rb'
132
+ - 'spec/v3/cref_spec.rb'
133
+ - 'spec/v3/rfc_pi_spec.rb'
83
134
  - 'spec/v3/rfc_spec.rb'
84
135
  - 'spec/v3/section_spec.rb'
136
+ - 'spec/v3/td_spec.rb'
85
137
 
86
138
  # Offense count: 1
87
139
  Security/Open:
88
140
  Exclude:
89
141
  - 'Rakefile'
142
+
143
+ # Offense count: 1
144
+ # This cop supports safe autocorrection (--autocorrect).
145
+ # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
146
+ # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
147
+ # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
148
+ # FunctionalMethods: let, let!, subject, watch
149
+ # AllowedMethods: lambda, proc, it
150
+ Style/BlockDelimiters:
151
+ Exclude:
152
+ - 'spec/v3/cref_spec.rb'
data/CLAUDE.md ADDED
@@ -0,0 +1,84 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ **rfcxml** is a Ruby gem for parsing and generating IETF RFC XML v3 documents. It is part of the Metanorma ecosystem and provides bidirectional XML serialization using the lutaml-model framework.
8
+
9
+ ## Development Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ bundle install
14
+
15
+ # Run all checks (tests + linting)
16
+ bundle exec rake
17
+
18
+ # Run tests only
19
+ bundle exec rake spec
20
+ bundle exec rspec # Run specific test file
21
+ bundle exec rspec spec/v3/rfc_spec.rb
22
+
23
+ # Run linting only
24
+ bundle exec rake rubocop
25
+ bundle exec rubocop --autocorrect # Auto-fix violations
26
+
27
+ # Interactive development console
28
+ bin/console
29
+ ```
30
+
31
+ ## Architecture
32
+
33
+ ### Core Framework: lutaml-model
34
+
35
+ All XML elements are modeled as classes inheriting from `Lutaml::Model::Serializable`. This provides ActiveRecord-like serialization for XML with a declarative DSL:
36
+
37
+ ```ruby
38
+ class SomeElement < Lutaml::Model::Serializable
39
+ attribute :name, :string
40
+ attribute :child, ChildClass, collection: true
41
+
42
+ xml do
43
+ element "element-name"
44
+ map_attribute "name", to: :name
45
+ map_element "child", to: :child
46
+ end
47
+ end
48
+ ```
49
+
50
+ ### Module Structure
51
+
52
+ - `Rfcxml::V3` namespace contains all RFC XML v3 element models
53
+ - Each XML element has its own file in `lib/rfcxml/v3/`
54
+ - Models require their dependencies directly (e.g., `Rfc` requires `Front`, `Middle`, `Back`)
55
+
56
+ ### Document Hierarchy
57
+
58
+ ```
59
+ Rfc (root)
60
+ ├── Front (metadata: title, authors, date, abstract)
61
+ ├── Middle (body: sections)
62
+ └── Back (references, appendices)
63
+ ```
64
+
65
+ ### Mixed Content
66
+
67
+ Some elements like `Section` support mixed content (text interspersed with child elements). Use `mixed: true` in the root declaration:
68
+
69
+ ```ruby
70
+ xml do
71
+ element "section"
72
+ mixed_content
73
+ end
74
+ ```
75
+
76
+ ## Reference Schema
77
+
78
+ The `reference-docs/` directory contains the official RFC XML v3 schema files:
79
+ - `v3.rnc` - RelaxNG compact syntax (authoritative)
80
+ - `v3.xsd` - XML Schema Definition
81
+
82
+ ## Testing
83
+
84
+ Tests perform round-trip parsing: parse XML → serialize back → verify valid XML structure using the `canon` gem for semantic comparison.
@@ -5,7 +5,7 @@ require "lutaml/model"
5
5
  module Rfcxml
6
6
  module V3
7
7
  class Blockquote < Lutaml::Model::Serializable
8
- attribute :content, :string
8
+ attribute :content, :string, collection: true
9
9
  attribute :anchor, :string
10
10
  attribute :pn, :string
11
11
  attribute :cite, :string
@@ -34,7 +34,7 @@ module Rfcxml
34
34
 
35
35
  xml do
36
36
  element "blockquote"
37
- ordered
37
+ mixed_content
38
38
 
39
39
  map_content to: :content
40
40
  map_attribute "anchor", to: :anchor
data/lib/rfcxml/v3/c.rb CHANGED
@@ -5,7 +5,7 @@ require "lutaml/model"
5
5
  module Rfcxml
6
6
  module V3
7
7
  class C < Lutaml::Model::Serializable
8
- attribute :content, :string
8
+ attribute :content, :string, collection: true
9
9
  attribute :cref, Cref, collection: true
10
10
  attribute :eref, Eref, collection: true
11
11
  attribute :iref, Iref, collection: true
@@ -14,7 +14,7 @@ module Rfcxml
14
14
 
15
15
  xml do
16
16
  element "c"
17
- ordered
17
+ mixed_content
18
18
 
19
19
  map_content to: :content
20
20
  map_element "cref", to: :cref
@@ -5,7 +5,7 @@ require "lutaml/model"
5
5
  module Rfcxml
6
6
  module V3
7
7
  class Cref < Lutaml::Model::Serializable
8
- attribute :content, :string
8
+ attribute :content, :string, collection: true
9
9
  attribute :anchor, :string
10
10
  attribute :source, :string
11
11
  attribute :display, :string, default: -> { "true" }
@@ -13,15 +13,15 @@ module Rfcxml
13
13
  attribute :em, Em, collection: true
14
14
  attribute :eref, Eref, collection: true
15
15
  attribute :relref, Relref, collection: true
16
- attribute :strong, Strong, collection: true
17
- attribute :sub, Sub, collection: true
18
- attribute :sup, Sup, collection: true
19
- attribute :tt, Tt, collection: true
16
+ attribute :strong, "Rfcxml::V3::Strong", collection: true
17
+ attribute :sub, "Rfcxml::V3::Sub", collection: true
18
+ attribute :sup, "Rfcxml::V3::Sup", collection: true
19
+ attribute :tt, "Rfcxml::V3::Tt", collection: true
20
20
  attribute :xref, Xref, collection: true
21
21
 
22
22
  xml do
23
23
  element "cref"
24
- ordered
24
+ mixed_content
25
25
 
26
26
  map_content to: :content
27
27
  map_attribute "anchor", to: :anchor
data/lib/rfcxml/v3/dt.rb CHANGED
@@ -5,7 +5,7 @@ require "lutaml/model"
5
5
  module Rfcxml
6
6
  module V3
7
7
  class Dt < Lutaml::Model::Serializable
8
- attribute :content, :string
8
+ attribute :content, :string, collection: true
9
9
  attribute :anchor, :string
10
10
  attribute :pn, :string
11
11
  attribute :bcp14, Bcp14, collection: true
@@ -23,7 +23,7 @@ module Rfcxml
23
23
 
24
24
  xml do
25
25
  element "dt"
26
- ordered
26
+ mixed_content
27
27
 
28
28
  map_content to: :content
29
29
  map_attribute "anchor", to: :anchor
@@ -5,7 +5,7 @@ require "lutaml/model"
5
5
  module Rfcxml
6
6
  module V3
7
7
  class Postamble < Lutaml::Model::Serializable
8
- attribute :content, :string
8
+ attribute :content, :string, collection: true
9
9
  attribute :cref, Cref, collection: true
10
10
  attribute :eref, Eref, collection: true
11
11
  attribute :iref, Iref, collection: true
@@ -14,7 +14,7 @@ module Rfcxml
14
14
 
15
15
  xml do
16
16
  element "postamble"
17
- ordered
17
+ mixed_content
18
18
 
19
19
  map_content to: :content
20
20
  map_element "cref", to: :cref
@@ -5,7 +5,7 @@ require "lutaml/model"
5
5
  module Rfcxml
6
6
  module V3
7
7
  class Preamble < Lutaml::Model::Serializable
8
- attribute :content, :string
8
+ attribute :content, :string, collection: true
9
9
  attribute :bcp14, Bcp14, collection: true
10
10
  attribute :cref, Cref, collection: true
11
11
  attribute :em, Em, collection: true
@@ -22,7 +22,7 @@ module Rfcxml
22
22
 
23
23
  xml do
24
24
  element "preamble"
25
- ordered
25
+ mixed_content
26
26
 
27
27
  map_content to: :content
28
28
  map_element "bcp14", to: :bcp14
@@ -5,13 +5,13 @@ require "lutaml/model"
5
5
  module Rfcxml
6
6
  module V3
7
7
  class Refcontent < Lutaml::Model::Serializable
8
- attribute :content, :string
8
+ attribute :content, :string, collection: true
9
9
  attribute :bcp14, Bcp14, collection: true
10
10
  include XrefText
11
11
 
12
12
  xml do
13
13
  element "refcontent"
14
- ordered
14
+ mixed_content
15
15
 
16
16
  map_content to: :content
17
17
  map_element "bcp14", to: :bcp14
data/lib/rfcxml/v3/rfc.rb CHANGED
@@ -48,6 +48,7 @@ module Rfcxml
48
48
  attribute :front, Front
49
49
  attribute :middle, Middle
50
50
  attribute :back, Back
51
+ attribute :pi_settings, :hash
51
52
 
52
53
  xml do
53
54
  element "rfc"
@@ -80,6 +81,8 @@ module Rfcxml
80
81
  %w[link front middle back].each do |element|
81
82
  map_element element, to: element.to_sym
82
83
  end
84
+
85
+ map_processing_instruction "rfc", to: :pi_settings
83
86
  end
84
87
 
85
88
  # Override to_xml to fix SVG elements
@@ -4,7 +4,7 @@ require "lutaml/model"
4
4
  module Rfcxml
5
5
  module V3
6
6
  class Strong < Lutaml::Model::Serializable
7
- attribute :content, :string
7
+ attribute :content, :string, collection: true
8
8
  attribute :bcp14, Bcp14, collection: true
9
9
  attribute :br, Br, collection: true
10
10
  attribute :cref, Cref, collection: true
@@ -19,7 +19,7 @@ module Rfcxml
19
19
 
20
20
  xml do
21
21
  element "strong"
22
- ordered
22
+ mixed_content
23
23
 
24
24
  map_content to: :content
25
25
  map_element "bcp14", to: :bcp14
data/lib/rfcxml/v3/sub.rb CHANGED
@@ -5,7 +5,7 @@ require "lutaml/model"
5
5
  module Rfcxml
6
6
  module V3
7
7
  class Sub < Lutaml::Model::Serializable
8
- attribute :content, :string
8
+ attribute :content, :string, collection: true
9
9
  attribute :bcp14, Bcp14, collection: true
10
10
  attribute :cref, Cref, collection: true
11
11
  attribute :em, "Rfcxml::V3::Em", collection: true
@@ -20,7 +20,7 @@ module Rfcxml
20
20
 
21
21
  xml do
22
22
  element "sub"
23
- ordered
23
+ mixed_content
24
24
 
25
25
  map_content to: :content
26
26
  map_element "bcp14", to: :bcp14
data/lib/rfcxml/v3/sup.rb CHANGED
@@ -7,7 +7,7 @@ module Rfcxml
7
7
  class Sup < Sub
8
8
  xml do
9
9
  element "sup"
10
- ordered
10
+ mixed_content
11
11
 
12
12
  map_content to: :content
13
13
  map_element "bcp14", to: :bcp14
data/lib/rfcxml/v3/td.rb CHANGED
@@ -12,22 +12,6 @@ module Rfcxml
12
12
  attribute :align, :string,
13
13
  values: %w[left center right]
14
14
 
15
- # Normalize empty string colspan/rowspan to nil.
16
- # Schema default for colspan/rowspan is "1", so empty string should not
17
- # be serialized as an attribute. This ensures round-trip comparison
18
- # treats rowspan="" (in source) as equivalent to absent rowspan.
19
- module ColspanRowspanNormalizer
20
- def colspan=(value)
21
- super(value.to_s.empty? ? nil : value)
22
- end
23
-
24
- def rowspan=(value)
25
- super(value.to_s.empty? ? nil : value)
26
- end
27
- end
28
-
29
- prepend ColspanRowspanNormalizer
30
-
31
15
  attribute :artset, Artset, collection: true
32
16
  attribute :artwork, Artwork, collection: true
33
17
  attribute :dl, Dl, collection: true
@@ -56,8 +40,10 @@ module Rfcxml
56
40
 
57
41
  map_content to: :content
58
42
  map_attribute "anchor", to: :anchor
59
- map_attribute "colspan", to: :colspan
60
- map_attribute "rowspan", to: :rowspan
43
+ map_attribute "colspan", to: :colspan,
44
+ value_map: { to: { empty: :empty } }
45
+ map_attribute "rowspan", to: :rowspan,
46
+ value_map: { to: { empty: :empty } }
61
47
  map_attribute "align", to: :align
62
48
 
63
49
  %w[artset artwork dl figure ol sourcecode t ul bcp14 br cref em eref
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rfcxml
4
- VERSION = "0.4.2"
4
+ VERSION = "0.4.4"
5
5
  end
@@ -38,6 +38,10 @@ class RoundTripTester
38
38
 
39
39
  attr_reader :results_dir
40
40
 
41
+ def failed?
42
+ @results.any? { |r| %i[fail error].include?(r[:status]) }
43
+ end
44
+
41
45
  def initialize(files:, threads: DEFAULT_THREADS, verbose: false)
42
46
  @files = files
43
47
  @threads = threads
@@ -358,4 +362,6 @@ if __FILE__ == $PROGRAM_NAME
358
362
 
359
363
  tester = RoundTripTester.new(**options)
360
364
  tester.run
365
+
366
+ exit 1 if tester.failed?
361
367
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rfcxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-27 00:00:00.000000000 Z
11
+ date: 2026-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -52,6 +52,7 @@ files:
52
52
  - ".rspec"
53
53
  - ".rubocop.yml"
54
54
  - ".rubocop_todo.yml"
55
+ - CLAUDE.md
55
56
  - CODE_OF_CONDUCT.md
56
57
  - Gemfile
57
58
  - README.adoc