typestar

Markdown TOC in Ruby

A complete script: parse headings and emit a nested contents list.

#!/usr/bin/env ruby
# Build a nested table of contents from markdown headings.

DOC = <<~MARKDOWN
  # Getting started
  ## Install
  ## First run
  # Concepts
  ## Tours and sets
  ### Stars
  # FAQ
MARKDOWN

entries = DOC.lines.filter_map do |line|
  next unless line =~ /\A(#+)\s+(.+)/
  depth = Regexp.last_match(1).length
  title = Regexp.last_match(2).strip
  slug = title.downcase.gsub(/[^a-z0-9]+/, "-")
  [depth, title, slug]
end

entries.each do |depth, title, slug|
  puts "#{"  " * (depth - 1)}- [#{title}](##{slug})"
end

puts "#{entries.length} headings"

How it works

  1. filter_map keeps only lines the heading regexp matches.
  2. Regexp.last_match pulls out the depth and the title.
  3. gsub slugifies titles; indentation comes from heading depth.

Keywords and builtins used here

The run, in numbers

Lines
26
Characters to type
541
Tokens
125
Three-star pace
75 tpm

At the three-star pace of 75 tokens a minute, this run takes about 100 seconds.

Type this snippet

Step 2 of 2 in Encore, step 29 of 29 in Language basics.

← Previous