This is part of the "Markdown mode" series:
Part 3.5 - Posted on the VS Gallery Part 3 - A live tool window previewer Part 2 - Writing a classifier Part 1 - Markdown!
A few nights ago, around midnight, I was in that I'm-pretty-tired-but-too-tired-to-fall-asleep-now state, and so decided to find something small that I could add to one of my extensions. Since Markdown Mode is the ripest for this type of thing, I decided to add outlining (a.k.a. folding) support for Markdown files:
Outlining regions tend to follow some type of structural decomposition of a file; in C#/VB/C++/etc., you get outlining regions for structural units like namespaces, structs/classes, methods/functions, and (sometimes) blocks. In Markdown, while there isn't an exact equivalent of these groupings, you can use the headers in a Markdown file to roughly break the file into sections.
The logic for this is fairly simple:
H1
H3
H2
H6
This code lives in MarkdownParser.ParseMarkdownSections, which is in MarkdownParser.cs. It returns an enumeration of these sections from first/largest to last/smallest.
MarkdownParser.ParseMarkdownSections
Once the decomposition logic exists, the outlining code is simple. Like many of the other features we've dealt with, this also uses tagging, exporting an ITagger<IOutliningRegionTag>. There's also a bit of logic for computing the collapsed form (what shows up in the editor when you collapse the region) and the collapsed hint form (what you see in a tooltip when hovering over the collapsed form). Still, the total size of OutliningTagger.cs is just under 100 lines, since the hard part is computing the sections.
ITagger<IOutliningRegionTag>
Since we already have the structure, it's nice to be able to see the structure and quickly navigate to different sections. In regular ol' code files, we get this in the navigation bar at the top of the file. Since I only need one navigation bar (there isn't a module/method split for Markdown files) and I don't want to waste vertical space, I just stuck a simple combo box onto the existing margin. It's exactly exactly pretty, but it gets the job done. I suppose there's an interesting conversation to be had here, in how much time/effort I should spend to make this visually congruous with the navigation bar; for my lack of talent in this area, it would probably take me longer to figure that out than it did to write this whole feature (which was about 45 minutes), so it isn't high on my list.
Since outlining wasn't exactly on the list of features, I haven't exactly knocked anything off the TODO block. From this point on, however, I think I'm just going to add new features as I find them useful, so I've gotten rid of the "TODO" list and kept only list of things I've finished. I've also dropped the "no longer doing" portion of the list.
ContentType