JSFiddle - React, Tailwind, and code Playground

HTML

<div id="outp">
</div>
<div id="content">
    <h1>Test 1</h1>blah
    <h2>Test 1.1</h2>
    <h3>Test 1.1.1</h3>asdf
    <h3>Test 1.1.2</h3>
    <h1>Test 2</h1>
    <h3>Test 2.1.1</h3>123123123
    <h2>Test 2.2</h2>
    <p></p>
</div>

JavaScript

var buildRec;

buildRec = function(headingNodes, $elm, lv) {
  var cnt, curLv, li, node;
  node = headingNodes.splice(0, 1);
  if (node && node.length > 0) {
    curLv = parseInt(node[0].tagName.substring(1));
    if (curLv === lv) {
      cnt = 0;
    } else if (curLv < lv) {
      cnt = 0;
      while (true) {
        $elm = $elm.parent().parent();
        cnt--;
        if (!(cnt > (curLv - lv))) {
          break;
        }
      }
    } else if (curLv > lv) {
      cnt = 0;
      while (true) {
        li = $elm.children().last();
        if (!($elm.children().last().length > 0)) {
          $elm.append($("<li>"));
            li = $elm.children().last();
        }
        li.append($("<ul>"));
          $elm = li.children().last();
        cnt++;
        if (!(cnt < (curLv - lv))) {
          break;
        }
      }
    }
    $elm.append($("<li>"));
      li = $elm.children().last();
    li.text(node[0].innerHTML);
    return buildRec(headingNodes, $elm, lv + cnt);
  }
};

// example usage
var headingNodes = $('#content').children().filter(":header")
var result = $('<ul>')
buildRec(headingNodes,result,1)
$("#outp").append(result);
console.log(result);