#!/usr/bin/env node // Generates CSS scroll-snap Web Stories for each published article. // Output: dist/stories/{slug}/index.html // Zero-CDN: inline CSS only, uses local OG images and local fonts. import { existsSync, mkdirSync, writeFileSync } from 'node:fs'; import { resolve } from 'node:path'; import { TeknavData } from '../teknav-data.js'; const SITE_URL = (process.env.TEKNAV_SITE_URL || process.env.VITE_SITE_URL || 'https://www.teknav.ir').replace(/\/$/, ''); const today = new Date().toISOString().slice(0, 10); function esc(value) { return String(value ?? '') .replace(/&/g, '&') .replace(/"/g, '"') .replace(//g, '>'); } function clean(value) { return String(value ?? '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim(); } function truncate(value, max) { const text = clean(value); return text.length > max ? `${text.slice(0, max - 1).trim()}…` : text; } function isPastOrTodayDate(date) { const value = String(date ?? '').slice(0, 10); return /^\d{4}-\d{2}-\d{2}$/.test(value) && value <= today; } function isPublishedArticle(article) { if (article.status === 'منتشرشده') return true; if (article.status === 'پیشنویس' || article.status === 'در انتظار بررسی') return false; if (['rust-systems', 'venture-capital-ai'].includes(article.slug)) return false; return !!article.dateEn; } function extractSlides(article) { const content = String(article.content || ''); const slides = []; // Lead paragraph const leadMatch = content.match(/
]*class="lead"[^>]*>([\s\S]*?)<\/p>/i) || content.match(/
([\s\S]*?)<\/p>/i); const lead = leadMatch ? truncate(clean(leadMatch[1]), 220) : truncate(article.summary || '', 220); if (lead) slides.push({ type: 'lead', text: lead }); // h2 headings + the text right after them const h2Pattern = /
${esc(s.text)}
`, slideNum++, totalSlides)); } else { slides.push(slide(`slide-${slideNum}`, ogImage, `${esc(s.body)}
` : ''}`, slideNum++, totalSlides)); } } // CTA slide slides.push(slide('cta', ogImage, ` `, slideNum++, totalSlides)); const jsonLd = JSON.stringify({ '@context': 'https://schema.org', '@graph': [ { '@type': ['Organization', 'NewsMediaOrganization'], '@id': `${SITE_URL}/#organization`, name: 'تکناو', url: SITE_URL, logo: { '@type': 'ImageObject', url: `${SITE_URL}/favicon.png` }, }, { '@type': ['NewsArticle', 'TechArticle'], headline: clean(article.title).slice(0, 110), description: clean(article.metaDescription || article.summary || '').slice(0, 160), image: `${SITE_URL}${ogImage}`, datePublished: article.dateEn, author: { '@type': 'Person', name: article.authorName || 'تکناو' }, publisher: { '@id': `${SITE_URL}/#organization` }, mainEntityOfPage: { '@type': 'WebPage', '@id': canonical }, url: storyUrl, }, ], }); return `