モジュール:ExtractYear
ナビゲーションに移動
検索に移動
local p = {}
-- =========================
-- 無視領域除去
-- =========================
local function strip_ignored(text)
text = mw.ustring.gsub(text, "<ref.-/>", "")
text = mw.ustring.gsub(text, "<ref.->.-</ref>", "")
text = mw.ustring.gsub(text, "{{%s*[Ss]fn.-}}", "")
text = mw.ustring.gsub(text, "{{%s*[Ee]fn.-}}", "")
text = mw.ustring.gsub(text, "{{%s*[Rr]efnest.-}}", "")
text = mw.ustring.gsub(text, "{{%s*[Rr]%s*[|}].-}}", "")
return text
end
-- =========================
-- 正規化
-- =========================
local function normalize(text)
text = mw.ustring.gsub(text, "%[%[([^%]|]+)|.-%]%]", "%1")
text = mw.ustring.gsub(text, "%[%[([^%]]+)%]%]", "%1")
text = mw.ustring.gsub(text, "%d+月%d+日", "")
text = mw.ustring.gsub(text, "%d+月", "")
text = mw.ustring.gsub(text, "午[前後]%d+時", "")
text = mw.ustring.gsub(text, "頃", "")
text = mw.ustring.gsub(text, "%?", "")
text = mw.ustring.gsub(text, "%s+", "")
return text
end
-- =========================
-- 単体素通し
-- =========================
local function single_keep(text)
if mw.ustring.match(text, "^%d+年$") then return text end
if mw.ustring.match(text, "^%d+年代$") then return text end
if mw.ustring.match(text, "^%d+世紀$") then return text end
if mw.ustring.match(text, "^%d+千年紀$") then return text end
if mw.ustring.match(text, "^%d+万年紀$") then return text end
return nil
end
-- =========================
-- 抽出
-- =========================
local function extract_years(text)
local list = {}
for y in mw.ustring.gmatch(text, "(%d+)年") do
table.insert(list, tonumber(y))
end
return list
end
-- =========================
-- 世紀計算
-- =========================
local function century_of(y)
return math.floor((y - 1) / 100) + 1
end
-- =========================
-- 変換ロジック(修正版)
-- =========================
local function convert_range(years)
if #years == 0 then return "" end
if #years == 1 then
return years[1] .. "年"
end
table.sort(years)
local y1 = years[1]
local y2 = years[#years]
-- 同一年
if y1 == y2 then
return y1 .. "年"
end
local c1 = century_of(y1)
local c2 = century_of(y2)
-- ★ 同一世紀内は必ず世紀
if c1 == c2 then
return c1 .. "世紀"
end
local diff = y2 - y1
if diff < 1000 then
return math.floor((y1 - 1) / 1000) + 1 .. "千年紀"
else
return math.floor((y1 - 1) / 10000) + 1 .. "万年紀"
end
end
-- =========================
-- メイン
-- =========================
function p.main(frame)
local text = frame.args[1] or ""
text = strip_ignored(text)
text = normalize(text)
local single = single_keep(text)
if single then return single end
local years = extract_years(text)
return convert_range(years)
end
return p