diff --git a/wechat-daily-news-inline.mjs b/wechat-daily-news-inline.mjs index 9642b0d..a931518 100644 --- a/wechat-daily-news-inline.mjs +++ b/wechat-daily-news-inline.mjs @@ -181,6 +181,18 @@ function extractClassDivBlocks(parentHtml, classPrefix) { return blocks; } +function extractHistoryItemBlocks(parentHtml) { + const source = String(parentHtml ?? ''); + const blocks = []; + const re = /<(?:div|li)\s+class="history-item[^"]*"[^>]*>[\s\S]*?<\/(?:div|li)>/gi; + let match = re.exec(source); + while (match) { + blocks.push(match[0]); + match = re.exec(source); + } + return blocks; +} + function isNews002Html(html) { const source = String(html ?? ''); if (/\bclass="[^"]*\bmasthead\b/u.test(source)) return true; @@ -608,6 +620,28 @@ function renderWeatherSection(sectionHtml, { sectionId = 'weather', maxDetailCha return parts.filter(Boolean).join(''); } +function renderHistorySection(sectionHtml, { maxItems = 3, maxBodyChars = 72 } = {}) { + const title = extractInnerHtml(sectionHtml, /
]*>([\s\S]*?)<\/div>/i); + const items = extractHistoryItemBlocks(sectionHtml) + .slice(0, maxItems) + .map((item) => { + const year = stripInlineText(extractInnerHtml(item, /]*>([\s\S]*?)<\/span>/i)); + const event = truncatePlainText( + stripInlineText(extractInnerHtml(item, /]*>([\s\S]*?)<\/span>/i)), + maxBodyChars, + ); + if (!year || !event) return ''; + return [ + `
`, + `

${year} · ${event}

`, + '
', + ].join(''); + }) + .filter(Boolean); + if (items.length === 0) return ''; + return [renderSectionTitle(title, 'history'), ...items].join(''); +} + function renderKnowledgeSection(sectionHtml, { maxItems = 4, maxBodyChars = 130 } = {}) { const title = extractInnerHtml(sectionHtml, /
]*>([\s\S]*?)<\/div>/i); const items = extractClassDivBlocks(sectionHtml, 'knowledge-item') @@ -767,7 +801,7 @@ const DEFAULT_CARD_BODY_CHARS = 132; const MIN_CARDS_TO_KEEP = 16; const BASE_TRIM_FLAGS = Object.freeze({ - skipHistory: true, + skipHistory: false, skipKnowledge: false, skipWeather: false, skipQuickLinks: true, @@ -870,10 +904,12 @@ function resolveSectionCardLimit(section, sectionCardLimits) { function shouldSkipSection(section, trimProfile) { if (!section) return true; if (section.id === 'hot') return true; - if (section.id === 'history') return true; + if (section.id === 'history') return trimProfile?.skipHistory === true; if (section.id === 'knowledge' && trimProfile?.skipKnowledge === true) return true; if (trimProfile?.skipSectionIds?.includes(section.id)) return true; - return /历史上的今天|近7天新闻早报/u.test(section.title); + if (/近7天新闻早报/u.test(section.title)) return true; + if (/历史上的今天/u.test(section.title) && trimProfile?.skipHistory !== false) return true; + return false; } function renderPageFooter(html) { @@ -1006,6 +1042,15 @@ function buildWechatInlineContent(html, { continue; } + if (section.id === 'history') { + const rendered = renderHistorySection(section.html); + if (rendered) { + contentParts.push(rendered); + renderedSectionCount += 1; + } + continue; + } + if (section.id === 'knowledge') { const rendered = renderKnowledgeSection(section.html, { maxItems: resolveSectionCardLimit(section, trimProfile.sectionCardLimits) ?? 4, @@ -1228,6 +1273,7 @@ export const wechatDailyNewsInlineInternals = { renderTodayDigest, renderBriefStats, renderWeatherSection, + renderHistorySection, selectTouristWeatherCards, isPopularTouristCityName, renderKnowledgeSection, diff --git a/wechat-daily-news-inline.test.mjs b/wechat-daily-news-inline.test.mjs index b6a98e7..9b51645 100644 --- a/wechat-daily-news-inline.test.mjs +++ b/wechat-daily-news-inline.test.mjs @@ -91,6 +91,49 @@ test('buildWechatInlineContent renders weather and optional quick links', () => assert.match(built.content, /30°/u); }); +const HISTORY_HTML = `
+

📰 每日新闻早报

+
要闻

头条

正文

+
+
📜 历史上的今天 · 9月24日
+
    +
  1. 1949年中国人民政治协商会议第一届全体会议开幕。
  2. +
  3. 1957年美国小石城中央高中发生种族融合冲突。
  4. +
  5. 1996年《全面禁止核试验条约》在联合国开放签署。
  6. +
  7. 2008年神舟七号载人飞船成功发射。
  8. +
+
+
`; + +test('renderHistorySection renders up to three compact history items', () => { + const sections = wechatDailyNewsInlineInternals.splitSections(HISTORY_HTML); + const history = sections.find((item) => item.id === 'history'); + const rendered = wechatDailyNewsInlineInternals.renderHistorySection(history.html); + assert.match(rendered, /历史上的今天 · 9月24日/u); + assert.match(rendered, /1949年/u); + assert.match(rendered, /1957年/u); + assert.match(rendered, /1996年/u); + assert.doesNotMatch(rendered, /2008年/u); + assert.match(rendered, /中国人民政治协商会议/u); +}); + +test('buildWechatInlineContent includes history snippet by default', () => { + const built = wechatDailyNewsInlineInternals.buildWechatInlineContent(HISTORY_HTML, { + includeFixedLayout: false, + }); + assert.match(built.content, /历史上的今天 · 9月24日/u); + assert.match(built.content, /1949年/u); + assert.doesNotMatch(built.content, /2008年/u); +}); + +test('buildWechatInlineContent can skip history when trimProfile requests it', () => { + const built = wechatDailyNewsInlineInternals.buildWechatInlineContent(HISTORY_HTML, { + includeFixedLayout: false, + trimProfile: { skipHistory: true }, + }); + assert.doesNotMatch(built.content, /历史上的今天/u); +}); + test('convertDailyNewsHtmlToWechatInlineArticle keeps weather when trimming', () => { const article = convertDailyNewsHtmlToWechatInlineArticle(WEATHER_HTML, { includeFixedLayout: false,