<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
	<id>https://wflswiki.zelda-110.link/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=240D%3AC010%3A132%3A2%3A0%3A0%3A0%3AAA</id>
	<title>武外梗百科 - 用户贡献 [zh]</title>
	<link rel="self" type="application/atom+xml" href="https://wflswiki.zelda-110.link/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=240D%3AC010%3A132%3A2%3A0%3A0%3A0%3AAA"/>
	<link rel="alternate" type="text/html" href="https://wflswiki.zelda-110.link/wiki/Special:%E7%94%A8%E6%88%B7%E8%B4%A1%E7%8C%AE/240D:C010:132:2:0:0:0:AA"/>
	<updated>2026-07-30T22:00:26Z</updated>
	<subtitle>用户贡献</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://wflswiki.zelda-110.link/index.php?title=Module:PageSummary&amp;diff=1049</id>
		<title>Module:PageSummary</title>
		<link rel="alternate" type="text/html" href="https://wflswiki.zelda-110.link/index.php?title=Module:PageSummary&amp;diff=1049"/>
		<updated>2026-02-18T01:32:54Z</updated>

		<summary type="html">&lt;p&gt;240D:C010:132:2:0:0:0:AA：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local function stripImages(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    -- 模式全部重新写，避免复制隐藏字符&lt;br /&gt;
    text = string.gsub(text, &amp;quot;%[%[(文件|Image|图像):&amp;quot;, &amp;quot;[[File:&amp;quot;)&lt;br /&gt;
    text = string.gsub(text, &amp;quot;%[%[(分类|Category):&amp;quot;, &amp;quot;[[Category:&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    local out = {}&lt;br /&gt;
    local i = 1&lt;br /&gt;
    local len = #text&lt;br /&gt;
    &lt;br /&gt;
    while i &amp;lt;= len do&lt;br /&gt;
        if text:byte(i) == 91 and text:byte(i+1) == 91 then&lt;br /&gt;
            local chunk = text:sub(i, i+15)&lt;br /&gt;
            if chunk:find(&amp;quot;^%[%[File:&amp;quot;) or chunk:find(&amp;quot;^%[%[Category:&amp;quot;) then&lt;br /&gt;
                local depth = 1&lt;br /&gt;
                local j = i + 2&lt;br /&gt;
                while j &amp;lt;= len and depth &amp;gt; 0 do&lt;br /&gt;
                    if text:byte(j) == 91 and text:byte(j+1) == 91 then&lt;br /&gt;
                        depth = depth + 1&lt;br /&gt;
                        j = j + 2&lt;br /&gt;
                    elseif text:byte(j) == 93 and text:byte(j+1) == 93 then&lt;br /&gt;
                        depth = depth - 1&lt;br /&gt;
                        j = j + 2&lt;br /&gt;
                    else&lt;br /&gt;
                        j = j + 1&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                i = j&lt;br /&gt;
            else&lt;br /&gt;
                table.insert(out, text:sub(i, i+1))&lt;br /&gt;
                i = i + 2&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            table.insert(out, text:sub(i, i))&lt;br /&gt;
            i = i + 1&lt;br /&gt;
        end&lt;br /&gt;
        if i &amp;gt; 1200 then break end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return table.concat(out)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function cleanFinal(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    -- 所有模式都重新手写，使用 string.gsub（模式是纯 ASCII）&lt;br /&gt;
    text = string.gsub(text, &amp;quot;{{[^{}]*}}&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    text = string.gsub(text, &amp;quot;&amp;lt;ref.-&amp;lt;/?ref[^&amp;gt;]*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    text = string.gsub(text, &amp;quot;&amp;lt;!%-%-.-%-%-&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
    text = string.gsub(text, &amp;quot;\n==+[^=]+==+&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
    text = string.gsub(text, &amp;quot;\n%s*[*#:;]+&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
    text = string.gsub(text, &amp;quot;%s*\n%s*&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
    text = string.gsub(text, &amp;quot;%s+&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    return mw.text.trim(text)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getSummaryAndImage(frame)&lt;br /&gt;
    local pageName = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
    if pageName == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local title = mw.title.new(pageName)&lt;br /&gt;
    if not title or not title.exists then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local content = title:getContent()&lt;br /&gt;
    if not content or content == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    -- 简单清洗 content，避免传入 gsub 的文本有问题&lt;br /&gt;
    content = string.gsub(content, &amp;quot;[\0-\31\127]&amp;quot;, &amp;quot;&amp;quot;)  -- 移除控制字符&lt;br /&gt;
    local rawExcerpt = mw.ustring.sub(content, 1, 800) or &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    -- 提取第一张图片（使用 find + 手动截取）&lt;br /&gt;
    local firstImage = nil&lt;br /&gt;
    local prefixes = {&amp;quot;File:&amp;quot;, &amp;quot;文件:&amp;quot;}&lt;br /&gt;
    for _, prefix in ipairs(prefixes) do&lt;br /&gt;
        local pattern = &amp;quot;%[%[&amp;quot; .. prefix&lt;br /&gt;
        local start = mw.ustring.find(rawExcerpt, pattern)&lt;br /&gt;
        if start then&lt;br /&gt;
            local pipePos = mw.ustring.find(rawExcerpt, &amp;quot;|&amp;quot;, start)&lt;br /&gt;
            local endPos = mw.ustring.find(rawExcerpt, &amp;quot;%]%]&amp;quot;, start)&lt;br /&gt;
            local boundary = pipePos or endPos&lt;br /&gt;
            if boundary then&lt;br /&gt;
                local candidate = mw.ustring.sub(rawExcerpt, start + #pattern + 1, boundary - 1)&lt;br /&gt;
                candidate = mw.text.trim(candidate)&lt;br /&gt;
                if candidate ~= &amp;quot;&amp;quot; and mw.ustring.find(candidate, &amp;quot;%.&amp;quot;) then&lt;br /&gt;
                    firstImage = prefix .. candidate&lt;br /&gt;
                    break&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local step1     = stripImages(rawExcerpt) or &amp;quot;&amp;quot;&lt;br /&gt;
    local cleanText = cleanFinal(step1) or &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    local targetLen = 120&lt;br /&gt;
    local summary = cleanText&lt;br /&gt;
    &lt;br /&gt;
    local ulen = mw.ustring.len(summary) or 0&lt;br /&gt;
    if ulen &amp;gt; targetLen then&lt;br /&gt;
        local temp = mw.ustring.sub(summary, 1, targetLen + 20)&lt;br /&gt;
        &lt;br /&gt;
        local breakPos = nil&lt;br /&gt;
        for i = mw.ustring.len(temp), 1, -1 do&lt;br /&gt;
            local char = mw.ustring.sub(temp, i, i)&lt;br /&gt;
            if char:match(&amp;quot;[ %s，。！？；：,…、]&amp;quot;) then&lt;br /&gt;
                breakPos = i&lt;br /&gt;
                break&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        if breakPos and breakPos &amp;gt; targetLen - 30 then&lt;br /&gt;
            summary = mw.ustring.sub(temp, 1, breakPos)&lt;br /&gt;
        else&lt;br /&gt;
            summary = mw.ustring.sub(temp, 1, targetLen)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        summary = mw.text.trim(summary) .. &amp;quot;…&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        summary = mw.text.trim(summary)&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local container = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;margin-bottom&#039;, &#039;25px&#039;)&lt;br /&gt;
        :css(&#039;display&#039;, &#039;flow-root&#039;)&lt;br /&gt;
    &lt;br /&gt;
    container:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;font-size&#039;, &#039;1.3em&#039;)&lt;br /&gt;
        :css(&#039;font-weight&#039;, &#039;bold&#039;)&lt;br /&gt;
        :css(&#039;margin-bottom&#039;, &#039;6px&#039;)&lt;br /&gt;
        :css(&#039;border-bottom&#039;, &#039;1px solid #eee&#039;)&lt;br /&gt;
        :wikitext(&#039;[[&#039; .. pageName .. &#039;]]&#039;)&lt;br /&gt;
    &lt;br /&gt;
    local textDiv = container:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;line-height&#039;, &#039;1.6&#039;)&lt;br /&gt;
        :css(&#039;color&#039;, &#039;#222&#039;)&lt;br /&gt;
        :css(&#039;font-size&#039;, &#039;14px&#039;)&lt;br /&gt;
    &lt;br /&gt;
    if firstImage and firstImage ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        textDiv:wikitext(&#039;[[&#039; .. firstImage .. &#039;|120px|right|link=&#039; .. pageName .. &#039;]]&#039;)&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    textDiv:wikitext(summary)&lt;br /&gt;
    &lt;br /&gt;
    return tostring(container)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>240D:C010:132:2:0:0:0:AA</name></author>
	</entry>
	<entry>
		<id>https://wflswiki.zelda-110.link/index.php?title=Module:PageSummary&amp;diff=1043</id>
		<title>Module:PageSummary</title>
		<link rel="alternate" type="text/html" href="https://wflswiki.zelda-110.link/index.php?title=Module:PageSummary&amp;diff=1043"/>
		<updated>2026-02-17T16:16:56Z</updated>

		<summary type="html">&lt;p&gt;240D:C010:132:2:0:0:0:AA：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local function stripImages(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    text = text:gsub(&amp;quot;%[%[(文件|Image|图像):&amp;quot;, &amp;quot;[[File:&amp;quot;)&lt;br /&gt;
           :gsub(&amp;quot;%[%[(分类|Category):&amp;quot;, &amp;quot;[[Category:&amp;quot;)&lt;br /&gt;
    local out = {}&lt;br /&gt;
    local i = 1&lt;br /&gt;
    local len = #text&lt;br /&gt;
    while i &amp;lt;= len do&lt;br /&gt;
        if text:byte(i) == 91 and text:byte(i+1) == 91 then&lt;br /&gt;
            local chunk = text:sub(i, i+15)&lt;br /&gt;
            if chunk:match(&amp;quot;^%[%[File:&amp;quot;) or chunk:match(&amp;quot;^%[%[Category:&amp;quot;) then&lt;br /&gt;
                local depth = 1&lt;br /&gt;
                local j = i + 2&lt;br /&gt;
                while j &amp;lt;= len and depth &amp;gt; 0 do&lt;br /&gt;
                    if text:byte(j) == 91 and text:byte(j+1) == 91 then&lt;br /&gt;
                        depth = depth + 1&lt;br /&gt;
                        j = j + 2&lt;br /&gt;
                    elseif text:byte(j) == 93 and text:byte(j+1) == 93 then&lt;br /&gt;
                        depth = depth - 1&lt;br /&gt;
                        j = j + 2&lt;br /&gt;
                    else&lt;br /&gt;
                        j = j + 1&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                i = j&lt;br /&gt;
            else&lt;br /&gt;
                table.insert(out, text:sub(i, i+1))&lt;br /&gt;
                i = i + 2&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            table.insert(out, text:sub(i, i))&lt;br /&gt;
            i = i + 1&lt;br /&gt;
        end&lt;br /&gt;
        if i &amp;gt; 1200 then break end&lt;br /&gt;
    end&lt;br /&gt;
    return table.concat(out)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function cleanFinal(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    text = text&lt;br /&gt;
        :gsub(&amp;quot;{{[^{}]*}}&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
        :gsub(&amp;quot;&amp;lt;ref.-&amp;lt;/?ref[^&amp;gt;]*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
        :gsub(&amp;quot;&amp;lt;!%-%-.-%-%-&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
        :gsub(&amp;quot;\n==+[^=]+==+&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
        :gsub(&amp;quot;\n%s*[*#:;]+&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
        :gsub(&amp;quot;%s*\n%s*&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
        :gsub(&amp;quot;%s+&amp;quot;, &amp;quot; &amp;quot;)&lt;br /&gt;
    return mw.text.trim(text)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getSummaryAndImage(frame)&lt;br /&gt;
    local pageName = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
    if pageName == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
    local title = mw.title.new(pageName)&lt;br /&gt;
    if not title or not title.exists then return &amp;quot;&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
    local content = title:getContent()&lt;br /&gt;
    if not content or content == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
&lt;br /&gt;
    local rawExcerpt = mw.ustring.sub(content, 1, 800) or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    -- 强力提取第一张图片（支持带参数的写法）&lt;br /&gt;
    local firstImage = mw.ustring.match(rawExcerpt, &amp;quot;%[%[File:([^|]+)&amp;quot;)&lt;br /&gt;
                  or mw.ustring.match(rawExcerpt, &amp;quot;%[%[文件:([^|]+)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    -- 验证图片是否有效&lt;br /&gt;
    if firstImage then&lt;br /&gt;
        firstImage = mw.text.trim(firstImage)&lt;br /&gt;
        firstImage = mw.ustring.gsub(firstImage, &amp;quot;[%z%s﻿&amp;lt;&amp;gt;\&amp;quot;]+&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
        if mw.ustring.len(firstImage) &amp;lt; 5 or not mw.ustring.find(firstImage, &amp;quot;[:%.]&amp;quot;) then&lt;br /&gt;
            firstImage = nil&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local step1     = stripImages(rawExcerpt) or &amp;quot;&amp;quot;&lt;br /&gt;
    local cleanText = cleanFinal(step1) or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    local targetLen = 120&lt;br /&gt;
    local summary   = cleanText:sub(1, targetLen * 2) or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    local ulen = mw.ustring.len(summary) or 0&lt;br /&gt;
    if ulen &amp;gt; targetLen then&lt;br /&gt;
        summary = mw.ustring.sub(summary, 1, targetLen) or &amp;quot;&amp;quot;&lt;br /&gt;
        local rev = summary:reverse()&lt;br /&gt;
        local lastBreak = rev:find(&amp;quot;[ %s%p，。！？；：,…]&amp;quot;) or 1&lt;br /&gt;
        if lastBreak &amp;gt; 1 and lastBreak &amp;lt; 20 then&lt;br /&gt;
            summary = mw.ustring.sub(summary, 1, #summary - lastBreak + 1) or &amp;quot;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        summary = mw.text.trim(summary) .. &amp;quot;...&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    summary = mw.text.trim(summary)&lt;br /&gt;
&lt;br /&gt;
    local container = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;margin-bottom&#039;, &#039;25px&#039;)&lt;br /&gt;
        :css(&#039;display&#039;, &#039;flow-root&#039;)&lt;br /&gt;
&lt;br /&gt;
    container:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;font-size&#039;, &#039;1.3em&#039;)&lt;br /&gt;
        :css(&#039;font-weight&#039;, &#039;bold&#039;)&lt;br /&gt;
        :css(&#039;margin-bottom&#039;, &#039;6px&#039;)&lt;br /&gt;
        :css(&#039;border-bottom&#039;, &#039;1px solid #eee&#039;)&lt;br /&gt;
        :wikitext(&#039;[[&#039; .. pageName .. &#039;]]&#039;)&lt;br /&gt;
&lt;br /&gt;
    local textDiv = container:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;line-height&#039;, &#039;1.6&#039;)&lt;br /&gt;
        :css(&#039;color&#039;, &#039;#222&#039;)&lt;br /&gt;
        :css(&#039;font-size&#039;, &#039;14px&#039;)&lt;br /&gt;
&lt;br /&gt;
    -- 只有图片有效时才输出图片代码，彻底杜绝泄漏&lt;br /&gt;
    if firstImage and firstImage ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        textDiv:wikitext(&#039;[[&#039; .. firstImage .. &#039;|120px|right|link=&#039; .. pageName .. &#039;]]&#039;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    textDiv:wikitext(summary)&lt;br /&gt;
&lt;br /&gt;
    return tostring(container)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>240D:C010:132:2:0:0:0:AA</name></author>
	</entry>
	<entry>
		<id>https://wflswiki.zelda-110.link/index.php?title=Module:PageSummary&amp;diff=1033</id>
		<title>Module:PageSummary</title>
		<link rel="alternate" type="text/html" href="https://wflswiki.zelda-110.link/index.php?title=Module:PageSummary&amp;diff=1033"/>
		<updated>2026-02-17T15:51:29Z</updated>

		<summary type="html">&lt;p&gt;240D:C010:132:2:0:0:0:AA：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
-- 更高效的图片/分类/文件链接剥离（字节级处理为主）&lt;br /&gt;
local function stripImages(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    -- 统一常见前缀，减少分支&lt;br /&gt;
    text = text:gsub(&amp;quot;%[%[(文件|File|Image|图像):&amp;quot;, &amp;quot;[[File:&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    local out = {}&lt;br /&gt;
    local i = 1&lt;br /&gt;
    local len = #text&lt;br /&gt;
    &lt;br /&gt;
    while i &amp;lt;= len do&lt;br /&gt;
        if text:byte(i) == 91 and text:byte(i+1) == 91 then  -- [[&lt;br /&gt;
            local chunk = text:sub(i, i+12)&lt;br /&gt;
            if chunk:match(&amp;quot;^%[%[File:&amp;quot;) &lt;br /&gt;
                or chunk:match(&amp;quot;^%[%[Category:&amp;quot;)&lt;br /&gt;
                or chunk:match(&amp;quot;^%[%[分类:&amp;quot;)&lt;br /&gt;
            then&lt;br /&gt;
                -- 跳过整段嵌套 [[...]]&lt;br /&gt;
                local depth = 1&lt;br /&gt;
                local j = i + 2&lt;br /&gt;
                while j &amp;lt;= len and depth &amp;gt; 0 do&lt;br /&gt;
                    if text:byte(j) == 91 and text:byte(j+1) == 91 then&lt;br /&gt;
                        depth = depth + 1&lt;br /&gt;
                        j = j + 2&lt;br /&gt;
                    elseif text:byte(j) == 93 and text:byte(j+1) == 93 then&lt;br /&gt;
                        depth = depth - 1&lt;br /&gt;
                        j = j + 2&lt;br /&gt;
                    else&lt;br /&gt;
                        j = j + 1&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                i = j  -- 跳到 ]] 之后&lt;br /&gt;
            else&lt;br /&gt;
                table.insert(out, &amp;quot;[[&amp;quot;) &lt;br /&gt;
                i = i + 2&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            table.insert(out, text:sub(i, i))&lt;br /&gt;
            i = i + 1&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        if i &amp;gt; 800 then break end  -- 安全阀&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return table.concat(out)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 合并清理步骤，减少重复扫描&lt;br /&gt;
local function cleanFinal(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    text = text&lt;br /&gt;
        :gsub(&amp;quot;{{[^{}]*}}&amp;quot;, &amp;quot;&amp;quot;)                  -- 模板&lt;br /&gt;
        :gsub(&amp;quot;&amp;lt;ref.-&amp;lt;/?ref[^&amp;gt;]*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)          -- 参考文献&lt;br /&gt;
        :gsub(&amp;quot;&amp;lt;!%-%-.-%-%-&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)               -- 注释&lt;br /&gt;
        :gsub(&amp;quot;\n==+.+==+&amp;quot;, &amp;quot; &amp;quot;)                 -- 标题&lt;br /&gt;
        :gsub(&amp;quot;\n%s*[*#:;]+&amp;quot;, &amp;quot; &amp;quot;)               -- 列表&lt;br /&gt;
        :gsub(&amp;quot;%s*\n%s*&amp;quot;, &amp;quot; &amp;quot;)                   -- 换行转空格&lt;br /&gt;
        :gsub(&amp;quot;%s+&amp;quot;, &amp;quot; &amp;quot;)                        -- 压缩空格&lt;br /&gt;
    &lt;br /&gt;
    return mw.text.trim(text)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getSummaryAndImage(frame)&lt;br /&gt;
    local pageName = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
    if pageName == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local title = mw.title.new(pageName)&lt;br /&gt;
    if not title or not title.exists then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local content = title:getContent()&lt;br /&gt;
    if not content or content == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    -- 只取前450字节（足够首图+摘要）&lt;br /&gt;
    local rawExcerpt = content:sub(1, 450)&lt;br /&gt;
    &lt;br /&gt;
    -- 提取第一张图片（兼容多种写法）&lt;br /&gt;
    local firstImage = rawExcerpt:match(&amp;quot;%[%[(File|文件|Image|图像):([^|%]]+)&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    local step1     = stripImages(rawExcerpt) or &amp;quot;&amp;quot;&lt;br /&gt;
    local cleanText = cleanFinal(step1) or &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    local targetLen = 120&lt;br /&gt;
    -- 提前多取一点，便于后续精确截断&lt;br /&gt;
    local summary = cleanText:sub(1, targetLen * 2) or &amp;quot;&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    -- 关键修复：判断前确保不是 nil&lt;br /&gt;
    local ulen = mw.ustring.len(summary) or 0&lt;br /&gt;
    &lt;br /&gt;
    if ulen &amp;gt; targetLen then&lt;br /&gt;
        summary = mw.ustring.sub(summary, 1, targetLen) or &amp;quot;&amp;quot;&lt;br /&gt;
        &lt;br /&gt;
        -- 尝试避免截断在单词/中文中间（简单向后找空格或标点）&lt;br /&gt;
        local rev = summary:reverse()&lt;br /&gt;
        local lastBreak = rev:find(&amp;quot;[ %s%p，。！？；：]&amp;quot;) or 1&lt;br /&gt;
        if lastBreak &amp;gt; 1 and lastBreak &amp;lt; 20 then&lt;br /&gt;
            summary = mw.ustring.sub(summary, 1, #summary - lastBreak + 1) or &amp;quot;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        summary = mw.text.trim(summary) .. &amp;quot;...&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    summary = mw.text.trim(summary)&lt;br /&gt;
    &lt;br /&gt;
    -- HTML 输出部分&lt;br /&gt;
    local container = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;margin-bottom&#039;, &#039;25px&#039;)&lt;br /&gt;
        :css(&#039;display&#039;, &#039;flow-root&#039;)&lt;br /&gt;
    &lt;br /&gt;
    -- 标题行&lt;br /&gt;
    container:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;font-size&#039;, &#039;1.3em&#039;)&lt;br /&gt;
        :css(&#039;font-weight&#039;, &#039;bold&#039;)&lt;br /&gt;
        :css(&#039;margin-bottom&#039;, &#039;6px&#039;)&lt;br /&gt;
        :css(&#039;border-bottom&#039;, &#039;1px solid #eee&#039;)&lt;br /&gt;
        :wikitext(&#039;[[&#039; .. pageName .. &#039;]]&#039;)&lt;br /&gt;
    &lt;br /&gt;
    -- 内容区（文字 + 右浮图片）&lt;br /&gt;
    local textDiv = container:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;line-height&#039;, &#039;1.6&#039;)&lt;br /&gt;
        :css(&#039;color&#039;, &#039;#222&#039;)&lt;br /&gt;
        :css(&#039;font-size&#039;, &#039;14px&#039;)&lt;br /&gt;
    &lt;br /&gt;
    if firstImage and firstImage ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        textDiv:wikitext(&lt;br /&gt;
            &#039;[[&#039; .. firstImage .. &#039;|120px|right|link=&#039; .. pageName .. &#039;]]&#039;&lt;br /&gt;
        )&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    textDiv:wikitext(summary)&lt;br /&gt;
    &lt;br /&gt;
    return tostring(container)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>240D:C010:132:2:0:0:0:AA</name></author>
	</entry>
	<entry>
		<id>https://wflswiki.zelda-110.link/index.php?title=Module:PageSummary&amp;diff=1032</id>
		<title>Module:PageSummary</title>
		<link rel="alternate" type="text/html" href="https://wflswiki.zelda-110.link/index.php?title=Module:PageSummary&amp;diff=1032"/>
		<updated>2026-02-17T15:50:14Z</updated>

		<summary type="html">&lt;p&gt;240D:C010:132:2:0:0:0:AA：​&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
-- 更高效的图片/链接/分类剥离（避免逐字符 + 频繁 sub）&lt;br /&gt;
local function stripImages(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    -- 预先把常见命名空间前缀统一处理，减少后续匹配分支&lt;br /&gt;
    text = text:gsub(&amp;quot;%[%[(文件|File|Image|图像):&amp;quot;, &amp;quot;[[File:&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    local out = {}&lt;br /&gt;
    local i = 1&lt;br /&gt;
    local len = #text   -- 优先用字节长度，性能更好（中文环境影响可接受）&lt;br /&gt;
    &lt;br /&gt;
    while i &amp;lt;= len do&lt;br /&gt;
        local byte = text:byte(i)&lt;br /&gt;
        if byte == 91 and text:byte(i+1) == 91 then  -- [[&lt;br /&gt;
            local chunk = text:sub(i, i+12)&lt;br /&gt;
            if chunk:match(&amp;quot;^%[%[File:&amp;quot;) &lt;br /&gt;
                or chunk:match(&amp;quot;^%[%[Category:&amp;quot;)&lt;br /&gt;
                or chunk:match(&amp;quot;^%[%[分类:&amp;quot;)&lt;br /&gt;
            then&lt;br /&gt;
                -- 跳过整段 [[...]]&lt;br /&gt;
                local depth = 1&lt;br /&gt;
                local j = i + 2&lt;br /&gt;
                while j &amp;lt;= len and depth &amp;gt; 0 do&lt;br /&gt;
                    if text:byte(j) == 91 and text:byte(j+1) == 91 then&lt;br /&gt;
                        depth = depth + 1&lt;br /&gt;
                        j = j + 2&lt;br /&gt;
                    elseif text:byte(j) == 93 and text:byte(j+1) == 93 then&lt;br /&gt;
                        depth = depth - 1&lt;br /&gt;
                        j = j + 2&lt;br /&gt;
                    else&lt;br /&gt;
                        j = j + 1&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                i = j&lt;br /&gt;
            else&lt;br /&gt;
                -- 普通 [[ ，保留&lt;br /&gt;
                table.insert(out, &amp;quot;[&amp;quot;)&lt;br /&gt;
                i = i + 1&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            table.insert(out, text:sub(i, i))&lt;br /&gt;
            i = i + 1&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        -- 安全阀（防止极端情况卡死）&lt;br /&gt;
        if i &amp;gt; 800 then break end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return table.concat(out)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- 合并多次 gsub，提升正则效率&lt;br /&gt;
local function cleanFinal(text)&lt;br /&gt;
    if not text or text == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    -- 一次性处理多种需要删除的模式&lt;br /&gt;
    text = text&lt;br /&gt;
        :gsub(&amp;quot;{{[^{}]*}}&amp;quot;, &amp;quot;&amp;quot;)                 -- 模板（包括嵌套一层的情况已足够）&lt;br /&gt;
        :gsub(&amp;quot;&amp;lt;ref.-&amp;lt;/?ref[^&amp;gt;]*&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)         -- 参考文献（更宽松匹配）&lt;br /&gt;
        :gsub(&amp;quot;&amp;lt;!%-%-.-%-%-&amp;gt;&amp;quot;, &amp;quot;&amp;quot;)              -- 注释&lt;br /&gt;
        :gsub(&amp;quot;\n==+.+==+&amp;quot;, &amp;quot; &amp;quot;)                -- 标题&lt;br /&gt;
        :gsub(&amp;quot;\n%s*[*#:;]+&amp;quot;, &amp;quot; &amp;quot;)              -- 列表&lt;br /&gt;
        :gsub(&amp;quot;%s*\n%s*&amp;quot;, &amp;quot; &amp;quot;)                  -- 换行 → 空格（合并多行）&lt;br /&gt;
        :gsub(&amp;quot;%s+&amp;quot;, &amp;quot; &amp;quot;)                       -- 压缩连续空格&lt;br /&gt;
    &lt;br /&gt;
    return mw.text.trim(text)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function p.getSummaryAndImage(frame)&lt;br /&gt;
    local pageName = mw.text.trim(frame.args[1] or &amp;quot;&amp;quot;)&lt;br /&gt;
    if pageName == &amp;quot;&amp;quot; then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local title = mw.title.new(pageName)&lt;br /&gt;
    if not title or not title.exists then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local content = title:getContent()&lt;br /&gt;
    if not content then return &amp;quot;&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    -- 只取前450字节（中文约200-300字），足够提取首图 + 摘要&lt;br /&gt;
    local rawExcerpt = content:sub(1, 450)&lt;br /&gt;
    &lt;br /&gt;
    -- 提取第一张图片（更宽松匹配，兼容更多写法）&lt;br /&gt;
    local firstImage = rawExcerpt:match(&amp;quot;%[%[(File|文件|Image|图像):([^|%]]+)&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    -- 核心剥离 + 清理&lt;br /&gt;
    local step1   = stripImages(rawExcerpt)&lt;br /&gt;
    local cleanText = cleanFinal(step1)&lt;br /&gt;
    &lt;br /&gt;
    local targetLen = 120&lt;br /&gt;
    local summary = cleanText:sub(1, targetLen * 2)  -- 多取一点，后面精确截断&lt;br /&gt;
    &lt;br /&gt;
    -- 更安全的截断（避免截断在 [[ 中间）&lt;br /&gt;
    local len = mw.ustring.len(summary)&lt;br /&gt;
    if len &amp;gt; targetLen then&lt;br /&gt;
        summary = mw.ustring.sub(summary, 1, targetLen)&lt;br /&gt;
        &lt;br /&gt;
        -- 简单向后找最近的空格或标点，避免断字&lt;br /&gt;
        local lastSpace = summary:reverse():find(&amp;quot;[ %s%p]&amp;quot;) or 1&lt;br /&gt;
        if lastSpace &amp;gt; 1 and lastSpace &amp;lt; 15 then&lt;br /&gt;
            summary = mw.ustring.sub(summary, 1, #summary - lastSpace + 1)&lt;br /&gt;
        end&lt;br /&gt;
        summary = mw.text.trim(summary) .. &amp;quot;...&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- HTML 构建部分基本保持原样（性能占比很低）&lt;br /&gt;
    local container = mw.html.create(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;margin-bottom&#039;, &#039;25px&#039;)&lt;br /&gt;
        :css(&#039;display&#039;, &#039;flow-root&#039;)&lt;br /&gt;
    &lt;br /&gt;
    -- 标题&lt;br /&gt;
    container:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;font-size&#039;, &#039;1.3em&#039;)&lt;br /&gt;
        :css(&#039;font-weight&#039;, &#039;bold&#039;)&lt;br /&gt;
        :css(&#039;margin-bottom&#039;, &#039;6px&#039;)&lt;br /&gt;
        :css(&#039;border-bottom&#039;, &#039;1px solid #eee&#039;)&lt;br /&gt;
        :wikitext(&#039;[[&#039; .. pageName .. &#039;]]&#039;)&lt;br /&gt;
    &lt;br /&gt;
    -- 内容区&lt;br /&gt;
    local textDiv = container:tag(&#039;div&#039;)&lt;br /&gt;
        :css(&#039;line-height&#039;, &#039;1.6&#039;)&lt;br /&gt;
        :css(&#039;color&#039;, &#039;#222&#039;)&lt;br /&gt;
        :css(&#039;font-size&#039;, &#039;14px&#039;)&lt;br /&gt;
    &lt;br /&gt;
    -- 图片右浮 + 链接到页面&lt;br /&gt;
    if firstImage then&lt;br /&gt;
        textDiv:wikitext(&lt;br /&gt;
            &#039;[[&#039; .. firstImage .. &#039;|120px|right|link=&#039; .. pageName .. &#039;]]&#039;&lt;br /&gt;
        )&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    textDiv:wikitext(summary)&lt;br /&gt;
    &lt;br /&gt;
    return tostring(container)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>240D:C010:132:2:0:0:0:AA</name></author>
	</entry>
</feed>