Aller au contenu

Module:NomRefAuto

Cette page fait l’objet d’une mesure de semi-protection étendue.
Une page de Wikipédia, l'encyclopédie libre.

 Documentationcréerpurger
-- Module utilisé par la génération automatique de noms des références ajoutées depuis l'éditeur visuel
-- Voir [[mw:Help:Cite/VisualEditor reference names]]

local NomRefAuto  = {}

local Commun = require( 'Module:Biblio/Commun' )
local extractArgs = require( 'Module:Outils' ).extractArgs
local Date = require( 'Module:Date' )

-- copié de [[Module:Biblio/Commun]]
local function texteLien( str )
	if type( str ) == 'string' then
		for lien, texte in string.gmatch( str, '%[%[ *([^%[%]|]*)|? *([^%[%]]*)%]%]' ) do
			texte = ( texte ~= '' and texte ) or lien or str
			if not lien then
				return str
			end
			local testlien = string.lower( lien )
			local fichier = string.match( testlien, '^fichier:' )
				or  string.match( testlien, '^image:' )
				or  string.match( testlien, '^file:' )
			if not fichier then
				return texte, lien
			end
		end
		return str
	end
end

local secondNiveau = {
    co = true, com = true, org = true, net = true,
    gov = true, ac = true, edu = true, asso = true,
}

local function extractionDomaine( url )
    if not url then return nil end

    -- 1. Extraire l'hôte (avec ou sans protocole)
    local host = mw.ustring.match(url, "^%s*%a[%w+.-]*://([^/?#]+)")
              or mw.ustring.match(url, "^%s*//([^/?#]+)")
              or mw.ustring.match(url, "^%s*([^/?#]+)")
    if not host then return nil end

    -- 2. Retirer identifiants (user:pass@) et port (:8080), passer en minuscules
    host = host:gsub("^.*@", ""):gsub(":%d+$", ""):lower()

    -- 3. Découper en labels
    local labels = {}
    for l in host:gmatch("[^.]+") do
        labels[#labels + 1] = l
    end

    local n = #labels
    if n == 0 then return nil end
    if n == 1 then return labels[1] end

    -- 4. Cas des TLD à deux niveaux (ex. bbc.co.uk, site.com.au)
    if n >= 3 and #labels[n] == 2 and secondNiveau[labels[n - 1]] then
        return labels[n - 2]
    end

    -- 5. Cas général : avant-dernier label
    return labels[n - 1]
end

--{{Harv}} et {{Harvsp}}
function NomRefAuto.harv( frame )
	local args = extractArgs( frame )
	local validArg = function ( ... ) return Commun.validTextArg( args, ... ) end

	local id = validArg( 'id' )
	if id then
		return id
	end

	local val1, val2, val3, val4, val5 = validArg(1), validArg(2), validArg(3), validArg(4), validArg(5)
	if val1 or val2 or val3 or val4 or val5 then
		return (val1 or '') .. (val2 or '') .. (val3 or '') .. (val4 or '') .. (val5 or '')
	end
	return ''
end

-- Cas général pour les fonctions de biblio
function NomRefAuto.main( frame )
	local args = extractArgs( frame )
	local validArg = function ( ... ) return Commun.validTextArg( args, ... ) end

	local id = validArg( 'id' )
	if id then
		return id
	end

	-- On génère un nom de référence à partir des noms des auteurs et de l'année
	-- de la même manière que Commun.spanInitial génère l'id.
	local nom = validArg( 'nom1', 'nom', 'last1', 'last', 'author' )
	local auteur_i = validArg( 'auteur1', 'author1', 'auteur' )
	local i = 1
	local idTab = { }
	local presence_auteur = false

	while nom or auteur_i do
		if auteur_i and not nom then
			-- tentative de séparation de l'auteur en prénom nom.
			auteur_i = texteLien( auteur_i )
			if auteur_i == '' then
				break
			end
			local a1, a2, a3 = string.match( auteur_i, '^([^ ]+) *([^ ]*) *(.*)$' )
			if a3 ~= '' then
				local a2len = mw.ustring.len( a2 )
				if a2len == 1 or ( a2len == 2 and mw.ustring.sub( a2, -1 ) == "." ) then
					-- a1 est le prénom, a2 une initiale et a3 le nom
					nom = a3
				else
					-- a2 peut être le deuxième prénom ou le début du nom
					nom = a2 .. ' ' .. a3
				end
			elseif a2 ~= '' then
				-- a1 prénom, a2 nom
				nom = a2
			else
				nom = a1
			end
		end
		table.insert( idTab, nom )
		presence_auteur = true

		if i == 4 then
			break
		end
		i = i + 1
		nom = validArg( 'nom' .. i, 'last' .. i )
		auteur_i = validArg( 'auteur' .. i, 'author' .. i )
	end

	if #idTab < 4 and validArg( 'auteur institutionnel' ) then
		table.insert( idTab, validArg( 'auteur institutionnel' ) )
		presence_auteur = true
	end

	local annee = validArg( 'année', 'year', 'date' )
	if annee then
		local t, d = Date.separationJourMoisAnnee( annee )
		if t and d.annee and annee ~= d.annee then
			annee = tostring( d.annee )
			args['année'] = annee
			if d.mois then
				args.mois = validArg( 'mois' ) or tostring( d.mois )
			end
			if d.jour then
				args.jour = validArg( 'jour' ) or tostring( d.jour )
			end
		elseif mw.ustring.find( annee, "%a" ) and annee:find( "%f[%d]%d%d%d%d%f[%D][a-h]?" ) then
			annee = annee:match( "%f[%d]%d%d%d%d%f[%D][a-h]?" )
		end
		annee = tostring( annee )
		table.insert( idTab, annee )
	end

	if presence_auteur == true then
		return table.concat( idTab ) .. '-'
	end

	-- En l'absence de noms d'auteurs, on retourne le nom de domaine extrait de l'url
	local url = validArg( 'url', 'lire en ligne', 'url texte', 'lien' )
	local domaine = extractionDomaine( url )
	if domaine and domaine ~= '' then
		if annee then
			return domaine .. annee .. '-'
		else
			return domaine .. '-'
		end
	end

	-- Par défaut, on renvoie une chaîne vide pour que les noms des modèles de
	-- références tels que définis dans [[MediaWiki:Cite-tool-definition.json]]
	-- soient utilisés
	return ''
end

return NomRefAuto