Class: Markdown::Merge::CodeBlockMerger
- Inherits:
-
Object
- Object
- Markdown::Merge::CodeBlockMerger
- Defined in:
- lib/markdown/merge/code_block_merger.rb
Overview
Merges fenced code blocks using language-specific *-merge gems.
When two code blocks with the same signature are matched, this class delegates the merge to the appropriate language-specific merger:
- Ruby code → prism-merge
- YAML code → psych-merge
- JSON code → json-merge
- TOML code → toml-merge
Constant Summary collapse
- DEFAULT_MERGERS =
Default language-to-merger mapping Each merger is a lambda that takes (template_content, dest_content, preference) and returns { merged: true/false, content: String, stats: Hash } simplecov:disable integration - DEFAULT_MERGERS lambdas require external gems
{ # Ruby code blocks 'ruby' => lambda { |template, dest, preference, **opts| require 'prism/merge' CodeBlockMerger.merge_with_prism(template, dest, preference, **opts) }, 'rb' => lambda { |template, dest, preference, **opts| require 'prism/merge' CodeBlockMerger.merge_with_prism(template, dest, preference, **opts) }, # YAML code blocks 'yaml' => lambda { |template, dest, preference, **opts| require 'psych/merge' CodeBlockMerger.merge_with_psych(template, dest, preference, **opts) }, 'yml' => lambda { |template, dest, preference, **opts| require 'psych/merge' CodeBlockMerger.merge_with_psych(template, dest, preference, **opts) }, # JSON code blocks 'json' => lambda { |template, dest, preference, **opts| require 'json/merge' CodeBlockMerger.merge_with_json(template, dest, preference, **opts) }, # Markdown code blocks 'markdown' => lambda { |template, dest, preference, **opts| require 'markdown/merge' CodeBlockMerger.merge_with_markdown(template, dest, preference, **opts) }, 'md' => lambda { |template, dest, preference, **opts| require 'markdown/merge' CodeBlockMerger.merge_with_markdown(template, dest, preference, **opts) }, # TOML code blocks 'toml' => lambda { |template, dest, preference, **opts| require 'toml/merge' CodeBlockMerger.merge_with_toml(template, dest, preference, **opts) } }.freeze
Instance Attribute Summary collapse
-
#enabled ⇒ Boolean
readonly
Whether inner-merge is enabled.
-
#mergers ⇒ Hash<String, Proc>
readonly
Language to merger mapping.
-
#runtime_delegates ⇒ Array<Ast::Merge::Runtime::Delegate>
readonly
Runtime delegates exposed by this merger.
Class Method Summary collapse
-
.merge_with_json(template, dest, preference, **opts) ⇒ Hash
Merge JSON code using json-merge.
-
.merge_with_markdown(template, dest, preference, **opts) ⇒ Hash
Merge Markdown code using markdown-merge.
-
.merge_with_prism(template, dest, preference, **opts) ⇒ Hash
Merge Ruby code using prism-merge.
-
.merge_with_psych(template, dest, preference, **opts) ⇒ Hash
Merge YAML code using psych-merge.
-
.merge_with_toml(template, dest, preference, **opts) ⇒ Hash
Merge TOML code using toml-merge.
Instance Method Summary collapse
-
#initialize(mergers: {}, enabled: true) ⇒ CodeBlockMerger
constructor
Creates a new CodeBlockMerger.
-
#merge_code_blocks(template_node, dest_node, preference:, runtime_session: nil, parent_operation: nil, **opts) ⇒ Hash
Merge two code blocks using the appropriate language-specific merger.
- #merge_code_blocks_without_runtime(template_node, dest_node, preference:, **opts) ⇒ Object
-
#supports_language?(language) ⇒ Boolean
Check if inner-merge is available for a language.
Constructor Details
#initialize(mergers: {}, enabled: true) ⇒ CodeBlockMerger
Creates a new CodeBlockMerger.
96 97 98 99 100 |
# File 'lib/markdown/merge/code_block_merger.rb', line 96 def initialize(mergers: {}, enabled: true) @mergers = DEFAULT_MERGERS.merge(mergers) @enabled = enabled @runtime_delegates = build_runtime_delegates.freeze end |
Instance Attribute Details
#enabled ⇒ Boolean (readonly)
Returns Whether inner-merge is enabled.
86 87 88 |
# File 'lib/markdown/merge/code_block_merger.rb', line 86 def enabled @enabled end |
#mergers ⇒ Hash<String, Proc> (readonly)
Returns Language to merger mapping.
83 84 85 |
# File 'lib/markdown/merge/code_block_merger.rb', line 83 def mergers @mergers end |
#runtime_delegates ⇒ Array<Ast::Merge::Runtime::Delegate> (readonly)
Returns Runtime delegates exposed by this merger.
89 90 91 |
# File 'lib/markdown/merge/code_block_merger.rb', line 89 def runtime_delegates @runtime_delegates end |
Class Method Details
.merge_with_json(template, dest, preference, **opts) ⇒ Hash
Errors are handled by merge_code_blocks when called via DEFAULT_MERGERS
Merge JSON code using json-merge.
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 |
# File 'lib/markdown/merge/code_block_merger.rb', line 652 def merge_with_json(template, dest, preference, **opts) merger = ::Json::Merge::SmartMerger.new( template, dest, preference: preference, add_template_only_nodes: opts.fetch(:add_template_only_nodes, false), resolution_mode: opts.fetch(:resolution_mode, :eager), unresolved_policy: opts[:unresolved_policy] ) merge_result = merger.merge_result if opts[:apply_unresolved_resolutions] merge_result.apply_unresolved_resolutions!(opts[:apply_unresolved_resolutions]) end { merged: true, content: merge_result.to_json, stats: merger.stats, unresolved_cases: merge_result.unresolved_cases } end |
.merge_with_markdown(template, dest, preference, **opts) ⇒ Hash
Merge Markdown code using markdown-merge.
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 |
# File 'lib/markdown/merge/code_block_merger.rb', line 680 def merge_with_markdown(template, dest, preference, **opts) nested_code_block_merger = CodeBlockMerger.new( mergers: opts.fetch(:nested_mergers, {}), enabled: opts.fetch(:inner_merge_code_blocks, true) ) merger = ::Markdown::Merge::SmartMerger.new( template, dest, preference: preference, add_template_only_nodes: opts.fetch(:add_template_only_nodes, false), inner_merge_code_blocks: nested_code_block_merger, resolution_mode: opts.fetch(:resolution_mode, :eager), unresolved_policy: opts[:unresolved_policy] ) merge_result = merger.merge_result if opts[:apply_unresolved_resolutions] merge_result.apply_unresolved_resolutions!(opts[:apply_unresolved_resolutions]) end { merged: true, content: merge_result.to_s, stats: merger.stats, unresolved_cases: merge_result.unresolved_cases, metadata: { nested_runtime_session: merger.runtime_session&.to_h } } end |
.merge_with_prism(template, dest, preference, **opts) ⇒ Hash
Errors are handled by merge_code_blocks when called via DEFAULT_MERGERS
Merge Ruby code using prism-merge.
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 |
# File 'lib/markdown/merge/code_block_merger.rb', line 592 def merge_with_prism(template, dest, preference, **opts) merger = ::Prism::Merge::SmartMerger.new( template, dest, preference: preference, add_template_only_nodes: opts.fetch(:add_template_only_nodes, false), resolution_mode: opts.fetch(:resolution_mode, :eager), unresolved_policy: opts[:unresolved_policy] ) merge_result = merger.merge_result if opts[:apply_unresolved_resolutions] merge_result.apply_unresolved_resolutions!(opts[:apply_unresolved_resolutions]) end { merged: true, content: merge_result.to_s, stats: merger.stats, unresolved_cases: merge_result.unresolved_cases } end |
.merge_with_psych(template, dest, preference, **opts) ⇒ Hash
Errors are handled by merge_code_blocks when called via DEFAULT_MERGERS
Merge YAML code using psych-merge.
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 |
# File 'lib/markdown/merge/code_block_merger.rb', line 622 def merge_with_psych(template, dest, preference, **opts) merger = ::Psych::Merge::SmartMerger.new( template, dest, preference: preference, add_template_only_nodes: opts.fetch(:add_template_only_nodes, false), resolution_mode: opts.fetch(:resolution_mode, :eager), unresolved_policy: opts[:unresolved_policy] ) merge_result = merger.merge_result if opts[:apply_unresolved_resolutions] merge_result.apply_unresolved_resolutions!(opts[:apply_unresolved_resolutions]) end { merged: true, content: merge_result.to_yaml, stats: merger.stats, unresolved_cases: merge_result.unresolved_cases } end |
.merge_with_toml(template, dest, preference, **opts) ⇒ Hash
Errors are handled by merge_code_blocks when called via DEFAULT_MERGERS
Merge TOML code using toml-merge.
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 |
# File 'lib/markdown/merge/code_block_merger.rb', line 718 def merge_with_toml(template, dest, preference, **opts) merger = ::Toml::Merge::SmartMerger.new( template, dest, preference: preference, add_template_only_nodes: opts.fetch(:add_template_only_nodes, false), resolution_mode: opts.fetch(:resolution_mode, :eager), unresolved_policy: opts[:unresolved_policy] ) merge_result = merger.merge_result if opts[:apply_unresolved_resolutions] merge_result.apply_unresolved_resolutions!(opts[:apply_unresolved_resolutions]) end { merged: true, content: merge_result.to_toml, stats: merger.stats, unresolved_cases: merge_result.unresolved_cases } end |
Instance Method Details
#merge_code_blocks(template_node, dest_node, preference:, runtime_session: nil, parent_operation: nil, **opts) ⇒ Hash
Merge two code blocks using the appropriate language-specific merger.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/markdown/merge/code_block_merger.rb', line 120 def merge_code_blocks(template_node, dest_node, preference:, runtime_session: nil, parent_operation: nil, **opts) if runtime_session && parent_operation return merge_code_blocks_with_runtime( template_node, dest_node, preference: preference, runtime_session: runtime_session, parent_operation: parent_operation, **opts ) end merge_code_blocks_without_runtime(template_node, dest_node, preference: preference, **opts) end |
#merge_code_blocks_without_runtime(template_node, dest_node, preference:, **opts) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/markdown/merge/code_block_merger.rb', line 135 def merge_code_blocks_without_runtime(template_node, dest_node, preference:, **opts) return not_merged('inner-merge disabled') unless @enabled language = extract_language(template_node) || extract_language(dest_node) return not_merged('no language specified') unless language template_content = extract_content(template_node) dest_content = extract_content(dest_node) perform_code_block_merge( language: language, template_content: template_content, dest_content: dest_content, preference: preference, reference_node: dest_node, **opts ) end |
#supports_language?(language) ⇒ Boolean
Check if inner-merge is available for a language.
106 107 108 109 110 111 |
# File 'lib/markdown/merge/code_block_merger.rb', line 106 def supports_language?(language) return false unless @enabled return false if language.nil? || language.empty? @mergers.key?(language.downcase) end |