module Markdown
module Merge
VERSION: String
# Base error class for Markdown::Merge
class Error < Ast::Merge::Error
end
# Raised when a Markdown file has parsing errors
class ParseError < Ast::Merge::ParseError
def initialize: (?String? message, ?content: String?, ?errors: Array[untyped]) -> void
end
# Raised when the template file has syntax errors
class TemplateParseError < ParseError
end
# Raised when the destination file has syntax errors
class DestinationParseError < ParseError
end
# Debug logging utility for Markdown::Merge operations
module DebugLogger
extend Ast::Merge::DebugLogger
def self.env_var_name: () -> String
def self.env_var_name=: (String name) -> String
def self.log_prefix: () -> String
def self.log_prefix=: (String prefix) -> String
def self.enabled?: () -> bool
def self.debug: (*untyped args) -> void
def self.info: (*untyped args) -> void
def self.warning: (*untyped args) -> void
def self.time: [T] (String label) { () -> T } -> T
def self.log_node: (untyped node, ?label: String) -> void
end
# Represents a frozen block of Markdown content
class FreezeNode < Ast::Merge::FreezeNodeBase
def initialize: (
start_line: Integer,
end_line: Integer,
content: String,
start_marker: String,
end_marker: String,
?nodes: Array[untyped],
?reason: String?
) -> void
def signature: () -> Array[Symbol | String]
def full_text: () -> String
def line_count: () -> Integer
def contains_type?: (Symbol type_symbol) -> bool
def inspect: () -> String
end
# Base class for file analysis for Markdown files
class FileAnalysisBase
include Ast::Merge::FileAnalyzable
DEFAULT_FREEZE_TOKEN: String
attr_reader document: untyped
attr_reader statements: Array[untyped]
def initialize: (
String source,
?freeze_token: String,
?signature_generator: (^(untyped) -> (Array[untyped] | untyped | nil))?,
**untyped parser_options
) -> void
# Abstract methods - subclasses must implement
def parse_document: (String source) -> untyped
def next_sibling: (untyped node) -> untyped?
def valid?: () -> bool
def compute_node_signature: (untyped node) -> Array[untyped]?
def fallthrough_node?: (untyped value) -> bool
def parser_node?: (untyped value) -> bool
def compute_parser_signature: (untyped node) -> Array[untyped]?
def safe_string_content: (untyped node) -> String
def extract_text_content: (untyped node) -> String
def extract_table_header_content: (untyped node) -> String
def source_range: (Integer start_line, Integer end_line) -> String
def count_children: (untyped node) -> Integer
private
def extract_and_integrate_all_nodes: () -> Array[untyped]
def collect_top_level_nodes: () -> Array[untyped]
def build_freeze_blocks: (Array[untyped] nodes) -> Array[FreezeNode]
def integrate_freeze_blocks: (Array[untyped] nodes, Array[FreezeNode] freeze_blocks) -> Array[untyped]
end
# Aligns Markdown block elements between template and destination files
class FileAligner
attr_reader template_analysis: FileAnalysisBase
attr_reader dest_analysis: FileAnalysisBase
attr_reader match_refiner: (^(Array[untyped], Array[untyped], Hash[Symbol, untyped]) -> Array[MatchResult])?
def initialize: (
FileAnalysisBase template_analysis,
FileAnalysisBase dest_analysis,
?match_refiner: (^(Array[untyped], Array[untyped], Hash[Symbol, untyped]) -> Array[MatchResult])?
) -> void
def align: () -> Array[Hash[Symbol, untyped]]
private
def build_signature_map: (Array[untyped] statements, FileAnalysisBase analysis) -> Hash[Array[untyped], Array[Integer]]
end
# Match result from refiners
class MatchResult
attr_reader template_node: untyped
attr_reader dest_node: untyped
attr_reader score: Float
def initialize: (
template_node: untyped,
dest_node: untyped,
score: Float
) -> void
end
# Resolves conflicts between matching Markdown elements
class ConflictResolver < Ast::Merge::ConflictResolverBase
def initialize: (
preference: Symbol,
template_analysis: FileAnalysisBase,
dest_analysis: FileAnalysisBase
) -> void
private
def resolve_node_pair: (
untyped template_node,
untyped dest_node,
template_index: Integer,
dest_index: Integer
) -> Hash[Symbol, untyped]
def content_identical?: (untyped template_node, untyped dest_node) -> bool
def node_to_text: (untyped node, FileAnalysisBase analysis) -> String
end
# Represents the result of a Markdown merge operation
class MergeResult < Ast::Merge::MergeResultBase
def initialize: (
content: String?,
?conflicts: Array[Hash[Symbol, untyped]],
?frozen_blocks: Array[Hash[Symbol, untyped]],
?stats: Hash[Symbol, untyped]
) -> void
def content: () -> String?
def content?: () -> bool
def content_string: () -> String?
def success?: () -> bool
def conflicts?: () -> bool
def has_frozen_blocks?: () -> bool
def nodes_added: () -> Integer
def nodes_removed: () -> Integer
def nodes_modified: () -> Integer
def merge_time_ms: () -> Float?
def frozen_count: () -> Integer
def inspect: () -> String
def to_s: () -> String
private
def default_stats: () -> Hash[Symbol, untyped]
end
# Algorithm for computing match scores between two Markdown tables
class TableMatchAlgorithm
DEFAULT_WEIGHTS: Hash[Symbol, Float]
FIRST_COLUMN_SIMILARITY_THRESHOLD: Float
attr_reader position_a: Integer?
attr_reader position_b: Integer?
attr_reader total_tables_a: Integer
attr_reader total_tables_b: Integer
attr_reader weights: Hash[Symbol, Float]
def initialize: (
?position_a: Integer?,
?position_b: Integer?,
?total_tables_a: Integer,
?total_tables_b: Integer,
?weights: Hash[Symbol, Float]
) -> void
def call: (untyped table_a, untyped table_b) -> Float
private
def levenshtein_distance: (String a, String b) -> Integer
def levenshtein_similarity: (String a, String b) -> Float
def extract_rows: (untyped table) -> Array[Array[String]]
def extract_cell_text: (untyped cell) -> String
def compute_header_match: (Array[Array[String]] rows_a, Array[Array[String]] rows_b) -> Float
def compute_first_column_match: (Array[Array[String]] rows_a, Array[Array[String]] rows_b) -> Float
def compute_row_content_match: (Array[Array[String]] rows_a, Array[Array[String]] rows_b) -> Float
def compute_total_cells_match: (Array[Array[String]] rows_a, Array[Array[String]] rows_b) -> Float
def compute_position_score: () -> Float
def weighted_average: (Hash[Symbol, Float] scores) -> Float
end
# Match refiner for Markdown tables that didn't match by exact signature
class TableMatchRefiner < Ast::Merge::MatchRefinerBase
attr_reader algorithm_options: Hash[Symbol, untyped]
def initialize: (
?threshold: Float,
?algorithm_options: Hash[Symbol, untyped],
**untyped options
) -> void
def call: (
Array[untyped] template_nodes,
Array[untyped] dest_nodes,
?Hash[Symbol, untyped] context
) -> Array[MatchResult]
private
def extract_tables: (Array[untyped] nodes) -> Array[untyped]
def table_node?: (untyped node) -> bool
def compute_table_similarity: (
untyped t_table,
untyped d_table,
Integer t_idx,
Integer d_idx,
Integer total_t,
Integer total_d
) -> Float
end
# Merges fenced code blocks using language-specific *-merge gems
class CodeBlockMerger
DEFAULT_MERGERS: Hash[String, ^(String, String, Symbol, **untyped) -> Hash[Symbol, untyped]]
attr_reader mergers: Hash[String, ^(String, String, Symbol, **untyped) -> Hash[Symbol, untyped]]
attr_reader enabled: bool
def initialize: (
?mergers: Hash[String, ^(String, String, Symbol, **untyped) -> Hash[Symbol, untyped]],
?enabled: bool
) -> void
def supports_language?: (String? language) -> bool
def merge_code_blocks: (
untyped template_node,
untyped dest_node,
preference: Symbol,
**untyped opts
) -> Hash[Symbol, untyped]
# Class methods for specific mergers
def self.merge_with_prism: (String template, String dest, Symbol preference, **untyped opts) -> Hash[Symbol, untyped]
def self.merge_with_psych: (String template, String dest, Symbol preference, **untyped opts) -> Hash[Symbol, untyped]
def self.merge_with_json: (String template, String dest, Symbol preference, **untyped opts) -> Hash[Symbol, untyped]
def self.merge_with_toml: (String template, String dest, Symbol preference, **untyped opts) -> Hash[Symbol, untyped]
private
def extract_language: (untyped node) -> String?
def extract_content: (untyped node) -> String
def rebuild_code_block: (String language, String content, untyped reference_node) -> String
def not_merged: (String reason) -> Hash[Symbol, untyped]
end
# Builds markdown output from merge operations
class OutputBuilder
@parts: Array[String]
@preserve_formatting: bool
def initialize: (?preserve_formatting: bool) -> void
def add_node_source: (untyped node, FileAnalysisBase analysis) -> void
def add_link_definition: (LinkDefinitionNode node) -> void
def add_gap_line: (?count: Integer) -> void
def add_raw: (String text) -> void
def to_s: () -> String
def empty?: () -> bool
def clear: () -> void
private
def extract_source: (untyped node, FileAnalysisBase analysis) -> String?
def extract_parser_node_source: (untyped node, FileAnalysisBase analysis) -> String?
end
# Formats link reference definitions for output
module LinkDefinitionFormatter
def self.format: (LinkDefinitionNode node) -> String
def self.format_all: (Array[LinkDefinitionNode] nodes, ?separator: String) -> String
end
# Base class for smart Markdown file merging
class SmartMergerBase
attr_reader template_analysis: FileAnalysisBase
attr_reader dest_analysis: FileAnalysisBase
attr_reader aligner: FileAligner
attr_reader resolver: ConflictResolver
attr_reader code_block_merger: CodeBlockMerger?
def initialize: (
String template_content,
String dest_content,
?signature_generator: (^(untyped) -> (Array[untyped] | untyped | nil))?,
?preference: Symbol,
?add_template_only_nodes: bool,
?inner_merge_code_blocks: (bool | CodeBlockMerger),
?freeze_token: String,
?match_refiner: (^(Array[untyped], Array[untyped], Hash[Symbol, untyped]) -> Array[MatchResult])?,
**untyped parser_options
) -> void
# Abstract methods - subclasses must implement
def create_file_analysis: (String content, **untyped options) -> FileAnalysisBase
def node_to_source: (untyped node, FileAnalysisBase analysis) -> String
def template_parse_error_class: () -> Class
def destination_parse_error_class: () -> Class
def merge: () -> String
def merge_result: () -> MergeResult
private
def build_result_content: (Array[Hash[Symbol, untyped]] alignment) -> String
def process_alignment_entry: (Hash[Symbol, untyped] entry) -> String?
def handle_match: (Hash[Symbol, untyped] entry) -> String?
def handle_template_only: (Hash[Symbol, untyped] entry) -> String?
def handle_dest_only: (Hash[Symbol, untyped] entry) -> String?
end end end