Some checks failed
deploy / deploy (push) Failing after 12s
- Бэкап старой версии на ветке vite-react-backup - Stack: Astro 5 + nginx:alpine runtime, образ ~50 МБ (был ~600 МБ) - @astrojs/rss заменён ручным buildRss() — гарантия CDATA в content:encoded для IPB Importer - @astrojs/sitemap → sitemap-index.xml + sitemap.txt - 152-ФЗ cookie consent + privacy.astro + Analytics с gating - AI-файлы: robots.txt с явным allow для AI-краулеров, ai.txt, llms.txt - Гибридный визуал: фото-фон шапки (аэрофото Пушкино) + PT Serif + IBM Plex Sans - Иерархия: hero "Главная история" с рамкой + "Ещё из истории" + "Хроника" - Категория "main" (псевдо) скрыта из плашек и из Рубрик в сайдбаре - hideFromList: true для технических постов - featuredImage в frontmatter для постов без хорошей первой <img> - WP resized-URL (-WxH.ext) автоматически → оригинал - CI/CD: .gitea/workflows/deploy.yml (push → SSH-build) - Внешние RSS: scripts/pull-external-rss.mjs пишет news.json в bind-mount, фронт фетчит client-side
36 lines
1.0 KiB
TypeScript
36 lines
1.0 KiB
TypeScript
/** Утилиты: извлечение превью-картинки и текстового excerpt из HTML-тела поста. */
|
|
|
|
const IMG_RE = /<img[^>]+src=["']([^"']+)["'][^>]*>/i;
|
|
const TAG_RE = /<[^>]+>/g;
|
|
const WS_RE = /\s+/g;
|
|
|
|
export function firstImage(html: string): string | null {
|
|
const m = IMG_RE.exec(html);
|
|
return m ? m[1] : null;
|
|
}
|
|
|
|
export function plainText(html: string, max = 320): string {
|
|
const txt = html
|
|
.replace(/<style[\s\S]*?<\/style>/gi, ' ')
|
|
.replace(/<script[\s\S]*?<\/script>/gi, ' ')
|
|
.replace(/<!--[\s\S]*?-->/g, ' ')
|
|
.replace(TAG_RE, ' ')
|
|
.replace(/ /g, ' ')
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(WS_RE, ' ')
|
|
.trim();
|
|
if (txt.length <= max) return txt;
|
|
return txt.slice(0, max).replace(/\s+\S*$/, '') + '…';
|
|
}
|
|
|
|
export function formatDateRu(d: Date): string {
|
|
return d.toLocaleDateString('ru-RU', {
|
|
day: 'numeric',
|
|
month: 'long',
|
|
year: 'numeric',
|
|
});
|
|
}
|