"use strict";Object.defineProperty(exports, "__esModule", { value: true });Object.defineProperty(exports, "MDAST", { enumerable: true, get: function () {return _unified.MDAST;} });exports.getCodeBlocks = exports.parse = exports.parseMeta = void 0;var _jsYaml = require("js-yaml");

var _unified = require("./unified");

var _utils = require("../utils");































const traversal = async (
node,
parent,
cb,
index = 0) =>
{
  await cb(node, parent, index);
  let i = 0;
  const children = 'children' in node ? node.children : [];
  for (const child of children) {
    await traversal(child, node, cb, i);
    i++;
  }
};

const reKeyValue = /^(([a-zA-Z0-9]+)(?:=([^" ]+)|="([^"]+)")?)/;
const parseMeta = meta => {
  if (!meta) {
    return {};
  }
  meta = meta.toString().trim();
  if (meta.slice(0, 1) !== '{' || meta.slice(-1) !== '}') {
    return {};
  }
  meta = meta.slice(1, -1);
  const results = {};
  let matched;
  while (matched = reKeyValue.exec(meta)) {
    const key = matched[2];
    const value = matched[3] || matched[4] || true;
    results[key] = value;
    meta = meta.slice(matched[1].length).trimLeft();
  }
  return results;
};exports.parseMeta = parseMeta;

const reFrontmatter = /^---\n([^]*)\n---\n/;

const parse = async markdownText => {
  if (!markdownText) {
    markdownText = '';
  }
  if (markdownText.startsWith('#! ')) {
    markdownText = markdownText.slice(markdownText.indexOf('\n'));
  }

  const matched = reFrontmatter.exec(markdownText);
  const settings = matched ? (0, _jsYaml.safeLoad)(matched[1]) : {};
  if (matched) {
    markdownText = markdownText.slice(matched[0].length);
  }

  const root = (0, _unified.parseMarkdown)(markdownText);
  return { settings, root };
};exports.parse = parse;

const getCodeBlocks = async node => {
  const codeBlocks = [];
  await traversal(node, node, async (node, parent, index) => {
    if (node.type !== 'code') {
      return;
    }

    const meta = parseMeta(node.meta);

    const filetype = node.lang;
    if (meta.timeout) {
      meta.timeout = Number.parseInt(meta.timeout);
    }
    if (typeof meta.runMode === 'string') {
      meta.runMode = meta.runMode === 'true';
    }

    codeBlocks.push({
      code: node.value,
      lang: filetype,
      meta,
      parent,
      index,
      hash: (0, _utils.sha256)(node.value) });

  });
  return codeBlocks;
};exports.getCodeBlocks = getCodeBlocks;