const peggy = require("peggy") const loaderUtils = require("loader-utils") const startRuleFinder = /\s*\/\/\s*peggy-loader:startRule\s*(\S+)\s*\n/g async function loadPeggy(rawSource) { const callback = this.async(); const tracks = await import("peggy-tracks") const rawOpts = loaderUtils.getOptions(this) const opts = typeof rawOpts === "object" && rawOpts !== null ? rawOpts : {} const peggyOpts = opts.hasOwnProperty("peggy") && typeof opts.peggy === "object" && opts.peggy !== null ? opts.peggy : {} const plugins = peggyOpts.hasOwnProperty("plugins") && Array.isArray(peggyOpts.plugins) ? peggyOpts.plugins : [] const tracksOpts = opts.hasOwnProperty("tracks") && typeof opts.tracks === "object" && opts.tracks !== null ? opts.tracks : {start: []} const start = Array.from({ [Symbol.iterator]() { return rawSource.matchAll(startRuleFinder) } }, ([_, rule]) => rule) const trackStarts = !opts.hasOwnProperty("tracks") ? [] : typeof tracksOpts.start === "string" ? [tracksOpts.start] : Array.isArray(tracksOpts.start) ? tracksOpts.start : start.length > 0 ? start : [undefined] const source = rawSource.replaceAll(startRuleFinder, "\n") const resultSource = peggy.generate(source, { ...peggyOpts, grammarSource: this.resourcePath, allowedStartRules: peggyOpts.allowedStartRules || start, output: "source", format: "es", plugins, }) for (const start of trackStarts) { const diagram = tracks.tracks({ ...tracksOpts, text: source, start, }) this.emitFile(`/tracks/${this.resourcePath}${typeof start === "string" ? "." + start : ""}.svg`, diagram.toStandalone(tracks.defaultCSS)) } // const fixedSource = resultSource.replace("export class SyntaxError", "class SyntaxError") callback(undefined, resultSource) } module.exports = loadPeggy