Class: Ace::Support::Markdown::Molecules::SectionEditor

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

Overview

Edit document sections by heading Supports replace, append, delete operations using exact string matching

Class Method Summary collapse

Class Method Details

.add_section(document, new_section) ⇒ MarkdownDocument

Add a new section at the end

Parameters:

  • document (MarkdownDocument)

    The document to update

  • new_section (Section)

    The section to add

Returns:

  • (MarkdownDocument)

    New document with added section

Raises:

  • (ArgumentError)


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/ace/support/markdown/molecules/section_editor.rb', line 133

def self.add_section(document, new_section)
  raise ArgumentError, "Document must be a MarkdownDocument" unless document.is_a?(Models::MarkdownDocument)
  raise ArgumentError, "New section must be a Section" unless new_section.is_a?(Models::Section)

  # Parse all sections
  all_sections = Atoms::SectionExtractor.extract_all(document.raw_body)

  # Convert to models
  sections = all_sections.map do |s|
    Models::Section.new(
      heading: s[:heading],
      level: s[:level],
      content: s[:content] || ""
    )
  end

  # Add new section
  sections << new_section

  document.with_sections(sections)
end

.append_to_section(document, heading, additional_content) ⇒ MarkdownDocument

Append content to a section

Parameters:

  • document (MarkdownDocument)

    The document to update

  • heading (String)

    The exact heading text to match

  • additional_content (String)

    Content to append

Returns:

  • (MarkdownDocument)

    New document with updated section

Raises:

  • (ArgumentError)


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/ace/support/markdown/molecules/section_editor.rb', line 53

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

  # Extract current section
  section_result = Atoms::SectionExtractor.extract(document.raw_body, heading)

  unless section_result[:found]
    raise SectionNotFoundError, "Section not found: #{heading}"
  end

  # Combine existing and new content
  existing_content = section_result[:section_content] || ""
  separator = existing_content.empty? ? "" : "\n\n"
  new_content = "#{existing_content}#{separator}#{additional_content}"

  # Replace with combined content
  replace_section(document, heading, new_content)
end

.delete_section(document, heading) ⇒ MarkdownDocument

Delete a section

Parameters:

  • document (MarkdownDocument)

    The document to update

  • heading (String)

    The exact heading text to match

Returns:

  • (MarkdownDocument)

    New document without the section

Raises:

  • (ArgumentError)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ace/support/markdown/molecules/section_editor.rb', line 76

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

  # Parse all sections
  all_sections = Atoms::SectionExtractor.extract_all(document.raw_body)

  # Filter out the target section
  remaining_sections = all_sections.reject { |s| s[:heading] == heading }

  # Convert to Section models
  new_sections = remaining_sections.map do |s|
    Models::Section.new(
      heading: s[:heading],
      level: s[:level],
      content: s[:content] || ""
    )
  end

  document.with_sections(new_sections)
end

.insert_section_before(document, before_heading, new_section) ⇒ MarkdownDocument

Insert a new section before another section

Parameters:

  • document (MarkdownDocument)

    The document to update

  • before_heading (String)

    Insert before this heading

  • new_section (Section)

    The section to insert

Returns:

  • (MarkdownDocument)

    New document with inserted section

Raises:

  • (ArgumentError)


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
# File 'lib/ace/support/markdown/molecules/section_editor.rb', line 102

def self.insert_section_before(document, before_heading, new_section)
  raise ArgumentError, "Document must be a MarkdownDocument" unless document.is_a?(Models::MarkdownDocument)
  raise ArgumentError, "New section must be a Section" unless new_section.is_a?(Models::Section)

  # Parse all sections
  all_sections = Atoms::SectionExtractor.extract_all(document.raw_body)

  # Find insertion point
  insert_index = all_sections.find_index { |s| s[:heading] == before_heading }

  raise SectionNotFoundError, "Section not found: #{before_heading}" unless insert_index

  # Convert existing sections to models
  sections = all_sections.map do |s|
    Models::Section.new(
      heading: s[:heading],
      level: s[:level],
      content: s[:content] || ""
    )
  end

  # Insert new section
  sections.insert(insert_index, new_section)

  document.with_sections(sections)
end

.replace_section(document, heading, new_content) ⇒ MarkdownDocument

Replace a section’s content by heading

Parameters:

  • document (MarkdownDocument)

    The document to update

  • heading (String)

    The exact heading text to match

  • new_content (String)

    The replacement content

Returns:

  • (MarkdownDocument)

    New document with replaced section

Raises:

  • (ArgumentError)


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/ace/support/markdown/molecules/section_editor.rb', line 15

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

  # Extract the current section to get its level
  section_result = Atoms::SectionExtractor.extract(document.raw_body, heading)

  unless section_result[:found]
    raise SectionNotFoundError, "Section not found: #{heading}"
  end

  # Parse all sections
  all_sections = Atoms::SectionExtractor.extract_all(document.raw_body)

  # Find and replace the target section
  new_sections = all_sections.map do |s|
    if s[:heading] == heading
      Models::Section.new(
        heading: s[:heading],
        level: s[:level],
        content: new_content
      )
    else
      Models::Section.new(
        heading: s[:heading],
        level: s[:level],
        content: s[:content] || ""
      )
    end
  end

  document.with_sections(new_sections)
end