coradoc 2.0.5 → 2.0.6

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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +82 -36
  3. data/coradoc-adoc/lib/coradoc/asciidoc/model/document.rb +2 -2
  4. data/coradoc-adoc/lib/coradoc/asciidoc/model/include.rb +2 -2
  5. data/coradoc-adoc/lib/coradoc/asciidoc/model.rb +6 -4
  6. data/coradoc-adoc/lib/coradoc/asciidoc/parser/block.rb +5 -4
  7. data/coradoc-adoc/lib/coradoc/asciidoc/parser/content.rb +4 -2
  8. data/coradoc-adoc/lib/coradoc/asciidoc/transform/from_core_model.rb +84 -13
  9. data/coradoc-adoc/lib/coradoc/asciidoc/transform/to_core_model.rb +94 -25
  10. data/coradoc-adoc/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +42 -18
  11. data/coradoc-adoc/lib/coradoc/asciidoc/transformer/structural_rules.rb +2 -1
  12. data/coradoc-adoc/lib/coradoc/asciidoc.rb +7 -2
  13. data/coradoc-adoc/spec/coradoc/asciidoc/integration_pipeline_spec.rb +1 -3
  14. data/coradoc-adoc/spec/coradoc/asciidoc/round_trip_spec.rb +0 -1
  15. data/coradoc-adoc/spec/coradoc/asciidoc/transform/from_core_model_spec.rb +3 -2
  16. data/coradoc-adoc/spec/coradoc/developer_experience_spec.rb +0 -1
  17. data/coradoc-adoc/spec/transform/from_core_model_spec.rb +3 -3
  18. data/coradoc-adoc/spec/transform/to_core_model_spec.rb +1 -0
  19. data/coradoc-html/lib/coradoc/html/converters/base.rb +41 -17
  20. data/coradoc-html/lib/coradoc/html/converters/example.rb +1 -2
  21. data/coradoc-html/lib/coradoc/html/converters/listing.rb +1 -2
  22. data/coradoc-html/lib/coradoc/html/converters/literal.rb +1 -2
  23. data/coradoc-html/lib/coradoc/html/converters/open.rb +1 -2
  24. data/coradoc-html/lib/coradoc/html/converters/quote.rb +2 -3
  25. data/coradoc-html/lib/coradoc/html/converters/sidebar.rb +1 -2
  26. data/coradoc-html/lib/coradoc/html/converters/source.rb +1 -2
  27. data/coradoc-html/lib/coradoc/html/converters/source_code.rb +1 -2
  28. data/coradoc-html/lib/coradoc/html/converters/term.rb +1 -2
  29. data/coradoc-html/lib/coradoc/html/converters/verse.rb +2 -3
  30. data/coradoc-html/lib/coradoc/html/input/converters/aside.rb +1 -1
  31. data/coradoc-html/lib/coradoc/html/input/converters/audio.rb +1 -1
  32. data/coradoc-html/lib/coradoc/html/input/converters/blockquote.rb +2 -3
  33. data/coradoc-html/lib/coradoc/html/input/converters/div.rb +1 -2
  34. data/coradoc-html/lib/coradoc/html/input/converters/figure.rb +2 -3
  35. data/coradoc-html/lib/coradoc/html/input/converters/hr.rb +1 -1
  36. data/coradoc-html/lib/coradoc/html/input/converters/p.rb +2 -1
  37. data/coradoc-html/lib/coradoc/html/input/converters/pre.rb +14 -10
  38. data/coradoc-html/lib/coradoc/html/input/converters/video.rb +1 -1
  39. data/coradoc-html/lib/coradoc/html/renderer.rb +50 -2
  40. data/coradoc-html/lib/coradoc/html/spa.rb +2 -2
  41. data/coradoc-html/lib/coradoc/html/static.rb +2 -2
  42. data/coradoc-html/lib/coradoc/html/templates/core_model/definition_list.liquid +11 -0
  43. data/coradoc-html/lib/coradoc/html/theme/modern/javascript_generator.rb +2 -2
  44. data/coradoc-html/lib/coradoc/html/theme/modern/serializers/document_serializer.rb +7 -11
  45. data/coradoc-html/lib/coradoc/html/theme/modern_renderer.rb +6 -7
  46. data/coradoc-html/lib/coradoc/html.rb +5 -15
  47. data/coradoc-html/spec/input/converters/converters_spec.rb +1 -1
  48. data/coradoc-markdown/lib/coradoc/markdown/model/attribute_list.rb +0 -3
  49. data/coradoc-markdown/lib/coradoc/markdown/model/definition_list.rb +0 -3
  50. data/coradoc-markdown/lib/coradoc/markdown/model/extension.rb +0 -2
  51. data/coradoc-markdown/lib/coradoc/markdown/model/highlight.rb +0 -1
  52. data/coradoc-markdown/lib/coradoc/markdown/model/math.rb +0 -1
  53. data/coradoc-markdown/lib/coradoc/markdown/model/strikethrough.rb +0 -1
  54. data/coradoc-markdown/lib/coradoc/markdown/parser/ast_processor.rb +2 -2
  55. data/coradoc-markdown/lib/coradoc/markdown/parser/block_parser.rb +2 -2
  56. data/coradoc-markdown/lib/coradoc/markdown/parser/inline_parser.rb +3 -3
  57. data/coradoc-markdown/lib/coradoc/markdown/parser.rb +9 -3
  58. data/coradoc-markdown/lib/coradoc/markdown/toc_generator.rb +6 -4
  59. data/coradoc-markdown/lib/coradoc/markdown/transform/from_core_model.rb +27 -6
  60. data/coradoc-markdown/lib/coradoc/markdown/transform/to_core_model.rb +5 -9
  61. data/coradoc-markdown/lib/coradoc/markdown/transformer.rb +2 -1
  62. data/coradoc-markdown/spec/transform/to_core_model_spec.rb +6 -8
  63. data/exe/coradoc +1 -0
  64. data/lib/coradoc/coradoc.rb +6 -7
  65. data/lib/coradoc/core_model/annotation_block.rb +0 -2
  66. data/lib/coradoc/core_model/block.rb +92 -32
  67. data/lib/coradoc/core_model/builder/block_builder.rb +20 -2
  68. data/lib/coradoc/core_model/builder/detection.rb +0 -8
  69. data/lib/coradoc/core_model/builder.rb +6 -7
  70. data/lib/coradoc/core_model/example_block.rb +12 -0
  71. data/lib/coradoc/core_model/listing_block.rb +15 -0
  72. data/lib/coradoc/core_model/literal_block.rb +12 -0
  73. data/lib/coradoc/core_model/open_block.rb +12 -0
  74. data/lib/coradoc/core_model/pass_block.rb +12 -0
  75. data/lib/coradoc/core_model/quote_block.rb +14 -0
  76. data/lib/coradoc/core_model/reviewer_block.rb +12 -0
  77. data/lib/coradoc/core_model/sidebar_block.rb +12 -0
  78. data/lib/coradoc/core_model/source_block.rb +22 -0
  79. data/lib/coradoc/core_model/verse_block.rb +14 -0
  80. data/lib/coradoc/core_model.rb +10 -0
  81. data/lib/coradoc/processor_registry.rb +0 -2
  82. data/lib/coradoc/version.rb +1 -1
  83. metadata +12 -34
  84. data/coradoc-markdown/coverage/.last_run.json +0 -5
  85. data/coradoc-markdown/coverage/.resultset.json +0 -6322
  86. data/coradoc-markdown/coverage/.resultset.json.lock +0 -0
  87. data/coradoc-markdown/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_asc.png +0 -0
  88. data/coradoc-markdown/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_asc_disabled.png +0 -0
  89. data/coradoc-markdown/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_both.png +0 -0
  90. data/coradoc-markdown/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_desc.png +0 -0
  91. data/coradoc-markdown/coverage/assets/0.13.2/DataTables-1.10.20/images/sort_desc_disabled.png +0 -0
  92. data/coradoc-markdown/coverage/assets/0.13.2/application.css +0 -1
  93. data/coradoc-markdown/coverage/assets/0.13.2/application.js +0 -7
  94. data/coradoc-markdown/coverage/assets/0.13.2/colorbox/border.png +0 -0
  95. data/coradoc-markdown/coverage/assets/0.13.2/colorbox/controls.png +0 -0
  96. data/coradoc-markdown/coverage/assets/0.13.2/colorbox/loading.gif +0 -0
  97. data/coradoc-markdown/coverage/assets/0.13.2/colorbox/loading_background.png +0 -0
  98. data/coradoc-markdown/coverage/assets/0.13.2/favicon_green.png +0 -0
  99. data/coradoc-markdown/coverage/assets/0.13.2/favicon_red.png +0 -0
  100. data/coradoc-markdown/coverage/assets/0.13.2/favicon_yellow.png +0 -0
  101. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  102. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  103. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  104. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  105. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  106. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  107. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  108. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  109. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-icons_222222_256x240.png +0 -0
  110. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-icons_2e83ff_256x240.png +0 -0
  111. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-icons_454545_256x240.png +0 -0
  112. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-icons_888888_256x240.png +0 -0
  113. data/coradoc-markdown/coverage/assets/0.13.2/images/ui-icons_cd0a0a_256x240.png +0 -0
  114. data/coradoc-markdown/coverage/assets/0.13.2/loading.gif +0 -0
  115. data/coradoc-markdown/coverage/assets/0.13.2/magnify.png +0 -0
  116. data/coradoc-markdown/coverage/index.html +0 -66032
@@ -6,6 +6,8 @@ module Coradoc
6
6
  class ModernRenderer
7
7
  # Generate Vue.js application code
8
8
  module JavascriptGenerator
9
+ autoload :VueTemplates, "#{__dir__}/vue_template_generator"
10
+
9
11
  class << self
10
12
  # Generate Vue application
11
13
  #
@@ -17,7 +19,6 @@ module Coradoc
17
19
  templates = load_templates
18
20
 
19
21
  # Get enhanced document template
20
- require_relative 'components/ui_components'
21
22
  document_template = UIComponents.enhanced_document_template(config)
22
23
 
23
24
  <<~JS
@@ -293,7 +294,6 @@ module Coradoc
293
294
  #
294
295
  # @return [Hash] Hash of templates
295
296
  def load_templates
296
- require_relative 'vue_template_generator'
297
297
  {
298
298
  paragraph: VueTemplates.template_for('paragraph'),
299
299
  admonition: VueTemplates.template_for('admonition'),
@@ -128,17 +128,13 @@ module Coradoc
128
128
  # @param block [Coradoc::CoreModel::Block] Block to serialize
129
129
  # @return [Hash] Serialized block
130
130
  def serialize_core_model_block(block)
131
- block_type = case block.element_type
132
- when 'paragraph' then 'paragraph'
133
- when 'block'
134
- case block.delimiter_type
135
- when '----' then 'source'
136
- when '____' then 'quote'
137
- when '====' then 'example'
138
- else 'block'
139
- end
140
- else
141
- 'block'
131
+ semantic = block.block_semantic_type&.to_sym
132
+ block_type = case semantic
133
+ when :paragraph then 'paragraph'
134
+ when :source_code then 'source'
135
+ when :quote, :verse then 'quote'
136
+ when :example then 'example'
137
+ else 'block'
142
138
  end
143
139
 
144
140
  {
@@ -13,6 +13,12 @@ module Coradoc
13
13
  # @example Generate modern HTML output
14
14
  # html = Coradoc::Output::Html.convert_to_html5(document, theme: :modern)
15
15
  class ModernRenderer < Base
16
+ autoload :Serializers, "#{__dir__}/modern/serializers/document_serializer"
17
+ autoload :JavascriptGenerator, "#{__dir__}/modern/javascript_generator"
18
+ autoload :TailwindConfigBuilder, "#{__dir__}/modern/tailwind_config_builder"
19
+ autoload :CSSGenerator, "#{__dir__}/modern/css_generator"
20
+ autoload :UIComponents, "#{__dir__}/modern/components/ui_components"
21
+
16
22
  # Register this theme
17
23
  Registry.register(:modern, self)
18
24
 
@@ -111,7 +117,6 @@ module Coradoc
111
117
  #
112
118
  # @return [Hash] Serialized document data
113
119
  def serialize_document
114
- require_relative 'modern/serializers/document_serializer'
115
120
  Serializers::DocumentSerializer.serialize(@document)
116
121
  end
117
122
 
@@ -121,7 +126,6 @@ module Coradoc
121
126
  # @param config [Hash] Theme configuration
122
127
  # @return [String] Vue application JavaScript
123
128
  def generate_vue_app(document_data, config)
124
- require_relative 'modern/javascript_generator'
125
129
  JavascriptGenerator.generate(document_data, config)
126
130
  end
127
131
 
@@ -130,7 +134,6 @@ module Coradoc
130
134
  # @param config [Hash] Theme configuration
131
135
  # @return [String] Tailwind configuration script
132
136
  def generate_tailwind_config(config)
133
- require_relative 'modern/tailwind_config_builder'
134
137
  TailwindConfigBuilder.build(config)
135
138
  end
136
139
 
@@ -139,10 +142,6 @@ module Coradoc
139
142
  # @param config [Hash] Theme configuration
140
143
  # @return [String] Custom CSS
141
144
  def generate_custom_css(config)
142
- require_relative 'modern/css_generator'
143
- require_relative 'modern/components/ui_components'
144
-
145
- # Use enhanced CSS from UIComponents module
146
145
  UIComponents.enhanced_css(config)
147
146
  end
148
147
 
@@ -7,21 +7,6 @@ require 'coradoc/html/output'
7
7
 
8
8
  module Coradoc
9
9
  module Html
10
- # Register HTML format with coradoc when loaded
11
- def self.register_with_coradoc
12
- return if @registered
13
-
14
- # Register with the main coradoc registry
15
- Coradoc.register_format(:html, self,
16
- aliases: %w[html htm],
17
- extensions: %w[.html .htm])
18
-
19
- @registered = true
20
- end
21
-
22
- # Call registration when this module is included/required
23
- register_with_coradoc
24
-
25
10
  module Converters
26
11
  # Autoload HTML converters - they will be loaded when accessed
27
12
  autoload :Base, 'coradoc/html/converters/base'
@@ -263,3 +248,8 @@ module Coradoc
263
248
  end
264
249
  end
265
250
  end
251
+
252
+ # Register after all module methods are defined
253
+ Coradoc.register_format(:html, Coradoc::Html,
254
+ aliases: %w[html htm],
255
+ extensions: %w[.html .htm])
@@ -123,7 +123,7 @@ RSpec.describe Coradoc::Input::Html::Converters do
123
123
  result = converter.to_coradoc(node, {})
124
124
 
125
125
  expect(result).to be_a(Coradoc::CoreModel::Block)
126
- expect(result.delimiter_type).to eq('paragraph')
126
+ expect(result.block_semantic_type).to eq('paragraph')
127
127
  end
128
128
 
129
129
  it 'preserves id attribute' do
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
- require_relative '../parser_util'
5
-
6
3
  module Coradoc
7
4
  module Markdown
8
5
  # Represents an Inline Attribute List (IAL) or Attribute List Definition (ALD)
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'definition_term'
4
- require_relative 'definition_item'
5
-
6
3
  module Coradoc
7
4
  module Markdown
8
5
  # DefinitionList model representing a Kramdown definition list.
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
-
5
3
  module Coradoc
6
4
  module Markdown
7
5
  # Represents a kramdown extension
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
3
 
5
4
  module Coradoc
6
5
  module Markdown
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
3
 
5
4
  module Coradoc
6
5
  module Markdown
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base'
4
3
 
5
4
  module Coradoc
6
5
  module Markdown
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'inline_parser'
4
-
5
3
  module Coradoc
6
4
  module Markdown
7
5
  module Parser
6
+ autoload :InlineParser, "#{__dir__}/inline_parser"
7
+
8
8
  # Post-processes the AST produced by BlockParser.
9
9
  #
10
10
  # This processor handles:
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'parslet_extras'
4
-
5
3
  module Coradoc
6
4
  module Markdown
7
5
  module Parser
6
+ autoload :ParsletExtras, "#{__dir__}/parslet_extras"
7
+
8
8
  class BlockParser < Parslet::Parser
9
9
  using ParsletExtras
10
10
 
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'parslet_extras'
4
- require_relative 'html_entities'
5
-
6
3
  module Coradoc
7
4
  module Markdown
8
5
  module Parser
6
+ autoload :ParsletExtras, "#{__dir__}/parslet_extras"
7
+ autoload :HtmlEntities, "#{__dir__}/html_entities"
8
+
9
9
  class InlineParser < Parslet::Parser
10
10
  using ParsletExtras
11
11
 
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'block_parser'
4
- require_relative 'inline_parser'
5
- require_relative 'ast_processor'
3
+ module Coradoc
4
+ module Markdown
5
+ module Parser
6
+ autoload :BlockParser, "#{__dir__}/block_parser"
7
+ autoload :InlineParser, "#{__dir__}/inline_parser"
8
+ autoload :AstProcessor, "#{__dir__}/ast_processor"
9
+ end
10
+ end
11
+ end
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'model/base'
4
- require_relative 'model/heading'
5
- require_relative 'model/document'
6
-
7
3
  module Coradoc
8
4
  module Markdown
5
+ module Model
6
+ autoload :Base, "#{__dir__}/model/base"
7
+ autoload :Heading, "#{__dir__}/model/heading"
8
+ autoload :Document, "#{__dir__}/model/document"
9
+ end
10
+
9
11
  # Table of Contents Generator
10
12
  #
11
13
  # Generates a table of contents from document headings.
@@ -127,22 +127,43 @@ module Coradoc
127
127
  end
128
128
 
129
129
  def transform_delimited_block(block)
130
- delimiter = block.delimiter_type
130
+ semantic = resolve_markdown_semantic(block)
131
131
 
132
- case delimiter
133
- when '```', '~'
132
+ case semantic
133
+ when :source_code, :listing
134
134
  transform_code_block(block)
135
- when '>'
135
+ when :quote, :verse
136
136
  transform_blockquote(block)
137
- when '---', '***', '___'
137
+ when :horizontal_rule
138
138
  transform_horizontal_rule(block)
139
- when '++++'
139
+ when :pass
140
140
  Coradoc::Markdown::Extension.nomarkdown(block.content.to_s)
141
+ when :literal
142
+ transform_code_block(block)
141
143
  else
142
144
  transform_paragraph(block)
143
145
  end
144
146
  end
145
147
 
148
+ def resolve_markdown_semantic(block)
149
+ # Polymorphic dispatch: typed classes override semantic_type
150
+ semantic = block.resolve_semantic_type
151
+ return semantic if semantic
152
+
153
+ # Backward compat: derive from delimiter_type
154
+ markdown_delimiter_to_semantic(block.delimiter_type)
155
+ end
156
+
157
+ def markdown_delimiter_to_semantic(delimiter)
158
+ case delimiter
159
+ when '```', '~' then :source_code
160
+ when '>' then :quote
161
+ when '---', '***', '___' then :horizontal_rule
162
+ when '++++' then :pass
163
+ else nil
164
+ end
165
+ end
166
+
146
167
  def transform_code_block(block)
147
168
  Coradoc::Markdown::CodeBlock.new(
148
169
  code: block.content.to_s,
@@ -103,18 +103,16 @@ module Coradoc
103
103
  end
104
104
 
105
105
  def transform_code_block(block)
106
- Coradoc::CoreModel::Block.new(
106
+ Coradoc::CoreModel::SourceBlock.new(
107
107
  element_type: 'block',
108
- delimiter_type: '```',
109
108
  content: block.code.to_s,
110
109
  language: block.language
111
110
  )
112
111
  end
113
112
 
114
113
  def transform_blockquote(blockquote)
115
- Coradoc::CoreModel::Block.new(
114
+ Coradoc::CoreModel::QuoteBlock.new(
116
115
  element_type: 'block',
117
- delimiter_type: '>',
118
116
  content: blockquote.content.to_s
119
117
  )
120
118
  end
@@ -184,7 +182,7 @@ module Coradoc
184
182
  def transform_horizontal_rule(_rule)
185
183
  Coradoc::CoreModel::Block.new(
186
184
  element_type: 'block',
187
- delimiter_type: '---'
185
+ block_semantic_type: :horizontal_rule
188
186
  )
189
187
  end
190
188
 
@@ -228,9 +226,8 @@ module Coradoc
228
226
  content: math.content.to_s
229
227
  )
230
228
  else
231
- Coradoc::CoreModel::Block.new(
229
+ Coradoc::CoreModel::PassBlock.new(
232
230
  element_type: 'block',
233
- delimiter_type: '++++',
234
231
  content: math.content.to_s,
235
232
  language: 'latexmath'
236
233
  )
@@ -247,9 +244,8 @@ module Coradoc
247
244
  content: ext.content.to_s
248
245
  )
249
246
  when :nomarkdown
250
- Coradoc::CoreModel::Block.new(
247
+ Coradoc::CoreModel::PassBlock.new(
251
248
  element_type: 'block',
252
- delimiter_type: '++++',
253
249
  content: ext.content.to_s
254
250
  )
255
251
  else
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'parslet'
4
- require_relative 'parser_util'
5
4
 
6
5
  module Coradoc
7
6
  module Markdown
7
+ autoload :ParserUtil, "#{__dir__}/parser_util"
8
+
8
9
  # Transformer converts Parslet AST into Markdown Document Model objects.
9
10
  #
10
11
  # This transformer takes the raw output from the BlockParser/InlineParser
@@ -71,9 +71,8 @@ RSpec.describe Coradoc::Markdown::Transform::ToCoreModel do
71
71
  )
72
72
  end
73
73
 
74
- it 'transforms to CoreModel::Block with code delimiter' do
75
- expect(transform).to be_a(Coradoc::CoreModel::Block)
76
- expect(transform.delimiter_type).to eq('```')
74
+ it 'transforms to CoreModel::SourceBlock with code content' do
75
+ expect(transform).to be_a(Coradoc::CoreModel::SourceBlock)
77
76
  expect(transform.content).to eq("def hello\n puts 'world'\nend")
78
77
  expect(transform.language).to eq('ruby')
79
78
  end
@@ -84,9 +83,8 @@ RSpec.describe Coradoc::Markdown::Transform::ToCoreModel do
84
83
  Coradoc::Markdown::Blockquote.new(content: 'Quoted text')
85
84
  end
86
85
 
87
- it 'transforms to CoreModel::Block with blockquote delimiter' do
88
- expect(transform).to be_a(Coradoc::CoreModel::Block)
89
- expect(transform.delimiter_type).to eq('>')
86
+ it 'transforms to CoreModel::QuoteBlock with blockquote content' do
87
+ expect(transform).to be_a(Coradoc::CoreModel::QuoteBlock)
90
88
  expect(transform.content).to eq('Quoted text')
91
89
  end
92
90
  end
@@ -222,9 +220,9 @@ RSpec.describe Coradoc::Markdown::Transform::ToCoreModel do
222
220
  Coradoc::Markdown::HorizontalRule.new
223
221
  end
224
222
 
225
- it 'transforms to CoreModel::Block with hr delimiter' do
223
+ it 'transforms to CoreModel::Block with horizontal rule semantic type' do
226
224
  expect(transform).to be_a(Coradoc::CoreModel::Block)
227
- expect(transform.delimiter_type).to eq('---')
225
+ expect(transform.block_semantic_type).to eq('horizontal_rule')
228
226
  end
229
227
  end
230
228
 
data/exe/coradoc CHANGED
@@ -21,6 +21,7 @@ require 'coradoc'
21
21
  require 'coradoc/cli'
22
22
 
23
23
  # Load available format gems
24
+ require 'coradoc/asciidoc'
24
25
  require 'coradoc/html'
25
26
  require 'coradoc/markdown'
26
27
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'lutaml/model'
4
- require_relative 'errors'
5
4
 
6
5
  # Coradoc - A hub-and-spoke document transformation library
7
6
  #
@@ -442,6 +441,7 @@ module Coradoc
442
441
  end
443
442
  end
444
443
 
444
+ autoload :Error, "#{__dir__}/errors"
445
445
  autoload :Version, "#{__dir__}/version"
446
446
  autoload :Logger, "#{__dir__}/logger"
447
447
  autoload :Hooks, "#{__dir__}/hooks"
@@ -449,14 +449,13 @@ module Coradoc
449
449
  autoload :Validation, "#{__dir__}/validation"
450
450
  autoload :Configurable, "#{__dir__}/configurable"
451
451
  autoload :FormatModule, "#{__dir__}/format_module"
452
+ autoload :CoreModel, "#{__dir__}/core_model"
453
+ autoload :Registry, "#{__dir__}/registry"
454
+ autoload :Transform, "#{__dir__}/transform"
455
+ autoload :Input, "#{__dir__}/input"
456
+ autoload :Output, "#{__dir__}/output"
452
457
  end
453
458
 
454
- require_relative 'core_model'
455
- require_relative 'registry'
456
- require_relative 'transform'
457
- require_relative 'input'
458
- require_relative 'output'
459
-
460
459
  # Format gems self-register via Coradoc.register_format when they are required.
461
460
  # No hardcoded registration needed here — each gem's entry file handles its own
462
461
  # registration (e.g., coradoc-adoc/lib/coradoc/asciidoc.rb calls
@@ -19,7 +19,6 @@ module Coradoc
19
19
  # @example Creating a NOTE annotation
20
20
  # note = CoreModel::AnnotationBlock.new(
21
21
  # annotation_type: "note",
22
- # delimiter_type: "****",
23
22
  # content: "This is important information."
24
23
  # )
25
24
  #
@@ -27,7 +26,6 @@ module Coradoc
27
26
  # reviewer = CoreModel::AnnotationBlock.new(
28
27
  # annotation_type: "reviewer",
29
28
  # annotation_label: "john.doe",
30
- # delimiter_type: "////",
31
29
  # content: "Please review this section."
32
30
  # )
33
31
  class AnnotationBlock < Block
@@ -2,39 +2,53 @@
2
2
 
3
3
  module Coradoc
4
4
  module CoreModel
5
- # Generic delimited block model
5
+ # Semantic block type constants
6
6
  #
7
- # Represents all standard AsciiDoc delimited blocks including:
8
- # - Example blocks (====)
9
- # - Literal blocks (````)
10
- # - Listing blocks (----)
11
- # - Open blocks (--)
12
- # - Pass blocks (++++/++++)
13
- # - Quote blocks (____)
14
- # - Sidebar blocks (****)
15
- # - Source blocks (----)
16
- # - Paragraphs (element_type: 'paragraph')
17
- #
18
- # This is a schema-agnostic representation that captures the semantic
19
- # structure without schema-specific interpretation.
7
+ # Format gems own the mapping between their syntax and these
8
+ # canonical semantic types. The core model never stores raw
9
+ # delimiter strings.
10
+ module BlockSemanticType
11
+ SOURCE_CODE = :source_code
12
+ LISTING = :listing
13
+ EXAMPLE = :example
14
+ QUOTE = :quote
15
+ SIDEBAR = :sidebar
16
+ LITERAL = :literal
17
+ OPEN = :open
18
+ PASS = :pass
19
+ VERSE = :verse
20
+ HORIZONTAL_RULE = :horizontal_rule
21
+ COMMENT = :comment
22
+ PARAGRAPH = :paragraph
23
+ VIDEO = :video
24
+ AUDIO = :audio
25
+ ANNOTATION = :annotation
26
+ REVIEWER = :reviewer
27
+
28
+ def self.all
29
+ [SOURCE_CODE, LISTING, EXAMPLE, QUOTE, SIDEBAR, LITERAL, OPEN, PASS,
30
+ VERSE, HORIZONTAL_RULE, COMMENT, PARAGRAPH, VIDEO, AUDIO,
31
+ ANNOTATION, REVIEWER].freeze
32
+ end
33
+ end
34
+
35
+ # Generic block model
20
36
  #
21
- # @example Creating a generic block
22
- # block = CoreModel::Block.new(
23
- # delimiter_type: "====",
24
- # delimiter_length: 4,
25
- # content: "Example content here"
26
- # )
37
+ # Represents all block-level elements in a format-neutral way.
38
+ # Each block has a `block_semantic_type` symbol (e.g., :source_code,
39
+ # :quote, :example) that captures its semantic meaning without
40
+ # tying it to any specific format's syntax.
27
41
  #
28
- # @example Creating a source block
42
+ # @example Creating a source code block
29
43
  # block = CoreModel::Block.new(
30
- # delimiter_type: "----",
44
+ # block_semantic_type: :source_code,
31
45
  # content: "puts 'Hello, World!'",
32
- # attributes: [{ role: "source", language: "ruby" }]
46
+ # language: "ruby"
33
47
  # )
34
48
  #
35
49
  # @example Creating a paragraph with inline formatting
36
50
  # block = CoreModel::Block.new(
37
- # element_type: "paragraph",
51
+ # block_semantic_type: :paragraph,
38
52
  # children: [
39
53
  # "Text with ",
40
54
  # CoreModel::InlineElement.new(format_type: "bold", content: "bold"),
@@ -44,14 +58,38 @@ module Coradoc
44
58
  class Block < Base
45
59
  include ChildrenContent
46
60
 
47
- # @!attribute element_type
61
+ class << self
62
+ # Class-level semantic type — overridden by each typed subclass.
63
+ # Returns nil for the generic Block base class.
64
+ def semantic_type
65
+ nil
66
+ end
67
+ end
68
+
69
+ # Resolve the semantic type from this block instance.
70
+ # Checks class-level semantic_type first (typed subclasses),
71
+ # then the block_semantic_type attribute, then element_type,
72
+ # then delimiter_type fallback.
73
+ def resolve_semantic_type
74
+ self.class.semantic_type ||
75
+ (block_semantic_type&.to_sym) ||
76
+ resolve_semantic_from_element_type ||
77
+ resolve_semantic_from_delimiter
78
+ end
79
+
80
+ # @!attribute block_semantic_type
48
81
  # @return [String, nil] the semantic type of the block
82
+ # (e.g., 'source_code', 'quote', 'example', 'paragraph')
83
+ attribute :block_semantic_type, :string
84
+
85
+ # @!attribute element_type
86
+ # @return [String, nil] the structural role of the block
49
87
  # (e.g., 'paragraph', 'block')
50
88
  attribute :element_type, :string
51
89
 
52
90
  # @!attribute delimiter_type
53
- # @return [String, nil] the delimiter character(s) used
54
- # (e.g., '****', '====', '----')
91
+ # @return [String, nil] DEPRECATED use block_semantic_type.
92
+ # Retained for backward compatibility during migration.
55
93
  attribute :delimiter_type, :string
56
94
 
57
95
  # @!attribute delimiter_length
@@ -76,15 +114,37 @@ module Coradoc
76
114
 
77
115
  private
78
116
 
117
+ def resolve_semantic_from_element_type
118
+ case element_type
119
+ when 'paragraph' then :paragraph
120
+ when 'comment' then :comment
121
+ else nil
122
+ end
123
+ end
124
+
125
+ def resolve_semantic_from_delimiter
126
+ delim = delimiter_type
127
+ return nil unless delim && delim.length >= 4
128
+
129
+ char = delim[0]
130
+ DELIMITER_CHAR_TO_SEMANTIC[char] || nil
131
+ end
132
+
133
+ # Map delimiter first character to semantic type (backward compat)
134
+ DELIMITER_CHAR_TO_SEMANTIC = {
135
+ '-' => :source_code,
136
+ '=' => :example,
137
+ '_' => :quote,
138
+ '*' => :sidebar,
139
+ '.' => :literal,
140
+ '+' => :pass
141
+ }.freeze
142
+
79
143
  # Attributes to compare for semantic equivalence
80
144
  #
81
- # Blocks are semantically equivalent if they have the same
82
- # delimiter type and content, regardless of delimiter length
83
- # or line structure.
84
- #
85
145
  # @return [Array<Symbol>] list of comparable attributes
86
146
  def comparable_attributes
87
- super + %i[delimiter_type content]
147
+ super + %i[block_semantic_type content]
88
148
  end
89
149
  end
90
150
  end