Class: Ace::Lint::Molecules::KramdownFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/lint/molecules/kramdown_formatter.rb

Overview

Formats markdown with kramdown

Class Method Summary collapse

Class Method Details

.detect_structural_changes(original, formatted) ⇒ Object



80
81
82
83
84
85
86
87
# File 'lib/ace/lint/molecules/kramdown_formatter.rb', line 80

def self.detect_structural_changes(original, formatted)
  changes = []
  changes << "frontmatter" if frontmatter_changed?(original, formatted)
  changes << "code blocks" if fence_count_changed?(original, formatted)
  changes << "tables" if table_row_count_changed?(original, formatted)
  changes << "html attributes" if html_attributes_changed?(original, formatted)
  changes
end

.format_content(content, options: {}) ⇒ Hash

Format markdown content

Parameters:

  • content (String)

    Markdown content

  • options (Hash) (defaults to: {})

    Kramdown options

Returns:

  • (Hash)

    Result with :success, :formatted_content, :errors



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ace/lint/molecules/kramdown_formatter.rb', line 50

def self.format_content(content, options: {})
  # Load kramdown configuration from ace-core config cascade
  # Config location: .ace/lint/kramdown.yml
  kramdown_config = Ace::Lint.kramdown_config

  # Convert string keys to symbols (kramdown expects symbols)
  kramdown_opts = kramdown_config.transform_keys(&:to_sym)

  # Merge: config file < formatting defaults < CLI options
  default_options = {
    line_width: kramdown_opts[:line_width] || 120,
    remove_block_html_tags: false,
    remove_span_html_tags: false
  }

  merged_options = kramdown_opts.merge(default_options).merge(options)
  Atoms::KramdownParser.format(content, options: merged_options)
end

.format_file(file_path, options: {}, guardrails: false) ⇒ Hash

Format markdown file in place

Parameters:

  • file_path (String)

    Path to markdown file

  • options (Hash) (defaults to: {})

    Kramdown options

  • guardrails (Boolean) (defaults to: false)

    Enable structural safety checks before write

Returns:

  • (Hash)

    Result with :success, :formatted, :errors, :warnings



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ace/lint/molecules/kramdown_formatter.rb', line 17

def self.format_file(file_path, options: {}, guardrails: false)
  content = File.read(file_path)
  result = format_content(content, options: options)

  return {success: false, formatted: false, errors: result[:errors], warnings: []} unless result[:success]

  formatted_content = result[:formatted_content]
  return {success: true, formatted: false, errors: [], warnings: []} if formatted_content == content

  if guardrails
    structural_changes = detect_structural_changes(content, formatted_content)
    if structural_changes.any?
      return {
        success: true,
        formatted: false,
        errors: [],
        warnings: ["Skipped formatting due to structural change risk: #{structural_changes.join(", ")}"]
      }
    end
  end

  File.write(file_path, formatted_content)
  {success: true, formatted: true, errors: [], warnings: []}
rescue Errno::ENOENT
  {success: false, formatted: false, errors: ["File not found: #{file_path}"], warnings: []}
rescue => e
  {success: false, formatted: false, errors: ["Error formatting file: #{e.message}"], warnings: []}
end

.needs_formatting?(content, options: {}) ⇒ Boolean

Check if content would change after formatting

Parameters:

  • content (String)

    Markdown content

  • options (Hash) (defaults to: {})

    Kramdown options

Returns:

  • (Boolean)

    True if formatting would change content



73
74
75
76
77
78
# File 'lib/ace/lint/molecules/kramdown_formatter.rb', line 73

def self.needs_formatting?(content, options: {})
  result = format_content(content, options: options)
  return false unless result[:success]

  result[:formatted_content] != content
end