Class: Ace::Support::Markdown::Molecules::DocumentBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/support/markdown/molecules/document_builder.rb

Overview

Build markdown documents programmatically Provides fluent API for creating documents from scratch

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDocumentBuilder

Returns a new instance of DocumentBuilder.



12
13
14
15
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 12

def initialize
  @frontmatter = {}
  @sections = []
end

Instance Attribute Details

#frontmatter(data) ⇒ DocumentBuilder (readonly)

Set frontmatter fields

Parameters:

  • data (Hash)

    Frontmatter data

Returns:

Raises:

  • (ArgumentError)


20
21
22
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 20

def frontmatter
  @frontmatter
end

#sectionsObject (readonly)

Returns the value of attribute sections.



10
11
12
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 10

def sections
  @sections
end

Class Method Details

.from_document(document) ⇒ DocumentBuilder

Create a builder from an existing document

Parameters:

  • document (MarkdownDocument)

    The source document

Returns:

Raises:

  • (ArgumentError)


120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 120

def self.from_document(document)
  raise ArgumentError, "Document must be a MarkdownDocument" unless document.is_a?(Models::MarkdownDocument)

  builder = new
  builder.frontmatter(document.frontmatter)

  if document.has_sections?
    document.sections.each do |section|
      builder.add_section(
        heading: section.heading,
        content: section.content,
        level: section.level
      )
    end
  else
    builder.body(document.raw_body)
  end

  builder
end

.minimal(frontmatter) ⇒ MarkdownDocument

Create a minimal document with just frontmatter

Parameters:

  • frontmatter (Hash)

    The frontmatter data

Returns:

  • (MarkdownDocument)


144
145
146
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 144

def self.minimal(frontmatter)
  new.frontmatter(frontmatter).build
end

Instance Method Details

#add_section(heading:, content:, level: 2) ⇒ DocumentBuilder

Add a section

Parameters:

  • heading (String)

    The section heading

  • content (String)

    The section content

  • level (Integer) (defaults to: 2)

    The heading level (default: 2)

Returns:



41
42
43
44
45
46
47
48
49
50
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 41

def add_section(heading:, content:, level: 2)
  section = Models::Section.new(
    heading: heading,
    level: level,
    content: content
  )

  @sections << section
  self
end

#body(content) ⇒ DocumentBuilder

Add raw body content (without sections)

Parameters:

  • content (String)

    The body content

Returns:



63
64
65
66
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 63

def body(content)
  @body_content = content
  self
end

#buildMarkdownDocument

Build the document as a MarkdownDocument model

Returns:

  • (MarkdownDocument)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 70

def build
  body_text = if @sections.any?
    # Build from sections
    @sections.map(&:to_markdown).join("\n\n")
  else
    # Use raw body content
    @body_content || ""
  end

  Models::MarkdownDocument.new(
    frontmatter: @frontmatter,
    raw_body: body_text,
    sections: @sections.any? ? @sections : nil
  )
end

#set_field(key, value) ⇒ DocumentBuilder

Set a single frontmatter field

Parameters:

  • key (String, Symbol)

    The field key

  • value (Object)

    The field value

Returns:



31
32
33
34
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 31

def set_field(key, value)
  @frontmatter[key.to_s] = value
  self
end

#title(title, content: "") ⇒ DocumentBuilder

Add a title (level 1 heading)

Parameters:

  • title (String)

    The title text

  • content (String) (defaults to: "")

    Content under the title

Returns:



56
57
58
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 56

def title(title, content: "")
  add_section(heading: title, content: content, level: 1)
end

#to_markdownString

Build and convert to markdown string

Returns:

  • (String)


88
89
90
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 88

def to_markdown
  build.to_markdown
end

#valid?Boolean

Check if builder is valid

Returns:

  • (Boolean)


113
114
115
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 113

def valid?
  validate[:valid]
end

#validateHash

Validate the current builder state

Returns:

  • (Hash)

    Result with :valid, :errors



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/ace/support/markdown/molecules/document_builder.rb', line 94

def validate
  errors = []

  if @frontmatter.empty?
    errors << "No frontmatter defined"
  end

  if @sections.empty? && (@body_content.nil? || @body_content.empty?)
    errors << "No content defined (neither sections nor body)"
  end

  {
    valid: errors.empty?,
    errors: errors
  }
end