Skip to main content
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.
Tweeted twitter.com/StackCodeReview/status/1184257768636723200
edited tags
Link
200_success
  • 145.7k
  • 22
  • 191
  • 481

Script to auto-generate Markdown tables of contentcontents

edited tags
Link
dfhwze
  • 14.2k
  • 3
  • 40
  • 101
Source Link

Script to auto-generate Markdown tables of content

I would greatly appreciate feedback on the enclosed script, which auto-generates a Markdown table of contents for Github-flavoured Markdown, with respect to:

  • Consistency with Ruby idiom & style
  • Any use of bad practices
#!/usr/bin/env ruby

def usage
  puts "Usage: #{$0} FILE.md"
  exit 1
end

class ToCWriter
  def initialize(source_file, top=2, max=4)
    @source_file = source_file
    @top = top
    @max = max
    @c = 1
    @level  = ""
    @header = ""
    @start  = ""
    write
  end

  def write
    puts "#### Table of contents\n\n"

    File.open(@source_file).each_line do |line|
      next unless line.match(/^#/)

      @level, @header = line.match(/^(#+) (.*)/).captures
      next if @header == "Table of contents"
      next if skip?

      ref = header_to_ref
      set_start

      puts "#{@start} [#{@header}](##{ref})"
    end
  end

 private

  def skip?
    len = @level.length
    len < @top || len > @max
  end

  def header_to_ref
    @header
      .gsub(/ /, "-")
      .gsub(/[\.\/,&\()<>-]+/, "-")
      .gsub(/-$/, "")
      .downcase
  end

  def set_start
    len = @level.length
    if len == @top
      @start = "#{@c}."
      @c += 1
    else
      bullet = len % 2 == 0 ? "*" : "-"
      @start = "    " * (len - 2) + bullet
    end
  end
end

usage unless ARGV.length == 1
source_file = ARGV[0]

ToCWriter.new(source_file)