JSFiddle - React, Tailwind, and code Playground

HTML

<pre></pre>
<hr />
<hr />

<h1>My fantastic site</h1>
<section>
  <h1>About me</h1>
  <p>I am a man who lives a fascinating life. Oh the stories I could tell you...</p>
  <section>
    <h1>What I do for a living</h1>
    <p>I sell enterprise-managed ant farms.</p>
  </section>
</section>
<section>
  <h1>Contact</h1>
  <p>Shout my name and I will come to you.</p>
</section>

<hr />

<h2>HTML5 Doctor articles</h2>
<article>
  <h1>The section element</h1>
  <p>We doctors are a bunch of chums using HTML5 and writing about how we do it...</p>
</article>
<article>
  <h1>The article element</h1>
  <p>We’ve discussed a lot of new elements here at HTML5Doctor...</p>
</article>

<hr />

<aside>
  <section>
    <h2>Twitter</h2>
  </section>
  <section>
    <h2>Recent comments</h2>
  </section>
</aside>

<hr />

<article>

  <hgroup>
    <h1>Title goes here</h1>
    <h2>Subtitle of article</h2>
  </hgroup>
  <p>Lorem Ipsum dolor set amet</p>
</article>

<hr />

<h1>Top of the outline</h1>

<section>
  <h2>A heading in the outline</h2>
  <p>Lorem ipsum dolor sit amet...</p>
</section>
<section>
  <h2>Another heading in the outline</h2>
  <p>Lorem ipsum dolor sit amet...</p>
  <blockquote>
    <h1>This quoted heading will not appear in the outline</h1>
    <p>Lorem ipsum dolor sit amet...</p>
  </blockquote>
</section>

<hr />

<p><b>TODO:</b> make this HTML4 document outline stuff work</p>
<h1>My fantastic site</h1>
<h2>About me</h2>
<p>I am a man who lives a fascinating life. Oh the stories I could tell you...</p>
<h3>What I do for a living</h3>
<p>I sell enterprise-managed ant farms.</p>
<h2>Contact</h2>
<p>Shout my name and I will come to you.</p>

JavaScript

// See http://html5doctor.com/document-outlines/
// That article begins with info on HTML4 document outlines
// This doesn't do that yet, it just handles the HTML5 stuff beneath in the article
// I'm sure there are problems with handling that HTML5 stuff tho

var headingElements = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'],
    sectioningElements = ['SECTION', 'ARTICLE', 'NAV', 'ASIDE'];

function makeOutline(root) {
    var ar = [],
        el = root.firstChild,
        nested, hg;
    while(el) {
        // If it's a sectioning element, create a new level in the outline
        if(sectioningElements.indexOf(el.tagName) > -1) {
            nested = makeOutline(el);
            if(nested.every(function(i){ return typeof i !== 'string'; })) {
                nested.unshift('Untitled ' + el.tagName.toLowerCase());
            }
            ar.push(nested);
        } else if(headingElements.indexOf(el.tagName) > -1) {
            ar.push(el.textContent);
        } else if(el.tagName === 'HGROUP') {
            hg = undefined;
            // Find the highest heading element within
            // Use its text, otherwhise it's untitled
            try {
                headingElements.forEach(function(t) {
                    els = el.getElementsByTagName(t);
                    if(els.length) {
                        hg = els[0].textContent;
                        throw BreakException;
                    }
                });
            } catch(e) {}
            if(!hg) {
                hg = 'Untitled hgroup';
            }
            ar.push(hg);
        }
        el = el.nextSibling;
    }
    return ar;
};

var outline = makeOutline(document.body);

// This is just used for displaying the outline. 
// Inspect the outline variable to see the generated array:
// console.log(outline);
    
function describeOutline(outline) {
    var indentForDepth = function(depth) {
        var str = '';
        for(i=depth;i>0;i--) {
            str += '\t';
        }
        return...