Creation of a markdown TOC: need to calculate the number of headers, each consisting of from one to six # followed by a blank space


My markdown files have 6 levels of headers. I am creating a macro which would generate a table of contents.

My only remaining problem is to count the total number of headers in the document.

There are 6 levels of headers

I only need the total number of headers, not the number at each level / of each type.

Please note that each header consists of from one to six # followed by a blank space.

thanks in advance for your time and help

This is the kind of thing which I personally tend to do with an Execute JavaScript action

Count of MD headings in text.kmmacros (20.8 KB)

JS Source
(() => {
    'use strict';

    // Rob Trew @ 2020 
    // Ver 0.2
    // (Generalized for a greater variety of line endings)

    const main = () => {
        const varName = 'markdownText';
        return lines(
            Application('Keyboard Maestro Engine')
        ).reduce(stringTallied, 0);

    // stringTallied :: (Int, String) -> Int
    const stringTallied = (total, s) =>
        s.startsWith('#') ? (
            1 + total
        ) : total;

    // --------------------- GENERIC ---------------------

    // lines :: String -> [String]
    const lines = s =>
        // A list of strings derived from 
        // a single string delimited by CR and/or LF
        0 < s.length ? (
        ) : [];

    return main()
1 Like

thanks very much for your post

1- your macro result is 7 for the text below and there are 12 headers

2- is it possible to put the result in a variable that I could recuperate in KBM for the rest of the macro (or simply the clipboard) ?

thanks again

Table of Contents @insertTOC



* (2) writing documents in Bear, how I go from outline to hierarchy of headers : bearapp


title 1

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

sub title 1

Erat imperdiet sed euismod nisi porta lorem mollis aliquam. Eget arcu dictum varius duis at. Tristique senectus et netus et malesuada fames. Sit amet consectetur adipiscing elit duis tristique sollicitudin. Sociis natoque penatibus et magnis

sub sub title 1

Vestibulum lorem sed risus ultricies tristique nulla aliquet enim. Risus sed vulputate odio ut enim blandit volutpat.

title 2

Amet massa vitae tortor condimentum lacinia quis. Risus in hendrerit gravida rutrum.

sub title 2

Augue mauris augue neque gravida in. Feugiat sed lectus vestibulum mattis ullamcorper velit. Condimentum vitae sapien pellentesque habitant.

sub sub title 2

Nisi porta lorem mollis aliquam ut porttitor leo a diam. Eu nisl nunc mi ipsum faucibus.

title 3

Pellentesque habitant morbi tristique senectus et netus et malesuada fames. Fusce id velit ut tortor pretium viverra suspendisse potenti. Sed egestas egestas fringilla phasellus faucibus. Ac turpis egestas maecenas pharetra. Neque viverra justo nec ultrices dui sapien eget.

sub title 3

Nulla aliquet porttitor lacus luctus accumsan tortor posuere ac ut.

sub sub title 3

Tristique et egestas quis ipsum suspendisse ultrices gravida. Iaculis nunc sed augue lacus viverra vitae congue eu consequat. Sit amet justo donec enim diam vulputate ut pharetra sit.

Thanks ! Generalized now (in the original post, macro and source) to a larger variety of line endings. Should now cover your files, I think.

To capture the result as a KM variable, you can choose a save results to variable option at the top of the script action, and specify a variable name at the foot of the action.


1 Like

fantastic !!! thank you so much !!

1 Like

There is another problem with generating a TOC which I have run into: Getting the href encoding of the heading text - in a way that satisfies all consumers of your Markdown.

I’ve seen two basic flavours:

  • Separating words by dashes.
  • Jamming words together.

Plus special character mangling.

I hope you don’t run into this problem. (I have, several times.)

1 Like

I will keep it in mind. thank you

1 Like