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-next 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-next 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.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 236 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.
226 227 228 229 230 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 226 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
81 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 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 81 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)
139 140 141 142 143 144 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 139 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
113 114 115 116 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 113 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
133 134 135 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 133 def content_style(diff_type) theme_style(:diff, diff_type, :content) end |
#display_mode ⇒ Symbol
Get display mode
166 167 168 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 166 def display_mode theme[:display_mode] || :separate end |
#format(doc1, doc2) ⇒ String
Format line-by-line diff Subclasses must implement this method
258 259 260 261 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 258 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
126 127 128 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 126 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.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 203 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
192 193 194 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 192 def structure_color(element) theme.dig(:structure, element, :color) end |
#structure_styles ⇒ Hash
Get structure styles
154 155 156 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 154 def structure_styles theme[:structure] || {} end |
#styled_marker(text, diff_type) ⇒ String
Apply marker styling using theme
174 175 176 177 178 179 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 174 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
64 65 66 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 64 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
185 186 187 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 185 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
73 74 75 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 73 def theme_style(section, diff_type, element) theme.dig(section, diff_type, element) || {} end |
#unchanged_content_style ⇒ Hash
Get style for unchanged content
148 149 150 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 148 def unchanged_content_style theme_style(:diff, :unchanged, :content) end |
#visualization_chars ⇒ Hash
Get visualization characters
160 161 162 |
# File 'lib/canon/diff_formatter/by_line/base_formatter.rb', line 160 def visualization_chars theme[:visualization] || {} end |