133 lines
4.5 KiB
JavaScript
133 lines
4.5 KiB
JavaScript
/**
|
|
* Macro Processor
|
|
* Handles macro execution and result rendering
|
|
*/
|
|
|
|
class MacroProcessor {
|
|
constructor(webdavClient) {
|
|
this.webdavClient = webdavClient;
|
|
this.macroRegistry = new MacroRegistry();
|
|
this.includeStack = [];
|
|
this.faqItems = [];
|
|
|
|
this.registerDefaultPlugins();
|
|
console.log('[MacroProcessor] Initialized');
|
|
}
|
|
|
|
/**
|
|
* Process all macros in markdown
|
|
*/
|
|
async processMacros(content) {
|
|
console.log('[MacroProcessor] Processing content, length:', content.length);
|
|
|
|
const macros = MacroParser.extractMacros(content);
|
|
console.log(`[MacroProcessor] Found ${macros.length} macros`);
|
|
|
|
const errors = [];
|
|
let processedContent = content;
|
|
let faqOutput = '';
|
|
|
|
// Process in reverse to preserve positions
|
|
for (let i = macros.length - 1; i >= 0; i--) {
|
|
const macro = macros[i];
|
|
console.log(`[MacroProcessor] Processing macro ${i}:`, macro.actor, macro.method);
|
|
|
|
try {
|
|
const result = await this.processMacro(macro);
|
|
|
|
if (result.success) {
|
|
console.log(`[MacroProcessor] Macro succeeded, replacing content`);
|
|
processedContent =
|
|
processedContent.substring(0, macro.start) +
|
|
result.content +
|
|
processedContent.substring(macro.end);
|
|
} else {
|
|
console.error(`[MacroProcessor] Macro failed:`, result.error);
|
|
errors.push({ macro: macro.fullMatch, error: result.error });
|
|
|
|
const errorMsg = `\n\n⚠️ **Macro Error**: ${result.error}\n\n`;
|
|
processedContent =
|
|
processedContent.substring(0, macro.start) +
|
|
errorMsg +
|
|
processedContent.substring(macro.end);
|
|
}
|
|
} catch (error) {
|
|
console.error(`[MacroProcessor] Macro exception:`, error);
|
|
errors.push({ macro: macro.fullMatch, error: error.message });
|
|
|
|
const errorMsg = `\n\n⚠️ **Macro Exception**: ${error.message}\n\n`;
|
|
processedContent =
|
|
processedContent.substring(0, macro.start) +
|
|
errorMsg +
|
|
processedContent.substring(macro.end);
|
|
}
|
|
}
|
|
|
|
// Append FAQ if any FAQ macros were used
|
|
if (this.faqItems.length > 0) {
|
|
faqOutput = '\n\n---\n\n## FAQ\n\n';
|
|
faqOutput += this.faqItems
|
|
.map((item, idx) => `### ${idx + 1}. ${item.title}\n\n${item.response}`)
|
|
.join('\n\n');
|
|
processedContent += faqOutput;
|
|
}
|
|
|
|
console.log('[MacroProcessor] Processing complete, errors:', errors.length);
|
|
|
|
return {
|
|
success: errors.length === 0,
|
|
content: processedContent,
|
|
errors
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Process single macro
|
|
*/
|
|
async processMacro(macro) {
|
|
const plugin = this.macroRegistry.resolve(macro.actor, macro.method);
|
|
|
|
if (!plugin) {
|
|
return {
|
|
success: false,
|
|
error: `Unknown macro: !!${macro.actor}.${macro.method}`
|
|
};
|
|
}
|
|
|
|
// Check for circular includes
|
|
if (macro.method === 'include') {
|
|
const path = macro.params.path;
|
|
if (this.includeStack.includes(path)) {
|
|
return {
|
|
success: false,
|
|
error: `Circular include: ${this.includeStack.join(' → ')} → ${path}`
|
|
};
|
|
}
|
|
}
|
|
|
|
try {
|
|
return await plugin.process(macro, this.webdavClient);
|
|
} catch (error) {
|
|
console.error('[MacroProcessor] Plugin error:', error);
|
|
return {
|
|
success: false,
|
|
error: `Plugin error: ${error.message}`
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register default plugins
|
|
*/
|
|
registerDefaultPlugins() {
|
|
// Include plugin
|
|
this.macroRegistry.register('core', 'include', new IncludePlugin(this));
|
|
|
|
// FAQ plugin
|
|
this.macroRegistry.register('core', 'faq', new FAQPlugin(this));
|
|
|
|
console.log('[MacroProcessor] Registered default plugins');
|
|
}
|
|
}
|
|
|
|
window.MacroProcessor = MacroProcessor; |