UNPKG

kdp-book-generator

Version:

Generate KDP-compliant PDFs and EPUBs from Markdown for Amazon book publishing

380 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BookConfigManager = void 0; /** * Manager for book configuration with KDP-compliant defaults and validation * * Features: * - Pre-defined KDP-compliant book formats * - Automatic margin calculation based on page count * - Configuration validation and merging * - Typography presets for professional book layout */ class BookConfigManager { /** * Get the default book configuration with KDP-compliant settings * * @returns Default BookConfig with 6"x9" format and standard typography */ static getDefaultConfig() { return { title: 'My Book', author: 'Author Name', format: this.KDP_FORMATS['6x9'], margins: this.calculateKDPMargins(200, '6x9'), // Default for 200 pages typography: this.getDefaultTypography(), pageNumbers: this.getDefaultPageNumbers(), tableOfContents: true, bleed: false, }; } static getKindleConfig() { return { title: 'My Book', author: 'Author Name', format: this.KDP_FORMATS['kindle'], margins: this.getKindleMargins(), typography: this.getKindleTypography(), pageNumbers: this.getKindlePageNumbers(), tableOfContents: true, bleed: false, }; } /** * Calculate KDP-compliant margins based on page count * * @param pageCount - Total number of pages in the book * @param format - Book format identifier (e.g., '6x9', '5.5x8.5') * @returns Margins object with calculated inside/outside margins per KDP requirements * * KDP margin requirements: * - 24 pages or less: 0.375" inside * - 25-150 pages: 0.5" inside * - 151-300 pages: 0.625" inside * - 301-500 pages: 0.75" inside * - 501+ pages: 0.875" inside */ static calculateKDPMargins(pageCount, format) { const formatData = this.KDP_FORMATS[format]; if (!formatData) { throw new Error(`Unknown format: ${format}`); } // Fixed margins as requested const insideMargin = 0.625; const outsideMargin = 0.625; // Default margins for top and bottom const topMargin = 0.625; const bottomMargin = 0.625; return { top: topMargin, bottom: bottomMargin, inside: insideMargin, outside: outsideMargin, unit: 'in', }; } static getDefaultTypography() { const bodyFont = { family: 'Nunito', size: 11, lineHeight: 1.5, weight: 'normal', style: 'normal', color: '#000000', marginTop: 0, marginBottom: 10, }; return { body: bodyFont, heading1: { family: 'Lexend', size: 20, lineHeight: 1.3, weight: 'normal', style: 'normal', color: '#000000', marginTop: 48, marginBottom: 24, }, heading2: { family: 'Lexend', size: 17, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 42, marginBottom: 18, }, heading3: { family: 'Lexend', size: 13, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 36, marginBottom: 16, }, heading4: { family: 'Lexend', size: 11, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 24, marginBottom: 12, }, heading5: { family: 'Lexend', size: 10, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 20, marginBottom: 10, }, heading6: { family: 'Lexend', size: 9, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 18, marginBottom: 8, }, }; } static getDefaultPageNumbers() { return { enabled: true, startPage: 1, format: 'decimal', position: 'footer', alignment: 'center', }; } static validateConfig(config) { const errors = []; // Validate format if (!config.format || !config.format.width || !config.format.height) { errors.push('Invalid format configuration'); } // Check if this is Kindle format const isKindle = config.format && config.format.name === 'Kindle'; // Validate margins if (!config.margins) { errors.push('Margins configuration is required'); } else { const { top, bottom, inside, outside } = config.margins; if (isKindle) { // Kindle has different margin requirements if (top < 0.25 || bottom < 0.25 || inside < 0.25 || outside < 0.25) { errors.push('Kindle margins must be at least 0.25"'); } } else { // Standard KDP print requirements if (top < 0.25 || bottom < 0.25 || inside < 0.375 || outside < 0.25) { errors.push('Margins do not meet KDP minimum requirements'); } } } // Validate typography if (!config.typography) { errors.push('Typography configuration is required'); } // Validate format constraints (skip for Kindle) if (!isKindle) { if (config.format.width < 4 || config.format.width > 8.5) { errors.push('Format width must be between 4" and 8.5"'); } if (config.format.height < 6 || config.format.height > 11.69) { errors.push('Format height must be between 6" and 11.69"'); } } return { valid: errors.length === 0, errors, }; } static getAvailableFormats() { return Object.keys(this.KDP_FORMATS); } static getFormatByName(name) { return this.KDP_FORMATS[name]; } static createCustomFormat(name, width, height, unit = 'in') { return { name, width, height, unit, }; } static getKindleMargins() { // Kindle needs minimal margins as devices handle their own return { top: 0.5, bottom: 0.5, inside: 0.3, outside: 0.3, unit: 'in', }; } static getKindleTypography() { // Kindle typography optimized for e-readers const bodyFont = { family: 'Georgia, serif', // Kindle defaults to serif fonts size: 12, // Slightly larger for e-readers lineHeight: 1.6, // More spacing for screen reading weight: 'normal', style: 'normal', color: '#000000', marginTop: 0, marginBottom: 12, }; return { body: bodyFont, heading1: { family: 'Helvetica, Arial, sans-serif', size: 24, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 24, marginBottom: 18, }, heading2: { family: 'Helvetica, Arial, sans-serif', size: 20, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 20, marginBottom: 14, }, heading3: { family: 'Helvetica, Arial, sans-serif', size: 16, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 18, marginBottom: 12, }, heading4: { family: 'Helvetica, Arial, sans-serif', size: 14, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 16, marginBottom: 10, }, heading5: { family: 'Helvetica, Arial, sans-serif', size: 13, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 14, marginBottom: 8, }, heading6: { family: 'Helvetica, Arial, sans-serif', size: 12, lineHeight: 1.3, weight: 'bold', style: 'normal', color: '#000000', marginTop: 12, marginBottom: 6, }, }; } static getKindlePageNumbers() { // Kindle handles page numbers differently return { enabled: false, // Kindle uses location numbers startPage: 1, format: 'decimal', position: 'footer', alignment: 'center', }; } static mergeConfig(defaultConfig, userConfig) { return { ...defaultConfig, ...userConfig, format: userConfig.format || defaultConfig.format, margins: { ...defaultConfig.margins, ...userConfig.margins }, typography: { ...defaultConfig.typography, ...userConfig.typography }, pageNumbers: { ...defaultConfig.pageNumbers, ...userConfig.pageNumbers }, }; } static loadFromFile(_configPath) { // This would load from JSON/YAML file // For now, return default config return this.getDefaultConfig(); } static saveToFile(_config, _configPath) { // This would save to JSON/YAML file // Implementation depends on chosen format } } exports.BookConfigManager = BookConfigManager; BookConfigManager.KDP_FORMATS = { '6x9': { name: '6" x 9"', width: 6, height: 9, unit: 'in', }, '5.5x8.5': { name: '5.5" x 8.5"', width: 5.5, height: 8.5, unit: 'in', }, '5x8': { name: '5" x 8"', width: 5, height: 8, unit: 'in', }, '8.5x11': { name: '8.5" x 11"', width: 8.5, height: 11, unit: 'in', }, '7x10': { name: '7" x 10"', width: 7, height: 10, unit: 'in', }, '7.5x9.25': { name: '7.5" x 9.25"', width: 7.5, height: 9.25, unit: 'in', }, kindle: { name: 'Kindle', width: 6, height: 9, unit: 'in', }, }; //# sourceMappingURL=book-config.js.map