Aller au contenu

Module:Test wikicode

Une page de Wikipédia, l'encyclopédie libre.

 Documentation[voir] [modifier] [historique] [purger]

Ce module permet d'extraire et d'analyser des parties de wikicode. Il peut faciliter la comparaison de wikicodes ayant des structures similaires plus facilement qu'en les comparant sous forme de chaînes de caractères.

Utilisation

[modifier le code]

Fonctions exportables :

  • parseLink(link) - analyse le wikicode d'un lien interne pour en retourner les composants.
  • parseImage(image) - analyse le wikicode d'une image pour en retourner les composants.
  • extract(wikicode, items) – extrait les items demandés du wikicode.

Détail par fonction

[modifier le code]

parseLink(link)

[modifier le code]

Analyse le lien interne link et retourne ses composants :

  • page : la destination du lien
  • text : le texte du lien
Appel Résultat
p.parseLink("[[Foo|Bar]]")
{
    page = "Foo",
    text = "Bar"
}
p.parseLink("[[Foo]]")
{
    page = "Foo",
    text = "Foo"
}

parseImage(image)

[modifier le code]

Analyse l'image image et retourne ses composants :

  • src : le nom de l'image, sans préfixe
  • format : une table dont les clés représentent les différents formats appliqués (border, frameless, framed et/ou thumbnail) avec en valeur true ou la valeur du paramètre thumbnail
  • halign : l'alignement horizontal de l'image (left, center ou right)
  • valign : l'alignement vertical de l'image (baseline, sub, super, top, text-top, middle, bottom ou text-bottom)
  • size : la taille de l'image ou le mot-clé upright ou une table avec la clé upright et en valeur la valeur du paramètre
  • link : la valeur du paramètre link
  • alt : la valeur du paramètre alt
  • class : la valeur du paramètre class
  • lang : la valeur du paramètre lang
  • caption : le titre de l'image
Appel Résultat
p.parseImage("[[Fichier:Test.svg]]")
{
    src = "Test.svg"
}
p.parseImage("[[Fichier:Test.svg|bordure|frameless]]")
{
    src = "Test.svg",
    format = {border = true, frameless = true}
}
p.parseImage("[[Fichier:Test.svg|gauche]]")
{
    src = "Test.svg",
    halign = "left"
}
p.parseImage("[[Fichier:Test.svg|top]]")
{
    src = "Test.svg",
    valign = "top"
}
p.parseImage("[[Fichier:Test.svg|14x14px]]")
{
    src = "Test.svg",
    size = "14x14px"
}
p.parseImage("[[Fichier:Test.svg|redresse]]")
{
    src = "Test.svg",
    size = "upright"
}
p.parseImage("[[Fichier:Test.svg|upright=1.2]]")
{
    src = "Test.svg",
    size = {upright = 1.2}
}
p.parseImage("[[Fichier:Test.svg|link=https://fr.wikipedia.org]]")
{
    src = "Test.svg",
    link = "https://fr.wikipedia.org"
}
p.parseImage("[[Fichier:Test.svg|alt=Image de test]]")
{
    src = "Test.svg",
    alt = "Image de test"
}
p.parseImage("[[Fichier:Test.svg|class = noviewer]]")
{
    src = "Test.svg",
    class = "noviewer"
}
p.parseImage("[[Fichier:Test.svg|langue=fr]]")
{
    src = "Test.svg",
    lang = "fr"
}
p.parseImage("[[Fichier:Test.svg|Image de test]]")
{
    src = "Test.svg",
    caption = "Image de test"
}

extract(wikicode, items)

[modifier le code]

Permet d'extraire du wikicode donné les composants indiqués par la table items :

  • link : extrait un lien interne et retourne ses composants tels qu'analysés par parseLink.
  • image : extrait une image et retourne ses composants tels qu'analysés par parseImage.
  • -, *, + : extraient n'importe quel texte, la quantité de texte retournée correspond au comportement des quantifieurs dans les expressions régulières Lua.
  • ^, $ : n'extraient rien, permettent d'indiquer que l'extraction doit se faire respectivement depuis le début ou jusqu'à la fin du wikicode. Le comportement est similaire aux assertions des expressions régulières Lua.

La fonction retourne une table contenant la valeur extraite pour chacun des composants ou nil si la structure du code ne correspond pas aux items demandés.

Appel Résultat
p.extract("Test [[Foo|Bar]] test", {"link"})
{
    {page = "Foo", text = "Bar"}
}
p.extract("Test [[Foo|Bar]] test", {"^", "-", "link", "+"})
{
    "Test ",
    {page = "Foo", text = "Bar"},
    " test"
}
p.extract("Test [[Image:Test.svg|40x40px]] [[Foo]]", {"image", "-", "link"})
{
    {src = "Test.svg", size="40x40px"},
    " ",
    {page = "Foo", text = "Foo"}
}
p.extract("Test [[Foo|Bar]] test", {"image"})
nil



local p = {};

local function isImage(link)
	return link:match('^%[%[[Ff]ichier:') or link:match('^%[%[[Ff]ile:') or link:match('^%[%[[Ii]mage:')
end

--[[
	Extrait la page et le texte d'un lien interne
]]--
function p.parseLink(link)
	link = link:gsub('^%[%[', '', 1)
	link = link:gsub('%]%]$', '', 1)
	local page, text
	for part in link:gmatch('([^|]+)|?') do
		if not page then
			page = part
		else
			text = text and (text .. '|' .. part) or part
		end
	end
	return {
		page = page and mw.text.trim(mw.uri.decode(page, 'WIKI')),
		text = text or page and mw.text.trim(mw.uri.decode(page)),
	}
end

--[[
	Extrait les paramètres d'une image.
]]--
function p.parseImage(image)
	image = image:gsub('^%[%[', '', 1)
	image = image:gsub('%]%]$', '', 1)
	local src, format, halign, valign, size, link, alt, class, lang, caption
	
	-- Traductions basées sur https://gerrit.wikimedia.org/g/mediawiki/core/+/7fbd64a5a994ec15a5550753ee4f7eea1bb09522/languages/messages/MessagesFr.php
	local formats = {
		border = {'bordure', 'border'},
		frameless = {'sans_cadre', 'non_encadré', 'non_encadre', 'frameless'},
		framed = {'cadre', 'encadré', 'encadre', 'frame', 'framed', 'enframed'},
		thumbnail = {'vignette', 'thumb', 'thumbnail'},
	}
	local haligns = {
		left = {'gauche', 'left'},
		right = {'droite', 'right'},
		center = {'centré', 'center', 'centre'},
		none = {'néant', 'neant', 'none'},
	}
	local valigns = {
		baseline = {'base', 'ligne-de-base', 'baseline'},
		sub = {'indice', 'ind', 'sub'},
		super = {'exposant', 'exp', 'super', 'sup'},
		top = {'haut', 'top'},
		['text-top'] = {'haut-texte', 'haut-txt', 'text-top'},
		middle = {'milieu', 'middle'},
		bottom = {'bas', 'bottom'},
		['text-bottom'] = {'bas-texte', 'bas-txt', 'text-bottom'},
	}
	local linkPrefixes = {'lien', 'link'}
	local altPrefixes = {'alt'}
	local classPrefixes = {'classe', 'class'}
	local langPrefixes = {'langue', 'lang'}
	local manualThumbPrefixes = {'vignette', 'thumbnail', 'thumb'}
	
	local function matchOption(part, options)
		for option, values in pairs(options) do
			for i, value in ipairs(values) do
				if part == value then return option end
			end
		end
	end
	local function matchPrefixOption(part, prefixes)
		for i, prefix in ipairs(prefixes) do
			local match = part:match('^' .. prefix .. '%s*=%s*(.-)%s*$')
			if match then return match end
		end
	end
	local function matchUpright(part)
		local isKeyword = part == 'redresse' or part == 'upright'
		if isKeyword then
			return true
		end
		local value = part:match('^redresse[=_](.*)') or part:match('^upright[= ](.*)')
		return value
	end
	for part in image:gmatch('([^|]+)|?') do
		part = mw.text.trim(part)
		if not src then
			src = part:gsub('^.-:', '', 1)
		else
			local formatPart = matchOption(part, formats)
			local halignPart = matchOption(part, haligns)
			local valignPart = matchOption(part, valigns)
			local linkPart = matchPrefixOption(part, linkPrefixes)
			local altPart = matchPrefixOption(part, altPrefixes)
			local classPart = matchPrefixOption(part, classPrefixes)
			local langPart = matchPrefixOption(part, langPrefixes)
			local manualThumbPart = matchPrefixOption(part, manualThumbPrefixes)
			local uprightPart = matchUpright(part)
			if formatPart then
				-- Il est possible de combiner border et frameless
				if not format then
					format = {}
				end
				format[formatPart] = true
			elseif halignPart then
				halign = halignPart
			elseif valignPart then
				valign = valignPart
			elseif uprightPart then
				size = uprightPart == true and "upright" or {upright = uprightPart}
			elseif linkPart then
				link = linkPart
			elseif altPart then
				alt = altPart
			elseif classPart then
				class = classPart
			elseif langPart then
				lang = langPart
			elseif manualThumbPart then
				if not format then
					format = {}
				end
				format.thumbnail = manualThumbPart
			elseif part:match('^%d-px$') or part:match('^%d*x%d-px$') then
				size = part
			else
				caption = part
			end
		end
	end
	return {
		src = mw.text.trim(mw.uri.decode(src, 'WIKI')),
		format = format,
		halign = halign,
		valign = valign,
		size = size,
		link = link,
		alt = alt,
		class = class,
		lang = lang,
		caption = caption,
	}
end

--[[
	A partir d'une chaîne de wikicode, extrait les éléments demandés.
	'^' et '$' n'extraient rien
	'-', '+' et '*' extraient du texte brut
	'link' extrait un lien interne
	'image' extrait une image
]]--
function p.extract(wikicode, items)
	local pattern = ''
	local resultItems = {}
	for k, item in ipairs(items) do
		if item == 'link' or item == 'image' then
			table.insert(resultItems, item)
			pattern = pattern .. '(%[%[[^%]]-%]%])'
		elseif item == '^' or item == '$' then
			pattern = pattern .. item
		elseif item == '-' or item == '+' or item == '*' then
			table.insert(resultItems, item)
			pattern = pattern .. '(.' .. item .. ')'
		else
			return error('Item ' .. item .. ' inconnu')
		end
	end
	if pattern == '' then
		return
	end
	local res = {wikicode:match(pattern)}
	if res[1] == nil then
		return
	end
	for k, item in ipairs(resultItems) do
		if item == 'image' then
			if not isImage(res[k]) then
				return
			end
			res[k] = p.parseImage(res[k])
		elseif item == 'link' then
			if isImage(res[k]) then
				return
			end
			res[k] = p.parseLink(res[k])
		end
	end
	return res
end

return p