llmxml
Version:
Convert between markdown and LLM-friendly pseudo-XML
56 lines (48 loc) • 1.8 kB
JavaScript
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
import peggy from 'peggy';
const currentDir = dirname(fileURLToPath(import.meta.url));
const rootDir = join(currentDir, '..');
const grammarPath = join(rootDir, 'src', 'grammar', 'llmxml.pegjs');
const outputDir = join(rootDir, 'dist');
// Ensure output directories exist
mkdirSync(join(outputDir, 'cjs', 'grammar'), { recursive: true });
mkdirSync(join(outputDir, 'esm', 'grammar'), { recursive: true });
// Read grammar file
const grammar = readFileSync(grammarPath, 'utf-8');
// Generate parser with createNode function
const parser = peggy.generate(grammar, {
format: 'bare',
output: 'source',
grammarSource: grammarPath,
allowedStartRules: ['Document'],
features: {
// Disable eval usage where possible
eval: false,
// Use native functions instead
native: true
}
});
// Write ESM version
const esmCode = '// Generated from ' + grammarPath + '\n' +
'// Note: This is a generated parser that uses eval() for performance.\n' +
'// The use of eval is safe here as it only processes the grammar rules\n' +
'// and does not execute any user-provided code.\n' +
'/* eslint-disable no-eval */\n\n' +
'import { createNode } from \'../../src/utils/ast.js\';\n\n' +
'const options = { createNode };\n' +
'export default ' + parser + ';\n';
writeFileSync(
join(outputDir, 'esm', 'grammar', 'llmxml.js'),
esmCode
);
// Write CJS version
const cjsCode = '// Generated from ' + grammarPath + '\n' +
'const { createNode } = require(\'../../src/utils/ast\');\n\n' +
'const options = { createNode };\n' +
'module.exports = ' + parser + ';\n';
writeFileSync(
join(outputDir, 'cjs', 'grammar', 'llmxml.js'),
cjsCode
);