Modul:Zitation
local Serial = "2019-01-17" --[=[ Zitation ]=]
Zitation = Zitation or { extern = false } Zitation.serial = Serial -- local globals local Selbst = "Modul:Zitation" local FehlerTypen = { Intern = { s = "Interner Fehler",
k = "Intern" }, Entfernen = { s = "Veraltet, bitte entfernen" }, Format = { s = "Parameterformat" }, Konflikt = { s = "Parameterkonflikt", k = "Parameter" }, Modul = { s = "Modul-Seite fehlt", k = "Intern" }, Name = { s = "Schreibweise falsch", k = "Name" }, Pflicht = { s = "Pflichtparameter fehlt", k = "Parameter" }, Problem = { s = "Parameterproblem" }, Abruf = { s = "Abrufdatum mangelhaft", k = "Abruf" }, Vorlage = { s = "Vorlagen-Seite fehlt", k = "Intern" }, Wert = { s = "Ungültig", k = "Parameter" } }
local KategorieBeginn = "Wikipedia:Vorlagenfehler" local Kategorien = { Intern = { s = "/Interner Fehler" },
Name = { s = "/Parameterfehler" }, Parameter = { s = "/Parameterfehler" }, Abruf = { s = "/Abrufdatum" }, arXiv = { s = "Parameter:arXiv" }, bibcode = { s = "Parameter:bibcode" }, Datum = { s = "Parameter:Datum" }, DNB = { s = "Parameter:DNB" }, DOI = { s = "Parameter:DOI" }, ISBN = { s = "Parameter:ISBN" }, ISSN = { s = "Parameter:ISSN" }, JSTOR = { s = "Parameter:JSTOR" }, LCCN = { s = "Parameter:LCCN" }, OCLC = { s = "Parameter:OCLC" }, PMID = { s = "Parameter:PMID" }, Sprachcode = { s = "Parameter:Sprachcode" }, URN = { s = "Parameter:URN" }, ZDB = { s = "Parameter:ZDB" } }
local DocTypes =
{ CSV = "CSV", DJVU = "DjVu", FLASH = "Flash", GZIP = "gzip", MIDI = "Musical Instrument Digital Interface", MP3 = "MP3", MPEG = "MPEG", MPEG4 = "MPEG-4", MSEXCEL = "MS Excel", MSPOWERPOINT = "MS PowerPoint", MSWORD = "MS Word", PDF = "PDF", POSTSCRIPT = "PostScript", RAR = "RAR", REAL = "RealPlayer", RTF = "Rich Text Format", WINDOWSMV = "WMV", ZIP = "ZIP" }
local URLunwanted = {
["//arxiv%.org/abs/"] = "arXiv", ["//adsabs%.harvard%.edu/"] = "bibcode", ["//portal%.dnb%.de/opac.+query=%d+X?$"] = "DNB", ["//doi%.org/10%."] = "DOI", ["//dx%.doi%.org/10%."] = "DOI", ["jstor%.org/pss/"] = "JSTOR", ["jstor%.org/stable/"] = "JSTOR", ["www%.worldcat%.org/oclc"] = "OCLC", ["ncbi%.nlm%.nih%.gov/pmc/articles/PMC%d"] = "PMC", ["ncbi%.nlm%.nih%.gov/pmc/articles/pmc%d"] = "PMC", ["ncbi%.nlm%.nih%.gov/pubmed/%d"] = "PMID", ["//nbn%-resolving%.de/urn:"] = "URN", ["//urn%.nb%.no/urn:nbn:"] = "URN", ["//urn%.kb%.se/resolve%?urn="] = "URN" }
local Fehler = false local Fun = { } local KBytesMax = 100 local Resultat local Silent = false local Spacer
-- Allgemeine Hilfsfunktionen ===========================================
local function faced( ahead, after )
-- Zwei Elemente durch schmalen Abstand verbinden -- Parameter: -- ahead -- string, mit erstem Element -- after -- string, mit zweitem Element -- Rückgabewert: string local e if not Spacer then e = mw.html.create( "span" ) :css( { display = "inline-block", width = ".2em" } ) :wikitext( " " ) Spacer = tostring( e ) end return string.format( "%s%s%s", ahead, Spacer, after )
end -- faced()
local function facet( ahead, after )
-- Zwei Elemente durch schmalen umbruchgeschützten Abstand verbinden -- Parameter: -- ahead -- string, mit erstem Element -- after -- string, mit zweitem Element -- Rückgabewert: string local e = mw.html.create( "span" ) :css( "white-space", "nowrap" ) :wikitext( faced( ahead, after ) ) return tostring( e )
end -- facet()
local function fading()
-- Ausblende-Modus feststellen -- Rückgabewert: true, wenn im Ansicht-Modus (kein Bearbeitungsmodus) if not Silent then if not Zitation.frame then Zitation.frame = mw.getCurrentFrame() end Silent = Zitation.frame:preprocess( "5291" ) end return ( Silent ~= "" )
end -- fading()
local function faraway( assign, alien )
-- Sprache zuweisen -- Parameter: -- assign -- mw.html-Element -- alien -- string mit Sprachcode, oder nil if alien and alien ~= "de" then assign:addClass( "lang" ) :attr( { dir = "auto", lang = alien } ) end
end -- faraway()
local function feed( area, access, about )
-- Zugriff auf Parameterkomponente -- Parameter: -- area -- string, mit Name der Parametergruppe -- access -- string, mit Name der Komponente, oder nil -- about -- true, for returning original parameter name -- Rückgabewert: Parameterwert, oder nil local e, r if not Zitation.o then Zitation.o = { } end e = Zitation.o[ area ] if e then if access then r = e[ access ] if type( r ) == "table" then if about then r = r.s or "???????" else r = r.v end end else r = e end end return r
end -- feed()
local function fehler( art, anzeige )
-- Ein Fehler ist aufgetreten -- Parameter: -- art -- string mit Schlüsselwort zum Typ -- anzeige -- string mit Einzelheiten, oder nil local t if not Fehler then Fehler = FehlerTypen end t = Fehler[ art ] if t then if anzeige then local s = mw.text.nowiki( anzeige ) if t.e then t.e = string.format( "%s; %s", t.e, s ) else t.e = s end end if t.k then local wk = Kategorien[ t.k ] if wk then wk.e = true else Fehler.Intern.e = "Wartungskat " .. wk Kategorien.Intern.e = true end end else Fehler.Intern.e = string.format( "fehler(%s) %s", art, anzeige ) Kategorien.Intern.e = true end
end -- fehler()
local function fehlerliste()
-- Auflistung aller Fehlermeldungen und Kategorien -- Rückgabewert: string mit formatiertem Ergebnis local r = "" local s local t = mw.title.getCurrentTitle() if Fehler then local sep = "" for k, v in pairs( Fehler ) do if v.e then if v.s then s = v.s .. ":" else s = "" end s = string.format( "*** %s %s", s, v.e ) if not v.k and fading() then local e = mw.html.create( "span" ) e:wikitext( s ) :addClass( "Zitationsfehler Zitationswartung" ) :css( "display", "none" ) s = tostring( e ) end r = string.format( "%s%s%s", r, sep, s ) sep = " " end end -- for k, v end if t.namespace == 0 or ( t.namespace == 4 and t.text:sub( 1, 4 ) == "Lua/" ) then Selbst = feed( "leise", "Vorlage" ) or Selbst for k, v in pairs( Kategorien ) do if v.e then if v.s:sub( 1, 1 ) == "/" then s = Selbst else s = "" end r = string.format( "%s", r, KategorieBeginn, s, v.s ) end end -- for k, v end return r
end -- fehlerliste()
local function fein( abtrennung, anhang )
-- Ergänze Resultat um fertig formatierten Block -- Parameter: -- abtrennung -- string mit vorangestelltem Separator -- anhang -- string mit Textelement if anhang then Resultat = string.format( "%s%s%s", Resultat, abtrennung, anhang ) end
end -- fein()
local function figure( a )
-- Ist das eine Zahl aus arabischen oder römischen Ziffern? return a:match( "^[0-9./%-:IVX]+$" ) or a:match( "^C*[LXVI]+$" ) or not mw.ustring.find( a, "%a" )
end -- figure()
local function figures( a )
-- Formatierte Aufzählung von Zahlen local i = true local r = a local j, k, s, suffix while i do i, j, suffix = r:match( "^(%d+)%-(%d+)(.*)$" ) if i then s = "" else s, i, j, suffix = r:match( "^(.*[^0-9]?)(%d+)%-(%d+)(.*)$" ) end if i then if tonumber( i ) < tonumber( j ) then k = 8211 else k = 45 end r = string.format( "%s%s&#%d;%s%s", s, i, k, j, suffix ) end end -- while return r:gsub( " +", " " ) :gsub( "(%d)%s*(ff?)%.?", "%1 %2." ) :gsub( " ", " " ) :gsub( "(%d+) (ff?%.)", faced )
end -- figures()
local function findbar( assigned, about )
-- Unauffindbare Namen (Personen) melden -- Parameter: -- assigned -- string; zwei lateinische Buchstaben oder ein CJK -- about -- string mit Parametername if not mw.ustring.find( assigned, "%a.*%a" ) then local Text = Zitation.fetch( "Text" ) if not Text.containsCJK then fehler( "Wert", string.format( "'%s' zu kurz", about ) ) end end
end -- findbar()
local function fire( art )
-- Melde Kategorie an -- Parameter: -- art -- string mit Schlagwort zum Typ local t = Kategorien[ art ] if t then t.e = true else fehler( "Intern", "Kategorie:" .. art ) end
end -- fire()
local function flat( adjust, anzahl, ascii )
-- Komma-separierte Aufzählung begrenzen -- Parameter: -- adjust -- string, mit Aufzählung -- anzahl -- number, mit Anzahl erlaubter Elemente -- ascii -- true, für ASCII-Auslassung -- Rückgabewert: string mit gleichem oder gekürztem Ergebnis local i = 1 local n = 0 local r = adjust while i do i = r:find( ",", i, true ) if i then n = n + 1 if n == anzahl then r = r:sub( 1, i ) if ascii then r = r .. " ..." else r = r .. " …" -- nbsp hellip end break -- while end i = i + 1 end end -- while i return r
end -- flat()
local function foreign( area, access )
-- Sprachcodes zuweisen -- Parameter: -- area -- string, mit Name der Parametergruppe -- access -- string, mit Name der Komponente local r = feed( area, access ) if r == "Undetermined" then fehler( "Wert", "Sprache" ) fire( "Sprachcode" ) elseif r then local Multilingual = Zitation.fetch( "Multilingual" ) local s = Multilingual.format( r, "-", false, false, false, Zitation.frame, "[, ]", " " ) local parts = mw.text.split( s or "", " " ) local lapsus for i = 1, #parts do if not Multilingual.getName( parts[ i ] ) then lapsus = true break -- for i end end -- for i if lapsus then fehler( "Wert", "Sprachcode=" .. r ) fire( "Sprachcode" ) s = r:lower():match( "^(%l%l%l?)-" ) if s then Zitation.fill( area, access, s ) end elseif s ~= r then local say = string.format( "%s: '%s' statt '%s' verwenden", "Sprachcode", s, r ) r = s Zitation.fill( area, access, r ) fehler( "Format", say ) end end return r
end -- foreign()
local function framedTemplate( access, args )
-- Vorlage einbinden -- Parameter: -- access -- Name der Vorlage -- args -- table mit Parameterliste -- Rückgabewert: string mit expandierter Vorlage if not Zitation.frame then Zitation.frame = mw.getCurrentFrame() end return Zitation.frame:expandTemplate{ title = access, args = args }
end -- framedTemplate()
local function future( ask )
-- Liegt Datum in der Zukunft? -- Parameter: -- ask -- table oder string, mit Datum -- Rückgabewert: true, wenn ask ungültig oder in der Zukunft local r = true local DateTime, datum if not Zitation.heute then DateTime = Zitation.fetch( "DateTime" ) Zitation.heute = DateTime() end if type( ask ) == "string" then DateTime = Zitation.fetch( "DateTime" ) datum = DateTime( ask ) else datum = ask end if type( datum ) == "table" then r = ( Zitation.heute < datum ) if r then local karenz = Zitation.heute:future( "15 days" ) if karenz > datum then r = false end end end return r
end -- future()
-- Spezielle Werte ======================================================
local function Abrufdatum( abruf )
-- Gib behauptetes Abrufdatum zurück -- Parameter: -- abruf -- table oder string, mit Datum local o = abruf local r if type( o ) == "string" then local DateTime = Zitation.fetch( "DateTime" ) o = DateTime( o ) end if type( o ) == "table" then if not future( o ) then local s = o:format( "ISO" ) r = o:format( "T._Monat JJJJ", "de" ) if not o.dom or not o.month then fehler( "Abruf", "Abrufdatum soll taggenau sein" ) elseif abruf ~= s then fehler( "Format", string.format( "'%s'=%s soll sein: %s", feed( "www", "Abruf", true ), abruf, s ) ) fire( "Datum" ) end end end if not r then r = abruf fehler( "Wert", string.format( "'%s'=%s", feed( "www", "Abruf", true ), abruf ) ) fire( "Datum" ) end return "abgerufen am " .. r
end -- Abrufdatum()
local function Herausgeber( apply, above, ahead )
-- Analysiere Herausgeber und formatiere ihn, mit Klammerzusatz -- Parameter: -- access -- string mit Herausgeber -- above -- true: innerhalb Klammerebene -- ahead -- true: vorangestellt statt Klammerzusatz -- Rückgabewerte: -- string local pat = "^([^%(%[]+)[%(%[]((%w+)%.?)[%)%]](.*)$" local scan = apply local seek = "|hg|hsg|hrsg|hrsgg|herausgeber|ed|eds|editor|editors|" local story = "" local r, s, start, sub, suffix while true do start, sub, s, suffix = mw.ustring.match( scan, pat ) if s then if seek:find( string.format( "|%s|", s:lower() ) ) then story = story .. mw.text.trim( start ) elseif suffix:sub( 1, 1 ) == "|" and sub:sub( 1, -1 ) == ")" then story = string.format( "%s%s%s", story, start, sub ) else story = string.format( "%s%s[%s]", story, start, s ) end scan = suffix else break -- while end end -- while r = story .. scan sub, suffix = mw.ustring.match( r, "^(%w+%.?)%s*(.+)$" ) if sub == "Hg." then -- (Verwechslungsgefahr bei abgekürztem Vornamen) r = mw.text.trim( suffix ) elseif sub then seek = "|hrsg|hrsgg|herausgegeben|" if seek:find( string.format( "|%s|", sub:lower() ) ) then r = mw.text.trim( suffix ) sub, suffix = mw.ustring.match( r, "^(vo?n?.?)%s*(.+)$" ) if sub == "von" or sub == "v." then r = mw.text.trim( suffix ) end end end if r ~= apply or r:match( "%)$" ) then fehler( "Wert", "Herausgeber mit problematischem Zusatz" ) end findbar( r, "Hrsg" ) if ahead then r = "Hrsg.: " .. r else if above then r = r .. " [Hrsg.]" else r = r .. " (Hrsg.)" end end return r
end -- Herausgeber()
local function Ortsname( analyse, area, access )
-- Analysiere einen Ortsnamen -- Parameter: -- analyse -- string, mit Ortsname -- area -- string, mit Name der Parametergruppe -- access -- string, mit Name der Komponente local s = analyse:gsub( "&#%x+;", "" ) if s:find( "%d%d%d%d" ) then fehler( "Wert", string.format( "'%s' %s (%s)", feed( area, access, true ), "mit verdächtiger Ziffernfolge", "Jahreszahl, Postleitzahl" ) ) end
end -- Ortsname()
Fun.arXiv = function ( access )
-- Analysiere arXiv-ID und gib sie als formatierten Link zurück local arXiv = Zitation.fetch( "arXiv", "Vorlage:arXiv" ) local details = arXiv.fair( access ) if not details.legal then fehler( "Wert", "'arXiv'" ) fire( "arXiv" ) end arXiv.features( { showArticle = "arXiv" } ) return arXiv.format( details )
end -- Fun.arXiv()
Fun.bibcode = function ( access )
-- Analysiere bibcode-ID und gib sie als formatierten Link zurück local bibcode = Zitation.fetch( "bibcode", "Vorlage:bibcode" ) local r = bibcode.format{ access } if not r:find( "//", 1, true ) then fehler( "Wert", "'bibcode' =" .. access ) fire( "bibcode" ) end return r
end -- Fun.bibcode()
Fun.DOI = function ( access )
-- Analysiere DOI und gib sie als formatierten Link zurück local URIutil = Zitation.fetch( "URIutil" ) local r = URIutil.linkDOI( access ) local s = "Digital Object Identifier" if r then r = string.format( "doi:%s", s, r ) else r = string.format( "DOI:%s%s", s, access, Zitation.fault( "(?!)", true )) fehler( "Wert", "'DOI'" ) fire( "DOI" ) end return r
end -- Fun.DOI()
Fun.DNB = function ( access )
-- Analysiere DNB und gib sie formatiert zurück local URIutil = Zitation.fetch( "URIutil" ) local r if URIutil.isDNBvalid( access ) then r = URIutil.linkDNBopac( access, false, true, true ) else local s = "Deutsche Nationalbibliothek" fehler( "Wert", "'DNB'" ) fire( "DNB" ) r = string.format( "DNB %s%s", s, access, Zitation.fault( "(?!)", true )) end return r
end -- Fun.DNB()
Fun.ISSN = function ( access, allow )
-- Analysiere ISSN und gib sie formatiert zurück -- allow -- true: permit invalid check digit local URIutil = Zitation.fetch( "URIutil" ) if allow or URIutil.isISSNvalid( access ) then r = URIutil.linkISSN( access, allow, true, true ) else local s = "International Standard Serial Number" fehler( "Wert", "'ISSN'" ) fire( "ISSN" ) r = string.format( "ISSN %s%s", s, access, Zitation.fault( "(?!)", true )) end return r
end -- Fun.ISSN()
Fun.ISSNfalsch = function ( access )
-- Analysiere formal falsche ISSN und gib sie formatiert zurück return Fun.ISSN( access, true )
end -- Fun.ISSNfalsch()
Fun.JSTOR = function ( access )
-- Analysiere JSTOR (stable) und gib sie formatiert zurück -- i: Volume local JSTOR = Zitation.fetch( "JSTOR" ) local r, URIutil if access:find( "/", 1, true ) then URIutil = Zitation.fetch( "URIutil" ) end r = JSTOR.feasible( access, "stable", URIutil ) if r then r = JSTOR.format( r, "stable", false, URIutil ) else fehler( "Wert", "'JSTOR'" ) fire( "JSTOR" ) r = string.format( "JSTOR:%s%s", access, Zitation.fault( "(?!)", true )) end return r
end -- Fun.JSTOR()
Fun.LCCN = function ( access )
-- Analysiere LCCN und gib sie formatiert zurück local URIutil = Zitation.fetch( "URIutil" ) local see = "Library of Congress Control Number" local r = string.format( "LCCN ", see ) if URIutil.isLCCN( access ) then r = r .. URIutil.linkLCCN( access, "-" ) else fehler( "Wert", "'LCCN'" ) fire( "LCCN" ) r = string.format( "%s%s%s", r, access, Zitation.fault( "(?!)", true )) end return r
end -- Fun.LCCN()
Fun.Lizenznummer = function ( access )
-- Gib DDR-Lizenznummer formatiert zurück return "Lizenznummer " .. access
end -- Fun.Lizenznummer()
Fun.OCLC = function ( access )
-- Analysiere OCLC und gib sie formatiert zurück local r if access:match( "^[1-9][0-9]*$" ) then r = framedTemplate( "OCLC", { access } ) else fehler( "Wert", "'OCLC'" ) fire( "OCLC" ) r = string.format( "OCLC %s", access ) end return r
end -- Fun.OCLC()
Fun.PMC = function ( access )
-- Analysiere PMC und gib sie formatiert zurück local start, s = access:match( "^(%a%a%a)%s*(%d+)$" ) local r if start and start:upper() == "PMC" then fehler( "Wert", "'PMC' vor Nummer unerwünscht" ) else s = access end if s:match( "^[1-9][0-9]*$" ) then r = framedTemplate( "PMC", { s } ) else fehler( "Wert", "'PMC'" ) fire( "PMID" ) -- Ja, PMID-Experte betreut auch PMC r = string.format( "PMC %s", access ) end return r
end -- Fun.PMC()
Fun.PMID = function ( access )
-- Analysiere PMID und gib sie formatiert zurück if not access:match( "^[1-9][0-9]*$" ) then fehler( "Wert", "'PMID'" ) fire( "PMID" ) end return string.format( "PMID %s", access )
end -- Fun.PMID()
Fun.URN = function ( access )
-- Analysiere URN und gib sie formatiert zurück local URIutil = Zitation.fetch( "URIutil" ) local r = URIutil.uriURN( "urn:" .. access ) if not r:find( "//", 1, true ) then fehler( "Wert", "'URN'=" .. access ) fire( "URN" ) end return r
end -- Fun.URN()
Fun.ZDB = function ( access )
-- Analysiere ZDB und gib sie formatiert zurück local URIutil = Zitation.fetch( "URIutil" ) if URIutil.isDNBvalid( access ) or URIutil.isDNBvalid( access:gsub( "-", "" ) ) then r = framedTemplate( "ZDB", { access:upper() } ) else local s = "Zeitschriftendatenbank" fehler( "Wert", "'ZDB'" ) fire( "ZDB" ) r = string.format( "ZDB %s%s", s, access, Zitation.fault( "(?!)", true )) end return r
end -- Fun.ZDB()
local function redundanz( analyse )
-- Prüfe Angabe auf Redundanz mit anderen Parametern -- Parameter: -- analyse -- string for k, v in pairs( URLunwanted ) do if analyse:match( k ) then local s = string.format( "%s '%s=' %s", "Statt URL sollte etwas wie", v, "angegeben werden" ) fehler( "Konflikt", s ) end end -- for k, v if analyse:find( "title=\"ctx_ver=Z39.88-2004", 1 , true ) then fehler( "Konflikt", "Verschachtelte Zitationsvorlagen" ) end
end -- redundanz()
local function bandNummer( area )
-- Formatiere Angaben von Band und/oder Nummer -- Parameter: -- area -- string, mit Name der Parametergruppe print/serie -- Rückgabewert: string mit Inhalt, oder nil local sB = feed( area, "Band" ) local sN = feed( area, "Nummer" ) local lead, r if sB then sB = sB:gsub( " ", " " ) :gsub( "&#%x+;", " " ) :gsub( " ", " " ) :gsub( "%s%s+", " " ) if sB:sub( 1, 5 ) == "Band " then sB = sB:sub( 6 ) lead = true elseif sB:sub( 1, 3 ) == "Bd." then sB = mw.text.trim( sB:sub( 4 ) ) lead = true end if figure( sB ) then r = facet( "Band", sB ) else if lead then sB = "Band " .. sB end r = sB:gsub( "(Band) (%d+)", facet ) end end if sN then lead = false sN = sN:gsub( " ", " " ) :gsub( "&#%x+;", " " ) :gsub( " ", " " ) :gsub( "%s%s+", " " ) if sN:sub( 1, 7 ) == "Nummer " then sN = sN:sub( 8 ) lead = true elseif sN:sub( 1, 3 ) == "Nr." then sN = mw.text.trim( sN:sub( 4 ) ) lead = true end if figure( sN ) then sN = facet( "Nr.", sN ) else if lead then sN = "Nr. " .. sN end sN = sN:gsub( "(Nr%.) (%d+)", facet ) end if r then r = string.format( "%s, %s", r, sN ) else r = sN end end return r
end -- bandNummer()
local function Kapitel( a )
-- Formatiere Kapitelangabe local r = a if a:match( "^%d+$" ) then r = facet( "Kap.", a ) end return r
end -- Kapitel()
local function ArtikelNr( aN, aS )
-- Analysiere ArtikelNr if aS then fehler( "Konflikt", "Seitenzahl redundant wenn ArtikelNr" ) end if not aN:match( "^%d+$" ) then fehler( "Wert", "'ArtikelNr'=" .. aN ) end
end -- ArtikelNr()
local function Seiten( a )
-- Analysiere Seitenzahl und formatiere local s, seiten = a:match( "^(%w+%.?)%s*(.+)$" ) local r if s then local seek = "|s.|ss.|seite|seiten|page|pages|p.|pp.|" if seek:find( string.format( "|%s|", s:lower() ) ) then fehler( "Wert", "Seitenzahl mit unnötigem Zusatz" ) seiten = mw.text.trim( seiten ) else seiten = a end else seiten = a end if #seiten > 50 then -- URL? Google-Buch? local shrink = string.format( "[%%-0-9,;/ f%%.%s]", mw.ustring.char( 8211 ) ) s = mw.ustring.gsub( seiten, shrink, "" ) if #s > 10 then fehler( "Wert", "Seitenzahl unerklärlich lang" ) r = a end end if not r then r = facet( "S.", figures( seiten ) ):gsub( "%.$", "." ) end return r
end -- Seiten()
local function Spalten( a )
-- Analysiere Spaltenangabe und formatiere local s, sp = a:match( "^(%w+%.?)%s*(.+)$" ) if s then local seek = "|sp.|spalte|spalten|" if seek:find( string.format( "|%s|", s:lower() ) ) then fehler( "Wert", "Spaltenangabe mit unnötigem Zusatz" ) sp = mw.text.trim( sp ) else sp = a end else sp = a end return facet( "Sp.", figures( sp ) ):gsub( "%.$", "." )
end -- Spalten()
local function Werktitel( a, amend, alien, abschluss )
-- Formatiere einen Werktitel, das Sammelwerk, ggf. Reihe -- Parameter: -- a -- string -- amend -- string mit Ergänzung, oder nil -- alien -- string mit Sprachcode, oder nil -- abschluss -- true: Satzendezeichen sicherstellen -- Rückgabewert: string mit formatiertem Werktitel local Text = Zitation.fetch( "Text" ) local cite = mw.html.create( "cite" ) local sep local r cite:css( "font-style", "italic" ) :wikitext( Text.uprightNonlatin( a ) ) faraway( cite, alien ) r = tostring( cite ) if amend then local s if Text.sentenceTerminated( a ) then sep = "" else sep = "." end r = string.format( "%s%s %s", r, sep, amend ) end if abschluss and ( ( not amend and not Text.sentenceTerminated( a ) ) or ( amend and not Text.sentenceTerminated( amend ) ) ) then r = r .. "." end return r
end -- Werktitel()
-- Einzelblöcke der Darstellung =========================================
local function resourceMeta( anfang )
-- Ergänze Resultat um für einen Online-Abruf wichtigen Informationen -- anfang -- boolean -- * true -- runde Klammern -- um .Format und .KBytes gesetzt -- * false -- eckige Klammern -- um .Format und .KBytes und .Abruf -- Rückgabewert: string mit führendem " " und Inhalt, oder "" local r = "" if feed( "www" ) then local sURL = feed( "www", "URL" ) local sWeblink = feed( "www", "Weblink" ) local some = ( sURL or sWeblink ) local sAbruf = feed( "www", "Abruf" ) local sFormat = feed( "www", "Format" ) local sKBytes = feed( "www", "KBytes" ) if some then local sep = "" some = some:lower() .. " " if sFormat then local s = sFormat:upper() if s ~= "HTML" then if s:find( "PDF%-?" ) then r = "pdf" else r = sFormat end end elseif some:find( "%Wpdf%W" ) then r = "pdf" end if r:lower() == "pdf" and sWeblink and some:find( " .*pdf" ) then r = "" end if r == "" then sKBytes = false else local docTypes = mw.text.split( r:upper(), " " ) local s r = "" sep = "" for i = 1, #docTypes do s = docTypes[ i ] r = string.format( "%s%s%s", r, sep, DocTypes[ s ] or s ) sep = " " end -- for i sep = "; " end if sKBytes then local scan = "^(%d+[,%.]?%d*)%s*(%a*)$" local large = sKBytes:find( "[sic!]", 3, true ) local lot, size, suffix sKBytes = sKBytes:gsub( " ", " " ) :gsub( " ", " " ) :gsub( "�*[aA]0;", " " ) :gsub( " ", " " ) :gsub( "�*202[fF];", " " ) :gsub( " ", " " ) if large then sKBytes = sKBytes:gsub( "%s*%[sic!%]%s*$", "" ) end size, suffix = sKBytes:match( scan ) if size then local n size = size:gsub( "%.", "" ) if size:find( "," ) then n = tonumber( size:gsub( ",", "." ), 10 ) size = string.format( "%1.1d", n ) else n = tonumber( size ) end if suffix then if suffix == "" then suffix = false else suffix = suffix:lower() if suffix:match( "^mi?b%l*$" ) then n = n * 1000 suffix = false elseif suffix:match( "^ki?b%l*$" ) then suffix = false end end end if suffix then fehler( "Wert", "Byte-Einheit nicht erkannt" ) else if n > 1000 then n = math.ceil( n * 0.01 ) * 0.1 size = string.format( "%.1f", n ) suffix = "MB" lot = ( n > KBytesMax ) else suffix = "kB" end end sKBytes = facet( size:gsub( "%.", "," ), suffix ) if lot then sKBytes = string.format( "%s", sKBytes ) if not large then fehler( "Wert", "zu viele MegaBytes" ) end end else fehler( "Wert", "KiloByte-Zahl nicht erkannt" ) end r = string.format( "%s%s%s", r, sep, sKBytes ) if large and not lot then fehler( "Wert", "Fehlplatziertes [sic!]" ) end sep = "; " end if not anfang and sAbruf and sWeblink then r = string.format( "%s%s%s", r, sep, Abrufdatum( sAbruf ) ) end if r ~= "" then if anfang then sep = " (%s)" else sep = " [%s]" end r = string.format( sep, r ) end redundanz( some ) elseif sFormat or sKBytes or sAbruf then local s = feed( "bas", "Titel" ) if not s or not s:find( "//" ) then fehler( "Problem", "Dateiformat/Größe/Abruf nur wenn Weblink" ) end end end return r
end -- resourceMeta()
local function autorHrsg()
-- Ergänze Resultat um Personen zu Beginn der Zitation local sAutor = feed( "bas", "Autor" ) local sHrsg = feed( "bas", "Hrsg" ) local sTyp = feed( "leise", "Typ" ) local lead if sTyp and sTyp ~= "wl" then fehler( "Wert", "'Typ' zurzeit nur 'Typ=wl' (Werkliste) unterstützt" ) r = "wl" end if sHrsg then lead = ( not feed( "bas", "Werk" ) ) findbar( sHrsg, "Hrsg" ) end if sAutor or lead then local list = false if sAutor then sAutor = sAutor:gsub( "^#", "#" ) -- nick, hashtag :gsub( "^%*", "*" ) if sTyp ~= "wl" then fein( "", sAutor ) list = true end if type( sAutor ) == "table" then sAutor = Zitation.citePerson( sAutor, false ) end findbar( sAutor, "Autor" ) if sHrsg and not feed( "bas", "Titel" ) then fehler( "Konflikt", "Gleichzeitig 'Autor' und 'Hrsg' nur wenn auch 'Titel'" ) end else fein( "", Herausgeber( sHrsg ) ) list = true end if list then fein( ": ", "" ) end end
end -- autorHrsg()
local function erstAusgabe()
-- Erstausgabe -- Rückgabewert: string local sJahr = feed( "ed1", "Jahr" ) local sOrt = feed( "ed1", "Ort" ) local sVerlag = feed( "ed1", "Verlag" ) local r = "Erstausgabe: " local sep if sVerlag then r = r .. sVerlag sep = "," if feed( "bas", "Verlag" ) == sVerlag then fehler( "Konflikt", string.format( "'%s' hat gleichen Wert wie '%s'", feed( "ed1", "Verlag", true ), feed( "bas", "Verlag", true ) ) ) end else sep = "" end if sOrt then r = string.format( "%s%s %s", r, sep, sOrt ) Ortsname( sOrt, "ed1", "Ort" ) sep = " " -- bas.Verlag und ed1.Verlag dürfen in derselben Stadt sein end if sJahr then local jahr if sJahr:match( "^%d%d%d%d$" ) then if not future( sJahr ) then jahr = tonumber( sJahr ) end end if jahr then local datum = feed( "bas", "Datum" ) r = string.format( "%s%s %s", r, sep, sJahr ) if type( datum ) == "table" and datum.year and datum.year < jahr then fehler( "Konflikt", string.format( "'%s' nach Neuausgabe", feed( "ed1", "Jahr", true ) ) ) end else fehler( "Wert", string.format( "'%s'=%s", feed( "ed1", "Jahr", true ), sJahr ) ) fire( "Datum" ) end end return r
end -- erstAusgabe()
local function originalPublikation()
-- Originalpublikation; zulässige Parameterlogik noch unklar -- Rückgabewert: string mit Inhalt, oder false local r if feed( "orig" ) then local sTitel = feed( "orig", "Titel" ) local sTranslator = feed( "orig", "Translator" ) if sTitel then local sprache = foreign( "orig", "Sprache" ) local sOrt = feed( "orig", "Ort" ) local sJahr = feed( "orig", "Jahr" ) r = Werktitel( sTitel, false, sprache, true ) if sOrt then r = string.format( "%s %s", r, sOrt ) Ortsname( sOrt, "orig", "Ort" ) end if sJahr then r = string.format( "%s %s", r, sJahr ) if sJahr:match( "^%d%d%d%d$" ) then if future( sJahr ) then fehler( "Wert", "Originaljahr in der Zukunft" ) else local jahr = tonumber( sJahr ) local datum = feed( "bas", "Datum" ) if type( datum ) == "table" and datum.year and datum.year < jahr then fehler( "Konflikt", "Originaljahr nach Neuausgabe" ) end
end
else
fehler( "Wert", "Originaljahr ist keine Jahreszahl" )
end
end
if ( sOrt or sJahr ) and
( sJahr or not sOrt:match( "%.$" ) ) then
r = r .. "."
end
if sprache then
local Multilingual = Zitation.fetch( "Multilingual" )
local s = Multilingual.format( sprache, "de", "m",
false, false,
Zitation.frame,
" ", ", " )
if s then
sprache = s
elseif sprache:match( "^%l%l%l?$" ) then
fehler( "Wert",
"Unbekannter Sprachcode=" .. sprache )
fire( "Sprachcode" )
sprache = string.format( "%s
", sprache )
-- elseif sprache:match( "^%l.+[ ,;/]" ) then -- fehler( "Wert", -- "Original-Sprachcode seltsam: " .. sprache )
end else sprache = "Originaltitel" end r = string.format( "%s: %s", sprache, r ) if sTranslator then r = string.format( "%s Übersetzt von %s", r, sTranslator ) end elseif not sTranslator then fehler( "Pflicht", "Originaltitel fehlt" ) end end return r
end -- originalPublikation()
local function titel()
-- Ergänze Resultat um Titel local sTitel = feed( "bas", "Titel" ) local sWerk = feed( "bas", "Werk" ) if sTitel then local stop = "" local sReihe = feed( "serie", "Reihe" ) local sTitelErg = feed( "bas", "TitelErg" ) local sURL = feed( "www", "URL" ) local s = Werktitel( sTitel, false, feed( "bas", "Sprache" ), sWerk or not sReihe or sTitelErg ) local Text if sURL then local URLutil = Zitation.fetch( "URLutil" ) if URLutil.isResourceURL( sURL ) then s = s:gsub( "%[", "[" ) :gsub( "%]", "]" ) sURL = sURL:gsub( "%[", "%5B" ) :gsub( "%]", "%5D" ) s = string.format( "[%s %s]%s", sURL, s, resourceMeta( true ) ) else fehler( "Wert", "URL" ) end end if sTitelErg then Text = Zitation.fetch( "Text" ) if ( sWerk or not sReihe ) and not Text.sentenceTerminated( sTitelErg ) then stop = "." end s = string.format( "%s %s%s", s, sTitelErg, stop ) end fein( "", s ) if not sWerk then local sAutor = feed( "bas", "Autor" ) local sHrsg = feed( "bas", "Hrsg" ) if sAutor and sHrsg then Text = Zitation.fetch( "Text" ) if stop == "" then local strip = Resultat:gsub( "$", "" ) if not Text.sentenceTerminated( strip ) then stop = "." end elseif sTitelErg then stop = "" end stop = stop .. " " s = Herausgeber( sHrsg, false, true ) if not ( sReihe or Text.sentenceTerminated( s ) ) then s = s .. "." end fein( stop, s ) end end else if sWerk then fehler( "Pflicht", "Kein 'Titel'" ) else fehler( "Pflicht", "Weder 'Titel' noch sonstiges Werk" ) end end
end -- titel()
local function werk()
-- Ergänze Resultat um Sammelwerk usw. local sWerk = feed( "bas", "Werk" ) if sWerk then local start = " In: " local sHrsg = feed( "bas", "Hrsg" ) local s = Werktitel( sWerk, feed( "bas", "WerkErg" ), feed( "bas", "Sprache" ), not feed( "serie", "Reihe" ) ) if sHrsg then s = string.format( "%s: %s", Herausgeber( sHrsg ), s ) end if Resultat == "" then start = "In: " end fein( start, s ) end
end -- werk()
local function auflage()
-- Ergänze Resultat um Auflage local sAuflage = feed( "print", "Auflage" ) if sAuflage then local s = sAuflage:gsub( "Auflage$", "Auflage") :gsub( "[eE]d%.?$", "ed." ) :gsub( "[eE]dition", "ed." ) :gsub( "[éÉ]d%.?$", "éd." ) :gsub( "[éÉ]dition", "éd." ) if s:match( "^%d+$" ) then s = s .. "." end if not ( s:find( "Aufl", 1, true ) or s:find( "[eé]d" ) ) then s = s .. " Auflage" end if not s:match( "%.$" ) then s = s .. "." end fein( " ", s ) end
end -- auflage()
local function reihe()
-- Ergänze Resultat um Angaben zur Reihe if feed( "serie" ) then local sReihe = feed( "serie", "Reihe" ) if sReihe then local sBN = bandNummer( "serie" ) local sHrsg = feed( "serie", "Hrsg" ) local s = Werktitel( sReihe, false, feed( "bas", "Sprache" ), sBN ) if sHrsg then s = string.format( "%s: %s", Herausgeber( sHrsg, true ), s ) end if sBN then s = string.format( "%s %s", s, sBN ) end fein( " ", string.format( "(= %s).", s ) ) else local scream local flop = function ( au ) if feed( "serie", au ) then local s = feed( "serie", au, true ) if scream then scream = scream .. ", " else scream = "" end scream = string.format( "%s'%s'", scream, s ) end end -- flop() flop( "Hrsg" ) flop( "Band" ) flop( "Nummer" ) if scream then -- Muss in dieser Konstellation eigentlich immer sein fehler( "Pflicht", scream .. " nur wenn Reihe angegeben" ) end end end
end -- reihe()
local function bibliografischeAngaben()
-- Ermittle die Aufzählung bibliografische Angaben
-- Rückgabewert: string mit Inhalt, oder false
local r = ""
local sep = ""
local datum = feed( "bas", "Datum" )
local sVerlag = feed( "bas", "Verlag" )
local s, sOrt
if feed( "print" ) then
sOrt = feed( "print", "Ort" )
if sOrt and
( feed( "id", "ISSN" ) or feed( "id", "ZDB" ) ) then
sOrt = false
end
s = bandNummer( "print" )
if s then
r = s
if s:find( "%.$" ) then
sep = " "
elseif sVerlag or sOrt then
sep = ". "
else
sep = ", "
end
end
end
if sVerlag then
r = string.format( "%s%s%s", r, sep, sVerlag )
sep = ", "
end
if sOrt then
s = sOrt:gsub( "[,/; ]+$", "" )
r = string.format( "%s%s%s", r, sep, s )
if s ~= sOrt then
Zitation.fill( "print", "Ort", s )
end
Ortsname( sOrt, "print", "Ort" )
sep = ", "
end
if datum then
local o = datum
if type( datum ) == "string" then
local DateTime = Zitation.fetch( "DateTime" )
o = DateTime( datum )
end
if type( o ) == "table" and o.year then
Zitation.fill( "bas", "Datum", o )
if future( o ) or
( o.zone and not o.hour ) then
o = false
elseif feed( "id", "ISBN" ) then
s = tostring( o.year )
elseif feed( "www", "URL" ) then
s = o:format( "T._Monat JJJJ hh:mm:ss Zone" )
else
s = o:format( "T._Monat JJJJ" )
end
else
o = false
end
if not o then
if type( datum ) == "string" then
-- s = "Datum: " .. datum -- LEGACY
s = datum
else
s = "Datum??"
end
fehler( "Wert", s )
fire( "Datum" )
end
if sOrt then
sep = " "
end
r = string.format( "%s%s%s", r, sep, s )
sep = ", "
end
if feed( "id" ) then
local lazy = false -- gültige ISBN bekannt
local sID = feed( "id", "ID" )
local sISBN = feed( "id", "ISBN" )
local sISBNfalsch = feed( "id", "ISBNfalsch" )
local sISBNdefekt = feed( "id", "ISBNdefekt" )
local fiddler =
function( at )
local s = feed( "id", at )
if s then
if lazy and
not ( at == "ISSN" or
at == "ISSNfalsch" ) then
s = "redundant, da ISBN gegeben"
s = string.format( "'%s' %s",
feed( "id", at, true ),
s )
fehler( "Konflikt", s )
else
s = Fun[ at ]( s )
r = string.format( "%s%s%s",
r, sep, s )
sep = ", "
end
end
end
if sISBN and sISBNfalsch then
s = string.format( "'%s' und '%s' %s",
feed( "id", "ISBN", true ),
feed( "id", "ISBNfalsch", true ),
"nicht gleichzeitig angeben" )
fehler( "Konflikt", s )
elseif sISBN or sISBNfalsch then
local mode
if sISBNfalsch then
mode = -1
end
s, lazy = Zitation.ISBN( sISBN or sISBNfalsch, mode )
r = string.format( "%s%s%s", r, sep, s )
sep = ", "
end
if sISBNdefekt then
s = Zitation.ISBN( sISBNdefekt, #sISBNdefekt )
r = string.format( "%s%s%s", r, sep, s )
sep = ", "
end
fiddler( "ISSN" )
fiddler( "ISSNfalsch" )
fiddler( "DNB" )
fiddler( "LCCN" )
fiddler( "Lizenznummer" )
fiddler( "OCLC" )
fiddler( "ZDB" )
if sID then
r = string.format( "%s%s%s", r, sep, sID )
sep = ", "
redundanz( sID )
end
end
if feed( "fragment" ) then
local sArtikelNr = feed( "fragment", "ArtikelNr" )
local sFundstelle = feed( "fragment", "Fundstelle" )
local sKapitel = feed( "fragment", "Kapitel" )
local sSeiten = feed( "fragment", "Seiten" )
local sSpalten = feed( "fragment", "Spalten" )
if sKapitel then
r = string.format( "%s%s%s", r, sep, Kapitel( sKapitel ) )
sep = ", "
end
if sSeiten then
r = string.format( "%s%s%s", r, sep, Seiten( sSeiten ) )
sep = ", "
end
if sSpalten then
r = string.format( "%s%s%s", r, sep, Spalten( sSpalten ) )
sep = ", "
end
if sArtikelNr then
ArtikelNr( sArtikelNr, sSeiten )
r = string.format( "%s%s%s", r, sep, sArtikelNr )
sep = ", "
end
if sFundstelle then
r = string.format( "%s%s%s",
r,
sep, "white-space:nowrap", sFundstelle )
sep = ", "
end
end
if feed( "id" ) then
local docCodes = { "DOI",
"PMID",
"PMC",
"arXiv",
"bibcode",
"JSTOR",
"URN" }
local sign
for i = 1, #docCodes do
s = docCodes[ i ]
sign = feed( "id", s )
if sign then
r = string.format( "%s%s%s", r, sep, Fun[ s ]( sign ) )
sep = ", "
end
end -- for i
end
if r == "" then
r = false
end
return r
end -- bibliografischeAngaben()
local function klammerInhalt()
-- Inhalt der Klammer am Ende der bibliografischen Angaben -- Rückgabewert: string mit Inhalt, oder false local r = "" local sep = "" local sKommentar = feed( "bas", "Kommentar" ) local sOrig = originalPublikation() local sprache = feed( "bas", "Sprache" ) local sUmfang = feed( "print", "Umfang" ) if sprache and sprache ~= "de" then local Multilingual = Zitation.fetch( "Multilingual" ) sprache = Multilingual.format( sprache, "de", "m", false, false, Zitation.frame, " ", ", " ) r = string.format( "%s%s%s", r, sep, sprache ) sep = ", " end if sUmfang then if not mw.ustring.find( sUmfang, "%a" ) then -- "14, 234" sUmfang = string.format( "%s S.", sUmfang ) end r = string.format( "%s%s%s", r, sep, sUmfang ) sep = ", " end local sanitize = feed( "www", "Weblink" ) if sanitize and sanitize:find( "InternetArchiveBot", 1, true ) then -- 2018-12-04 mw.addWarning( "Unerlaubte Bot-Aktion
" .. "Informationsverlust vorheriger Angaben.
" .. "Unzulässige Formatierung.
" .. sanitize ) fein( "", "") Zitation.o.www = false
-- Wiederholt ZR-widrig den Titel der Website u. a. 171587445/183321268
end if feed( "www" ) then local sWeblink = feed( "www", "Weblink" ) if sWeblink then local WLink = Zitation.fetch( "WLink" ) local show = WLink.getWeblink( sWeblink ) local spec = resourceMeta( false ) show = show:gsub( " www%d*%.", " " ) r = string.format( "%s%s%s%s", r, sep, show, spec ) if spec == "" then sep = " – " else sep = " " end if sWeblink:find( "", 1, true ) or sWeblink:find( "class=\"cite\"", 1, true ) then fehler( "Konflikt", "Zitationsvorlage rekursiv eingebunden" ) fire( "Parameter" ) -- Langfristig wirkungslos; greift nur vorübergehend -- wenn IQ noch reine Vorlage, -- oder cite als reine Vorlage. -- Nach vollständiger Umsetzung -- sperrt sich aber das System, -- weil Modul:Zitation -- dann rekursiv aufgerufen werden würde. end elseif feed( "www", "URL" ) then local sAbruf = feed( "www", "Abruf" ) if sAbruf then r = string.format( "%s%s%s", r, sep, Abrufdatum( sAbruf ) ) sep = ", " end else local s = feed( "bas", "Titel" ) if not s or not s:find( "//" ) then fehler( "Problem", "Dateiformat/Größe/Abruf nur bei externem Link" ) end end end if sOrig then r = string.format( "%s%s%s", r, sep, sOrig ) if feed( "orig", "Translator" ) then sep = ", " else sep = " " end end if feed( "ed1" ) then r = string.format( "%s%s%s", r, sep, erstAusgabe() ) sep = ", " end if sKommentar then r = string.format( "%s%s%s", r, sep, sKommentar ) redundanz( sKommentar ) end if r == "" then r = false end return r
end -- klammerInhalt()
local function endBlock()
-- Ergänze Resultat um bibliografische Angaben, Klammer sowie Zitat. -- Komma-getrennte Aufzählung, die mit Punkt abgeschlossen wird, -- oder Zitat wird nachgestellt. local sZitat = feed( "bas", "Zitat" ) local sep = "" local s = bibliografischeAngaben() if s then fein( " ", s ) if not s:match( "%.$" ) then sep = "." end end s = klammerInhalt() if s then if Resultat:find( "%)$" ) then -- Irgendwas zuvor endet auf eine runde Klammer. sep = " – (" else sep = " (" end fein( sep, s .. ")" ) sep = "." end if sep ~= "" then -- Aufzählung enthält zumindest ein Element if sZitat then fein( ":", "" ) elseif not Resultat:match( "%.$" ) then fein( ".", "" ) end end if sZitat then local sprache = feed( "bas", "Sprache" ) local Text = Zitation.fetch( "Text" ) local story = Text.quoteUnquoted( sZitat, sprache ) if sprache and sprache ~= "de" then local q = mw.html.create( "span" ) faraway( q, sprache ) q:wikitext( story ) story = tostring( q ) end fein( " ", story ) end
end -- endBlock()
local function coins()
-- Ergänze Resultat um COinS, wenn gewünscht local COinS = feed( "coins" ) if COinS then local std = "book" local pars if type( COinS ) == "table" then pars = COinS elseif feed( "bas" ) then local datum = feed( "bas", "Datum" ) local sAutor = feed( "bas", "Autor" ) local sKapitel = feed( "fragment", "Kapitel" ) local sTitel = feed( "bas", "Titel" ) local sWerk = feed( "bas", "Werk" ) local stick pars = { } if sWerk then if feed( "print", "Nummer" ) or feed( "id", "ISSN" ) or feed( "id", "ISSNfalsch" ) or feed( "id", "ZDB" ) or feed( "fragment", "ArtikelNr" ) then pars.genre = "journal" pars.jtitle = sWerk std = "journal" else pars.genre = "book" pars.btitle = sWerk end pars.atitle = sTitel elseif sKapitel then pars.genre = "bookitem" pars.btitle = sTitel pars.atitle = sKapitel else pars.genre = "book" pars.btitle = sTitel end if type( datum ) == "table" then pars.date = datum:format( "ISO" ) end if sAutor then if type( sAutor ) == "table" then stick = Zitation.citePerson( sAutor, true ) else pars.au = flat( sAutor, 3, true ) end end pars.pub = feed( "bas", "Verlag" ) pars.pages = feed( "fragment", "Seiten" ) if feed( "id" ) then pars.isbn = feed( "id", "ISBN" ) or feed( "id", "ISBNfalsch" ) feed( "id", "ISBNfalsch" ) pars.issn = feed( "id", "ISSN" ) or feed( "id", "ISSNfalsch" ) pars.oclc = feed( "id", "OCLC" ) pars.doi = feed( "id", "DOI" ) pars.pmc = feed( "id", "PMC" ) pars.pmid = feed( "id", "PMID" ) end if feed( "print" ) then pars.edition = feed( "print", "Auflage" ) pars.issue = feed( "print", "Nummer" ) pars.place = feed( "print", "Ort" ) pars.volume = feed( "print", "Band" ) end pars.series = feed( "serie", "Reihe" ) end if pars then fein( "", Zitation.COinS( pars, false, stick ), std ) end end
end -- coins()
-- Exportierte Funktionen ===============================================
Zitation.failure = function ( alert, always )
-- Ausgabe von Fehlern mit class=error -- Parameter: -- alert -- string, mit Fehlerliste, oder nil -- always -- do not hide: boolean, or nil -- Rückgabewert: string, ggf. mit Fehlermeldung local r if alert then local TemplUtl = Zitation.fetch( "TemplUtl" ) local light = feed( "leise", "leiser" ) and not always local self = feed( "leise", "Vorlage" ) or Selbst r = string.format( "Fehler in %s – %s", self, alert ) r = TemplUtl.failure( r, not light, false, Zitation.frame ) else r = "" end return r
end -- Zitation.failure()
Zitation.fault = function ( a, always )
-- Formatiere Fehler als teils ausgeblendet -- Parameter: -- a -- string, mit Fehlermeldung -- always -- true, wenn nicht zu unterdrücken -- Rückgabewert: -- string, ggf. mit umschließendem HTML-Element local r if not always and feed( "leise", "leiser" ) and mw.site.server == "//de.wikipedia.org" then if fading() then local e = mw.html.create( "span" ) e:addClass( "Zitationsfehler Zitationswartung" ) :css( "display", "none" ) :wikitext( a ) r = tostring( e ) end end return r or a
end -- Zitation.fault()
Zitation.fetch = function ( assigned, acquire )
-- Binde Modul ein -- Parameter: -- assigned -- string mit Name -- "arXiv" -- "bibcode" -- "DateTime" -- "JSTOR" -- "Multilingual" -- "TemplUtl" -- "Text" -- "URIutil" -- "URLutil" -- "WLink" -- acquire -- string mit abweichendem Modulnamen, oder false -- Rückgabewert: table des Moduls -- error: Modul nicht gefunden local r if Zitation.extern then r = Zitation.extern[ assigned ] else Zitation.extern = { } end if not r then local s = assigned local lucky, g if acquire then s = acquire end lucky, g = pcall( require, "Module:" .. s ) if type( g ) == "table" then r = g[ assigned ]() Zitation.extern[ assigned ] = r else fehler( "Modul", g ) error( string.format( "Zitation.fetch(%s) %s", s, g ) ) end end return r
end -- Zitation.fetch()
Zitation.figure = function ( adjust )
-- Bilde Zahlenwert -- Parameter: -- adjust -- Wert beliebigen Typs -- Rückgabewert: -- Numerischer Wert, notfalls 0 local r local s = type( adjust ) if s == "string" then r = tonumber( adjust ) or 0 elseif s == "number" then r = adjust else r = 0 end return r
end -- Zitation.figure()
Zitation.fill = function ( area, access, assign, alias )
-- Parameterkomponente zuweisen -- Parameter: -- area -- string, mit Name der Parametergruppe -- access -- string, mit Name der Komponente -- assign -- Parameterwert -- alias -- string, mit Name des Benutzerparameters, oder nil if not Zitation.o then Zitation.o = { } end if type( Zitation.o[ area ] ) ~= "table" then Zitation.o[ area ] = { } end Zitation.o[ area ][ access ] = { s = alias or string.format( "%s.%s", area, access ), v = assign }
end -- Zitation.fill()
Zitation.filler = function ( args, assign )
-- Parameterkomponenten zuweisen -- Parameter: -- args -- Zfilter.object, -- mit Zuweisungen nach Vorlagenparametername -- assign -- table, mit Transformation in neutrales Datenmodell local g, r, value if not Zitation.o then Zitation.o = { } end for k, v in pairs( assign ) do value = args{ k } if value then g = v[ 1 ] if not Zitation.o[ g ] then Zitation.o[ g ] = { } end Zitation.o[ g ][ v[ 2 ] ] = value end end -- for k, v
end -- Zitation.filler()
Zitation.filter = function ( args, allowed )
-- Analysiere Argumentenliste und gleiche mit erlaubten Namen ab -- Parameter: -- args -- table, mit aktuellen Werten -- allowed -- table, mit erlaubten Namen, zugewiesen: -- true -- Nur diese Namensvariante bekannt -- table -- Namensvariationen -- Jeder Wert: -- true -- unerwünscht, Meldung -- table -- Details -- table -- low=true: Keine Meldung -- Rückgabewerte: -- table, mit gefilterten Werten, nach Parametername -- Zfilter object -- Jede Komponente: -- index-Zugriff: -- string, mit Parameterwert, kein leerer string -- get-Zugriff: -- table, mit -- s=Orginal-Parametername -- v=Parameterwert, nicht leer local signatur = "__Zfilter" local meta = { } local r = { [ signatur ] = { } } local discard = false local doubled = false local un = false local d, lapsus meta.__call = function ( self, arglist ) -- Antwort auf: Tabelle{ ... } return self[ signatur ][ arglist[ 1 ] ] end meta.__index = function ( self, access ) -- Antwort auf: ... = Tabelle[x] local e = self[ signatur ][ access ] if type( e ) == "table" then e = e.v end return e end meta.__newindex = function ( self, access, assign ) -- Antwort auf: Tabelle[x] = ... local put = assign if assign and ( type( assign ) ~= "table" or not assign.v ) then put = { s=access, v=assign } end self[ signatur ][ access ] = put return end setmetatable( r, meta ) for s, v in pairs( args ) do d = allowed[ s ] if d then lapsus = false if type( d ) == "table" then for dk, dv in pairs( d ) do if args[ dk ] then if not doubled then doubled = { } end if not doubled[ dk ] then doubled[ tostring( s ) ] = dk end end end else d = false end elseif type( s ) == "string" then if d == false then if not discard then discard = { } end table.insert( discard, s ) else lapsus = true end else lapsus = true if v then if mw.text.trim( v ) == "" then fehler( "Format", "Pipe '|' zu viel" ) end v = false end s = tostring( s ) end if lapsus then if not un then un = { } end un[ s ] = true end if v == "" then v = false end if v then r[ s ] = v if v:find( "", 1, true ) and type( s ) == "string" then
if not v:find( "InternetArchiveBot", 1, true ) then
fehler( "Wert", string.format( "'%s' mit Wikisyntax", s ) )
end
end end end -- for s, v if un then local down = { } local scream = false local undesired = false local unknown = false local light, s, sa for k, v in pairs( allowed ) do s = mw.ustring.lower( k ) down[ s ] = { standard=k } if type( v ) == "table" then for ka, va in pairs( v ) do sa = mw.ustring.lower( ka ) if type( va ) == "table" then va.standard = k else va = { standard=k } end down[ sa ] = va end end end -- for k, v for k, v in pairs( un ) do if type( k ) == "string" then s = mw.ustring.lower( k ) d = down[ s ] else d = false end if d then if type( d ) == "table" then light = d.low s = d.standard else light = false end if r[ s ] then if not doubled then doubled = { } end if not doubled[ s ] then doubled[ k ] = s end else r[ s ] = r{ k } r[ k ] = nil if not light then if not undesired then undesired = { } end undesired[ k ] = s end end else if not unknown then unknown = { } end unknown[ k ] = true end end -- for k, v if unknown then down = { } for k, v in pairs( allowed ) do if type( v ) == "table" then sa = mw.ustring.lower( k ) for ka, va in pairs( v ) do sa = mw.ustring.lower( ka ) if type( va ) == "table" then va.standard = k else va = { standard=k } end down[ sa ] = va end end end -- for k, v for k, v in pairs( unknown ) do if type( k ) == "string" then s = mw.ustring.lower( k ) d = down[ s ] if d then if type( d ) == "table" then light = d.low else light = false end s = d.standard if r[ s ] then if not doubled then doubled = { } end doubled[ k ] = s else r[ s ] = r{ k } r[ k ] = nil if not light then if not undesired then undesired = { } end undesired[ k ] = d.standard end end else if scream then scream = scream .. ", " else scream = "Unbekannte Parameter: " end scream = scream .. k end end end -- for k, v fehler( "Konflikt", scream ) scream = false end if undesired then for k, v in pairs( undesired ) do if scream then scream = scream .. ", " else scream = "" end scream = string.format( "%s '%s' ist '%s'", scream, k, v ) end -- for k, v fehler( "Name", scream ) scream = false end end if doubled then for k, v in pairs( doubled ) do if scream then scream = scream .. "," else scream = "Parameterwerte gedoppelt: " end scream = string.format( "%s '%s' ./. '%s'", scream, k, v ) end -- for k, v fehler( "Konflikt", scream ) scream = false end if discard then for k, v in pairs( discard ) do fehler( "Entfernen", v .. "=" ) end -- for k, v end return r
end -- Zitation.filter()
Zitation.format = function ()
-- Generiere Zitation -- Rückgabewert: -- 1 -- string mit Vorlagenresultat -- 2 -- string mit Fehlermeldung(en) und -kategorien, oder false local s Resultat = "" foreign( "bas", "Sprache" ) autorHrsg() titel() -- Schließt mit Punkt etc. werk() -- Schließt mit Punkt etc. reihe() auflage() -- Schließt mit Punkt endBlock() -- Schließt mit Punkt coins() s = fehlerliste() if s == "" then s = false end return Resultat, s
end -- Zitation.format()
Zitation.COinS = function ( args, assign, already )
-- Create string with COinS
-- Parameter:
-- args -- table, with COinS components
-- assign -- optional string, with ID
-- already -- optional string, with preformatted &sequence
-- Returns HTML element string
local Text = Zitation.fetch( "Text" )
local WLink = Zitation.fetch( "WLink" )
local rft = { }
local site = mw.site.server:gsub( "^%l*:?//", "" )
local s, sub, v
if assign then
sub = assign
else
if args.genre then
sub = args.genre
else
sub = "book"
end
end
if args.isbn then
args.isbn = args.isbn:gsub( "-", "" ):upper()
end
s = string.format( "%s%s%s",
"ctx_ver=Z39.88-2004",
"&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A",
sub )
if not args.genre then
s = s .. "&rft.genre=book"
end
if type( assign ) == "string" then
sub = assign
else
sub = mw.title.getCurrentTitle().fullText
end
s = string.format( "%s&rfr_id=info:sid/%s:%s",
s,
site,
mw.uri.encode( sub ) )
if already then
s = s .. already
end
for k, v in pairs( args ) do
table.insert( rft, k )
end -- for k, v
table.sort( rft )
for i = 1, #rft do
sub = rft[ i ]
v = args[ sub ]
if type( v ) == "table" then
if type( v.tostring ) == "function" then
v = v.tostring()
end
end
if type( v ) == "string" then
v = mw.text.killMarkers( v ) -- <math>
v = mw.uri.encode( WLink.getPlain( Text.getPlain( v ) ) )
:gsub( "%%E2%%80%%93", "-" )
s = string.format( "%s&rft.%s=%s", s, sub, v )
end
end -- for i
s = string.format( "%s",
s,
"style='display:none'",
" " )
return s
end -- Zitation.COinS()
Zitation.ISBN = function ( access, accept, alert )
-- Create string with formatted ISBN -- Parameter: -- access -- string, with presumable ISBN -- accept -- optional number, whether invalid data is permitted -- 0, nil -- require valid ISBN -- -1 -- ignore invalid check digit -- other -- other, e.g. number of digits -- alert -- optional string, with maintenance category title -- Returns: -- 1 -- string, for display -- 2 -- true, if conditions not matched local URIutil = Zitation.fetch( "URIutil" ) local mode = accept or 0 local isbn, lapsus, legal, lethal, r if mode == -1 then legal, isbn = URIutil.isISBN( access ) if legal then if URIutil.isISBNvalid( access ) then fehler( "Wert", "'ISBN' ist nicht formal falsch" ) else lapsus = true end end elseif mode == 0 then legal, isbn = URIutil.isISBNvalid( access ) else legal, isbn = URIutil.isISBN( access ) if isbn == -1 then lapsus = true legal = true lethal = true end end if legal then if lethal then r = URIutil.linkISBN( access, true, true, true, alert ) else r = "ISBN " .. URIutil.formatISBN( access, isbn ) end if lapsus then local plus = mw.html.create( "small" ) local show, story if lethal then show = "defekt" story = "WP:ISBNdefekt" else show = "formal falsch" story = "WP:ISBNformalFalsch" end if story then show = string.format( "%s", story, show ) end show = string.format( "(%s)", show ) plus:addClass( "ISBN-bad-code" ) :css( "white-space", "nowrap" ) :wikitext( show ) r = string.format( "%s %s", r, tostring( plus ) ) end else r = string.format( "ISBN %s%s", access, Zitation.fault( "(?!)", true ) ) fehler( "Wert", "'ISBN'" ) fire( "ISBN" ) end return r, legal
end -- Zitation.ISBN()
-- Export ===============================================================
local p = { }
p.Endpunkt = function ( frame )
-- LEGACY für Vorlage:Internetquelle local r = "" local s = frame.args.titel if s then local Text = Zitation.fetch( "Text" ) if Text.sentenceTerminated( s ) then r = "" else r = "." end end return r
end -- p.Endpunkt
p.TitelFormat = function ( frame )
-- LEGACY für Vorlage:Internetquelle local r = "" local s = frame.args.titel if s then local Text = Zitation.fetch( "Text" ) if Text.sentenceTerminated( s ) then r = s else r = s .. "." end r = string.format( "%s", r ) end return r
end -- p.TitelFormat
p.COinS_Template = function ( frame )
local l, r = pcall( Zitation.COinS, frame:getParent().args ) return r
end -- p.COinS_Template
p.ISBN = function ( frame )
local mode = frame.args[ 2 ] if mode then mode = tonumber( mode ) end if frame.args.template then Selbst = frame.args.template end local l, r = pcall( Zitation.ISBN, frame.args[ 1 ], mode, frame.args.link ) return r
end -- p.ISBN
function p.failsafe()
return Zitation.serial
end
p.Zitation = function ()
return Zitation
end -- p.Zitation
return p