mycro-zine/src/index.mjs

138 lines
3.3 KiB
JavaScript

/**
* MycroZine - 8-page mini-zine generator utilities
*
* A toolkit for creating print-ready mycro-zines (8-page mini folded zines).
*
* @module mycro-zine
*/
export { createPrintLayout } from './layout.mjs';
export {
STYLES,
TONES,
PAGE_TEMPLATES,
ZINE_STRUCTURES,
getContentOutlinePrompt,
getImagePrompt,
getIdeationPrompt
} from './prompts.mjs';
export {
generateQRCode,
generateQRCodeDataURL,
generateZineQRCodes,
generateUndernetQRCodes
} from './qrcode.mjs';
/**
* Zine configuration defaults
*/
export const DEFAULTS = {
style: 'punk-zine',
tone: 'rebellious',
paperFormat: 'letter', // US Letter 8.5" x 11"
dpi: 300,
pageCount: 8
};
/**
* Page dimensions in pixels at 300 DPI
* Paper is landscape orientation for traditional mini-zine folding
*/
export const DIMENSIONS = {
letter: {
width: 3300, // 11" x 300 (landscape)
height: 2550, // 8.5" x 300
panelWidth: 825, // ~7cm (width / 4 cols)
panelHeight: 1275, // ~10.8cm (height / 2 rows)
panelCols: 4,
panelRows: 2
},
a4: {
width: 3508, // 297mm at 300 DPI (landscape)
height: 2480, // 210mm at 300 DPI
panelWidth: 877,
panelHeight: 1240,
panelCols: 4,
panelRows: 2
}
};
/**
* Validate a zine configuration
*
* @param {Object} config - Zine configuration to validate
* @returns {{ valid: boolean, errors: string[] }}
*/
export function validateConfig(config) {
const errors = [];
if (!config.topic || typeof config.topic !== 'string') {
errors.push('Topic is required and must be a string');
}
if (config.style && !['punk-zine', 'minimal', 'collage', 'retro', 'academic'].includes(config.style)) {
errors.push(`Invalid style: ${config.style}`);
}
if (config.tone && !['rebellious', 'playful', 'informative', 'poetic'].includes(config.tone)) {
errors.push(`Invalid tone: ${config.tone}`);
}
if (config.paperFormat && !['letter', 'a4'].includes(config.paperFormat)) {
errors.push(`Invalid paper format: ${config.paperFormat}`);
}
if (config.pages && (!Array.isArray(config.pages) || config.pages.length !== 8)) {
errors.push('Pages must be an array of exactly 8 items');
}
return {
valid: errors.length === 0,
errors
};
}
/**
* Create a new zine configuration
*
* @param {Object} options
* @param {string} options.topic - Main topic/theme
* @param {string} [options.title] - Zine title (generated from topic if not provided)
* @param {string} [options.style='punk-zine'] - Visual style
* @param {string} [options.tone='rebellious'] - Content tone
* @param {string} [options.paperFormat='letter'] - Paper format
* @param {string[]} [options.sourceUrls] - Reference URLs
* @returns {Object} Zine configuration object
*/
export function createZineConfig(options) {
const {
topic,
title = topic.toUpperCase(),
style = DEFAULTS.style,
tone = DEFAULTS.tone,
paperFormat = DEFAULTS.paperFormat,
sourceUrls = []
} = options;
const config = {
id: `zine_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
topic,
title,
style,
tone,
paperFormat,
sourceUrls,
createdAt: Date.now(),
pages: [],
outline: null,
status: 'draft'
};
const validation = validateConfig(config);
if (!validation.valid) {
throw new Error(`Invalid config: ${validation.errors.join(', ')}`);
}
return config;
}