Class: MarkdownComposer::CompositionBuffer
- Inherits:
-
Object
- Object
- MarkdownComposer::CompositionBuffer
- Defined in:
- lib/markdown_composer/composition_buffer.rb
Instance Attribute Summary collapse
-
#diagnostics ⇒ Object
readonly
Returns the value of attribute diagnostics.
-
#origin_nodes ⇒ Object
readonly
Returns the value of attribute origin_nodes.
Instance Method Summary collapse
- #append(units) ⇒ Object
- #copy(target, units, options: {}) ⇒ Object
- #dedupe_by_origin! ⇒ Object
- #empty? ⇒ Boolean
- #index ⇒ Object
-
#initialize(markdown = +"",, diagnostics: Diagnostics.new) ⇒ CompositionBuffer
constructor
A new instance of CompositionBuffer.
- #insert_after(target, units, options: {}) ⇒ Object
- #insert_before(target, units, options: {}) ⇒ Object
- #insert_between(start_target, end_target, units, options: {}) ⇒ Object
- #markdown ⇒ Object
- #move(selector, target, units = nil, options: {}) ⇒ Object
- #place_markdown(target, markdown, origin_nodes: [], options: {}) ⇒ Object
- #prepend(units) ⇒ Object
- #remove(target, options: {}) ⇒ Object
- #replace(target, units, options: {}) ⇒ Object
- #replace_markdown(markdown) ⇒ Object
- #replace_markdown_ranges(replacements) ⇒ Object
- #set(units) ⇒ Object
- #sync_origins_to_current! ⇒ Object
- #to_h ⇒ Object
Constructor Details
#initialize(markdown = +"",, diagnostics: Diagnostics.new) ⇒ CompositionBuffer
Returns a new instance of CompositionBuffer.
7 8 9 10 11 |
# File 'lib/markdown_composer/composition_buffer.rb', line 7 def initialize(markdown = +"", diagnostics: Diagnostics.new) @markdown = markdown.dup @diagnostics = diagnostics @origin_nodes = [] end |
Instance Attribute Details
#diagnostics ⇒ Object (readonly)
Returns the value of attribute diagnostics.
5 6 7 |
# File 'lib/markdown_composer/composition_buffer.rb', line 5 def diagnostics @diagnostics end |
#origin_nodes ⇒ Object (readonly)
Returns the value of attribute origin_nodes.
5 6 7 |
# File 'lib/markdown_composer/composition_buffer.rb', line 5 def origin_nodes @origin_nodes end |
Instance Method Details
#append(units) ⇒ Object
27 28 29 30 |
# File 'lib/markdown_composer/composition_buffer.rb', line 27 def append(units) @origin_nodes.concat(origin_units(units)) insert_at_end(units_to_markdown(units)) end |
#copy(target, units, options: {}) ⇒ Object
64 65 66 67 |
# File 'lib/markdown_composer/composition_buffer.rb', line 64 def copy(target, units, options: {}) placement = target&.fetch("placement", nil) || "after" placement == "before" ? insert_before(target, units, options: ) : insert_after(target, units, options: ) end |
#dedupe_by_origin! ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/markdown_composer/composition_buffer.rb', line 149 def dedupe_by_origin! seen = {} deduped = [] origin_nodes.each do |node| key = node.attributes["origin_id"] || node.id next if seen[key] seen[key] = true deduped << node end set(deduped) end |
#empty? ⇒ Boolean
17 18 19 |
# File 'lib/markdown_composer/composition_buffer.rb', line 17 def empty? @markdown.strip.empty? end |
#index ⇒ Object
125 126 127 |
# File 'lib/markdown_composer/composition_buffer.rb', line 125 def index DocumentIndex.from_markdown(@markdown, source_key: "buffer", diagnostics: diagnostics) end |
#insert_after(target, units, options: {}) ⇒ Object
41 42 43 |
# File 'lib/markdown_composer/composition_buffer.rb', line 41 def insert_after(target, units, options: {}) insert_relative(target, units, :after, options: ) end |
#insert_before(target, units, options: {}) ⇒ Object
37 38 39 |
# File 'lib/markdown_composer/composition_buffer.rb', line 37 def insert_before(target, units, options: {}) insert_relative(target, units, :before, options: ) end |
#insert_between(start_target, end_target, units, options: {}) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/markdown_composer/composition_buffer.rb', line 92 def insert_between(start_target, end_target, units, options: {}) start_ranges = target_ranges(start_target, options: ) end_ranges = target_ranges(end_target, options: ) return diagnostics.warn("target.empty", "Between target matched no buffer content", path: "target") if start_ranges.empty? || end_ranges.empty? start_range = start_ranges.first end_range = end_ranges.first if start_range.end >= end_range.begin diagnostics.error("target.order_invalid", "Between start anchor must resolve before end anchor", path: "target") return self end @origin_nodes.concat(origin_units(units)) buffer_lines = lines @markdown = join_markdown_fragments( buffer_lines[0...start_range.end].to_a.join, units_to_markdown(units), buffer_lines[start_range.end..].to_a.join ) self end |
#markdown ⇒ Object
13 14 15 |
# File 'lib/markdown_composer/composition_buffer.rb', line 13 def markdown @markdown.dup end |
#move(selector, target, units = nil, options: {}) ⇒ Object
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/markdown_composer/composition_buffer.rb', line 114 def move(selector, target, units = nil, options: {}) ranges = units ? unit_ranges(units) : target_ranges(selector, options: ) return warn_empty_destructive_target("move", path: "select") if ranges.empty? return warn_empty_destructive_target("move", path: "target") if target_ranges(target, options: ).empty? moved = units ? units_to_markdown(units) : ranges.map { |range| lines[(range.begin - 1)..(range.end - 1)].join }.join("\n") replace_ranges(ranges, "") unit = ComposerNode.new(id: "buffer:moved", source_key: "buffer", type: "paragraph", source_position: 0, level: nil, text: moved, attributes: {}, children: [], raw: moved, start_line: 1, end_line: moved.lines.length) copy(target, [ unit ], options: ) end |
#place_markdown(target, markdown, origin_nodes: [], options: {}) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/markdown_composer/composition_buffer.rb', line 69 def place_markdown(target, markdown, origin_nodes: [], options: {}) target ||= { "position" => "end" } content = normalize_markdown_fragment(markdown) origins = Array(origin_nodes).compact case target["position"] when "output" @origin_nodes = origins @markdown = trim_outer_blank_lines(content) @markdown = normalize_markdown_fragment(@markdown) unless @markdown.empty? when "start" @origin_nodes = origins + @origin_nodes insert_at_start(content) when "end" @origin_nodes.concat(origins) insert_at_end(content) when nil place_markdown_relative(target, content, origins, target["placement"] == "before" ? :before : :after, options: ) end self end |
#prepend(units) ⇒ Object
32 33 34 35 |
# File 'lib/markdown_composer/composition_buffer.rb', line 32 def prepend(units) @origin_nodes = origin_units(units) + @origin_nodes insert_at_start(units_to_markdown(units)) end |
#remove(target, options: {}) ⇒ Object
57 58 59 60 61 62 |
# File 'lib/markdown_composer/composition_buffer.rb', line 57 def remove(target, options: {}) ranges = target_ranges(target, options: ) return warn_empty_destructive_target("remove_buffer_target", path: "target") if ranges.empty? replace_ranges(ranges, "") end |
#replace(target, units, options: {}) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/markdown_composer/composition_buffer.rb', line 45 def replace(target, units, options: {}) if target && target["position"] == "output" return set(units) end ranges = target_ranges(target, options: ) return warn_empty_destructive_target("replace", path: "target") if ranges.empty? @origin_nodes.concat(origin_units(units)) replace_ranges(ranges, units_to_markdown(units)) end |
#replace_markdown(markdown) ⇒ Object
129 130 131 132 |
# File 'lib/markdown_composer/composition_buffer.rb', line 129 def replace_markdown(markdown) @markdown = markdown.to_s self end |
#replace_markdown_ranges(replacements) ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/markdown_composer/composition_buffer.rb', line 134 def replace_markdown_ranges(replacements) buffer_lines = lines Array(replacements).sort_by { |replacement| replacement.fetch(:range).begin }.reverse_each do |replacement| range = replacement.fetch(:range) content = replacement.fetch(:markdown).to_s start = [ range.begin - 1, 0 ].max finish = [ range.end - 1, buffer_lines.length - 1 ].min replacement_lines = content.empty? ? [] : [ normalize_markdown_fragment(content) ] buffer_lines[start..finish] = replacement_lines end @markdown = buffer_lines.join sync_origins_to_current! self end |
#set(units) ⇒ Object
21 22 23 24 25 |
# File 'lib/markdown_composer/composition_buffer.rb', line 21 def set(units) @markdown = units_to_markdown(units) @origin_nodes = origin_units(units) self end |
#sync_origins_to_current! ⇒ Object
162 163 164 165 |
# File 'lib/markdown_composer/composition_buffer.rb', line 162 def sync_origins_to_current! @origin_nodes = index.nodes self end |
#to_h ⇒ Object
167 168 169 170 171 172 173 174 175 |
# File 'lib/markdown_composer/composition_buffer.rb', line 167 def to_h { type: "composition_buffer", markdown: markdown, origins: origin_nodes.map { |node| { id: node.id, origin_id: node.attributes["origin_id"], source_key: node.source_key, source_position: node.source_position } }, nodes: index.nodes.map(&:to_h), sections: index.sections.map(&:to_h) } end |