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
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 42 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.
12 13 14 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 12 def context_lines @context_lines end |
#diff_grouping_lines ⇒ Object (readonly)
Returns the value of attribute diff_grouping_lines.
12 13 14 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 12 def diff_grouping_lines @diff_grouping_lines end |
#diff_mode ⇒ Object (readonly)
Returns the value of attribute diff_mode.
12 13 14 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 12 def diff_mode @diff_mode end |
#legacy_terminal ⇒ Object (readonly)
Returns the value of attribute legacy_terminal.
12 13 14 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 12 def legacy_terminal @legacy_terminal end |
#show_diffs ⇒ Object (readonly)
Returns the value of attribute show_diffs.
12 13 14 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 12 def show_diffs @show_diffs end |
#use_color ⇒ Object (readonly)
Returns the value of attribute use_color.
12 13 14 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 12 def use_color @use_color end |
#visualization_map ⇒ Object (readonly)
Returns the value of attribute visualization_map.
12 13 14 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 12 def visualization_map @visualization_map end |
Class Method Details
.for_format(format, **options) ⇒ BaseFormatter
Create a format-specific by-line formatter
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 20 def self.for_format(format, **) case format when :xml XmlFormatter.new(**) when :html, :html4, :html5 # 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 JsonFormatter.new(**) when :yaml YamlFormatter.new(**) else SimpleFormatter.new(**) end end |
Instance Method Details
#apply_bg(presenter, bg_color) ⇒ Rainbow::Presenter
Apply a background color to a Rainbow presenter.
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 237 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.
227 228 229 230 231 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 227 def apply_color(presenter, color) valid_colors = normalize_color_for_rainbow(color) valid_colors.each { |c| presenter = presenter.public_send(c) } presenter end |
#apply_theme_style(text, style) ⇒ String
Apply full theme styling to text
82 83 84 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 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 82 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)
140 141 142 143 144 145 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 140 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
114 115 116 117 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 114 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
134 135 136 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 134 def content_style(diff_type) theme_style(:diff, diff_type, :content) end |
#display_mode ⇒ Symbol
Get display mode
167 168 169 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 167 def display_mode theme[:display_mode] || :separate end |
#format(doc1, doc2) ⇒ String
Format line-by-line diff Subclasses must implement this method
259 260 261 262 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 259 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
127 128 129 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 127 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.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 204 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
193 194 195 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 193 def structure_color(element) theme.dig(:structure, element, :color) end |
#structure_styles ⇒ Hash
Get structure styles
155 156 157 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 155 def structure_styles theme[:structure] || {} end |
#styled_marker(text, diff_type) ⇒ String
Apply marker styling using theme
175 176 177 178 179 180 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 175 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
65 66 67 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 65 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
186 187 188 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 186 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
74 75 76 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 74 def theme_style(section, diff_type, element) theme.dig(section, diff_type, element) || {} end |
#unchanged_content_style ⇒ Hash
Get style for unchanged content
149 150 151 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 149 def unchanged_content_style theme_style(:diff, :unchanged, :content) end |
#visualization_chars ⇒ Hash
Get visualization characters
161 162 163 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 161 def visualization_chars theme[:visualization] || {} end |