Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | /** * Script to replace "The Economist" branding references in old news articles * with OSINT/INTOP political intelligence branding across all 14 languages. * * Usage: npx tsx scripts/fix-old-articles-branding.ts [--dry-run] * * Replaces: * - site-tagline div content (language-specific from SITE_TAGLINE constants) * - "style: The Economist" in HTML comment frontmatter * - "The Economist" references in article body/disclaimers * - "Journalism Standards" footer text * * Preserves: * - External links to economist.com (legitimate references) */ import * as fs from 'fs'; import * as path from 'path'; // New taglines from scripts/article-template/constants.ts const SITE_TAGLINE: Record<string, string> = { en: "Latest news and analysis from Sweden's Riksdag. AI-generated political intelligence based on OSINT/INTOP data covering parliament, government, and agencies with systematic transparency.", sv: 'Senaste nyheter och analyser från Sveriges riksdag. AI-genererad politisk underrättelsejournalistik baserad på OSINT/INTOP-data som bevakar riksdagen, regeringen och myndigheter med systematisk transparens.', da: 'Seneste nyheder og analyser fra Sveriges Riksdag. AI-genereret politisk efterretningsjournalistik baseret på OSINT/INTOP-data, der dækker parlament, regering og myndigheder med systematisk gennemsigtighed.', no: 'Siste nyheter og analyser fra Sveriges riksdag. AI-generert politisk etterretningsjournalistikk basert på OSINT/INTOP-data som dekker parlament, regjering og myndigheter med systematisk åpenhet.', fi: 'Uusimmat uutiset ja analyysit Ruotsin valtiopäiviltä. Tekoälyn tuottama poliittinen tiedustelujournalismi OSINT/INTOP-dataan perustuen, joka kattaa eduskunnan, hallituksen ja viranomaiset järjestelmällisellä läpinäkyvyydellä.', de: 'Aktuelle Nachrichten und Analysen aus dem schwedischen Riksdag. KI-generierter politischer Nachrichtendienst-Journalismus basierend auf OSINT/INTOP-Daten über Parlament, Regierung und Behörden mit systematischer Transparenz.', fr: 'Dernières nouvelles et analyses du Riksdag suédois. Journalisme de renseignement politique généré par IA basé sur des données OSINT/INTOP couvrant le parlement, le gouvernement et les agences avec une transparence systématique.', es: 'Últimas noticias y análisis del Riksdag sueco. Periodismo de inteligencia política generado por IA basado en datos OSINT/INTOP que cubre el parlamento, el gobierno y las agencias con transparencia sistemática.', nl: 'Laatste nieuws en analyses van de Zweedse Riksdag. AI-gegenereerde politieke inlichtingenjournalistiek gebaseerd op OSINT/INTOP-data over parlement, regering en instanties met systematische transparantie.', ar: 'أحدث الأخبار والتحليلات من البرلمان السويدي. صحافة استخبارات سياسية مولّدة بالذكاء الاصطناعي مبنية على بيانات OSINT/INTOP تغطي البرلمان والحكومة والوكالات بشفافية منهجية.', he: 'חדשות ניתוחים אחרונים מהריקסדאג השוודי. עיתונות מודיעין פוליטי מבוססת AI ונתוני OSINT/INTOP המכסה פרלמנט, ממשלה וסוכנויות עם שקיפות שיטתית.', ja: 'スウェーデン議会リクスダーグの最新ニュースと分析。OSINT/INTOPデータに基づくAI生成の政治インテリジェンスジャーナリズムで、議会、政府、機関を体系的な透明性で報道。', ko: '스웨덴 의회 릭스다그의 최신 뉴스와 분석. OSINT/INTOP 데이터 기반 AI 생성 정치 인텔리전스 저널리즘으로 의회, 정부, 기관을 체계적인 투명성으로 보도.', zh: '来自瑞典议会的最新新闻和分析。基于OSINT/INTOP数据的AI生成政治情报新闻,以系统性透明度报道议会、政府和机构。', }; const NEWS_DIR = path.join(process.cwd(), 'news'); const dryRun = process.argv.includes('--dry-run'); function getLanguageFromFilename(filename: string): string | null { const match = filename.match(/-([a-z]{2})\.html$/); return match ? match[1] : null; } function replaceTagline(html: string, lang: string): string { const tagline = SITE_TAGLINE[lang]; if (!tagline) return html; // Replace site-tagline div content return html.replace( /(<div class="site-tagline">)([^<]*?)(<\/div>)/g, `$1${tagline}$3` ); } function replaceEconomistReferences(html: string): string { let result = html; // 1. Replace "style: The Economist" in HTML comment frontmatter result = result.replace(/style: The Economist\b/g, 'style: OSINT/INTOP'); // 2. Replace "Journalism Standards" footer patterns (en + sv) result = result.replace( /Journalism Standards<\/strong>: The Economist style/g, 'Journalism Standards</strong>: OSINT/INTOP data-driven AI-generated political intelligence' ); result = result.replace( /Journalistiska standarder<\/strong>: The Economist-stil/g, 'Journalistiska standarder</strong>: OSINT/INTOP-datadriven AI-genererad politisk underrättelsejournalistik' ); // 3. Skip lines containing economist.com URLs (legitimate external references) // Process line by line to preserve external links const lines = result.split('\n'); const processedLines = lines.map(line => { // Skip lines with economist.com URLs (legitimate external reference links) if (/href=["'][^"']*economist\.com/.test(line)) return line; // Replace "The Economist" patterns not already handled // Various editorial standards patterns line = line.replace(/following The Economist editorial standards/g, 'following OSINT/INTOP editorial standards'); line = line.replace(/enligt The Economist-standarder/g, 'enligt OSINT/INTOP-standarder'); line = line.replace(/enligt The Economists redaktionella standard/g, 'enligt OSINT/INTOP redaktionella standard'); line = line.replace(/i enlighet med The Economists redaktionella standard/g, 'i enlighet med OSINT/INTOP redaktionella standard'); line = line.replace(/in The Economist style/g, 'in OSINT/INTOP style'); line = line.replace(/i The Economist-stil/g, 'i OSINT/INTOP-stil'); // English patterns line = line.replace(/The Economist-style analysis/g, 'OSINT/INTOP data-driven analysis'); line = line.replace(/The Economist-style political journalism emphasizing/g, 'OSINT/INTOP data-driven AI-generated political intelligence emphasizing'); line = line.replace(/The Economist-style political journalism/g, 'OSINT/INTOP data-driven political journalism'); line = line.replace(/The Economist-style/g, 'OSINT/INTOP data-driven'); // Generic "The Economist" that references the brand, not external links // Replace remaining "The Economist" in article contexts (not in <a> tags) // Use negative lookahead to avoid replacing inside link text to economist.com line = line.replace(/The Economist noted in its/g, 'As noted in a'); // Swedish patterns line = line.replace(/The Economist-inspirerad/g, 'OSINT/INTOP-baserad'); // Danish patterns line = line.replace(/The Economist-inspireret/g, 'OSINT/INTOP-baseret'); // Norwegian patterns line = line.replace(/The Economist-inspirert/g, 'OSINT/INTOP-basert'); // Generic suffix patterns across Scandinavian languages line = line.replace(/The Economist-stil\b/g, 'OSINT/INTOP-stil'); // Dutch line = line.replace(/The Economist-stijl\b/g, 'OSINT/INTOP-stijl'); // German (with and without "The ") line = line.replace(/The Economist-Stil\b/g, 'OSINT/INTOP-Stil'); line = line.replace(/im Economist-Stil\b/g, 'im OSINT/INTOP-Stil'); line = line.replace(/Economist-Stil\b/g, 'OSINT/INTOP-Stil'); // Dutch (without "The " prefix) line = line.replace(/in Economist-stijl\b/g, 'in OSINT/INTOP-stijl'); line = line.replace(/Economist-stijl\b/g, 'OSINT/INTOP-stijl'); // Finnish (note the space before the hyphen) line = line.replace(/The Economist -tyylinen/g, 'OSINT/INTOP -tyylinen'); line = line.replace(/The Economist -tyyliin/g, 'OSINT/INTOP -tyyliin'); line = line.replace(/The Economist-tyylinen/g, 'OSINT/INTOP-tyylinen'); // French line = line.replace(/style The Economist\b/g, 'style OSINT/INTOP'); line = line.replace(/The Economist couvrant/g, 'OSINT/INTOP couvrant'); line = line.replace(/The Economist avec/g, 'OSINT/INTOP avec'); // Spanish line = line.replace(/estilo The Economist\b/g, 'estilo OSINT/INTOP'); line = line.replace(/The Economist que cubre/g, 'OSINT/INTOP que cubre'); line = line.replace(/The Economist cubriendo/g, 'OSINT/INTOP cubriendo'); line = line.replace(/The Economist sobre/g, 'OSINT/INTOP sobre'); line = line.replace(/The Economist con/g, 'OSINT/INTOP con'); // Dutch additional line = line.replace(/The Economist over/g, 'OSINT/INTOP over'); line = line.replace(/The Economist met/g, 'OSINT/INTOP met'); line = line.replace(/The Economist politieke/g, 'OSINT/INTOP politieke'); // German additional line = line.replace(/The Economist mit/g, 'OSINT/INTOP mit'); line = line.replace(/The Economist zu /g, 'OSINT/INTOP zu '); line = line.replace(/The Economist über/g, 'OSINT/INTOP über'); // Hebrew line = line.replace(/The Economist המכסה/g, 'OSINT/INTOP המכסה'); line = line.replace(/The Economist עם/g, 'OSINT/INTOP עם'); // Arabic line = line.replace(/The Economist تغطي/g, 'OSINT/INTOP تغطي'); // Japanese line = line.replace(/The Economist スタイル/g, 'OSINT/INTOP スタイル'); // Chinese line = line.replace(/The Economist 风格/g, 'OSINT/INTOP 风格'); line = line.replace(/The Economist风格/g, 'OSINT/INTOP風格'); // Korean line = line.replace(/The Economist 스타일/g, 'OSINT/INTOP 스타일'); // Catch remaining "The Economist." and "The Economist," sentence endings // But not "The Economist:" (which is a reference title) line = line.replace(/The Economist\./g, 'OSINT/INTOP.'); line = line.replace(/The Economist,/g, 'OSINT/INTOP,'); // HTML entity versions line = line.replace(/The Economist-stil som täcker/g, 'OSINT/INTOP-stil som täcker'); line = line.replace(/The Economist-stil som dekker riksdag, regjering og myndigheter med systematisk åpenhet/g, 'OSINT/INTOP-stil som dekker riksdag, regjering og myndigheter med systematisk åpenhet'); line = line.replace(/The Economist-stil der dækker/g, 'OSINT/INTOP-stil der dækker'); line = line.replace(/The Economist couvrant le parlement, le gouvernement et les agences avec une transparence systématique/g, 'OSINT/INTOP couvrant le parlement, le gouvernement et les agences avec une transparence systématique'); line = line.replace(/The Economist cubriendo parlamento, gobierno y agencias con transparencia sistemática/g, 'OSINT/INTOP cubriendo parlamento, gobierno y agencias con transparencia sistemática'); line = line.replace(/The Economist -tyylin poliittista journalismia, joka kattaa parlamentin, hallituksen ja virastot systemaattisella läpinäkyvyydellä/g, 'OSINT/INTOP -tyylin poliittista journalismia, joka kattaa parlamentin, hallituksen ja virastot systemaattisella läpinäkyvyydellä'); return line; }); return processedLines.join('\n'); } function processFile(filepath: string): boolean { const filename = path.basename(filepath); const lang = getLanguageFromFilename(filename); if (!lang) { console.warn(` ⚠️ Could not determine language for: ${filename}`); return false; } const original = fs.readFileSync(filepath, 'utf-8'); // Check if file contains any Economist references if (!original.includes('Economist')) { return false; } let modified = original; // Replace site-tagline modified = replaceTagline(modified, lang); // Replace other Economist references modified = replaceEconomistReferences(modified); if (modified === original) { return false; } if (!dryRun) { fs.writeFileSync(filepath, modified, 'utf-8'); } return true; } // Main execution console.log(`🔄 Fixing old articles branding (${dryRun ? 'DRY RUN' : 'LIVE'})...\n`); const files = fs.readdirSync(NEWS_DIR) .filter(f => f.endsWith('.html')) .sort(); let modified = 0; let skipped = 0; const langStats: Record<string, number> = {}; for (const file of files) { const filepath = path.join(NEWS_DIR, file); const lang = getLanguageFromFilename(file); if (processFile(filepath)) { modified++; if (lang) { langStats[lang] = (langStats[lang] || 0) + 1; } if (dryRun) { console.log(` 📝 Would modify: ${file}`); } } else { skipped++; } } console.log(`\n✅ Done!`); console.log(` Modified: ${modified} files`); console.log(` Skipped: ${skipped} files (no changes needed)`); console.log(`\n📊 Changes by language:`); for (const [lang, count] of Object.entries(langStats).sort()) { console.log(` ${lang}: ${count} files`); } // Verify no remaining Economist references (except legitimate external links) console.log(`\n🔍 Checking for remaining "Economist" references...`); let remaining = 0; for (const file of files) { const filepath = path.join(NEWS_DIR, file); const content = dryRun ? fs.readFileSync(filepath, 'utf-8') : fs.readFileSync(filepath, 'utf-8'); // Split into lines and check each const lines = content.split('\n'); for (let i = 0; i < lines.length; i++) { if (lines[i].includes('Economist') && !/href=["'][^"']*economist\.com/.test(lines[i])) { remaining++; if (remaining <= 20) { console.log(` ⚠️ ${file}:${i + 1}: ${lines[i].trim().substring(0, 120)}`); } } } } if (remaining > 20) { console.log(` ... and ${remaining - 20} more`); } if (remaining === 0) { console.log(' ✅ No remaining references (except legitimate external links)'); } else { console.log(`\n ⚠️ ${remaining} remaining references found`); } |