Die Dokumentation für dieses Modul kann unter Modul:Vorlage:Cite journal/Doku erstellt werden

--[=[ 2016-05-31
Unterstützung für {{Cite journal}}
]=]


-- Global
local Selbst = "Vorlage:Cite journal"
local Fehler = false
local KategorieBeginn  =  "Kategorie:Wikipedia:Vorlagenfehler/" .. Selbst
local Kategorien       =
     { Intern       =  { s = "/Interner Fehler" },
       Parameter    =  { s = "/Parameterfehler" }
     }
local Zitation

local ParValid = {
    last                = true,
    first               = true,
    authorlink          = true,
    last1               = true,
    first1              = true,
    authorlink1         = true,
    author              = true,
    authors             = true,
    last2               = true,
    first2              = true,
    authorlink2         = true,
    last3               = true,
    first3              = true,
    authorlink3         = true,
    last4               = true,
    first4              = true,
    authorlink4         = true,
    last5               = true,
    first5              = true,
    authorlink5         = true,
    last6               = true,
    first6              = true,
    authorlink6         = true,
    last7               = true,
    first7              = true,
    authorlink7         = true,
    last8               = true,
    first8              = true,
    authorlink8         = true,
    last9               = true,
    first9              = true,
    authorlink9         = true,
    ["display-authors"] = true,
    date                = true,
    year                = true,
    title               = true,
    chapter             = true,
    chapterurl          = true,
    url                 = true,
    format              = true,
    journal             = true,
    series              = true,
    language            = true,
    location            = true,
    publisher           = true,
    volume              = true,
    issue               = true,
    page                = true,
    pages               = true,
    arxiv               = true,
    bibcode             = true,
    doi                 = true,
    isbn                = true,
    issn                = true,
    jstor               = true,
    lccn                = true,
    oclc                = true,
    pmc                 = true,
    pmid                = true,
    id                  = true,
    accessdate          = true,
    quote               = true }

--Derzeit nicht unterstützt
--|archiveurl
--|archivedate
--|deadurl
--|trans_title
--|doi_brokendate
--|at
--|nopp
--|publication-date
--|type
--|department
--|origyear
--|others

-- Nicht unterstützt da durch Wikipedia:Zitierregeln festgelegt
--|author-name-separator
--|author-separator
--|separator
--|postscript
--|lastauthoramp


-- Nicht unterstützt da unzulässige Angabe für einen Artikel in einem Fachjournal
--|editor1-last
--|editor1-first
--|editor1-link
--|editor2-last
--|editor2-first
--|editor2-link
--|editor3-last
--|editor3-first
--|editor3-link
--|editor4-last
--|editor4-first
--|editor4-link
--|editor5-last
--|editor5-first
--|editor5-link
--|displayeditors
--|edition

-- Nicht unterstützt, da sie bei Artikeln keine Verwendung finden

-- Derzeit allgemein nicht unterstützt
--|laysummary
--|laysource
--|laydate
--|ref
--|via
--|registration
--|subscription
--|author-mask
--|ref

--|asin
--|jfm
--|mr
--|ol
--|osti
--|rfc
--|ssrn
--|zbl

-- Nutzung in en-Wiki nicht mehr erwünscht
--| coauthors --> Include coauthors in authors or use separate authorn or lastn/firstn to list coauthors
--| month --> Use date instead.
--| day --> Use date instead.

-- Nicht unterstützte Alias der englischen Vorlage
-- author1, author2 .. --> bitte last1, last2 .. nutzen (Parameter ist nur für den Nachnamen gedacht, wird aber ab und an mit dem vollen Namen verwechselt)
-- journal --> work, newspaper, magazine, periodical

local function fault( a )
    -- Formatiere Fehler mit class=error
    -- Parameter:
    --     a  -- string mit Text
    return string.format( "<span class=\"error\">%s</span>", a )
end -- fault()



local function fehler( art, anzeige )
    -- Ein Fehler ist aufgetreten
    -- Parameter:
    --     art      -- string mit Schlüsselwort zum Typ
    --     anzeige  -- string mit Einzelheiten
    local t
    if not Fehler then
    	Fehler = { Intern    = { s = "Interner Fehler",
                                 k = "Intern" },
                   Modul     = { s = "Modul-Seite fehlt",
                                 k = "Intern" },
                   Vorlage   = { s = "Vorlagen-Seite fehlt",
                                 k = "Intern" },
                   Konflikt  = { s = "Parameterkonflikt",
                                 k = "Parameter" },
                   Parameter = { s = "Parameterfehler",
                                 k = "Parameter" },
                   Pflicht   = { s = "Pflichtparameter fehlt",
                                 k = "Parameter" },
                   Wert      = { s = "Ungültig",
                                 k = "Parameter" },
                   Doppelt   = { s = "Mehrfache Angabe von Parametern",
                                 k = "Parameter" },
                   TitelP    = { k = "TitelP" }
                 }
    end
    t = Fehler[ art ]
    if t then
        if t.e then
            t.e  =  string.format( "%s; %s", t.e, anzeige )
        elseif anzeige then
            t.e  =  anzeige
        else
            t.e  =  ""
        end
        if t.k then
            local wk  =  Kategorien[ t.k ]
            if wk then
                wk.e  =  true
            else
                Fehler.Intern.e      =  string.format( "Wartungskat %s", 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
    -- Rückgabewert: string mit formatiertem Ergebnis
    local r = ""
    local sep = ""
    if Fehler then
        for k, v in pairs( Fehler ) do
             if v.e then
                r = string.format( "%s%s*** %s: %s", r, sep, v.s or "", v.e)
                sep = " "
            end
        end -- for k, v
        r = "<br />" .. fault( r )
    end
    return r
end -- fehlerliste()



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 firelist()
    -- Auflistung aller gemeldeten Kategorien
    -- Returns: string mit allen Kategorien
    local r  =  ""
    local s
    for k, v in pairs( Kategorien ) do
        if v.e then
            if v.x then
                s  =  "Kategorie:Wikipedia:"
            else
                s  =  KategorieBeginn
            end
            r = string.format( "%s[[%s%s]]", r, s, v.s )
        end
    end -- for k, v
    return r
end -- firelist()

--------------------------------------------------------------------------------

function autorenListe(args, max)
    local names = {}
    local r = ""
    local first = ""
    local sep = ""
    local AddEtAl = false

    -- Prüfung ob mehr als die maximal erwünschte Anzahl von Autoren vorhanden sind
 	for i = max+1, 99, 1 do
 		if args["last" .. i] then
 			max = tonumber(args["display-authors"]) or 1
 			AddEtAl = true
 		end
 	end

    for i = 1, max, 1 do
        if (i == 1) then
        	if args["last"] or args["last" .. i] then
        		if args["last"] and  args["last" .. i] then
        			fehler( "Doppelt", "'last' und 'last1'" )
    			end
        		if args["first"] and args["first" .. i] then
        			fehler( "Doppelt", "'first' und 'first1'" )
        		end

				local linkcount = 0
				local linkparams =  ""
				if args["author-link"] then
					linkcount = linkcount +1
					linkparams = linkparams .. ", 'author-link'"
				end
				if args["author-link1"] then
					linkcount = linkcount +1
					linkparams = linkparams .. ", 'author-link1'"
				end
				if args["authorlink"] then
					linkcount = linkcount +1
					linkparams = linkparams .. ", 'authorlink'"
				end
				if args["authorlink1"] then
					linkcount = linkcount +1
					linkparams = linkparams .. ", 'authorlink1'"
				end

				if linkcount > 1 then
					linkparams = string.gsub(linkparams, ", (['%w%d%-]+)", "%1",1)
					linkparams = string.gsub(linkparams, ", (['%w%d%-]+)$", " und %1")
					fehler( "Doppelt", linkparams )
				end

        		if args["last"] or args["last1"] then
            		first = ""
            		if args["first"] or args["first" .. i] then
            			first = (args["first"] or args["first" .. i]) .. " "
            		end
            		if args["authorlink"] or args["author-link"] or args["authorlink1"] or args["author-link1"] then
            			r = string.format("%s%s[[%s|%s%s]]", r, sep, args["authorlink"] or args["author-link"] or args["authorlink1"] or args["author-link1"], first, args["last"] or args["last1"])
        			else
            			r = string.format("%s%s%s%s", r, sep, first, args["last"] or args["last1"])
    				end
        			sep = ", "
        		end
			elseif args["first" .. i] then
    			fehler( "Parameter", "'first" .. i.."' ohne 'last" .. i.."'" )
			elseif args["first"] then
    			fehler( "Parameter", "'first' ohne 'last'" )
    		end
    	else
            if args["last" .. i] then
            	first = ""
            	if args["first" .. i] then
            		first = args["first" .. i] .. " "
            	end
            	if args["authorlink"..i] then
            		r = string.format("%s%s[[%s|%s%s]]", r, sep, args["authorlink"..i], first, args["last"..i])
        		else
            		r = string.format("%s%s%s%s", r, sep, first, args["last"..i])
    			end
        		sep = ", "
        	elseif args["first" .. i] then
        		fehler( "Parameter", "'first" .. i.."' ohne 'last"..i"'" )
        	end
        	-- TODO Fehlermeldung, wenn ein Autor fehlt --> z.B. last1 und last3 aber nicht last2
    	end
	end
    if args["last" .. max+1] or AddEtAl then
		r = string.format("%s %s", r, 'et al.')
	end

    if r == "" then
    	r = nil
	end
    return r, AddEtAl;
end --autoren_liste

function hrsgListe(args, max)
    local names = {}
    local r = ""
    local first = ""
    local sep = ""
    --local max = tonumber(args["display-editors"]) or 5

    for i = 1, max, 1 do
        if (i == 1) then
        	if args["editor-last"] or args["editor" .. i .. "-last"] then
	        	--Doppelte udn uneinheitlich genutzte Parameter
	    		if args["editor-last"] and  args["editor" .. i .. "-last"] then
	    			fehler( "Doppelt", "'editor-last' und 'editor" .. i .. "-last'" )
		    		if args["editor-last"] then
			    		if args["editor" .. i .. "-first"] then
			    			fehler( "Doppelt", "'editor-last' verlangt 'editor-first' nicht 'editor" .. i .. "-first'" )
			    		end
			    		if args["editor" .. i .. "-link"] then
			    			fehler( "Doppelt", "'editor-last' verlangt 'editor-link' nicht 'editor" .. i .. "-link'" )
			    		end
		    		else
			    		if args["editor-first"] then
			    			fehler( "Doppelt", "'editor" .. i .. "-last' verlangt 'editor" .. i .. "-first' nicht 'editor-first'" )
			    		end
			    		if args["editor-link"] then
			    			fehler( "Doppelt", "'editor" .. i .. "-last' verlangt 'editor" .. i .. "-link' nicht 'editor-link'" )
			    		end
	    			end
	    		end

	    		if args["editor-first"] and  args["editor" .. i .. "-first"] then
	    			fehler( "Doppelt", "'editor-first' und 'editor" .. i .. "-first'" )
	    		end
	    		if args["editor-link"] and  args["editor" .. i .. "-link"] then
	    			fehler( "Doppelt", "'editor-link' und 'editor" .. i .. "-link'" )
	    		end
				-- Formatierung
				if args["editor-first"] or args["editor" .. i .. "-first"] then
					first = (args["editor-first"] or args["editor" .. i .. "-first"]) .. " "
				else
					first = ""
				end

        		if args["editor-last"] or args["editor" .. i .. "-last"] then
        			r = string.format("%s%s[[%s|%s%s]]", r, sep, args["editor-link"] or args["editor" .. i .. "-link"], first, args["editor-last"] or args["editor" .. i .. "-last"])
    			else
        			r = string.format("%s%s%s%s", r, sep, first, args["editor-last"] or args["editor" .. i .. "-last"])
				end
    			sep = ", "
		    elseif args["editor" .. i .. "-first"] then
    			fehler( "Parameter", "'editor" .. i .. "-first' ohne 'editor" .. i .. "-last'" )
			elseif args["editor-first"] then
    			fehler( "Parameter", "'editor-first' ohne 'editor" .. i .. "-last'" )
        	end

    	else
            if args["editor" .. i .. "-last"] then
            	if args["editor" .. i .. "-first"] then
            		first = args["editor" .. i .. "-first"] .. " "
            	else
            		first = ""
            	end
        		if args["editor" .. i .. "-link"] then
        			r = string.format("%s%s[[%s|%s%s]]", r, sep, args["editor" .. i .. "-link"], first, args["editor" .. i .. "-last"])
    			else
        			r = string.format("%s%s%s%s", r, sep, first, args["editor" .. i .. "-last"])
				end
        		sep = ", "
        	elseif args["editor" .. i .. "-first"] then
        		fehler( "Parameter", "'editor" .. i .. "-first' ohne 'editor" .. i .. "-last'" )
        	end
    	end
	end

    if args["editor" .. max+1 .. "-last"] then
		r = string.format("%s %s", r, 'et al.')
	end

    if r == "" then
    	r = nil
	end
    return r;
end -- hrsgListe

local Autor = function ( args, max, keinefehler )
    -- Auflistung der Autoren
    -- Returns:
    --  r    .. string mit der Autorenliste
    --  etal .. boolean ob die Autorenliste gekürzt wurde

--|author
--|authors
--|last1 |first1 |author-link1
-- ..
--|last9 |first9 |author-link9
--|display-authors

--Nicht unterstützt
--|authorn --> nutze lastn
--|author1 --> nutze author
--|coauthors --> nutze authors

    local r = args.author or args.authors
    local a, etal = autorenListe( args, max or 9 );

    if not keinefehler then
		if r and a then
    		fehler( "Doppelt", "'author(s)' und 'last*'" )
    	end
    	if args["display-authors"] and not a then
    		fehler( "Parameter", "'display-authors' ohne 'first*' oder 'last*'" )
    	end
    	if (args.author and args.authors) then
            fehler( "Doppelt", "'author' und 'authors'" )
        end
    end

	if r then
		if (args["authorlink"] or args["author-link"] or args["authorlink1"] or args["author-link1"]) then
			if args.author then
				r = string.format("[[%s|%s]]", args["authorlink"] or args["author-link"] or args["authorlink1"] or args["author-link1"], args.author)
			elseif not keinefehler then
				fehler( "Parameter", "'author*link*' ohne 'author'" )
			end
		end
    else
    	r = a
    end
    return r, etal
end -- Autor()



local Datum = function ( args )
--|date
--|year
--|origyear
    local r = args.year or args.date
    if r then
        if args.year and args.date then
	        fehler( "Doppelt", "'year' und 'date'" )
        elseif args.year and ((tonumber( args.year ) or 0) > 0) then
        	r = args.year
        elseif args.date then
			r = args.date
			--erweiterte Datumsauswertung, z.B. ISO-Format prüfen?
        end
    end
    return r
end -- Datum()



local Herausgeber = function ( args, max )
-- |editor
-- |editors

-- Noch nicht unterstützt
-- |editor-first |editor-last |editor-link
-- |editor1-last |editor1-first |editor1-link
-- ...
-- |editor5-last |editor5-first |editor5-link
-- |display-editors

    local r = args.editor or args.editors
    local e = hrsgListe( args, max or 5 )
    if r and e then
    	fehler( "Doppelt", "'editor(s)' und 'editor*-last'" )
	elseif r then
        if args.editor and args.editors then
            fehler( "Doppelt", "'editor' und 'editors'" )
        end
    else
    	r = e
    end
    return r
end -- Herausgeber()



--local Translator = function ( args )
--  local af = args[ "Übersetzerin" ]
--  local am = args[ "Übersetzer" ]
--    local r = am or  af
--    if r then
--        if am and af then
--            fehler( "Doppelt", "'Übersetzer' und 'Übersetzerin'" )
--        end
--    end
--    return r
--end -- Translator()



local Titel = function ( args )
    local r = args.title
    if not r then
		fehler( "Pflicht" , "'title'" )
    end
    return r
end -- Titel()

local Werk = function ( args )
-- Nicht unterstützte Alias der englischen Vorlage
-- journal --> work, newspaper, magazine, periodical // series
    local r = args.journal
    if not r then
		fehler( "Pflicht" , "'journal'" )
    end
    return r
end -- Werk()

local Seiten = function ( args )
    local r = args.page or args.pages
    if r then
        if args.page and args.pages then
            fehler( "Doppelt", "'page' und 'pages'" )
        end
        -- p. bzw. pp. durch f. bzw. ff. ersetzen
        s = r:gsub( "[%s]*pp[%.]*", " ff." ):gsub( "[%s]*p[%.]*", " f." )
        if r ~= s then
        	fehler( "Wert", "'page' oder 'pages' enthält englischsprachige Abkürzungen" )
    	else
    		r = s
		end
    end
    return r
end -- Seiten()

local URL = function ( args )
    local r
    if args.chapter then
    	r = args.chapterurl
    else
		r = args.url
    end
    return r
end -- URL()



local format = function ( args )
    -- Analysiere Argumente und bilde formatierte Zitation
    -- Parameter:
    --     args    -- table mit Vorlagenparametern
    --     arrest  -- true: Reduziertes Ergebnis zur Substitution
    -- Rückgabewert: string mit formatierter Zitation
    local r
    local z = { }
    local pars, schrott = Zitation.filter( args, ParValid )
    if schrott then
        fehler( "Parameter", schrott )
    end
    -- unerwünschte Ausgabe für Artikel
    --z.Hrsg         = Herausgeber( pars )
    --z.Auflage      = pars.edition
    --z.Verlag       = pars.publisher
    --z.Ort          = pars.location
    --z.Spalten      = pars.Spalten
    --z.TitelErg     = pars.TitelErg
    --z.WerkErg      = pars.WerkErg
    --z.HrsgReihe
    --z.Reihe        = Reihe ( pars )

    -- Pflichtparameter
    z.Werk         = Werk ( pars )

    -- erwünschte Angaben
    z.Autor, etal = Autor( pars, tonumber(args["display-authors"]) or 9)
    if etal then
    	z.Coins_autoren = Autor( pars, 99, true )
    end

    z.Titel        = Titel( pars )
    z.Kapitel      = pars.chapter

    z.Band         = pars.volume
    z.Nummer       = pars.issue
    z.Seiten       = Seiten( pars )
    z.Datum        = Datum( pars )

    --z.Originalsprache = pars.Originalsprache
    --z.Originaltitel  = pars.Originaltitel
    --z.Translator   = Translator( pars )

    -- Sinnvolle Angaben
    z.ISSN         = pars.issn
    z.DOI          = pars.doi
    z.PMID         = pars.pmid
    z.PMC          = pars.pmc
    z.arXiv        = pars.arxiv
    z.JSTOR        = pars.jstor
    z.Bibcode      = pars.bibcode
    z.ID           = pars.id

    z.ISBN         = pars.isbn
    z.OCLC         = pars.oclc
    z.LCCN         = pars.lccn

    z.URL          = URL( pars )
    z.Zitat        = pars.quote
    z.Format       = pars.format
    z.Abruf        = pars.accessdate --Zugriff ( pars )
    z.Sprache      = pars.language

    --z.Kommentar    = pars.comment
    --z.Typ          = Typ( pars )

    z.COinS        = true
    z.genre        = "journal"
    z._Selbst      = "Cite journal"

    r, schrott = Zitation.format( z )
    if schrott then
        r = r .. schrott
        --fehler( "Wert", schrott )
    end
    return r
end -- format()



local function f( arglist, arrest )
    -- Hauptfunktion zur Steuerung des Gesamtablaufs
    -- Parameter:
    --     arglist  -- table mit Vorlagenparametern
    --     arrest   -- true: Reduziertes Ergebnis zur Substitution
    -- Rückgabewert: string mit formatiertem Gesamtergebnis
    --                      einschließlich Fehlerliste und Kategorien
    local lucky, r = pcall( require, "Modul:Zitation" )
    if type( r ) == "table" then
        Zitation = r.Zitation()
        r        = format( arglist, arrest )
    else
        fehler( "Modul", r )
    end
    return  string.format( "%s%s%s", r, fehlerliste(), firelist() )
end -- f()



-- Export
local p = {}

function p.test( a )
    local lucky, r = pcall( f, a )
    return r
end

function p.f( frame )
    local frameP = frame:getParent()
    local lean   = ( frameP:getTitle() ~= Selbst )
    local lucky, params, r
    if lean then    -- subst:
        params = frame.args
    else
        params = frameP.args
    end
    lucky, r = pcall( f, params, lean )
    return r
end

return p