/gi, "\n" ) .replace( /<\/p>/gi, "\n" ) .replace( /<[^>]+>/g, "" ) .replace( / | /gi, " " ) .replace( /&/gi, "&" ) .replace( /"/gi, '"' ) .replace( /'|'/gi, "'" ) .replace( /([0-9a-f]+);/gi, (_, n) => String.fromCodePoint( parseInt( n, 16 ) ) ) .replace( /(\d+);/g, (_, n) => String.fromCodePoint( Number(n) ) ) .replace( /\r/g, "" ) .replace( /[ \t]+\n/g, "\n" ) .replace( /\n{3,}/g, "\n\n" ) .trim(); } function parseForumDate(text) { const match = text.match( /(\d{1,2})\.(\d{1,2})\.(\d{4})\s+(\d{1,2}):(\d{2})/ ); if (!match) { return null; } return new Date( +match[3], +match[2] - 1, +match[1], +match[4], +match[5], 0, 0 ).getTime(); } function freshnessLabel(text) { const publishedAt = parseForumDate(text); if (publishedAt == null) { return "AKTUÁLNÍ"; } const minutes = Math.max( 0, Math.floor( ( Date.now() - publishedAt ) / 60000 ) ); if (minutes < 30) { return "ČERSTVÉ"; } if (minutes < 360) { return "LOVÍ SE"; } if (minutes < 1440) { return "DNES"; } return "AKTUÁLNÍ"; } function extractThreadTitle(html) { const h1 = ( html.match( /
]*>([\s\S]*?)<\/h1>/i
) || []
)[1];
if (h1) {
return htmlToText(
h1
).trim();
}
const title =
(
html.match(
/\s*([\s\S]*?)\s*<\/title>/i
) || []
)[1];
if (!title) {
return null;
}
return title
.replace(
/\s*-\s*Diskuse[\s\S]*$/i,
""
)
.trim();
}
function esc(s) {
return String(s)
.replace(
/&/g,
"&"
)
.replace(
//g,
">"
)
.replace(
/"/g,
"""
);
}
function renderHtml(data) {
const comment =
esc(data.comment)
.replace(
/\n/g,
"
"
);
const published =
data.publishedAt == null
? "null"
: String(
data.publishedAt
);
const deadline =
data.deadlineAt == null
? "null"
: String(
data.deadlineAt
);
return `
BIKE-FORUM.CZ
${esc(data.threadTitle)}
${esc(data.freshness)}
Aktuální zadání
${esc(data.topic)}
${esc(data.exactDate)}
Od zveřejnění
—
Do konce 14denní lhůty
—
Celý komentář
${comment}
prohlížeč:
${esc(data.browserName)}
Změnit prohlížeč
`;
}
" ); const published = data.publishedAt == null ? "null" : String( data.publishedAt ); const deadline = data.deadlineAt == null ? "null" : String( data.deadlineAt ); return `