{"version":3,"file":"index.cjs","sources":["../src/index.js"],"sourcesContent":["import { load } from 'cheerio';\nimport { extname } from 'path';\nimport Prism from 'prismjs';\nimport loadLanguages from 'prismjs/components/index.js';\nimport he from 'he';\n\n// Import languages from Prism's default export\nconst { languages } = Prism;\n\n/**\n * Check if a file is HTML based on its extension\n * @param {string} filePath - Path to the file\n * @returns {boolean} - True if the file has an HTML extension\n */\nconst isHTMLFile = (filePath) => {\n  const extension = extname(filePath).toLowerCase();\n  return ['.html', '.htm'].includes(extension);\n};\n\n/**\n * @typedef Options\n * @property {boolean} [decode=false] - Whether to decode HTML entities\n * @property {boolean} [lineNumbers=false] - Whether to add line numbers\n * @property {string[]} [preLoad=[]] - Languages to preload\n */\n\n/**\n * Metalsmith plugin to highlight code syntax with PrismJS\n *\n * This plugin finds all code blocks in HTML files that have language-* classes\n * and applies Prism.js syntax highlighting to them. It can also add line numbers\n * and handle HTML entity decoding.\n *\n * @param {Options} [options] - Configuration options\n * @param {boolean} [options.decode=false] - Whether to decode HTML entities in code blocks\n * @param {boolean} [options.lineNumbers=false] - Whether to add line numbers to code blocks\n * @param {string[]} [options.preLoad=[]] - Languages to preload before processing\n * @returns {import('metalsmith').Plugin} - A metalsmith plugin function\n * @example\n * // Basic usage\n * metalsmith.use(prism());\n *\n * // With options\n * metalsmith.use(prism({\n *   decode: true,\n *   lineNumbers: true,\n *   preLoad: ['java', 'scala']\n * }));\n */\nconst metalsmithPrism = (options = {}) => {\n  // Create a new options object with defaults\n  const opts = {\n    decode: false,\n    lineNumbers: false,\n    preLoad: [],\n    ...options\n  };\n\n  // Track loaded languages to avoid duplicate loading\n  const loadedLanguages = new Set();\n\n  // Set up line numbers functionality\n  const NEW_LINE_EXP = /\\n(?!$)/g;\n  let lineNumbersWrapper;\n\n  return (files, metalsmith, done) => {\n    // Get debug instance from metalsmith\n    const debug = metalsmith.debug('metalsmith-prism');\n    \n    debug('Starting metalsmith-prism plugin');\n    debug('Options:', opts);\n\n    // Always load PHP by default\n    debug('Loading PHP by default');\n    try {\n      loadLanguages(['php']);\n      loadedLanguages.add('php');\n    } catch (e) {\n      debug('Failed to load PHP:', e);\n    }\n\n    // Preload languages if specified\n    if (opts.preLoad && opts.preLoad.length) {\n      debug('Preloading languages:', opts.preLoad);\n      opts.preLoad.forEach((language) => {\n        if (!loadedLanguages.has(language)) {\n          try {\n            loadLanguages([language]);\n            loadedLanguages.add(language);\n            debug(`Successfully preloaded language: ${language}`);\n          } catch (e) {\n            console.warn(`Failed to preload prism syntax: ${language}!`, e);\n            debug(`Error preloading language ${language}:`, e);\n          }\n        } else {\n          debug(`Language ${language} already loaded, skipping`);\n        }\n      });\n    }\n\n    /**\n     * Require optional language package\n     * @param {string} language\n     * @param {Set} loadedLanguages\n     */\n    const requireLanguage = (language, loadedLanguages) => {\n      if (loadedLanguages.has(language) || languages[language]) {\n        debug(`Language ${language} already available, skipping load`);\n        return;\n      }\n\n      debug(`Loading language on-demand: ${language}`);\n      try {\n        loadLanguages([language]);\n        loadedLanguages.add(language);\n        debug(`Successfully loaded language: ${language}`);\n      } catch (e) {\n        console.warn(`Failed to load prism syntax: ${language}!`, e);\n        debug(`Error loading language ${language}:`, e);\n      }\n    };\n\n    // Only set up the hook if line numbers are requested\n    if (opts.lineNumbers) {\n      debug('Setting up line numbers hook');\n      Prism.hooks.add('after-tokenize', (env) => {\n        const match = env.code.match(NEW_LINE_EXP);\n        const linesNum = match ? match.length + 1 : 1;\n        debug(`Counted ${linesNum} lines for line numbers`);\n        const lines = new Array(linesNum + 1).join('<span></span>');\n        lineNumbersWrapper = `<span aria-hidden=\"true\" class=\"line-numbers-rows\">${lines}</span>`;\n      });\n    }\n\n    // Call done asynchronously to avoid blocking\n    setImmediate(done);\n\n    try {\n      Object.keys(files).forEach((file) => {\n        if (!isHTMLFile(file)) {\n          return;\n        }\n\n        debug(`Processing HTML file: ${file}`);\n        const contents = files[file].contents.toString();\n        const $ = load(contents, { decodeEntities: false });\n        let highlighted = false;\n        const code = $('code');\n\n        if (!code.length) {\n          debug(`No code blocks found in ${file}`);\n          return;\n        }\n\n        debug(`Found ${code.length} code blocks in ${file}`);\n\n        code.each(function () {\n          const $this = $(this);\n\n          const className = $this.attr('class') || '';\n          const targets = className.split('language-');\n          let addLineNumbers = false;\n\n          if (targets.length > 1) {\n            const $pre = $this.parent('pre');\n\n            if ($pre) {\n              // Copy className to <pre> container\n              $pre.addClass(className);\n\n              if (opts.lineNumbers) {\n                $pre.addClass('line-numbers');\n                addLineNumbers = true;\n                debug('Adding line numbers');\n              }\n            }\n\n            highlighted = true;\n            let language = targets[1];\n            debug(`Detected language: ${language}`);\n            requireLanguage(language, loadedLanguages);\n\n            if (!languages[language]) {\n              debug(`Language ${language} not available, falling back to markup`);\n              language = 'markup';\n            }\n\n            const html = language === 'markup' && !opts.decode ? $this.html() : he.decode($this.html());\n            debug(`HTML decoding ${opts.decode ? 'applied' : 'not applied'} for language ${language}`);\n\n            debug(`Highlighting code with language: ${language}`);\n            const highlightedCode = Prism.highlight(html, languages[language]);\n            $this.html(addLineNumbers ? highlightedCode + lineNumbersWrapper : highlightedCode);\n          }\n        });\n\n        if (highlighted) {\n          debug(`Updating contents of ${file} with highlighted code`);\n          files[file].contents = Buffer.from($.html());\n        } else {\n          debug(`No code was highlighted in ${file}`);\n        }\n      });\n\n      debug('Completed metalsmith-prism plugin');\n    } catch (error) {\n      debug.error('Error in metalsmith-prism plugin:', error);\n      // We can't call done(error) here because done has already been called\n      console.error('Error processing files:', error);\n    }\n  };\n};\n\n// ESM export\nexport default metalsmithPrism;\n"],"names":["languages","Prism","isHTMLFile","filePath","extension","extname","toLowerCase","includes","metalsmithPrism","options","opts","decode","lineNumbers","preLoad","loadedLanguages","Set","NEW_LINE_EXP","lineNumbersWrapper","files","metalsmith","done","debug","loadLanguages","add","e","length","forEach","language","has","console","warn","requireLanguage","hooks","env","match","code","linesNum","lines","Array","join","setImmediate","Object","keys","file","contents","toString","$","load","decodeEntities","highlighted","each","$this","className","attr","targets","split","addLineNumbers","$pre","parent","addClass","html","he","highlightedCode","highlight","Buffer","from","error"],"mappings":"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"}