Class: Coradoc::AsciiDoc::Model::Document
- Defined in:
- lib/coradoc/asciidoc/model/document.rb
Overview
Document model representing an AsciiDoc document.
The Document class is the main container for parsed AsciiDoc content. It holds the document’s header, attributes, and sections (blocks, lists, etc.).
Instance Attribute Summary collapse
-
#document_attributes ⇒ DocumentAttributes
readonly
Document-level attributes like author, date, etc.
-
#header ⇒ Header
readonly
Document header containing title and metadata.
-
#sections ⇒ Array<Base>
readonly
Document content blocks (sections, paragraphs, lists, etc.).
Attributes inherited from Base
Class Method Summary collapse
Instance Method Summary collapse
-
#[](index) ⇒ Coradoc::AsciiDoc::Model::Base
The section at the specified index.
-
#[]=(index, value) ⇒ Coradoc::AsciiDoc::Model::Base
The section that was set.
-
#expand_includes(base_dir = '.') ⇒ Coradoc::AsciiDoc::Model::Document
Expand include directives in the document.
-
#freeze(options = {}) ⇒ Document
Freeze the document by resolving external references.
Methods inherited from Base
#block_level?, #inline?, #serialize_content, #simplify_block_content, #to_adoc, #to_h, visit, #visit
Instance Attribute Details
#document_attributes ⇒ DocumentAttributes (readonly)
Returns Document-level attributes like author, date, etc.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/coradoc/asciidoc/model/document.rb', line 37 class Document < Base attribute :document_attributes, Coradoc::AsciiDoc::Model::DocumentAttributes, default: lambda { Coradoc::AsciiDoc::Model::DocumentAttributes.new } attribute :header, Coradoc::AsciiDoc::Model::Header, default: lambda { Coradoc::AsciiDoc::Model::Header.new( title: Coradoc::AsciiDoc::Model::Title.new(content: '') ) } attribute :sections, Coradoc::AsciiDoc::Model::Base, collection: true, initialize_empty: true, polymorphic: [ Coradoc::AsciiDoc::Model::Admonition, Coradoc::AsciiDoc::Model::Audio, Coradoc::AsciiDoc::Model::BibliographyEntry, Coradoc::AsciiDoc::Model::Block::Core, Coradoc::AsciiDoc::Model::Image::BlockImage, Coradoc::AsciiDoc::Model::CommentBlock, Coradoc::AsciiDoc::Model::CommentLine, Coradoc::AsciiDoc::Model::Include, Coradoc::AsciiDoc::Model::LineBreak, Coradoc::AsciiDoc::Model::List::Core, Coradoc::AsciiDoc::Model::Paragraph, Coradoc::AsciiDoc::Model::Table, Coradoc::AsciiDoc::Model::Tag, Coradoc::AsciiDoc::Model::Video ] # @param [Integer] index The index of the section to retrieve # @return [Coradoc::AsciiDoc::Model::Base] The section at the specified index def [](index) sections[index] end # @param [Integer] index The index of the section to set # @param [Coradoc::AsciiDoc::Model::Base] value The section to set at the specified index # @return [Coradoc::AsciiDoc::Model::Base] The section that was set def []=(index, value) sections[index] = value end # Expand include directives in the document # @param base_dir [String] Base directory for resolving relative includes # @return [Coradoc::AsciiDoc::Model::Document] A new document with includes expanded def (base_dir = '.') freeze(base_dir: base_dir, includes: true, images: :reference, media: :reference) end # Freeze the document by resolving external references. # # This method creates a NEW document with resolved references. # The original document is never modified (immutable principle). # # @param options [Hash] Resolution options # @option options [String] :base_dir Base directory for relative paths (default: ".") # @option options [Boolean] :includes Resolve include:: directives (default: true) # @option options [Symbol] :images Image resolution: :reference, :copy, :embed (default: :reference) # @option options [Symbol] :media Media resolution: :reference, :copy (default: :reference) # @option options [String] :output_dir Output directory for :copy mode # @option options [Integer] :max_recursion Maximum recursion depth for includes (default: 10) # @return [Document] NEW document with resolved references # # @example Resolve includes only # frozen = doc.freeze(base_dir: "/docs", includes: true) # # @example Create self-contained document # frozen = doc.freeze( # base_dir: "/docs", # includes: true, # images: :embed, # output_dir: "/output" # ) # def freeze( = {}) resolver = Resolver.new() base_dir = [:base_dir] || '.' resolver.resolve_document(self, base_dir) end class << self def from_ast(elements) sections = [] document_attributes = nil header = nil elements.each do |element| case element when Coradoc::AsciiDoc::Model::DocumentAttributes document_attributes = element when Coradoc::AsciiDoc::Model::Header header = element when Coradoc::AsciiDoc::Model::Base sections << element else warn "Unknown element type: #{element.class}" warn "Element: #{element.inspect}" end end # Merge standalone LineBreak elements into the previous element's line_break merge_line_breaks(sections) # Only pass non-nil values to preserve defaults attrs = { sections: sections } attrs[:document_attributes] = document_attributes if document_attributes attrs[:header] = header if header new(attrs) end private def merge_line_breaks(sections) return if sections.empty? # Skip leading LineBreak elements sections.shift while sections.first.is_a?(Coradoc::AsciiDoc::Model::LineBreak) i = 0 while i < sections.length # If current element is a LineBreak and there's a previous element if sections[i].is_a?(Coradoc::AsciiDoc::Model::LineBreak) && i.positive? prev = sections[i - 1] line_break = sections[i] # Skip consecutive LineBreaks if prev.is_a?(Coradoc::AsciiDoc::Model::LineBreak) sections.delete_at(i) next end # Merge the line break into the previous element if it has a line_break attribute if prev.is_a?(Coradoc::AsciiDoc::Model::Base) && prev.class.attributes.key?(:line_break) prev.line_break = prev.line_break.to_s + line_break.line_break.to_s sections.delete_at(i) # Don't increment i since we deleted an element next else # Keep as standalone if no suitable previous element i += 1 end else i += 1 end end end end end |
#header ⇒ Header (readonly)
Returns Document header containing title and metadata.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/coradoc/asciidoc/model/document.rb', line 37 class Document < Base attribute :document_attributes, Coradoc::AsciiDoc::Model::DocumentAttributes, default: lambda { Coradoc::AsciiDoc::Model::DocumentAttributes.new } attribute :header, Coradoc::AsciiDoc::Model::Header, default: lambda { Coradoc::AsciiDoc::Model::Header.new( title: Coradoc::AsciiDoc::Model::Title.new(content: '') ) } attribute :sections, Coradoc::AsciiDoc::Model::Base, collection: true, initialize_empty: true, polymorphic: [ Coradoc::AsciiDoc::Model::Admonition, Coradoc::AsciiDoc::Model::Audio, Coradoc::AsciiDoc::Model::BibliographyEntry, Coradoc::AsciiDoc::Model::Block::Core, Coradoc::AsciiDoc::Model::Image::BlockImage, Coradoc::AsciiDoc::Model::CommentBlock, Coradoc::AsciiDoc::Model::CommentLine, Coradoc::AsciiDoc::Model::Include, Coradoc::AsciiDoc::Model::LineBreak, Coradoc::AsciiDoc::Model::List::Core, Coradoc::AsciiDoc::Model::Paragraph, Coradoc::AsciiDoc::Model::Table, Coradoc::AsciiDoc::Model::Tag, Coradoc::AsciiDoc::Model::Video ] # @param [Integer] index The index of the section to retrieve # @return [Coradoc::AsciiDoc::Model::Base] The section at the specified index def [](index) sections[index] end # @param [Integer] index The index of the section to set # @param [Coradoc::AsciiDoc::Model::Base] value The section to set at the specified index # @return [Coradoc::AsciiDoc::Model::Base] The section that was set def []=(index, value) sections[index] = value end # Expand include directives in the document # @param base_dir [String] Base directory for resolving relative includes # @return [Coradoc::AsciiDoc::Model::Document] A new document with includes expanded def (base_dir = '.') freeze(base_dir: base_dir, includes: true, images: :reference, media: :reference) end # Freeze the document by resolving external references. # # This method creates a NEW document with resolved references. # The original document is never modified (immutable principle). # # @param options [Hash] Resolution options # @option options [String] :base_dir Base directory for relative paths (default: ".") # @option options [Boolean] :includes Resolve include:: directives (default: true) # @option options [Symbol] :images Image resolution: :reference, :copy, :embed (default: :reference) # @option options [Symbol] :media Media resolution: :reference, :copy (default: :reference) # @option options [String] :output_dir Output directory for :copy mode # @option options [Integer] :max_recursion Maximum recursion depth for includes (default: 10) # @return [Document] NEW document with resolved references # # @example Resolve includes only # frozen = doc.freeze(base_dir: "/docs", includes: true) # # @example Create self-contained document # frozen = doc.freeze( # base_dir: "/docs", # includes: true, # images: :embed, # output_dir: "/output" # ) # def freeze( = {}) resolver = Resolver.new() base_dir = [:base_dir] || '.' resolver.resolve_document(self, base_dir) end class << self def from_ast(elements) sections = [] document_attributes = nil header = nil elements.each do |element| case element when Coradoc::AsciiDoc::Model::DocumentAttributes document_attributes = element when Coradoc::AsciiDoc::Model::Header header = element when Coradoc::AsciiDoc::Model::Base sections << element else warn "Unknown element type: #{element.class}" warn "Element: #{element.inspect}" end end # Merge standalone LineBreak elements into the previous element's line_break merge_line_breaks(sections) # Only pass non-nil values to preserve defaults attrs = { sections: sections } attrs[:document_attributes] = document_attributes if document_attributes attrs[:header] = header if header new(attrs) end private def merge_line_breaks(sections) return if sections.empty? # Skip leading LineBreak elements sections.shift while sections.first.is_a?(Coradoc::AsciiDoc::Model::LineBreak) i = 0 while i < sections.length # If current element is a LineBreak and there's a previous element if sections[i].is_a?(Coradoc::AsciiDoc::Model::LineBreak) && i.positive? prev = sections[i - 1] line_break = sections[i] # Skip consecutive LineBreaks if prev.is_a?(Coradoc::AsciiDoc::Model::LineBreak) sections.delete_at(i) next end # Merge the line break into the previous element if it has a line_break attribute if prev.is_a?(Coradoc::AsciiDoc::Model::Base) && prev.class.attributes.key?(:line_break) prev.line_break = prev.line_break.to_s + line_break.line_break.to_s sections.delete_at(i) # Don't increment i since we deleted an element next else # Keep as standalone if no suitable previous element i += 1 end else i += 1 end end end end end |
#sections ⇒ Array<Base> (readonly)
Returns Document content blocks (sections, paragraphs, lists, etc.).
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/coradoc/asciidoc/model/document.rb', line 37 class Document < Base attribute :document_attributes, Coradoc::AsciiDoc::Model::DocumentAttributes, default: lambda { Coradoc::AsciiDoc::Model::DocumentAttributes.new } attribute :header, Coradoc::AsciiDoc::Model::Header, default: lambda { Coradoc::AsciiDoc::Model::Header.new( title: Coradoc::AsciiDoc::Model::Title.new(content: '') ) } attribute :sections, Coradoc::AsciiDoc::Model::Base, collection: true, initialize_empty: true, polymorphic: [ Coradoc::AsciiDoc::Model::Admonition, Coradoc::AsciiDoc::Model::Audio, Coradoc::AsciiDoc::Model::BibliographyEntry, Coradoc::AsciiDoc::Model::Block::Core, Coradoc::AsciiDoc::Model::Image::BlockImage, Coradoc::AsciiDoc::Model::CommentBlock, Coradoc::AsciiDoc::Model::CommentLine, Coradoc::AsciiDoc::Model::Include, Coradoc::AsciiDoc::Model::LineBreak, Coradoc::AsciiDoc::Model::List::Core, Coradoc::AsciiDoc::Model::Paragraph, Coradoc::AsciiDoc::Model::Table, Coradoc::AsciiDoc::Model::Tag, Coradoc::AsciiDoc::Model::Video ] # @param [Integer] index The index of the section to retrieve # @return [Coradoc::AsciiDoc::Model::Base] The section at the specified index def [](index) sections[index] end # @param [Integer] index The index of the section to set # @param [Coradoc::AsciiDoc::Model::Base] value The section to set at the specified index # @return [Coradoc::AsciiDoc::Model::Base] The section that was set def []=(index, value) sections[index] = value end # Expand include directives in the document # @param base_dir [String] Base directory for resolving relative includes # @return [Coradoc::AsciiDoc::Model::Document] A new document with includes expanded def (base_dir = '.') freeze(base_dir: base_dir, includes: true, images: :reference, media: :reference) end # Freeze the document by resolving external references. # # This method creates a NEW document with resolved references. # The original document is never modified (immutable principle). # # @param options [Hash] Resolution options # @option options [String] :base_dir Base directory for relative paths (default: ".") # @option options [Boolean] :includes Resolve include:: directives (default: true) # @option options [Symbol] :images Image resolution: :reference, :copy, :embed (default: :reference) # @option options [Symbol] :media Media resolution: :reference, :copy (default: :reference) # @option options [String] :output_dir Output directory for :copy mode # @option options [Integer] :max_recursion Maximum recursion depth for includes (default: 10) # @return [Document] NEW document with resolved references # # @example Resolve includes only # frozen = doc.freeze(base_dir: "/docs", includes: true) # # @example Create self-contained document # frozen = doc.freeze( # base_dir: "/docs", # includes: true, # images: :embed, # output_dir: "/output" # ) # def freeze( = {}) resolver = Resolver.new() base_dir = [:base_dir] || '.' resolver.resolve_document(self, base_dir) end class << self def from_ast(elements) sections = [] document_attributes = nil header = nil elements.each do |element| case element when Coradoc::AsciiDoc::Model::DocumentAttributes document_attributes = element when Coradoc::AsciiDoc::Model::Header header = element when Coradoc::AsciiDoc::Model::Base sections << element else warn "Unknown element type: #{element.class}" warn "Element: #{element.inspect}" end end # Merge standalone LineBreak elements into the previous element's line_break merge_line_breaks(sections) # Only pass non-nil values to preserve defaults attrs = { sections: sections } attrs[:document_attributes] = document_attributes if document_attributes attrs[:header] = header if header new(attrs) end private def merge_line_breaks(sections) return if sections.empty? # Skip leading LineBreak elements sections.shift while sections.first.is_a?(Coradoc::AsciiDoc::Model::LineBreak) i = 0 while i < sections.length # If current element is a LineBreak and there's a previous element if sections[i].is_a?(Coradoc::AsciiDoc::Model::LineBreak) && i.positive? prev = sections[i - 1] line_break = sections[i] # Skip consecutive LineBreaks if prev.is_a?(Coradoc::AsciiDoc::Model::LineBreak) sections.delete_at(i) next end # Merge the line break into the previous element if it has a line_break attribute if prev.is_a?(Coradoc::AsciiDoc::Model::Base) && prev.class.attributes.key?(:line_break) prev.line_break = prev.line_break.to_s + line_break.line_break.to_s sections.delete_at(i) # Don't increment i since we deleted an element next else # Keep as standalone if no suitable previous element i += 1 end else i += 1 end end end end end |
Class Method Details
.from_ast(elements) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/coradoc/asciidoc/model/document.rb', line 124 def from_ast(elements) sections = [] document_attributes = nil header = nil elements.each do |element| case element when Coradoc::AsciiDoc::Model::DocumentAttributes document_attributes = element when Coradoc::AsciiDoc::Model::Header header = element when Coradoc::AsciiDoc::Model::Base sections << element else warn "Unknown element type: #{element.class}" warn "Element: #{element.inspect}" end end # Merge standalone LineBreak elements into the previous element's line_break merge_line_breaks(sections) # Only pass non-nil values to preserve defaults attrs = { sections: sections } attrs[:document_attributes] = document_attributes if document_attributes attrs[:header] = header if header new(attrs) end |
Instance Method Details
#[](index) ⇒ Coradoc::AsciiDoc::Model::Base
Returns The section at the specified index.
74 75 76 |
# File 'lib/coradoc/asciidoc/model/document.rb', line 74 def [](index) sections[index] end |
#[]=(index, value) ⇒ Coradoc::AsciiDoc::Model::Base
Returns The section that was set.
81 82 83 |
# File 'lib/coradoc/asciidoc/model/document.rb', line 81 def []=(index, value) sections[index] = value end |
#expand_includes(base_dir = '.') ⇒ Coradoc::AsciiDoc::Model::Document
Expand include directives in the document
88 89 90 |
# File 'lib/coradoc/asciidoc/model/document.rb', line 88 def (base_dir = '.') freeze(base_dir: base_dir, includes: true, images: :reference, media: :reference) end |
#freeze(options = {}) ⇒ Document
Freeze the document by resolving external references.
This method creates a NEW document with resolved references. The original document is never modified (immutable principle).
117 118 119 120 121 |
# File 'lib/coradoc/asciidoc/model/document.rb', line 117 def freeze( = {}) resolver = Resolver.new() base_dir = [:base_dir] || '.' resolver.resolve_document(self, base_dir) end |