This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import articles from '../data/articles.json' with { type: 'json' };
|
||||
import { agentRewriteRevisions } from '../data/agent-rewrite-revisions.mjs';
|
||||
|
||||
const archiveBySlug = new Map(articles.map((article) => [article.slug, article]));
|
||||
const forbidden = [
|
||||
/synthetic-plan-hand-off/i,
|
||||
/productionEffect/i,
|
||||
/future-only/i,
|
||||
/plan\/scenario/i,
|
||||
/source cutoff/i,
|
||||
/editorial date/i,
|
||||
/planDate/i,
|
||||
/not-collected/i,
|
||||
/not-attempted/i,
|
||||
/future owner/i,
|
||||
/author trajectory/i,
|
||||
/развитие автора/i,
|
||||
/План на \d{4}/i,
|
||||
];
|
||||
|
||||
function bodyWithoutSources(content) {
|
||||
return content
|
||||
.replace(/<h2>Проверяемые источники<\/h2>[\s\S]*$/, '')
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/&(?:quot|amp|lt|gt|#039);/g, ' ')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
const failures = [];
|
||||
const seen = new Set();
|
||||
|
||||
for (const revision of agentRewriteRevisions) {
|
||||
const body = bodyWithoutSources(revision.contentHtml || '');
|
||||
const issues = [];
|
||||
if (!archiveBySlug.has(revision.slug)) issues.push('slug отсутствует в архиве');
|
||||
if (seen.has(revision.slug)) issues.push('дубликат slug');
|
||||
seen.add(revision.slug);
|
||||
if (!revision.title || !revision.excerpt) issues.push('нет title/excerpt');
|
||||
if (body.length < 5000 || body.length > 15000) issues.push('основной текст вне 5 000–15 000 знаков');
|
||||
if (!/<figure>[\s\S]*?<img\b[^>]+alt=(?:"[^"<>]+"|'[^'<>]+')[\s\S]*?<\/figure>/.test(revision.contentHtml)) issues.push('нет figure с alt');
|
||||
if (!/<table>[\s\S]*?<\/table>/.test(revision.contentHtml)) issues.push('нет table');
|
||||
if (!/<pre><code>[\s\S]*?<\/code><\/pre>/.test(revision.contentHtml)) issues.push('нет pre/code');
|
||||
if (!/<ol>[\s\S]*?<\/ol>/.test(revision.contentHtml)) issues.push('нет ol');
|
||||
if (!/<h2>Проверяемые источники<\/h2>[\s\S]*?https?:\/\//.test(revision.contentHtml)) issues.push('нет проверяемого источника');
|
||||
const meta = forbidden.find((pattern) => pattern.test(body));
|
||||
if (meta) issues.push('мета-лексика: ' + meta);
|
||||
if (issues.length) failures.push({ index: revision.index, slug: revision.slug, issues });
|
||||
}
|
||||
|
||||
const report = {
|
||||
drafts: agentRewriteRevisions.length,
|
||||
uniqueSlugs: seen.size,
|
||||
failures,
|
||||
nextExpectedIndex: articles.findIndex((article) => !seen.has(article.slug)) + 1 || null,
|
||||
};
|
||||
console.log(JSON.stringify(report, null, 2));
|
||||
if (failures.length) process.exitCode = 1;
|
||||
@@ -82,7 +82,7 @@ for (const slug of slugs) {
|
||||
|
||||
const content = cleanReaderHtml(article.contentHtml);
|
||||
const body = bodyText(content);
|
||||
const imageSources = [...content.matchAll(/<img[^>]+src="([^"]+)"/g)].map((match) => match[1]);
|
||||
const imageSources = [...content.matchAll(/<img[^>]+\bsrc=(['"])(.*?)\1/gi)].map((match) => match[2]);
|
||||
const figures = [...content.matchAll(/<figure>([\s\S]*?)<\/figure>/g)].map((match) => match[1]);
|
||||
|
||||
if (article.readingMinutes < 8) issues.push('указано меньше 8 минут чтения');
|
||||
@@ -98,7 +98,7 @@ for (const slug of slugs) {
|
||||
if (count(content, /<table>/g) < 1 || count(content, /<thead>/g) < 1) issues.push('нет доступной таблицы');
|
||||
if (count(content, /<pre><code>/g) < 1) issues.push('нет воспроизводимого примера');
|
||||
if (count(content, /<ol>/g) < 1) issues.push('нет последовательности проверки или действий');
|
||||
if (count(content, /<a href="https?:\/\//g) < 2) issues.push('меньше двух внешних источников');
|
||||
if (count(content, /<a\b[^>]*\bhref=(['"])https?:\/\/[^'"]+\1/gi) < 2) issues.push('меньше двух внешних источников');
|
||||
if (!content.includes('<h2>Проверяемые источники</h2>')) issues.push('нет отдельного раздела с источниками');
|
||||
const proseWithoutCode = content
|
||||
.replace(/<pre><code>[\s\S]*?<\/code><\/pre>/g, '')
|
||||
@@ -114,8 +114,8 @@ for (const slug of slugs) {
|
||||
|
||||
for (const figure of figures) {
|
||||
const image = figure.match(/<img\b[^>]*>/);
|
||||
const alt = image?.[0].match(/\balt="([^"]*)"/);
|
||||
if (!image || !alt || alt[1].trim() === '') {
|
||||
const alt = image?.[0].match(/\balt=(['"])(.*?)\1/i);
|
||||
if (!image || !alt || alt[2].trim() === '') {
|
||||
issues.push('у рисунка нет содержательного alt-текста');
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user