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) ⇒ BaseFormatter
constructor
A new instance of BaseFormatter.
-
#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) ⇒ BaseFormatter
Returns a new instance of BaseFormatter.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 48 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) @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 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.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 240 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.
230 231 232 233 234 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 230 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
85 86 87 88 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 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 85 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)
143 144 145 146 147 148 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 143 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
117 118 119 120 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 117 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
137 138 139 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 137 def content_style(diff_type) theme_style(:diff, diff_type, :content) end |
#display_mode ⇒ Symbol
Get display mode
170 171 172 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 170 def display_mode theme[:display_mode] || :separate end |
#format(doc1, doc2) ⇒ String
Format line-by-line diff Subclasses must implement this method
262 263 264 265 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 262 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
130 131 132 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 130 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.
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 207 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
196 197 198 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 196 def structure_color(element) theme.dig(:structure, element, :color) end |
#structure_styles ⇒ Hash
Get structure styles
158 159 160 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 158 def structure_styles theme[:structure] || {} end |
#styled_marker(text, diff_type) ⇒ String
Apply marker styling using theme
178 179 180 181 182 183 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 178 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
68 69 70 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 68 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
189 190 191 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 189 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
77 78 79 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 77 def theme_style(section, diff_type, element) theme.dig(section, diff_type, element) || {} end |
#unchanged_content_style ⇒ Hash
Get style for unchanged content
152 153 154 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 152 def unchanged_content_style theme_style(:diff, :unchanged, :content) end |
#visualization_chars ⇒ Hash
Get visualization characters
164 165 166 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 164 def visualization_chars theme[:visualization] || {} end |