diff --git a/README.md b/README.md
index 5fca4028..c35ef65c 100644
--- a/README.md
+++ b/README.md
@@ -39,27 +39,27 @@ tools that do one thing well.
## Table of Contents
- * [1 How It Works](#section_1)
- * [2 Installation](#section_2)
- * [2.1 Basic GitHub Checkout](#section_2.1)
- * [2.1.1 Upgrading](#section_2.1.1)
- * [2.2 Homebrew on Mac OS X](#section_2.2)
- * [2.3 Neckbeard Configuration](#section_2.3)
- * [2.4 Uninstalling Ruby Versions](#section_2.4)
- * [3 Usage](#section_3)
- * [3.1 rbenv global](#section_3.1)
- * [3.2 rbenv local](#section_3.2)
- * [3.3 rbenv shell](#section_3.3)
- * [3.4 rbenv versions](#section_3.4)
- * [3.5 rbenv version](#section_3.5)
- * [3.6 rbenv rehash](#section_3.6)
- * [3.7 rbenv which](#section_3.7)
- * [3.8 rbenv whence](#section_3.8)
- * [4 Development](#section_4)
- * [4.1 Version History](#section_4.1)
- * [4.2 License](#section_4.2)
+* [How It Works](#how-it-works)
+* [Installation](#installation)
+ * [Basic GitHub Checkout](#basic-github-checkout)
+ * [Upgrading](#upgrading)
+ * [Homebrew on Mac OS X](#homebrew-on-mac-os-x)
+ * [Neckbeard Configuration](#neckbeard-configuration)
+ * [Uninstalling Ruby Versions](#uninstalling-ruby-versions)
+* [Usage](#usage)
+ * [rbenv global](#rbenv-global)
+ * [rbenv local](#rbenv-local)
+ * [rbenv shell](#rbenv-shell)
+ * [rbenv versions](#rbenv-versions)
+ * [rbenv version](#rbenv-version)
+ * [rbenv rehash](#rbenv-rehash)
+ * [rbenv which](#rbenv-which)
+ * [rbenv whence](#rbenv-whence)
+* [Development](#development)
+ * [Version History](#version-history)
+ * [License](#license)
-## 1 How It Works
+## How It Works ##
rbenv operates on the per-user directory `~/.rbenv`. Version names in
rbenv correspond to subdirectories of `~/.rbenv/versions`. For
@@ -79,14 +79,14 @@ and then execute the corresponding binary.
Because of the simplicity of the shim approach, all you need to use
rbenv is `~/.rbenv/shims` in your `$PATH`.
-## 2 Installation
+## Installation ##
**Compatibility note**: rbenv is _incompatible_ with rvm. Things will
appear to work until you try to install a gem. The problem is that
rvm actually overrides the `gem` command with a shell function!
Please remove any references to rvm before using rbenv.
-### 2.1 Basic GitHub Checkout
+### Basic GitHub Checkout ###
This will get you going with the latest version of rbenv and make it
easy to fork and contribute any changes back upstream.
@@ -140,7 +140,7 @@ easy to fork and contribute any changes back upstream.
$ rbenv rehash
-#### 2.1.1 Upgrading
+#### Upgrading ####
If you've installed rbenv using the instructions above, you can
upgrade your installation at any time using git.
@@ -162,7 +162,7 @@ tag:
v0.2.0
$ git checkout v0.2.0
-### 2.2 Homebrew on Mac OS X
+### Homebrew on Mac OS X ###
You can also install rbenv using the
[Homebrew](http://mxcl.github.com/homebrew/) package manager on Mac OS
@@ -178,7 +178,7 @@ Afterwards you'll still need to add `eval "$(rbenv init -)"` to your
profile as stated in the caveats. You'll only ever have to do this
once.
-### 2.3 Neckbeard Configuration
+### Neckbeard Configuration ###
Skip this section unless you must know what every line in your shell
profile is doing.
@@ -210,7 +210,7 @@ opposed to this idea. Here's what `rbenv init` actually does:
Run `rbenv init -` for yourself to see exactly what happens under the
hood.
-### 2.4 Uninstalling Ruby Versions
+### Uninstalling Ruby Versions ###
As time goes on, ruby versions you install will accumulate in your
`~/.rbenv/versions` directory.
@@ -219,12 +219,12 @@ There is no uninstall or remove command in `rbenv`, so removing old
versions is a simple matter of `rm -rf` the directory of the relevant
ruby version you want removed under `~/.rbenv/versions`
-## 3 Usage
+## Usage ##
Like `git`, the `rbenv` command delegates to subcommands based on its
first argument. The most common subcommands are:
-### 3.1 rbenv global
+### rbenv global ###
Sets the global version of Ruby to be used in all shells by writing
the version name to the `~/.rbenv/version` file. This version can be
@@ -239,7 +239,7 @@ The special version name `system` tells rbenv to use the system Ruby
When run without a version number, `rbenv global` reports the
currently configured global version.
-### 3.2 rbenv local
+### rbenv local ###
Sets a local per-project Ruby version by writing the version name to
an `.rbenv-version` file in the current directory. This version
@@ -254,7 +254,7 @@ configured local version. You can also unset the local version:
$ rbenv local --unset
-### 3.3 rbenv shell
+### rbenv shell ###
Sets a shell-specific Ruby version by setting the `RBENV_VERSION`
environment variable in your shell. This version overrides both
@@ -274,7 +274,7 @@ prefer not to use shell integration, you may simply set the
$ export RBENV_VERSION=jruby-1.7.1
-### 3.4 rbenv versions
+### rbenv versions ###
Lists all Ruby versions known to rbenv, and shows an asterisk next to
the currently active version.
@@ -287,7 +287,7 @@ the currently active version.
rbx-1.2.4
ree-1.8.7-2011.03
-### 3.5 rbenv version
+### rbenv version ###
Displays the currently active Ruby version, along with information on
how it was set.
@@ -295,7 +295,7 @@ how it was set.
$ rbenv version
1.8.7-p352 (set by /Volumes/37signals/basecamp/.rbenv-version)
-### 3.6 rbenv rehash
+### rbenv rehash ###
Installs shims for all Ruby binaries known to rbenv (i.e.,
`~/.rbenv/versions/*/bin/*`). Run this command after you install a new
@@ -303,7 +303,7 @@ version of Ruby, or install a gem that provides binaries.
$ rbenv rehash
-### 3.7 rbenv which
+### rbenv which ###
Displays the full path to the binary that rbenv will execute when you
run the given command.
@@ -311,7 +311,7 @@ run the given command.
$ rbenv which irb
/Users/sam/.rbenv/versions/1.9.3-p327/bin/irb
-### 3.8 rbenv whence
+### rbenv whence ###
Lists all Ruby versions with the given command installed.
@@ -320,7 +320,7 @@ Lists all Ruby versions with the given command installed.
jruby-1.7.1
ree-1.8.7-2011.03
-## 4 Development
+## Development ##
The rbenv source code is [hosted on
GitHub](https://github.com/sstephenson/rbenv). It's clean, modular,
@@ -329,7 +329,7 @@ and easy to understand, even if you're not a shell hacker.
Please feel free to submit pull requests and file bugs on the [issue
tracker](https://github.com/sstephenson/rbenv/issues).
-### 4.1 Version History
+### Version History ###
**0.3.0** (December 25, 2011)
@@ -405,7 +405,7 @@ tracker](https://github.com/sstephenson/rbenv/issues).
* Initial public release.
-### 4.2 License
+### License ###
(The MIT license)
diff --git a/doc/README.mdtoc b/doc/README.mdtoc
deleted file mode 100644
index 12802a67..00000000
--- a/doc/README.mdtoc
+++ /dev/null
@@ -1,411 +0,0 @@
-# Simple Ruby Version Management: rbenv
-
-rbenv lets you easily switch between multiple versions of Ruby. It's
-simple, unobtrusive, and follows the UNIX tradition of single-purpose
-tools that do one thing well.
-
-
-
-### rbenv _does…_
-
-* Let you **change the global Ruby version** on a per-user basis.
-* Provide support for **per-project Ruby versions**.
-* Allow you to **override the Ruby version** with an environment
- variable.
-
-### In contrast with rvm, rbenv _does not…_
-
-* **Need to be loaded into your shell.** Instead, rbenv's shim
- approach works by adding a directory to your `$PATH`.
-* **Override shell commands like `cd`.** That's dangerous and
- error-prone.
-* **Have a configuration file.** There's nothing to configure except
- which version of Ruby you want to use.
-* **Install Ruby.** You can build and install Ruby yourself, or use
- [ruby-build](https://github.com/sstephenson/ruby-build) to
- automate the process.
-* **Manage gemsets.** [Bundler](http://gembundler.com/) is a better
- way to manage application dependencies. If you have projects that
- are not yet using Bundler you can install the
- [rbenv-gemset](https://github.com/jamis/rbenv-gemset) plugin.
-* **Require changes to Ruby libraries for compatibility.** The
- simplicity of rbenv means as long as it's in your `$PATH`,
- [nothing](https://rvm.io/integration/bundler/)
- [else](https://rvm.io/integration/capistrano/)
- needs to know about it.
-* **Prompt you with warnings when you switch to a project.** Instead
- of executing arbitrary code, rbenv reads just the version name
- from each project. There's nothing to "trust."
-
-## Table of Contents
-
-## How It Works ##
-
-rbenv operates on the per-user directory `~/.rbenv`. Version names in
-rbenv correspond to subdirectories of `~/.rbenv/versions`. For
-example, you might have `~/.rbenv/versions/1.8.7-p354` and
-`~/.rbenv/versions/1.9.3-p327`.
-
-Each version is a working tree with its own binaries, like
-`~/.rbenv/versions/1.8.7-p354/bin/ruby` and
-`~/.rbenv/versions/1.9.3-p327/bin/irb`. rbenv makes _shim binaries_
-for every such binary across all installed versions of Ruby.
-
-These shims are simple wrapper scripts that live in `~/.rbenv/shims`
-and detect which Ruby version you want to use. They insert the
-directory for the selected version at the beginning of your `$PATH`
-and then execute the corresponding binary.
-
-Because of the simplicity of the shim approach, all you need to use
-rbenv is `~/.rbenv/shims` in your `$PATH`.
-
-## Installation ##
-
-**Compatibility note**: rbenv is _incompatible_ with rvm. Things will
- appear to work until you try to install a gem. The problem is that
- rvm actually overrides the `gem` command with a shell function!
- Please remove any references to rvm before using rbenv.
-
-### Basic GitHub Checkout ###
-
-This will get you going with the latest version of rbenv and make it
-easy to fork and contribute any changes back upstream.
-
-1. Check out rbenv into `~/.rbenv`.
-
- $ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
-
-2. Add `~/.rbenv/bin` to your `$PATH` for access to the `rbenv`
- command-line utility.
-
- $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
-
- **Zsh note**: Modify your `~/.zshenv` file instead of `~/.bash_profile`.
-
- **Ubuntu note**: Ubuntu uses `~/.profile` for enabling certain path
- changes. This file won't be read if you create a `~/.bash_profile`.
- Therefore, it's recommended that you add this line and the one in
- point 3 below to your `~/.profile`. This has the added advantage
- of working under both bash and zsh.
-
-3. Add rbenv init to your shell to enable shims and autocompletion.
-
- $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
-
- **Zsh note**: Modify your `~/.zshenv` file instead of `~/.bash_profile`.
-
- **Ubuntu note**: Same as Ubuntu note for point 2 above.
-
-4. Restart your shell as a login shell so the path changes take effect.
- You can now begin using rbenv.
-
- $ exec $SHELL -l
-
-5. Install Ruby versions into `~/.rbenv/versions`. For example, to
- install Ruby 1.9.3-p327, download and unpack the source, then run:
-
- $ ./configure --prefix=$HOME/.rbenv/versions/1.9.3-p327
- $ make
- $ make install
-
- The [ruby-build](https://github.com/sstephenson/ruby-build) project
- provides an `rbenv install` command that simplifies the process of
- installing new Ruby versions to:
-
- $ rbenv install 1.9.3-p327
-
-6. Rebuild the shim binaries. You should do this any time you install
- a new Ruby binary (for example, when installing a new Ruby version,
- or when installing a gem that provides a binary).
-
- $ rbenv rehash
-
-#### Upgrading ####
-
-If you've installed rbenv using the instructions above, you can
-upgrade your installation at any time using git.
-
-To upgrade to the latest development version of rbenv, use `git pull`:
-
- $ cd ~/.rbenv
- $ git pull
-
-To upgrade to a specific release of rbenv, check out the corresponding
-tag:
-
- $ cd ~/.rbenv
- $ git fetch
- $ git tag
- v0.1.0
- v0.1.1
- v0.1.2
- v0.2.0
- $ git checkout v0.2.0
-
-### Homebrew on Mac OS X ###
-
-You can also install rbenv using the
-[Homebrew](http://mxcl.github.com/homebrew/) package manager on Mac OS
-X.
-
- $ brew update
- $ brew install rbenv
- $ brew install ruby-build
-
-The same commands can be used for upgrading.
-
-Afterwards you'll still need to add `eval "$(rbenv init -)"` to your
-profile as stated in the caveats. You'll only ever have to do this
-once.
-
-### Neckbeard Configuration ###
-
-Skip this section unless you must know what every line in your shell
-profile is doing.
-
-`rbenv init` is the only command that crosses the line of loading
-extra commands into your shell. Coming from rvm, some of you might be
-opposed to this idea. Here's what `rbenv init` actually does:
-
-1. Sets up your shims path. This is the only requirement for rbenv to
- function properly. You can do this by hand by prepending
- `~/.rbenv/shims` to your `$PATH`.
-
-2. Installs autocompletion. This is entirely optional but pretty
- useful. Sourcing `~/.rbenv/completions/rbenv.bash` will set that
- up. There is also a `~/.rbenv/completions/rbenv.zsh` for Zsh
- users.
-
-3. Rehashes shims. From time to time you'll need to rebuild your
- shim files. Doing this on init makes sure everything is up to
- date. You can always run `rbenv rehash` manually.
-
-4. Installs the sh dispatcher. This bit is also optional, but allows
- rbenv and plugins to change variables in your current shell, making
- commands like `rbenv shell` possible. The sh dispatcher doesn't do
- anything crazy like override `cd` or hack your shell prompt, but if
- for some reason you need `rbenv` to be a real script rather than a
- shell function, you can safely skip it.
-
-Run `rbenv init -` for yourself to see exactly what happens under the
-hood.
-
-### Uninstalling Ruby Versions ###
-
-As time goes on, ruby versions you install will accumulate in your
-`~/.rbenv/versions` directory.
-
-There is no uninstall or remove command in `rbenv`, so removing old
-versions is a simple matter of `rm -rf` the directory of the relevant
-ruby version you want removed under `~/.rbenv/versions`
-
-## Usage ##
-
-Like `git`, the `rbenv` command delegates to subcommands based on its
-first argument. The most common subcommands are:
-
-### rbenv global ###
-
-Sets the global version of Ruby to be used in all shells by writing
-the version name to the `~/.rbenv/version` file. This version can be
-overridden by a per-project `.rbenv-version` file, or by setting the
-`RBENV_VERSION` environment variable.
-
- $ rbenv global 1.9.3-p327
-
-The special version name `system` tells rbenv to use the system Ruby
-(detected by searching your `$PATH`).
-
-When run without a version number, `rbenv global` reports the
-currently configured global version.
-
-### rbenv local ###
-
-Sets a local per-project Ruby version by writing the version name to
-an `.rbenv-version` file in the current directory. This version
-overrides the global, and can be overridden itself by setting the
-`RBENV_VERSION` environment variable or with the `rbenv shell`
-command.
-
- $ rbenv local rbx-1.2.4
-
-When run without a version number, `rbenv local` reports the currently
-configured local version. You can also unset the local version:
-
- $ rbenv local --unset
-
-### rbenv shell ###
-
-Sets a shell-specific Ruby version by setting the `RBENV_VERSION`
-environment variable in your shell. This version overrides both
-project-specific versions and the global version.
-
- $ rbenv shell jruby-1.7.1
-
-When run without a version number, `rbenv shell` reports the current
-value of `RBENV_VERSION`. You can also unset the shell version:
-
- $ rbenv shell --unset
-
-Note that you'll need rbenv's shell integration enabled (step 3 of
-the installation instructions) in order to use this command. If you
-prefer not to use shell integration, you may simply set the
-`RBENV_VERSION` variable yourself:
-
- $ export RBENV_VERSION=jruby-1.7.1
-
-### rbenv versions ###
-
-Lists all Ruby versions known to rbenv, and shows an asterisk next to
-the currently active version.
-
- $ rbenv versions
- 1.8.7-p352
- 1.9.2-p290
- * 1.9.3-p327 (set by /Users/sam/.rbenv/global)
- jruby-1.7.1
- rbx-1.2.4
- ree-1.8.7-2011.03
-
-### rbenv version ###
-
-Displays the currently active Ruby version, along with information on
-how it was set.
-
- $ rbenv version
- 1.8.7-p352 (set by /Volumes/37signals/basecamp/.rbenv-version)
-
-### rbenv rehash ###
-
-Installs shims for all Ruby binaries known to rbenv (i.e.,
-`~/.rbenv/versions/*/bin/*`). Run this command after you install a new
-version of Ruby, or install a gem that provides binaries.
-
- $ rbenv rehash
-
-### rbenv which ###
-
-Displays the full path to the binary that rbenv will execute when you
-run the given command.
-
- $ rbenv which irb
- /Users/sam/.rbenv/versions/1.9.3-p327/bin/irb
-
-### rbenv whence ###
-
-Lists all Ruby versions with the given command installed.
-
- $ rbenv whence rackup
- 1.9.3-p327
- jruby-1.7.1
- ree-1.8.7-2011.03
-
-## Development ##
-
-The rbenv source code is [hosted on
-GitHub](https://github.com/sstephenson/rbenv). It's clean, modular,
-and easy to understand, even if you're not a shell hacker.
-
-Please feel free to submit pull requests and file bugs on the [issue
-tracker](https://github.com/sstephenson/rbenv/issues).
-
-### Version History ###
-
-**0.3.0** (December 25, 2011)
-
-* Added an `rbenv root` command which prints the value of
- `$RBENV_ROOT`, or the default root directory if it's unset.
-* Clarified Zsh installation instructions in the readme.
-* Removed some redundant code in `rbenv rehash`.
-* Fixed an issue with calling `readlink` for paths with spaces.
-* Changed Zsh initialization code to install completion hooks only for
- interactive shells.
-* Added preliminary support for ksh.
-* `rbenv rehash` creates or removes shims only when necessary instead
- of removing and re-creating all shims on each invocation.
-* Fixed that `RBENV_DIR`, when specified, would be incorrectly
- expanded to its parent directory.
-* Removed the deprecated `set-default` and `set-local` commands.
-* Added a `--no-rehash` option to `rbenv init` for skipping the
- automatic rehash when opening a new shell.
-
-**0.2.1** (October 1, 2011)
-
-* Changed the `rbenv` command to ensure that `RBENV_DIR` is always an
- absolute path. This fixes an issue where Ruby scripts using the
- `ruby-local-exec` wrapper would go into an infinite loop when
- invoked with a relative path from the command line.
-
-**0.2.0** (September 28, 2011)
-
-* Renamed `rbenv set-default` to `rbenv global` and `rbenv set-local`
- to `rbenv local`. The `set-` commands are deprecated and will be
- removed in the next major release.
-* rbenv now uses `greadlink` on Solaris.
-* Added a `ruby-local-exec` command which can be used in shebangs in
- place of `#!/usr/bin/env ruby` to properly set the project-specific
- Ruby version regardless of current working directory.
-* Fixed an issue with `rbenv rehash` when no binaries are present.
-* Added support for `rbenv-sh-*` commands, which run inside the
- current shell instead of in a child process.
-* Added an `rbenv shell` command for conveniently setting the
- `$RBENV_VERSION` environment variable.
-* Added support for storing rbenv versions and shims in directories
- other than `~/.rbenv` with the `$RBENV_ROOT` environment variable.
-* Added support for debugging rbenv via `set -x` when the
- `$RBENV_DEBUG` environment variable is set.
-* Refactored the autocompletion system so that completions are now
- built-in to each command and shared between bash and Zsh.
-* Added support for plugin bundles in `~/.rbenv/plugins` as documented
- in [issue #102](https://github.com/sstephenson/rbenv/pull/102).
-* Added `/usr/local/etc/rbenv.d` to the list of directories searched
- for rbenv hooks.
-* Added support for an `$RBENV_DIR` environment variable which
- defaults to the current working directory for specifying where rbenv
- searches for local version files.
-
-**0.1.2** (August 16, 2011)
-
-* Fixed rbenv to be more resilient against nonexistent entries in
- `$PATH`.
-* Made the `rbenv rehash` command operate atomically.
-* Modified the `rbenv init` script to automatically run `rbenv
- rehash` so that shims are recreated whenever a new shell is opened.
-* Added initial support for Zsh autocompletion.
-* Removed the dependency on egrep for reading version files.
-
-**0.1.1** (August 14, 2011)
-
-* Fixed a syntax error in the `rbenv help` command.
-* Removed `-e` from the shebang in favor of `set -e` at the top of
- each file for compatibility with operating systems that do not
- support more than one argument in the shebang.
-
-**0.1.0** (August 11, 2011)
-
-* Initial public release.
-
-### License ###
-
-(The MIT license)
-
-Copyright (c) 2011 Sam Stephenson
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/doc/build b/doc/build
deleted file mode 100755
index 3d542d44..00000000
--- a/doc/build
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh -e
-
-ruby mdtoc.rb README.mdtoc > ../README.md
-
diff --git a/doc/filter-toc b/doc/filter-toc
new file mode 100755
index 00000000..761288be
--- /dev/null
+++ b/doc/filter-toc
@@ -0,0 +1,4 @@
+#!/bin/bash
+# Render Markdown ToC with only headings appearing after "Table of Contents"
+dir="$(dirname "$0")"
+"$dir"/mdtoc "$1" | sed -n '/table-of-contents/,$p' | grep -v table-of-contents
diff --git a/doc/mdtoc b/doc/mdtoc
new file mode 100755
index 00000000..5d635542
--- /dev/null
+++ b/doc/mdtoc
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+require 'escape_utils'
+
+start_at_level = 2
+
+headers = Hash.new(0)
+
+anchor = lambda { |title|
+ href = title.downcase
+ href.gsub!(/[^\w\- ]/, '') # remove punctuation
+ href.gsub!(' ', '-') # replace spaces with dash
+ href = EscapeUtils.escape_uri(href) # escape extended UTF-8 chars
+
+ uniq = (headers[href] > 0) ? "-#{headers[href]}" : ''
+ headers[href] += 1
+
+ href + uniq
+}
+
+ARGF.each_line do |line|
+ if line =~ /^(#+) (.+?)#*$/
+ level = $1.size
+ next if level < start_at_level
+ title = $2.strip
+ href = anchor.call title
+
+ puts "%s* [%s](#%s)" % [
+ ' ' * (level - start_at_level),
+ title,
+ href
+ ]
+ end
+end
diff --git a/doc/mdtoc.rb b/doc/mdtoc.rb
deleted file mode 100644
index 3c5a1735..00000000
--- a/doc/mdtoc.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env ruby
-
-# A little Markdown filter that scans your document for headings,
-# numbers them, adds anchors, and inserts a table of contents.
-#
-# To use it, make sure the headings you want numbered and linked are
-# in this format:
-#
-# ### Title ###
-#
-# I.e. they must have an equal number of octothorpes around the title
-# text. (In Markdown, `#` means `h1`, `##` means `h2`, and so on.)
-# The table of contents will be inserted before the first such
-# heading.
-#
-# Released into the public domain.
-# Sam Stephenson
-# 2011-04-30
-
-def mdtoc(markdown)
- titles = []
- lines = markdown.split($/)
- start = nil
-
- # First pass: Scan the Markdown source looking for titles of the
- # format: `### Title ###`. Record the line number, header level
- # (number of octothorpes), and text of each matching title.
- lines.each_with_index do |line, line_no|
- if line.match(/^(\#{1,6})\s+(.+?)\s+\1$/)
- titles << [line_no, $1.length, $2]
- start ||= line_no
- end
- end
-
- last_section = nil
- last_level = nil
-
- # Second pass: Iterate over all matched titles and compute their
- # corresponding section numbers. Then replace the titles with
- # annotated anchors.
- titles.each do |title_info|
- line_no, level, text = title_info
-
- if last_section
- section = last_section.dup
-
- if last_level < level
- section << 1
- else
- (last_level - level).times { section.pop }
- section[-1] += 1
- end
- else
- section = [1]
- end
-
- name = section.join(".")
- lines[line_no] = %(#{"#" * level} #{name} #{text})
-
- title_info << section
- last_section = section
- last_level = level
- end
-
- # Third pass: Iterate over matched titles once more to produce the
- # table of contents. Then insert it immediately above the first
- # matched title.
- if start
- toc = titles.map do |(line_no, level, text, section)|
- name = section.join(".")
- %(#{" " * (section.length * 3)}* [#{name} #{text}](#section_#{name}))
- end + [""]
-
- lines.insert(start, *toc)
- end
-
- lines.join("\n")
-end
-
-if __FILE__ == $0
- puts mdtoc($<.read)
-end