All files / src/pipeline/parsing create-markdown-parser.js

89.28% Statements 25/28
100% Branches 0/0
50% Functions 3/6
89.28% Lines 25/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96            3x 3x 3x 3x 3x   3x 3x 3x     3x                 3x 3x     3x 3x     3x 3x 3x 3x                   4x 4x   4x                     1x 1x                         4x   4x     3x                              
/**
 * Configures and exports a fully set up markdown-it instance.
 * This module integrates custom extensions, plugins, and related constants.
 * It centralizes markdown parsing setup to reduce complexity in index.js.
 */
 
const MarkdownIt = require('markdown-it');
const containers = require('markdown-it-container');
const path = require('node:path');
const fs = require('fs-extra');
const findPkgDir = require('find-pkg-dir');
 
const { configurePlugins } = require('../../markdown-it/plugins');
const { createTemplateTagParser, createSpecParser } = require('../../parsers');
const { whitespace, templateTags } = require('../../utils/regex-patterns.js');
 
// Constants used in markdown parsing
const noticeTypes = {
  note: 1,
  issue: 1,
  example: 1,
  warning: 1,
  todo: 1,
  'informative': 1
};
// Domain-specific regex patterns for markdown parsing (now centralized)
const specNameRegex = templateTags.specName;
const templateTagRegex = templateTags.terminology;
 
// Load spec corpus
const modulePath = findPkgDir(__dirname);
const specCorpus = fs.readJsonSync(path.join(modulePath, 'assets/compiled/refs.json'));
 
// Global variables (shared across renders)
let definitions = globalThis.definitions;
let references = globalThis.references;
let specGroups = globalThis.specGroups;
let noticeTitles = globalThis.noticeTitles;
 
/**
 * Creates and configures a markdown-it instance with extensions and plugins.
 * @param {Object} config - Configuration object (e.g., for anchor symbol).
 * @param {Function} setToc - Function to set the table of contents HTML.
 * @returns {Object} The configured markdown-it instance.
 */
function createMarkdownParser(config, setToc) {
  // Create parser functions with bound dependencies - cleaner than classes
  const templateTagParser = createTemplateTagParser(config, globalThis);
  const specParser = createSpecParser(specCorpus, globalThis);
 
  let md = MarkdownIt({
    html: true,
    linkify: true,
    typographer: true
  })
  .use(require('./apply-markdown-it-extensions.js'), [
      /*
        The first extension focuses on template-tag constructs.
        All complex logic is now delegated to pure functions.
      */
      {
        filter: type => type.match(templateTagRegex),
        parse: (token, type, primary) => templateTagParser(token, type, primary)
      },
      /*
        The second extension handles specification references.
        All complex logic is now delegated to pure functions.
      */
      {
        filter: type => type.match(specNameRegex),
        parse: (token, type, name) => specParser.parseSpecReference(token, type, name),
        render: (token, type, name) => specParser.renderSpecReference(token, type, name)
      }
    ]);
 
  md = configurePlugins(md, config, containers, noticeTypes, globalThis.noticeTitles, setToc);
 
  return md;
}
 
module.exports = { 
  createMarkdownParser, 
  noticeTypes, 
  spaceRegex: whitespace.oneOrMore, 
  specNameRegex, 
  templateTagRegex, 
  specCorpus, 
  definitions, 
  references, 
  specGroups, 
  noticeTitles,
  // Export parsers for direct access if needed
  createTemplateTagParser,
  createSpecParser
};