From d82393a47f9e998798da30ef9ee21309fdbc293a Mon Sep 17 00:00:00 2001 From: Oleg Proskurin Date: Sun, 28 Dec 2025 23:02:09 +0700 Subject: [PATCH] feat: update script --- scripts/html-reddit-to-markdown.js | 98 +++++++++++++++--------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/scripts/html-reddit-to-markdown.js b/scripts/html-reddit-to-markdown.js index f5d8fdd..5a74044 100644 --- a/scripts/html-reddit-to-markdown.js +++ b/scripts/html-reddit-to-markdown.js @@ -4,15 +4,21 @@ * HTML Reddit to Markdown Converter * * Парсит HTML файлы Reddit постов и конвертирует их в Markdown. - * Поддерживает извлечение основного контента и разделение на секции. + * Автоматически находит контент поста и конвертирует. * * Usage: - * node scripts/html-reddit-to-markdown.js \ - * --input 0-inbox/post.htm \ - * --start 249 \ - * --end 1219 \ - * --sections 6 \ - * --output /tmp/sections.json + * # Простая конвертация в Markdown + * node scripts/html-reddit-to-markdown.js source.html output.md + * + * # Конвертация с разделением на секции (JSON) + * node scripts/html-reddit-to-markdown.js source.html output.json + * + * # Продвинутое использование (извлечь определенные строки) + * node scripts/html-reddit-to-markdown.js source.html output.md --start 249 --end 1219 + * + * Формат определяется автоматически по расширению выходного файла: + * .md → чистый Markdown + * .json → JSON с секциями и метаданными */ const fs = require('fs'); @@ -23,22 +29,16 @@ const TurndownService = require('turndown'); // Настройка CLI program - .option('-i, --input ', 'Input HTML file') - .option('-s, --start ', 'Start line number', parseInt) - .option('-e, --end ', 'End line number', parseInt) - .option('-n, --sections ', 'Number of sections to split into', parseInt, 6) - .option('-o, --output ', 'Output JSON file') - .option('--markdown-only', 'Output single markdown file instead of JSON') + .argument('', 'Input HTML file') + .argument('[output]', 'Output file (.md or .json)', '/tmp/output.md') + .option('-s, --sections ', 'Number of sections to split into (only for JSON output)', parseInt, 6) + .option('--start ', 'Start line number (advanced)', parseInt) + .option('--end ', 'End line number (advanced)', parseInt) .parse(process.argv); +const [inputFile, outputFile] = program.args; const options = program.opts(); -// Валидация параметров -if (!options.input) { - console.error('Error: --input is required'); - process.exit(1); -} - /** * Извлекает строки из файла */ @@ -61,7 +61,8 @@ function parseRedditPost(html) { // Найти основной контейнер с постом // Reddit использует id формата "t3_xxxxx-post-rtjson-content" - const postContent = $('[id$="-post-rtjson-content"]'); + // Ищем элемент, который НАЧИНАЕТСЯ с "t3_" И заканчивается на "-post-rtjson-content" + const postContent = $('[id^="t3_"][id$="-post-rtjson-content"]'); if (postContent.length === 0) { // Попробовать альтернативный селектор @@ -177,11 +178,11 @@ function splitIntoSections(markdown, numSections) { */ async function main() { try { - console.log('🔍 Reading HTML file:', options.input); + console.log('🔍 Reading HTML file:', inputFile); - // Извлечь нужные строки + // Извлечь нужные строки (если указаны --start и --end) const html = extractLines( - options.input, + inputFile, options.start, options.end ); @@ -192,49 +193,50 @@ async function main() { console.log('🔄 Converting to Markdown...'); const markdown = convertToMarkdown(postHtml); - console.log('✂️ Splitting into sections...'); - const sections = splitIntoSections(markdown, options.sections); + // Определить формат вывода по расширению файла + const isMarkdownOutput = outputFile.endsWith('.md'); - console.log(`✅ Created ${sections.length} sections:`); - sections.forEach(s => { - console.log(` Section ${s.number}: "${s.title}" (${s.headerCount} headers)`); - }); - - // Вывод результата - if (options.markdownOnly) { - const outputPath = options.output || '/tmp/output.md'; - fs.writeFileSync(outputPath, markdown, 'utf-8'); - console.log(`\n💾 Saved markdown to: ${outputPath}`); + if (isMarkdownOutput) { + // Простой вывод в Markdown + fs.writeFileSync(outputFile, markdown, 'utf-8'); + console.log(`\n✅ Markdown saved to: ${outputFile}`); + console.log(`📊 Size: ${(markdown.length / 1024).toFixed(1)} KB`); } else { + // Вывод в JSON с секциями + console.log('✂️ Splitting into sections...'); + const sections = splitIntoSections(markdown, options.sections); + + console.log(`✅ Created ${sections.length} sections:`); + sections.forEach(s => { + console.log(` Section ${s.number}: "${s.title}" (${s.headerCount} headers)`); + }); + const result = { metadata: { - inputFile: options.input, + inputFile: inputFile, totalSections: sections.length, extractedLines: options.start && options.end ? `${options.start}-${options.end}` - : 'all', + : 'auto-detected', generatedAt: new Date().toISOString() }, + fullMarkdown: markdown, sections: sections }; - if (options.output) { - fs.writeFileSync( - options.output, - JSON.stringify(result, null, 2), - 'utf-8' - ); - console.log(`\n💾 Saved JSON to: ${options.output}`); - } else { - console.log('\n📄 JSON Output:'); - console.log(JSON.stringify(result, null, 2)); - } + fs.writeFileSync( + outputFile, + JSON.stringify(result, null, 2), + 'utf-8' + ); + console.log(`\n✅ JSON saved to: ${outputFile}`); } console.log('\n✨ Done!'); } catch (error) { console.error('❌ Error:', error.message); + console.error('\nStack trace:', error.stack); process.exit(1); } }