Modul:Citation/CS1: razlika između inačica
Prijeđi na navigaciju
Prijeđi na pretraživanje
Nema sažetka uređivanja |
mNema sažetka uređivanja |
||
| Redak 11: | Redak 11: | ||
local whitelist = require('Module:Citation/CS1/Whitelist') | local whitelist = require('Module:Citation/CS1/Whitelist') | ||
local dateval = require('Module:Citation/CS1/Date_validation') | local dateval = require('Module:Citation/CS1/Date_validation') | ||
-- ISO 639-1 → naziv jezika (po potrebi širiš) | |||
local iso639 = { | |||
en = "engleski", | |||
de = "njemacki", | |||
fr = "francuski", | |||
es = "spanjolski", | |||
it = "talijanski", | |||
hr = "hrvatski", | |||
sr = "srpski", | |||
bs = "bosanski", | |||
sl = "slovenski", | |||
ru = "ruski", | |||
pl = "poljski", | |||
cs = "ceski", | |||
da = "danski", | |||
sv = "svedski", | |||
fi = "finski", | |||
nl = "nizozemski", | |||
} | |||
-- ISO 3166 (minimalno, širiš po potrebi) | |||
local iso3166 = { | |||
DE = "Njemacka", | |||
HR = "Hrvatska", | |||
AT = "Austrija", | |||
CH = "Svicaraska", | |||
IT = "Italija", | |||
FR = "Francuska", | |||
} | |||
local function normalizeLanguage(lang) | |||
if not lang then return nil end | |||
local code = mw.ustring.lower(mw.text.trim(lang)) | |||
return iso639[code] or lang | |||
end | |||
local function normalizeCountry(code) | |||
if not code then return nil end | |||
code = mw.ustring.upper(mw.text.trim(code)) | |||
return iso3166[code] or code | |||
end | |||
local function validateISBN(isbn) | |||
if not isbn then return nil end | |||
isbn = isbn:gsub("[^0-9Xx]", "") | |||
if #isbn == 10 then | |||
local sum = 0 | |||
for i = 1, 9 do | |||
sum = sum + tonumber(isbn:sub(i,i)) * (11 - i) | |||
end | |||
local check = isbn:sub(10,10) | |||
check = (check == "X" or check == "x") and 10 or tonumber(check) | |||
if (sum + check) % 11 == 0 then | |||
return isbn | |||
end | |||
return isbn .. " (neispravan ISBN-10)" | |||
end | |||
if #isbn == 13 then | |||
local sum = 0 | |||
for i = 1, 12 do | |||
local n = tonumber(isbn:sub(i,i)) | |||
sum = sum + (i % 2 == 0 and n * 3 or n) | |||
end | |||
local check = tonumber(isbn:sub(13,13)) | |||
if (10 - (sum % 10)) % 10 == check then | |||
return isbn | |||
end | |||
return isbn .. " (neispravan ISBN-13)" | |||
end | |||
return isbn .. " (neispravan format)" | |||
end | |||
local function formatEditors(args) | |||
local list = {} | |||
if util.is_set(args.editor) then | |||
table.insert(list, args.editor) | |||
end | |||
for i = 1, 9 do | |||
local e = args["editor" .. i] | |||
if util.is_set(e) then | |||
table.insert(list, e) | |||
end | |||
end | |||
if #list == 0 then return nil end | |||
if #list == 1 then return "Uredio: " .. list[1] end | |||
if #list == 2 then return "Uredili: " .. list[1] .. " i " .. list[2] end | |||
local last = table.remove(list) | |||
return "Uredili: " .. table.concat(list, ", ") .. " i " .. last | |||
end | |||
local function formatTranslators(args) | |||
local list = {} | |||
if util.is_set(args.translator) then | |||
table.insert(list, args.translator) | |||
end | |||
for i = 1, 9 do | |||
local t = args["translator" .. i] | |||
if util.is_set(t) then | |||
table.insert(list, t) | |||
end | |||
end | |||
if #list == 0 then return nil end | |||
if #list == 1 then return "Preveo: " .. list[1] end | |||
if #list == 2 then return "Preveli: " .. list[1] .. " i " .. list[2] end | |||
local last = table.remove(list) | |||
return "Preveli: " .. table.concat(list, ", ") .. " i " .. last | |||
end | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Redak 214: | Redak 331: | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- CITATION: | -- CITATION: BOOK | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
local function citeBook(args) | local function citeBook(args) | ||
local parts = {} | local parts = {} | ||
local lang_full = normalizeLanguage(args.language) | |||
local lang_full = | local isbn = args.isbn and validateISBN(args.isbn) or nil | ||
local country = normalizeCountry(args.country) | |||
table.insert(parts, sentence({ | table.insert(parts, sentence({ | ||
formatAuthors(args), | formatAuthors(args), | ||
| Redak 277: | Redak 350: | ||
})) | })) | ||
table.insert(parts, sentence({ | table.insert(parts, sentence({ | ||
formatEditors(args), | |||
formatTranslators(args), | |||
args.edition and (args.edition .. ". izd.") or nil, | args.edition and (args.edition .. ". izd.") or nil, | ||
args.series and ("Serija: " .. args.series) or nil, | args.series and ("Serija: " .. args.series) or nil, | ||
args.volume and ("Svezak " .. args.volume) or nil, | args.volume and ("Svezak " .. args.volume) or nil, | ||
util.join({args.location, args.publisher}, ": "), | util.join({args.location, args.publisher}, ": "), | ||
country and ("(" .. country .. ")") or nil, | |||
isbn and ("ISBN " .. isbn) or nil, | isbn and ("ISBN " .. isbn) or nil, | ||
formatIds(args) | formatIds(args) | ||
})) | })) | ||
if util.is_set(args.url) then | if util.is_set(args.url) then | ||
local url = "[" .. args.url .. " " .. args.url .. "]" | local url = "[" .. args.url .. " " .. args.url .. "]" | ||
| Redak 298: | Redak 370: | ||
end | end | ||
if util.is_set(args.quote) then | if util.is_set(args.quote) then | ||
table.insert(parts, sentence({quoted(args.quote)})) | table.insert(parts, sentence({quoted(args.quote)})) | ||
| Redak 306: | Redak 377: | ||
end | end | ||
local function citeWeb(args) | |||
local function | |||
local parts = {} | local parts = {} | ||
local lang_full = normalizeLanguage(args.language) | |||
table.insert(parts, sentence({ | table.insert(parts, sentence({ | ||
formatAuthors(args), | formatAuthors(args), | ||
args. | args.date and "(" .. args.date .. ")" or nil, | ||
italic(args.title), | |||
lang_full and ("[jezik: " .. lang_full .. "]") or nil | |||
})) | })) | ||
table.insert(parts, sentence({ | table.insert(parts, sentence({ | ||
italic(args. | italic(args.work), | ||
args.publisher, | |||
args. | |||
formatIds(args) | formatIds(args) | ||
})) | })) | ||
if util.is_set(args.url) then | if util.is_set(args.url) then | ||
local url = | local url = "[" .. args.url .. " " .. args.url .. "]" | ||
if util.is_set(args[ | if util.is_set(args["access-date"]) then | ||
url = url .. | url = url .. " (pristupljeno " .. args["access-date"] .. ")" | ||
end | end | ||
table.insert(parts, sentence({url})) | table.insert(parts, sentence({url})) | ||
| Redak 339: | Redak 406: | ||
end | end | ||
return util.join(parts, | return util.join(parts, " ") | ||
end | end | ||
local function | local function citeJournal(args) | ||
local parts = {} | local parts = {} | ||
local lang_full = normalizeLanguage(args.language) | |||
table.insert(parts, sentence({ | table.insert(parts, sentence({ | ||
formatAuthors(args), | formatAuthors(args), | ||
args. | args.year and "(" .. args.year .. ")" or nil, | ||
quoted(args.title) | quoted(args.title), | ||
lang_full and ("[jezik: " .. lang_full .. "]") or nil | |||
})) | })) | ||
table.insert(parts, sentence({ | table.insert(parts, sentence({ | ||
italic(args. | italic(args.journal), | ||
args. | util.join({args.volume, args.issue and "(" .. args.issue .. ")" or nil}, " "), | ||
args.pages and ("str. " .. args.pages) or nil, | |||
args.pages and ( | |||
formatIds(args) | formatIds(args) | ||
})) | })) | ||
if util.is_set(args.url) then | if util.is_set(args.url) then | ||
local url = | local url = "[" .. args.url .. " " .. args.url .. "]" | ||
if util.is_set(args[ | if util.is_set(args["access-date"]) then | ||
url = url .. | url = url .. " (pristupljeno " .. args["access-date"] .. ")" | ||
end | end | ||
table.insert(parts, sentence({url})) | table.insert(parts, sentence({url})) | ||
end | end | ||
if util.is_set(args.quote) then | |||
table.insert(parts, sentence({quoted(args.quote)})) | |||
end | end | ||
return util.join(parts, | return util.join(parts, " ") | ||
end | end | ||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
-- GLAVNA FUNKCIJA | -- GLAVNA FUNKCIJA | ||
| Redak 480: | Redak 463: | ||
if cls == 'book' then | if cls == 'book' then | ||
return citeBook(args) | |||
elseif cls == 'journal' then | elseif cls == 'journal' then | ||
return citeJournal(args) | |||
elseif cls == 'newspaper' then | elseif cls == 'newspaper' then | ||
return citeNewspaper(args) | |||
elseif cls == 'encyclopedia' then | elseif cls == 'encyclopedia' then | ||
return citeEncyclopedia(args) | |||
elseif cls == 'law' then | elseif cls == 'law' then | ||
return citeLaw(args) | |||
elseif cls == 'archive' then | elseif cls == 'archive' then | ||
return citeArchive(args) | |||
elseif cls == 'interview' then | elseif cls == 'interview' then | ||
return citeInterview(args) | |||
else | else | ||
return citeWeb(args) | |||
end | end | ||
-- Alias za #invoke: ... |main | -- Alias za #invoke: ... |main | ||
| Redak 502: | Redak 484: | ||
return p | return p | ||
end | |||
function p.bibliography(frame) | |||
local args = frame.args | |||
local out = {} | |||
local index = 1 | |||
while args[tostring(index)] do | |||
table.insert(out, "* " .. args[tostring(index)]) | |||
index = index + 1 | |||
end | |||
return table.concat(out, "\n") | |||
end | |||
Inačica od 18. siječanj 2026. u 11:02
Dokumentacija modula
Ovaj modul i njegovi pod-moduli podržavaju CS1 i CS2 stil citiranja. Ovaj modul nije namijenjen za direktno pozivanje, već ga je potrebno pozvati iz predloška koji ga koristi.
<section end=module_components_table />
<section begin=module_components_table /> Pod-moduli navedeni niže osiguravaju funkcionalnost predložaka za for CS1/2 stil citiranja:
| Pod-modul | Opis | |
|---|---|---|
| Gold padlock | Modul:Citation/CS1 | Odgovoran za prikazivanje i druge podržane funkcije |
| Modul:Citation/CS1/Configuration | Tablice prijevoda; Rukovanje pogreškama i identifikatorima | |
| Modul:Citation/CS1/Whitelist | Popis aktivnih i zastarjelih parametara za citiranje | |
| Modul:Citation/CS1/Date validation | Rukovanje oblicima datuma i validacija njihove točnosti | |
| Modul:Citation/CS1/Identifiers | Funkcije za rukovanje imenovanim identifikatorima (ISBN, DOI, PMID, i sl.) | |
| Modul:Citation/CS1/Utilities | Često korištene tablice i funkcije | |
| Modul:Citation/CS1/COinS | Funkcije koje stvaraju meta-podatke o citiranom CS1/2 izvoru | |
| Modul:Citation/CS1/styles.css | CSS stilovi primijenjeni na predloške za citiranje | |
| Pogreška pri izradbi sličice: | Modul:Citation/CS1/Suggestions | Popias koji mapira česte netočno navedene parametre i dodjeljuje im ispravna imena |
-- Modul:Citation/CS1
-- Hrvatska, stabilna i pojednostavljena verzija CS1 sustava
require('strict')
local p = {}
local cfg = require('Module:Citation/CS1/Configuration')
local util = require('Module:Citation/CS1/Utilities')
local ids = require('Module:Citation/CS1/Identifiers')
local whitelist = require('Module:Citation/CS1/Whitelist')
local dateval = require('Module:Citation/CS1/Date_validation')
-- ISO 639-1 → naziv jezika (po potrebi širiš)
local iso639 = {
en = "engleski",
de = "njemacki",
fr = "francuski",
es = "spanjolski",
it = "talijanski",
hr = "hrvatski",
sr = "srpski",
bs = "bosanski",
sl = "slovenski",
ru = "ruski",
pl = "poljski",
cs = "ceski",
da = "danski",
sv = "svedski",
fi = "finski",
nl = "nizozemski",
}
-- ISO 3166 (minimalno, širiš po potrebi)
local iso3166 = {
DE = "Njemacka",
HR = "Hrvatska",
AT = "Austrija",
CH = "Svicaraska",
IT = "Italija",
FR = "Francuska",
}
local function normalizeLanguage(lang)
if not lang then return nil end
local code = mw.ustring.lower(mw.text.trim(lang))
return iso639[code] or lang
end
local function normalizeCountry(code)
if not code then return nil end
code = mw.ustring.upper(mw.text.trim(code))
return iso3166[code] or code
end
local function validateISBN(isbn)
if not isbn then return nil end
isbn = isbn:gsub("[^0-9Xx]", "")
if #isbn == 10 then
local sum = 0
for i = 1, 9 do
sum = sum + tonumber(isbn:sub(i,i)) * (11 - i)
end
local check = isbn:sub(10,10)
check = (check == "X" or check == "x") and 10 or tonumber(check)
if (sum + check) % 11 == 0 then
return isbn
end
return isbn .. " (neispravan ISBN-10)"
end
if #isbn == 13 then
local sum = 0
for i = 1, 12 do
local n = tonumber(isbn:sub(i,i))
sum = sum + (i % 2 == 0 and n * 3 or n)
end
local check = tonumber(isbn:sub(13,13))
if (10 - (sum % 10)) % 10 == check then
return isbn
end
return isbn .. " (neispravan ISBN-13)"
end
return isbn .. " (neispravan format)"
end
local function formatEditors(args)
local list = {}
if util.is_set(args.editor) then
table.insert(list, args.editor)
end
for i = 1, 9 do
local e = args["editor" .. i]
if util.is_set(e) then
table.insert(list, e)
end
end
if #list == 0 then return nil end
if #list == 1 then return "Uredio: " .. list[1] end
if #list == 2 then return "Uredili: " .. list[1] .. " i " .. list[2] end
local last = table.remove(list)
return "Uredili: " .. table.concat(list, ", ") .. " i " .. last
end
local function formatTranslators(args)
local list = {}
if util.is_set(args.translator) then
table.insert(list, args.translator)
end
for i = 1, 9 do
local t = args["translator" .. i]
if util.is_set(t) then
table.insert(list, t)
end
end
if #list == 0 then return nil end
if #list == 1 then return "Preveo: " .. list[1] end
if #list == 2 then return "Preveli: " .. list[1] .. " i " .. list[2] end
local last = table.remove(list)
return "Preveli: " .. table.concat(list, ", ") .. " i " .. last
end
--------------------------------------------------------------------------------
-- POMOĆNE FUNKCIJE
--------------------------------------------------------------------------------
local function getArgs(frame)
return require('Module:Arguments').getArgs(frame)
end
local function clean(s)
if not s then return nil end
return mw.text.trim(s):gsub('[%.,;:]+$', '')
end
local function italic(s)
if not util.is_set(s) then return nil end
return "''" .. clean(s) .. "''"
end
local function quoted(s)
if not util.is_set(s) then return nil end
return '„' .. clean(s) .. '“'
end
local function sentence(parts)
local line = util.join(parts, ' ')
if not line or line == '' then return nil end
if not line:match('[%.%!%?]$') then
line = line .. '.'
end
return line
end
local function normalizeClass(args, frame)
local cls = args.CitationClass or args.type
if cls then
cls = mw.text.trim(cls):lower()
else
local title = frame:getTitle() or (frame:getParent() and frame:getParent():getTitle()) or ''
title = mw.ustring.lower(title)
if title:find('cite web', 1, true) then cls = 'web'
elseif title:find('cite book', 1, true) then cls = 'book'
elseif title:find('cite journal', 1, true) then cls = 'journal'
elseif title:find('citiranje knjige', 1, true) then cls = 'book'
elseif title:find('citiranje weba', 1, true) then cls = 'web'
elseif title:find('citiranje casopisa', 1, true) then cls = 'journal'
elseif title:find('citiranje novina', 1, true) then cls = 'newspaper'
elseif title:find('citiranje enciklopedije', 1, true) then cls = 'encyclopedia'
elseif title:find('citiranje zakona', 1, true) then cls = 'law'
elseif title:find('citiranje arhive', 1, true) then cls = 'archive'
elseif title:find('citiranje intervjua', 1, true) then cls = 'interview'
else cls = 'web'
end
end
if cls ~= 'web' and cls ~= 'book' and cls ~= 'journal' then
cls = 'web'
end
return cls
end
--------------------------------------------------------------------------------
-- HRVATSKI ALIAS PARAMETRI (ASCII-SAFE)
--------------------------------------------------------------------------------
local hr_aliases = {
autor = "author",
autor1 = "author1",
autor2 = "author2",
autor3 = "author3",
naslov = "title",
izdavac = "publisher",
mjesto = "location",
place = "location",
godina = "year",
stranica = "pages",
stranice = "pages",
urednik = "editor",
izdanje = "edition",
novine = "newspaper",
enciklopedija = "encyclopedia",
zakon = "law",
arhiva = "archive",
intervju = "interview",
}
--------------------------------------------------------------------------------
-- PROŠIRENI getArgs() S MAPIRANJEM HR PARAMETARA
--------------------------------------------------------------------------------
local function getArgs(frame)
local args = require('Module:Arguments').getArgs(frame)
-- mapiranje hrvatskih parametara
for hr, en in pairs(hr_aliases) do
if args[hr] and not args[en] then
args[en] = args[hr]
end
end
-- fallback: page → pages
if args.page and not args.pages then
args.pages = args.page
end
return args
end
--------------------------------------------------------------------------------
-- VALIDACIJA PARAMETARA (CS1-like)
--------------------------------------------------------------------------------
local function validateParams(args, cls)
local errors = {}
-- Nepoznati parametri
for k, v in pairs(args) do
if type(k) == 'string' and not whitelist.params[k] then
table.insert(errors, "Nepoznat parametar: <code>" .. k .. "</code>")
end
end
-- Obavezni parametri po klasi
for _, req in ipairs(cfg.required_params[cls] or {}) do
if not util.is_set(args[req]) then
table.insert(errors, "Nedostaje obavezni parametar: <code>" .. req .. "</code>")
end
end
-- Parametri koji ne pripadaju klasi
local allowed = {}
for _, p in ipairs(cfg.class_params[cls] or {}) do
allowed[p] = true
end
for k, v in pairs(args) do
if type(k) == 'string' and whitelist.params[k] and not allowed[k] then
table.insert(errors, "Parametar <code>" .. k .. "</code> nije dopušten u klasi <code>" .. cls .. "</code>")
end
end
-- Bare URL
if util.is_set(args.url) and not util.is_set(args.title) then
table.insert(errors, "Bare URL: nedostaje parametar <code>title</code>")
end
-- Prazni parametri
for k, v in pairs(args) do
if type(k) == 'string' and type(v) == 'string' and mw.text.trim(v) == '' then
table.insert(errors, "Prazan parametar: <code>" .. k .. "</code>")
end
end
return errors
end
--------------------------------------------------------------------------------
-- FORMATIRANJE IDENTIFIKATORA
--------------------------------------------------------------------------------
local function formatIds(args)
local out = {}
for id, _ in pairs(cfg.id_handlers or {}) do
local val = args[id:lower()] or args[id]
if util.is_set(val) then
table.insert(out, ids.format(id, val))
end
end
return util.join(out, ' · ')
end
--------------------------------------------------------------------------------
-- FORMATIRANJE AUTORA
--------------------------------------------------------------------------------
local function formatAuthors(args)
local list = {}
if util.is_set(args.author) then
table.insert(list, args.author)
end
for i = 1, 9 do
local a = args['author' .. i]
if util.is_set(a) then
table.insert(list, a)
end
end
if #list == 0 then return nil end
if #list == 1 then return list[1] end
if #list == 2 then return list[1] .. ' i ' .. list[2] end
local last = table.remove(list)
return table.concat(list, ', ') .. ' i ' .. last
end
--------------------------------------------------------------------------------
-- CITATION: BOOK
--------------------------------------------------------------------------------
local function citeBook(args)
local parts = {}
local lang_full = normalizeLanguage(args.language)
local isbn = args.isbn and validateISBN(args.isbn) or nil
local country = normalizeCountry(args.country)
table.insert(parts, sentence({
formatAuthors(args),
args.year and "(" .. args.year .. ")" or nil,
italic(args.title),
args.subtitle and italic(args.subtitle) or nil,
lang_full and ("[jezik: " .. lang_full .. "]") or nil
}))
table.insert(parts, sentence({
formatEditors(args),
formatTranslators(args),
args.edition and (args.edition .. ". izd.") or nil,
args.series and ("Serija: " .. args.series) or nil,
args.volume and ("Svezak " .. args.volume) or nil,
util.join({args.location, args.publisher}, ": "),
country and ("(" .. country .. ")") or nil,
isbn and ("ISBN " .. isbn) or nil,
formatIds(args)
}))
if util.is_set(args.url) then
local url = "[" .. args.url .. " " .. args.url .. "]"
if util.is_set(args["access-date"]) then
url = url .. " (pristupljeno " .. args["access-date"] .. ")"
end
table.insert(parts, sentence({url}))
end
if util.is_set(args.quote) then
table.insert(parts, sentence({quoted(args.quote)}))
end
return util.join(parts, " ")
end
local function citeWeb(args)
local parts = {}
local lang_full = normalizeLanguage(args.language)
table.insert(parts, sentence({
formatAuthors(args),
args.date and "(" .. args.date .. ")" or nil,
italic(args.title),
lang_full and ("[jezik: " .. lang_full .. "]") or nil
}))
table.insert(parts, sentence({
italic(args.work),
args.publisher,
formatIds(args)
}))
if util.is_set(args.url) then
local url = "[" .. args.url .. " " .. args.url .. "]"
if util.is_set(args["access-date"]) then
url = url .. " (pristupljeno " .. args["access-date"] .. ")"
end
table.insert(parts, sentence({url}))
end
if util.is_set(args.quote) then
table.insert(parts, sentence({quoted(args.quote)}))
end
return util.join(parts, " ")
end
local function citeJournal(args)
local parts = {}
local lang_full = normalizeLanguage(args.language)
table.insert(parts, sentence({
formatAuthors(args),
args.year and "(" .. args.year .. ")" or nil,
quoted(args.title),
lang_full and ("[jezik: " .. lang_full .. "]") or nil
}))
table.insert(parts, sentence({
italic(args.journal),
util.join({args.volume, args.issue and "(" .. args.issue .. ")" or nil}, " "),
args.pages and ("str. " .. args.pages) or nil,
formatIds(args)
}))
if util.is_set(args.url) then
local url = "[" .. args.url .. " " .. args.url .. "]"
if util.is_set(args["access-date"]) then
url = url .. " (pristupljeno " .. args["access-date"] .. ")"
end
table.insert(parts, sentence({url}))
end
if util.is_set(args.quote) then
table.insert(parts, sentence({quoted(args.quote)}))
end
return util.join(parts, " ")
end
--------------------------------------------------------------------------------
-- GLAVNA FUNKCIJA
--------------------------------------------------------------------------------
function p.citation(frame)
local args = getArgs(frame)
local cls = normalizeClass(args, frame)
-- Validacija
local errors = validateParams(args, cls)
if #errors > 0 then
local out = '<div class="citation-errors" style="color:#b00; font-size:90%;">'
for _, e in ipairs(errors) do
out = out .. '• ' .. e .. '<br>'
end
out = out .. '</div>'
return out
end
if cls == 'book' then
return citeBook(args)
elseif cls == 'journal' then
return citeJournal(args)
elseif cls == 'newspaper' then
return citeNewspaper(args)
elseif cls == 'encyclopedia' then
return citeEncyclopedia(args)
elseif cls == 'law' then
return citeLaw(args)
elseif cls == 'archive' then
return citeArchive(args)
elseif cls == 'interview' then
return citeInterview(args)
else
return citeWeb(args)
end
-- Alias za #invoke: ... |main
p.main = p.citation
return p
end
function p.bibliography(frame)
local args = frame.args
local out = {}
local index = 1
while args[tostring(index)] do
table.insert(out, "* " .. args[tostring(index)])
index = index + 1
end
return table.concat(out, "\n")
end