Class: Canon::DiffFormatter::ByLine::BaseFormatter
- Inherits:
-
Object
- Object
- Canon::DiffFormatter::ByLine::BaseFormatter
- Defined in:
- lib/canon/diff_formatter/by_line/base_formatter.rb
Overview
Base formatter for line-by-line diffs Provides common LCS diff logic and hunk building
Direct Known Subclasses
HtmlFormatter, JsonFormatter, SimpleFormatter, XmlFormatter, YamlFormatter
Instance Attribute Summary collapse
-
#context_lines ⇒ Object
readonly
Returns the value of attribute context_lines.
-
#diff_grouping_lines ⇒ Object
readonly
Returns the value of attribute diff_grouping_lines.
-
#diff_mode ⇒ Object
readonly
Returns the value of attribute diff_mode.
-
#legacy_terminal ⇒ Object
readonly
Returns the value of attribute legacy_terminal.
-
#show_diffs ⇒ Object
readonly
Returns the value of attribute show_diffs.
-
#use_color ⇒ Object
readonly
Returns the value of attribute use_color.
-
#visualization_map ⇒ Object
readonly
Returns the value of attribute visualization_map.
Class Method Summary collapse
-
.for_format(format, **options) ⇒ BaseFormatter
Create a format-specific by-line formatter.
Instance Method Summary collapse
-
#apply_bg(presenter, bg_color) ⇒ Rainbow::Presenter
Apply a background color to a Rainbow presenter.
-
#apply_color(presenter, color) ⇒ Rainbow::Presenter
Apply a color to a Rainbow presenter, normalizing bright_/light_ colors.
-
#apply_theme_style(text, style) ⇒ String
Apply full theme styling to text.
-
#changed_content_styles ⇒ Hash
Get changed content styles (old and new).
-
#compute_line_num_width(doc1, doc2) ⇒ Object
Compute line number column width from document line counts.
-
#content_style(diff_type) ⇒ Hash
Get content style for a diff type.
-
#display_mode ⇒ Symbol
Get display mode.
-
#format(doc1, doc2) ⇒ String
Format line-by-line diff Subclasses must implement this method.
-
#initialize(use_color: true, context_lines: 3, diff_grouping_lines: nil, visualization_map: nil, show_diffs: :all, differences: [], diff_mode: :separate, legacy_terminal: false, equivalent: nil, theme: nil, character_visualization: true) ⇒ BaseFormatter
constructor
rubocop:disable Metrics/ParameterLists.
-
#marker_style(diff_type) ⇒ Hash
Get marker style for a diff type.
-
#normalize_color_for_rainbow(color) ⇒ Array<Symbol>
Normalize a color symbol for Rainbow presenter.
-
#structure_color(element) ⇒ Symbol?
Get structure color.
-
#structure_styles ⇒ Hash
Get structure styles.
-
#styled_marker(text, diff_type) ⇒ String
Apply marker styling using theme.
-
#theme ⇒ Hash
Get the resolved theme hash.
-
#theme_color(diff_type, element) ⇒ Symbol?
Get theme color for a specific diff type and element.
-
#theme_style(section, diff_type, element) ⇒ Hash
Get theme by section and type.
-
#unchanged_content_style ⇒ Hash
Get style for unchanged content.
-
#visualization_chars ⇒ Hash
Get visualization characters.
Constructor Details
#initialize(use_color: true, context_lines: 3, diff_grouping_lines: nil, visualization_map: nil, show_diffs: :all, differences: [], diff_mode: :separate, legacy_terminal: false, equivalent: nil, theme: nil, character_visualization: true) ⇒ BaseFormatter
rubocop:disable Metrics/ParameterLists
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 49 def initialize(use_color: true, context_lines: 3, diff_grouping_lines: nil, visualization_map: nil, show_diffs: :all, differences: [], diff_mode: :separate, legacy_terminal: false, equivalent: nil, theme: nil, character_visualization: true) @use_color = use_color @context_lines = context_lines @diff_grouping_lines = diff_grouping_lines @visualization_map = visualization_map @show_diffs = show_diffs @differences = differences @line_num_width = 4 @diff_mode = legacy_terminal ? :separate : diff_mode @legacy_terminal = legacy_terminal @equivalent = equivalent @theme = theme @character_visualization = character_visualization end |
Instance Attribute Details
#context_lines ⇒ Object (readonly)
Returns the value of attribute context_lines.
14 15 16 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 14 def context_lines @context_lines end |
#diff_grouping_lines ⇒ Object (readonly)
Returns the value of attribute diff_grouping_lines.
14 15 16 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 14 def diff_grouping_lines @diff_grouping_lines end |
#diff_mode ⇒ Object (readonly)
Returns the value of attribute diff_mode.
14 15 16 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 14 def diff_mode @diff_mode end |
#legacy_terminal ⇒ Object (readonly)
Returns the value of attribute legacy_terminal.
14 15 16 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 14 def legacy_terminal @legacy_terminal end |
#show_diffs ⇒ Object (readonly)
Returns the value of attribute show_diffs.
14 15 16 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 14 def show_diffs @show_diffs end |
#use_color ⇒ Object (readonly)
Returns the value of attribute use_color.
14 15 16 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 14 def use_color @use_color end |
#visualization_map ⇒ Object (readonly)
Returns the value of attribute visualization_map.
14 15 16 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 14 def visualization_map @visualization_map end |
Class Method Details
.for_format(format, **options) ⇒ BaseFormatter
Create a format-specific by-line formatter
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/canon/diff_formatter/by_line/base_formatter.rb', line 22 def self.for_format(format, **) case format when :xml require_relative "xml_formatter" XmlFormatter.new(**) when :html, :html4, :html5 require_relative "html_formatter" # Determine HTML version from format version = case format when :html5 then :html5 when :html4 then :html4 else :html4 # default to html4 end HtmlFormatter.new(html_version: version, **) when :json require_relative "json_formatter" JsonFormatter.new(**) when :yaml require_relative "yaml_formatter" YamlFormatter.new(**) else require_relative "simple_formatter" SimpleFormatter.new(**) end end |
Instance Method Details
#apply_bg(presenter, bg_color) ⇒ Rainbow::Presenter
Apply a background color to a Rainbow presenter.
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 244 def apply_bg(presenter, bg_color) return presenter unless bg_color case bg_color.to_s when /^light_(.+)$/ # Rainbow doesn't support light_ backgrounds, use the base color base = $1.to_sym presenter.background(base) when "default", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" presenter.background(bg_color) else # Try as-is and let Rainbow handle unknown colors presenter.background(bg_color) end end |
#apply_color(presenter, color) ⇒ Rainbow::Presenter
Apply a color to a Rainbow presenter, normalizing bright_/light_ colors.
234 235 236 237 238 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 234 def apply_color(presenter, color) valid_colors = normalize_color_for_rainbow(color) valid_colors.each { |c| presenter = presenter.send(c) } presenter end |
#apply_theme_style(text, style) ⇒ String
Apply full theme styling to text
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 89 def apply_theme_style(text, style) return text if style.empty? || !@use_color color = style[:color] bg = style[:bg] bold = style[:bold] underline = style[:underline] strikethrough = style[:strikethrough] # Apply visualization first visual = apply_visualization(text) return visual unless color || bg || bold || underline || strikethrough require "rainbow" rainbow = Rainbow.new rainbow.enabled = true presenter = rainbow.wrap(visual) if color && color != :default presenter = apply_color(presenter, color) end presenter = apply_bg(presenter, bg) if bg presenter = presenter.bold if bold presenter = presenter.underline if underline presenter = presenter.cross_out if strikethrough presenter.to_s end |
#changed_content_styles ⇒ Hash
Get changed content styles (old and new)
147 148 149 150 151 152 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 147 def changed_content_styles { content_old: theme_style(:diff, :changed, :content_old), content_new: theme_style(:diff, :changed, :content_new), } end |
#compute_line_num_width(doc1, doc2) ⇒ Object
Compute line number column width from document line counts
121 122 123 124 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 121 def compute_line_num_width(doc1, doc2) max_lines = [doc1.count("\n"), doc2.count("\n")].max @line_num_width = [max_lines.to_s.length, 4].max end |
#content_style(diff_type) ⇒ Hash
Get content style for a diff type
141 142 143 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 141 def content_style(diff_type) theme_style(:diff, diff_type, :content) end |
#display_mode ⇒ Symbol
Get display mode
174 175 176 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 174 def display_mode theme[:display_mode] || :separate end |
#format(doc1, doc2) ⇒ String
Format line-by-line diff Subclasses must implement this method
266 267 268 269 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 266 def format(doc1, doc2) raise NotImplementedError, "Subclasses must implement the format method" end |
#marker_style(diff_type) ⇒ Hash
Get marker style for a diff type
134 135 136 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 134 def marker_style(diff_type) theme_style(:diff, diff_type, :marker) end |
#normalize_color_for_rainbow(color) ⇒ Array<Symbol>
Normalize a color symbol for Rainbow presenter. Rainbow doesn’t support :bright_blue directly - instead it uses chained methods like .blue.bright or .bright.blue. This returns an array of method symbols to chain.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 211 def normalize_color_for_rainbow(color) return [] if color.nil? case color.to_s when /^bright_(.+)$/ # :bright_blue -> [:blue, :bright] base = $1.to_sym [base, :bright] when /^light_(.+)$/ # :light_red -> Rainbow doesn't support light_, treat as white [:white] when "default", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white" [color] else # Unknown color, return as-is and let Rainbow raise [color] end end |
#structure_color(element) ⇒ Symbol?
Get structure color
200 201 202 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 200 def structure_color(element) theme.dig(:structure, element, :color) end |
#structure_styles ⇒ Hash
Get structure styles
162 163 164 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 162 def structure_styles theme[:structure] || {} end |
#styled_marker(text, diff_type) ⇒ String
Apply marker styling using theme
182 183 184 185 186 187 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 182 def styled_marker(text, diff_type) style = marker_style(diff_type) return text unless @use_color && style[:color] apply_theme_style(text, style) end |
#theme ⇒ Hash
Get the resolved theme hash
72 73 74 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 72 def theme @theme ||= Theme.resolver(Canon::Config.instance).resolve end |
#theme_color(diff_type, element) ⇒ Symbol?
Get theme color for a specific diff type and element
193 194 195 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 193 def theme_color(diff_type, element) theme_style(:diff, diff_type, element)[:color] end |
#theme_style(section, diff_type, element) ⇒ Hash
Get theme by section and type
81 82 83 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 81 def theme_style(section, diff_type, element) theme.dig(section, diff_type, element) || {} end |
#unchanged_content_style ⇒ Hash
Get style for unchanged content
156 157 158 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 156 def unchanged_content_style theme_style(:diff, :unchanged, :content) end |
#visualization_chars ⇒ Hash
Get visualization characters
168 169 170 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 168 def visualization_chars theme[:visualization] || {} end |