モジュール:分註
表示
| このモジュールはテンプレートスタイルを使用しています: |
| Luaモジュールを使用しています: |
テンプレート {{分註}} の表示処理を担当する Lua モジュールです。
上段・下段の文字列をもとに、分注または組み文字の HTML 構造を生成します。
type の正規化、括弧生成、ARIA 属性付与、|type = unknown の警告処理など表示ロジックは本モジュールが担当します。
設定値は Module:分註/config に分離しています。
-- Module:分註
--
-- 本モジュールは、分注(上下に並べた注記)および組み文字を統一した形式で描画
-- するための処理を提供します。
-- 主にテンプレートから {{#invoke:分註|main}} として呼び出され、HTML を構築し
-- て返します。
--
-- 設定値は Module:分註/config に集約されています。
require('strict')
local cfg = require('Module:分註/config')
local yesno = require('Module:Yesno')
local getArgs = require('Module:Arguments').getArgs
local p = {}
----------------------------------------------------------------------
-- Bunchu "class"
----------------------------------------------------------------------
local Bunchu = {}
Bunchu.__index = Bunchu
----------------------------------------------------------------------
-- 名前空間名を ID に変換するヘルパー
-- (canonicalName または name でマッチ)
----------------------------------------------------------------------
local function resolveNamespaceId(key)
if type(key) ~= "string" then
return nil
end
local lower = mw.ustring.lower(mw.text.trim(key))
-- Main 名前空間だけ 0 扱いにする
if lower == "main" then
return 0
end
-- それ以外は name / canonicalName で総当たり
for id, info in pairs(mw.site.namespaces) do
local name = info.name
local canon = info.canonicalName
if name and mw.ustring.lower(name) == lower then
return id
end
if canon and mw.ustring.lower(canon) == lower then
return id
end
end
return nil
end
----------------------------------------------------------------------
-- 名前空間名リストを ID の集合に変換するヘルパー
-- (canonicalName または name でマッチ)
----------------------------------------------------------------------
local allowedNamespaceIds
local function getAllowedNamespaceIds()
if allowedNamespaceIds then
return allowedNamespaceIds
end
local resolved = {}
local list = cfg.allowedNamespaces
if type(list) == "table" then
for _, key in ipairs(list) do
local id = resolveNamespaceId(key)
if id then
resolved[id] = true
else
mw.addWarning(cfg.warningUnknownNamespace .. tostring(key))
end
end
end
allowedNamespaceIds = resolved
return resolved
end
----------------------------------------------------------------------
-- normalizeType
----------------------------------------------------------------------
--[[
正規化された type 名を返す関数。
ユーザー入力のゆらぎ(大文字混在、表記揺れ、和名など)を cfg.typeAliases
に基づいて吸収する。
@param raw string|nil
@return string canonical type ("bunchu", "kumimoji", "unknown")
]]
function Bunchu.normalizeType(raw)
if not raw or raw == "" then
return "unknown"
end
local v = mw.ustring.lower(tostring(raw))
v = mw.text.trim(v)
v = v:gsub("[_%-/]", "")
v = v:gsub("%s+", "")
for canonical, aliases in pairs(cfg.typeAliases) do
for _, alias in ipairs(aliases) do
if v == alias then
return canonical
end
end
end
return "unknown"
end
----------------------------------------------------------------------
-- Constructor
----------------------------------------------------------------------
--[[
インスタンス生成。
@param args table Module:Arguments により取得した引数テーブル
@return Bunchu インスタンス
]]
function Bunchu.new(args)
local self = setmetatable({}, Bunchu)
self.text1 = args[1] or ""
self.text2 = args[2] or ""
self.rawType = args.type
self.type = Bunchu.normalizeType(self.rawType)
-- bracket の明示指定判定
self.bracketRaw = args.bracket
local bracketGiven = self.bracketRaw ~= nil
-- 明示指定があればそれを優先、ないときは、type == "bunchu"だけ
-- デフォルトで括弧あり
if bracketGiven then
self.bracket = yesno(self.bracketRaw) or false
else
self.bracket = (self.type == "bunchu")
end
-- 括弧は分注 (type = bunchu) のみ使用する仕様。
-- 他のtypeでは bracket = yes と指定されても括弧は表示しない。
self.bracketEffective = self.bracket and (self.type == "bunchu")
self.size = args.size
self.extraStyle = args.style
return self
end
----------------------------------------------------------------------
-- HTML build methods
----------------------------------------------------------------------
-- span wrapper
function Bunchu:buildRoot()
self.root = mw.html.create("span")
self.root:addClass("wst-bunchu")
return self.root
end
-- data-* と aria-* 属性設定
function Bunchu:applySemanticAttributes()
self.root:attr("data-wst-bunchu-type", self.type)
-- ARIA label
local aria = cfg.ariaLabels[self.type]
if aria then
self.root:attr("aria-label", aria)
end
-- ARIA role
local role = cfg.ariaRole[self.type]
if role then
self.root:attr("role", role)
end
end
-- style 属性構築
function Bunchu:applyStyle()
local parts = {}
if self.size then
table.insert(parts, "font-size:" .. self.size .. ";")
end
if self.extraStyle then
table.insert(parts, self.extraStyle)
end
if #parts > 0 then
self.root:cssText(table.concat(parts, " "))
end
end
-- 括弧(左)
function Bunchu:addInlineStartBracketIfNeeded()
if not self.bracketEffective then return end
local inlineStart = self.root:tag("span")
inlineStart:addClass("wst-bunchu-col wst-bunchu-bracket-inline-start")
inlineStart:attr("role", "none")
inlineStart:tag("span"):wikitext("⎛")
inlineStart:tag("span"):wikitext("⎝")
end
-- 上下テキスト
function Bunchu:addText()
local col = self.root:tag("span")
col:addClass("wst-bunchu-col wst-bunchu-text")
col:tag("span"):wikitext(self.text1)
col:tag("span"):wikitext(self.text2)
end
-- 括弧(右)
function Bunchu:addInlineEndBracketIfNeeded()
if not self.bracketEffective then return end
local inlineEnd = self.root:tag("span")
inlineEnd:addClass("wst-bunchu-col wst-bunchu-bracket-inline-end")
inlineEnd:attr("role", "none")
inlineEnd:tag("span"):wikitext("⎞")
inlineEnd:tag("span"):wikitext("⎠")
end
----------------------------------------------------------------------
-- finalizeOutput
----------------------------------------------------------------------
--[[
unknown の場合の警告表示と追跡カテゴリ付加。
@param html string
@return string
]]
function Bunchu:finalizeOutput(html)
if self.type == "unknown" then
-- プレビュー時にのみ表示される警告
mw.addWarning(cfg.warningUnknownType)
-- 許可された名前空間でのみ追跡カテゴリを付与
local title = mw.title.getCurrentTitle()
local allowed = getAllowedNamespaceIds()
if allowed[title.namespace] then
html = html .. "[[Category:" .. cfg.trackingCategoryUnknown .. "]]"
end
end
return html
end
----------------------------------------------------------------------
-- render
----------------------------------------------------------------------
--[[
最終的な HTML を構築する。
TemplateStyles の読み込みもここで行う。
@return string HTML
]]
function Bunchu:render()
self:buildRoot()
self:applySemanticAttributes()
self:applyStyle()
self:addInlineStartBracketIfNeeded()
self:addText()
self:addInlineEndBracketIfNeeded()
local html = tostring(self.root)
local styleTag = mw.getCurrentFrame():extensionTag(
'templatestyles',
'',
{ src = cfg.styles }
)
html = styleTag .. html
return self:finalizeOutput(html)
end
----------------------------------------------------------------------
-- Entry point
----------------------------------------------------------------------
--[[
#invoke から呼び出されるエントリポイント。
@param frame table
@return string
]]
function p.main(frame)
local args = getArgs(frame)
local obj = Bunchu.new(args)
return obj:render()
end
return p