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,334 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
# A list of content elements that provides unified content handling
|
|
7
|
+
#
|
|
8
|
+
# ContentList handles mixed content types (strings, TextElements, model objects)
|
|
9
|
+
# and provides a consistent API for querying and manipulating content.
|
|
10
|
+
#
|
|
11
|
+
# @example Create from strings
|
|
12
|
+
# content = ContentList.new("Hello", "World")
|
|
13
|
+
# content.text # => "HelloWorld"
|
|
14
|
+
#
|
|
15
|
+
# @example Create from mixed types
|
|
16
|
+
# content = ContentList.new([
|
|
17
|
+
# "Hello ",
|
|
18
|
+
# Bold.new("World"),
|
|
19
|
+
# "!"
|
|
20
|
+
# ])
|
|
21
|
+
# content.text # => "Hello World!"
|
|
22
|
+
#
|
|
23
|
+
# @example Query by type
|
|
24
|
+
# bold_items = content.find_type(Inline::Bold)
|
|
25
|
+
#
|
|
26
|
+
# @example Iterate elements
|
|
27
|
+
# content.each do |element|
|
|
28
|
+
# puts element.class
|
|
29
|
+
# end
|
|
30
|
+
#
|
|
31
|
+
class ContentList
|
|
32
|
+
include Enumerable
|
|
33
|
+
|
|
34
|
+
# Get the raw items array
|
|
35
|
+
#
|
|
36
|
+
# @return [Array] The content items
|
|
37
|
+
attr_reader :items
|
|
38
|
+
|
|
39
|
+
# Create a new ContentList
|
|
40
|
+
#
|
|
41
|
+
# @param items [Array, String, Object] Content items to initialize with
|
|
42
|
+
#
|
|
43
|
+
# @example From strings
|
|
44
|
+
# ContentList.new("Hello", "World")
|
|
45
|
+
#
|
|
46
|
+
# @example From array
|
|
47
|
+
# ContentList.new(["Hello", Bold.new("World")])
|
|
48
|
+
#
|
|
49
|
+
# @example From nested array
|
|
50
|
+
# ContentList.new([["Hello", " "], "World"])
|
|
51
|
+
#
|
|
52
|
+
def initialize(*items)
|
|
53
|
+
@items = normalize(items.flatten)
|
|
54
|
+
freeze
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Create a ContentList from a single value
|
|
58
|
+
#
|
|
59
|
+
# @param value [Object] The content value
|
|
60
|
+
# @return [ContentList] New ContentList
|
|
61
|
+
#
|
|
62
|
+
# @example From string
|
|
63
|
+
# ContentList.from("Hello")
|
|
64
|
+
#
|
|
65
|
+
# @example From array
|
|
66
|
+
# ContentList.from(["Hello", "World"])
|
|
67
|
+
#
|
|
68
|
+
def self.from(value)
|
|
69
|
+
case value
|
|
70
|
+
when ContentList
|
|
71
|
+
value
|
|
72
|
+
when Array
|
|
73
|
+
new(*value)
|
|
74
|
+
when nil
|
|
75
|
+
new
|
|
76
|
+
else
|
|
77
|
+
new(value)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Iterate over content items
|
|
82
|
+
#
|
|
83
|
+
# @yield [Object] Each content item
|
|
84
|
+
# @return [Enumerator] If no block given
|
|
85
|
+
#
|
|
86
|
+
# @example Iterate
|
|
87
|
+
# content.each { |item| puts item }
|
|
88
|
+
#
|
|
89
|
+
def each(&block)
|
|
90
|
+
@items.each(&block)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Add an item to the content
|
|
94
|
+
#
|
|
95
|
+
# @param item [Object] Item to add
|
|
96
|
+
# @return [ContentList] Self for chaining
|
|
97
|
+
#
|
|
98
|
+
# @example Add item
|
|
99
|
+
# content << "more text"
|
|
100
|
+
#
|
|
101
|
+
# Note: This returns a new ContentList since ContentList is immutable
|
|
102
|
+
#
|
|
103
|
+
def <<(item)
|
|
104
|
+
ContentList.new(*@items, coerce(item))
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Get all items as a plain string
|
|
108
|
+
#
|
|
109
|
+
# @return [String] All items joined as string
|
|
110
|
+
#
|
|
111
|
+
# @example Get text
|
|
112
|
+
# content.text # => "Hello World"
|
|
113
|
+
#
|
|
114
|
+
def text
|
|
115
|
+
@items.map(&:to_s).join
|
|
116
|
+
end
|
|
117
|
+
alias to_str text
|
|
118
|
+
alias to_s text
|
|
119
|
+
|
|
120
|
+
# Find all items of a specific type
|
|
121
|
+
#
|
|
122
|
+
# @param type [Class, Module] Type to find
|
|
123
|
+
# @return [Array] Items of the specified type
|
|
124
|
+
#
|
|
125
|
+
# @example Find bold items
|
|
126
|
+
# content.find_type(Inline::Bold)
|
|
127
|
+
#
|
|
128
|
+
def find_type(type)
|
|
129
|
+
@items.select { |item| item.is_a?(type) }
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Check if content is empty
|
|
133
|
+
#
|
|
134
|
+
# @return [Boolean] true if no items
|
|
135
|
+
#
|
|
136
|
+
def empty?
|
|
137
|
+
@items.empty?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Get number of items
|
|
141
|
+
#
|
|
142
|
+
# @return [Integer] Number of items
|
|
143
|
+
#
|
|
144
|
+
def size
|
|
145
|
+
@items.size
|
|
146
|
+
end
|
|
147
|
+
alias length size
|
|
148
|
+
|
|
149
|
+
# Get item at index
|
|
150
|
+
#
|
|
151
|
+
# @param index [Integer] Index
|
|
152
|
+
# @return [Object, nil] Item at index or nil
|
|
153
|
+
#
|
|
154
|
+
def [](index)
|
|
155
|
+
@items[index]
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Get first item
|
|
159
|
+
#
|
|
160
|
+
# @return [Object, nil] First item or nil
|
|
161
|
+
#
|
|
162
|
+
def first
|
|
163
|
+
@items.first
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Get last item
|
|
167
|
+
#
|
|
168
|
+
# @return [Object, nil] Last item or nil
|
|
169
|
+
#
|
|
170
|
+
def last
|
|
171
|
+
@items.last
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Convert to array
|
|
175
|
+
#
|
|
176
|
+
# @return [Array] Items as array
|
|
177
|
+
#
|
|
178
|
+
def to_a
|
|
179
|
+
@items.dup
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Join items with a separator
|
|
183
|
+
#
|
|
184
|
+
# @param sep [String] Separator
|
|
185
|
+
# @return [String] Joined string
|
|
186
|
+
#
|
|
187
|
+
# @example Join with spaces
|
|
188
|
+
# content.join(" ") # => "Hello World"
|
|
189
|
+
#
|
|
190
|
+
def join(sep = '')
|
|
191
|
+
@items.map(&:to_s).join(sep)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Map over items
|
|
195
|
+
#
|
|
196
|
+
# @yield [Object] Each item
|
|
197
|
+
# @return [Array] Mapped items
|
|
198
|
+
#
|
|
199
|
+
# @example Map
|
|
200
|
+
# content.map(&:class) # => [String, Bold, String]
|
|
201
|
+
#
|
|
202
|
+
def map(&block)
|
|
203
|
+
@items.map(&block)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Select items matching predicate
|
|
207
|
+
#
|
|
208
|
+
# @yield [Object] Each item
|
|
209
|
+
# @return [Array] Selected items
|
|
210
|
+
#
|
|
211
|
+
# @example Select strings
|
|
212
|
+
# content.select { |i| i.is_a?(String) }
|
|
213
|
+
#
|
|
214
|
+
def select(&block)
|
|
215
|
+
@items.select(&block)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Reject items matching predicate
|
|
219
|
+
#
|
|
220
|
+
# @yield [Object] Each item
|
|
221
|
+
# @return [Array] Remaining items
|
|
222
|
+
#
|
|
223
|
+
def reject(&block)
|
|
224
|
+
@items.reject(&block)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Check if content includes an item
|
|
228
|
+
#
|
|
229
|
+
# @param item [Object] Item to check
|
|
230
|
+
# @return [Boolean] true if item is in content
|
|
231
|
+
#
|
|
232
|
+
def include?(item)
|
|
233
|
+
@items.include?(item)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Check if content includes an item of a type
|
|
237
|
+
#
|
|
238
|
+
# @param type [Class, Module] Type to check
|
|
239
|
+
# @return [Boolean] true if any item is of the type
|
|
240
|
+
#
|
|
241
|
+
# @example Check for bold
|
|
242
|
+
# content.include_type?(Inline::Bold)
|
|
243
|
+
#
|
|
244
|
+
def include_type?(type)
|
|
245
|
+
@items.any? { |item| item.is_a?(type) }
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Concatenate another ContentList or array
|
|
249
|
+
#
|
|
250
|
+
# @param other [ContentList, Array] Other content to add
|
|
251
|
+
# @return [ContentList] New ContentList with combined items
|
|
252
|
+
#
|
|
253
|
+
# @example Concatenate
|
|
254
|
+
# content + ContentList.new("more")
|
|
255
|
+
#
|
|
256
|
+
def +(other)
|
|
257
|
+
other_items = other.is_a?(ContentList) ? other.items : Array(other)
|
|
258
|
+
ContentList.new(*@items, *other_items)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# String representation for debugging
|
|
262
|
+
#
|
|
263
|
+
# @return [String] Debug string
|
|
264
|
+
#
|
|
265
|
+
def inspect
|
|
266
|
+
"#<#{self.class.name} size=#{@items.size} items=#{@items.inspect}>"
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Two ContentLists are equal if their items are equal
|
|
270
|
+
#
|
|
271
|
+
# @param other [Object] Object to compare
|
|
272
|
+
# @return [Boolean] true if equal
|
|
273
|
+
#
|
|
274
|
+
def ==(other)
|
|
275
|
+
return false unless other.is_a?(ContentList)
|
|
276
|
+
|
|
277
|
+
@items == other.items
|
|
278
|
+
end
|
|
279
|
+
alias eql? ==
|
|
280
|
+
|
|
281
|
+
# Hash code for use in Hash keys
|
|
282
|
+
#
|
|
283
|
+
# @return [Integer] Hash code
|
|
284
|
+
#
|
|
285
|
+
def hash
|
|
286
|
+
@items.hash
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
private
|
|
290
|
+
|
|
291
|
+
# Normalize items to appropriate content types
|
|
292
|
+
#
|
|
293
|
+
# @param items [Array] Raw items
|
|
294
|
+
# @return [Array] Normalized items
|
|
295
|
+
#
|
|
296
|
+
def normalize(items)
|
|
297
|
+
items.map { |item| coerce(item) }
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Coerce an item to appropriate content type
|
|
301
|
+
#
|
|
302
|
+
# @param item [Object] Item to coerce
|
|
303
|
+
# @return [Object] Coerced item
|
|
304
|
+
#
|
|
305
|
+
def coerce(item)
|
|
306
|
+
case item
|
|
307
|
+
when String
|
|
308
|
+
# Convert string to TextElement
|
|
309
|
+
TextElement.new(content: item)
|
|
310
|
+
when TextElement, Model::Base
|
|
311
|
+
# Already appropriate type
|
|
312
|
+
item
|
|
313
|
+
when nil
|
|
314
|
+
# Skip nil items
|
|
315
|
+
nil
|
|
316
|
+
when Hash
|
|
317
|
+
# Convert hash to TextElement if it has content key
|
|
318
|
+
if item[:content] || item['content']
|
|
319
|
+
TextElement.from_hash(item)
|
|
320
|
+
else
|
|
321
|
+
TextElement.new(content: item.inspect)
|
|
322
|
+
end
|
|
323
|
+
when Array
|
|
324
|
+
# Flatten nested arrays
|
|
325
|
+
normalize(item)
|
|
326
|
+
else
|
|
327
|
+
# Try to convert to string, then to TextElement
|
|
328
|
+
TextElement.new(content: item.to_s)
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
autoload :Resolver, "#{__dir__}/resolver"
|
|
7
|
+
|
|
8
|
+
# Document model representing an AsciiDoc document.
|
|
9
|
+
#
|
|
10
|
+
# The Document class is the main container for parsed AsciiDoc content.
|
|
11
|
+
# It holds the document's header, attributes, and sections (blocks, lists, etc.).
|
|
12
|
+
#
|
|
13
|
+
# @!attribute [r] document_attributes
|
|
14
|
+
# @return [DocumentAttributes] Document-level attributes like author, date, etc.
|
|
15
|
+
# @!attribute [r] header
|
|
16
|
+
# @return [Header] Document header containing title and metadata
|
|
17
|
+
# @!attribute [r] sections
|
|
18
|
+
# @return [Array<Base>] Document content blocks (sections, paragraphs, lists, etc.)
|
|
19
|
+
#
|
|
20
|
+
# @example Create a new document
|
|
21
|
+
# doc = Coradoc::AsciiDoc::Model::Document.new(
|
|
22
|
+
# header: Coradoc::AsciiDoc::Model::Header.new(title: "My Document"),
|
|
23
|
+
# sections: [Coradoc::AsciiDoc::Model::Paragraph.new("Hello World")]
|
|
24
|
+
# )
|
|
25
|
+
#
|
|
26
|
+
# @example Parse and serialize
|
|
27
|
+
# doc = Coradoc.parse("= Title\n\nContent")
|
|
28
|
+
# doc.to_adoc # => "= Title\n\nContent"
|
|
29
|
+
#
|
|
30
|
+
# @example Expand includes
|
|
31
|
+
# doc = Coradoc.parse_file("main.adoc")
|
|
32
|
+
# expanded = doc.expand_includes("/path/to/docs")
|
|
33
|
+
#
|
|
34
|
+
# @example Freeze document with unified resolution
|
|
35
|
+
# frozen = doc.freeze(base_dir: "/path/to/docs", includes: true, images: :reference)
|
|
36
|
+
#
|
|
37
|
+
class Document < Base
|
|
38
|
+
attribute :document_attributes,
|
|
39
|
+
Coradoc::AsciiDoc::Model::DocumentAttributes,
|
|
40
|
+
default: lambda {
|
|
41
|
+
Coradoc::AsciiDoc::Model::DocumentAttributes.new
|
|
42
|
+
}
|
|
43
|
+
attribute :header,
|
|
44
|
+
Coradoc::AsciiDoc::Model::Header,
|
|
45
|
+
default: lambda {
|
|
46
|
+
Coradoc::AsciiDoc::Model::Header.new(
|
|
47
|
+
title: Coradoc::AsciiDoc::Model::Title.new(content: '')
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
attribute :sections,
|
|
52
|
+
Coradoc::AsciiDoc::Model::Base,
|
|
53
|
+
collection: true,
|
|
54
|
+
initialize_empty: true,
|
|
55
|
+
polymorphic: [
|
|
56
|
+
Coradoc::AsciiDoc::Model::Admonition,
|
|
57
|
+
Coradoc::AsciiDoc::Model::Audio,
|
|
58
|
+
Coradoc::AsciiDoc::Model::BibliographyEntry,
|
|
59
|
+
Coradoc::AsciiDoc::Model::Block::Core,
|
|
60
|
+
Coradoc::AsciiDoc::Model::Image::BlockImage,
|
|
61
|
+
Coradoc::AsciiDoc::Model::CommentBlock,
|
|
62
|
+
Coradoc::AsciiDoc::Model::CommentLine,
|
|
63
|
+
Coradoc::AsciiDoc::Model::Include,
|
|
64
|
+
Coradoc::AsciiDoc::Model::LineBreak,
|
|
65
|
+
Coradoc::AsciiDoc::Model::List::Core,
|
|
66
|
+
Coradoc::AsciiDoc::Model::Paragraph,
|
|
67
|
+
Coradoc::AsciiDoc::Model::Table,
|
|
68
|
+
Coradoc::AsciiDoc::Model::Tag,
|
|
69
|
+
Coradoc::AsciiDoc::Model::Video
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
# @param [Integer] index The index of the section to retrieve
|
|
73
|
+
# @return [Coradoc::AsciiDoc::Model::Base] The section at the specified index
|
|
74
|
+
def [](index)
|
|
75
|
+
sections[index]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @param [Integer] index The index of the section to set
|
|
79
|
+
# @param [Coradoc::AsciiDoc::Model::Base] value The section to set at the specified index
|
|
80
|
+
# @return [Coradoc::AsciiDoc::Model::Base] The section that was set
|
|
81
|
+
def []=(index, value)
|
|
82
|
+
sections[index] = value
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Expand include directives in the document
|
|
86
|
+
# @param base_dir [String] Base directory for resolving relative includes
|
|
87
|
+
# @return [Coradoc::AsciiDoc::Model::Document] A new document with includes expanded
|
|
88
|
+
def expand_includes(base_dir = '.')
|
|
89
|
+
freeze(base_dir: base_dir, includes: true, images: :reference, media: :reference)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Freeze the document by resolving external references.
|
|
93
|
+
#
|
|
94
|
+
# This method creates a NEW document with resolved references.
|
|
95
|
+
# The original document is never modified (immutable principle).
|
|
96
|
+
#
|
|
97
|
+
# @param options [Hash] Resolution options
|
|
98
|
+
# @option options [String] :base_dir Base directory for relative paths (default: ".")
|
|
99
|
+
# @option options [Boolean] :includes Resolve include:: directives (default: true)
|
|
100
|
+
# @option options [Symbol] :images Image resolution: :reference, :copy, :embed (default: :reference)
|
|
101
|
+
# @option options [Symbol] :media Media resolution: :reference, :copy (default: :reference)
|
|
102
|
+
# @option options [String] :output_dir Output directory for :copy mode
|
|
103
|
+
# @option options [Integer] :max_recursion Maximum recursion depth for includes (default: 10)
|
|
104
|
+
# @return [Document] NEW document with resolved references
|
|
105
|
+
#
|
|
106
|
+
# @example Resolve includes only
|
|
107
|
+
# frozen = doc.freeze(base_dir: "/docs", includes: true)
|
|
108
|
+
#
|
|
109
|
+
# @example Create self-contained document
|
|
110
|
+
# frozen = doc.freeze(
|
|
111
|
+
# base_dir: "/docs",
|
|
112
|
+
# includes: true,
|
|
113
|
+
# images: :embed,
|
|
114
|
+
# output_dir: "/output"
|
|
115
|
+
# )
|
|
116
|
+
#
|
|
117
|
+
def freeze(options = {})
|
|
118
|
+
resolver = Resolver.new(options)
|
|
119
|
+
base_dir = options[:base_dir] || '.'
|
|
120
|
+
resolver.resolve_document(self, base_dir)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
class << self
|
|
124
|
+
def from_ast(elements)
|
|
125
|
+
sections = []
|
|
126
|
+
document_attributes = nil
|
|
127
|
+
header = nil
|
|
128
|
+
|
|
129
|
+
elements.each do |element|
|
|
130
|
+
case element
|
|
131
|
+
when Coradoc::AsciiDoc::Model::DocumentAttributes
|
|
132
|
+
document_attributes = element
|
|
133
|
+
|
|
134
|
+
when Coradoc::AsciiDoc::Model::Header
|
|
135
|
+
header = element
|
|
136
|
+
|
|
137
|
+
when Coradoc::AsciiDoc::Model::Base
|
|
138
|
+
sections << element
|
|
139
|
+
|
|
140
|
+
else
|
|
141
|
+
warn "Unknown element type: #{element.class}"
|
|
142
|
+
warn "Element: #{element.inspect}"
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Merge standalone LineBreak elements into the previous element's line_break
|
|
147
|
+
merge_line_breaks(sections)
|
|
148
|
+
|
|
149
|
+
# Only pass non-nil values to preserve defaults
|
|
150
|
+
attrs = { sections: sections }
|
|
151
|
+
attrs[:document_attributes] = document_attributes if document_attributes
|
|
152
|
+
attrs[:header] = header if header
|
|
153
|
+
|
|
154
|
+
new(attrs)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
private
|
|
158
|
+
|
|
159
|
+
def merge_line_breaks(sections)
|
|
160
|
+
return if sections.empty?
|
|
161
|
+
|
|
162
|
+
# Skip leading LineBreak elements
|
|
163
|
+
sections.shift while sections.first.is_a?(Coradoc::AsciiDoc::Model::LineBreak)
|
|
164
|
+
|
|
165
|
+
i = 0
|
|
166
|
+
while i < sections.length
|
|
167
|
+
# If current element is a LineBreak and there's a previous element
|
|
168
|
+
if sections[i].is_a?(Coradoc::AsciiDoc::Model::LineBreak) && i.positive?
|
|
169
|
+
prev = sections[i - 1]
|
|
170
|
+
line_break = sections[i]
|
|
171
|
+
|
|
172
|
+
# Skip consecutive LineBreaks
|
|
173
|
+
if prev.is_a?(Coradoc::AsciiDoc::Model::LineBreak)
|
|
174
|
+
sections.delete_at(i)
|
|
175
|
+
next
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Merge the line break into the previous element if it has a line_break attribute
|
|
179
|
+
if prev.is_a?(Coradoc::AsciiDoc::Model::Base) && prev.class.attributes.key?(:line_break)
|
|
180
|
+
prev.line_break = prev.line_break.to_s + line_break.line_break.to_s
|
|
181
|
+
sections.delete_at(i)
|
|
182
|
+
# Don't increment i since we deleted an element
|
|
183
|
+
next
|
|
184
|
+
else
|
|
185
|
+
# Keep as standalone if no suitable previous element
|
|
186
|
+
i += 1
|
|
187
|
+
end
|
|
188
|
+
else
|
|
189
|
+
i += 1
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
# Container for document-level attributes.
|
|
7
|
+
#
|
|
8
|
+
# DocumentAttributes holds key-value pairs that define document metadata
|
|
9
|
+
# and configuration options. These are the `:key: value` declarations at
|
|
10
|
+
# the top of an AsciiDoc file.
|
|
11
|
+
#
|
|
12
|
+
# @!attribute [r] data
|
|
13
|
+
# @return [Array<Attribute>] Array of attribute key-value pairs
|
|
14
|
+
#
|
|
15
|
+
# @example Access attributes as hash
|
|
16
|
+
# attrs = Coradoc::AsciiDoc::Model::DocumentAttributes.new
|
|
17
|
+
# attrs.data << Coradoc::AsciiDoc::Model::Attribute.new("author", "John Doe")
|
|
18
|
+
# attrs.to_hash # => {"author" => "John Doe"}
|
|
19
|
+
#
|
|
20
|
+
# @example Get specific attribute
|
|
21
|
+
# value = attrs.get_attribute("author")
|
|
22
|
+
#
|
|
23
|
+
class DocumentAttributes < Base
|
|
24
|
+
attribute :data, Attribute, collection: true
|
|
25
|
+
|
|
26
|
+
def to_hash
|
|
27
|
+
return {} if data.nil?
|
|
28
|
+
|
|
29
|
+
data.each_with_object({}) do |attribute, hash|
|
|
30
|
+
hash[attribute.key.to_s] = attribute.value
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def get_attribute(name)
|
|
35
|
+
return nil if data.nil?
|
|
36
|
+
|
|
37
|
+
attribute = data.find { |attr| attr.key.to_s == name.to_s }
|
|
38
|
+
attribute&.value
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
# Document header containing title and metadata.
|
|
7
|
+
#
|
|
8
|
+
# The Header represents the document-level metadata including the main title,
|
|
9
|
+
# author information, and revision details. This corresponds to the AsciiDoc
|
|
10
|
+
# header line (e.g., `= Document Title`) and associated metadata.
|
|
11
|
+
#
|
|
12
|
+
# @!attribute [r] title
|
|
13
|
+
# @return [String] The main document title
|
|
14
|
+
# @!attribute [r] author
|
|
15
|
+
# @return [Author, nil] Document author information
|
|
16
|
+
# @!attribute [r] revision
|
|
17
|
+
# @return [Revision, nil] Document revision information (version, date)
|
|
18
|
+
#
|
|
19
|
+
# @example Create a simple header
|
|
20
|
+
# header = Coradoc::AsciiDoc::Model::Header.new(title: "My Document")
|
|
21
|
+
#
|
|
22
|
+
# @example Create a header with author and revision
|
|
23
|
+
# header = Coradoc::AsciiDoc::Model::Header.new(
|
|
24
|
+
# title: "My Document",
|
|
25
|
+
# author: Coradoc::AsciiDoc::Model::Author.new("John Doe"),
|
|
26
|
+
# revision: Coradoc::AsciiDoc::Model::Revision.new("1.0", "2024-01-01")
|
|
27
|
+
# )
|
|
28
|
+
#
|
|
29
|
+
class Header < Base
|
|
30
|
+
include Coradoc::AsciiDoc::Model::Anchorable
|
|
31
|
+
|
|
32
|
+
attribute :title, Coradoc::AsciiDoc::Model::Title
|
|
33
|
+
attribute :author, Coradoc::AsciiDoc::Model::Author
|
|
34
|
+
attribute :revision, Coradoc::AsciiDoc::Model::Revision
|
|
35
|
+
|
|
36
|
+
def validate
|
|
37
|
+
validate_author_type
|
|
38
|
+
validate_revision_type
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def validate_author_type
|
|
44
|
+
return if author.nil? || author.is_a?(Coradoc::AsciiDoc::Model::Author)
|
|
45
|
+
|
|
46
|
+
raise TypeError, "author must be a Coradoc::AsciiDoc::Model::Author, got #{author.class}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def validate_revision_type
|
|
50
|
+
return if revision.nil? || revision.is_a?(Coradoc::AsciiDoc::Model::Revision)
|
|
51
|
+
|
|
52
|
+
raise TypeError, "revision must be a Coradoc::AsciiDoc::Model::Revision, got #{revision.class}"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
class BlockImage < Coradoc::AsciiDoc::Model::Image::Core
|
|
7
|
+
class AttributeList < Coradoc::AsciiDoc::Model::Image::Core::AttributeList
|
|
8
|
+
extend AttributeList::Matchers
|
|
9
|
+
|
|
10
|
+
def named_validators
|
|
11
|
+
super.merge(
|
|
12
|
+
{
|
|
13
|
+
caption: String,
|
|
14
|
+
align: one('left', 'center', 'right'),
|
|
15
|
+
float: one('left', 'right')
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module AsciiDoc
|
|
5
|
+
module Model
|
|
6
|
+
module Image
|
|
7
|
+
class BlockImage < Coradoc::AsciiDoc::Model::Image::Core
|
|
8
|
+
def block_level?
|
|
9
|
+
true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Autoload nested AttributeList class
|
|
13
|
+
autoload :AttributeList, 'coradoc/asciidoc/model/image/block_image/attribute_list'
|
|
14
|
+
|
|
15
|
+
attribute :colons, :string, default: -> { '::' }
|
|
16
|
+
attribute :attributes,
|
|
17
|
+
Coradoc::AsciiDoc::Model::Image::BlockImage::AttributeList,
|
|
18
|
+
default: lambda {
|
|
19
|
+
::Coradoc::AsciiDoc::Model::AttributeList.new
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|