hiparquia.dog — sitio F0-lite: Astro estático, cero JS, candado del protocolo en código
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import pw from '/home/claude/.npm-global/lib/node_modules/playwright/index.js';
|
||||
import fs from 'fs';
|
||||
const { chromium } = pw;
|
||||
|
||||
/* Las tarjetas al compartir. 1200×630 es lo que leen WhatsApp, Facebook,
|
||||
Telegram y X — ninguno ejecuta JavaScript, así que la tarjeta es esta imagen
|
||||
y las etiquetas og:. Sin ella, el enlace viaja desnudo.
|
||||
(Lección de serclin.mx: el og:image ausente decide la tarjeta, no el sitio.) */
|
||||
|
||||
const TARJETAS = [
|
||||
{ archivo: 'hiparquia', palabra: 'hiparquia',
|
||||
pie: 'Cada verso con su ficha: la fuente, la edición y hasta dónde llegó el cotejo.',
|
||||
tam: 128 },
|
||||
{ archivo: 'hombres-necios', palabra: 'necios',
|
||||
pie: 'Sor Juana Inés de la Cruz · Inundación castálida, Madrid, 1689',
|
||||
tam: 172 },
|
||||
{ archivo: 'nada-te-turbe', palabra: 'nada',
|
||||
pie: 'Atribuido a Teresa de Ávila (1515–1582) · letrilla hallada en su breviario',
|
||||
tam: 172 },
|
||||
];
|
||||
|
||||
const W = 1200, H = 630;
|
||||
const b64 = fs.readFileSync('src/fuentes/Commissioner-latin.woff2').toString('base64');
|
||||
|
||||
const pagina = (T) => `<!doctype html><meta charset="utf-8"><style>
|
||||
@font-face{ font-family:Commissioner; src:url(data:font/woff2;base64,${b64}) format('woff2');
|
||||
font-weight:100 900; font-display:block; }
|
||||
*{margin:0;padding:0;box-sizing:border-box}
|
||||
html,body{width:${W}px;height:${H}px;background:#000}
|
||||
body{font-family:Commissioner;color:#fff;font-variation-settings:"FLAR" 0,"VOLM" 0;
|
||||
padding:78px;display:flex;flex-direction:column;justify-content:space-between;
|
||||
-webkit-font-smoothing:antialiased}
|
||||
.palabra{font-weight:800;font-size:${T.tam}px;line-height:1.02;letter-spacing:-0.025em;
|
||||
margin-block:auto 0}
|
||||
.pie{font-weight:300;font-size:29px;line-height:1.45;color:#a6a6a6;max-width:26em;
|
||||
margin-block-start:30px}
|
||||
</style>
|
||||
<div class="palabra">${T.palabra}</div>
|
||||
<div class="pie">${T.pie}</div>`;
|
||||
|
||||
const b = await chromium.launch({ executablePath:'/opt/pw-browsers/chromium',
|
||||
args:['--force-device-scale-factor=1','--hide-scrollbars'] });
|
||||
const p = await b.newPage({ viewport:{ width:W, height:H }, deviceScaleFactor:1 });
|
||||
fs.mkdirSync('public/og', { recursive:true });
|
||||
const out = [];
|
||||
for (const T of TARJETAS) {
|
||||
await p.setContent(pagina(T));
|
||||
await p.evaluate(()=>document.fonts.ready);
|
||||
const f = `public/og/${T.archivo}.png`;
|
||||
await p.screenshot({ path:f });
|
||||
const desborde = await p.evaluate(() => {
|
||||
const d = document.documentElement;
|
||||
return { h: d.scrollWidth - d.clientWidth, v: d.scrollHeight - d.clientHeight };
|
||||
});
|
||||
out.push({ archivo:T.archivo, bytes: fs.statSync(f).size, desborde });
|
||||
}
|
||||
await b.close();
|
||||
console.log(JSON.stringify(out, null, 1));
|
||||
Reference in New Issue
Block a user