Modul:RefQ
Modulul RefQ este un strat intermediar între Modul:Wikidata și Modul:Citat Q. Primește parametrii pe care i-ar primi {{Citat Q}}, obține de la Modul:Citat Q textul citării, îi calculează automat un nume (pe baza unui hash al textului) și returnează o notă de subsol <ref> completă.
Numele este determinat doar de conținutul citării, deci două citări identice primesc același nume, iar MediaWiki le contopește într-o singură notă de subsol.
Utilizare într-un format
[modificare sursă]{{#invoke:RefQ|ref|Q136354833}}
Parametrii sunt aceiași ca la {{Citat Q}}:
| Parametru | Descriere |
|---|---|
1 sau q |
(obligatoriu) Identificatorul Wikidata al sursei, de exemplu Q136354833.
|
pagini (pagina, pages, page) |
Pagina sau paginile, afișate în atributul details ca p. ... (o singură pagină) sau pp. ... (interval sau listă).
|
p / pp |
La fel, dar cu prefixul impus: p., respectiv pp..
|
capitol (cap, chapter) |
Capitolul, afișat în details ca cap. „...”.
|
secțiune (secțiunea, section, at) |
Secțiunea, afișată în details ca secțiunea „...”.
|
access-date (accessdate, accesat, data accesării) |
Data accesării, afișată în details ca accesat la ...; datele recunoscute de Modul:DateUtils (de exemplu 2024-03-05) sunt reformatate (5 martie 2024).
|
details |
Text liber adăugat la sfârșitul atributului details.
|
| alți parametri | Se transmit neschimbați către Modul:Citat Q și au prioritate față de datele din Wikidata (de exemplu titlu, url).
|
Parametrii din details nu intră în textul citării, deci nici în nume: {{#invoke:RefQ|ref|Q1|p=23}} și {{#invoke:RefQ|ref|Q1|p=50}} sunt subreferințe ale aceleiași note principale, la fel ca referințele Wikidata cu P248 = Q1 și P304.
Dacă lipsește QID-ul, se afișează mesajul de eroare „RefQ: lipsă QID”. Dacă Modul:Citat Q nu returnează nimic, nu se generează nicio notă.
Rezultatul este o notă de subsol de forma:
<ref name="wdref-0123456789abcdef0123456789abcdef">{{Citat web|titlu = ...|url = ...|id = [[Wikidata]] [[d:Q136354833|Q136354833]]}}</ref>
Notele apar acolo unde este plasată lista de note ({{Listă note}} sau <references />).
Utilizare din Lua
[modificare sursă]local RefQ = require('Modul:RefQ')
| Funcție | Descriere |
|---|---|
RefQ.cite(reference, options) |
Transmite argumentele către cite_ref din Modul:Citat Q și returnează textul citării (wikitext neexpandat, de forma {{Citat web|...}}). reference este o structură de referință Wikidata (cu .snaks), iar options un tabel, de exemplu { subject = 'Q42' }. Pentru referințele cu subreferință (vezi mai jos) returnează și o a doua valoare: textul pentru atributul details.
|
RefQ.wrap(content, frame, details) |
Împachetează un text de citare într-un <ref> cu nume calculat. Returnează un șir gol dacă content este gol. frame este opțional (implicit mw.getCurrentFrame()). Dacă details este dat, devine atributul details al notei.
|
RefQ.build(frame, ...) |
Echivalent cu RefQ.wrap(RefQ.cite(...), frame, details). Exemplu: RefQ.build(frame, reference, { subject = 'Q42' }).
|
RefQ.ref(frame) |
Punctul de intrare pentru formate (vezi mai sus). Folosește cite_item_lua din Modul:Citat Q.
|
Exemplu, pentru o referință dintr-o afirmație Wikidata:
local frame = mw.getCurrentFrame()
local text, details = RefQ.cite(reference, { subject = subjectId }) -- textul citării (+ details)
local ref = RefQ.wrap(text, frame, details) -- <ref name="wdref-..." details="...">...</ref>
Subreferințe (atributul details)
[modificare sursă]O referință Wikidata care conține afirmat în (P248) și, în afară de aceasta, doar una sau mai multe dintre proprietățile P304, P792, P958, P813 este afișată ca subreferință: conținutul notei este citarea lucrării din P248 (ca {{Citat Q|Qxxx}}), iar celelalte proprietăți formează atributul details, separate prin virgulă. O referință care conține doar P248 primește același conținut, fără details, deci aceeași notă principală.
- P792 (capitol) →
cap. „...” - P958 (secțiune) →
secțiunea „...” - P304 (pagini) →
p. ...pentru o singură pagină,pp. ...pentru mai multe (interval sau listă) - P813 (data accesării) →
accesat la ..., data fiind formatată cu Modul:DateUtils
Exemplu: <ref name="wdref-..." details="cap. „Origini”, p. 23, accesat la 5 martie 2024">{{Citat carte|...}}</ref>. Deoarece numele depinde doar de conținut, toate subreferințele aceleiași lucrări sunt grupate sub aceeași notă principală.
Cum se calculează numele
[modificare sursă]Numele este wdref- urmat de hash-ul MD5 al textului citării (fără details), calculat cu mw.hash.hashValue('md5', ...). Se folosește textul neexpandat produs de Modul:Citat Q (cite_ref sau cite_item_lua), nu rezultatul expandat al unui format, deoarece acesta conține marcaje interne (strip markers) care diferă la fiecare apel.
Observații:
- Două citări primesc același nume doar dacă Modul:Citat Q produce exact același text pentru ele. O referință Wikidata cu informații suplimentare (dată de accesare, URL, pagină etc.) sau care depinde de
subjectpoate produce un text diferit față de apelul direct cu QID-ul sursei, și deci un nume diferit. - Funcția
cite_qdin Modul:Citat Q (cea folosită de {{Citat Q}}) returnează text expandat și nu este folosită de acest modul.
Dependențe
[modificare sursă]Modulul este folosit de Modul:Wikidata (printReference și printFirstReferences).
-- Modul:RefQ
-- Layer between Modul:Wikidata and Modul:Citat Q.
-- Passes its parameters to Modul:Citat Q, names the result automatically
-- (hash of the citation text) and renders it as a complete <ref> footnote.
-- References made only of P248 plus locator properties are rendered as
-- sub-references: the cited work as content and the locators in |details=.
local p = {}
local getArgs = require('Module:Arguments').getArgs
local CitatQ = require('Modul:Citat Q')
local DateUtils = require('Modul:DateUtils')
local function snakValues(snaks)
local values = {}
for _, snak in ipairs(snaks or {}) do
if snak.snaktype == 'value' and snak.datavalue then
table.insert(values, snak)
end
end
return values
end
local function joinValues(snaks, toText)
local parts = {}
for _, snak in ipairs(snakValues(snaks)) do
local text = toText(snak)
if text and text ~= '' then table.insert(parts, text) end
end
return (#parts > 0) and table.concat(parts, ', ') or nil
end
local function stringValue(snak)
local v = snak.datavalue.value
return type(v) == 'string' and mw.text.trim(v) or nil
end
local function wikidataDate(snak)
return DateUtils.formatDate(DateUtils.extractDateFromWikidataSnak(snak), false, true)
end
-- Free-text dates (template parameters) are reformatted when recognised.
local function textDate(text)
local ok, d = pcall(DateUtils.parseDate, text)
local formatted = ok and d and DateUtils.formatDate(d, false, true)
return formatted or text
end
local function isPageRange(pages)
local _, numberCount = mw.ustring.gsub(pages, '%d+', '')
return numberCount > 1 or mw.ustring.find(pages, '[-–—,;/]') ~= nil
end
-- Builds the |details= text from plain values:
-- { chapter, section, pages, plural (true/false/nil = detect), accessDate, extra }
local function buildDetails(v)
local parts = {}
if v.chapter then table.insert(parts, 'cap. „' .. v.chapter .. '”') end
if v.section then table.insert(parts, 'secțiunea „' .. v.section .. '”') end
if v.pages then
local plural = v.plural
if plural == nil then plural = isPageRange(v.pages) end
table.insert(parts, (plural and 'pp. ' or 'p. ') .. v.pages)
end
if v.accessDate then table.insert(parts, 'accesat la ' .. v.accessDate) end
if v.extra then table.insert(parts, v.extra) end
return (#parts > 0) and table.concat(parts, ', ') or nil
end
-- Wikidata reference properties allowed in |details=
local DETAIL_PROPS = { P792 = true, P958 = true, P304 = true, P813 = true }
-- If the reference has exactly P248, optionally with some DETAIL_PROPS (and
-- nothing else), returns the stated-in QID and the details text.
local function splitSnakDetails(snaks)
local statedIn = snakValues(snaks['P248'])[1]
if not statedIn or statedIn.datavalue.type ~= 'wikibase-entityid' then return nil end
for propId, _ in pairs(snaks) do
if propId ~= 'P248' and not DETAIL_PROPS[propId] then return nil end
end
return statedIn.datavalue.value.id, buildDetails{
chapter = joinValues(snaks['P792'], stringValue),
section = joinValues(snaks['P958'], stringValue),
pages = joinValues(snaks['P304'], stringValue),
accessDate = joinValues(snaks['P813'], wikidataDate),
}
end
-- Template parameters that go into |details= instead of the citation.
-- p= / pp= force the singular / plural page prefix.
local DETAIL_ARGS = {
chapter = { 'capitol', 'cap', 'chapter' },
section = { 'secțiune', 'secțiunea', 'section', 'at' },
pages = { 'pagini', 'pagina', 'pages', 'page' },
singularPage = { 'p' },
pluralPages = { 'pp' },
accessDate = { 'access-date', 'accessdate', 'accesat', 'data accesării' },
extra = { 'details' },
}
-- Separates the details parameters from the arguments passed to Citat Q.
local function splitArgDetails(args)
local rest, found = {}, {}
local detailArgName = {}
for key, names in pairs(DETAIL_ARGS) do
for _, name in ipairs(names) do detailArgName[name] = key end
end
for name, value in pairs(args) do
local key = detailArgName[name]
if key then
found[key] = found[key] or value
else
rest[name] = value
end
end
local plural = nil
local pages = found.pages
if found.pluralPages then pages, plural = found.pluralPages, true
elseif found.singularPage then pages, plural = found.singularPage, false
end
return rest, buildDetails{
chapter = found.chapter,
section = found.section,
pages = pages,
plural = plural,
accessDate = found.accessDate and textDate(found.accessDate),
extra = found.extra,
}
end
-- Returns the unexpanded citation wikitext for a Wikidata reference
-- (reference structure + options, as for Modul:Citat Q's cite_ref) and,
-- for sub-referenceable references, a second value with the details text.
function p.cite(reference, options)
if reference and reference.snaks then
local statedInId, details = splitSnakDetails(reference.snaks)
if statedInId then
return CitatQ.cite_item_lua(statedInId, {}), details
end
end
return CitatQ.cite_ref(reference, options)
end
-- Wraps citation text in a <ref> whose name is derived from the text.
-- The optional details become the ref's |details= attribute; they are not
-- part of the name, so all sub-references of a work share the main reference.
function p.wrap(content, frame, details)
if not content or content == '' then return '' end
frame = frame or mw.getCurrentFrame()
local args = { name = 'wdref-' .. mw.hash.hashValue('md5', content) }
if details and details ~= '' then args.details = details end
return frame:extensionTag{
name = 'ref',
content = content,
args = args,
}
end
-- Lua entry point: parameters -> Modul:Citat Q -> named <ref>.
function p.build(frame, ...)
local content, details = p.cite(...)
return p.wrap(content, frame, details)
end
-- Template entry point: {{#invoke:RefQ|ref|Q136354833|...}} (or through {{RefQ}})
-- Takes what {{Citat Q}} takes: the QID in |1= (or |q=) plus optional overrides.
-- Locator parameters (pages, chapter, section, access date, details) go into
-- the ref's |details= attribute, in the same form as for Wikidata references;
-- all other parameters are passed to Modul:Citat Q's cite_item_lua, which
-- returns the same kind of unexpanded text as cite_ref, so equal citations
-- get equal names whether they come from a template or from Wikidata.
function p.ref(frame)
local args = getArgs(frame)
local qid = args.q or args[1]
if not qid or qid == '' then
return '<span class="error">RefQ: lipsă QID</span>'
end
local rest, details = splitArgDetails(args)
rest.q = nil
rest[1] = nil
return p.wrap(CitatQ.cite_item_lua(qid, rest), frame, details)
end
return p