Class: Markdown::Merge::Cleanse::BlockSpacing

Inherits:
Object
  • Object
show all
Defined in:
lib/markdown/merge/cleanse/block_spacing.rb

Overview

Fixes missing blank lines between block elements in Markdown.

Markdown best practices require blank lines between:

  • List items and headings

  • Thematic breaks (—) and following content

  • HTML blocks (like </details>) and following markdown

  • Nested list items and headings

This class detects and fixes these issues without using a full markdown parser, making it safe to use on documents that might have syntax issues.

Examples:

Basic usage

fixer = Markdown::Merge::Cleanse::BlockSpacing.new(content)
if fixer.malformed?
  fixed_content = fixer.fix
end

Check specific issues

fixer = Markdown::Merge::Cleanse::BlockSpacing.new(content)
fixer.issues.each do |issue|
  puts "Line #{issue[:line]}: #{issue[:type]}"
end

Constant Summary collapse

THEMATIC_BREAK =

Patterns for block elements that should have blank lines after them

/\A\s*(?:---+|\*\*\*+|___+)\s*\z/
HEADING =
/\A\s*\#{1,6}\s+/
LIST_ITEM =
/\A\s*(?:[-*+]|\d+\.)\s+/
HTML_CLOSE_TAG =
/\A\s*<\/[a-zA-Z][a-zA-Z0-9]*>\s*\z/
HTML_OPEN_TAG =
/\A\s*<[a-zA-Z][a-zA-Z0-9]*(?:\s|>)/
HTML_ANY_TAG =
/\A\s*<\/?[a-zA-Z]/
/\A\s*\[[^\]]+\]:\s*/
HTML_BLOCK_ELEMENTS =

Block-level HTML elements that can span multiple lines These create a context where we shouldn’t insert blank lines

%w[
  ul
  ol
  li
  dl
  dt
  dd
  div
  table
  thead
  tbody
  tfoot
  tr
  th
  td
  blockquote
  pre
  figure
  figcaption
  details
  summary
  section
  article
  aside
  nav
  header
  footer
  main
  address
  form
  fieldset
].freeze
HTML_BLOCK_OPEN =

Pattern to match opening block-level HTML tags

/\A\s*<(#{HTML_BLOCK_ELEMENTS.join("|")})(?:\s|>)/i
HTML_BLOCK_CLOSE =

Pattern to match closing block-level HTML tags

/\A\s*<\/(#{HTML_BLOCK_ELEMENTS.join("|")})>/i
MARKDOWN_CONTAINER_ELEMENTS =

HTML elements that contain markdown content (not HTML content) These should have blank lines before their closing tags

%w[details].freeze
MARKDOWN_CONTAINER_CLOSE =

Pattern to match closing tags for markdown containers

/\A\s*<\/(#{MARKDOWN_CONTAINER_ELEMENTS.join("|")})>/i
MARKDOWN_CONTENT =

Markdown content: anything that’s not blank, not HTML, and not a link ref def

->(line) {
  stripped = line.strip
  return false if stripped.empty?
  return false if stripped.start_with?("<")
  return false if line.match?(LINK_REF_DEF)
  true
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ BlockSpacing

Initialize a new BlockSpacing fixer.

Parameters:

  • source (String)

    The markdown content to analyze



108
109
110
111
112
# File 'lib/markdown/merge/cleanse/block_spacing.rb', line 108

def initialize(source)
  @source = source
  @issues = []
  analyze
end

Instance Attribute Details

#issuesArray<Hash> (readonly)

Returns Issues found.

Returns:

  • (Array<Hash>)

    Issues found



103
104
105
# File 'lib/markdown/merge/cleanse/block_spacing.rb', line 103

def issues
  @issues
end

#sourceString (readonly)

Returns The original content.

Returns:

  • (String)

    The original content



100
101
102
# File 'lib/markdown/merge/cleanse/block_spacing.rb', line 100

def source
  @source
end

Instance Method Details

#fixString

Fix the block spacing issues.

Returns:

  • (String)

    Content with blank lines added where needed



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/markdown/merge/cleanse/block_spacing.rb', line 131

def fix
  return source unless malformed?

  lines = source.lines
  result = []
  insertions = @issues.map { |i| i[:line] }.to_set

  lines.each_with_index do |line, idx|
    result << line
    # If this line needs a blank line after it, add one
    if insertions.include?(idx + 1) # issues use 1-based line numbers
      result << "\n" unless line.strip.empty?
    end
  end

  result.join
end

#issue_countInteger

Get the count of issues found.

Returns:

  • (Integer)

    number of issues



124
125
126
# File 'lib/markdown/merge/cleanse/block_spacing.rb', line 124

def issue_count
  @issues.size
end

#malformed?Boolean

Check if the content has block spacing issues.

Returns:

  • (Boolean)

    true if issues were found



117
118
119
# File 'lib/markdown/merge/cleanse/block_spacing.rb', line 117

def malformed?
  @issues.any?
end