Module:Sandbox/HenryLi/Article

local p = {}

-- 數字
local digits = {"零","壹","貳","叁","肆","伍","陸","柒","捌","玖"}
local units = {"","拾","佰","仟"}
local bigUnits = {"","萬","億"}

-- 轉換個十百千
local function fourDigitToChinese(num)
    local str = ""
    local zero = false
    local n = tonumber(num)
    local numStr = tostring(n)
    local len = #numStr

    for i = 1, len do
        local digit = tonumber(numStr:sub(i,i))
        local pos = len - i + 1
        if digit == 0 then
            zero = true
        else
            if zero then
                str = str .. digits[1]
                zero = false
            end
            str = str .. digits[digit+1] .. units[pos]
        end
    end

    return str
end

-- 主轉換函數
local function toChineseFormal(num)
    if type(num) ~= "number" then
        num = tonumber(num) or 0
    end

    if num == 0 then return digits[1] end

    local str = ""
    local parts = {}
    local unitIndex = 1

    while num > 0 do
        local segment = num % 10000
        if segment ~= 0 then
            local segmentStr = fourDigitToChinese(segment) .. bigUnits[unitIndex]
            table.insert(parts,1,segmentStr)
        else
            table.insert(parts,1,"")
        end
        num = math.floor(num / 10000)
        unitIndex = unitIndex + 1
    end

    str = table.concat(parts)

    -- 清理多餘零
    str = mw.ustring.gsub(str,"零+","零")
    str = mw.ustring.gsub(str,"零$","")

    -- 特殊處理十位 10-19
    str = mw.ustring.gsub(str,"^壹拾","拾")

    return str
end

-- 讀參數
local function getArg(frame, name_or_number, default)
    local function clean(value)
        if not value then return nil end
        value = mw.text.trim(value)
        if value == "" then return nil end
        return value
    end

    local value = frame.args[name_or_number]
    value = clean(value)

    if not value and frame.getParent then
        local parent = frame:getParent()
        if parent and parent.args then
            value = clean(parent.args[name_or_number])
        end
    end

    if not value then
        return default
    end

    return value
end

-- 計字
-- 0x4E00  0x9FFF  本
-- 0x3400  0x4DBF  甲
-- 0x20000 0x2A6DF 乙
-- 0x2A700 0x2B73F 丙
-- 0x2B740 0x2B81F 丁
-- 0x2B820 0x2CEAF 戊
-- 0xF900  0xFAFF  容
local function countCharacter(text)
    local _, count = mw.ustring.gsub(text, "[一-龯㐀-䶿豈-﫿]", "")
    return count
end


-- 省非文計
local function cleanText(text)
    -- 記。唔現
    text = mw.ustring.gsub(text, "<!%-%-.-%-%->", "")
    -- 攷
    text = mw.ustring.gsub(text, "<ref[^>/]->.-</ref>", "")
    text = mw.ustring.gsub(text, "<ref[^>]*/>", "")
    -- 模
    text = mw.ustring.gsub(text, "{{[^{}]-}}", "")
    -- 表
    text = mw.ustring.gsub(text, "{|.-|}", "")
	-- 題
    text = mw.ustring.gsub(text, "\n=+[^\n]+=+\n", "\n")
    -- 圖。檔
    text = mw.ustring.gsub(text, "%[%[File:.-%]%]", "")
    text = mw.ustring.gsub(text, "%[%[Image:.-%]%]", "")
    -- 省內通 [[甲|乙]] → 乙
    text = mw.ustring.gsub(text, "%[%[[^|%]]-|", "")
    text = mw.ustring.gsub(text, "%[%[", "")
    text = mw.ustring.gsub(text, "%]%]", "")
	-- 省外通
    text = mw.ustring.gsub(text, "%[https?://.-%]", "")

    return text
end

-- 字數評級
local function grade(count)
	if count < 150 then -- 小學一二年班 百五字
		return "草稿"
	elseif count < 600 then -- 中學畢業 八千卦估算
        return "簡介"
    elseif count < 1500 then -- 夠料 一萬六千卦估算
        return "及格"
	elseif count < 10000 then
		return "長文"
    else
        return "超長"
    end
end

local function hasSource(text)
    if mw.ustring.find(text, "<ref") then
        return true
    else
        return false
    end
end

local function wikidata(title)
	local entityId = mw.wikibase.getEntityIdForTitle(title)
	if entityId then

	    local entity = mw.wikibase.getEntity(entityId)
	    if entity then
	        return entity
		else
			return nil
	    end
	else
		return nil
	end
end

local function commonscat(entity)
	local commons = nil
	if not entity then
		return nil
	end
    if entity.sitelinks and entity.sitelinks.commonswiki then
		local name = entity.sitelinks.commonswiki.title
		if mw.ustring.match(name, "^Category:") then
	        return entity.sitelinks.commonswiki.title .. ""
		end
    end

	local claims = entity.claims

    if claims then
        if claims["P373"] then
			return "Category:" .. claims["P373"][1].mainsnak.datavalue.value .. ""
		end
		if claims["P948"] then
			return "Category:" .. claims["P948"][1].mainsnak.datavalue.value .. ""
        end
    end
	return commons
end

local function hasImage(frame, title)
	local html = frame:preprocess("{{:" .. title.fullText .. "}}")

    if html and string.find(html, "<img") then
        return true
    else
        return false
    end
end

local function isDisambiguity(entity)
	if entity and entity.claims and entity.claims["P31"] then
        for _, claim in ipairs(entity.claims["P31"]) do
            local value = claim.mainsnak.datavalue.value.id
            if value == "Q4167410" then
                return true
            end
        end
	end
	return false
end

p.count = function(frame)

	local page = getArg(frame, 1)
	local title

    if page then
        title = mw.title.new(page)
    else
        title = mw.title.getCurrentTitle()
    end

	if not title or not title.exists then
        return "無此版題"
    end

	if title.isRedirect then
		return "跳轉"
	end

    -- 限文章
    -- if title.namespace ~= 0 then
    --     return "祇容文章"
    -- end

    local text = title:getContent()
    if not text then
        return "莫能讀"
    end

	local sourced = hasSource(text)
	local sourceText
	if sourced then
		sourceText = ""
	else
		sourceText = "。欠來源"
	end

	local wikidataConnected = wikidata(page)
	local wikidataText
	if wikidataConnected then
		wikidataText = ""
	else
		wikidataText = "。欠資料庫"
	end
	if isDisambiguity(wikidataConnected) then
		return "搞清楚"
	end
	local imageText
	if not hasImage(frame, title) then
		imageText = "無圖"
		if wikidataConnected then
			-- 若果無圖
			-- 要做啲嘢
			imageText = imageText .. "。[[commons:" .. commonscat(wikidataConnected) .. "]]"
		end	
	end


	text = cleanText(text)
	local count = countCharacter(text)
	local level = grade(count)
	local countChinese = toChineseFormal(count)


    return string.format("%s字。%s%s%s%s", countChinese, level, sourceText, wikidataText, imageText)
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.