Module:PageSummary:修订间差异
武外梗百科 爱国好学自强图新的百科全书
更多操作
无编辑摘要 |
无编辑摘要 |
||
| 第1行: | 第1行: | ||
local p = {} | local p = {} | ||
-- stripImages | -- ──────────────────────────────────────────────── | ||
-- 剥离图片、分类等 [[File:…]] [[Category:…]] 结构,避免出现在摘要中 | |||
-- ──────────────────────────────────────────────── | |||
local function stripImages(text) | |||
if not text or text == "" then return "" end | |||
-- 统一常见命名空间写法,减少匹配分支 | |||
text = text:gsub("%[%[(文件|File|Image|图像):", "[[File:") | |||
:gsub("%[%[(分类|Category):", "[[Category:") | |||
local out = {} | |||
local i = 1 | |||
local len = #text | |||
while i <= len do | |||
if text:byte(i) == 91 and text:byte(i+1) == 91 then -- [[ | |||
local chunk = text:sub(i, i+15) | |||
if chunk:match("^%[%[File:") or chunk:match("^%[%[Category:") then | |||
-- 跳过整段嵌套链接 [[ ... ]] | |||
local depth = 1 | |||
local j = i + 2 | |||
while j <= len and depth > 0 do | |||
if text:byte(j) == 91 and text:byte(j+1) == 91 then | |||
depth = depth + 1 | |||
j = j + 2 | |||
elseif text:byte(j) == 93 and text:byte(j+1) == 93 then | |||
depth = depth - 1 | |||
j = j + 2 | |||
else | |||
j = j + 1 | |||
end | |||
end | |||
i = j -- 跳到 ]] 之后或文本末尾 | |||
else | |||
-- 普通内部链接,保留 | |||
table.insert(out, "[[") | |||
i = i + 2 | |||
end | |||
else | |||
table.insert(out, text:sub(i,i)) | |||
i = i + 1 | |||
end | |||
if i > 1200 then break end -- 极端安全阀 | |||
end | |||
return table.concat(out) | |||
end | |||
-- cleanFinal | -- ──────────────────────────────────────────────── | ||
-- 清理模板、参考文献、标题、列表等,得到纯文本摘要 | |||
-- ──────────────────────────────────────────────── | |||
local function cleanFinal(text) | |||
if not text or text == "" then return "" end | |||
text = text | |||
:gsub("{{[^{}]*}}", "") -- 模板(简单版,够用) | |||
:gsub("<ref.-</?ref[^>]*>", "") -- 参考文献 | |||
:gsub("<!%-%-.-%-%->", "") -- HTML 注释 | |||
:gsub("\n==+[^=]+==+", " ") -- 各级标题 | |||
:gsub("\n%s*[*#:;]+", " ") -- 列表、定义列表 | |||
:gsub("%s*\n%s*", " ") -- 所有换行 → 单个空格 | |||
:gsub("%s+", " ") -- 压缩连续空格 | |||
return mw.text.trim(text) | |||
end | |||
-- ──────────────────────────────────────────────── | |||
-- 主函数:生成带首图的简短摘要 + 标题 | |||
-- ──────────────────────────────────────────────── | |||
function p.getSummaryAndImage(frame) | function p.getSummaryAndImage(frame) | ||
local pageName = mw.text.trim(frame.args[1] or "") | local pageName = mw.text.trim(frame.args[1] or "") | ||
| 第15行: | 第81行: | ||
if not content or content == "" then return "" end | if not content or content == "" then return "" end | ||
-- | -- 安全取前 300 个 unicode 字符(避免字节截断中文) | ||
local rawExcerpt = mw.ustring.sub(content, 1, 300) | local rawExcerpt = mw.ustring.sub(content, 1, 300) | ||
-- | -- 提取第一张图片(优先标准写法) | ||
local | local firstImage = mw.ustring.match(rawExcerpt, "%[%[(File|文件|Image|图像):([^|%]]+)") | ||
-- | -- 备选:更宽松匹配,但只接受文件类 | ||
if not firstImage then | if not firstImage then | ||
local candidate = mw.ustring.match(rawExcerpt, "%[%[([^|%]]+)%]") | |||
if | if candidate then | ||
local ns = candidate:match("^([^:]+):") | |||
if ns and (ns:lower() == "file" or ns == "文件" or ns:lower() == "image" or ns == "图像") then | |||
firstImage = candidate | |||
end | |||
end | end | ||
end | end | ||
| 第36行: | 第102行: | ||
local targetLen = 120 | local targetLen = 120 | ||
local summary = cleanText:sub(1, targetLen * 2) or "" | local summary = cleanText:sub(1, targetLen * 2) or "" | ||
local ulen = mw.ustring.len(summary) or 0 | local ulen = mw.ustring.len(summary) or 0 | ||
| 第42行: | 第108行: | ||
summary = mw.ustring.sub(summary, 1, targetLen) or "" | summary = mw.ustring.sub(summary, 1, targetLen) or "" | ||
-- 尽量避免截在中文单词/句子中间 | |||
local rev = summary:reverse() | local rev = summary:reverse() | ||
local lastBreak = rev:find("[ %s%p,。!?;:]") or 1 | local lastBreak = rev:find("[ %s%p,。!?;:,…]") or 1 | ||
if lastBreak > 1 and lastBreak < 20 then | if lastBreak > 1 and lastBreak < 20 then | ||
summary = mw.ustring.sub(summary, 1, #summary - lastBreak + 1) or "" | summary = mw.ustring.sub(summary, 1, #summary - lastBreak + 1) or "" | ||
| 第53行: | 第120行: | ||
summary = mw.text.trim(summary) | summary = mw.text.trim(summary) | ||
-- HTML | -- ── HTML 输出 ─────────────────────────────────── | ||
local container = mw.html.create('div') | local container = mw.html.create('div') | ||
:css('margin-bottom', '25px') | :css('margin-bottom', '25px') | ||
:css('display', 'flow-root') | :css('display', 'flow-root') | ||
-- 标题 | |||
container:tag('div') | container:tag('div') | ||
:css('font-size', '1.3em') | :css('font-size', '1.3em') | ||
| 第65行: | 第133行: | ||
:wikitext('[[' .. pageName .. ']]') | :wikitext('[[' .. pageName .. ']]') | ||
-- 内容区(右浮图 + 文字) | |||
local textDiv = container:tag('div') | local textDiv = container:tag('div') | ||
:css('line-height', '1.6') | :css('line-height', '1.6') | ||
| 第70行: | 第139行: | ||
:css('font-size', '14px') | :css('font-size', '14px') | ||
if firstImage and firstImage ~= "" then | if firstImage and firstImage ~= "" then | ||
firstImage = mw.text.trim(firstImage) | firstImage = mw.text.trim(firstImage) | ||
local img = '[[' .. firstImage .. '|120px|right|link=' .. pageName .. ']]' | |||
textDiv:wikitext(img) | |||
local | |||
textDiv:wikitext( | |||
end | end | ||