Class: Ace::Support::Markdown::Models::MarkdownDocument
- Inherits:
-
Object
- Object
- Ace::Support::Markdown::Models::MarkdownDocument
- Defined in:
- lib/ace/support/markdown/models/markdown_document.rb
Overview
Immutable representation of a markdown document Contains frontmatter and sections for safe transformations
Instance Attribute Summary collapse
-
#file_path ⇒ Object
readonly
Returns the value of attribute file_path.
-
#frontmatter ⇒ Object
readonly
Returns the value of attribute frontmatter.
-
#raw_body ⇒ Object
readonly
Returns the value of attribute raw_body.
-
#sections ⇒ Object
readonly
Returns the value of attribute sections.
Class Method Summary collapse
-
.parse(content, file_path: nil) ⇒ MarkdownDocument
Parse document from markdown string.
-
.parse_with_sections(content, file_path: nil) ⇒ MarkdownDocument
Parse document with sections.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Compare documents for equality.
-
#find_section(heading) ⇒ Section?
Find a section by heading text.
-
#get_frontmatter(key) ⇒ Object?
Get a specific frontmatter field.
-
#has_frontmatter? ⇒ Boolean
Check if document has frontmatter.
-
#has_sections? ⇒ Boolean
Check if document has sections parsed.
-
#initialize(frontmatter:, raw_body:, sections: nil, file_path: nil) ⇒ MarkdownDocument
constructor
Create a new MarkdownDocument.
-
#stats ⇒ Hash
Get document statistics.
-
#to_h ⇒ Hash
Hash representation.
-
#to_markdown ⇒ String
Convert document to complete markdown string.
-
#with_body(new_body) ⇒ MarkdownDocument
Create a new document with updated body.
-
#with_frontmatter(updates) ⇒ MarkdownDocument
Create a new document with updated frontmatter.
-
#with_sections(new_sections) ⇒ MarkdownDocument
Create a new document with updated sections.
Constructor Details
#initialize(frontmatter:, raw_body:, sections: nil, file_path: nil) ⇒ MarkdownDocument
Create a new MarkdownDocument
17 18 19 20 21 22 23 24 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 17 def initialize(frontmatter:, raw_body:, sections: nil, file_path: nil) @frontmatter = frontmatter.freeze @raw_body = raw_body.freeze @sections = sections&.freeze @file_path = file_path&.freeze validate! end |
Instance Attribute Details
#file_path ⇒ Object (readonly)
Returns the value of attribute file_path.
10 11 12 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 10 def file_path @file_path end |
#frontmatter ⇒ Object (readonly)
Returns the value of attribute frontmatter.
10 11 12 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 10 def frontmatter @frontmatter end |
#raw_body ⇒ Object (readonly)
Returns the value of attribute raw_body.
10 11 12 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 10 def raw_body @raw_body end |
#sections ⇒ Object (readonly)
Returns the value of attribute sections.
10 11 12 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 10 def sections @sections end |
Class Method Details
.parse(content, file_path: nil) ⇒ MarkdownDocument
Parse document from markdown string
137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 137 def self.parse(content, file_path: nil) result = Atoms::FrontmatterExtractor.extract(content) raise ValidationError, result[:errors].join(", ") unless result[:valid] new( frontmatter: result[:frontmatter], raw_body: result[:body], file_path: file_path ) end |
.parse_with_sections(content, file_path: nil) ⇒ MarkdownDocument
Parse document with sections
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 153 def self.parse_with_sections(content, file_path: nil) doc = parse(content, file_path: file_path) # Extract all sections section_data = Atoms::SectionExtractor.extract_all(doc.raw_body) sections = section_data.map do |s| Section.new( heading: s[:heading], level: s[:level], content: s[:content] || "" ) end doc.with_sections(sections) end |
Instance Method Details
#==(other) ⇒ Boolean
Compare documents for equality
115 116 117 118 119 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 115 def ==(other) other.is_a?(MarkdownDocument) && @frontmatter == other.frontmatter && @raw_body == other.raw_body end |
#find_section(heading) ⇒ Section?
Find a section by heading text
77 78 79 80 81 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 77 def find_section(heading) return nil unless @sections @sections.find { |s| s.heading == heading } end |
#get_frontmatter(key) ⇒ Object?
Get a specific frontmatter field
70 71 72 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 70 def get_frontmatter(key) @frontmatter[key.to_s] || @frontmatter[key.to_sym] end |
#has_frontmatter? ⇒ Boolean
Check if document has frontmatter
91 92 93 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 91 def has_frontmatter? !@frontmatter.empty? end |
#has_sections? ⇒ Boolean
Check if document has sections parsed
97 98 99 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 97 def has_sections? !@sections.nil? && !@sections.empty? end |
#stats ⇒ Hash
Get document statistics
103 104 105 106 107 108 109 110 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 103 def stats { frontmatter_fields: @frontmatter.keys.length, body_length: @raw_body.length, sections_count: @sections&.length || 0, word_count: @raw_body.split(/\s+/).length } end |
#to_h ⇒ Hash
Hash representation
123 124 125 126 127 128 129 130 131 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 123 def to_h { frontmatter: @frontmatter, raw_body: @raw_body, sections: @sections&.map(&:to_h), file_path: @file_path, stats: stats } end |
#to_markdown ⇒ String
Convert document to complete markdown string
85 86 87 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 85 def to_markdown Atoms::FrontmatterSerializer.rebuild_document(@frontmatter, @raw_body) end |
#with_body(new_body) ⇒ MarkdownDocument
Create a new document with updated body
43 44 45 46 47 48 49 50 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 43 def with_body(new_body) MarkdownDocument.new( frontmatter: @frontmatter, raw_body: new_body, sections: nil, # Invalidate sections cache file_path: @file_path ) end |
#with_frontmatter(updates) ⇒ MarkdownDocument
Create a new document with updated frontmatter
29 30 31 32 33 34 35 36 37 38 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 29 def with_frontmatter(updates) new_frontmatter = @frontmatter.merge(updates) MarkdownDocument.new( frontmatter: new_frontmatter, raw_body: @raw_body, sections: @sections, file_path: @file_path ) end |
#with_sections(new_sections) ⇒ MarkdownDocument
Create a new document with updated sections
55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/ace/support/markdown/models/markdown_document.rb', line 55 def with_sections(new_sections) # Rebuild raw_body from sections new_body = new_sections.map(&:to_markdown).join("\n\n") MarkdownDocument.new( frontmatter: @frontmatter, raw_body: new_body, sections: new_sections, file_path: @file_path ) end |