coradoc 2.0.27 → 2.0.29

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/lib/coradoc/cli.rb +9 -6
  3. data/lib/coradoc/configurable.rb +6 -3
  4. data/lib/coradoc/coradoc.rb +5 -2
  5. data/lib/coradoc/core_model/attribute_reference_resolver.rb +19 -7
  6. data/lib/coradoc/core_model/base.rb +45 -2
  7. data/lib/coradoc/core_model/comment_line.rb +1 -1
  8. data/lib/coradoc/core_model/definition_item.rb +22 -1
  9. data/lib/coradoc/core_model/horizontal_rule_block.rb +4 -0
  10. data/lib/coradoc/core_model/include_level_offset.rb +1 -1
  11. data/lib/coradoc/core_model/include_options.rb +1 -0
  12. data/lib/coradoc/core_model/inline_content.rb +1 -0
  13. data/lib/coradoc/core_model/list_block.rb +1 -1
  14. data/lib/coradoc/core_model/listing_block.rb +4 -0
  15. data/lib/coradoc/core_model/literal_block.rb +4 -0
  16. data/lib/coradoc/core_model/pass_block.rb +4 -0
  17. data/lib/coradoc/core_model/source_block.rb +4 -0
  18. data/lib/coradoc/core_model/stem_block.rb +4 -0
  19. data/lib/coradoc/dispatch.rb +1 -0
  20. data/lib/coradoc/errors.rb +19 -0
  21. data/lib/coradoc/format_catalog.rb +19 -0
  22. data/lib/coradoc/format_module.rb +10 -0
  23. data/lib/coradoc/hooks.rb +1 -1
  24. data/lib/coradoc/include_selectors/level_offset.rb +0 -2
  25. data/lib/coradoc/include_selectors/lines.rb +2 -2
  26. data/lib/coradoc/include_selectors/tags.rb +2 -4
  27. data/lib/coradoc/introspection/element_counter.rb +2 -2
  28. data/lib/coradoc/link_rewriter/visitor.rb +5 -14
  29. data/lib/coradoc/pipeline.rb +64 -5
  30. data/lib/coradoc/query.rb +8 -8
  31. data/lib/coradoc/reference/address/anchor.rb +48 -0
  32. data/lib/coradoc/reference/address/doi.rb +40 -0
  33. data/lib/coradoc/reference/address/isbn.rb +39 -0
  34. data/lib/coradoc/reference/address/path.rb +66 -0
  35. data/lib/coradoc/reference/address/scoped_path.rb +47 -0
  36. data/lib/coradoc/reference/address/url.rb +41 -0
  37. data/lib/coradoc/reference/address.rb +153 -0
  38. data/lib/coradoc/reference/catalog/composite.rb +59 -0
  39. data/lib/coradoc/reference/catalog/local.rb +97 -0
  40. data/lib/coradoc/reference/catalog/memory_index.rb +59 -0
  41. data/lib/coradoc/reference/catalog.rb +33 -0
  42. data/lib/coradoc/reference/edge/citation_options.rb +16 -0
  43. data/lib/coradoc/reference/edge/footnote_ref_options.rb +13 -0
  44. data/lib/coradoc/reference/edge/image_ref_options.rb +15 -0
  45. data/lib/coradoc/reference/edge/include_options.rb +15 -0
  46. data/lib/coradoc/reference/edge/kind.rb +72 -0
  47. data/lib/coradoc/reference/edge/link_options.rb +12 -0
  48. data/lib/coradoc/reference/edge/navigation_options.rb +12 -0
  49. data/lib/coradoc/reference/edge/options.rb +13 -0
  50. data/lib/coradoc/reference/edge.rb +80 -0
  51. data/lib/coradoc/reference/edge_search.rb +128 -0
  52. data/lib/coradoc/reference/materializer/base.rb +44 -0
  53. data/lib/coradoc/reference/materializer/passthrough.rb +31 -0
  54. data/lib/coradoc/reference/materializer/registry.rb +116 -0
  55. data/lib/coradoc/reference/materializer.rb +14 -0
  56. data/lib/coradoc/reference/presentation/base.rb +47 -0
  57. data/lib/coradoc/reference/presentation/custom_hierarchy.rb +104 -0
  58. data/lib/coradoc/reference/presentation/page.rb +20 -0
  59. data/lib/coradoc/reference/presentation/single_document.rb +35 -0
  60. data/lib/coradoc/reference/presentation/split_pages.rb +118 -0
  61. data/lib/coradoc/reference/presentation.rb +16 -0
  62. data/lib/coradoc/reference/resolution.rb +184 -0
  63. data/lib/coradoc/reference/resolver/base.rb +15 -0
  64. data/lib/coradoc/reference/resolver/caching.rb +37 -0
  65. data/lib/coradoc/reference/resolver/catalog.rb +69 -0
  66. data/lib/coradoc/reference/resolver/chain.rb +33 -0
  67. data/lib/coradoc/reference/resolver.rb +20 -0
  68. data/lib/coradoc/reference/result/ambiguous.rb +23 -0
  69. data/lib/coradoc/reference/result/base.rb +46 -0
  70. data/lib/coradoc/reference/result/missing.rb +14 -0
  71. data/lib/coradoc/reference/result/resolved.rb +22 -0
  72. data/lib/coradoc/reference/result.rb +20 -0
  73. data/lib/coradoc/reference.rb +65 -0
  74. data/lib/coradoc/registry.rb +6 -6
  75. data/lib/coradoc/resolve_includes.rb +2 -2
  76. data/lib/coradoc/validation.rb +44 -4
  77. data/lib/coradoc/version.rb +1 -1
  78. data/lib/coradoc.rb +1 -1
  79. metadata +45 -1
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lutaml/model'
4
+
5
+ module Coradoc
6
+ module Reference
7
+ module Result
8
+ # Base class for resolution outcomes. Subclasses are value types.
9
+ # Every Result carries the Edge that asked — so callers can log,
10
+ # trace, and re-route without re-resolving.
11
+ class Base < Lutaml::Model::Serializable
12
+ attribute :edge, Coradoc::Reference::Edge
13
+ attribute :address, Coradoc::Reference::Address
14
+
15
+ def resolved?
16
+ is_a?(Result::Resolved)
17
+ end
18
+
19
+ def ambiguous?
20
+ is_a?(Result::Ambiguous)
21
+ end
22
+
23
+ def missing?
24
+ is_a?(Result::Missing)
25
+ end
26
+
27
+ # This Result as seen by +edge+. Returns self when the edge is
28
+ # value-equal to the one embedded; otherwise rebuilds the same
29
+ # outcome (target/candidates preserved) for the asking edge.
30
+ # Used by caching resolvers so two edges sharing an Address
31
+ # never see each other's identity.
32
+ def for_edge(edge)
33
+ return self if self.edge == edge
34
+
35
+ self.class.build(edge: edge, address: address, **result_data)
36
+ end
37
+
38
+ private
39
+
40
+ def result_data
41
+ {}
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module Reference
5
+ module Result
6
+ # No catalog knows this address. Caller's +missing:+ policy decides.
7
+ class Missing < Base
8
+ def self.build(edge:, address:)
9
+ new(edge: edge, address: address)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module Reference
5
+ module Result
6
+ # Catalog knew the address; exactly one Content was returned.
7
+ class Resolved < Base
8
+ attribute :target, Coradoc::CoreModel::Base
9
+
10
+ def self.build(edge:, address:, target:)
11
+ new(edge: edge, address: address, target: target)
12
+ end
13
+
14
+ private
15
+
16
+ def result_data
17
+ { target: target }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Coradoc
4
+ module Reference
5
+ # Sum type for resolution outcomes. Callers pattern-match on the
6
+ # concrete subclass — never check +nil+.
7
+ #
8
+ # case resolver.resolve(edge)
9
+ # in Result::Resolved => r # have the target
10
+ # in Result::Ambiguous => a # multiple candidates
11
+ # in Result::Missing => m # catalog does not know
12
+ # end
13
+ module Result
14
+ autoload :Base, "#{__dir__}/result/base"
15
+ autoload :Resolved, "#{__dir__}/result/resolved"
16
+ autoload :Ambiguous, "#{__dir__}/result/ambiguous"
17
+ autoload :Missing, "#{__dir__}/result/missing"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'coradoc/errors'
4
+
5
+ module Coradoc
6
+ # Unified content-graph reference resolution.
7
+ #
8
+ # Every referenceable thing in a document is a Content node; every
9
+ # reference is a directed Edge with a kind. The four primitives:
10
+ #
11
+ # Content — CoreModel::Base with an id (already on Base).
12
+ # Document — Content that contains Content (composite).
13
+ # Reference::Edge — directed {source Content, target Address, kind}.
14
+ # Reference::Address — scheme-aware locator (anchor, path, url, ...).
15
+ #
16
+ # Same Content graph → N Presentations → M Materializers. The public
17
+ # entry point is +Coradoc.resolve_references+.
18
+ module Reference
19
+ # Base class for reference-resolution errors. All subclasses inherit
20
+ # from here so callers can rescue the family with one +rescue+ clause.
21
+ class Error < Coradoc::Error; end
22
+
23
+ # Raised when no catalog knew the requested Address and the
24
+ # +missing:+ policy is :error.
25
+ class MissingReferenceError < Error
26
+ attr_reader :address
27
+
28
+ def initialize(message = nil, address: nil)
29
+ @address = address
30
+ super(message || "Reference not found: #{address}")
31
+ end
32
+ end
33
+
34
+ # Raised when multiple catalogs matched an Address and the
35
+ # +ambiguous:+ policy is :error.
36
+ class AmbiguousReferenceError < Error
37
+ attr_reader :address, :candidates
38
+
39
+ def initialize(message = nil, address: nil, candidates: nil)
40
+ @address = address
41
+ @candidates = candidates
42
+ super(message || "Reference is ambiguous: #{address}")
43
+ end
44
+ end
45
+
46
+ # Raised when the catalog index is malformed — a programmer
47
+ # error, not a runtime condition. Surfaces as a clear message
48
+ # rather than a vague NoMethodError.
49
+ class InvalidCatalogError < Error; end
50
+
51
+ # Raised when building an Edge whose kind was never registered.
52
+ # External kinds register via +Edge.register_kind+ (OCP).
53
+ class UnknownKindError < Error; end
54
+
55
+ autoload :Address, "#{__dir__}/reference/address"
56
+ autoload :Edge, "#{__dir__}/reference/edge"
57
+ autoload :Catalog, "#{__dir__}/reference/catalog"
58
+ autoload :Result, "#{__dir__}/reference/result"
59
+ autoload :Resolver, "#{__dir__}/reference/resolver"
60
+ autoload :Presentation, "#{__dir__}/reference/presentation"
61
+ autoload :Materializer, "#{__dir__}/reference/materializer"
62
+ autoload :EdgeSearch, "#{__dir__}/reference/edge_search"
63
+ autoload :Resolution, "#{__dir__}/reference/resolution"
64
+ end
65
+ end
@@ -102,24 +102,24 @@ module Coradoc
102
102
  #
103
103
  # @yield [Symbol, Object] name and item
104
104
  # @return [Enumerator]
105
- def each(&block)
106
- @items.each(&block)
105
+ def each(&)
106
+ @items.each(&)
107
107
  end
108
108
 
109
109
  # Iterate over item values
110
110
  #
111
111
  # @yield [Object]
112
112
  # @return [Enumerator]
113
- def each_value(&block)
114
- @items.each_value(&block)
113
+ def each_value(&)
114
+ @items.each_value(&)
115
115
  end
116
116
 
117
117
  # Iterate over item names
118
118
  #
119
119
  # @yield [Symbol]
120
120
  # @return [Enumerator]
121
- def each_key(&block)
122
- @items.each_key(&block)
121
+ def each_key(&)
122
+ @items.each_key(&)
123
123
  end
124
124
 
125
125
  # Find an item whose processor_match? returns true for the given filename
@@ -24,8 +24,8 @@ module Coradoc
24
24
  DEFAULT_MAX_DEPTH = 64
25
25
 
26
26
  class << self
27
- def call(core, resolver:, base_dir:, **opts)
28
- new(resolver: resolver, base_dir: base_dir, **opts).call(core)
27
+ def call(core, resolver:, base_dir:, **)
28
+ new(resolver: resolver, base_dir: base_dir, **).call(core)
29
29
  end
30
30
  end
31
31
 
@@ -28,6 +28,46 @@ module Coradoc
28
28
  # end
29
29
  #
30
30
  module Validation
31
+ module_function
32
+
33
+ # Targets of every unresolved +include::+ edge in the tree
34
+ # (deduplicated, in document order). A document is "unresolved"
35
+ # when it was parsed in graph mode and never went through
36
+ # +Coradoc.resolve_includes+.
37
+ def unresolved_include_targets(model)
38
+ targets = []
39
+ walk_nodes(model) do |node|
40
+ targets << node.target if node.is_a?(Coradoc::CoreModel::Include)
41
+ end
42
+ targets.uniq
43
+ end
44
+
45
+ # Serialization boundary check: formats that cannot represent an
46
+ # unresolved include edge (FormatModule::Interface
47
+ # #preserves_unresolved_includes? == false) must not silently drop
48
+ # the content — raise UnresolvedIncludesError instead, pointing at
49
+ # the hydration step (resolve_includes).
50
+ def guard_unresolved_includes!(model, format_module)
51
+ return if format_module.preserves_unresolved_includes?
52
+
53
+ targets = unresolved_include_targets(model)
54
+ return if targets.empty?
55
+
56
+ raise Coradoc::UnresolvedIncludesError, targets
57
+ end
58
+
59
+ def walk_nodes(node, &block)
60
+ return unless node.is_a?(Coradoc::CoreModel::Base)
61
+
62
+ yield node
63
+ return unless node.is_a?(Coradoc::CoreModel::HasChildren)
64
+
65
+ children = node.children
66
+ return unless children
67
+
68
+ children.each { |child| walk_nodes(child, &block) }
69
+ end
70
+
31
71
  # A single validation error
32
72
  class Error
33
73
  attr_reader :path, :message, :code, :element
@@ -600,8 +640,8 @@ module Coradoc
600
640
  #
601
641
  # @yield Schema definition block
602
642
  # @return [Schema] The defined schema
603
- def define(&block)
604
- Schema.define(&block)
643
+ def define(&)
644
+ Schema.define(&)
605
645
  end
606
646
 
607
647
  # Generate a validation schema from a CoreModel class
@@ -614,8 +654,8 @@ module Coradoc
614
654
  # schema = Coradoc::Validation.auto_schema(Coradoc::CoreModel::Block)
615
655
  # result = schema.validate(document)
616
656
  #
617
- def auto_schema(model_class, **options)
618
- SchemaGenerator.generate(model_class, **options)
657
+ def auto_schema(model_class, **)
658
+ SchemaGenerator.generate(model_class, **)
619
659
  end
620
660
 
621
661
  # Validate a document with default schema
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coradoc
4
- VERSION = '2.0.27'
4
+ VERSION = '2.0.29'
5
5
  end
data/lib/coradoc.rb CHANGED
@@ -30,9 +30,9 @@
30
30
  # Coradoc.serialize(doc, to: :html)
31
31
 
32
32
  require_relative 'coradoc/coradoc'
33
- require_relative 'coradoc/version'
34
33
 
35
34
  module Coradoc
35
+ autoload :VERSION, 'coradoc/version'
36
36
  autoload :CLI, 'coradoc/cli'
37
37
  autoload :Visitor, 'coradoc/visitor'
38
38
  autoload :LinkRewriter, 'coradoc/link_rewriter'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coradoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.27
4
+ version: 2.0.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -131,6 +131,49 @@ files:
131
131
  - lib/coradoc/performance_regression.rb
132
132
  - lib/coradoc/pipeline.rb
133
133
  - lib/coradoc/query.rb
134
+ - lib/coradoc/reference.rb
135
+ - lib/coradoc/reference/address.rb
136
+ - lib/coradoc/reference/address/anchor.rb
137
+ - lib/coradoc/reference/address/doi.rb
138
+ - lib/coradoc/reference/address/isbn.rb
139
+ - lib/coradoc/reference/address/path.rb
140
+ - lib/coradoc/reference/address/scoped_path.rb
141
+ - lib/coradoc/reference/address/url.rb
142
+ - lib/coradoc/reference/catalog.rb
143
+ - lib/coradoc/reference/catalog/composite.rb
144
+ - lib/coradoc/reference/catalog/local.rb
145
+ - lib/coradoc/reference/catalog/memory_index.rb
146
+ - lib/coradoc/reference/edge.rb
147
+ - lib/coradoc/reference/edge/citation_options.rb
148
+ - lib/coradoc/reference/edge/footnote_ref_options.rb
149
+ - lib/coradoc/reference/edge/image_ref_options.rb
150
+ - lib/coradoc/reference/edge/include_options.rb
151
+ - lib/coradoc/reference/edge/kind.rb
152
+ - lib/coradoc/reference/edge/link_options.rb
153
+ - lib/coradoc/reference/edge/navigation_options.rb
154
+ - lib/coradoc/reference/edge/options.rb
155
+ - lib/coradoc/reference/edge_search.rb
156
+ - lib/coradoc/reference/materializer.rb
157
+ - lib/coradoc/reference/materializer/base.rb
158
+ - lib/coradoc/reference/materializer/passthrough.rb
159
+ - lib/coradoc/reference/materializer/registry.rb
160
+ - lib/coradoc/reference/presentation.rb
161
+ - lib/coradoc/reference/presentation/base.rb
162
+ - lib/coradoc/reference/presentation/custom_hierarchy.rb
163
+ - lib/coradoc/reference/presentation/page.rb
164
+ - lib/coradoc/reference/presentation/single_document.rb
165
+ - lib/coradoc/reference/presentation/split_pages.rb
166
+ - lib/coradoc/reference/resolution.rb
167
+ - lib/coradoc/reference/resolver.rb
168
+ - lib/coradoc/reference/resolver/base.rb
169
+ - lib/coradoc/reference/resolver/caching.rb
170
+ - lib/coradoc/reference/resolver/catalog.rb
171
+ - lib/coradoc/reference/resolver/chain.rb
172
+ - lib/coradoc/reference/result.rb
173
+ - lib/coradoc/reference/result/ambiguous.rb
174
+ - lib/coradoc/reference/result/base.rb
175
+ - lib/coradoc/reference/result/missing.rb
176
+ - lib/coradoc/reference/result/resolved.rb
134
177
  - lib/coradoc/registry.rb
135
178
  - lib/coradoc/relative_path.rb
136
179
  - lib/coradoc/resolve_includes.rb
@@ -144,6 +187,7 @@ metadata:
144
187
  homepage_uri: https://github.com/lutaml/coradoc
145
188
  source_code_uri: https://github.com/lutaml/coradoc
146
189
  changelog_uri: https://github.com/lutaml/coradoc/blob/main/CHANGELOG.md
190
+ rubygems_mfa_required: 'true'
147
191
  rdoc_options: []
148
192
  require_paths:
149
193
  - lib