markdown headers should have anchors #6

technoweenie opened this Issue May 9, 2010 · 52 comments


None yet

technoweenie commented May 9, 2010

Anchors are great for usability in long documentation.

# Install
blah blah

<h1 name="INSTALL">Install</h1>
<p>blah blah</p>

Should be:

<h1 id="INSTALL">Install</h1>
<p>blah blah</p>

Name isn't a valid xhtml attribute for headers.


technoweenie commented May 9, 2010

ah, i'm old school :)


The MultiMarkdown renderer included in TextMate does this already.

Blech it's in Perl, but it's a pretty good implementation if you're looking for an example.


dabrahams commented May 19, 2010



defunkt commented Jul 7, 2010

If someone has a patch that works with RDiscount that would be best.

kneath commented Jul 25, 2010

Note that we can't support the id="blah" method due to expected suicide rate increases resulting from CSS specificity hell. If someone has a parser that outputs something like:

<a name="install" />

I'd be all on board.


dabrahams commented Jul 26, 2010

If I had ever coded a single line of Ruby I'm sure I could send you a correct patch with no testing and one hand tied behind my back. 'Till then, please consider this a feature request, guys :-). I don't have a patch.

I've noticed this problem with README.rst files as well. As well as headings, inline targets in .rst files, e.g. _some target, don't work. The inline target text gets wrapped in a <span> but doesn't get made into any sort of link target. Should I file this as a separate issue?

Another implementation of such a thing:

How about post-processing the html? Too slow?

getify commented Jan 24, 2011

+1 for this.

FYI, in IE

<a ... />

is invalid and won't work. You have to do:

<a ...></a>


tmm1 commented Jan 24, 2011

RDiscount already has support for TOCs:

> md ="# Install", :generate_toc)
 => #<RDiscount:0x101849728 @generate_toc=true, @text="# Install"> 

> md.to_html
 => "<h1 id=\"Install\">Install</h1>\n" 

> md.toc_content
 => "\n <ul>\n <li><a href=\"#Install\">Install</a> </li>\n </ul>\n\n" 

This should be easy to patch to generate <a> tags instead of using <h1 id=...>

tmm1 commented Jan 24, 2011

This patch to RDiscount:

diff --git a/ext/generate.c b/ext/generate.c
index 6840bdf..eb9a2ee 100644
--- a/ext/generate.c
+++ b/ext/generate.c
@@ -1215,12 +1215,12 @@ text(MMIOT *f)
 static void
 printheader(Paragraph *pp, MMIOT *f)
-    Qprintf(f, "<h%d", pp->hnumber);
     if ( f->flags & TOC ) {
-       Qprintf(f, " id=\"", pp->hnumber);
+       Qprintf(f, "<a name=\"", pp->hnumber);
        mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), Qchar, f);
-       Qchar('"', f);
+       Qprintf(f, "\"></a>\n");
+    Qprintf(f, "<h%d", pp->hnumber);
     Qchar('>', f);
     push(T(pp->text->text), S(pp->text->text), f);

lets it use <a> instead:

> md ="# Install", :generate_toc)
 => #<RDiscount:0x10036a690 @text="# Install", @generate_toc=true> 

> md.to_html
 => "<a name=\"Install\"></a>\n<h1>Install</h1>\n" 

Ideally, though, the patch would instead be applied upstream to Discount and then pulled into RDiscount via the rake gather task. Otherwise these changes will just get blown away next time RDiscount updates its Discount dependency.


rtomayko commented Jan 25, 2011

Applied to rdiscount master:


This has also been applied upstream:


I need to do some testing on linux at least before putting out the first rdiscount 2.x release.

benatkin commented May 6, 2011

Back to square one ;)

It was worth it, though - syntax highlighting FTW!

So can we use anchors or TOC's in files now?

@ge0ffrey Not yet. Here's the code for a header in of this repo:

<p>We use this library on GitHub when rendering your README or any other
rich text file.</p> 


<p>The following markups are supported.  The dependencies listed are required if
you wish to run the library.</p> 

Nice and simple...doesn't support links, though.

+1 to getting anchor links. Our file is getting to big for people to read without a TOC with links to anchors.

+5! come on, this is basic. you've got a nice wiki, you've got a nice tracker, you got nice version control... the versionc control is talking to the tickets, now the tickets need to tie to the wiki. everyone can see where the spec became a ticket became code became.... ah, needs automated test scripts. well, baby steps!

benatkin commented Jul 4, 2011

I'm right there with you, @FairchildHeavyIndustries. It would help with integration immensely. Half the time when I link to Wikipedia I link to subheadings.

Actually that's probably a part of it - it wouldn't be useful to very many without a way to get an anchor tag besides firing up a web inspector. I'm not too crazy about TOCs for short single web pages. It could also be a problem for pages where there are a ton of headers. I'm partial to the links that show up when you hover over paragraphs in Docco. Maybe something like that just for headers on github READMEs and wikis would be useful and not too obtrusive. Another idea is a button to show a TOC.

nazgob commented Jul 26, 2011


tpope commented Sep 18, 2011

I don't understand the status of the RDiscount solution, but it took like 5 minutes and 3 lines of code to bolt in on after the fact:

diff --git a/lib/github/markups.rb b/lib/github/markups.rb
index 739b61a..90eb17a 100644
--- a/lib/github/markups.rb
+++ b/lib/github/markups.rb
@@ -1,5 +1,8 @@
 markup(:markdown, /md|mkdn?|mdown|markdown/) do |content|
+<h([1-6])>(.*?)<\/h\1>/) do |original|
+    anchor = $2.gsub(/<.*?>/, '').gsub(/[^[:alnum:]]+/, '-').downcase
+    %(<a name="#{anchor}"></a>\n#{original})
+  end

 markup(:redcloth, /textile/) do |content|
diff --git a/test/markups/README.markdown b/test/markups/README.markdown
index b36565c..90a9b1b 100644
--- a/test/markups/README.markdown
+++ b/test/markups/README.markdown
@@ -1,2 +1,3 @@
+# Zero
 * One
 * Two
diff --git a/test/markups/README.markdown.html b/test/markups/
index a1b9aba..8123213 100644
--- a/test/markups/README.markdown.html
+++ b/test/markups/README.markdown.html
@@ -1,3 +1,6 @@
+<a name="zero"></a>

ojak commented Oct 19, 2011

+1 Shouldn't be too tough to give all markdown file anchors a namespace on display?

rmzelle commented Oct 27, 2011


cbeams commented Jan 24, 2012


Oh yeah, it would be awesome!

+1, seriously

+1, hard.

I'm a tech writer, and this would make documentation on Github significantly easier to navigate for my readers.

+1 I'm on!

@technoweenie @rtomayko Do you want a patch similar to what tpope had? I would like to get support for this feature as well.

What about repeated headers? Like, for instance, two h1s for API calls containing h2s that say "Request" and "Response".


dabrahams commented Mar 18, 2012

on Sat Mar 17 2012, Benjamin Atkin <> wrote:

What about repeated headers? Like, for instance, two h1s for API calls containing h2s that say "Request" and "Response".

Add a number at the end


Anchors for markdown files are incredibly important for usability, otherwise you get pages that are far too long and difficult to navigate.

Dru89 commented Apr 13, 2012

What about repeated headers? Like, for instance, two h1s for API calls containing h2s that say "Request" and "Response".

Add a number at the end

Or you could just as easily not care about what the actual id tag is, as long as you're keeping references to it. For instance, <h2>Response</h2> may just become some hash like <h2 id='a4f432e-38er-2838-187'>Response</h2> as long as it works and keeps the same reference.

@Dru89, the obvious difficulty with that is providing links to specific sub-sections. Even if the contents of the ID are deterministic, renaming a header could potentially change the ID and thus break all references to it.

Of course this issue exists with placing an incremental number at the end of the header string, but I think your proposal has a much higher chance of breaking stuff.

ivank commented Apr 24, 2012

+1 !!!

Common guys - you could just make a toc or a headers outline like the they have in Rails Guides - generated automatically or something.


rtomayko commented Apr 24, 2012

This is fixed and in production on

There will be no TOC without it being opt in. We're not sure how best to do that yet. First step will likely be to have a hashmark appear when hovering over a header. We're experimenting.

rtomayko closed this Apr 24, 2012



dabrahams commented Apr 25, 2012

Nicely done! I thought id="..." attributes were the modern way of doing this stuff, but whatever, as long as it works.

ivank commented May 11, 2012

Do you have any idea where is the switch to activate the TOC? is it some kind of custom GFM code or an option in the admin? I would really love this feature

If you could extend this to the github wiki's too, that would be great. for any reason you'd want to link directly to a header in a readme, it's even more so in a wiki.

@ivank I think you're on the wrong issue thread 😄

I agree with @jrochkind
This should also be availabile in the wiki's

current workaround is to manually put
<a name='A'/> before/after a header
and llink to it with

dmtrs commented Feb 19, 2013

+1 +1 +1

@jrochkind 👍

Whatever happened to common sense here?

tobeportable referenced this issue in cjohansen/makeup Mar 5, 2013


toc #2

I have noticed that this is now also available on the wiki's?

Is this available as an option when using GitHub::Markup.render(source, ?


gjtorikian commented Feb 5, 2015

Hey @sanderson-sfdc! In the time between this issue and now, we moved our Markdown rendering over to use html-pipeline for "extended" Markdown behaviors. By extended I mean stuff like linkifying the headers (like here), syntax highlighting code examples, coverting emoji, etc. Basically anything beyond the usual "bold/italic" stuff you get our of regular Markdown.

html-pipeline is a series of filters that passes content from one filter to another, and the MarkdownFilter natively uses this gem to rendering markdown. The smallest filter sequence to turn markdown into HTML, and linkify headers, would be:

require 'html/pipeline'

pipeline = [
result =

Heya Garen! Thanks for the tip, that's exactly what I did and it works great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment