Module:PageSummary:修订间差异
武外梗百科 爱国好学自强图新的百科全书
更多操作
无编辑摘要 |
无编辑摘要 |
||
| 第1行: | 第1行: | ||
local p = {} | local p = {} | ||
-- 更高效的图片/ | -- 更高效的图片/分类/文件链接剥离(字节级处理为主) | ||
local function stripImages(text) | local function stripImages(text) | ||
if not text or text == "" then return "" end | if not text or text == "" then return "" end | ||
-- | -- 统一常见前缀,减少分支 | ||
text = text:gsub("%[%[(文件|File|Image|图像):", "[[File:") | text = text:gsub("%[%[(文件|File|Image|图像):", "[[File:") | ||
local out = {} | local out = {} | ||
local i = 1 | local i = 1 | ||
local len = #text | local len = #text | ||
while i <= len do | while i <= len do | ||
if text:byte(i) == 91 and text:byte(i+1) == 91 then -- [[ | |||
local chunk = text:sub(i, i+12) | local chunk = text:sub(i, i+12) | ||
if chunk:match("^%[%[File:") | if chunk:match("^%[%[File:") | ||
| 第20行: | 第19行: | ||
or chunk:match("^%[%[分类:") | or chunk:match("^%[%[分类:") | ||
then | then | ||
-- | -- 跳过整段嵌套 [[...]] | ||
local depth = 1 | local depth = 1 | ||
local j = i + 2 | local j = i + 2 | ||
| 第34行: | 第33行: | ||
end | end | ||
end | end | ||
i = j | i = j -- 跳到 ]] 之后 | ||
else | else | ||
table.insert(out, "[[") | |||
table.insert(out, "[") | i = i + 2 | ||
i = i + | |||
end | end | ||
else | else | ||
| 第45行: | 第43行: | ||
end | end | ||
if i > 800 then break end -- 安全阀 | |||
if i > 800 then break end | |||
end | end | ||
| 第52行: | 第49行: | ||
end | end | ||
-- 合并清理步骤,减少重复扫描 | |||
-- | |||
local function cleanFinal(text) | local function cleanFinal(text) | ||
if not text or text == "" then return "" end | if not text or text == "" then return "" end | ||
text = text | text = text | ||
:gsub("{{[^{}]*}}", "") | :gsub("{{[^{}]*}}", "") -- 模板 | ||
:gsub("<ref.-</?ref[^>]*>", "") | :gsub("<ref.-</?ref[^>]*>", "") -- 参考文献 | ||
:gsub("<!%-%-.-%-%->", "") | :gsub("<!%-%-.-%-%->", "") -- 注释 | ||
:gsub("\n==+.+==+", " ") | :gsub("\n==+.+==+", " ") -- 标题 | ||
:gsub("\n%s*[*#:;]+", " ") | :gsub("\n%s*[*#:;]+", " ") -- 列表 | ||
:gsub("%s*\n%s*", " ") | :gsub("%s*\n%s*", " ") -- 换行转空格 | ||
:gsub("%s+", " ") | :gsub("%s+", " ") -- 压缩空格 | ||
return mw.text.trim(text) | return mw.text.trim(text) | ||
end | end | ||
function p.getSummaryAndImage(frame) | function p.getSummaryAndImage(frame) | ||
| 第79行: | 第73行: | ||
local content = title:getContent() | local content = title:getContent() | ||
if not content then return "" end | if not content or content == "" then return "" end | ||
-- | -- 只取前450字节(足够首图+摘要) | ||
local rawExcerpt = content:sub(1, 450) | local rawExcerpt = content:sub(1, 450) | ||
-- | -- 提取第一张图片(兼容多种写法) | ||
local firstImage = rawExcerpt:match("%[%[(File|文件|Image|图像):([^|%]]+)") | local firstImage = rawExcerpt:match("%[%[(File|文件|Image|图像):([^|%]]+)") | ||
local step1 = stripImages(rawExcerpt) or "" | |||
local step1 | local cleanText = cleanFinal(step1) or "" | ||
local cleanText = cleanFinal(step1) | |||
local targetLen = 120 | local targetLen = 120 | ||
local summary = cleanText:sub(1, targetLen * 2) | -- 提前多取一点,便于后续精确截断 | ||
local summary = cleanText:sub(1, targetLen * 2) or "" | |||
-- | -- 关键修复:判断前确保不是 nil | ||
local | local ulen = mw.ustring.len(summary) or 0 | ||
if | |||
summary = mw.ustring.sub(summary, 1, targetLen) | if ulen > targetLen then | ||
summary = mw.ustring.sub(summary, 1, targetLen) or "" | |||
-- | -- 尝试避免截断在单词/中文中间(简单向后找空格或标点) | ||
local | local rev = summary:reverse() | ||
if | local lastBreak = rev:find("[ %s%p,。!?;:]") or 1 | ||
summary = mw.ustring.sub(summary, 1, #summary - | if lastBreak > 1 and lastBreak < 20 then | ||
summary = mw.ustring.sub(summary, 1, #summary - lastBreak + 1) or "" | |||
end | end | ||
summary = mw.text.trim(summary) .. "..." | summary = mw.text.trim(summary) .. "..." | ||
end | end | ||
-- HTML | summary = mw.text.trim(summary) | ||
-- 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') | ||
| 第120行: | 第119行: | ||
:wikitext('[[' .. pageName .. ']]') | :wikitext('[[' .. pageName .. ']]') | ||
-- | -- 内容区(文字 + 右浮图片) | ||
local textDiv = container:tag('div') | local textDiv = container:tag('div') | ||
:css('line-height', '1.6') | :css('line-height', '1.6') | ||
| 第126行: | 第125行: | ||
:css('font-size', '14px') | :css('font-size', '14px') | ||
if firstImage and firstImage ~= "" then | |||
if firstImage then | |||
textDiv:wikitext( | textDiv:wikitext( | ||
'[[' .. firstImage .. '|120px|right|link=' .. pageName .. ']]' | '[[' .. firstImage .. '|120px|right|link=' .. pageName .. ']]' | ||
2026年2月17日 (二) 23:51的版本
此模块的文档可以在Module:PageSummary/doc创建
local p = {}
-- 更高效的图片/分类/文件链接剥离(字节级处理为主)
local function stripImages(text)
if not text or text == "" then return "" end
-- 统一常见前缀,减少分支
text = text:gsub("%[%[(文件|File|Image|图像):", "[[File:")
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+12)
if chunk:match("^%[%[File:")
or chunk:match("^%[%[Category:")
or chunk:match("^%[%[分类:")
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 > 800 then break end -- 安全阀
end
return table.concat(out)
end
-- 合并清理步骤,减少重复扫描
local function cleanFinal(text)
if not text or text == "" then return "" end
text = text
:gsub("{{[^{}]*}}", "") -- 模板
:gsub("<ref.-</?ref[^>]*>", "") -- 参考文献
:gsub("<!%-%-.-%-%->", "") -- 注释
:gsub("\n==+.+==+", " ") -- 标题
:gsub("\n%s*[*#:;]+", " ") -- 列表
:gsub("%s*\n%s*", " ") -- 换行转空格
:gsub("%s+", " ") -- 压缩空格
return mw.text.trim(text)
end
function p.getSummaryAndImage(frame)
local pageName = mw.text.trim(frame.args[1] or "")
if pageName == "" then return "" end
local title = mw.title.new(pageName)
if not title or not title.exists then return "" end
local content = title:getContent()
if not content or content == "" then return "" end
-- 只取前450字节(足够首图+摘要)
local rawExcerpt = content:sub(1, 450)
-- 提取第一张图片(兼容多种写法)
local firstImage = rawExcerpt:match("%[%[(File|文件|Image|图像):([^|%]]+)")
local step1 = stripImages(rawExcerpt) or ""
local cleanText = cleanFinal(step1) or ""
local targetLen = 120
-- 提前多取一点,便于后续精确截断
local summary = cleanText:sub(1, targetLen * 2) or ""
-- 关键修复:判断前确保不是 nil
local ulen = mw.ustring.len(summary) or 0
if ulen > targetLen then
summary = mw.ustring.sub(summary, 1, targetLen) or ""
-- 尝试避免截断在单词/中文中间(简单向后找空格或标点)
local rev = summary:reverse()
local lastBreak = rev:find("[ %s%p,。!?;:]") or 1
if lastBreak > 1 and lastBreak < 20 then
summary = mw.ustring.sub(summary, 1, #summary - lastBreak + 1) or ""
end
summary = mw.text.trim(summary) .. "..."
end
summary = mw.text.trim(summary)
-- HTML 输出部分
local container = mw.html.create('div')
:css('margin-bottom', '25px')
:css('display', 'flow-root')
-- 标题行
container:tag('div')
:css('font-size', '1.3em')
:css('font-weight', 'bold')
:css('margin-bottom', '6px')
:css('border-bottom', '1px solid #eee')
:wikitext('[[' .. pageName .. ']]')
-- 内容区(文字 + 右浮图片)
local textDiv = container:tag('div')
:css('line-height', '1.6')
:css('color', '#222')
:css('font-size', '14px')
if firstImage and firstImage ~= "" then
textDiv:wikitext(
'[[' .. firstImage .. '|120px|right|link=' .. pageName .. ']]'
)
end
textDiv:wikitext(summary)
return tostring(container)
end
return p