| Contenidos de Wikipedia en español bajo licencia CC BY-SA 4.0 ⇔ Mapas de OpenStreetMap bajo licencia ODbL |
Módulo:XCols
De Hispanopedia
La documentación para este módulo puede ser creada en Módulo:XCols/doc
local p = {}
local SA = require "Module:SimpleArgs"
--local SD = require "Module:SimpleDebug"
--local TNTT = require "Module:TNTTools"
local dir = require "Module:Dir"
local RS = {
Lines = 'Lines',
Header = 'Header',
FreeHeader = 'FreeHeader',
Footer = 'Footer',
NumColumns = 'NumColumns',
NumDisplay = 'NumDisplay',
Width = 'Width',
SameWidth = 'SameWidth',
HAlign = 'HAlign',
VAlign = 'VAlign',
SepCols = 'SepCols',
BgColor = 'BgColor',
HeaderBgColor = 'HeaderBgColor',
FooterBgColor = 'FooterBgColor',
NColsBiggerNLabs = 'NColsBiggerNLabs',
}
local i18n = {
[RS.Lines] = "lines",
[RS.Header] = "header",
[RS.FreeHeader] = "free_header",
[RS.Footer] = "footer",
[RS.NumColumns] = "col_n",
[RS.NumDisplay] = "display_n",
[RS.Width] = "width",
[RS.SameWidth] = "same_width",
[RS.HAlign] = "h_align",
[RS.VAlign] = "v_align",
[RS.SepCols] = "col_sep",
[RS.BgColor] = "bg_color",
[RS.HeaderBgColor] = "header_bg_color",
[RS.FooterBgColor] = "footer_bg_color",
[RS.NColsBiggerNLabs] = "The column number ($1) is greater than the label number ($2)",
}
local I18n = 'XCols'
i18n = SA.loadI18n (I18n, i18n)
local function I18nStr (S, ...)
--return TNTT.GetMsgP (I18n, S, {...})
return SA.I18nStrParams (i18n[S], ...)
end
local function I18nStrArrOr1 (S)
--return TNTT.TabTransMT (I18n, S, 2)
return SA.I18nParamsTab (i18n[S])
end
local lang = mw.language.getContentLanguage().code
local dirh = ''
if dir.isRTL(lang) then
dirh = 'rtl'
else
dirh = 'ltr'
end
function p.MultiCol (splited, NCols, LinesByLin)
local NLines = 0
local LinCol = {}
local WithBreakLine = false
local HeightByLin = {}
local ColWidht = {}
function CountChBegin (s, achar)
local c = 1
for j = 2, #s do
if string.sub(s,j,j) == achar then
c = c + 1
else
break
end
end
return c
end --CountChBegin
function PrepareItems ()
local IsUl = false
local IsFirst = true
local NLinesCol = 0
for k, v in ipairs(LinesByLin) do
NLinesCol = NLinesCol + 1
v = mw.text.trim (v)
if splited then
local z = {}
table.insert (z, v)
LinesByLin[k] = z
else
v = mw.text.split(v, "\n")
LinesByLin[k] = v
end
end
WithBlankLin = false
for k, v in ipairs(LinesByLin) do
if #v > 1 then
WithBlankLin = true
end
local Char = string.sub(v[1],1,1) or ''
if Char == ';' then
local Sep = string.find(v[1],':') or 0
if Sep ~=0 then
local Temp = {}
local Begin = mw.text.trim (string.sub (v[1],1,Sep-1))
local End = mw.text.trim (string.sub (v[1],Sep+1))
table.insert (Temp, Begin)
table.insert (Temp, End)
for kk = 2, #v do
table.insert (Temp, v[kk])
end
LinesByLin[k] = Temp
end
end
end
local TempH = {}
for k, v in ipairs(LinesByLin) do
if #v == 1 then
table.insert (TempH, v)
else
local vz = {}
for kk, vv in ipairs(v) do
local Begin = string.sub(vv, 1, 3)
if (Begin == '---') then
if #vz > 0 then
table.insert (TempH, vz)
vz = {}
end
table.insert (TempH, {vv})
else
table.insert (vz, vv)
end
end
if #vz > 0 then
table.insert (TempH, vz)
end
end
end
LinesByLin = {}
for k, v in ipairs(TempH) do
table.insert (LinesByLin, v)
end
for k, v in ipairs(LinesByLin) do
local Begin = string.sub(v[1], 1, 3)
if (#v == 1) and (Begin == '---') then
WithBreakLine = true
break
end
end
if WithBreakLine then
local LinesByLinTemp = {}
local CurCol = 1
for k, v in ipairs(LinesByLin) do
local Begin = string.sub(v[1], 1, 3)
if (#v == 1) and (Begin == '---') then
if k ~= 1 then
CurCol = CurCol + 1
end
local width = string.sub(v[1], 4)
if width ~= '' then
SA.CheckSize (CurCol, width)
end
table.insert (ColWidht, width)
else
table.insert (LinesByLinTemp, v)
table.insert (LinCol, CurCol)
end
end
NCols = CurCol
LinesByLin = {}
for k, v in ipairs(LinesByLinTemp) do
table.insert (LinesByLin, v)
end
else
if not WithBlankLin then
Levels = {}
local MaxLevel = 0
local MinLevel = 3
for k, v in ipairs(LinesByLin) do
local Begin = string.sub(v[1], 1, 1)
local Begin2 = string.sub(v[1], 2, 2)
function GetLev (achar)
if Begin2 == achar then
return 3
else
return 2
end
end
if Begin == '=' then
Lev = 0
elseif Begin == '*' then
Lev = GetLev ('*')
elseif Begin == '#' then
Lev = GetLev ('#')
elseif Begin == ':' then
Lev = GetLev (':')
else
Lev = 1
end
MinLevel = math.min (MinLevel, Lev)
MaxLevel = math.max (MaxLevel, Lev)
table.insert (Levels, Lev)
end
local c = false
local various = MinLevel ~= MaxLevel
if various then
local LinesByLinTemp = {}
local Lines = {}
for k, v in ipairs(LinesByLin) do
if Levels[k] == MinLevel then
if #Lines == 0 then
table.insert (Lines, v[1])
else
table.insert (LinesByLinTemp, Lines)
Lines = {v[1]}
end
else
table.insert (Lines, v[1])
end
end
table.insert (LinesByLinTemp, Lines)
LinesByLin = {}
for k, v in ipairs(LinesByLinTemp) do
table.insert (LinesByLin, v)
end
end
end
for k, v in ipairs(LinesByLin) do
table.insert (LinCol, 1)
local h = 0
for kk, vv in ipairs(v) do
local HByL = 0
if kk == 1 then
local Char = string.sub(vv,1,1) or ''
if Char == '=' then
local HH = {2, 1.8, 1.38, 1.28, 1.2}
local c = CountChBegin (vv, '=')
HByL = HH[c]
elseif (Char == ';') or (Char == '*') then
HByL = 0.8
elseif #v > 1 then
local Char = string.sub(v[2],1,1) or ''
if (Char == '*') or (Char == '#') or (Char == ':') then
HByL = 1
else
HByL = 0.8
end
else
HByL = 1
end
elseif kk == #v then
HByL = 1
else
HByL = 0.8
end
h = h + HByL
end
table.insert (HeightByLin, h)
NLines = NLines + h
end
end
end --PrepareItems
function SetColToLines ()
local AbsLinesPerCol = 0
function CalcLinesPerCol (L,C)
AbsLinesPerCol = L/C
end
CalcLinesPerCol (NLines, NCols)
local DoItN = 0
local LinesForDo = NLines
local ColsForDo = NCols
local CurrCol = 1
for k, v in ipairs(LinesByLin) do
local fornext = false
if (CurrCol < NCols) and (((AbsLinesPerCol - DoItN) + (HeightByLin[k]/2)) < ((DoItN + HeightByLin[k]) - AbsLinesPerCol)) then
LinesForDo = LinesForDo - DoItN
CalcLinesPerCol (LinesForDo, ColsForDo-1)
CurrCol = CurrCol + 1
DoItN = HeightByLin[k]
ColsForDo = ColsForDo - 1
else
DoItN = DoItN + HeightByLin[k]
end
LinCol[k] = CurrCol
end
end --SetColToLines
function TheItems ()
local IsUl = 0
local IsUlIntra = false
local LastWasUl = false
local IsOl = 0
local IsOlIntra = false
local LastWasOl = false
local IsDl = false
local IsDlx = false
local IsDlIntra = false
local LastWasDl = false
local Lines = {}
local vv = ''
local Result = {}
local CurrCol = 1
function SplitChBegin0 (k, i, achar)
local s = LinesByLin[k][i]
local c = 1
for j = 2, #s do
if string.sub(s,j,j) == achar then
c = c + 1
else
break
end
end
return mw.text.trim (string.sub(s,c+1)), c
end --SplitChBegin0
function SplitChBegin (k, i, achar)
local s, c = SplitChBegin0 (k, i, achar)
LinesByLin[k][i] = '<li>'..s..'</li>'
return c
end --SplitChBegin
function WithHeader (k, i)
local s, c = SplitChBegin0 (k, i, '=')
local cc = 0
for j = #s, 1, -1 do
if string.sub(s,j,j) == '=' then
cc = cc + 1
else
break
end
end
s = string.sub (s,1,#s-cc)
LinesByLin[k][i] = '<h'..c..'>'..s..'</h'..c..'>'
end --WithHeader
function AddClose (num, achar)
for i = 1, num do
vv = vv..'</'..achar..'l>'
end
end --AddClose
function OnEnd ()
if IsUl > 0 then
AddClose (IsUl, 'u')
IsUl = 0
elseif IsOl > 0 then
AddClose (IsOl, 'o')
IsOl = 0
elseif IsDlx then
vv = vv..'</dl>'
IsDlx = false
elseif IsDl then
vv = vv..'</dl>'
IsDl = false
end
end --OnEnd
for k, v in ipairs(LinesByLin) do
if #v ~= 1 then
vv = vv..'<p>'
end
for i, j in ipairs(LinesByLin[k]) do
function BetweenAny (What)
LinesByLin[k][i] = '<'..What..'>'..string.sub(LinesByLin[k][i], 2)..'</'..What..'>'
end
function BeginUlOrOlOrDl (What)
LinesByLin[k][i] = '<'..What..'l>'..LinesByLin[k][i]
end
function EndUlOrOlOrDl (What)
LinesByLin[k][i] = '</'..What..'l>'..LinesByLin[k][i]
end
function BeginOrEndUlOrOl (IniV, NewV, achar)
local IsBegin = IniV < NewV
local s = ''
if IsBegin then
for k = 1, NewV-IniV do
s = s..'<'..achar..'l>'
end
else
for k = 1, (IniV-NewV)-1 do
s = s..'</'..achar..'l>'
end
EndUlOrOlOrDl (achar)
end
LinesByLin[k][i] = s..LinesByLin[k][i]
end --BeginOrEndUlOrOl
local Char = string.sub(LinesByLin[k][i],1,1) or ''
if Char == '*' then
local c = SplitChBegin (k, i, '*')
if IsUl ~= c then
BeginOrEndUlOrOl (IsUl, c, 'u')
IsUl = c
end
IsUlIntra = i > 1
elseif Char == '#' then
local c = SplitChBegin (k, i, '#')
if IsOl ~= c then
BeginOrEndUlOrOl (IsUl, c, 'o')
IsOl = c
end
IsOlIntra = i > 1
elseif Char == '=' then
OnEnd ()
WithHeader (k, i)
elseif Char == ';' then
BetweenAny ('dt')
BeginUlOrOlOrDl ('d')
IsDlx = true
elseif Char == ':' then
BetweenAny ('dd')
if not IsDl then
BeginUlOrOlOrDl ('d')
end
IsDl = true
IsDlIntra = i > 1
else
if #v == 1 then
LinesByLin[k][i] = '<p>'..LinesByLin[k][i]..'</p>'
elseif i ~= #LinesByLin[k] then
LinesByLin[k][i] = LinesByLin[k][i]..'<br>'
end
if IsUl > 0 then
BeginOrEndUlOrOl (IsUl, 0, 'u')
IsUl = 0
end
if IsOl > 0 then
BeginOrEndUlOrOl (IsUl, 0, 'o')
IsOl = 0
end
if IsDl then
EndUlOrOlOrDl ('d')
end
if IsDlx then
LinesByLin[k][i] = '<dd>'..LinesByLin[k][i]..'</dd>'
end
IsUlIntra = false
IsOlIntra = false
IsDlIntra = false
end
--revised intralin
if vv ~= '' then
if IsUl > 0 then
vv = vv..LinesByLin[k][i]
if (i < #LinesByLin[k]) and ((LinesByLin[k][i+1] == '') or (string.sub(LinesByLin[k][i+1],1,1) ~= '*')) then
vv = vv..'</ul>'
IsUl = IsUl - 1
IsUlIntra = false
LastWasUl = true
end
elseif IsOl > 0 then
vv = vv..LinesByLin[k][i]
if (i < #LinesByLin[k]) and ((LinesByLin[k][i+1] == '') or (string.sub(LinesByLin[k][i+1],1,1) ~= '#')) then
vv = vv..'</ol>'
IsOl = IsOl - 1
IsOlIntra = false
LastWasOl = true
end
elseif IsDl then
vv = vv..LinesByLin[k][i]
if (i < #LinesByLin[k]) and ((LinesByLin[k][i+1] == '') or (string.sub(LinesByLin[k][i+1],1,1) ~= ':')) then
vv = vv..'</dl>'
IsDl = false
IsDlIntra = false
LastWasDl = true
end
elseif LastWasUl then
vv = vv..LinesByLin[k][i]
LastWasUl = false
elseif LastWasOl then
vv = vv..LinesByLin[k][i]
LastWasOl = false
elseif LastWasDl then
vv = vv..LinesByLin[k][i]
LastWasDl = false
else
vv = vv..LinesByLin[k][i]
end
else
vv = LinesByLin[k][i]
end
end
--revised lin with lines
if IsUlIntra then
AddClose (IsUl, 'u')
IsUl = 0
IsUlIntra = false
end
if IsOlIntra then
AddClose (IsOl, 'o')
IsOl = 0
IsOlIntra = false
end
if IsDlx then
vv = vv..'</dl>'
IsDlx = false
end
if IsDlIntra then
vv = vv..'</dl>'
IsDl = false
IsDlIntra = false
end
if #v ~= 1 then
vv = vv..'</p>'
end
local IsLastLine = (k == #LinesByLin)
if IsLastLine or (CurrCol ~= LinCol[k+1]) then
if not IsLastLine then
CurrCol = LinCol[k+1]
end
OnEnd ()
if vv ~= '' then
table.insert(Result, vv)
vv = ''
end
end
end
return Result
end --TheItems
PrepareItems()
if (not WithBreakLine) then
SetColToLines ()
end
return TheItems (true), NCols, ColWidht
end --MultiCol
function p.MultiColX (splited, width, same_width, sep_cols, NCols, Lines, h_align, v_align, header, footer, bg_color, free_header, header_bg_color, footer_bg_color)
Lines, NCols, ColWidht = p.MultiCol (splited, NCols, Lines)
local col_width = ''
if same_width then
col_width = math.floor(100/NCols)..'%'
end
local td = {}
local s = mw.html.create("table")
function AddAny (S, IsHeader, Color)
if (S ~= nil) and (S ~= '') then
local tr = s:newline():tag('tr')
if Color ~= nil then
tr: css ('background-color', Color)
end
local td = tr:newline():tag('td')
:attr('colspan', NCols)
if Color ~= nil then
td: css ('padding-right', '0.3em')
td: css ('padding-left', '0.3em')
td: css ('padding-top', '0.2em')
td: css ('padding-bottom', '0.2em')
end
if IsHeader then
local d = td:newline():tag('div')
:addClass ('center')
:css ('width', 'auto')
:css ('margin-left', 'auto')
:css ('margin-right', 'auto')
:wikitext ( "'''"..S.."'''")
else
S = mw.text.split (S, "\n")
S = table.concat(S, '<br>')
td :wikitext (S)
end
end
end
s: attr ('direction', dirh)
if h_align ~= nil then
s: attr ('align', h_align)
if h_align ~= 'center' then
s: css ('padding-left', '8px')
s: css ('padding-right', '8px')
if h_align == 'right' then
s: css ('margin-left', '12px')
elseif h_align == 'left' then
s: css ('margin-right', '12px')
end
end
end
if width ~= nil then
s: css ('width', width)
end
if bg_color ~= nil then
s: css ('background-color', bg_color)
s: css ('padding-right', sep_cols)
s: css ('padding-left', sep_cols)
end
AddAny (header, true, header_bg_color)
AddAny (free_header, false, header_bg_color)
local tr = s:newline():tag('tr')
if v_align ~= nil then
tr:attr ('valign', v_align)
end
for k = 1, NCols do
td[k] = tr:newline():tag('td')
if same_width then
td[k]:css ('width', col_width)
elseif (#ColWidht > 0) and (ColWidht[k] ~= '') then
td[k]:css ('width', ColWidht[k])
end
local AddRight = false
local AddLeft = false
if NCols > 1 then
if k == 1 then
if dir.isRTL(lang) then
AddLeft = true
else
AddRight = true
end
elseif k == NCols then
if dir.isRTL(lang) then
AddRight = true
else
AddLeft = true
end
else
AddRight = true
AddLeft = true
end
end
if AddRight then
td[k] :css ('padding-right', sep_cols)
end
if AddLeft then
td[k] :css ('padding-left', sep_cols)
end
td[k]:wikitext (Lines[k])
end
AddAny (footer, false, footer_bg_color)
return tostring (s)
end --MultiColX
function p.MainVals (args, Required)
local lines = ''
if Required then
lines = SA.RStr_Par (args, I18nStrArrOr1(RS.Lines))
else
lines = SA.Str_Par (args, I18nStrArrOr1(RS.Lines))
end
local NLines = 0
local splited = false
if lines ~= nil then
lines = mw.text.split(mw.text.trim(lines), "\n\n")
NLines = #lines
if NLines == 1 then
lines = mw.text.split (lines[1], "\n")
NLines = #lines
splited = true
end
end
local NCols = SA.PosInt_Par (args, I18nStrArrOr1(RS.NumColumns), 1, 1, 10)
local width = SA.Size_Par (args, I18nStrArrOr1(RS.Width), true, {perc={20,100},em={12,119},px={200,1900}})
local same_width = SA.Bool_Par (args, I18nStrArrOr1(RS.SameWidth), false)
local sep_cols = SA.Size_Par (args, I18nStrArrOr1(RS.SepCols), false, {em={0.6,2.2},px={9,36}}, '0.6em')
local h_align = SA.HAlign_Par (args, I18nStrArrOr1(RS.HAlign))
local v_align = SA.VAlign_Par (args, I18nStrArrOr1(RS.VAlign), 'top')
local header = SA.Str_Par (args, I18nStrArrOr1(RS.Header))
local footer = SA.Str_Par (args, I18nStrArrOr1(RS.Footer))
return splited, NLines, lines, NCols, width, same_width, sep_cols, h_align, v_align, header, footer
end --MainVals
function p.main (frame)
local args,NArgs = SA.GetArgs (frame)
if NArgs == 0 then return end
local splited, NLines, Lines, NCols, width, same_width, sep_cols, h_align, v_align, header, footer, bg_color, free_header, header_bg_color = p.MainVals (args, true)
if NCols > NLines then
error (I18nStr (RS.NColsBiggerNLabs, NCols, NLines))
else
local bg_color = SA.Str_Par (args, I18nStrArrOr1(RS.BgColor))
local free_header = SA.Str_Par (args, I18nStrArrOr1(RS.FreeHeader))
local header_bg_color = SA.Str_Par (args, I18nStrArrOr1(RS.HeaderBgColor))
local footer_bg_color = SA.Str_Par (args, I18nStrArrOr1(RS.FooterBgColor))
return p.MultiColX (splited, width, same_width, sep_cols, NCols, Lines, h_align, v_align, header, footer, bg_color, free_header, header_bg_color, footer_bg_color)
end
end --main
return p