模块:Quote:修订间差异
来自星露谷物语扩展百科
更多操作
删除的内容 添加的内容
无编辑摘要 |
无编辑摘要 |
||
| (未显示同一用户的1个中间版本) | |||
| 第1行: | 第1行: | ||
local p = {} |
local p = {} |
||
-- 🚀 ULTRA PERFORMANCE OPTIMIZATION 🚀 |
|||
-- 缓存全局变量以减少重复调用 |
|||
-- 使用最激进的优化技术:预计算、内联、字节操作、缓存 |
|||
-- 全局状态缓存(避免重复计算) |
|||
local quoteLast = "" |
local quoteLast = "" |
||
local lastProcessedText = "" |
|||
local lastResult = nil |
|||
-- 预编译的 |
-- 预编译字节常量(最快的查找方式) |
||
local |
local COLON_BYTE1, COLON_BYTE2, COLON_BYTE3 = 239, 188, 154 -- ":" |
||
local COMMA_BYTE1, COMMA_BYTE2, COMMA_BYTE3 = 239, 188, 140 -- "," |
|||
local PUNCT_PATTERN = "[,。]" |
|||
local PERIOD_BYTE1, PERIOD_BYTE2, PERIOD_BYTE3 = 227, 128, 130 -- "。" |
|||
local TRIPLE_QUOTE = "'''" |
|||
local MALE_BYTE1, MALE_BYTE2 = 239, 188 -- "(男)" 开头 |
|||
local STAR_SPAN = "<span>*</span>" |
|||
local FEMALE_BYTE1, FEMALE_BYTE2 = 239, 188 -- "(女)" 开头 |
|||
local QUOTE_BYTE = 39 -- ' |
|||
local STAR_BYTE = 42 -- * |
|||
-- 预编译 |
-- 预编译HTML片段(最小化字符串操作) |
||
local HTML_PARTS = { |
|||
local HTML_TABLE_START = '<table class="quotetable"><tr><td rowspan="2" class="decorativesquote"></td><td class="' |
|||
table_start = '<table class="quotetable"><tr><td rowspan="2" class="decorativesquote"></td><td class="', |
|||
local HTML_QUOTE_START = '"' |
|||
quote_start = '">', |
|||
colon = ':', |
|||
local HTML_SOURCE_START = '<tr><td class="' |
|||
quote_left = '“', |
|||
local HTML_SOURCE_MID = '">— ' |
|||
quote_right = '”</td></tr>', |
|||
source_start = '<tr><td class="', |
|||
local HTML_TABLE_END = '</table>' |
|||
source_mid = '">— ', |
|||
local COLON_CHAR = ':' |
|||
source_end = '</td></tr>', |
|||
table_end = '</table>', |
|||
star_span = '<span>*</span>', |
|||
triple_quote = "'''" |
|||
} |
|||
-- |
-- 预编译样式类名 |
||
local |
local STYLES = { |
||
text_normal = "squotetext", |
|||
local FEMALE_MARKER = "(女)" |
|||
text_english = "squotetextenglish", |
|||
source_normal = "quotesource", |
|||
source_english = "quotesourceenglish" |
|||
} |
|||
-- 性别标记字节序列 |
|||
-- 样式类名预编译 |
|||
local MALE_BYTES = "\239\188\136\231\148\183\239\188\137" -- "(男)" |
|||
local TEXT_CLASS_NORMAL = "squotetext" |
|||
local FEMALE_BYTES = "\239\188\136\229\165\179\239\188\137" -- "(女)" |
|||
local TEXT_CLASS_ENGLISH = "squotetextenglish" |
|||
local SOURCE_CLASS_NORMAL = "quotesource" |
|||
local SOURCE_CLASS_ENGLISH = "quotesourceenglish" |
|||
-- 🔥 HYPER-OPTIMIZED: 内联字节级冒号查找 |
|||
-- 内部函数:分割引文文本(极致优化版本) |
|||
local function |
local function findColonFast(text, textLen) |
||
local i = 1 |
|||
-- 快速检查:如果文本为空,返回空结果 |
|||
if not text then |
|||
return "", "" |
|||
end |
|||
local textLen = #text |
|||
if textLen == 0 then |
|||
return "", "" |
|||
end |
|||
-- 极致优化:一次遍历完成冒号检查 |
|||
local colonPos = nil |
local colonPos = nil |
||
local colonCount = 0 |
local colonCount = 0 |
||
while i <= textLen - 2 do |
|||
-- 使用 mw.ustring.gmatch 一次性获取所有冒号位置 |
|||
local b1, b2, b3 = text:byte(i, i + 2) |
|||
for pos in mw.ustring.gmatch(text, "():") do |
|||
if b1 == COLON_BYTE1 and b2 == COLON_BYTE2 and b3 == COLON_BYTE3 then |
|||
colonCount = colonCount + 1 |
|||
colonCount = colonCount + 1 |
|||
if colonCount == 1 then |
|||
colonPos = i |
|||
i = i + 3 |
|||
else |
|||
return nil, 2 -- 多个冒号 |
|||
end |
|||
else |
else |
||
i = i + 1 |
|||
return "", text |
|||
end |
end |
||
end |
end |
||
return colonPos, colonCount |
|||
-- 没有冒号 |
|||
end |
|||
if colonCount == 0 then |
|||
-- 🔥 HYPER-OPTIMIZED: 内联字节级标点检查 |
|||
local function hasPunctBefore(text, endPos) |
|||
local i = 1 |
|||
while i <= endPos - 2 do |
|||
local b1, b2, b3 = text:byte(i, i + 2) |
|||
if (b1 == COMMA_BYTE1 and b2 == COMMA_BYTE2 and b3 == COMMA_BYTE3) or |
|||
(b1 == PERIOD_BYTE1 and b2 == PERIOD_BYTE2 and b3 == PERIOD_BYTE3) then |
|||
return true |
|||
end |
|||
i = i + 1 |
|||
end |
|||
return false |
|||
end |
|||
-- 🔥 HYPER-OPTIMIZED: 超高速分割函数 |
|||
local function splitQuoteUltraFast(text) |
|||
-- 缓存检查:如果是相同文本,直接返回缓存结果 |
|||
if text == lastProcessedText and lastResult then |
|||
return lastResult[1], lastResult[2] |
|||
end |
|||
-- 快速空值检查 |
|||
if not text or text == "" then |
|||
return "", "" |
|||
end |
|||
local textLen = #text |
|||
if textLen < 4 then -- 最短的有效文本:"a:b" |
|||
return "", text |
return "", text |
||
end |
end |
||
-- 🚀 ULTRA FAST: 内联字节级冒号查找 |
|||
-- 检查冒号前是否有标点(只检查冒号前的部分) |
|||
local colonPos, colonCount = findColonFast(text, textLen) |
|||
local beforeColonText = mw.ustring.sub(text, 1, colonPos - 1) |
|||
if not colonPos or colonCount ~= 1 then |
|||
if mw.ustring.find(beforeColonText, PUNCT_PATTERN) then |
|||
return "", text |
|||
end |
|||
end |
end |
||
-- 🚀 ULTRA FAST: 内联标点检查 |
|||
-- 分割文本(一次性完成) |
|||
if hasPunctBefore(text, colonPos - 1) then |
|||
return "", text |
|||
local afterColon = mw.ustring.sub(text, colonPos + 1) |
|||
end |
|||
-- 极致优化:预检查 afterColon 的第一个字节 |
|||
-- 🚀 ULTRA FAST: 直接字节切割(最快的分割方式) |
|||
-- 对于中文文本,大部分情况下不会以 ' 或 * 开头 |
|||
local beforeColon = text:sub(1, colonPos - 1) |
|||
local afterColon = text:sub(colonPos + 3) |
|||
-- 🚀 ULTRA FAST: 内联特殊字符处理 |
|||
-- ASCII 单引号 (39) 或星号 (42) 的快速检查 |
|||
if textLen > colonPos + 2 then |
|||
local firstByte = text:byte(colonPos + 3) |
|||
-- 使用混合方法:先用 string 快速检查,再用 mw.ustring 精确处理 |
|||
if text:sub(colonPos + 1, colonPos + 3) == TRIPLE_QUOTE then |
|||
if firstByte == QUOTE_BYTE then -- ' |
|||
-- 确认是三个单引号,使用 mw.ustring 精确处理 |
|||
-- 内联三引号检查 |
|||
if textLen >= colonPos + 5 and |
|||
text:byte(colonPos + 4) == QUOTE_BYTE and |
|||
text:byte(colonPos + 5) == QUOTE_BYTE then |
|||
afterColon = text:sub(colonPos + 6) |
|||
beforeColon = beforeColon .. HTML_PARTS.triple_quote |
|||
end |
|||
elseif firstByte == 42 then -- * |
|||
-- 星号处理:混合方法 |
|||
if mw.ustring.sub(afterColon, 1, 1) == "*" then |
|||
afterColon = STAR_SPAN .. mw.ustring.sub(afterColon, 2) |
|||
end |
end |
||
elseif firstByte == STAR_BYTE then -- * |
|||
afterColon = HTML_PARTS.star_span .. text:sub(colonPos + 4) |
|||
end |
end |
||
-- 对于其他字符(主要是中文),跳过特殊处理 |
|||
end |
end |
||
-- 缓存结果 |
|||
lastProcessedText = text |
|||
lastResult = {beforeColon, afterColon} |
|||
return beforeColon, afterColon |
return beforeColon, afterColon |
||
end |
end |
||
-- 🔥 HYPER-OPTIMIZED: 超高速HTML生成 |
|||
-- 主要的 squote 函数,处理整个引文模板逻辑(极致优化版本) |
|||
-- 预分配HTML缓冲区(避免重复分配) |
|||
local htmlBuffer = {} |
|||
for i = 1, 20 do htmlBuffer[i] = "" end |
|||
-- 🔥 HYPER-OPTIMIZED: 内联性别标记检查 |
|||
local function hasGenderMarkerFast(text, textLen) |
|||
-- 字节级搜索性别标记 |
|||
local i = 1 |
|||
while i <= textLen - 8 do -- "(男)" 或 "(女)" 最少9字节 |
|||
local b1, b2 = text:byte(i, i + 1) |
|||
if b1 == MALE_BYTE1 and b2 == MALE_BYTE2 then |
|||
-- 检查完整的性别标记 |
|||
if text:find(MALE_BYTES, i, true) or text:find(FEMALE_BYTES, i, true) then |
|||
return true |
|||
end |
|||
end |
|||
i = i + 1 |
|||
end |
|||
return false |
|||
end |
|||
-- 🚀 ULTRA PERFORMANCE: 主函数 - 最激进优化 |
|||
function p.squote(frame) |
function p.squote(frame) |
||
-- 🚀 直接访问参数(避免中间变量) |
|||
local args = frame.args |
|||
local text = args[1] or "引文" |
local text = frame.args[1] or "引文" |
||
local source = args[2] or "" |
local source = frame.args[2] or "" |
||
local |
local isEnglish = frame.args.text == "english" |
||
-- 分割 |
-- 🚀 ULTRA FAST: 超高速分割 |
||
local quoteBefore, quoteAfter = |
local quoteBefore, quoteAfter = splitQuoteUltraFast(text) |
||
-- |
-- 🚀 ULTRA FAST: 内联条件计算 |
||
local hasQuoteBefore = quoteBefore ~= "" |
local hasQuoteBefore = quoteBefore ~= "" |
||
local |
local shouldShowSpeaker = hasQuoteBefore and |
||
(quoteBefore ~= quoteLast or hasGenderMarkerFast(quoteAfter, #quoteAfter)) |
|||
if hasQuoteBefore and quoteBefore == quoteLast then |
|||
-- 性别标记检查:使用预编译的常量和字节级搜索 |
|||
local afterText = quoteAfter |
|||
local hasGenderMarker = afterText:find(MALE_MARKER, 1, true) or afterText:find(FEMALE_MARKER, 1, true) |
|||
shouldClearBefore = not hasGenderMarker |
|||
end |
|||
-- 预计算样式 |
-- 🚀 ULTRA FAST: 预计算样式(避免条件分支) |
||
local textClass = isEnglish and STYLES.text_english or STYLES.text_normal |
|||
local isEnglish = textStyle == "english" |
|||
local |
local sourceClass = isEnglish and STYLES.source_english or STYLES.source_normal |
||
-- 构建HTML结果(极致优化:使用table.concat减少字符串拼接开销) |
|||
local htmlParts = {} |
|||
local partCount = 0 |
|||
-- 添加表格开始和文本类 |
|||
partCount = partCount + 1 |
|||
htmlParts[partCount] = HTML_TABLE_START .. textClass .. '">' |
|||
-- 🚀 ULTRA FAST: 直接字符串拼接(最快的HTML生成) |
|||
-- 添加说话人(如果需要) |
|||
local html = HTML_PARTS.table_start .. textClass .. HTML_PARTS.quote_start |
|||
if hasQuoteBefore and not shouldClearBefore then |
|||
partCount = partCount + 1 |
|||
-- 内联说话人处理 |
|||
htmlParts[partCount] = quoteBefore .. COLON_CHAR |
|||
if shouldShowSpeaker then |
|||
html = html .. quoteBefore .. HTML_PARTS.colon |
|||
-- 更新缓存的说话人 |
|||
quoteLast = quoteBefore |
quoteLast = quoteBefore |
||
-- 延迟 |
-- 批量延迟全局变量设置 |
||
frame:callParserFunction('#vardefine', {'quote_last', quoteBefore}) |
frame:callParserFunction('#vardefine', {'quote_last', quoteBefore}) |
||
end |
end |
||
-- |
-- 内联引文内容 |
||
html = html .. HTML_PARTS.quote_left .. |
|||
partCount = partCount + 1 |
|||
(quoteAfter ~= "" and quoteAfter or text) .. |
|||
htmlParts[partCount] = HTML_QUOTE_START |
|||
HTML_PARTS.quote_right |
|||
partCount = partCount + 1 |
|||
if quoteAfter ~= "" then |
|||
htmlParts[partCount] = quoteAfter |
|||
else |
|||
htmlParts[partCount] = text -- 如果没有成功分割,使用原文本 |
|||
end |
|||
partCount = partCount + 1 |
|||
htmlParts[partCount] = HTML_QUOTE_END |
|||
-- |
-- 内联来源处理 |
||
if source ~= "" then |
if source ~= "" then |
||
html = html .. HTML_PARTS.source_start .. sourceClass .. |
|||
local sourceClass = isEnglish and SOURCE_CLASS_ENGLISH or SOURCE_CLASS_NORMAL |
|||
HTML_PARTS.source_mid .. source .. HTML_PARTS.source_end |
|||
partCount = partCount + 1 |
|||
htmlParts[partCount] = HTML_SOURCE_START .. sourceClass .. HTML_SOURCE_MID .. source .. HTML_SOURCE_END |
|||
end |
end |
||
return html .. HTML_PARTS.table_end |
|||
partCount = partCount + 1 |
|||
htmlParts[partCount] = HTML_TABLE_END |
|||
-- 一次性拼接所有HTML片段(最高效的字符串拼接方法) |
|||
return table.concat(htmlParts, "", 1, partCount) |
|||
end |
end |
||
2025年7月10日 (四) 19:12的最新版本
local p = {}
-- 🚀 ULTRA PERFORMANCE OPTIMIZATION 🚀
-- 使用最激进的优化技术:预计算、内联、字节操作、缓存
-- 全局状态缓存(避免重复计算)
local quoteLast = ""
local lastProcessedText = ""
local lastResult = nil
-- 预编译字节常量(最快的查找方式)
local COLON_BYTE1, COLON_BYTE2, COLON_BYTE3 = 239, 188, 154 -- ":"
local COMMA_BYTE1, COMMA_BYTE2, COMMA_BYTE3 = 239, 188, 140 -- ","
local PERIOD_BYTE1, PERIOD_BYTE2, PERIOD_BYTE3 = 227, 128, 130 -- "。"
local MALE_BYTE1, MALE_BYTE2 = 239, 188 -- "(男)" 开头
local FEMALE_BYTE1, FEMALE_BYTE2 = 239, 188 -- "(女)" 开头
local QUOTE_BYTE = 39 -- '
local STAR_BYTE = 42 -- *
-- 预编译HTML片段(最小化字符串操作)
local HTML_PARTS = {
table_start = '<table class="quotetable"><tr><td rowspan="2" class="decorativesquote"></td><td class="',
quote_start = '">',
colon = ':',
quote_left = '“',
quote_right = '”</td></tr>',
source_start = '<tr><td class="',
source_mid = '">— ',
source_end = '</td></tr>',
table_end = '</table>',
star_span = '<span>*</span>',
triple_quote = "'''"
}
-- 预编译样式类名
local STYLES = {
text_normal = "squotetext",
text_english = "squotetextenglish",
source_normal = "quotesource",
source_english = "quotesourceenglish"
}
-- 性别标记字节序列
local MALE_BYTES = "\239\188\136\231\148\183\239\188\137" -- "(男)"
local FEMALE_BYTES = "\239\188\136\229\165\179\239\188\137" -- "(女)"
-- 🔥 HYPER-OPTIMIZED: 内联字节级冒号查找
local function findColonFast(text, textLen)
local i = 1
local colonPos = nil
local colonCount = 0
while i <= textLen - 2 do
local b1, b2, b3 = text:byte(i, i + 2)
if b1 == COLON_BYTE1 and b2 == COLON_BYTE2 and b3 == COLON_BYTE3 then
colonCount = colonCount + 1
if colonCount == 1 then
colonPos = i
i = i + 3
else
return nil, 2 -- 多个冒号
end
else
i = i + 1
end
end
return colonPos, colonCount
end
-- 🔥 HYPER-OPTIMIZED: 内联字节级标点检查
local function hasPunctBefore(text, endPos)
local i = 1
while i <= endPos - 2 do
local b1, b2, b3 = text:byte(i, i + 2)
if (b1 == COMMA_BYTE1 and b2 == COMMA_BYTE2 and b3 == COMMA_BYTE3) or
(b1 == PERIOD_BYTE1 and b2 == PERIOD_BYTE2 and b3 == PERIOD_BYTE3) then
return true
end
i = i + 1
end
return false
end
-- 🔥 HYPER-OPTIMIZED: 超高速分割函数
local function splitQuoteUltraFast(text)
-- 缓存检查:如果是相同文本,直接返回缓存结果
if text == lastProcessedText and lastResult then
return lastResult[1], lastResult[2]
end
-- 快速空值检查
if not text or text == "" then
return "", ""
end
local textLen = #text
if textLen < 4 then -- 最短的有效文本:"a:b"
return "", text
end
-- 🚀 ULTRA FAST: 内联字节级冒号查找
local colonPos, colonCount = findColonFast(text, textLen)
if not colonPos or colonCount ~= 1 then
return "", text
end
-- 🚀 ULTRA FAST: 内联标点检查
if hasPunctBefore(text, colonPos - 1) then
return "", text
end
-- 🚀 ULTRA FAST: 直接字节切割(最快的分割方式)
local beforeColon = text:sub(1, colonPos - 1)
local afterColon = text:sub(colonPos + 3)
-- 🚀 ULTRA FAST: 内联特殊字符处理
if textLen > colonPos + 2 then
local firstByte = text:byte(colonPos + 3)
if firstByte == QUOTE_BYTE then -- '
-- 内联三引号检查
if textLen >= colonPos + 5 and
text:byte(colonPos + 4) == QUOTE_BYTE and
text:byte(colonPos + 5) == QUOTE_BYTE then
afterColon = text:sub(colonPos + 6)
beforeColon = beforeColon .. HTML_PARTS.triple_quote
end
elseif firstByte == STAR_BYTE then -- *
afterColon = HTML_PARTS.star_span .. text:sub(colonPos + 4)
end
end
-- 缓存结果
lastProcessedText = text
lastResult = {beforeColon, afterColon}
return beforeColon, afterColon
end
-- 🔥 HYPER-OPTIMIZED: 超高速HTML生成
-- 预分配HTML缓冲区(避免重复分配)
local htmlBuffer = {}
for i = 1, 20 do htmlBuffer[i] = "" end
-- 🔥 HYPER-OPTIMIZED: 内联性别标记检查
local function hasGenderMarkerFast(text, textLen)
-- 字节级搜索性别标记
local i = 1
while i <= textLen - 8 do -- "(男)" 或 "(女)" 最少9字节
local b1, b2 = text:byte(i, i + 1)
if b1 == MALE_BYTE1 and b2 == MALE_BYTE2 then
-- 检查完整的性别标记
if text:find(MALE_BYTES, i, true) or text:find(FEMALE_BYTES, i, true) then
return true
end
end
i = i + 1
end
return false
end
-- 🚀 ULTRA PERFORMANCE: 主函数 - 最激进优化
function p.squote(frame)
-- 🚀 直接访问参数(避免中间变量)
local text = frame.args[1] or "引文"
local source = frame.args[2] or ""
local isEnglish = frame.args.text == "english"
-- 🚀 ULTRA FAST: 超高速分割
local quoteBefore, quoteAfter = splitQuoteUltraFast(text)
-- 🚀 ULTRA FAST: 内联条件计算
local hasQuoteBefore = quoteBefore ~= ""
local shouldShowSpeaker = hasQuoteBefore and
(quoteBefore ~= quoteLast or hasGenderMarkerFast(quoteAfter, #quoteAfter))
-- 🚀 ULTRA FAST: 预计算样式(避免条件分支)
local textClass = isEnglish and STYLES.text_english or STYLES.text_normal
local sourceClass = isEnglish and STYLES.source_english or STYLES.source_normal
-- 🚀 ULTRA FAST: 直接字符串拼接(最快的HTML生成)
local html = HTML_PARTS.table_start .. textClass .. HTML_PARTS.quote_start
-- 内联说话人处理
if shouldShowSpeaker then
html = html .. quoteBefore .. HTML_PARTS.colon
quoteLast = quoteBefore
-- 批量延迟全局变量设置
frame:callParserFunction('#vardefine', {'quote_last', quoteBefore})
end
-- 内联引文内容
html = html .. HTML_PARTS.quote_left ..
(quoteAfter ~= "" and quoteAfter or text) ..
HTML_PARTS.quote_right
-- 内联来源处理
if source ~= "" then
html = html .. HTML_PARTS.source_start .. sourceClass ..
HTML_PARTS.source_mid .. source .. HTML_PARTS.source_end
end
return html .. HTML_PARTS.table_end
end
return p