Modul:Popis epizoda
Dokumentacija modula
| Koristi Lua modul: |
Modul Popis epizoda omogućava funkcioniranje predloška {{popis epizoda}}. Modul stvara tablicu s podesivom bojom, širinom i tekstom zaglavlja te redove s informacijama o pojedinim epizodama.
Upotreba
{{#invoke:Popis epizoda|popis}}
Kategorije za praćenje
local p = {}
local dateModule = require('Module:Formatiraj datum')
function p.popis(frame)
local args = frame:getParent().args
local output = {}
-- Prikazuje "Nadolazeća epizoda"
local function nadolazeca()
return '<span class="skin-nightmode-reset-color tv-tba" style="background:#eceff2; padding:1px 5px; border-radius:7px; display:inline-block; font-size:88%"><abbr title="Nadolazeća epizoda">N/E</abbr></span>'
end
-- Prikazuje "Nema podataka"
local function nemapodataka()
return '<span class="skin-nightmode-reset-color tv-tba" style="background:#eceff2; padding:1px 5px; border-radius:7px; display:inline-block; font-size:88%"><abbr title="Nema podataka">n.p.</abbr></span>'
end
-- Dohvaća boju zaglavlja i linija
local rawColor = args["boja"] or args["pozadina"]
local defaultColor = (rawColor and mw.text.trim(rawColor) ~= "") and rawColor or "#CCF"
local textColor = frame:expandTemplate{
title = "Jači kontrast boja",
args = { defaultColor, "white", "black" }
}
-- Dohvaća širinu tablice
local rawWidth = args["širina"]
local tableWidth = "100%"
if rawWidth and rawWidth ~= "" then
if mw.ustring.match(rawWidth, "%%$") then
tableWidth = rawWidth
else
tableWidth = rawWidth .. "%"
end
end
-- Postavlja zastavice za parametre
local flags = {
useBroj = false, useBrojsve = false, bothUsed = false, hasDatumHR = false, hasDatum = false,
hasNaslov = false, hasProducent = false, hasRedatelj = false, hasScenarist = false, hasAuxA = false,
hasAuxB = false, hasAuxC = false, hasAuxD = false, hasAuxE = false, hasGledanost = false,
hasDatumALT = false, hasGosti = false, hasTrajanje = false, hasProdkod = false
}
-- Ključevi za provjeru
local dioAnchors = {
"brojsve", "broj", "naslov", "naslovHR", "datum", "datumHR", "datumALT", "scenarist",
"redatelj", "producent", "gledanost", "auxA", "auxB", "auxC", "auxD", "auxE", "gosti", "trajanje", "prodkod"
}
-- Ključevi za reference u zaglavlju
local headerRefKeys = {
naslov = "izvor naslov", naslovHR = "izvor naslovHR", datum = "izvor datum",
datumALT = "izvor datumALT", datumHR = "izvor datumHR", scenarist = "izvor scenarist",
redatelj = "izvor redatelj", producent = "izvor producent", prodkod = "izvor prodkod", gledanost = "izvor gledanost"
}
local lastBrojsve, lastBroj
local concat = table.concat
-- Traži maksimalan broj dijelova
local function getMaxDio(i, keyPrefix)
local max = 0
for d = 1, 100 do
if args[keyPrefix .. i .. "dio" .. d] and args[keyPrefix .. i .. "dio" .. d] ~= "" then
max = d
end
end
return max > 0 and max or 1
end
-- Dohvaća vrijednost dijela
local function getDioValue(i, key, d)
local val = args[key .. i .. "dio" .. d]
return (val and val ~= "") and val or nil
end
-- Dohvaća naslov po dijelovima
local function getDioNaslovVariants(i, d)
local results = {}
local key = "naslov" .. i .. "dio" .. d
local refKey = "Rnaslov" .. i .. "dio" .. d
local val = args[key]
local ref = args[refKey] or ""
if val and val ~= "" then
if string.match(val, "%s/%s") then
local parts = mw.text.split(val, "%s/%s")
for _, part in ipairs(parts) do
table.insert(results, { text = part, ref = "" })
end
if ref ~= "" and #results > 0 then
results[#results].ref = ref
end
else
table.insert(results, { text = val, ref = ref })
end
elseif ref ~= "" then
table.insert(results, { text = "", ref = ref })
end
return results
end
-- Računa broj redova za spajanje
local function getRowSpan(i, keyPrefix, maxDio, startDio)
for d = startDio + 1, maxDio do
local val = args[keyPrefix .. i .. "dio" .. d]
local hasAny = false
for _, anchor in ipairs(dioAnchors) do
local otherVal = args[anchor .. i .. "dio" .. d]
if otherVal and otherVal ~= "" then
hasAny = true
break
end
end
if val and val ~= "" then
return d - startDio
elseif not hasAny then
return d - startDio
end
end
return maxDio - startDio + 1
end
-- Vraća maksimalan broj dijelova
local function getMaxDioAcrossKeys(i, keys)
local max = 1
for _, key in ipairs(keys) do
local count = getMaxDio(i, key)
if count > max then max = count end
end
return max
end
-- Provjerava postoji li naslov
local function hasNaslov(i)
if args["naslov" .. i] or args["Rnaslov" .. i] then return true end
for d = 1, 100 do
local key = "naslov" .. i .. "dio" .. d
local refKey = "Rnaslov" .. i .. "dio" .. d
if (args[key] and args[key] ~= "") or (args[refKey] and args[refKey] ~= "") then
return true
end
end
return false
end
-- Provjerava postoji li ALT naslov
local function hasAlt(i)
return args["naslovALT" .. i] or args["RnaslovALT" .. i]
end
-- Dohvaća varijante naslova
local function getTitleVariants(prefix, i)
local results = {}
local key = prefix .. i
local val = args[key]
local ref = args["R" .. prefix .. i] or ""
if val and val ~= "" then
if string.match(val, "%s/%s") then
local parts = mw.text.split(val, "%s/%s")
for _, part in ipairs(parts) do
table.insert(results, { text = part, ref = ref })
end
else
table.insert(results, { text = val, ref = ref })
end
elseif ref ~= "" then
table.insert(results, { text = "", ref = ref })
end
return results
end
-- Dohvaća vrijednost polja
local function getValue(i, key)
if key == "redatelj" then return args["redatelj" .. i] or args["režija" .. i] or "" end
if key == "scenarist" then return args["scenarist" .. i] or args["scenarij" .. i] or "" end
if key == "gosti" then return args["gosti" .. i] or "" end
if key == "trajanje" then return args["trajanje" .. i] or "" end
if key == "prodkod" then return args["prodkod" .. i] or "" end
return args[key .. i] or ""
end
-- Provjerava ima li sadržaja
local function hasAnyContent(i)
for _, key in ipairs(dioAnchors) do
if args[key .. i] and args[key .. i] ~= "" then
return true
end
end
for _, key in ipairs(dioAnchors) do
for d = 1, 100 do
if args[key .. i .. "dio" .. d] and args[key .. i .. "dio" .. d] ~= "" then
return true
end
end
end
if args["Rnaslov" .. i] and args["Rnaslov" .. i] ~= "" then
return true
end
if args["kratkisadržaj" .. i] or args["sadržaj" .. i] then
return true
end
return false
end
-- Gradi naslov epizode
local function buildNaslov(i)
local useQuotes = not (args["navodnici"] == "ne")
local function splitAndQuote(text)
local parts = {}
local i_pos = 1
while i_pos <= #text do
local hrStart, hrEnd = mw.ustring.find(text, "<hr>", i_pos, true)
local brStart, brEnd = mw.ustring.find(text, "<br>", i_pos, true)
local slashStart, slashEnd = mw.ustring.find(text, " / ", i_pos)
local nextBreak, breakType, breakEnd
if hrStart then nextBreak = hrStart; breakType = "<hr>"; breakEnd = hrEnd end
if brStart and (not nextBreak or brStart < nextBreak) then nextBreak = brStart; breakType = "<br>"; breakEnd = brEnd end
if slashStart and (not nextBreak or slashStart < nextBreak) then nextBreak = slashStart; breakType = " / "; breakEnd = slashEnd end
if nextBreak then
local segment = mw.text.trim(mw.ustring.sub(text, i_pos, nextBreak - 1))
table.insert(parts, useQuotes and ('"' .. segment .. '"') or segment)
table.insert(parts, breakType)
i_pos = breakEnd + 1
else
local segment = mw.text.trim(mw.ustring.sub(text, i_pos))
table.insert(parts, useQuotes and ('"' .. segment .. '"') or segment)
break
end
end
return table.concat(parts)
end
local function formatVariants(variants, separator)
if #variants == 0 then return "" end
local parts = {}
for index, item in ipairs(variants) do
local text = item.text
local ref = item.ref
local quoted = splitAndQuote(text)
if index == #variants and ref and ref ~= "" then
quoted = quoted .. ref
end
table.insert(parts, quoted)
end
return separator .. table.concat(parts, " / ")
end
local dio1Variants = getDioNaslovVariants(i, 1)
if #dio1Variants > 0 then
local allDioVariants = {}
for d = 1, 100 do
local dioVariants = getDioNaslovVariants(i, d)
for _, v in ipairs(dioVariants) do
table.insert(allDioVariants, v)
end
end
return formatVariants(allDioVariants, "")
end
local mainVariants = getTitleVariants("naslov", i)
if #mainVariants == 1 then
local valUpper = mw.ustring.upper(mainVariants[1].text or "")
if valUpper == "NE" or valUpper == "N/E" then
return nadolazeca()
end
end
local altVariants = getTitleVariants("naslovALT", i)
local alt
if #altVariants == 1 then
local valUpper = mw.ustring.upper(altVariants[1].text or "")
if valUpper == "NE" or valUpper == "N/E" then
alt = '<br>' .. nadolazeca()
else
alt = formatVariants(altVariants, "<br>")
end
else
alt = formatVariants(altVariants, "<br>")
end
local main = formatVariants(mainVariants, "")
return main .. alt
end
-- Gradi hrvatski naslov
local function buildNaslovHR(i)
local useQuotes = not (args["navodnici"] == "ne")
local naslov = args["naslovHR" .. i]
local valUpper = mw.ustring.upper(naslov or "")
if valUpper == "NE" or valUpper == "N/E" then
return nadolazeca()
end
local ref = args["RnaslovHR" .. i] or ""
if naslov and naslov ~= "" then
local normalized = mw.ustring.gsub(naslov, "<hr>", "§§<hr>§§")
normalized = mw.ustring.gsub(normalized, "<br>", "§§<br>§§")
normalized = mw.ustring.gsub(normalized, " / ", "§§")
local parts = mw.text.split(normalized, "§§")
local quoted = {}
for _, part in ipairs(parts) do
local trimmed = mw.text.trim(part)
if trimmed == "<hr>" or trimmed == "<br>" then
table.insert(quoted, trimmed)
else
table.insert(quoted, useQuotes and ('"' .. trimmed .. '"') or trimmed)
end
end
local result = ""
for i_idx, part in ipairs(quoted) do
if i_idx > 1 and part ~= "<hr>" and part ~= "<br>" and quoted[i_idx - 1] ~= "<hr>" and quoted[i_idx - 1] ~= "<br>" then
result = result .. " / "
end
result = result .. part
end
if ref ~= "" then result = result .. ref end
return result
elseif ref ~= "" then
return ref
end
return ""
end
-- Prikupljanje indeksa epizoda
local episodeIndices = {}
for k, v in pairs(args) do
local match = string.match(k, "^%a+(%d+)$")
if match and v ~= "" then
local index = tonumber(match)
if index then
episodeIndices[index] = true
end
end
local dioMatch = string.match(k, "^%a+(%d+)dio%d+$")
if dioMatch and v ~= "" then
local index = tonumber(dioMatch)
if index then
episodeIndices[index] = true
end
end
end
-- Sortiranje epizoda
local sortedIndices = {}
for index in pairs(episodeIndices) do
table.insert(sortedIndices, index)
end
table.sort(sortedIndices)
-- Glavna petlja za epizode
for _, i in ipairs(sortedIndices) do
-- Automatski broj epizode u seriji
if args["brojsve" .. i] then
lastBrojsve = args["brojsve" .. i]
elseif lastBrojsve then
local num = tonumber(string.match(lastBrojsve, "%d+"))
if num then
args["brojsve" .. i] = tostring(num + 1) .. "."
lastBrojsve = args["brojsve" .. i]
end
end
-- Check for dio parameters in brojsve
for d = 1, 100 do
if args["brojsve" .. i .. "dio" .. d] and args["brojsve" .. i .. "dio" .. d] ~= "" then
lastBrojsve = args["brojsve" .. i .. "dio" .. d]
end
end
-- Automatski broj epizode u sezoni
if args["broj" .. i] then
lastBroj = args["broj" .. i]
elseif lastBroj then
local num = tonumber(string.match(lastBroj, "%d+"))
if num then
args["broj" .. i] = tostring(num + 1) .. "."
lastBroj = args["broj" .. i]
end
end
-- Provjeri dio za posljednji broj
for d = 1, 100 do
if args["broj" .. i .. "dio" .. d] and args["broj" .. i .. "dio" .. d] ~= "" then
lastBroj = args["broj" .. i .. "dio" .. d]
end
end
-- Postavljanje zastavica za stupce
if ((args["broj" .. i] and args["broj" .. i] ~= "") or (args["broj" .. i .. "dio1"] and args["broj" .. i .. "dio1"] ~= "")) and ((args["brojsve" .. i] and args["brojsve" .. i] ~= "") or (args["brojsve" .. i .. "dio1"] and args["brojsve" .. i .. "dio1"] ~= "")) then flags.bothUsed = true end
if (args["broj" .. i] and args["broj" .. i] ~= "") or (args["broj" .. i .. "dio1"] and args["broj" .. i .. "dio1"] ~= "") then flags.useBroj = true end
if (args["brojsve" .. i] and args["brojsve" .. i] ~= "") or (args["brojsve" .. i .. "dio1"] and args["brojsve" .. i .. "dio1"] ~= "") then flags.useBrojsve = true end
if (args["gosti" .. i] and args["gosti" .. i] ~= "") or (args["gosti" .. i .. "dio1"] and args["gosti" .. i .. "dio1"] ~= "") then flags.hasGosti = true end
if (args["trajanje" .. i] and args["trajanje" .. i] ~= "") or (args["trajanje" .. i .. "dio1"] and args["trajanje" .. i .. "dio1"] ~= "") then flags.hasTrajanje = true end
if (args["datum" .. i] and args["datum" .. i] ~= "") or (args["datum" .. i .. "dio1"] and args["datum" .. i .. "dio1"] ~= "") then flags.hasDatum = true end
if (args["datumHR" .. i] and args["datumHR" .. i] ~= "") or (args["datumHR" .. i .. "dio1"] and args["datumHR" .. i .. "dio1"] ~= "") then flags.hasDatumHR = true end
if (args["datumALT" .. i] and args["datumALT" .. i] ~= "") or (args["datumALT" .. i .. "dio1"] and args["datumALT" .. i .. "dio1"] ~= "") then flags.hasDatumALT = true end
if (args["prodkod" .. i] and args["prodkod" .. i] ~= "") or (args["prodkod" .. i .. "dio1"] and args["prodkod" .. i .. "dio1"] ~= "") then flags.hasProdkod = true end
if hasNaslov(i) or hasAlt(i) or (args["naslov" .. i .. "dio1"] and args["naslov" .. i .. "dio1"] ~= "") or args["Rnaslov" .. i] then flags.hasNaslov = true end
if (args["naslovHR" .. i] and args["naslovHR" .. i] ~= "") or args["RnaslovHR" .. i] or (args["naslovHR" .. i .. "dio1"] and args["naslovHR" .. i .. "dio1"] ~= "") then flags.hasNaslovHR = true end
if (args["producent" .. i] and args["producent" .. i] ~= "") or (args["producent" .. i .. "dio1"] and args["producent" .. i .. "dio1"] ~= "") then flags.hasProducent = true end
if (args["redatelj" .. i] and args["redatelj" .. i] ~= "") or (args["režija" .. i] and args["režija" .. i] ~= "") or (args["redatelj" .. i .. "dio1"] and args["redatelj" .. i .. "dio1"] ~= "") then flags.hasRedatelj = true end
if (args["scenarist" .. i] and args["scenarist" .. i] ~= "") or (args["scenarij" .. i] and args["scenarij" .. i] ~= "") or (args["scenarist" .. i .. "dio1"] and args["scenarist" .. i .. "dio1"] ~= "") then flags.hasScenarist = true end
local flagKeys = {
auxA = "hasAuxA", auxB = "hasAuxB", auxC = "hasAuxC",
auxD = "hasAuxD", auxE = "hasAuxE", gledanost = "hasGledanost"
}
for key, flag in pairs(flagKeys) do
if (args[key .. i] and args[key .. i] ~= "") or (args[key .. i .. "dio1"] and args[key .. i .. "dio1"] ~= "") then flags[flag] = true
end
end
end
-- Dohvaća tekst zaglavlja
local function getText(key, default)
return (args[key] and args[key] ~= "") and args[key] or default
end
-- Dohvaća širinu stupca
local function getWidth(key, default)
local raw = args[key]
if not raw or raw == "" then return default end
if mw.ustring.match(raw, "%%$") then
return raw
end
local val = tonumber(raw)
if val and val >= 1 and val <= 100 then
return val .. "%"
end
return default
end
-- Stvara reference za zaglavlje
local function buildReferenceSpan(reference)
if not reference or reference == "" then return "" end
local span = mw.html.create("span"):wikitext(reference)
span
:css("color", "black")
:css("background-color", "white")
:css("padding", "1px")
:css("display", "inline-block")
:css("line-height", "50%")
return " " .. tostring(span)
end
-- Generiranje zaglavlja tablice
local headers = {}
if flags.bothUsed then
table.insert(headers, {
text = getText("tekst brojsve", "<abbr title='Broj epizode'>Br.</abbr> u<br><span style='white-space:nowrap'>seriji</span>"),
width = getWidth("širina brojsve", "7%"),
key = "brojsve",
shaded = true
})
table.insert(headers, {
text = getText("tekst broj", "<abbr title='Broj epizode'>Br.</abbr> u <br><span style='white-space:nowrap'>sezoni</span>"),
width = getWidth("širina broj", "7%"),
key = "broj",
shaded = false
})
elseif flags.useBrojsve then
table.insert(headers, {
text = getText("tekst brojsve", "<abbr title='Broj epizode'>Br.</abbr>"),
width = getWidth("širina brojsve", "7%"),
key = "brojsve",
shaded = true
})
elseif flags.useBroj then
local shaded = not flags.useBrojsve
table.insert(headers, {
text = getText("tekst broj", "<abbr title='Broj epizode'>Br.</abbr>"),
width = getWidth("širina broj", "7%"),
key = "broj",
shaded = shaded
})
end
-- Dodatni stupci zaglavlja
local optionalHeaders = {
{ flag = "hasAuxA", textKey = "tekst auxA", defaultText = "auxA", widthKey = "širina auxA", defaultWidth = "15%", key = "auxA" },
{ flag = "hasNaslov", textKey = "tekst naslov", defaultText = "Naslov", widthKey = "širina naslov", defaultWidth = "35%", key = "naslov" },
{ flag = "hasNaslovHR", textKey = "tekst naslovHR", defaultText = "Hrvatski naslov", widthKey = "širina naslovHR", defaultWidth = getWidth("širina naslov", "35%"), key = "naslovHR" },
{ flag = "hasGosti", textKey = "tekst gosti", defaultText = "Gosti", widthKey = "širina gosti", defaultWidth = "20%", key = "gosti" },
{ flag = "hasAuxB", textKey = "tekst auxB", defaultText = "auxB", widthKey = "širina auxB", defaultWidth = "15%", key = "auxB" },
{ flag = "hasProducent", textKey = "tekst producent", defaultText = "Producent", widthKey = "širina producent", defaultWidth = "15%", key = "producent" },
{ flag = "hasRedatelj", textKey = "tekst redatelj", defaultText = args["tekst režija"] or "Redatelj", widthKey = "širina redatelj", defaultWidth = args["širina režija"] or "15%", key = "redatelj" },
{ flag = "hasScenarist", textKey = "tekst scenarist", defaultText = args["tekst scenarij"] or "Scenarist", widthKey = "širina scenarist", defaultWidth = args["širina scenarij"] or "15%", key = "scenarist" },
{ flag = "hasAuxC", textKey = "tekst auxC", defaultText = "auxC", widthKey = "širina auxC", defaultWidth = "15%", key = "auxC" },
{ flag = "hasAuxD", textKey = "tekst auxD", defaultText = "auxD", widthKey = "širina auxD", defaultWidth = "15%", key = "auxD" },
{ flag = "hasTrajanje", textKey = "tekst trajanje", defaultText = "Trajanje", widthKey = "širina trajanje", defaultWidth = "10%", key = "trajanje" },
{ flag = "hasDatum", textKey = "tekst datum", defaultText = flags.hasDatumHR and "Prvo prikazivanje" or "Prikazivanje", widthKey = "širina datum", defaultWidth = "25%", key = "datum" },
{ flag = "hasDatumALT", textKey = "tekst datumALT", defaultText = "Prikazivanje", widthKey = "širina datumALT", defaultWidth = "25%", key = "datumALT" },
{ flag = "hasDatumHR", textKey = "tekst datumHR", defaultText = "Prikazivanje u Hrvatskoj", widthKey = "širina datumHR", defaultWidth = "25%", key = "datumHR" },
{ flag = "hasProdkod", textKey = "tekst prodkod", defaultText = "<abbr title='Produkcijski'>Prod.</abbr><br>kôd", widthKey = "širina prodkod", defaultWidth = "5%", key = "prodkod" },
{ flag = "hasGledanost", textKey = "tekst gledanost", defaultText = "Gledanost", widthKey = "širina gledanost", defaultWidth = "1%", key = "gledanost" },
{ flag = "hasAuxE", textKey = "tekst auxE", defaultText = "auxE", widthKey = "širina auxE", defaultWidth = "15%", key = "auxE" },
}
for _, h in ipairs(optionalHeaders) do
if flags[h.flag] then
local label = getText(h.textKey, h.defaultText)
if h.key == "naslov" and args["extra naslov"] and args["extra naslov"] ~= "" then
label = label .. " " .. args["extra naslov"]
end
if h.key == "datum" and args["extra datum"] and args["extra datum"] ~= "" then
label = label .. " " .. args["extra datum"]
end
if h.key == "datumALT" and args["extra datumALT"] and args["extra datumALT"] ~= "" then
label = label .. " " .. args["extra datumALT"]
end
if h.key == "datumHR" and args["extra datumHR"] and args["extra datumHR"] ~= "" then
label = label .. " " .. args["extra datumHR"]
end
if h.key == "gledanost" and args["extra gledanost"] and args["extra gledanost"] ~= "" then
label = label .. " " .. args["extra gledanost"]
end
table.insert(headers, {
text = label,
width = getWidth(h.widthKey, h.defaultWidth),
key = h.key
})
end
end
-----------------------------------------
----- POČETAK TABLICE -----
-----------------------------------------
local numColumns = #headers
-- Veličina fonta (75-100%)
local fontSize = "100%"
if args["font"] and args["font"] ~= "" then
local rawFont = args["font"]
local numericFont = tonumber(rawFont:match("^%d+"))
if numericFont then
if numericFont < 75 then numericFont = 75
elseif numericFont > 100 then numericFont = 100
end
fontSize = numericFont .. "%"
end
end
-- Moguće skupljanje tablice
local collapseArg = (args["sklopi"] or args["collapse"] or ""):lower()
local collapseClass = ""
if collapseArg == "da" or collapseArg == "yes" then
collapseClass = " mw-collapsible mw-collapsed"
end
table.insert(output, string.format('{| class="wikitable%s" style="width:%s; font-size:%s"', collapseClass, tableWidth, fontSize))
-- Opis ispod tablice
if args["opis"] and args["opis"] ~= "" then
table.insert(output, "|+ " .. args["opis"])
end
-- Generiranje reda zaglavlja
local headerRow = {}
for _, h in ipairs(headers) do
local style = string.format('background-color:%s; color:%s; width:%s', defaultColor, textColor, h.width)
local label = h.text
local refArgKey = headerRefKeys[h.key]
if refArgKey then
local ref = args[refArgKey]
if ref and ref ~= "" then
label = label .. buildReferenceSpan(ref)
end
end
table.insert(headerRow, string.format('! style="%s" | %s', style, label))
end
table.insert(output, concat(headerRow, '\n'))
-- Određivanje prikaza sažetka
local title = mw.title.getCurrentTitle()
local currentPage = title.text
local targetPage = args["stranica"] or args["članak"] or args["1"]
local showSummary = not targetPage or mw.uri.anchorEncode(currentPage) == mw.uri.anchorEncode(targetPage)
-- Reset brojeva za novi prolaz
lastBrojsve = nil
lastBroj = nil
-- Glavna petlja za ispis redaka
for _, i in ipairs(sortedIndices) do
-- Automatski broj epizode u seriji
if not args["brojsve" .. i] and lastBrojsve then
local num = tonumber(string.match(lastBrojsve, "%d+"))
if num then
args["brojsve" .. i] = tostring(num + 1) .. "."
end
end
lastBrojsve = args["brojsve" .. i]
for d = 1, 100 do
if args["brojsve" .. i .. "dio" .. d] and args["brojsve" .. i .. "dio" .. d] ~= "" then
lastBrojsve = args["brojsve" .. i .. "dio" .. d]
end
end
-- Automatski broj epizode u sezoni
if not args["broj" .. i] and lastBroj then
local num = tonumber(string.match(lastBroj, "%d+"))
if num then
args["broj" .. i] = tostring(num + 1) .. "."
end
end
lastBroj = args["broj" .. i]
for d = 1, 100 do
if args["broj" .. i .. "dio" .. d] and args["broj" .. i .. "dio" .. d] ~= "" then
lastBroj = args["broj" .. i .. "dio" .. d]
end
end
-- Odjeljak (section) između epizoda
local odjeljakKey = "odjeljak" .. i
local odjeljakText = args[odjeljakKey]
if odjeljakText and odjeljakText ~= "" then
local backgroundColor = args["odjeljakboja" .. i] or args["boja"] or args["pozadina"] or "#ccccff"
local textColor = frame:expandTemplate{
title = "Jači kontrast boja",
args = { backgroundColor, "white", "black" }
}
local wrappedText = string.format(
'<div style="max-width: 90vw; position: sticky; left: 0.2em; text-align:center;">%s</div>',
odjeljakText
)
table.insert(output, "|-")
table.insert(output, string.format(
'! colspan="%d" style="background:%s; color:%s;" | %s',
numColumns, backgroundColor, textColor, wrappedText
))
table.insert(output, "|-")
end
-- Prikaz svih dijelova epizode
if hasAnyContent(i) then
local maxDio = getMaxDioAcrossKeys(i, dioAnchors)
for d = 1, maxDio do
local shouldRender = true
if d >= 3 then
shouldRender = false
for _, key in ipairs(dioAnchors) do
local val = args[key .. i .. "dio" .. (d - 1)]
if val and val ~= "" then
shouldRender = true
break
end
end
end
if shouldRender then
-- Anchor na broj epizode
local anchor = ""
local styleFix = ""
local rawBrojsve = ""
if d == 1 then
rawBrojsve = args["brojsve" .. i] or lastBrojsve or ""
if rawBrojsve == "" then
rawBrojsve = args["broj" .. i] or ""
end
end
if rawBrojsve == "" then
rawBrojsve = args["brojsve" .. i .. "dio" .. d] or ""
if rawBrojsve == "" then
rawBrojsve = args["broj" .. i .. "dio" .. d] or ""
end
end
local anchorNum = string.match(rawBrojsve, "%d+")
if anchorNum then
anchor = string.format('id="ep%s"', anchorNum)
styleFix = 'style="scroll-margin-top:80px;"'
end
table.insert(output, string.format('|- %s %s class="vevent TV-epizoda"', anchor, styleFix))
-- Prolazak kroz sve stupce
for _, h in ipairs(headers) do
local key = h.key
local dioVal = getDioValue(i, key, d)
local value = ""
if dioVal then
local span = getRowSpan(i, key, maxDio, d)
local style = (key == "gosti") and "text-align:left" or "text-align:center"
value = dioVal
-- Formatiranje datuma
if key == "datum" or key == "datumHR" or key == "datumALT" then
style = "text-align:center; white-space:nowrap"
local rawDateInput = dioVal
value = dateModule.televizija{ args = { [1] = dioVal, [2] = "dtstart" } }
if rawDateInput and rawDateInput ~= "" and not p.unformattedDateCategoryAdded then
-- expand template output so we can see the hidden span
local expanded = frame:preprocess(rawDateInput)
local dateToParse = expanded
local datePart = string.match(expanded, "^(.-)%s+%(([^)]+)%)s*$")
if datePart then dateToParse = mw.text.trim(datePart) end
local isFormatted = false
-- check for hidden ISO date inside the itvstart span
local hiddenISO = string.match(expanded, '>(%d%d%d%d%-%d%d%-%d%d)<')
or string.match(expanded, '>(%d%d%d%d%-%d%d)<')
or string.match(expanded, '>(%d%d%d%d)<')
if hiddenISO then
isFormatted = true
elseif mw.ustring.match(dateToParse, "^%d%d%d%d%-%d%d%-%d%d$") then
isFormatted = true
elseif mw.ustring.match(dateToParse, "^%d%d%d%d%-%d%d$") then
isFormatted = true
elseif mw.ustring.match(dateToParse, "^%d%d%d%d$") then
isFormatted = true
elseif dateModule.dohvatiISO(dateToParse) then
isFormatted = true
end
if not isFormatted and showSummary then
local category = frame:expandTemplate{
title = 'main other',
args = { '[[Kategorija:Popisi epizoda bez formatiranih datuma]]' }
}
table.insert(output, category)
p.unformattedDateCategoryAdded = true
end
end
-- Formatiranje naslova
elseif key == "naslov" or key == "naslovHR" or string.match(key, "^naslovHR%d+dio%d+$") then
style = "text-align:left"
local useQuotes = not (args["navodnici"] == "ne")
if string.match(dioVal, "%s/%s") then
local parts = mw.text.split(dioVal, "%s/%s")
local quoted = {}
for _, part in ipairs(parts) do
table.insert(quoted, useQuotes and ('"' .. part .. '"') or part)
end
value = table.concat(quoted, " / ")
else
value = useQuotes and ('"' .. dioVal .. '"') or dioVal
end
local valUpper = mw.ustring.upper(dioVal or "")
if valUpper == "NE" or valUpper == "N/E" then
value = nadolazeca()
end
value = string.format('<span class="summary">%s</span>', value)
else
value = dioVal
end
-- Dodavanje ćelije
if h.shaded then
if span > 1 then
table.insert(output, string.format(
'! rowspan="%d" style="font-weight:normal; %s" | %s',
span, style, value))
else
table.insert(output, string.format(
'! style="font-weight:normal; %s" | %s',
style, value))
end
else
if span > 1 then
table.insert(output, string.format(
'| rowspan="%d" style="%s" | %s',
span, style, value))
else
table.insert(output, string.format(
'| style="%s" | %s',
style, value))
end
end
-- Ako nema vrijednosti za dio, ali je prvi dio
elseif d == 1 then
if key == "naslov" then
local raw = buildNaslov(i)
if mw.text.trim(raw) == "" then
value = ""
else
value = string.format('<span class="summary">%s</span>', raw)
end
elseif key == "naslovHR" then
local raw = buildNaslovHR(i)
if mw.text.trim(raw) == "" then
value = ""
else
value = string.format('<span class="summary">%s</span>', raw)
end
elseif key == "datum" or key == "datumHR" or key == "datumALT" then
local originalValue = getValue(i, key)
local rawDateInput = originalValue
value = dateModule.televizija{ args = { [1] = originalValue, [2] = "dtstart" } }
if rawDateInput and rawDateInput ~= "" and not p.unformattedDateCategoryAdded then
-- expand template output so we can see the hidden span
local expanded = frame:preprocess(rawDateInput)
local dateToParse = expanded
local datePart = string.match(expanded, "^(.-)%s+%(([^)]+)%)s*$")
if datePart then dateToParse = mw.text.trim(datePart) end
local isFormatted = false
-- check for hidden ISO date inside the itvstart span
local hiddenISO = string.match(expanded, '>(%d%d%d%d%-%d%d%-%d%d)<')
or string.match(expanded, '>(%d%d%d%d%-%d%d)<')
or string.match(expanded, '>(%d%d%d%d)<')
if hiddenISO then
isFormatted = true
elseif mw.ustring.match(dateToParse, "^%d%d%d%d%-%d%d%-%d%d$") then
isFormatted = true
elseif mw.ustring.match(dateToParse, "^%d%d%d%d%-%d%d$") then
isFormatted = true
elseif mw.ustring.match(dateToParse, "^%d%d%d%d$") then
isFormatted = true
elseif dateModule.dohvatiISO(dateToParse) then
isFormatted = true
end
if not isFormatted and showSummary then
local category = frame:expandTemplate{
title = 'main other',
args = { '[[Kategorija:Popisi epizoda bez formatiranih datuma]]' }
}
table.insert(output, category)
p.unformattedDateCategoryAdded = true
end
end
else
value = getValue(i, key)
end
-- Logika za prazne ćelije
local praznoText = args["prazno"]
local innerText = value:match('<span[^>]*>(.-)</span>')
local isEmptySpan = innerText and mw.text.trim(innerText) == ""
local isUpcoming = false
local contentLang = mw.getContentLanguage()
local today = contentLang:formatDate('Y-m-d')
local function checkDateInFuture(dateInput)
if not dateInput or dateInput == "" then return false end
local isoDate = nil
-- Traži ISO datum iz predložaka poput {{premijera}}
local expanded = frame:preprocess(dateInput)
isoDate = string.match(expanded, '>(%d%d%d%d%-%d%d%-%d%d)<')
or string.match(expanded, '>(%d%d%d%d%-%d%d)<')
or string.match(expanded, '>(%d%d%d%d)<')
-- ako nema, sredi običan tekst
if not isoDate then
local dateToParse = expanded
local datePart = string.match(expanded, "^(.-)%s+%(([^)]+)%)s*$")
if datePart then dateToParse = mw.text.trim(datePart) end
isoDate = mw.ustring.match(dateToParse, "(%d%d%d%d%-%d%d%-%d%d)")
if not isoDate then isoDate = dateModule.dohvatiISO(dateToParse) end
end
if isoDate then return isoDate > today end
return false
end
-- provjera je li datum u budućnosti
if not isUpcoming then
local rawDateParam = args["datum" .. i]
if rawDateParam and rawDateParam ~= "" then
isUpcoming = checkDateInFuture(rawDateParam)
end
end
if not isUpcoming then
for dCheck = 1, 10 do
local rawDateParam = args["datum" .. i .. "dio" .. dCheck]
if rawDateParam and rawDateParam ~= "" then
if checkDateInFuture(rawDateParam) then
isUpcoming = true
break
end
end
end
end
-- naslovHR dobiva N/E ako je datumHR u budućnosti
local rawDateHR = args["datumHR" .. i]
local rawTitleHR = args["naslovHR" .. i]
if rawDateHR and checkDateInFuture(rawDateHR) then
if (not rawTitleHR or mw.text.trim(rawTitleHR) == "") and key == "naslovHR" and (not praznoText or praznoText == "") then
value = "N/E"
end
end
-- Kategorija za nadolazeće epizode (uvijek ako je datum u budućnosti)
if isUpcoming and showSummary and not p.upcomingCategoryAdded then
local category = frame:expandTemplate{
title = 'main other',
args = { '[[Kategorija:Stranice s nadolazećim televizijskim epizodama]]' }
}
table.insert(output, category)
p.upcomingCategoryAdded = true
end
-- Logika za praznoText
if not praznoText or praznoText == "" then
if (not value or value == "" or isEmptySpan) then
if isUpcoming then
value = nadolazeca()
else
value = nemapodataka()
if showSummary and not p.incompleteCategoryAdded then
local category = frame:expandTemplate{
title = 'main other',
args = { '[[Kategorija:Nepotpuni popisi epizoda]]' }
}
table.insert(output, category)
p.incompleteCategoryAdded = true
end
end
end
else
if (not value or value == "" or isEmptySpan) then
if praznoText == "NE" or praznoText == "N/E" then
value = nadolazeca()
else
value = string.format('<span class="skin-nightmode-reset-color tv-tba" style="background:#eceff2; padding:1px 5px; border-radius:7px; display:inline-block; font-size:88%%">%s</span>', praznoText)
end
end
end
if (not praznoText or praznoText == "") and (value == "NE" or value == "N/E") then
value = nadolazeca()
end
local span = getRowSpan(i, key, maxDio, d)
local style = (key == "gosti") and "text-align:left" or ""
if key == "broj" or key == "producent" or key == "redatelj" or key == "scenarist" or key == "gledanost"
or key == "auxA" or key == "auxB" or key == "auxC" or key == "auxD" or key == "auxE" or key == "trajanje" or key == "prodkod" then
style = "text-align:center"
elseif key == "datum" or key == "datumHR" or key == "datumALT" then
style = "text-align:center; white-space:nowrap"
end
if h.shaded then
if span > 1 then
table.insert(output, string.format(
'! rowspan="%d" style="font-weight:normal; %s" | %s',
span, style, value))
else
table.insert(output, string.format(
'! style="font-weight:normal; %s" | %s',
style, value))
end
else
if span > 1 then
table.insert(output, string.format(
'| rowspan="%d" style="%s" | %s',
span, style, value))
else
table.insert(output, string.format(
'| style="%s" | %s',
style, value))
end
end
end
end
end
end
end
-- Kratki sadržaj
local sadrzaj = args["kratkisadržaj" .. i] or args["sadržaj" .. i] or ""
if showSummary and sadrzaj ~= "" then
local nextOdjeljak = args["odjeljak" .. (i + 1)]
local style = ""
if not nextOdjeljak then
local lineColor = args["bojalinije" .. i] or defaultColor
style = string.format('style="border-bottom:3px solid %s"', lineColor)
end
local wrapped = string.format(
'<div style="max-width: 90vw; position: sticky; left: 0.2em;">%s</div>', sadrzaj)
table.insert(output, string.format(
'|- \n| colspan="%d" %s | %s', numColumns, style, wrapped))
end
end
table.insert(output, "|}")
return concat(output, "\n")
end
return p