Modul:Japanese calendar

Vikipediya, ochiq ensiklopediya

Bu modul uchun Modul:Japanese calendar/doc nomli hujjat sahifasini yaratishingiz mumkin

local eras = mw.loadData( 'Module:Japanese calendar/data' )
local halfToFull = require( 'Module:Convert character width' ).full --  

--------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------

local function yearToEraIndex( year )
    year = tonumber( year )
    if type( year ) ~= 'number' then return end
    for i, t in ipairs( eras ) do
        if year > t.startYear then
            return i
        elseif year == t.startYear then
            if eras[ i + 1 ] and eras[ i + 1 ].startYear == t.startYear then --  
                return i + 1
            else
                return i
            end
        end
    end
end

local function textToEraIndex( s )
    if not s or s == '' then return end
    for i, t in ipairs( eras ) do
        if s == t.article or s == t.kanji then
            return i
        end
    end
end

--------------------------------------------------------------------
-- Era class definition
--------------------------------------------------------------------

local era = {}
era.__index = era

function era:new( init )
    init = type( init ) == 'table' and init or {}
    local obj = {}
    
    -- Grab the data from the init table.
    obj.gregorianYear = tonumber( init.year )
    local initText = type( init.era ) == 'string' and init.era or nil
    local initIndex = tonumber( init.index )
    if not ( initIndex and initIndex >= 1 and math.floor( initIndex ) == initIndex and initIndex ~= math.huge ) then --  
        initIndex = nil
    end
    
    --  
    local eraIndex
    if initIndex then
        eraIndex = initIndex
    elseif initText then
        eraIndex = textToEraIndex( initText )
    elseif obj.gregorianYear then
        eraIndex = yearToEraIndex( obj.gregorianYear )
    end
    
    --  
    if not eraIndex then return end
    local eraData = eras[ eraIndex ]
    if not eraData or not eraData.article or eraData.article == '' then return end --  
    
    obj.startYear = eraData.startYear
    obj.endYear = eraData.endYear
    obj.article = eraData.article
    obj.kanji = eraData.kanji
    obj.label = eraData.label
    
    -- Create a link to the era article if possible.
    if obj.label and obj.article then
        obj.link = mw.ustring.format( '[[%s|%s]]', obj.article, obj.label )
    elseif obj.article then
        obj.link = mw.ustring.format( '[[%s]]', obj.article )
    end
    
    --  
    local nextEraData = eras[ eraIndex - 1 ]
    local nextStartYear = nextEraData and nextEraData.startYear
    if obj.gregorianYear
        and (  
            not nextStartYear
            or ( nextStartYear and obj.gregorianYear <= nextStartYear )
        )
        and obj.gregorianYear >= obj.startYear  
        and obj.article ~= ''  
        and ( obj.endYear and obj.gregorianYear <= obj.endYear or true )  
        then
        obj.eraYear = obj.gregorianYear - obj.startYear + 1
        if obj.eraYear == 1 then
            obj.eraYearKanji = '元'
        else
            obj.eraYearKanji = halfToFull( obj.eraYear )
        end
    end

    --  
    obj.label = obj.label or obj.article
    
    --  
    function obj:getNextEra()
        if not eraIndex then return end       
        return era:new{ index = eraIndex - 1, year = obj.gregorianYear }
    end
    
    function obj:getPreviousEra()
        if not eraIndex then return end            
        return era:new{ index = eraIndex + 1, year = obj.gregorianYear }
    end

    --  
    function obj:getOldEra()
        if obj.eraYear == 1 then
            local prevEra = obj:getPreviousEra()
            if prevEra then
                return prevEra
            else
                return obj
            end
        else
            return obj
        end
    end
    
    return setmetatable( obj, {
        __index = self
    })
end

--------------------------------------------------------------------
-- Interface for old Japanese calendar templates
--------------------------------------------------------------------

local function getStartYear( obj )
    return obj.startYear
end

local function getEndYear( obj )
    return obj.endYear
end

local function getEraYear( obj )
    return obj.eraYear
end

local function getEraYearKanji( obj )
    return obj.eraYearKanji
end

local function getArticle( obj )
    return obj.article
end

local function getLabel( obj )
    return obj.label
end

local function getLink( obj )
    return obj.link
end

local function getKanji( obj )
    return obj.kanji
end

local function getLabelAndEraYear( obj, kanji )
    local eraYear = kanji and obj.eraYearKanji or obj.eraYear
    if obj.label and eraYear then
        return mw.ustring.format( '%s %s', obj.label, tostring( eraYear ) )
    end
end

local function getLinkAndEraYear( obj, kanji )
    local eraYear = kanji and obj.eraYearKanji or obj.eraYear
    if obj.link and eraYear then
        return mw.ustring.format( '%s %s', obj.link, tostring( eraYear ) )
    end
end

local function getLabelAndEraYearKanji( obj )
    return getLabelAndEraYear( obj, true )
end

local function getLinkAndEraYearKanji( obj )
    return getLinkAndEraYear( obj, true )
end

--  
local function makeWrapper( func )
    return function( frame )
        --  
        local origArgs
        if frame == mw.getCurrentFrame() then
            origArgs = frame:getParent().args
            for k, v in pairs( frame.args ) do
                origArgs = frame.args
                break
            end
        else
            origArgs = frame
        end
        --  
        local args = {}
        for k, v in pairs( origArgs ) do
            if type( v ) == 'string' then
                v = mw.text.trim( v )
            end
            if v ~= '' then
                args[k] = v
            end
        end
        
        local myEra
        local otherEraArgs = {}
        table.insert( otherEraArgs, args.next )
        table.insert( otherEraArgs, args.previous )
        table.insert( otherEraArgs, args.old )
        if #otherEraArgs > 1 then
            return '<strong class="error">[[Module:Japanese calendar]] error: you can only specify one parameter out of "next", "previous" and "old".</strong>'
        elseif args.next then
            myEra = era:new( args ):getNextEra()
        elseif args.previous then
            myEra = era:new( args ):getPreviousEra()
        elseif args.old then
            myEra = era:new( args ):getOldEra()
        else
            myEra = era:new( args )
        end
        return myEra and func( myEra ) or ''
    end
end

--------------------------------------------------------------------
-- Return the era class and the template interface
--------------------------------------------------------------------
 
return {
    era = function () return era end,  
    baseyear = makeWrapper( getStartYear ),
    endyear = makeWrapper( getEndYear ),
    year = makeWrapper( getEraYear ),
    kanjiyear = makeWrapper( getEraYearKanji ),
    article = makeWrapper( getArticle ),
    label = makeWrapper( getLabel ),
    link = makeWrapper( getLink ),
    kanji = makeWrapper( getKanji ),
    label_year = makeWrapper( getLabelAndEraYear ),
    link_year = makeWrapper( getLinkAndEraYear ),
    label_kanjiyear = makeWrapper( getLabelAndEraYearKanji ),
    link_kanjiyear = makeWrapper( getLinkAndEraYearKanji )
}