Skip to main content
Glama
index.ts•6.88 kB
#!/usr/bin/env node import 'dotenv/config'; import { Command } from 'commander'; import { PDFGenerator } from './generators/pdf-generator.js'; import { PDFConfig, BookGenerationOptions, ResearchCompilationOptions } from './types/index.js'; import { EGWDatabase } from '@surgbc/egw-writings-shared'; import * as fs from 'fs/promises'; import * as path from 'path'; // Export classes and types for library usage export { PDFGenerator } from './generators/pdf-generator.js'; export { PDFConfig, BookGenerationOptions, ResearchCompilationOptions, GenerationProgress } from './types/index.js'; const program = new Command(); program .name('egw-pdf-generator') .description('Generate PDFs from EGW Writings with configurable formatting') .version('1.0.0'); // Default PDF configuration const defaultConfig: PDFConfig = { pageSize: 'A4', margins: { top: 72, bottom: 72, left: 72, right: 72 }, fontSize: 12, lineHeight: 1.4, fontFamily: 'Times', paragraphIds: { show: false, style: 'hidden', format: 'sequential' }, pagination: { show: true, style: 'bottom-center', format: 'numeric', startNumber: 1 }, toc: { generate: true, maxDepth: 3, pageBreakAfter: true } }; program .command('book') .description('Generate PDF for a specific book') .requiredOption('-b, --book-id <id>', 'Book ID to generate PDF for') .option('-o, --output <path>', 'Output PDF file path', './output.pdf') .option('-c, --config <path>', 'JSON configuration file path') .option('--page-size <size>', 'Page size (A4, Letter, Legal, Custom)', 'A4') .option('--font-size <size>', 'Font size in points', '12') .option('--font-family <family>', 'Font family (Times, Helvetica, Courier)', 'Times') .option('--no-toc', 'Disable table of contents') .option('--no-pagination', 'Disable page numbers') .option('--show-paragraph-ids', 'Show paragraph identification') .option('--paragraph-style <style>', 'Paragraph ID style (inline, footnote, margin)', 'hidden') .action(async (options) => { try { console.log(`šŸ“– Generating PDF for book ID ${options.bookId}...`); let config = { ...defaultConfig }; // Load custom config if provided if (options.config) { const customConfig = JSON.parse(await fs.readFile(options.config, 'utf8')); config = { ...config, ...customConfig }; } // Apply CLI options config.pageSize = options.pageSize; config.fontSize = parseInt(options.fontSize); config.fontFamily = options.fontFamily; config.toc.generate = options.toc; config.pagination.show = options.pagination; config.paragraphIds.show = options.showParagraphIds; config.paragraphIds.style = options.paragraphStyle; const generator = new PDFGenerator((progress) => { const percentage = Math.round(progress.progress); const stage = progress.stage.charAt(0).toUpperCase() + progress.stage.slice(1); console.log(`${stage}: ${percentage}%${progress.currentChapter ? ` - ${progress.currentChapter}` : ''}`); }); const bookOptions: BookGenerationOptions = { bookId: parseInt(options.bookId), config, outputPath: path.resolve(options.output) }; await generator.generateBookPDF(bookOptions); generator.close(); console.log(`āœ… PDF generated successfully: ${options.output}`); } catch (error) { console.error(`āŒ Error generating PDF: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); } }); program .command('research') .description('Generate PDF from research compilation') .requiredOption('-q, --query <query>', 'Search query for research compilation') .option('-o, --output <path>', 'Output PDF file path', './research.pdf') .option('-c, --config <path>', 'JSON configuration file path') .option('--max-results <number>', 'Maximum search results to include', '50') .option('--languages <langs>', 'Comma-separated language codes', 'en') .option('--group-by <field>', 'Group results by (book, author, date, relevance)', 'book') .action(async (options) => { try { console.log(`šŸ” Compiling research for query: "${options.query}"...`); let config = { ...defaultConfig }; if (options.config) { const customConfig = JSON.parse(await fs.readFile(options.config, 'utf8')); config = { ...config, ...customConfig }; } const generator = new PDFGenerator((progress) => { const percentage = Math.round(progress.progress); console.log(`${progress.stage}: ${percentage}%`); }); // TODO: Implement research compilation console.log('🚧 Research compilation feature coming soon!'); generator.close(); } catch (error) { console.error(`āŒ Error generating research PDF: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); } }); program .command('list-books') .description('List available books in the database') .option('-l, --language <lang>', 'Filter by language code', 'en') .option('--limit <number>', 'Maximum books to show', '20') .action(async (options) => { try { const db = new EGWDatabase(); const books = await db.getBooks(options.language); const limitedBooks = books.slice(0, parseInt(options.limit)); console.log(`šŸ“š Available books (${limitedBooks.length}):\n`); limitedBooks.forEach((book: any) => { console.log(`ID: ${book.book_id}`); console.log(`Title: ${book.title}`); console.log(`Author: ${book.author}`); console.log(`Published: ${book.pub_year}`); console.log(`Pages: ${book.npages}`); console.log(`Language: ${book.lang}`); console.log('---'); }); db.close(); } catch (error) { console.error(`āŒ Error listing books: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); } }); program .command('config') .description('Generate example configuration file') .option('-o, --output <path>', 'Configuration file output path', './pdf-config.json') .action(async (options) => { try { await fs.writeFile(options.output, JSON.stringify(defaultConfig, null, 2)); console.log(`āœ… Example configuration saved to: ${options.output}`); console.log('\nšŸ“– You can customize this file and use it with --config option'); } catch (error) { console.error(`āŒ Error creating config: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); } }); // Only run CLI when this module is executed directly if (import.meta.url === `file://${process.argv[1]}`) { program.parse(); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pythondev-pro/egw_writings_mcp_server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server