Class: Markdown::Merge::ListMerger
- Inherits:
-
Object
- Object
- Markdown::Merge::ListMerger
- Includes:
- Ast::Merge::JaccardSimilarity
- Defined in:
- lib/markdown/merge/list_merger.rb
Overview
Merges two Markdown list nodes at the item level.
When a template list and destination list are matched (e.g., via fuzzy matching or a shared content fingerprint), this merger produces a result that is smarter than simply picking one whole list as the winner:
- Items that appear in both lists are resolved by preference (template or dest).
- Items that only appear in the destination are kept (project customisations).
- Items that only appear in the template are added (new canonical steps).
Item matching uses significant-token Jaccard overlap so minor wording differences (e.g., "Commit changes" vs "Commit your changes") still produce a match.
The merged list is emitted as plain Markdown text (ordered 1. … lines) and
passed to the caller via add_raw on the OutputBuilder.
Constant Summary collapse
- ITEM_MATCH_THRESHOLD =
Minimum Jaccard token overlap to consider two list items as matching.
0.35
Instance Method Summary collapse
-
#merge_lists(template_node, dest_node, preference:, add_template_only_nodes: true, template_analysis: nil, dest_analysis: nil, resolution_mode: :eager, unresolved_policy: nil) ⇒ Hash
Merge two list nodes.
Instance Method Details
#merge_lists(template_node, dest_node, preference:, add_template_only_nodes: true, template_analysis: nil, dest_analysis: nil, resolution_mode: :eager, unresolved_policy: nil) ⇒ Hash
Merge two list nodes.
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 |
# File 'lib/markdown/merge/list_merger.rb', line 48 def merge_lists(template_node, dest_node, preference:, add_template_only_nodes: true, template_analysis: nil, dest_analysis: nil, resolution_mode: :eager, unresolved_policy: nil) t_items = extract_items(template_node) d_items = extract_items(dest_node) return not_merged('empty list') if t_items.empty? && d_items.empty? alignment = align_items(t_items, d_items) lines, unresolved_cases = emit_lines( alignment, template_node: template_node, dest_node: dest_node, preference: preference, add_template_only: add_template_only_nodes, template_analysis: template_analysis, dest_analysis: dest_analysis, resolution_mode: resolution_mode, unresolved_policy: Ast::Merge::UnresolvedPolicy.coerce(unresolved_policy) ) return not_merged('no lines emitted') if lines.empty? { merged: true, content: lines.join("\n") + "\n", stats: { decision: unresolved_cases.empty? ? :merged : :unresolved }, unresolved_cases: unresolved_cases } end |