define(["exports", "deps/marked", "core/utils", "deps/beautify-html", "core/beautify-options"], function (exports, _marked, _utils, _beautifyHtml, _beautifyOptions) {
  "use strict";

  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.run = run;

  var _marked2 = _interopRequireDefault(_marked);

  var _beautifyHtml2 = _interopRequireDefault(_beautifyHtml);

  var _beautifyOptions2 = _interopRequireDefault(_beautifyOptions);

  function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
      default: obj
    };
  }

  function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }

  var _createClass = function () {
    function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }

    return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  }();

  _marked2.default.setOptions({
    sanitize: false,
    gfm: true
  });

  function toHTML(text) {
    var normalizedLeftPad = (0, _utils.normalizePadding)(text);
    // As markdown is pulled from HTML, > is already escaped and
    // so blockquotes aren't picked up by the parser. This fixes it.
    var potentialMarkdown = normalizedLeftPad.replace(/&gt;/gm, ">");
    var html = (0, _marked2.default)(potentialMarkdown);

    return html;
  }

  function processElements(selector) {
    return function (element) {
      var elementsToProcess = Array.from(element.querySelectorAll(selector));
      elementsToProcess.reverse().map(function (element) {
        return { element: element, html: toHTML(element.innerHTML) };
      }).reduce(function (div, _ref) {
        var element = _ref.element,
            html = _ref.html;

        var node = div;
        div.innerHTML = html;
        // Same element, don't nest
        if (div.firstChild && element.localName === div.firstChild.localName) {
          node = div.firstChild;
        }
        element.innerHTML = "";
        while (node.firstChild) {
          element.appendChild(node.firstChild);
        }
        return div;
      }, element.ownerDocument.createElement("div"));
      return elementsToProcess;
    };
  }

  var Builder = function () {
    function Builder(doc) {
      _classCallCheck(this, Builder);

      this.doc = doc;
      this.root = doc.createDocumentFragment();
      this.stack = [this.root];
      this.current = this.root;
    }

    _createClass(Builder, [{
      key: "findPosition",
      value: function findPosition(header) {
        return parseInt(header.tagName.charAt(1), 10);
      }
    }, {
      key: "findParent",
      value: function findParent(position) {
        var parent = void 0;
        while (position > 0) {
          position--;
          parent = this.stack[position];
          if (parent) return parent;
        }
      }
    }, {
      key: "findHeader",
      value: function findHeader(_ref2) {
        var node = _ref2.firstChild;

        while (node) {
          if (/H[1-6]/.test(node.tagName)) {
            return node;
          }
          node = node.nextSibling;
        }
        return null;
      }
    }, {
      key: "addHeader",
      value: function addHeader(header) {
        var section = this.doc.createElement("section");
        var position = this.findPosition(header);

        section.appendChild(header);
        this.findParent(position).appendChild(section);
        this.stack[position] = section;
        this.stack.length = position + 1;
        this.current = section;
      }
    }, {
      key: "addSection",
      value: function addSection(node, process) {
        var header = this.findHeader(node);
        var position = header ? this.findPosition(header) : 1;
        var parent = this.findParent(position);

        if (header) {
          node.removeChild(header);
        }

        node.appendChild(process(node));

        if (header) {
          node.insertBefore(header, node.firstChild);
        }

        parent.appendChild(node);
        this.current = parent;
      }
    }, {
      key: "addElement",
      value: function addElement(node) {
        this.current.appendChild(node);
      }
    }]);

    return Builder;
  }();

  function structure(fragment, doc) {
    function process(root) {
      var stack = new Builder(doc);
      while (root.firstChild) {
        var node = root.firstChild;
        if (node.nodeType !== Node.ELEMENT_NODE) {
          root.removeChild(node);
          continue;
        }
        switch (node.localName) {
          case "h1":
          case "h2":
          case "h3":
          case "h4":
          case "h5":
          case "h6":
            stack.addHeader(node);
            break;
          case "section":
            stack.addSection(node, process);
            break;
          default:
            stack.addElement(node);
        }
      }
      return stack.root;
    }
    return process(fragment);
  }

  function substituteWithTextNodes(elements) {
    Array.from(elements).forEach(function (element) {
      var textNode = element.ownerDocument.createTextNode(element.textContent);
      element.parentElement.replaceChild(textNode, element);
    });
  }

  var processBlockLevelElements = processElements("section section, body > section, .issue, .note, .req");

  function run(conf, doc, cb) {
    if (conf.format !== "markdown") {
      return cb();
    }
    // We transplant the UI to do the markdown processing
    var rsUI = doc.getElementById("respec-ui");
    rsUI.remove();
    // The new body will replace the old body
    var newBody = doc.createElement("body");
    newBody.innerHTML = doc.body.innerHTML;
    // Marked expects markdown be flush against the left margin
    // so we need to normalize the inner text of some block
    // elements.
    processBlockLevelElements(newBody);
    // Process the rest
    var dirtyHTML = toHTML(newBody.innerHTML);
    var cleanHTML = dirtyHTML
    // Markdown parsing sometimes inserts empty p tags
    .replace(/<p>\s*<\/p>/gm, "");
    var beautifulHTML = _beautifyHtml2.default.html_beautify(cleanHTML, _beautifyOptions2.default)
    // beautifer has a bad time with "\n&quot;<element"
    // https://github.com/beautify-web/js-beautify/issues/943
    .replace(/&quot;\n\s+\</gm, "\"<");

    newBody.innerHTML = beautifulHTML;
    // Remove links where class .nolinks
    substituteWithTextNodes(newBody.querySelectorAll(".nolinks a[href]"));
    // Restructure the document properly
    var fragment = structure(newBody, doc);
    // Frankenstein the whole thing back together
    newBody.appendChild(fragment);
    newBody.appendChild(rsUI);
    doc.body.parentNode.replaceChild(newBody, doc.body);
    cb();
  };
});
//# sourceMappingURL=markdown.js.map