/** * Include Plugin * Includes content from other files * * Usage: * !!include path: 'myfile.md' * !!include path: 'collection:folder/file.md' */ class IncludePlugin extends MacroPlugin { constructor(processor) { super(); this.processor = processor; } canHandle(actor, method) { return actor === 'core' && method === 'include'; } async process(macro, webdavClient) { const path = macro.params.path; console.log('[IncludePlugin] Processing include:', path); if (!path) { console.error('[IncludePlugin] Missing path parameter'); return { success: false, error: 'Include macro requires "path" parameter' }; } try { // Parse path format: "collection:path/to/file" or "path/to/file" let targetCollection = webdavClient.currentCollection; let targetPath = path; if (path.includes(':')) { [targetCollection, targetPath] = path.split(':', 2); console.log('[IncludePlugin] Using external collection:', targetCollection); } else { console.log('[IncludePlugin] Using current collection:', targetCollection); } // Check for circular includes const fullPath = `${targetCollection}:${targetPath}`; if (this.processor.includeStack.includes(fullPath)) { console.error('[IncludePlugin] Circular include detected'); return { success: false, error: `Circular include detected: ${this.processor.includeStack.join(' → ')} → ${fullPath}` }; } // Add to include stack this.processor.includeStack.push(fullPath); // Switch collection temporarily const originalCollection = webdavClient.currentCollection; webdavClient.setCollection(targetCollection); // Fetch file console.log('[IncludePlugin] Fetching:', targetPath); const content = await webdavClient.get(targetPath); // Restore collection webdavClient.setCollection(originalCollection); // Remove from stack this.processor.includeStack.pop(); console.log('[IncludePlugin] Include successful, length:', content.length); return { success: true, content: content }; } catch (error) { console.error('[IncludePlugin] Error:', error); // Restore collection on error if (webdavClient.currentCollection !== this.processor.webdavClient?.currentCollection) { webdavClient.setCollection(this.processor.webdavClient?.currentCollection); } this.processor.includeStack = this.processor.includeStack.filter( item => !item.includes(path) ); return { success: false, error: `Cannot include "${path}": ${error.message}` }; } } } window.IncludePlugin = IncludePlugin;