Module:Peter Bowman/odm-przym-ros

From Wikipedia

Documentation for this module may be created at Module:Peter Bowman/odm-przym-ros/doc

local p = {}

local myUStringSub = mw.ustring.sub
local myStringGSub = string.gsub
local myTrim = mw.text.trim

--[[ przypadek = {
    rodzaj_liczba = {
        twardy_temat(-ый),  -- np. холодный (id=1)
        twardy_temat(-ой),  -- np. удалой (id=2)
        miękki_temat(-ий),  -- np. последний (id=3)
        -{гкх}-ий,          -- np. русский (id=4)
        -{гкхш}-ой,         -- np. большой (id=5)
        -{жшчщ}-ий,         -- np. хороший (id=6)
        -цый,               -- np. куцый (id=7)
        dzierżawczy1-ий,    -- np. лисий (id=8)
        dzierżawczy2        -- zakończone na -ов, -ев, -ёв, -ин, -ын (np. отцов) (id=9)
    },...
   },...
]]
local dcl = {
    M  = { m_lp = { 'ый', 'о́й', 'ий', 'ий', 'о́й', 'ий', 'ый', 'ий', '' },
           f_lp = { 'ая', 'а́я', 'яя', 'ая', 'а́я', 'ая', 'ая', 'ья', 'а' },
           n_lp = { 'ое', 'о́е', 'ее', 'ое', 'о́е', 'ее', 'ее', 'ье', 'о' },
           lm   = { 'ые', 'ы́е', 'ие', 'ие', 'и́е', 'ие', 'ые', 'ьи', 'ы' }
         },
    D  = { m_lp = { 'ого', 'о́го', 'его', 'ого', 'о́го', 'его', 'его', 'ьего', 'а' },
           f_lp = { 'ой', 'о́й', 'ей', 'ой', 'о́й', 'ей', 'ей', 'ьей', 'ой' },
           -- n_lp = m_lp
           lm   = { 'ых', 'ы́х', 'их', 'их', 'и́х', 'их', 'ых', 'ьих', 'ых' }
         },
    C  = { m_lp = { 'ому', 'о́му', 'ему', 'ому', 'о́му', 'ему', 'ему', 'ьему', 'у' },
           -- f_lp = D.f_lp
           -- n_lp = m_lp
           lm   = { 'ым', 'ы́м', 'им', 'им', 'и́м', 'им', 'ым', 'ьим', 'ым' }
         },
    B  = { -- m_lp_nzw = M.m_lp, m_lp_zw = D.m_lp
           f_lp = { 'ую', 'у́ю', 'юю', 'ую', 'у́ю', 'ую', 'ую', 'ью', 'у' }
           -- n_lp = M.m_lp
           -- lm_nzw = M.lm, lm_zw = D.lm
         },
    N  = { -- m_lp = C.lm
           -- f_lp_1 = D.f_lp 													  -- -ой / -ей
           f_lp_2 = { 'ою', 'о́ю', 'ею', 'ою', 'о́ю', 'ею', 'ею', 'ьею', 'ою' },	-- -ою / -ею
           -- n_lp = m.lp = C.lm
           lm   = { 'ыми', 'ы́ми', 'ими', 'ими', 'и́ми', 'ими', 'ыми', 'ьими', 'ыми' }
         },
    Ms = { m_lp = { 'ом', 'о́м', 'ем', 'ом', 'о́м', 'ем', 'ем', 'ьем', 'ом' }
           -- f_lp = D.f_lp
           -- n_lp = m_lp
           -- lm   = D.lm
        }
}

dcl.D.n_lp = dcl.D.m_lp
dcl.C.f_lp = dcl.D.f_lp
dcl.C.n_lp = dcl.C.m_lp
dcl.B.m_lp_nzw = dcl.M.m_lp
dcl.B.m_lp_zw = dcl.D.m_lp
dcl.B.n_lp = dcl.M.m_lp
dcl.B.lm_nzw = dcl.M.lm
dcl.B.lm_zw = dcl.D.lm
dcl.N.m_lp = dcl.C.lm
dcl.N.f_lp_1 = dcl.D.f_lp
dcl.N.n_lp = dcl.C.lm
dcl.Ms.f_lp = dcl.D.f_lp
dcl.Ms.n_lp = dcl.Ms.m_lp
dcl.Ms.lm = dcl.D.lm

local function checkEnding(s, poss)
    local ending = myUStringSub(s, -2)
    local consonant = myUStringSub(s, -3, -3)
    
    if ending == 'ий' then
        if poss == 'tak' then
            return 8    -- лисий
        elseif (consonant == 'г') or (consonant == 'к') or (consonant == 'х') then
            return 4    -- русский
        elseif (consonant == 'ж') or (consonant == 'ч') or (consonant == 'щ') or (consonant == 'ш') then
            return 6    -- хороший
        else
            return 3    -- последний
        end
    elseif (ending == '́й') or (ending == 'ой') then
        if (consonant == 'г') or (consonant == 'к') or (consonant == 'х') or (consonant == 'ш') then
            return 5    -- большой
        else
            return 2    -- удалой
        end
    elseif ending == 'ый' then
        if consonant == 'ц' then
            return 7    -- куцый
        else
            return 1    -- холодный
        end
    elseif poss == 'tak' then
        return 9        -- отцов
    else
        return 0
    end
end

local function declensionTable(s, id, t)
    local html = mw.html.create('')
    
    html:tag('tr')
    	:tag('th'):attr('rowspan', 2):wikitext("[[przypadek]]"):done()
    	:tag('th'):attr('colspan', 4)
    		:tag('i'):wikitext('liczba pojedyncza'):done():done()
    	:tag('th'):attr('colspan', 2)
    		:tag('i'):wikitext('liczba mnoga')
    
    html:tag('tr')
    	:tag('td'):addClass('forma'):wikitext(t.zw):done()
    	:tag('td'):addClass('forma'):wikitext(t.nzw):done()
    	:tag('td'):addClass('forma'):wikitext(t.f):done()
    	:tag('td'):addClass('forma'):wikitext(t.n):done()
    	:tag('td'):addClass('forma'):wikitext(t.zw):done()
    	:tag('td'):addClass('forma'):wikitext(t.nzw)
    
    html:tag('tr')
    	:tag('td'):addClass('forma'):wikitext('[[mianownik]]'):done()
    	:tag('td'):wikitext(s .. dcl.M.m_lp[id]):attr('colspan', 2):done()
    	:tag('td'):wikitext(s .. dcl.M.f_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.M.n_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.M.lm[id]):attr('colspan', 2)
    
    html:tag('tr')
    	:tag('td'):addClass('forma'):wikitext('[[dopełniacz]]'):done()
    	:tag('td'):wikitext(s .. dcl.D.m_lp[id]):attr('colspan', 2):done()
    	:tag('td'):wikitext(s .. dcl.D.f_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.D.n_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.D.lm[id]):attr('colspan', 2)
    		
    html:tag('tr')
    	:tag('td'):addClass('forma'):wikitext('[[celownik]]'):done()
    	:tag('td'):wikitext(s .. dcl.C.m_lp[id]):attr('colspan', 2):done()
    	:tag('td'):wikitext(s .. dcl.C.f_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.C.n_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.C.lm[id]):attr('colspan', 2)
    		
    html:tag('tr')
    	:tag('td'):addClass('forma'):wikitext('[[biernik]]'):done()
    	:tag('td'):wikitext(s .. dcl.B.m_lp_zw[id]):done()
    	:tag('td'):wikitext(s .. dcl.B.m_lp_nzw[id]):done()
    	:tag('td'):wikitext(s .. dcl.B.f_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.B.n_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.B.lm_zw[id]):done()
    	:tag('td'):wikitext(s .. dcl.B.lm_nzw[id])

	html:tag('tr')
    	:tag('td'):addClass('forma'):wikitext('[[narzędnik]]'):done()
    	:tag('td'):wikitext(s .. dcl.N.m_lp[id]):attr('colspan', 2):done()
    	:tag('td'):wikitext(s .. dcl.N.f_lp_1[id] .. '<br>(' .. s .. dcl.N.f_lp_2[id] .. ')'):done()
    	:tag('td'):wikitext(s .. dcl.N.n_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.N.lm[id]):attr('colspan', 2)
    
    html:tag('tr')
    	:tag('td'):addClass('forma'):wikitext('[[miejscownik]]'):done()
    	:tag('td'):wikitext(s .. dcl.Ms.m_lp[id]):attr('colspan', 2):done()
    	:tag('td'):wikitext(s .. dcl.Ms.f_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.Ms.n_lp[id]):done()
    	:tag('td'):wikitext(s .. dcl.Ms.lm[id]):attr('colspan', 2)
    
    return html
end

function p.main(frame)
    local args = frame:getParent().args
    local class, style = frame.args.class, frame.args.style
    local poss, no_sf = args['dzierżawczy'], args['krótka forma']
    
    local pattern, subst = "[, ilub/]+", " / "
    local sf_m_lp = args['krótka forma m lp'] and myStringGSub(args['krótka forma m lp'], pattern, subst) or nil
    local sf_f_lp = args['krótka forma f lp'] and myStringGSub(args['krótka forma f lp'], pattern, subst) or nil
    local sf_n_lp = args['krótka forma n lp'] and myStringGSub(args['krótka forma n lp'], pattern, subst) or nil
    local sf_lm   = args['krótka forma lm']   and myStringGSub(args['krótka forma lm'],   pattern, subst) or nil
    
    local ns = mw.title.getCurrentTitle():inNamespace(0)

    local adj  = args[1] and myTrim(args[1]) or nil
    local comp = args[2] and myTrim(args[2]) or nil
    comp = comp
        and ((comp == 'brak')
            and 'brak'
            or myStringGSub(comp, pattern, subst))
        or nil
    local sup  = args[3] and myTrim(args[3]) or nil
    
    if adj == nil then
        return '<b>podaj pierwszy parametr: stopień równy przymiotnika</b>' .. (ns
            and '[[Kategoria:Błąd w szablonie odmiany]]' or '')
    end
    
    local id = checkEnding(adj, poss)
    
    if id == 0 then
        return '<b>nie rozpoznano końcówki przymiotnika;' ..
        	' [[Dyskusja szablonu:odmiana-przymiotnik-rosyjski|zgłoś problem]]</b>' .. (ns
            	and '[[Kategoria:Błąd w szablonie odmiany]]' or '')
    end
    
    local stem = (id == 9)                  -- отцов
        and adj
        or (((id == 2) or (id == 5))        -- удалой, большой
            and myUStringSub(adj, 1, -4)
            or  myUStringSub(adj, 1, -3))
        
    local templates = {
        nzw = 'nżw', --frame:expandTemplate{ title = 'nżw' },
        zw = 'żw',   --frame:expandTemplate{ title = 'żw' },
        f = 'f',     --frame:expandTemplate{ title = 'f' },
        n = 'n'      --frame:expandTemplate{ title = 'n' }
    }
    
    local pos_degree = declensionTable(stem, id, templates)
    
    local grad = mw.html.create('')
    local innerTableCSS = { width = '100%', margin = '5px 0 0 0' }

    if comp == 'brak' then
    	grad:tag('tr')
    		:tag('td'):attr('colspan', 7):css{ padding = '0', border = 'none' }
    		:tag('table'):addClass('wikitable odmiana adj'):css(innerTableCSS)
    		:tag('tr')
    		:tag('th'):attr('colspan', 7)
    			:tag('b'):wikitext('&nbsp;nie stopniuje się')
    else
    	if comp then
    		grad:tag('tr')
    			:tag('td'):attr('colspan', 7):css{ padding = '0', border = 'none' }
    			:tag('table'):addClass(class):css(innerTableCSS)
    			:tag('tr')
    			:tag('th'):attr('colspan', 7):wikitext('&nbsp;stopień wyższy ')
    				:tag('b'):wikitext(comp)
    	end
    	
    	if sup then
    		grad:tag('tr')
    			:tag('td'):attr('colspan', 7):css{ padding = '0', border = 'none' }
    			:tag('table')
    				:addClass(class .. ' collapsible collapsed')
    				:css(innerTableCSS)
    			:tag('tr')
    				:tag('th'):attr('colspan', 7):wikitext('&nbsp;stopień najwyższy ')
    					:tag('b'):wikitext(sup):done():done():done()
    			:node(declensionTable(myUStringSub(sup, 1, -3), checkEnding(sup), templates))
    	end
    end
    
    local short_forms = mw.html.create('')
    
    short_forms:tag('tr'):tag('td'):attr('colspan', 7):css{
    	padding = '0',
    	border = 'none',
    	height = '5px',
    	background = '#FFFFFF'
    }
    
    if no_sf == 'nie' then
    	short_forms:tag('tr')
    		:tag('td'):wikitext("krótka forma"):addClass('forma'):done()
    		:tag('td'):wikitext("—"):attr('colspan', 2):done()
    		:tag('td'):wikitext("—"):done()
    		:tag('td'):wikitext("—"):done()
    		:tag('td'):wikitext("—"):attr('colspan', 2)
    elseif (sf_m_lp and sf_f_lp and sf_n_lp and sf_lm) then
    	short_forms:tag('tr')
    		:tag('td'):wikitext("krótka forma"):addClass('forma'):done()
    		:tag('td'):wikitext(sf_m_lp):attr('colspan', 2):done()
    		:tag('td'):wikitext(sf_f_lp):done()
    		:tag('td'):wikitext(sf_n_lp):done()
    		:tag('td'):wikitext(sf_lm):attr('colspan', 2)
    else
    	short_forms = nil
    end
    
    local html = mw.html.create('div')
    
    html:addClass('NavFrame collapse-odmiana'):css('display', 'inline')
    
    html:tag('div'):wikitext("&nbsp;"):addClass('NavHead'):css{
    	background = 'transparent',
    	['text-align'] = 'left',
    	['padding-right'] = '55px',
    	display = 'inline'
    }
    
    html:tag('div'):addClass('NavContent'):css{ ['text-align'] = 'left', display = 'inline' }
    	:tag('table'):addClass(class):cssText(style)
    		:node(pos_degree)
    		:node(short_forms)
    		:node(grad)
    
    return html
end

return p