coradoc-adoc 2.0.0
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 +7 -0
- data/.rspec +3 -0
- data/lib/coradoc/asciidoc/model/admonition.rb +37 -0
- data/lib/coradoc/asciidoc/model/anchorable.rb +64 -0
- data/lib/coradoc/asciidoc/model/attached.rb +26 -0
- data/lib/coradoc/asciidoc/model/attribute.rb +22 -0
- data/lib/coradoc/asciidoc/model/attribute_list/matchers.rb +45 -0
- data/lib/coradoc/asciidoc/model/attribute_list.rb +230 -0
- data/lib/coradoc/asciidoc/model/attribute_list_attribute.rb +11 -0
- data/lib/coradoc/asciidoc/model/audio.rb +44 -0
- data/lib/coradoc/asciidoc/model/author.rb +36 -0
- data/lib/coradoc/asciidoc/model/base.rb +141 -0
- data/lib/coradoc/asciidoc/model/bibliography.rb +37 -0
- data/lib/coradoc/asciidoc/model/bibliography_entry.rb +38 -0
- data/lib/coradoc/asciidoc/model/block/core.rb +139 -0
- data/lib/coradoc/asciidoc/model/block/example.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/listing.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/literal.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/open.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/pass.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/quote.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/reviewer_comment.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/side.rb +14 -0
- data/lib/coradoc/asciidoc/model/block/source_code.rb +14 -0
- data/lib/coradoc/asciidoc/model/block.rb +21 -0
- data/lib/coradoc/asciidoc/model/break.rb +33 -0
- data/lib/coradoc/asciidoc/model/comment_block.rb +33 -0
- data/lib/coradoc/asciidoc/model/comment_line.rb +30 -0
- data/lib/coradoc/asciidoc/model/content_list.rb +334 -0
- data/lib/coradoc/asciidoc/model/document.rb +197 -0
- data/lib/coradoc/asciidoc/model/document_attributes.rb +43 -0
- data/lib/coradoc/asciidoc/model/glossaries.rb +11 -0
- data/lib/coradoc/asciidoc/model/header.rb +57 -0
- data/lib/coradoc/asciidoc/model/highlight.rb +11 -0
- data/lib/coradoc/asciidoc/model/image/block_image/attribute_list.rb +23 -0
- data/lib/coradoc/asciidoc/model/image/block_image.rb +25 -0
- data/lib/coradoc/asciidoc/model/image/core/attribute_list.rb +43 -0
- data/lib/coradoc/asciidoc/model/image/core.rb +72 -0
- data/lib/coradoc/asciidoc/model/image/inline_image.rb +17 -0
- data/lib/coradoc/asciidoc/model/image.rb +14 -0
- data/lib/coradoc/asciidoc/model/include.rb +66 -0
- data/lib/coradoc/asciidoc/model/inline/anchor.rb +41 -0
- data/lib/coradoc/asciidoc/model/inline/attribute_reference.rb +25 -0
- data/lib/coradoc/asciidoc/model/inline/base.rb +15 -0
- data/lib/coradoc/asciidoc/model/inline/bold.rb +38 -0
- data/lib/coradoc/asciidoc/model/inline/cross_reference.rb +29 -0
- data/lib/coradoc/asciidoc/model/inline/cross_reference_arg.rb +15 -0
- data/lib/coradoc/asciidoc/model/inline/footnote.rb +34 -0
- data/lib/coradoc/asciidoc/model/inline/hard_line_break.rb +24 -0
- data/lib/coradoc/asciidoc/model/inline/highlight.rb +36 -0
- data/lib/coradoc/asciidoc/model/inline/italic.rb +38 -0
- data/lib/coradoc/asciidoc/model/inline/link.rb +46 -0
- data/lib/coradoc/asciidoc/model/inline/monospace.rb +39 -0
- data/lib/coradoc/asciidoc/model/inline/quotation.rb +25 -0
- data/lib/coradoc/asciidoc/model/inline/small.rb +25 -0
- data/lib/coradoc/asciidoc/model/inline/span.rb +38 -0
- data/lib/coradoc/asciidoc/model/inline/stem.rb +24 -0
- data/lib/coradoc/asciidoc/model/inline/strikethrough.rb +39 -0
- data/lib/coradoc/asciidoc/model/inline/subscript.rb +33 -0
- data/lib/coradoc/asciidoc/model/inline/superscript.rb +33 -0
- data/lib/coradoc/asciidoc/model/inline/underline.rb +25 -0
- data/lib/coradoc/asciidoc/model/inline.rb +31 -0
- data/lib/coradoc/asciidoc/model/line_break.rb +11 -0
- data/lib/coradoc/asciidoc/model/list/core.rb +61 -0
- data/lib/coradoc/asciidoc/model/list/definition.rb +27 -0
- data/lib/coradoc/asciidoc/model/list/definition_item.rb +43 -0
- data/lib/coradoc/asciidoc/model/list/item.rb +72 -0
- data/lib/coradoc/asciidoc/model/list/nestable.rb +14 -0
- data/lib/coradoc/asciidoc/model/list/ordered.rb +34 -0
- data/lib/coradoc/asciidoc/model/list/unordered.rb +34 -0
- data/lib/coradoc/asciidoc/model/list.rb +29 -0
- data/lib/coradoc/asciidoc/model/named_attribute.rb +12 -0
- data/lib/coradoc/asciidoc/model/paragraph.rb +59 -0
- data/lib/coradoc/asciidoc/model/rejected_positional_attribute.rb +12 -0
- data/lib/coradoc/asciidoc/model/resolvable.rb +71 -0
- data/lib/coradoc/asciidoc/model/resolver.rb +430 -0
- data/lib/coradoc/asciidoc/model/reviewer_note.rb +54 -0
- data/lib/coradoc/asciidoc/model/revision.rb +47 -0
- data/lib/coradoc/asciidoc/model/section.rb +109 -0
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_adapter.rb +28 -0
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_mapping.rb +42 -0
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_mapping_rule.rb +41 -0
- data/lib/coradoc/asciidoc/model/serialization/asciidoc_transform.rb +211 -0
- data/lib/coradoc/asciidoc/model/serialization/errors.rb +57 -0
- data/lib/coradoc/asciidoc/model/serialization.rb +39 -0
- data/lib/coradoc/asciidoc/model/spacing.rb +282 -0
- data/lib/coradoc/asciidoc/model/table.rb +44 -0
- data/lib/coradoc/asciidoc/model/table_cell.rb +122 -0
- data/lib/coradoc/asciidoc/model/table_row.rb +26 -0
- data/lib/coradoc/asciidoc/model/tag.rb +36 -0
- data/lib/coradoc/asciidoc/model/term.rb +48 -0
- data/lib/coradoc/asciidoc/model/text_element.rb +66 -0
- data/lib/coradoc/asciidoc/model/title.rb +85 -0
- data/lib/coradoc/asciidoc/model/video/attribute_list.rb +43 -0
- data/lib/coradoc/asciidoc/model/video.rb +49 -0
- data/lib/coradoc/asciidoc/model.rb +75 -0
- data/lib/coradoc/asciidoc/parse_error.rb +161 -0
- data/lib/coradoc/asciidoc/parser/admonition.rb +26 -0
- data/lib/coradoc/asciidoc/parser/attribute_list.rb +110 -0
- data/lib/coradoc/asciidoc/parser/base.rb +159 -0
- data/lib/coradoc/asciidoc/parser/bibliography.rb +31 -0
- data/lib/coradoc/asciidoc/parser/block.rb +186 -0
- data/lib/coradoc/asciidoc/parser/block_assembler.rb +183 -0
- data/lib/coradoc/asciidoc/parser/cache.rb +155 -0
- data/lib/coradoc/asciidoc/parser/citation.rb +32 -0
- data/lib/coradoc/asciidoc/parser/content.rb +76 -0
- data/lib/coradoc/asciidoc/parser/document_attributes.rb +27 -0
- data/lib/coradoc/asciidoc/parser/fix_files.rb +76 -0
- data/lib/coradoc/asciidoc/parser/header.rb +31 -0
- data/lib/coradoc/asciidoc/parser/inline.rb +199 -0
- data/lib/coradoc/asciidoc/parser/list.rb +130 -0
- data/lib/coradoc/asciidoc/parser/metadata_detector.rb +164 -0
- data/lib/coradoc/asciidoc/parser/paragraph.rb +64 -0
- data/lib/coradoc/asciidoc/parser/section.rb +62 -0
- data/lib/coradoc/asciidoc/parser/stem.rb +19 -0
- data/lib/coradoc/asciidoc/parser/table.rb +166 -0
- data/lib/coradoc/asciidoc/parser/term.rb +70 -0
- data/lib/coradoc/asciidoc/parser/text.rb +156 -0
- data/lib/coradoc/asciidoc/parser.rb +10 -0
- data/lib/coradoc/asciidoc/serializer/adoc_serializer.rb +86 -0
- data/lib/coradoc/asciidoc/serializer/element_registry.rb +95 -0
- data/lib/coradoc/asciidoc/serializer/fallback_serializer.rb +21 -0
- data/lib/coradoc/asciidoc/serializer/formatter.rb +144 -0
- data/lib/coradoc/asciidoc/serializer/registrations.rb +108 -0
- data/lib/coradoc/asciidoc/serializer/serialization_context.rb +238 -0
- data/lib/coradoc/asciidoc/serializer/serializers/admonition.rb +19 -0
- data/lib/coradoc/asciidoc/serializer/serializers/attribute.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/attribute_list.rb +40 -0
- data/lib/coradoc/asciidoc/serializer/serializers/attribute_list_attribute.rb +18 -0
- data/lib/coradoc/asciidoc/serializer/serializers/audio.rb +33 -0
- data/lib/coradoc/asciidoc/serializer/serializers/author.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/base.rb +152 -0
- data/lib/coradoc/asciidoc/serializer/serializers/bibliography.rb +35 -0
- data/lib/coradoc/asciidoc/serializer/serializers/bibliography_entry.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/core.rb +70 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/example.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/listing.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/literal.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/open.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/pass.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/quote.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/reviewer_comment.rb +17 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/side.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block/source_code.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/block.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/break.rb +18 -0
- data/lib/coradoc/asciidoc/serializer/serializers/comment_block.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/comment_line.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/document.rb +65 -0
- data/lib/coradoc/asciidoc/serializer/serializers/document_attributes.rb +21 -0
- data/lib/coradoc/asciidoc/serializer/serializers/header.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/highlight.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/image/core.rb +30 -0
- data/lib/coradoc/asciidoc/serializer/serializers/image.rb +14 -0
- data/lib/coradoc/asciidoc/serializer/serializers/include.rb +19 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/anchor.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/attribute_reference.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/bold.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/cross_reference.rb +30 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/cross_reference_arg.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/footnote.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/hard_line_break.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/highlight.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/italic.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/link.rb +38 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/monospace.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/quotation.rb +21 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/small.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/span.rb +35 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/stem.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/strikethrough.rb +29 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/subscript.rb +29 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/superscript.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline/underline.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/inline.rb +32 -0
- data/lib/coradoc/asciidoc/serializer/serializers/line_break.rb +18 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/core.rb +47 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/definition.rb +35 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/definition_item.rb +38 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/item.rb +120 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/ordered.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list/unordered.rb +29 -0
- data/lib/coradoc/asciidoc/serializer/serializers/list.rb +19 -0
- data/lib/coradoc/asciidoc/serializer/serializers/named_attribute.rb +22 -0
- data/lib/coradoc/asciidoc/serializer/serializers/paragraph.rb +65 -0
- data/lib/coradoc/asciidoc/serializer/serializers/reviewer_note.rb +28 -0
- data/lib/coradoc/asciidoc/serializer/serializers/revision.rb +26 -0
- data/lib/coradoc/asciidoc/serializer/serializers/section.rb +37 -0
- data/lib/coradoc/asciidoc/serializer/serializers/table.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/table_cell.rb +75 -0
- data/lib/coradoc/asciidoc/serializer/serializers/table_row.rb +24 -0
- data/lib/coradoc/asciidoc/serializer/serializers/tag.rb +19 -0
- data/lib/coradoc/asciidoc/serializer/serializers/term.rb +20 -0
- data/lib/coradoc/asciidoc/serializer/serializers/text_element.rb +23 -0
- data/lib/coradoc/asciidoc/serializer/serializers/title.rb +55 -0
- data/lib/coradoc/asciidoc/serializer/serializers/video.rb +33 -0
- data/lib/coradoc/asciidoc/serializer/spacing_strategy.rb +70 -0
- data/lib/coradoc/asciidoc/serializer.rb +75 -0
- data/lib/coradoc/asciidoc/transform/from_core_model.rb +502 -0
- data/lib/coradoc/asciidoc/transform/from_core_model_registrations.rb +126 -0
- data/lib/coradoc/asciidoc/transform/registry.rb +146 -0
- data/lib/coradoc/asciidoc/transform/to_core_model.rb +564 -0
- data/lib/coradoc/asciidoc/transform/to_core_model_registrations.rb +257 -0
- data/lib/coradoc/asciidoc/transform.rb +13 -0
- data/lib/coradoc/asciidoc/transformer/block_rules.rb +101 -0
- data/lib/coradoc/asciidoc/transformer/header_rules.rb +91 -0
- data/lib/coradoc/asciidoc/transformer/inline_rules.rb +179 -0
- data/lib/coradoc/asciidoc/transformer/list_rules.rb +131 -0
- data/lib/coradoc/asciidoc/transformer/misc_rules.rb +196 -0
- data/lib/coradoc/asciidoc/transformer/structural_rules.rb +216 -0
- data/lib/coradoc/asciidoc/transformer/text_rules.rb +107 -0
- data/lib/coradoc/asciidoc/transformer.rb +406 -0
- data/lib/coradoc/asciidoc/version.rb +7 -0
- data/lib/coradoc/asciidoc.rb +148 -0
- data/lib/coradoc/util/asciidoc.rb +71 -0
- data/lib/coradoc/util.rb +8 -0
- metadata +343 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
# Title element for sections and document headers.
|
|
7
|
+
#
|
|
8
|
+
# Represents a title with optional level information. Titles are used by
|
|
9
|
+
# sections to define their heading level and text content.
|
|
10
|
+
#
|
|
11
|
+
# @!attribute [r] id
|
|
12
|
+
# @return [String, nil] Optional identifier for the title
|
|
13
|
+
# @!attribute [r] content
|
|
14
|
+
# @return [Array<TextElement>] Title text content (can include inline formatting)
|
|
15
|
+
# @!attribute [r] level_int
|
|
16
|
+
# @return [Integer, nil] Heading level (0-5 for standard, 6+ uses style attribute)
|
|
17
|
+
# @!attribute [r] line_break
|
|
18
|
+
# @return [String] Line break character after title (default: newline)
|
|
19
|
+
# @!attribute [r] style
|
|
20
|
+
# @return [String, nil] Optional style attribute for title formatting
|
|
21
|
+
#
|
|
22
|
+
# @example Create a level 1 title
|
|
23
|
+
# title = Coradoc::AsciiDoc::Model::Title.new(
|
|
24
|
+
# content: [Coradoc::AsciiDoc::Model::TextElement.new("Chapter 1")],
|
|
25
|
+
# level_int: 0
|
|
26
|
+
# )
|
|
27
|
+
# title.to_adoc # => "= Chapter 1\n"
|
|
28
|
+
#
|
|
29
|
+
# @example Create a level 2 title
|
|
30
|
+
# title = Coradoc::AsciiDoc::Model::Title.new(
|
|
31
|
+
# content: [Coradoc::AsciiDoc::Model::TextElement.new("Section 1.1")],
|
|
32
|
+
# level_int: 1
|
|
33
|
+
# )
|
|
34
|
+
# title.to_adoc # => "== Section 1.1\n"
|
|
35
|
+
#
|
|
36
|
+
class Title < Base
|
|
37
|
+
include Coradoc::AsciiDoc::Model::Anchorable
|
|
38
|
+
|
|
39
|
+
attribute :id, :string
|
|
40
|
+
attribute :content, Coradoc::AsciiDoc::Model::TextElement, collection: true
|
|
41
|
+
# attribute :level, :string
|
|
42
|
+
attribute :level_int, :integer
|
|
43
|
+
attribute :line_break, :string, default: -> { "\n" }
|
|
44
|
+
attribute :style, :string
|
|
45
|
+
|
|
46
|
+
alias text content
|
|
47
|
+
|
|
48
|
+
# Convert title content to string
|
|
49
|
+
# @return [String] The title text
|
|
50
|
+
def to_s
|
|
51
|
+
case content
|
|
52
|
+
when String
|
|
53
|
+
content
|
|
54
|
+
when Array
|
|
55
|
+
content.map do |item|
|
|
56
|
+
item.is_a?(Coradoc::AsciiDoc::Model::TextElement) ? item.content.to_s : item.to_s
|
|
57
|
+
end.join
|
|
58
|
+
else
|
|
59
|
+
content.to_s
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def level_str
|
|
64
|
+
return '' if level_int.nil?
|
|
65
|
+
|
|
66
|
+
if level_int <= 5
|
|
67
|
+
'=' * (level_int + 1)
|
|
68
|
+
else
|
|
69
|
+
'======'
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def style_str
|
|
74
|
+
return '' if level_int.nil?
|
|
75
|
+
|
|
76
|
+
_style = [style]
|
|
77
|
+
_style << "level=#{level_int}" if level_int > 5
|
|
78
|
+
_style = _style.compact.join(',')
|
|
79
|
+
|
|
80
|
+
_style.empty? ? '' : "[#{_style}]\n"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
class Video < Base
|
|
7
|
+
class AttributeList < Coradoc::AsciiDoc::Model::AttributeList
|
|
8
|
+
extend AttributeList::Matchers
|
|
9
|
+
def positional_validators
|
|
10
|
+
[
|
|
11
|
+
[:alt, String],
|
|
12
|
+
[:width, Integer],
|
|
13
|
+
[:height, Integer]
|
|
14
|
+
]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def named_validators
|
|
18
|
+
{
|
|
19
|
+
title: String,
|
|
20
|
+
poster: String,
|
|
21
|
+
width: Integer,
|
|
22
|
+
height: Integer,
|
|
23
|
+
start: Integer,
|
|
24
|
+
end: Integer,
|
|
25
|
+
theme: one('dark', 'light'),
|
|
26
|
+
lang: /[a-z]{2,3}(?:-[A-Z]{2})?/,
|
|
27
|
+
list: String,
|
|
28
|
+
playlist: String,
|
|
29
|
+
options: many(
|
|
30
|
+
'autoplay',
|
|
31
|
+
'loop',
|
|
32
|
+
'modest',
|
|
33
|
+
'nocontrols',
|
|
34
|
+
'nofullscreen',
|
|
35
|
+
'muted'
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
# Video block element for AsciiDoc documents.
|
|
7
|
+
#
|
|
8
|
+
# Videos are embedded multimedia content with support for various
|
|
9
|
+
# video platforms and custom attributes.
|
|
10
|
+
#
|
|
11
|
+
# @!attribute [r] id
|
|
12
|
+
# @return [String, nil] Optional identifier for the video
|
|
13
|
+
#
|
|
14
|
+
# @!attribute [r] title
|
|
15
|
+
# @return [String, nil] Optional video title
|
|
16
|
+
#
|
|
17
|
+
# @!attribute [r] src
|
|
18
|
+
# @return [String] The video source URL or path
|
|
19
|
+
#
|
|
20
|
+
# @!attribute [r] attributes
|
|
21
|
+
# @return [Coradoc::AsciiDoc::Model::Video::AttributeList] Video-specific attributes
|
|
22
|
+
#
|
|
23
|
+
# @!attribute [r] line_break
|
|
24
|
+
# @return [String] Line break character (default: "\n")
|
|
25
|
+
#
|
|
26
|
+
# @example Create a video block
|
|
27
|
+
# video = Coradoc::AsciiDoc::Model::Video.new
|
|
28
|
+
# video.src = "https://example.com/video.mp4"
|
|
29
|
+
# video.title = "Demo Video"
|
|
30
|
+
#
|
|
31
|
+
class Video < Base
|
|
32
|
+
# Autoload nested AttributeList class
|
|
33
|
+
autoload :AttributeList, 'coradoc/asciidoc/model/video/attribute_list'
|
|
34
|
+
|
|
35
|
+
include Coradoc::AsciiDoc::Model::Anchorable
|
|
36
|
+
|
|
37
|
+
attribute :id, :string
|
|
38
|
+
attribute :title, :string
|
|
39
|
+
attribute :src, :string, default: -> { '' }
|
|
40
|
+
attribute :attributes,
|
|
41
|
+
Video::AttributeList,
|
|
42
|
+
default: lambda {
|
|
43
|
+
Coradoc::AsciiDoc::Model::AttributeList.new
|
|
44
|
+
}
|
|
45
|
+
attribute :line_break, :string, default: -> { "\n" }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# IMPORTANT: Load Serialization module eagerly — it registers the asciidoc
|
|
4
|
+
# format with Lutaml::Model, which is needed before any model class can
|
|
5
|
+
# use the asciidoc DSL.
|
|
6
|
+
require_relative 'model/serialization'
|
|
7
|
+
|
|
8
|
+
module Coradoc
|
|
9
|
+
module AsciiDoc
|
|
10
|
+
module Model
|
|
11
|
+
# Base class for all AsciiDoc model classes (no side effects)
|
|
12
|
+
autoload :Base, "#{__dir__}/model/base"
|
|
13
|
+
|
|
14
|
+
# Layer 0: Mixins (no dependencies)
|
|
15
|
+
autoload :Anchorable, "#{__dir__}/model/anchorable"
|
|
16
|
+
autoload :Attached, "#{__dir__}/model/attached"
|
|
17
|
+
autoload :Spacing, "#{__dir__}/model/spacing"
|
|
18
|
+
|
|
19
|
+
# Layer 1: Simple types (only depend on Layer 0)
|
|
20
|
+
autoload :Attribute, "#{__dir__}/model/attribute"
|
|
21
|
+
autoload :AttributeListAttribute, "#{__dir__}/model/attribute_list_attribute"
|
|
22
|
+
autoload :NamedAttribute, "#{__dir__}/model/named_attribute"
|
|
23
|
+
autoload :RejectedPositionalAttribute, "#{__dir__}/model/rejected_positional_attribute"
|
|
24
|
+
autoload :AttributeList, "#{__dir__}/model/attribute_list"
|
|
25
|
+
autoload :Author, "#{__dir__}/model/author"
|
|
26
|
+
autoload :Revision, "#{__dir__}/model/revision"
|
|
27
|
+
autoload :Break, "#{__dir__}/model/break"
|
|
28
|
+
autoload :CommentBlock, "#{__dir__}/model/comment_block"
|
|
29
|
+
autoload :CommentLine, "#{__dir__}/model/comment_line"
|
|
30
|
+
autoload :Glossaries, "#{__dir__}/model/glossaries"
|
|
31
|
+
autoload :Include, "#{__dir__}/model/include"
|
|
32
|
+
autoload :Tag, "#{__dir__}/model/tag"
|
|
33
|
+
|
|
34
|
+
# Layer 2-3: Text types
|
|
35
|
+
autoload :TextElement, "#{__dir__}/model/text_element"
|
|
36
|
+
autoload :Admonition, "#{__dir__}/model/admonition"
|
|
37
|
+
autoload :Highlight, "#{__dir__}/model/highlight"
|
|
38
|
+
autoload :LineBreak, "#{__dir__}/model/line_break"
|
|
39
|
+
autoload :Title, "#{__dir__}/model/title"
|
|
40
|
+
autoload :Paragraph, "#{__dir__}/model/paragraph"
|
|
41
|
+
|
|
42
|
+
# Layer 4-5: Block and List types
|
|
43
|
+
autoload :Block, "#{__dir__}/model/block"
|
|
44
|
+
autoload :ContentList, "#{__dir__}/model/content_list"
|
|
45
|
+
autoload :Term, "#{__dir__}/model/term"
|
|
46
|
+
autoload :List, "#{__dir__}/model/list"
|
|
47
|
+
|
|
48
|
+
# Layer 6: Structural types
|
|
49
|
+
autoload :DocumentAttributes, "#{__dir__}/model/document_attributes"
|
|
50
|
+
autoload :Header, "#{__dir__}/model/header"
|
|
51
|
+
autoload :Section, "#{__dir__}/model/section"
|
|
52
|
+
|
|
53
|
+
# Layer 7-8: Content types
|
|
54
|
+
autoload :Audio, "#{__dir__}/model/audio"
|
|
55
|
+
autoload :BibliographyEntry, "#{__dir__}/model/bibliography_entry"
|
|
56
|
+
autoload :Bibliography, "#{__dir__}/model/bibliography"
|
|
57
|
+
autoload :Video, "#{__dir__}/model/video"
|
|
58
|
+
autoload :Image, "#{__dir__}/model/image"
|
|
59
|
+
|
|
60
|
+
# Layer 9: Table types
|
|
61
|
+
autoload :TableCell, "#{__dir__}/model/table_cell"
|
|
62
|
+
autoload :TableRow, "#{__dir__}/model/table_row"
|
|
63
|
+
autoload :Table, "#{__dir__}/model/table"
|
|
64
|
+
|
|
65
|
+
# Layer 10: Inline types
|
|
66
|
+
autoload :Inline, "#{__dir__}/model/inline"
|
|
67
|
+
|
|
68
|
+
# Layer 11: Complex types
|
|
69
|
+
autoload :ReviewerNote, "#{__dir__}/model/reviewer_note"
|
|
70
|
+
|
|
71
|
+
# Layer 12: Document
|
|
72
|
+
autoload :Document, "#{__dir__}/model/document"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
# Custom error class for parsing failures
|
|
6
|
+
#
|
|
7
|
+
# Provides detailed context about where parsing failed, including
|
|
8
|
+
# line number, column position, and source snippet.
|
|
9
|
+
#
|
|
10
|
+
# @example Raising a parse error
|
|
11
|
+
# raise Coradoc::AsciiDoc::ParseError.new(
|
|
12
|
+
# "Unexpected token",
|
|
13
|
+
# line: 42,
|
|
14
|
+
# column: 10,
|
|
15
|
+
# source: "line with error",
|
|
16
|
+
# suggestion: "Did you mean X?"
|
|
17
|
+
# )
|
|
18
|
+
#
|
|
19
|
+
class ParseError < Error
|
|
20
|
+
# @return [Integer, nil] Line number where error occurred
|
|
21
|
+
attr_reader :line
|
|
22
|
+
|
|
23
|
+
# @return [Integer, nil] Column position where error occurred
|
|
24
|
+
attr_reader :column
|
|
25
|
+
|
|
26
|
+
# @return [String, nil] Source line containing the error
|
|
27
|
+
attr_reader :source_line
|
|
28
|
+
|
|
29
|
+
# @return [String, nil] Helpful suggestion for fixing the error
|
|
30
|
+
attr_reader :suggestion
|
|
31
|
+
|
|
32
|
+
# @return [String, nil] Full source content (for multi-line context)
|
|
33
|
+
attr_reader :source
|
|
34
|
+
|
|
35
|
+
# @return [Exception, nil] Original exception that caused this error
|
|
36
|
+
attr_reader :cause
|
|
37
|
+
|
|
38
|
+
# Create a new ParseError
|
|
39
|
+
#
|
|
40
|
+
# @param message [String] Error description
|
|
41
|
+
# @param line [Integer, nil] Line number (1-indexed)
|
|
42
|
+
# @param column [Integer, nil] Column position (1-indexed)
|
|
43
|
+
# @param source_line [String, nil] The source line containing the error
|
|
44
|
+
# @param source [String, nil] Full source content
|
|
45
|
+
# @param suggestion [String, nil] Suggestion for fixing the error
|
|
46
|
+
# @param cause [Exception, nil] Original exception that caused this error
|
|
47
|
+
def initialize(message, line: nil, column: nil, source_line: nil, source: nil, suggestion: nil, cause: nil)
|
|
48
|
+
@line = line
|
|
49
|
+
@column = column
|
|
50
|
+
@source_line = source_line
|
|
51
|
+
@source = source
|
|
52
|
+
@suggestion = suggestion
|
|
53
|
+
@cause = cause
|
|
54
|
+
|
|
55
|
+
full_message = build_full_message(message)
|
|
56
|
+
super(full_message)
|
|
57
|
+
|
|
58
|
+
set_backtrace(cause.backtrace) if cause&.backtrace
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Build a formatted error message with context
|
|
62
|
+
#
|
|
63
|
+
# @param base_message [String] The base error message
|
|
64
|
+
# @return [String] Formatted error message with location context
|
|
65
|
+
def build_full_message(base_message)
|
|
66
|
+
parts = [base_message]
|
|
67
|
+
|
|
68
|
+
if line && column
|
|
69
|
+
parts << "at line #{line}, column #{column}"
|
|
70
|
+
elsif line
|
|
71
|
+
parts << "at line #{line}"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
if source_line
|
|
75
|
+
parts << "\n > #{source_line}"
|
|
76
|
+
parts << " > #{' ' * (column - 1)}^" if column&.positive?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
parts << "\n Suggestion: #{suggestion}" if suggestion
|
|
80
|
+
|
|
81
|
+
parts.join("\n")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Create a ParseError from a Parslet exception
|
|
85
|
+
#
|
|
86
|
+
# @param exception [Parslet::ParseFailed] The Parslet exception
|
|
87
|
+
# @param source [String] The original source text
|
|
88
|
+
# @return [ParseError] A new ParseError with extracted context
|
|
89
|
+
def self.from_parslet(exception, source = nil)
|
|
90
|
+
return exception if exception.is_a?(ParseError)
|
|
91
|
+
|
|
92
|
+
line, column = extract_location(exception)
|
|
93
|
+
source_line = extract_source_line(source, line)
|
|
94
|
+
suggestion = generate_suggestion(exception)
|
|
95
|
+
|
|
96
|
+
new(
|
|
97
|
+
exception.message,
|
|
98
|
+
line: line,
|
|
99
|
+
column: column,
|
|
100
|
+
source_line: source_line,
|
|
101
|
+
source: source,
|
|
102
|
+
suggestion: suggestion,
|
|
103
|
+
cause: exception
|
|
104
|
+
)
|
|
105
|
+
rescue StandardError
|
|
106
|
+
# If we can't extract details, wrap the original exception
|
|
107
|
+
new(exception.message, cause: exception)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Extract line and column from Parslet error
|
|
111
|
+
#
|
|
112
|
+
# @param exception [Parslet::ParseFailed] The Parslet exception
|
|
113
|
+
# @return [Array<Integer, Integer>] Line and column numbers
|
|
114
|
+
def self.extract_location(exception)
|
|
115
|
+
return [nil, nil] unless exception.is_a?(Parslet::ParseFailed)
|
|
116
|
+
|
|
117
|
+
cause = exception.cause
|
|
118
|
+
return [nil, nil] unless cause
|
|
119
|
+
|
|
120
|
+
[cause.source_line, cause.source_column]
|
|
121
|
+
rescue NoMethodError
|
|
122
|
+
[nil, nil]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Extract the relevant source line
|
|
126
|
+
#
|
|
127
|
+
# @param source [String, nil] Full source text
|
|
128
|
+
# @param line [Integer, nil] Line number
|
|
129
|
+
# @return [String, nil] The source line
|
|
130
|
+
def self.extract_source_line(source, line)
|
|
131
|
+
return nil if source.nil? || line.nil?
|
|
132
|
+
|
|
133
|
+
lines = source.split("\n")
|
|
134
|
+
lines[line - 1] if line.positive? && line <= lines.length
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Generate a helpful suggestion based on the error
|
|
138
|
+
#
|
|
139
|
+
# @param exception [Exception] The parsing exception
|
|
140
|
+
# @return [String, nil] A suggestion string
|
|
141
|
+
def self.generate_suggestion(exception)
|
|
142
|
+
message = exception.message.to_s.downcase
|
|
143
|
+
|
|
144
|
+
case message
|
|
145
|
+
when /expected.*heading/
|
|
146
|
+
"Make sure headings start with '=' followed by a space"
|
|
147
|
+
when /expected.*list/
|
|
148
|
+
"List items should start with '*', '.', or a term followed by '::'"
|
|
149
|
+
when /expected.*table/
|
|
150
|
+
"Tables require '|===' delimiters and '|' for cell separators"
|
|
151
|
+
when /expected.*block/
|
|
152
|
+
'Block delimiters should be 4 identical characters (----, ====, etc.)'
|
|
153
|
+
when /expected.*attribute/
|
|
154
|
+
"Attributes should be in the format ':name: value'"
|
|
155
|
+
when /unexpected.*end/
|
|
156
|
+
'Check for missing closing delimiters or incomplete syntax'
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Parser
|
|
6
|
+
module Admonition
|
|
7
|
+
def admonition_type
|
|
8
|
+
str('NOTE') | str('TIP') | str('EDITOR') |
|
|
9
|
+
str('IMPORTANT') | str('WARNING') | str('CAUTION') |
|
|
10
|
+
str('TODO')
|
|
11
|
+
# requires atypical syntax for access?
|
|
12
|
+
# | str('DANGER')
|
|
13
|
+
# | str('SAFETY PRECAUTION')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def admonition_line
|
|
17
|
+
admonition_type.as(:admonition_type) >> str(': ') >>
|
|
18
|
+
(text.as(:text) >>
|
|
19
|
+
line_ending.as(:line_break)
|
|
20
|
+
).repeat(1)
|
|
21
|
+
.as(:content)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Parser
|
|
6
|
+
module AttributeList
|
|
7
|
+
def named_attribute_name
|
|
8
|
+
attribute_name
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def named_value_noquote
|
|
12
|
+
match('[^\],]').repeat(1)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def named_value_single_quote
|
|
16
|
+
str("'") >>
|
|
17
|
+
match("[^']").repeat(1) >>
|
|
18
|
+
str("'")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def named_value_double_quote
|
|
22
|
+
str('"') >>
|
|
23
|
+
match('[^"]').repeat(1) >>
|
|
24
|
+
str('"')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def named_value
|
|
28
|
+
(named_value_single_quote |
|
|
29
|
+
named_value_double_quote |
|
|
30
|
+
named_value_noquote
|
|
31
|
+
).as(:named_value)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def named_key
|
|
35
|
+
match('[a-zA-Z0-9_-]').repeat(1).as(:named_key)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def named_attribute
|
|
39
|
+
(named_key >>
|
|
40
|
+
str(' ').maybe >> str('=') >> str(' ').maybe >>
|
|
41
|
+
named_value >>
|
|
42
|
+
str(' ').maybe
|
|
43
|
+
).as(:named)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def positional_value_unquoted
|
|
47
|
+
match['a-zA-Z0-9_\-%.'].repeat(1)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def positional_value_single_quote
|
|
51
|
+
str("'") >>
|
|
52
|
+
match("[^']").repeat(1) >>
|
|
53
|
+
str("'")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def positional_value_double_quote
|
|
57
|
+
str('"') >>
|
|
58
|
+
match('[^"]').repeat(1) >>
|
|
59
|
+
str('"')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def positional_attribute
|
|
63
|
+
((positional_value_single_quote |
|
|
64
|
+
positional_value_double_quote |
|
|
65
|
+
positional_value_unquoted
|
|
66
|
+
) >>
|
|
67
|
+
str('=').absent?
|
|
68
|
+
).as(:positional)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def named_many
|
|
72
|
+
(named_attribute.repeat(1, 1) >>
|
|
73
|
+
(str(',') >> space.maybe >> named_attribute).repeat(0))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def positional_one_named_many
|
|
77
|
+
(positional_attribute.repeat(1, 1) >>
|
|
78
|
+
(str(',') >> space.maybe >> named_attribute).repeat(1))
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def positional_many_named_many
|
|
82
|
+
(positional_attribute.repeat(1, 1) >>
|
|
83
|
+
(str(',') >> space.maybe >> positional_attribute).repeat(1) >>
|
|
84
|
+
(str(',') >> space.maybe >> named_attribute).repeat(1))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def positional_many
|
|
88
|
+
(positional_attribute.repeat(1, 1) >>
|
|
89
|
+
(str(',') >> space.maybe >> positional_attribute).repeat(0))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def positional_zero_or_one
|
|
93
|
+
positional_attribute.repeat(0, 1)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def attribute_list(name = :attribute_list)
|
|
97
|
+
str('[').present? >>
|
|
98
|
+
str('[') >> str('[').absent? >>
|
|
99
|
+
(named_many |
|
|
100
|
+
positional_one_named_many |
|
|
101
|
+
positional_many_named_many |
|
|
102
|
+
positional_many |
|
|
103
|
+
positional_zero_or_one
|
|
104
|
+
).as(:attribute_array).as(name) >>
|
|
105
|
+
str(']')
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|