Modul:Citat Q
Modul:Citat Q generează citări bibliografice complete (CS1) extrăgând automat date structurate din Wikidata. Modulul este capabil să gestioneze moștenirea datelor (titluri, autori, identificatori) de la lucrările părinte sau revistele în care au fost publicate articolele.
Utilizare
Acest modul este de obicei apelat printr-un format, de exemplu {{Citat Q}}, dar i se poate apela direct din alt modul și funcția cite_item_lua cu un item ID ca prim parametru și cu un tablou asociativ ce conține ceilalți parametri ca al doilea parametru; sau funcția cite_ref care primește o referință brută din Wikidata, alături de tabloul asociativ de parametri pentru a produce același lucru.
Pentru parametrii admiși în tabelul asociativ, vezi documentația formatului {{Citat Q}}.
Sintaxa de bază pentru apelarea directă a modulului este:
{{#invoke:Citat Q|cite_q|q=<QID>|...}}
Parametri
Modulul acceptă următorii parametri. Parametrii manuali au prioritate față de datele din Wikidata.
| Parametru | Descriere | Exemplu |
|---|---|---|
| q | Obligatoriu. ID-ul elementului Wikidata (QID). | Q136457009
|
| p | Specifică o singură pagină. Suprascrie P304 din Wikidata. | 42
|
| pp | Specifică un interval de pagini. Suprascrie P304 din Wikidata. | 42-45
|
| title | Suprascrie titlul (P1476). | Titlu manual
|
| publisher | Suprascrie editura (P123). | Editura Humanitas
|
| pubDate | Suprascrie data publicării (P577). | 2023-01-01
|
| author | Adaugă un autor manual (ignoră autorii de pe Wikidata). | Ion Popescu
|
| archive-url | URL-ul către versiunea arhivată a resursei. | https://archive.org/...
|
| archive-date | Data la care a fost făcută arhivarea. | 2023-05-20
|
Funcționalități speciale
Modulul implementează o logică avansată de fallback pentru a completa datele lipsă:
- Titluri: Dacă elementul nu are titlu (P1476), modulul caută titlul lucrării originale (P629 - ediție a operelor) sau folosește eticheta elementului (cu fallback pe en/fr/de dacă eticheta în română lipsește).
- Autori: Dacă nu există autori (P50) sau nume de autori (P2093) pe ediție, aceștia sunt moșteniți de la lucrarea originală (P629).
- Reviste și identificatori: Pentru articole științifice, ISSN-ul, ISBN-ul și Editura sunt căutate automat în elementul Revistei/Publicației (P1433) dacă nu există pe articol.
- Legături în citare:
- Autori/editori: Se creează legături către ro.wiki doar dacă există articol.
- Edituri: Dacă nu există articol pe ro.wiki, se afișează numele urmat de un link mic către Wikidata.
- Locul publicării: Se creează legătură doar dacă există articol pe ro.wiki.
Exemple
Exemplele de mai jos demonstrează cazurile specifice discutate și rezolvate în acest modul.
Fallback de limbă (Q136445638)
Acest element nu are etichetă în limba română. Modulul preia automat eticheta din engleză/franceză pentru a nu genera o citare goală.
| Sintaxa | Rezultat |
|---|---|
{{#invoke:Citat Q|cite_q|q=Q136445638}}
|
Gh. I. Cantacuzino; Gh. Sion (). „Ruinele curţii feudale de la Coiani – Mironeşti (judeţul Giurgiu) – Date arheologice şi arhitectonice” (PDF). Buletinul Comisiunii Monumentelor Istorice. Institutul Național al Patrimoniului (I; nr. în TOM: 1-2; anul 1990; Serie Nouă). Wikidata Q136445638. |
Moștenire titlu și autori din părinte (Q136698231)
Acest element este o ediție specifică. Titlul și autorii nu sunt completate pe ediție, ci sunt moștenite automat de la lucrarea părinte (P629).
| Sintaxa | Rezultat |
|---|---|
{{#invoke:Citat Q|cite_q|q=Q136698231}}
|
„Mănăstirea Cernica” (PDF). București: Editura Meridiane[*]. . Wikidata Q136698231. |
Extragere ISSN din revista în care este publicat un articol (Q136457009)
Acest articol științific nu are ISSN-ul trecut direct pe el. Modulul identifică revista în care a fost publicat (P1433) și extrage ISSN-ul de acolo. De asemenea, demonstrează suprascrierea paginilor cu parametrul pp.
| Sintaxa | Rezultat |
|---|---|
{{#invoke:Citat Q|cite_q|Q136457009|pp=15-20}}
|
Gabriel Sarcină (). „Considerente istorice și geografice despre județul Gorj, surprinse în «Memoriile...» generaului Bauer de la 1778”. Litua. Studii și cercetări (25): 15–20. ISSN 1582-7151. Wikidata Q136457009. |
Legături inteligente și editură
Editura primește un link către Wikidata dacă nu are articol pe Wikipedia în română, iar autorii primesc link doar dacă au articol. Demonstrație pentru lucrarea Sapiens.
- Autorul (Yuval Noah Harari) are articol pe ro.wiki
- Editura (Harvill Secker) nu are articol pe ro.wiki
| Sintaxa | Rezultat |
|---|---|
{{#invoke:Citat Q|cite_q|Q12411055}}
|
Yuval Noah Harari (). „Sapiens” (în ebraică). דביר[*]. OL 17628800W. Wikidata Q12411055. |
local p = {}
-- =============================================================================
-- CONFIGURATION & CONSTANTS
-- =============================================================================
local MONTHS = {
"ianuarie", "februarie", "martie", "aprilie", "mai", "iunie",
"iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie"
}
-- Internal property mapping
local PROP_MAP = {
-- Basic Metadata
title = { id = 'P1476', type = 'monolingualtext' },
subtitle = { id = 'P1680', type = 'monolingualtext' },
pubDate = { id = 'P577', type = 'time' },
accessDate = { id = 'P813', type = 'time' },
publisher = { id = 'P123', type = 'item_linked' },
place = { id = 'P291', type = 'item_sitelink' },
language = { id = 'P407', type = 'item_code' },
archiveurl = { id = 'P1065', type = 'url' },
archivedate = { id = 'P2960', type = 'time' },
-- Container / Parent
journal = { id = 'P1433', type = 'item_label' },
series = { id = 'P179', type = 'item_label' },
-- Specifics
volume = { id = 'P478', type = 'string' },
issue = { id = 'P433', type = 'string' },
pages = { id = 'P304', type = 'string' },
at = { id = 'P958', type = 'string' },
chapter = { id = 'P792', type = 'string' },
edition = { id = 'P393', type = 'string' },
version = { id = 'P348', type = 'string' },
-- Identifiers (Fallback enabled)
doi = { id = 'P356', type = 'string' },
isbn = { id = 'P212', type = 'string' },
isbn10 = { id = 'P957', type = 'string' },
issn = { id = 'P236', type = 'string' },
oclc = { id = 'P243', type = 'string' },
pmid = { id = 'P698', type = 'string' },
pmc = { id = 'P932', type = 'string' },
arxiv = { id = 'P818', type = 'string' },
bibcode = { id = 'P819', type = 'string' },
jstor = { id = 'P888', type = 'string' },
s2cid = { id = 'P8299', type = 'string' },
lccn = { id = 'P1144', type = 'string' },
hdl = { id = 'P1184', type = 'string' },
ismn = { id = 'P1208', type = 'string' },
citeseerx = { id = 'P3784', type = 'string' },
ol = { id = 'P648', type = 'string' },
}
-- Contributors
local CONTRIB_MAP = {
author = { id = 'P50', fallback = 'P2093', label = 'Autor' },
editor = { id = 'P98', fallback = 'P5769', label = 'Editor' },
translator = { id = 'P655', label = 'Traducător' },
illustrator = { id = 'P110', label = 'Ilustrator' },
composer = { id = 'P86', label = 'Compozitor' },
screenwriter= { id = 'P58', label = 'Scenarist' },
director = { id = 'P57', label = 'Regizor' },
}
local URL_PROPS = {
{ id = 'P854', type = 'url' }, -- reference URL
{ id = 'P953', type = 'url' }, -- full work available at URL
{ id = 'P4945', type = 'url' }, -- download URL
{ id = 'P973', type = 'url' }, -- described at URL
{ id = 'P856', type = 'url' }, -- official website
}
-- =============================================================================
-- HELPERS
-- =============================================================================
-- Helper: Generalized extractor for both Reference Snaks and Entity Claims
local function get_prop_values(source, propId)
if not source or not source[propId] then return nil end
local values = {}
-- Handle both Reference structure (snaks) and Entity structure (claims)
local list = source[propId]
for _, item in ipairs(list) do
local snak = item.mainsnak or item -- specific to how wikidata Lua tables are structured
if snak.snaktype == 'value' and snak.datavalue then
if snak.datatype == 'wikibase-item' then
table.insert(values, snak.datavalue.value.id) -- Store QID
elseif snak.datatype == 'string' or snak.datatype == 'monolingualtext' then
table.insert(values, snak.datavalue.value) -- Store String
-- Add other datatypes (time, quantity) if needed
end
end
end
return (#values > 0) and values or nil
end
local function getLabel(id)
if not id then return nil end
-- Try ro first
local label = mw.wikibase.getLabelByLang(id, 'ro')
if label then return label end
-- Try mul second
label = mw.wikibase.getLabelByLang(id, 'mul')
if label then return label end
-- Try the entity's own language (P407) third
local entity = mw.wikibase.getEntity(id)
if entity and entity.claims and entity.claims['P407'] then
for _, langClaim in ipairs(entity.claims['P407']) do
if langClaim.mainsnak.snaktype == 'value' then
local langId = langClaim.mainsnak.datavalue.value.id
-- Get language code
local langEntity = mw.wikibase.getEntity(langId)
if langEntity and langEntity.claims and langEntity.claims['P424'] then
local langCode = langEntity.claims['P424'][1].mainsnak.datavalue.value
label = mw.wikibase.getLabelByLang(id, langCode)
if label then return label end
end
end
end
end
-- Finally try en, fr, de
for _, lang in ipairs({'en', 'fr', 'de'}) do
label = mw.wikibase.getLabelByLang(id, lang)
if label then return label end
end
return nil
end
local function getLinkedLabel(id)
local label = getLabel(id) or id
local sitelink = mw.wikibase.getSitelink(id)
if sitelink then
return "[[" .. sitelink .. "|" .. label .. "]]"
else
return "[[:d:" .. id .. "|" .. label .. "]]<abbr title='Articolul încă nu există în acest wiki'>[*]</abbr>"
end
end
local function getSitelinkOrLabel(id)
local label = getLabel(id) or id
local sitelink = mw.wikibase.getSitelink(id)
if sitelink then
return "[[" .. sitelink .. "|" .. label .. "]]"
else
return label
end
end
local function getExternalIdData(refSnaks, statedInId, refData, subjectQid)
if not refSnaks then return nil end
-- If no P248, try to infer statedInId from ID properties in the reference
if not statedInId then
for propId, snakList in pairs(refSnaks) do
if propId ~= 'P304' and propId ~= 'P813' and propId ~= 'P854' and propId ~= 'P1810' then
local propEntity = mw.wikibase.getEntity(propId)
if propEntity and propEntity.claims and propEntity.claims['P9073'] then
-- This ID property has P9073, use its first value as statedInId
for _, claim in ipairs(propEntity.claims['P9073']) do
if claim.mainsnak.snaktype == 'value' then
statedInId = claim.mainsnak.datavalue.value.id
break
end
end
if statedInId then break end
end
end
end
end
if not statedInId then return nil end
-- First pass: Check if any ID in refSnaks has P9073 match
for propId, snakList in pairs(refSnaks) do
if propId ~= 'P248' and propId ~= 'P304' and propId ~= 'P813' and propId ~= 'P854' and propId ~= 'P1810' then
local propEntity = mw.wikibase.getEntity(propId)
if propEntity and propEntity.claims and propEntity.claims['P9073'] then
for _, claim in ipairs(propEntity.claims['P9073']) do
if claim.mainsnak.snaktype == 'value' then
local serviceId = claim.mainsnak.datavalue.value.id
if serviceId == statedInId then
-- Found a match with ID in reference!
local result = {}
for _, snak in ipairs(snakList) do
if snak.snaktype == 'value' then
local idValue = snak.datavalue.value
if propEntity.claims['P1630'] and idValue then
local formatterUrl = propEntity.claims['P1630'][1].mainsnak.datavalue.value
result.url = formatterUrl:gsub("$1", idValue)
end
break
end
end
-- Get title from P1810 or subject
if refData['P1810'] then
result.title = refData['P1810']
elseif subjectQid then
result.title = getLabel(subjectQid)
end
result.publisher = getLinkedLabel(statedInId)
return result
end
end
end
end
end
end
-- Second pass: No ID in reference, check if subject has matching ID
if subjectQid then
-- Find all properties with P9073 pointing to statedInId
local candidateProps = {}
-- We need to search for properties that have P9073 = statedInId
-- This is expensive, so let's check the subject's claims for common ID properties
local subjectEntity = mw.wikibase.getEntity(subjectQid)
if subjectEntity and subjectEntity.claims then
for propId, claims in pairs(subjectEntity.claims) do
-- Check if this property has P9073 pointing to our statedInId
local propEntity = mw.wikibase.getEntity(propId)
if propEntity and propEntity.claims and propEntity.claims['P9073'] then
for _, claim in ipairs(propEntity.claims['P9073']) do
if claim.mainsnak.snaktype == 'value' then
local serviceId = claim.mainsnak.datavalue.value.id
if serviceId == statedInId then
-- Found a matching property on the subject!
local result = {}
-- Get the ID value from subject's claims
for _, subjectClaim in ipairs(claims) do
if subjectClaim.mainsnak.snaktype == 'value' then
local idValue = subjectClaim.mainsnak.datavalue.value
-- Build URL
if propEntity.claims['P1630'] and idValue then
local formatterUrl = propEntity.claims['P1630'][1].mainsnak.datavalue.value
result.url = formatterUrl:gsub("$1", idValue)
end
break
end
end
-- Get title from P1810 or subject
if refData['P1810'] then
result.title = refData['P1810']
else
result.title = getLabel(subjectQid)
end
result.publisher = getLinkedLabel(statedInId)
return result
end
end
end
end
end
end
end
return nil
end
local function formatDate(timeValue)
if not timeValue then return nil end
local sign, y, m, d = timeValue.time:match("^([%+%-]?)(%d+)-(%d+)-(%d+)T")
if not y then return nil end
local yearStr = (sign == '-') and ("-" .. y) or y
if timeValue.precision <= 9 then
return yearStr
elseif timeValue.precision == 10 then
local monthNum = tonumber(m)
if monthNum and MONTHS[monthNum] then
return MONTHS[monthNum] .. " " .. yearStr
else
return yearStr .. "-" .. m
end
else
if d == '00' then
local monthNum = tonumber(m)
if monthNum and MONTHS[monthNum] then
return MONTHS[monthNum] .. " " .. yearStr
else
return yearStr .. "-" .. m
end
end
return yearStr .. "-" .. m .. "-" .. d
end
end
local function getPropValue(entity, propId, valueType)
if not entity or not entity.claims or not entity.claims[propId] then return nil end
for _, statement in ipairs(entity.claims[propId]) do
if statement.mainsnak.snaktype == 'value' then
local val = statement.mainsnak.datavalue.value
if valueType == 'item' then return val.id
elseif valueType == 'item_label' then return getLabel(val.id)
elseif valueType == 'item_linked' then return getLinkedLabel(val.id)
elseif valueType == 'item_sitelink' then return getSitelinkOrLabel(val.id)
elseif valueType == 'item_code' then
local langItem = mw.wikibase.getEntity(val.id)
if langItem and langItem.claims and langItem.claims['P424'] then
return langItem.claims['P424'][1].mainsnak.datavalue.value
end
return getLabel(val.id)
elseif valueType == 'time' then return formatDate(val)
elseif valueType == 'string' or valueType == 'url' or valueType == 'external-id' then return val
elseif valueType == 'monolingualtext' then
-- Check language preference
if val.language == 'ro' or val.language == 'mul' then
return val.text
end
-- Continue to next statement if language doesn't match
end
end
end
-- If no ro/mul found, try other preferred languages
if valueType == 'monolingualtext' then
for _, lang in ipairs({'en', 'fr', 'de'}) do
for _, statement in ipairs(entity.claims[propId]) do
if statement.mainsnak.snaktype == 'value' then
local val = statement.mainsnak.datavalue.value
if val.language == lang then
return val.text
end
end
end
end
end
return nil
end
local function getPeople(entity, propId, fallbackPropId, max)
local results = {}
if not entity or not entity.claims then return results end
local count = 0
local max_results = max or 10
local function add(claims, isString)
if not claims then return end
for _, claim in ipairs(claims) do
if count >= max_results then break end
if claim.mainsnak.snaktype == 'value' then
local val = claim.mainsnak.datavalue.value
local person = { name = nil, link = nil }
if isString then
person.name = val
else
local itemId
if type(val) == 'table' then
itemId = val.id
else
itemId = val
end
if itemId then
person.name = getLabel(itemId)
person.link = mw.wikibase.getSitelink(itemId)
end
end
-- Only add if we have a valid name
if person.name and type(person.name) == 'string' then
table.insert(results, person)
count = count + 1
end
end
end
end
add(entity.claims[propId], false)
if fallbackPropId and count < max_results then
add(entity.claims[fallbackPropId], true)
end
return results
end
local function getFirstUrlFromProps(entity, urlProps)
if not entity then return nil end
for _, propConfig in ipairs(urlProps) do
local val = getPropValue(entity, propConfig.id, propConfig.type)
if val then return val end
end
return nil
end
local function parseRefSnaks(refSnaks)
local data = {}
if not refSnaks then return data end
for propId, snakList in pairs(refSnaks) do
for _, snak in ipairs(snakList) do
if snak.snaktype == 'value' then
local val = snak.datavalue.value
if snak.datatype == 'wikibase-item' then data[propId] = val.id
elseif snak.datatype == 'time' then data[propId] = formatDate(val)
elseif snak.datatype == 'monolingualtext' then data[propId] = val.text
elseif snak.datatype == 'string' or snak.datatype == 'url' or snak.datatype == 'external-id' then data[propId] = val
end
break
end
end
end
return data
end
-- =============================================================================
-- MAIN RESOLVER
-- =============================================================================
local function resolveCitationData(args, refSnaks, itemQid, subjectQid)
local manual = args or {}
if manual['p'] then manual['pages'] = manual['p'] end
if manual['pp'] then manual['pages'] = manual['pp'] end
local refData = parseRefSnaks(refSnaks)
local statedInId = refData['P248']
local workId = itemQid
local statedInItem = statedInId and mw.wikibase.getEntity(statedInId) or nil
local workItem = workId and mw.wikibase.getEntity(workId) or nil
-- Use the proper getExternalIdData function (defined outside this function)
local externalIdData = getExternalIdData(refSnaks, statedInId, refData, subjectQid)
-- Standard Metadata Logic
local p629 = nil
if workItem then p629 = getPropValue(workItem, 'P629', 'item') end
if not p629 and statedInItem then p629 = getPropValue(statedInItem, 'P629', 'item') end
local parentItem = p629 and mw.wikibase.getEntity(p629) or nil
local journalId = nil
if workItem then journalId = getPropValue(workItem, 'P1433', 'item') end
if not journalId and parentItem then journalId = getPropValue(parentItem, 'P1433', 'item') end
local journalItem = journalId and mw.wikibase.getEntity(journalId) or nil
local function getValue(key, type_override)
local config = PROP_MAP[key]
if not config then return manual[key] end
local propId = config.id
local vType = type_override or config.type
if manual[key] then return manual[key] end
-- Priority: Reference > Work > Journal > StatedIn > Parent
if refData[propId] then
local val = refData[propId]
if vType == 'item_label' and val:match("^Q%d+") then return getLabel(val) end
if vType == 'item_linked' and val:match("^Q%d+") then return getLinkedLabel(val) end
if vType == 'item_sitelink' and val:match("^Q%d+") then return getSitelinkOrLabel(val) end
if vType == 'item_code' and val:match("^Q%d+") then
local langItem = mw.wikibase.getEntity(val)
if langItem and langItem.claims and langItem.claims['P424'] then
return langItem.claims['P424'][1].mainsnak.datavalue.value
end
return getLabel(val)
end
return val
end
local function check(e) return e and getPropValue(e, propId, vType) end
return check(workItem) or check(journalItem) or check(statedInItem) or check(parentItem)
end
local c = {}
for key, _ in pairs(PROP_MAP) do
c[key] = getValue(key)
end
-- Apply external ID data
if externalIdData then
if externalIdData.publisher and not manual['publisher'] then
c.publisher = externalIdData.publisher
end
if externalIdData.title and not manual['title'] then
c.title = externalIdData.title
end
end
if not c.title then c.title = getValue('at') end
if not c.title and parentItem then c.title = getPropValue(parentItem, 'P1476', 'monolingualtext') end
if not c.title and workItem then c.title = getLabel(workItem.id) end
if not c.title and statedInItem then c.title = getLabel(statedInItem.id) end
if not externalIdData then
local subtitle = getValue('subtitle')
if c.title and subtitle then c.title = c.title .. ": " .. subtitle end
end
-- URL Construction
local function getUrl()
if manual['url'] then return manual['url'] end
if externalIdData and externalIdData.url then return externalIdData.url end
for _, propConfig in ipairs(URL_PROPS) do
if refData[propConfig.id] then return refData[propConfig.id] end
end
local function checkUrl(e) return e and getFirstUrlFromProps(e, URL_PROPS) end
return checkUrl(statedInItem) or checkUrl(workItem) or checkUrl(journalItem) or checkUrl(parentItem)
end
c.url = getUrl()
-- Authors
local function resolvePeople(typeKey, propConfig)
if manual[typeKey] then return { { name = manual[typeKey], link = nil } } end
if refData[propConfig.id] then
local qid = refData[propConfig.id]
if qid and type(qid) == 'string' and qid:match("^Q%d+") then
local name = getLabel(qid)
if name then return { { name = name, link = mw.wikibase.getSitelink(qid) } } end
end
end
if propConfig.fallback and refData[propConfig.fallback] then
return { { name = refData[propConfig.fallback], link = nil } }
end
local function check(e) return e and getPeople(e, propConfig.id, propConfig.fallback, 10) end
local res = check(workItem) or check(parentItem) or check(statedInItem) or check(journalItem)
return res or {}
end
c.authors = resolvePeople('author', CONTRIB_MAP.author)
c.editors = resolvePeople('editor', CONTRIB_MAP.editor)
c.translators = resolvePeople('translator', CONTRIB_MAP.translator)
local others = {}
for key, config in pairs(CONTRIB_MAP) do
if key ~= 'author' and key ~= 'editor' and key ~= 'translator' then
local list = resolvePeople(key, config)
if #list > 0 then
local names = {}
for _, person in ipairs(list) do table.insert(names, person.name) end
table.insert(others, config.label .. ": " .. table.concat(names, ", "))
end
end
end
if #others > 0 then c.others = table.concat(others, "; ") end
if workItem then c.qid = workItem.id
elseif statedInItem then c.qid = statedInItem.id
end
-- =========================================================================
-- FINAL FALLBACK: STANDALONE EXTERNAL IDS (Fixes P1047 / veralz)
-- =========================================================================
if (not c.title or not c.url) and refSnaks then
for propId, snakList in pairs(refSnaks) do
if propId ~= 'P248' and propId ~= 'P304' and propId ~= 'P813' and propId ~= 'P577' then
local snak = snakList[1]
if snak and snak.snaktype == 'value' and snak.datavalue then
local dtype = snak.datatype
local val = snak.datavalue.value
if dtype == 'external-id' or dtype == 'string' then
local success, propEntity = pcall(mw.wikibase.getEntity, propId)
if success and propEntity then
-- Generate URL
if not c.url and propEntity.claims and propEntity.claims['P1630'] then
for _, claim in ipairs(propEntity.claims['P1630']) do
if claim.mainsnak.snaktype == 'value' then
local fmt = claim.mainsnak.datavalue.value
-- FIX: Escape the $ symbol for Lua patterns
c.url = fmt:gsub("%$1", val)
break
end
end
end
-- Generate Title
if not c.title then
local label = getLabel(propId) or propId
c.title = label .. ": " .. val
end
if c.title and c.url then break end
end
end
end
end
end
end
return c
end
-- =============================================================================
-- OUTPUT BUILDER
-- =============================================================================
local function buildTemplate(data)
local template = "Citation"
if data.isbn or data.isbn10 then
template = "Citat carte"
elseif data.issn or data.doi or (data.journal and (data.volume or data.issue)) then
template = "Citat revistă"
elseif data.url and not data.journal then
template = "Citat web"
end
local mapping = {
{ 'title', 'titlu' },
{ 'publisher', 'editură' },
{ 'place', 'loc' },
{ 'pubDate', 'data' },
{ 'accessDate', 'access-date' },
{ 'series', 'serie' },
{ 'volume', 'volum' },
{ 'issue', 'număr' },
{ 'pages', 'pagini' },
{ 'edition', 'ediție' },
{ 'language', 'limba' },
{ 'format', 'format' },
{ 'chapter', 'capitol' },
{ 'others', 'alții' },
{ 'doi', 'doi' },
{ 'isbn', 'isbn' },
{ 'isbn10', 'isbn' },
{ 'issn', 'issn' },
{ 'oclc', 'oclc' },
{ 'pmid', 'pmid' },
{ 'pmc', 'pmc' },
{ 'arxiv', 'arxiv' },
{ 'bibcode', 'bibcode' },
{ 'jstor', 'jstor' },
{ 'lccn', 'lccn' },
{ 'ismn', 'ismn' },
{ 'ol', 'ol' },
{ 'url', 'url' },
{ 'archiveurl', 'archive-url' },
{ 'archivedate', 'archive-date' },
}
if template == "Citat web" then
table.insert(mapping, { 'journal', 'website' })
elseif template == "Citat revistă" then
table.insert(mapping, { 'journal', 'revistă' })
else
table.insert(mapping, { 'journal', 'lucrare' })
end
local parts = { "{{" .. template }
for i, person in ipairs(data.authors) do
local nameParam = (i == 1) and "autor" or ("autor" .. i)
table.insert(parts, "| " .. nameParam .. " = " .. person.name)
if person.link then
local linkParam = (i == 1) and "author-link" or ("author-link" .. i)
table.insert(parts, "| " .. linkParam .. " = " .. person.link)
end
end
for i, person in ipairs(data.editors) do
local nameParam = (i == 1) and "editor" or ("editor" .. i)
table.insert(parts, "| " .. nameParam .. " = " .. person.name)
if person.link then
local linkParam = (i == 1) and "editor-link" or ("editor-link" .. i)
table.insert(parts, "| " .. linkParam .. " = " .. person.link)
end
end
for i, person in ipairs(data.translators) do
table.insert(parts, "| nume-traducător" .. i .. " = " .. person.name)
if person.link then
table.insert(parts, "| translator-link" .. i .. " = " .. person.link)
end
end
for _, map in ipairs(mapping) do
local val = data[map[1]]
if val and val ~= '' then
table.insert(parts, "| " .. map[2] .. " = " .. val)
end
end
if data.qid then
local qidStr = "[[Wikidata]] [[d:" .. data.qid .. "|" .. data.qid .. "]]"
table.insert(parts, "| id = " .. qidStr)
end
table.insert(parts, "}}")
return table.concat(parts)
end
-- =============================================================================
-- PUBLIC INTERFACE
-- =============================================================================
function p.cite_q(frame)
local args = {}
if frame:getParent() then
for k, v in pairs(frame:getParent().args) do
if v ~= "" then args[k] = v end
end
end
for k, v in pairs(frame.args) do
if v ~= "" then args[k] = v end
end
local qid = args['q'] or args[1]
if not qid or qid == "" then
return "Eroare: Lipsă QID"
end
args['q'] = nil
args[1] = nil
local data = resolveCitationData(args, nil, qid)
return frame:preprocess(buildTemplate(data))
end
function p.cite_ref(ref, args)
if not ref or not ref.snaks then return "" end
-- Extract subject QID from args if provided
local subjectQid = nil
if args then
subjectQid = args['subject']
end
local data = resolveCitationData(args or {}, ref.snaks, nil, subjectQid)
return buildTemplate(data)
end
function p.cite_item_lua(qid, args)
local data = resolveCitationData(args or {}, nil, qid)
return buildTemplate(data)
end
return p