Module:ControlArgs/Test

La bibliothèque libre.
Aller à la navigation Aller à la recherche
Documentation du module [voir] [modifier] [purger]
La documentation de ce module Scribunto écrit en Lua est incluse depuis sa sous-page de documentation.

ControlArgs/Test de mode normal[modifier]

{{#invoke:ControlArgs/Test | normal }} Erreur Lua dans package.lua à la ligne 80 : module 'Module:ControlArgs' not found.

ControlArgs/Test de mode doc by arg 1[modifier]

{{#invoke:ControlArgs/Test | normal | doc }} Erreur Lua dans package.lua à la ligne 80 : module 'Module:ControlArgs' not found.

ControlArgs/Test de mode doc by function[modifier]

{{#invoke:ControlArgs/Test | doc }} Erreur Lua dans package.lua à la ligne 80 : module 'Module:ControlArgs' not found.

ControlArgs/Test de mode langtest[modifier]

{{#invoke:ControlArgs/Test | langtest }} Erreur Lua dans package.lua à la ligne 80 : module 'Module:ControlArgs' not found.

ControlArgs/Test de mode tests[modifier]

{{#invoke:ControlArgs/Test | tests }} Erreur Lua dans package.lua à la ligne 80 : module 'Module:ControlArgs' not found.

--[[

-- relire ControlArgs/Auteur : module code in english

-- doc : need="0" not necessary argument
-- need="1" necessary from argument
-- need="2" necessary from argument or module interaction

--]]

------------------------------------------------------------
-- Interactions between modules :
-- Interactions inter modulos :
-- Interactions entre modules :
------------------------------------------------------------

--	Module dependencies. Dependencias del módulo. Dépendances du module.
local CA = require "Module:ControlArgs"
local AT = require "Module:Auteur"

-- This module require the template {{Boîte déroulante/début}} and {{Boîte déroulante/fin}}
--local CA = require "Module:ControlArgs" dans les sous modules
local I18N = require("Module:ControlArgs/I18N")
local p = {}
--p.nowyear = nowyear

------------------------------------------------------------
-- Arguments table to change in calling modules
------------------------------------------------------------

-- relire ControlArgs/Auteur : module code in english

------------------------------------------------------------
-- Main tables of arguments. Principales tablas de argumentos. Principales tables d'arguments.
------------------------------------------------------------

p.args_source_example = { "Hugo", "Victor", "1841", "1895", "arg5", "arg6", c = ' docdef docavant erron ', nom = 'Voltaire', nomm = 'Voltaire', anneenaissance = '1987', BNF = '123456789' }

------------------------------------------------------------
-- Miscelanous functions. Fonctions utilitaires.
------------------------------------------------------------

-- Some usual fonctional styles for this module and those using it.
-- Quelques styles fonctionnels banals dans ce module et ses modules appelants.

function p.dropdown_box(if_view, title, contenu, alignT)
	-- Insérer le "contenu" dans la boite déroulante "title" et l'aligner par défaut à gauche(left), sinon à droite(right) ou au centre(center).
	if (if_view == false) or (if_view == 0) or (not if_view) then return "" end
	if not contenu then contenu = " Boîte vide " end
	if not title then title = " Boîte déroulante " end
	if not alignT then alignT = "left" end
	local frame = mw.getCurrentFrame()
--	frame:preprocess( string ) -- If you are expanding any text
	local txt = "{{Boîte déroulante/début|titre=" .. title .. "|alignT=" .. alignT .. "}}" .. contenu .. "{{Boîte déroulante/fin}}"
	local res = frame:preprocess( txt )
	return res
--	frame:expandTemplate{ title = title, args = table } -- If you are expanding a single template
--	local deb = frame:expandTemplate{ title = Boîte déroulante/début, args = { titre = titre, alignT = alignT } }
--	local fin = frame:expandTemplate{ title = Boîte déroulante/fin }
--	local res = deb .. contenu .. fin
--	return res
end -- function p.dropdown_box(if_view, title, contenu, alignT)

------------------------------------------------------------
-- Document the tables and their structures. List a table content, with formating.
-- Documentar las tablas y sus estructuras. Lista de un contenido de la tabla, con el formateo.
-- Documenter les tables et leurs structures. Lister un contenu de la table, avec le formatage.
------------------------------------------------------------

-- Dump and format the content of a table and its sub-tables ; with limits in length, deep and exceptions.
-- Listar y formatar le contento de una tabla y su sub-tablas.
-- Lister et formater le contenu d'une table et ses sous-tables ; avec des limites en longueur, profondeur et exceptions.
-- For each (sub)table, list : in first vars, then functions, then sub-tables list, then sub-tables contents

function p.testable_recursive(tbl, uppername, name, level_i, levelmaxi, max_n, exclude1, exclude2, exclude3)
	if type(name) ~= "string" then name = "table" end
	local res, newname, part, shift = "", "", "", ""
	local sep, N = ", ", 0
	local isempty = true
	local levelname = uppername .. "." .. name
	local tot_vars, tot_func, tot_tabs = 0, 0, 0
	local nbr_vars, lst_vars = 0, ""
	local nbr_func, lst_func = 0, ""
	local nbr_tabs, lst_tabs = 0, ""
	local max, lst_subtabs = 0, ""
	local st, vr, fn, tb = "", 0, 0, 0
	local tobreak = nil
	-- limit the number of the level of sub-tables
	level_i = tonumber(level_i)
	if type(level_i) ~= "number" then level_i = 1 end
	levelmaxi = tonumber(levelmaxi)
	if type(levelmaxi) ~= "number" then levelmaxi = 99 end
	if level_i > levelmaxi then
		return CA.message_color( " display list levelmaxi=" .. tostring(levelmaxi) ), tot_vars, tot_func, tot_tabs
	end
	max_n = tonumber(max_n) or 999
	shift = string.rep("*", level_i)
	--
	-- Do not list if exclude1, exclude2 or exclude3 are in the table name.
	if type(exclude1) == "string" and exclude1 ~= "" then
		if string.find(name, exclude1) ~= nil then
			return "", tot_vars, tot_func, tot_tabs
		end
	end
	if type(exclude2) == "string" and exclude2 ~= "" then
		if string.find(name, exclude2) ~= nil then
			return "", tot_vars, tot_func, tot_tabs
		end
	end
	if type(exclude3) == "string" and exclude3 ~= "" then
		if string.find(name, exclude3) ~= nil then
			return "", tot_vars, tot_func, tot_tabs
		end
	end
	-- display table error
	if type(tbl) ~= "table" then
		return '<br/>Table "' .. tostring(name) .. '" is invalid.<br/>', tot_vars, tot_func, tot_tabs
	end
	--
	-- List and count vars, functions and sub tables
	-- All named elements, including [1] and ["1"].
	-- Tous les élements, y compris [1] et ["1"].
	for k, v in pairs(tbl) do
		k = tostring(k)
		if type(v) == "table" then
			lst_tabs = lst_tabs .. k .. sep
			nbr_tabs = nbr_tabs + 1
			isempty = false
			newname = tostring(k)
			max = max + 1
			-- List recursively (or no) each sub-table
			if level_i < levelmaxi then
				st, vr, fn, tb = CA.testable_recursive(v, levelname, newname, level_i+1, levelmaxi, max_n, exclude1, exclude2, exclude3)
				lst_subtabs = lst_subtabs .. st
				tot_vars = tot_vars + vr
				tot_func = tot_func + fn
				tot_tabs = tot_tabs + tb + 1
			end
			if level_i >= levelmaxi then
				local table_listlimit_levelmaxi = CA.str_vars("table_listlimit_levelmaxi", levelmaxi)
				res = res .. " " .. CA.message_color( table_listlimit_levelmaxi )
				break
			end
			local sep = ""
			if max == max_n then
				local table_listlimit_max_n = CA.str_vars("table_listlimit_max_n", max_n)
				res = res .. "\n" .. shift .. " Table '''" .. levelname .. "''' " .. CA.message_color(table_listlimit_max_n)
				break
			end
--			end
		elseif type(v) == "function" then
			lst_func = lst_func .. k .. sep
			nbr_func = nbr_func + 1
			tot_func = tot_func + 1
			isempty = false
		else -- type(v) == other
			lst_vars = lst_vars .. type(v) .. " - " .. tostring(k) .. " =''' " .. tostring(v) .. "''' " .. sep
			nbr_vars = nbr_vars + 1
			tot_vars = tot_vars + 1
			isempty = false
		end
	end
	res = res .. "\n" .. shift .. " Table '''" .. levelname .. "''', " .. tostring(nbr_vars) .. " vars: " .. lst_vars
	res = res .. "\n" .. shift .. " Table '''" .. levelname .. "''', " .. tostring(nbr_func) .. " functions: " .. lst_func
	res = res .. "\n" .. shift .. " Table '''" .. levelname .. "''', " .. tostring(nbr_tabs) .. " tables: " .. lst_tabs .. lst_subtabs
	return res, tot_vars, tot_func, tot_tabs
end -- function p.testable_recursive(tbl, uppername, name, level_i, levelmaxi, max_n, exclude1, exclude2, exclude3)

-- Test de limite de liste de table et des arguments i devenus "i"
p.tablim = { "one", "two", max1 = "MAX1", max2 = "MAX2", max3 = "MAX3"}
p.tablim.life = { animal = "dog", vegetal = "carot"}
p.tablim.life.animals = { "turtle"}
p.tablim.comfort = { "tv", mobile = "car"}
p.tablim.house = { "kitcheen", "bedroom"}
p.tablim.house.garden = { flower = "rose", nature = "river"}

function p.testable_lister(table, tablename, opt)
	local res = "\n\n* Content of the '''" .. tostring(tablename) .. "''' table, begin:"
	-- test : check mw content
	if not opt then opt = { levelmaxi = 99 } end
	local levelmaxi = opt.levelmaxi or 99
	local max_n = opt.max_n or 9999
	local exclude1 = opt.exclude1 or ""
	local exclude2 = opt.exclude2 or ""
	local exclude3 = opt.exclude3 or ""
	local tot_vars, tot_func, tot_tabs = 0, 0, 0
	-- limit the number of the level of sub-tables
	level_i = tonumber(level_i)
	if type(level_i) ~= "number" then level_i = 1 end
	levelmaxi = tonumber(levelmaxi)
	if type(levelmaxi) ~= "number" then levelmaxi = 99 end
	if level_i > levelmaxi then
		return "", tot_vars, tot_func, tot_tabs
	end
	res = res .. " ( " .. CA.ta("levelmaxi", levelmaxi) .. CA.ta("max_n", max_n) .. CA.ta("exclude1", exclude1) .. CA.ta("exclude2", exclude2) .. CA.ta("exclude3", exclude3) .. " ) "
	local st, vr, fn, tb = CA.testable_recursive(table, "", tablename, 1, levelmaxi, max_n, exclude1, exclude2, exclude3)
	res = res .. st
	tot_vars = tot_vars + vr
	tot_func = tot_func + fn
	tot_tabs = tot_tabs + tb
	res = res .. "\n\n* Content of the '''" .. tostring(tablename) .. "''' table: "
	res = res .. CA.str_vars(" %1 variables, %2 functions, %3 sub-tables. End.\n", vr, fn, tb)
	return res, tot_vars, tot_func, tot_tabs
end -- function p.testable_lister(table, tablename, opt)

-- relire ControlArgs/Auteur : module code in english

-- Remplacer ou ajouter tous les champs de la table add à la table de base, sur un seul niveau.
function p.table_mixer(base, add)
	local v2, nn, ni = 0, 0, 0
	local tb = {}
	 -- cumuler les elements
	if type(base) == "table" and type(add) == "table" then
		for i, val in ipairs(base) do
			v2 = mw.clone( val )
			tb[i] = v2
		end
		for i, val in ipairs(add) do
			v2 = mw.clone( val )
			tb[i] = v2
		end
		for key, val in pairs(base) do
			v2 = mw.clone( val )
			tb[key] = v2
		end
		for key, val in pairs(add) do
			v2 = mw.clone( val )
			tb[key] = v2
		end
	else
		tb = base
	end
	-- compter les elements
	if type(tb) == "table" then
		for i, val in ipairs(tb) do
			ni = ni + 1
		end
		for key, val in pairs(tb) do
			nn = nn + 1
		end
	end
	return tb, ni, nn
end -- function p.table_mixer(base, add)

------------------------------------------------------------
-- Manage translations of arguments and messages
-- Gestione traducciones de argumentos y mensajes
-- Gérer les traductions des arguments et messages
------------------------------------------------------------

function p.trans(key) -- give the translation of indentified texts, or arguments indentifier, or errors messages
	local t = CA.wiki_args[key]
	if t == nil then t="" end
	return t
end

function p.get_IETF_fr()
	-- Chargement de la base de donnée des langues avec gestion d'erreur.
	-- voir : https://fr.wikipedia.org/wiki/Module:Langue
	local dataLangue
	local success, resultat = pcall (mw.loadData, 'Module:Langue/Data' )
	if success then
		dataLangue = resultat
	else
		-- Base de donnée à minima en cas de bug sur le Module:Langue/Data
		dataLangue = {
			en = { code = 'en', nom = 'anglais' },
			fr = { code = 'fr', nom = 'français' },
			de = { code = 'de', nom = 'allemand' },
			es = { code = 'es', nom = 'espagnol' },
			it = { code = 'it', nom = 'italien'	 },
			la = { code = 'la', nom = 'latin'	 },
--			['rtl script'] = { Arab = true }, -- debug : risque d'anomalie, anomaly risc
		}
		dataLangue.anglais = dataLangue.en
		dataLangue['français'] = dataLangue.fr
		dataLangue.francais = dataLangue.fr
		dataLangue.allemand = dataLangue.de
		dataLangue.espagnol = dataLangue.es
		dataLangue.italien = dataLangue.it
	end
	return dataLangue
end -- function p.get_IETF_fr()

function p.dummy_languages() -- Test dummy languages
	-- https://fr.wikipedia.org/wiki/%C3%89tiquette_d%27identification_de_langues_IETF
	-- https://fr.wikipedia.org/wiki/Module:Langue/Data
	--	pour convertir en code de langue IETF les noms français de langues
	-- https://www.mediawiki.org/wiki/Manual:$wgDummyLanguageCodes
	--	List of language codes that have been renamed to new (correct) codes, or don't correspond to an actual interface language.
	--	array( 'als' => 'gsw', 'bat-smg' => 'sgs', 'be-x-old' => 'be-tarask', 'bh' => 'bho'...
	local dummy_i18n = {
		en = "Module:ControlArgs/I18N", -- english
		es = "Modul:ControlArgs/I18N", -- spanish
		fr = "Module:ControlArgs/I18N", -- french
		Fr = "Module:ControlArgs/I18N", -- error test
		als = "Modulen:ControlArgs/I18N", -- alemanish
		gsw = "Mod-gsw:ControlArgs/I18N", -- unknown
		["bat-smg"] = "Mod-bat-smg:ControlArgs/I18N", -- alemanish
		sgs = "Mod-sgs:ControlArgs/I18N", -- unknown
	}
	local t = '\n* dummy_languages : ' ..  CA.ta("isTag", "isKnownLanguageTag(xx)") .. CA.ta("isLang", "isSupportedLanguage(xx)") .. CA.ta("isBuilt", "isValidBuiltInCode(xx)")
	for lang, modname in pairs(dummy_i18n) do -- Pour tous les parametres connus
		local isTag = mw.language.isKnownLanguageTag(lang)
		local isLang = mw.language.isSupportedLanguage(lang)
		local isBuilt = mw.language.isValidBuiltInCode(lang)
		local langname = mw.language.fetchLanguageName(lang, "en")
		local native = mw.language.fetchLanguageName(lang)
		local space_name = tostring(mw.site.namespaces.Module.name)
		t = t .. '\n**' .. CA.ta("lang", lang) .. CA.ta("isTag", isTag) .. CA.ta("isLang", isLang)
		t = t .. CA.ta("langname", langname) .. CA.ta("native", native)
	end
	return t
end -- function p.dummy_languages()

-- Verifier la cohérence des tables de traductions
function p.verif_i18n(i18n)
	if type(i18n) ~= "table" then i18n = CA.i18n end
	if type(i18n) ~= "table" then return " verif_i18n MISSING. " end
	local nerr, trad, t, err = 0, "", "", ""
	--
	-- Lister toutes les différences des tables de traductions.
	local prec_tab, suiv_tab, max, nk = nil, nil, 0, 0
	local lang, prec_lang, suiv_lang = "", "", ""
	local all_txts = {}
	for lang, texts in pairs(i18n) do -- Pour toutes les langues et tous les textes à traduire
		suiv_lang = lang -- table suivante de traduction d'une langue
		suiv_tab = texts -- table suivante de traduction d'une langue
		for k, v in pairs(texts) do -- Lister tous les textes traduits au moins dans une langue
			all_txts[k] = "x"
		end
		if prec_tab ~= nil and suiv_tab ~= nil then -- pour chaque couple de langues à comparer
			t = t .. "\n* Comparer les langues : '''" .. prec_lang .. "/" .. suiv_lang .. "''', "
			nk = 0
			for k, x in pairs(all_txts) do -- Pour tous les textes à traduire
				trad = suiv_tab[k]
				nk = nk + 1
				if trad == nil then -- and k ~= nil then -- args vers un argument nommé
					err = CA.erreur_add("err_module_miss_i18n_txt", k, suiv_lang)
					t = t .. "<br/>" .. err .. " "
					nerr = nerr + 1
				end
			end
			if nk > max then max = nk end
		end
		prec_lang = suiv_lang
		prec_tab = suiv_tab
	end
	if nerr > 0 then
		err = CA.erreur_add("err_module_miss_i18n_res", nerr, max)
		t = t .. "<br/>" .. err .. " "
		local err_module_miss_i18n_cat = CA.str_vars("err_module_miss_i18n_cat")
		CA.catGen(err_module_miss_i18n_cat) -- generate one category
	end
	-- tester vr le nombre total de variables de traductions
	local st, vr, fn, tb = CA.testable_lister(i18n, "i18n")
	if vr < 33 then
		err = CA.erreur_add("err_module_i18n_miss_trans", vr)
		t = t .. "<br/>" .. err .. " "
		local err_module_miss_i18n_cat = CA.str_vars("err_module_miss_i18n_cat")
		CA.catGen(err_module_miss_i18n_cat) -- generate one category
	end
	return t
end -- function p.verif_i18n(i18n)

-- Modifier ou ajouter des langues et champs de traductions d'une table ou d'un module
function p.add_i18n(i18n, t)
	-- or p.i18n, txt = p.add_i18n(p.i18n_args) -- fusionner les traductions d'une table i18n
	-- or p.i18n, txt = p.add_i18n("ControlArgs/I18N") -- fusionner les traductions d'un module I18N
	local I18N, moduleI18N, localnamespace_Module
	t = t or "add_i18n : "
	if type(i18n) == "string" then -- Si les langues sont dans un module
		-- Verifier que les traductions sont disponibles.
		if type(CA.module_name) ~= "string" then CA.module_name = "ControlArgs" end
		-- "Module" namespace translated to local language :
	--	localnamespace_Module = tostring(mw.site.namespaces.Module.name)
	--	moduleI18N = localnamespace_Module .. ":" .. i18n -- Module:ControlArgs/I18N
		moduleI18N = i18n -- Module:ControlArgs/I18N
		t = t .. CA.ta("localnamespace_Module", localnamespace_Module) .. CA.ta("CA.module_name", CA.module_name)
		t = t .. CA.ta("i18n", i18n) .. CA.ta("moduleI18N", moduleI18N)
		I18N = require(moduleI18N) -- integrer le module I18N
		if type(I18N) == "table" then
			i18n, txt = CA.add_i18n(I18N.i18n)
			t = t .. CA.ta("require(moduleI18N)", I18N) .. CA.ta("require(moduleI18N).i18n", i18n)
			if type(i18n) == "table" then
				CA.i18n = i18n
			end
		end
	end
	if type(i18n) ~= "table" then return CA.i18n, "rien a importer." end
	local an, ln = 0, 0
	for lng, argmts in pairs(i18n) do -- Pour toutes les langues à importer
		if CA.i18n[lng] then -- la langue existe déja, y ajouter ou y remplacer les champs importés
			t = t .. CA.str_vars(", '''Langue : %1''' ", lng)
			ln = ln + 1
			for argn, val in pairs(argmts) do -- Pour tous les champs importés
				CA.i18n[lng][argn] = val -- ajouter ou remplacer un champs et sa traduction
				t = t .. CA.str_vars(", %1 ", argn)
				an = an + 1
			end
		else -- ajouter la table et tous ses champs si elle n'est pas encore dans CA.i18n
			if mw.language.isKnownLanguageTag(lng) then
				CA.i18n[lng] = i18n[lng]
			end
		end
	end
	t = t .. CA.str_vars(", Comptes des ajouts : '''langues=%1 champs=%2''' ", ln, an)
	return CA.i18n, t, ln, an
end -- function p.add_i18n(i18n, t)

function p.init_lang(lang)
	-- en : init or change the language and its table
	-- es : inicializar o cambiar el idioma y su mesa
	-- fr : initialiser ou modifier la langue et sa table
	t = '\n* init_lang : '
	if type(lang) ~= "string" then
		lang = mw.language.getContentLanguage().code -- {{CONTENTLANG}} Langue du wikipedia courant
	end
	if not mw.language.isSupportedLanguage(lang) then
		-- Error if the language is not a wikipedia language
		-- Erreur si la langue n'est pas une des langues wikipedia
		t = t .. CA.erreur_add("err_lang_not_exist", " ", lang)
		local err_module_with_error = CA.str_vars("err_module_with_error")
		CA.catGen(err_module_with_error) -- generate one category
		return t
	end
	if not CA.i18n[lang] then
		-- Error if the language is not tanslated
		-- Erreur si la langue n'est pas traduite
		t = t .. CA.erreur_add("err_lang_not_translated", " ", lang)
		local err_module_with_error = CA.str_vars("err_module_with_error")
		CA.catGen(err_module_with_error) -- generate one category
		return t
	end
	--
	-- Active une langue et sa table déjà enregistrées
	CA.user_lang = lang -- langue pour les erreurs et messages
	CA.wiki_args = CA.i18n[lang]
	t = t .. CA.str_vars('lang = %1, CA.user_lang = %2, CA.wiki_args = %3 ', lang, CA.user_lang, CA.wiki_args)
	t = t .. CA.wiki_args["err_module_with_error"] .. " "
	--[[
	-- Initialiser aussi le mode venant de " | mode=doc | "
	-- Initialize also the mode from " | mode=doc | "
	local argval = nil
	local arglingual = CA.wiki_args["mode"]
	if arglingual and CA.args_source then
		argval = CA.args_source[arglingual]
		if argval then
--			CA.mode_name = argval
		end
	end]]
	return t
end -- function p.init_lang(lang)

------------------------------------------------------------
-- Manage categories. Administrar categorías. Gérer les catégories.
------------------------------------------------------------

function p.catGen_test(tst) -- tester les categories
	local cat, t, c = "", "", ":"
	tst = tst or "\n\n* Test catégories par '''catGen''' :"
	--
	cat, t = CA.catGen("fausse catégorie", c)
	tst = tst .. (t or "")
	--
	local catName = ""
	cat, t = CA.catGen(catName, catName, c)
	tst = tst .. (t or "")
	--
	catName = CA.str_vars("L'année %1 renommée", 2013)
	cat, t = CA.catGen("cat_name_number", catName, c)
	tst = tst .. (t or "")
	--
	catName = CA.str_vars("cat_name_number", 2013)
	cat, t = CA.catGen(catName, catName, c)
	tst = tst .. (t or "")
	--
	catName = CA.str_vars("cat_name_number", 2013)
	cat, t = CA.catGen(catName, c)
	tst = tst .. (t or "")
	--
	tst = tst .. "\n\n* Test catégories '''categ_lister''' :" .. CA.categ_lister(":") -- generate the categories wikitext
	return tst
end -- function p.catGen_test(tst)

------------------------------------------------------------
-- Argts : Manage arguments. Gestione argumentos. Gérer les arguments.
------------------------------------------------------------

function p.arg_memorize(argname, argval, tr) -- memorize the value in local table
	-- arg_memorize("firstname", "Victor")
	local args_known = CA.args_known
	if type(argname) ~= "string" then return nil end
	if argval == nil then return nil end
	if type(args_known) ~= "table" then return nil end
	local arg_to_mem = args_known[argname]
	if arg_to_mem == nil then return nil end
	arg_to_mem["val"] = argval
	local keyword = arg_to_mem["keyword"]
	return argname, argval
end -- p.arg_memorize(argname, argval, tr)

function p.argv(argname, args_src) -- read arg value from local data
--	arg = CA.argv("name") -- read the argument from local memory, no matter the language of the wiki
	local args_source = CA.args_source
	local err = nil
	if type(args_src) == "table" then args_source = args_src end
--	if type(args_src) ~= "table" then return "err:argv-args_src" end
--	if type(argname) ~= "string" then return "err:argv-argname" end
--	if args_source[argname] == nil then return "err:argv-args" end
--	return args_source[argname] or "err:argv-ret"
	if type(args_src) ~= "table" then err = "err_argv_args_src" end
	if type(argname) ~= "string" then err = "err_argv_args_name" end
	if args_source[argname] == nil then err = "err_argv_args_miss" end
	if err then err = CA.erreur_add(err, argname) end
	return args_source[argname] or err
end -- p.argv(argname, args_src)

-- Repérer les mots semblables
-- calcule la distance de Levenshtein entre deux mots (ASCII),
-- voir fr:Module:Classification ReptileDB Hexasoft
function p.levenshtein(mot1, mot2)
	-- eviter les exceptions
	local cout = 0
	mot1 = tostring(mot1)
	mot2 = tostring(mot2)
	local len1 = string.len(mot1)
	local len2 = string.len(mot2)
	local lev = 0
	local t = "<br/>lev: " .. CA.ta("mot1", mot1) .. CA.ta("mot2", mot2)
	if (type(mot1) ~= "string") or (type(mot2) ~= "string") or (mot1 == "") or (mot2 == "") then
		lev = len1 + len2
		return lev, t .. CA.ta("lev", lev)
	end
	-- cas simple
	if (mot1 == mot2) then
		lev = 0
		return lev, t .. CA.ta("lev", lev)
	end
	local d = {}
	for i = 1, len1+2 do -- for i = 1, len1-1+1 do
		d[i] = {}
		--	d[i][1] = 0 -- d[i][1] = i
		for j = 1, len2+2 do
			--	d[i][j] = {}
			d[i][j] = 0 -- d[1][j] = j
		end
	end
	-- on simule un tableau à deux dimensions
	for i = 2, len1+1 do -- for i = 1, len1-1+1 do
		--	d[i] = {}
		d[i][1] = i-1 -- d[i][1] = i
	end
	for j = 2, len2+1 do
		d[1][j] = j-1 -- d[1][j] = j
	end
	for i = 2, len1+1 do -- for i = 2, len1+1 do
		for j = 2, len2+1 do -- for j = 2, len2+1 do
			-- on récupère les deux caractères
			local c1 = string.byte(mot1, i-1)
			local c2 = string.byte(mot2, j-1)
			if (c1 == c2) then
				cout = 0
				d[i][j] = d[i-1][j-1]
			else
				cout = 1
				d[i][j] = math.min(d[i-1][j], d[i][j-1], d[i-1][j-1]) + 1
			end
			--	d[i][j] = math.min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+cout)
		end
	end
	local lev = d[len1+1][len2+1] -- return d[len1-1][len2] - 1
	return lev, t .. CA.ta("lev", lev)
end -- function p.levenshtein(mot1, mot2)

function p.wordiff(search, word, max)
	-- search = mot cherché dans la liste
	-- word = un des mot de la liste
	-- CA.max_nearest_argument = 3 -- Limite de differences des arguments proposables à l'utilisateur
	if not max then max = CA.max_nearest_argument end
	if not max then max = 3 end
	local len1, len2, lev, tlev, t, diff
--	t = t .. "<br/>- diff: " .. CA.ta("mot1", mot1) .. CA.ta("mot2", mot2) .. CA.ta("diff", diff)
	t = "<br/>wordiff : "
	if (not search ) or (not word) then
		diff = 9
		t = t .. CA.ta("diff", diff) .. " no word. "
	elseif search == word then
		diff = 0
		t = t .. CA.ta("diff", diff) .. " , " .. search .. " = " .. word .. " "
	else
		len1 = string.len(search)
		len2 = string.len(word)
		lev, tlev = CA.levenshtein(tostring(search), tostring(word))
		-- diff = ( levenstein + écart de longueur ) * ( longueur du mot cherché / longueur d'un mot moyen )
		diff = lev + math.abs( string.len( search ) - string.len( word ) )
	--	diff = diff * 7 / len1
	--	diff = math.floor( diff * 10 ) / 10
		if (diff <= max) then
			t = t .. CA.ta("lev", lev) .. CA.ta("diff", diff) .. " '''" .. search .. " ==> " .. word .. "''' "
		else
			t = t .. CA.ta("lev", lev) .. CA.ta("diff", diff) .. " " .. search .. " / " .. word .. " "
		end
	end
	return diff, t, search, word
end -- function p.wordiff(search, word, max)

function p.levenshtein_test( res, c)
	res = res .. "\n* " .. CA.str_vars("max_nearest_argument_msg", CA.max_nearest_argument or 3)
	local errors = ""
	local n, t = CA.wordiff( "nom", "nom")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "nom", "Nom")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "top", "pot")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "ami", "amis")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "nom", "name")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "m", "mu")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "m", "mur")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "mur", "m")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "c", "long")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "xxx", "")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "", "xyz")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "xxx", "xyz")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "prénom", "Prenom")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "catégorie", "Category")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "description", "Description")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "anneeDeces", "anneeNaissance")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "anoNacimiento", "anneeNaissance")
	res = res .. tostring(t)
	local n, t = CA.wordiff( "avant-après", "après-avant")
	res = res .. tostring(t)
	if errors ~= "" then res = res .. "\n* '''levenshtein_test''' errors = " .. CA.error_color(errors) end
	return res
end -- function p.levenshtein_test( res, c)

-- Cherche le mot le plus proche dans une table { key = mot, ... }
function p.mot_proche(cherche, liste)
	local dist, lengths = 9, 0
	local trouve1, trouve2, trouve3 = nil, nil, nil
	local min1, min2, min3 = 9, 9, 9
	local max = CA.max_nearest_argument - 1 + string.len(cherche)/3
	for key, mot in pairs(liste) do
		if tostring(cherche) == tostring(mot) then
			trouve1 = tostring(mot) -- A word is the word searched
			min1 = 0
			dist = 0
		end
	end
	if min1 ~= 0 then
		for key, mot in pairs(liste) do
			-- Search the most similar and same length. Buscar las más similares y la misma longitud. Chercher le plus ressemblant et la même longueur.
			dist = CA.wordiff(tostring(cherche), tostring(mot))
			if type(dist) ~= "number" then dist = 9 end
			if (dist < min1) then
				trouve3 = trouve2
				min3 = min2
				trouve2 = trouve1
				min2 = min1
				min1 = dist
				trouve1 = tostring(mot)
			end
		end
	end
	t = t .. "<br/>" .. CA.ta("cherche", cherche) .. CA.ta("trouve1", trouve1) .. CA.ta("min1", min1) .. CA.ta("trouve2", trouve2) .. CA.ta("min2", min2) .. " " .. t
	if trouve1 and min1 == 0 then t = t .. CA.wikidata_color(CA.ta("connu", trouve1)) end
	if trouve1 and min1 <= max then t = t .. CA.wikidata_color(CA.ta("min1 "..min1.."<="..max, trouve1)) end
	if trouve2 and min2 <= max then t = t .. CA.wikidata_color(CA.ta("min2 "..min2.."<="..max, trouve2)) end
	if trouve3 and min3 <= max then t = t .. CA.wikidata_color(CA.ta("min3 "..min3.."<="..max, trouve3)) end
	return trouve1, min1, trouve2, min2, t
end -- function p.mot_proche(cherche, liste)

function p.mot_proche_test(t)
	local t = t .. "\n* '''mot_proche_test''' :"
	local t1, m1, t2, m2, txt = p.mot_proche("mot", {["a"]="Mot", ["b"]="mot", ["c"]="mont"})
	t = t .. "\na :" .. txt
	local t1, m1, t2, m2, txt = p.mot_proche("mot", {["a"]="but", ["b"]="porter", ["c"]="pot"})
	t = t .. "\nb :" .. txt
	local t1, m1, t2, m2, txt = p.mot_proche("mot", {["a"]="m", ["b"]="mur", ["c"]="mu"})
	t = t .. "\nc :" .. txt
	local t1, m1, t2, m2, txt = p.mot_proche("mot", {["a"]="Mot", ["b"]="xxxxx", ["c"]="mott"})
	t = t .. "\nd :" .. txt
	local t1, m1, t2, m2, txt = p.mot_proche("longeur", {["a"]="largeur", ["b"]="longueur", ["c"]="largueur"})
	t = t .. "\ne '''mot_proche_test''' fin" .. txt
	return t
end -- function p.mot_proche_test(t)

-- Pour un argument inconnu, cherche le nom d'argument le plus proche, parmi les arguments connus traduits
function p.cherche_arg_proche(cherche, args_known)
	local trouve1, min1, trouve2, min2 = nil, 9, nil, 9
	local liste, arglingual = {}, "xxx"
--	local key_N, key_known = {}, "xxx"
	if type(cherche) ~= "string" then return nil end
	if type(args_known) ~= "table" then return nil end
	-- faire la liste des arguments possibles
	for key, argm in pairs(args_known) do
		if not tonumber(key) then -- Pour les arguments nommés seulement
			key = tostring(key)
			arglingual = tostring(CA.wiki_args[key])
			liste[key] = arglingual
		end
	end
	-- Cherche l'argument le plus proche dans la liste
	trouve1, min1, trouve2, min2 = CA.mot_proche(cherche, liste)
	return trouve1, min1, trouve2, min2
end -- function p.cherche_arg_proche(cherche, args_known)

------------------------------------------------------------
-- Données de wikidata par mw.wikibase
------------------------------------------------------------
-- Le 30/09/2013, wikidata n'est pas encore disponoble pour wikisource.
-- https://fr.wikisource.org/wiki/Wikisource:Questions_techniques#Installation_de_l.27Extension:Wikibase_.3F
-- Le truc c'est que Wikidata (le "repo") ne supporte pas encore Wikisource. Mais ce support est prévu, il y a des discussions avec l'équipe de développement à ce propos et je viens de lancer une page décrivant les liens possibles entre les pages de Wikisource et les entrés de Wikidata dans un premier temps. Cela devrait être fait dans le courant de l'année. Tpt (d) 24 juin 2013 à 18:58 (UTC)
-- https://www.wikidata.org/wiki/Wikidata:Wikisource

-- http://test2.wikipedia.org/w/index.php?title=Bertha_von_Suttner&action=edit
-- {{authority control|TYP=p|GND=118620126|LCCN=n/50/66831|NDL=01229737|VIAF=95160848}}
-- http://test2.wikipedia.org/wiki/Module:Wikibase

--[[
== Lua Test ==
* ID: {{#invoke:Wikibase|id}}
* Label(): {{#invoke:Wikibase|label}}
* Label(Q2099): {{#invoke:Wikibase|label|Q7259}}
* Label(q555555): {{#invoke:Wikibase|label|q555555}} <!-- Unknown or missing entity. Will result in empty output. -->
* Label(xyz): {{#invoke:Wikibase|label|xyz}} <!-- Invalid entity. Will result in "Script error". -->
* Page(): {{#invoke:Wikibase|page}}
* Page(Q7259): {{#invoke:Wikibase|page|Q7259}}
* Page(q555555): {{#invoke:Wikibase|page|q555555}} <!-- Unknown or missing entity. Will result in empty output. -->
* Page(xyz): {{#invoke:Wikibase|page|xyz}} <!-- Invalid entity. Will result in "Script error". -->
--]]

--	t = t .. CA.import_wikidata("899264") -- Q899264#sitelinks = Martin Fleischmann
--	t = t .. CA.import_wikidata("535") -- Q535 = Victor Hugo = Victor Marie Hugo
--	t = t .. CA.import_wikidata("Q899264", "q899264", "p18") -- Q899264#sitelinks = Martin Fleischmann
--	t = t .. CA.import_wikidata("Q535", "p18", "P18") -- Q535 = Victor Hugo = Victor Marie Hugo
--	t = t .. CA.import_wikidata("Martin Fleischmann") -- Q899264#sitelinks = Martin Fleischmann
--	t = t .. CA.import_wikidata("Victor Hugo") -- Q535 = Victor Hugo = Victor Marie Hugo

-- mw.wikibase.getEntity() --	 gets entity data of the Wikidata item connected with the current page. See the section Entity table and data structure for an example of the structure returned.
-- mw.wikibase.label( id ) --	 takes an item ID and returns the label in the language of the local wiki.
-- mw.wikibase.sitelink( id ) --	takes an item ID and returns the title of the corresponding page on the local wiki.
-- http://www.mediawiki.org/wiki/Extension:WikibaseClient/Lua
-- p.entity = mw.wikibase.getEntity()
-- p.father = mw.wikibase.label( "Q" .. entity.claims.p107[0].mainsnak.datavalue.value["numeric-id"])
-- p.id = ""
-- father == "Lord Byron"
------------------------------------------------------------

function p.wikidata_test(t)
	local t = t or "\n* '''wikidata_test''' :"
	local wd, tw
	wd, tw = CA.import_wikidata( CA.args_known, "Q899264") -- Q899264#sitelinks = Martin Fleischmann
	t = t .. tw
	wd, tw = CA.import_wikidata( CA.args_known, "Q535") -- Q535 = Victor Hugo = Victor Marie Hugo
	t = t .. tw
	wd, tw = CA.import_wikidata( CA.args_known )
	t = t .. tw
	if type(wd.birthyear) == "table" then
		t = t .. CA.testable_lister(wd.birthyear, "wd.birthyear", { levelmaxi = 5, max_n = 2 , exclude1 = "name" } )
	end
	if type(wd.deathyear) == "table" then
		t = t .. CA.testable_lister(wd.deathyear, "wd.deathyear", { levelmaxi = 5, max_n = 2 , exclude1 = "name" } )
	end
	return t
end -- function p.wikidata_test(t)

-- Processus global des arguments :
-- args = frame...
-- args_known = CA.args_known
-- wiki_args = i18n.args_lang
-- wd = wikidata
-- import_args en 2 boucles : 1 Importer des args normaux
-- import_args en 2 boucles : 2 Traiter les anomalies apres wikidata et import
-- interact args
-- utilisation normale
-- tests unitaires

------------------------------------------------------------
-- Running internal tests and their documentations.
-- Ejecución de las pruebas internas y su documentación.
-- Exécution des tests internes et de leurs documentations.
------------------------------------------------------------

local args_test_errors = { "aaa", "bbb", "ccc", "ddd", ["prénom"] = "Arthur",
	options = ' docdef docavant ', lastXXname = 'Voltaire', birthyear = '1999', birthyear = '2000',
} -- Arguments pour auto-test

function p.table_compte(tab)
	if p[tab] == nil then return CA.str_vars("Table '''%1''' nulle. ", tab) end
	if p[tab] == nil then return CA.str_vars("Table '''%1''' vide. ", tab) end
	local st, vr, fn, tb = CA.testable_lister(p[tab], "CA."..tab)
	local t = CA.str_vars("Table '''%1''' : comptes vars='''%2''', funcs='''%3''', tabs='''%4''' ", tab, vr, fn, tb)
	return t
end -- function p.table_compte(tab)

function p.tables_comptes(txt)
	local t = txt or "\n* Comptes des tables : "
	t = t .. "<br/>" .. CA.table_compte("i18n")
	t = t .. "<br/>" .. CA.table_compte("wiki_args")
	t = t .. "<br/>" .. CA.table_compte("args_known")
	t = t .. "<br/>" .. CA.table_compte("args_wikidata")
	t = t .. "<br/>" .. CA.table_compte("args_source")
	t = t .. "<br/>" .. CA.table_compte("args_import")
	t = t .. "<br/>" .. CA.table_compte("args_final")
	return t
end -- function p.tables_comptes()

function p.debug_traceback(t)
	if type(t) ~= "string" then t = "\n* '''debug.traceback()''' : " end
	t = t .. debug.traceback()
	t = string.gsub(t, "Module", "\n* Module" )
	return t
end

function p.tested_options_list(t)
-- List tested options after collect them
	if type(t) ~= "string" then t = "\n* '''tested_options_list''' : " end
	for key, x in pairs(CA.tested_options) do
		t = t .. " , " .. key
	end
	return t
end

function p.ControlArgs_tests_init(res, args_source)
-- Special init for the test mode
	if type(res) ~= "string" then res = "\n* Mode test : " end
	if type(args_source) ~= "table" then args_source = {} end
	--[[
	if CA.i18n and CA.i18n.en then CA.i18n.es.error_i18n_wanted = 'EN error wanted' end
	if CA.i18n and CA.i18n.es then CA.i18n.es.error_i18n_deseada = 'ES error deseada' end
	if CA.i18n and CA.i18n.fr then CA.i18n.fr.error_i18n_voulue = 'FR erreur voulue' end]]
--[[
	if lang == "en" then args_source = p.ArgtestEN end
	if lang == "es" then args_source = p.ArgtestES end
	if lang == "fr" then args_source = p.ArgtestFR end
--]]
	if not args_source.description then args_source.description = "Victor Hugo est très connu." end
	if not args_source.genre then args_source.genre = "Romanciers/Poètes/Auteurs de théatre" end
	if not args_source.language then args_source.language = "français/japonais" end
	if not args_source.occupation then args_source.occupation = "Académiciens/Personnalités politiques" end
	if not args_source.prize then args_source.prize = "Nobel de littérature/Pulitzer" end
	if not args_source.wikipedia then args_source.wikipedia = "Alain Fournier" end
	if not args_source.wikiquote then args_source.wikiquote = "Charles Beaudelaire" end
	if not args_source.commons then args_source.commons = "Victor Hugo" end
	CA.args_source = args_source
	return res
end -- function p.ControlArgs_tests_init(res, args_source)

--	Documentations et tests détaillés supplémentaires
--	res = res .. p.ControlArgs_tests(args_final)
function p.ControlArgs_tests(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	p.ControlArgs_tests_init(res, CA.args_source)
	res = ""
	-- CA.options = " : docdata docmin docdef docmax docligne docavant docapres docnotice " -- for documentation
	-- CA.options = " erron noerr nobox nocat " -- without normal result
	-- CA.options = " debug tests en es fr " -- for debug or enforce language
--	if CA.option("tests") then
		res = res .. CA.ta("\n* gener_tests CA.invoke_options", CA.invoke_options) .. CA.ta("CA.mode_options", CA.mode_options)
	--	local contenu = p.dummy_languages() or "dummy_languages is empty"
	--	res = res .. p.dropdown_box(1, "Langues plus ou moins bien définies. ", contenu)
		local contenu = CA.levenshtein_test( "\n\n* Test des mots proches, distances de '''levenshtein''' : ", c)
		res = res .. p.dropdown_box(1, "Tests unitaires des mots proches. ", contenu)
	--	contenu = CA.mot_proche_test("\n\n* Test des mots proches, sélection des mots : ")
	--	res = res .. p.dropdown_box(1, "Test des mots proches. ", contenu)
		contenu = p.wikidata_test("\n\n* Test de '''wikidata''', données centralisées des wikipedia : ")
		res = res .. p.dropdown_box(1, "Tests unitaires de wikidata. ", contenu)
		contenu = contenu .. p.catGen_test( "\n\n* Test des catégories générées par '''catGen''' :" )
		res = res .. p.dropdown_box(1, "Tests unitaires des catégories. ", contenu)
--	end
	--
--	if CA.option("tests") then
		local contenu = p.tables_comptes("\n* Comptages des contenus de tables : ")
		res = res .. p.dropdown_box(1, "Comptages des contenus de tables.", contenu)
		--
		local contenu = CA.testable_lister(p.tablim, "p.tablim", {} )
		res = res .. p.dropdown_box(1, "Liste de table, test sans limites : ", contenu)
		--
		local contenu = CA.testable_lister(p.tablim, "p.tablim", { levelmaxi = 2, max_n = 2, exclude1 = "hou" } )
		res = res .. p.dropdown_box(1, "Liste de table, test avec limites : ", contenu)
		--
		local contenu = CA.search_namespace() -- Module namespace 828 translated
		res = res .. p.dropdown_box(1, "Module namespace and page names. ", contenu)
		--
		local contenu = CA.testable_lister(CA.args_source, "CA.args_source")
		res = res .. p.dropdown_box(1, "Détails de la table des arguments reçus. ", contenu)
		--
		local contenu = CA.testable_lister(CA.args_known, "CA.args_known")
		res = res .. p.dropdown_box(1, "Détails des arguments connus : args_known", contenu)
		--
--		local contenu = CA.testable_lister(CA.i18n, "CA.i18n")
--		contenu = contenu .. CA.table_compte("i18n")
--		res = res .. p.dropdown_box(1, "Détails des tables de traductions : i18n", contenu)
		--
		local contenu = CA.verif_i18n(CA.i18n)
		res = res .. p.dropdown_box(1, "Translations missing, Manques de traductions : i18n", contenu)
--	end
	return res
end -- function p.ControlArgs_tests(args_final)

-- Basic result for arguments only
function p.ControlArgs_result(args_final)
	if type(args_final) ~= "table" then args_final = CA.args_final end -- optional arguments
	local res = ""
	-- CA.options = " : docdata docmin docdef docmax docligne docavant docapres docnotice " -- for documentation
	-- CA.options = " erron noerr nobox nocat " -- without normal result
	-- CA.options = " debug tests en es fr " -- for debug or enforce language
	if CA.option("debug")		then res = res .. "\n*" .. CA.ta("CA.catView", CA.catView) .. CA.ta("CA.invoke_options", CA.invoke_options) .. CA.ta("CA.mode_options", CA.mode_options) end
	--
	if CA.option("docdata")		then res = res .. "\n*" .. CA.generDoc(" docdef docligne ", CA.args_wikidata, "Wikidata") end
	if CA.option("docavant")		then res = res .. "\n*" .. CA.generDoc("", args_final, "ControlArgs") end
	if CA.option("docavant") and not CA.option("noerr") then res = res .. "\n*" .. CA.erreur_lister() end
	if not CA.option("nobox")	then res = res .. CA.normal_box(nil, args_final) end
	if not CA.option("nocat")	then res = res .. "\n*" .. CA.categ_lister() end -- categories in wikitext
	if CA.option("docapres")		then res = res .. "\n*" .. CA.generDoc("", args_final, "ControlArgs") end
	if CA.option("docapres") and not CA.option("noerr") then res = res .. "\n*" .. CA.erreur_lister() end
	res = res .. " "
	return res
end -- function p.ControlArgs_result(args_final)

-- Lister tous les paramètres d'un module, dans une langue au choix
function p.autotest_lang(args_known, args_source, lang, options, title, msgs_list)
	local res = ""
	CA.local_messages = {} -- collecte de touts les messages
	CA.local_erreurs = {} -- collecte de toutes les erreurs
	CA.invoke_options = " "
	CA.mode_options = options
	if type(msgs_list) ~= "table" then msgs_list = CA.i18n[lang] end
	if type(msgs_list) ~= "table" then msgs_list = CA.wiki_args end
	CA.cat_init() -- initialize the category list
--	CA.init_lang( lang, CA.wiki_args)
	CA.msgs_list = CA.i18n[lang] or CA.wiki_args
	CA.wiki_args = CA.msgs_list
	if not CA.wiki_args then return "" end
	CA.init_args(args_known, args_source, lang, msgs_list)
	local args_import = CA.import_arguments( args_known, args_source, msgs_list, CA.args_wikidata)
	CA.msgs_list = CA.i18n[lang] or CA.wiki_args
	CA.wiki_args = CA.msgs_list
	if not CA.wiki_args then return "" end
	local args_final = CA.interact_args_final(args_import)
	CA.msgs_list = CA.i18n[lang] or CA.wiki_args
	CA.wiki_args = CA.msgs_list
	if not CA.wiki_args then return "" end
	res = res .. "\n\n\n* " .. title
	res = res .. p.ControlArgs_result(args_final)
--	res = res .. CA.tables_comptes("\n* Comptages des tables '''autotest_lang''' : ")
	return res
end -- function p.autotest_lang(args_known, args_source, lang, options, title, msgs_list)

function p.tests_langs(args_known, args_source)
	local res = ""
	res = res .. "\n* '''Autotest en plusieurs langues''' :"
	res = res .. p.autotest_lang(args_known, p.ArgtestEN, "en", "en docavant docligne", "Auto test in english.")
	res = res .. p.autotest_lang(args_known, p.ArgtestES, "es", "es docavant docligne", "Auto test en español.")
	res = res .. p.autotest_lang(args_known, p.ArgtestFR, "fr", "fr docavant docligne", "Auto test en français.")
	return res
end -- function p.tests_langs(args_known, args_source)

function p.tests_time_old( if_view, res, time1, time2, time3, time4)
	-- Display example :
	-- Execution and test time : 2014-02-22 18:09:15 UTC , url = http://fr.wikisource.org/wiki/Module:ControlArgs/Documentation ,
	-- start = 84 mS , import + 8 mS , generate page + 0 mS , tests + 127 mS , total = 221 mS ControlArgs:tests:fr
	if not if_view then return "" end
	time1 = time1 or CA.time1
	time2 = time2 or CA.time2
	time3 = time3 or CA.time3
	time4 = time4 or CA.time4
	local nowyear = os.date("%Y-%m-%d %H:%M:%S")
	local mwtitle = mw.title.getCurrentTitle()
	local url = tostring(mwtitle:canonicalUrl( ))
	local time2d = time2 - time1
	local time3d = time3 - time2
	local time4d = time4 - time3
	local total = time4
	time1  = tostring(math.floor( time1	 * 1000 )) .. " mS"
	time2d = tostring(math.floor( time2d * 1000 )) .. " mS"
	time3d = tostring(math.floor( time3d * 1000 )) .. " mS"
	time4d = tostring(math.floor( time4d * 1000 )) .. " mS"
	total = tostring(math.floor( total * 1000 )) .. " mS"
	res = res or ""
	res = res .."\n* Execution and test time : " .. nowyear .. " UTC" .. CA.ta("url", url) -- <br/>
	res = res .. CA.ta("<br/>start", time1) .. CA.ta("import", time2d, "+")
	res = res .. CA.ta("generate page", time3d, "+") .. CA.ta("tests", time4d, "+") .. CA.ta("total", total)
	return res
end -- function p.tests_time( if_view, res, time1, time2, time3, time4)

------------------------------------------------------------
-- Arguments sources exemples
------------------------------------------------------------

--	local args_source_example = { c=":", categoryEN = "cat author", imageEN = "Smith.jpg", prize = "Nobel", categorie = "catAuteur", image = "Franc.jpg", prix = "NobelFr", categoria = "catAuteur", imagen = "Espangnol.jpg", premio = "NobelES"}

local ArgtNormal = {
	c=": docdef docavant docligne docapres",
	nom = "Rimbaud", ["prénom"] = "Arnaud", anneeDeces = "1842",
	image = "Carjat Arthur Rimbaud 1872 n2.jpg", langues = "Francais"
}

p.ArgtestEN = { c=": debug en docligne docapres", name = "Rimbaud", firstname = "Arnaud", initiale = "AR", options = " ", rights = "70", deathyear = "1842",  image = "Carjat Arthur Rimbaud 1872 n2.jpg", country = "France", BNF = "45274126861", DNB = "3684200072", ARCid = "R457-J-44" }

p.ArgtestES = { c=": es docavant docligne tests", nombre = "Rimbaud", apellido = "Carnaud", optionsES = " ", derechos = "70", anoMuerte = "1842",  imagen = "Carjat Arthur Rimbaud 1872 n2.jpg", payx = "France", BNF = "45274126861", DNB = "3684200072", ARCid = "R457-J-44" }

p.ArgtestFR = { c = ": f-r docdef doc-avant",  nom = "Rimbaud", ["prénom"] = "Arnaud", optionsFR = " ", droits = "70", anneeDeces = "1842",	image = "Carjat Arthur Rimbaud 1872 n2.jpg", payx = "France", BNF = "45274126861", DNB = "3684200072", ARCid = "R457-J-44" }
-- ["mode"] = "doc", 
-- _source.BNF = "45274126861", _source.DNB = "3684200072", _source.GKD = "71yhjey852"
-- _source.ARCid = "R457-J-44", _source.IBLid = "37581257954"

------------------------------------------------------------
-- Main interface to templates
-- Interfaz principales de modelos
-- Interface principal avec les modèles
------------------------------------------------------------

function p.base(frame, function_mode, mode_options)
	CA.time1 = os.clock()
	local res, t = "", ""
--	if function_mode then return res end
	CA.frame = frame
	CA.module_name = CA.frame:getTitle() -- example "Module:Auteur"
--	res = res .. "\n*" .. CA.module_name.."Base"
	local lang = tostring(mw.language.getContentLanguage().code)
	-- import and count sources arguments in wiki language
	local args_invoke = frame.args
	local args_template = frame:getParent().args
--	local x, template_ni, template_nn = CA.table_mixer(args_template)
--	local y, invoke_ni, invoke_nn = CA.table_mixer(args_invoke)
	--
--	Add or replace all the arguments from the template inside arguments from the module.
--	Remplacer ou ajouter tous les champs du modèle dans ceux du module.
	local args_source, args_src_ni, args_src_nn = CA.table_mixer(args_invoke, args_template)
	CA.args_source = args_source
	CA.args_source = p.ArgtestFR
	--
	-- Initialize i18n languages tables, need to adapt in calling modules
	CA.add_i18n(CA.i18n_args)
	CA.add_i18n("Module:ControlArgs/I18N")
	CA.cat_init() -- initialize the category list
	CA.init_lang(lang, CA.wiki_args)
	CA.init_args(p.args_known_default, CA.args_source, lang, msgs_list)
	--
	-- Import and adapt wikidata
	local args_wikidata, t = CA.import_wikidata(CA.args_known)
	local args_import, t = CA.import_arguments(p.args_known_default, CA.args_source ) -- , CA.i18n.fr, args_source
--	local args_import, t = CA.control_arguments(CA.args_known_default, lang, args_wikidata)
	CA.args_import = args_import
	CA.invoke_options = args_source.c
	CA.mode_options = mode_options
	--
	-- Interactions between argumensts (title, initiale ...)
	-- Interactions entre parametres (titre, initiale ...)
--	CA.args_final = p.interact_args_final(CA.args_import)
	CA.args_final = CA.args_import
	--
	-- Mode from arguments
	CA.args_final.mode = args_template.mode or args_template[1] or args_template["1"]
	or args_invoke.mode or args_invoke[1] or args_invoke["1"]
	or function_mode or "normal"
	CA.mode_name = CA.args_final.mode
	CA.time2 = os.clock()
	--
	-- Options from mode
	if CA.mode_name == "normal" then
		mode_options = "noerr nocat"
	elseif CA.mode_name == "doc" then
		mode_options = " : docdef docavant docligne" --  docdata
--	elseif mode_name == "notice" then mode_options = "noerr nocat"
--	elseif mode_name == "oldargs" then mode_options = "noerr nocat"
	elseif CA.mode_name == "langtest" then
		mode_options = " : docdef docavant docligne docdata"
	elseif CA.mode_name == "tests" then
		mode_options = " : docdef docavant docligne docdata tests"
	end
	CA.mode_options = mode_options
	--
--	res = res .. CA.ta("CA.import_arguments_err", CA.import_arguments_err)
--	res = res .. "\n* mode " .. CA.ta("CA.mode_name", CA.mode_name)
	--
	local res_function = "\n" .. CA.module_name .. ":" .. CA.mode_name .. ":" .. CA.wiki_lang .. " "
	if CA.mode_name == "doc" or CA.mode_name == "tests" then
		res = res .. "<br/>" .. res_function
	end
	--
	if CA.mode_name == "langtest" then
		res = res .. "\n* '''Autotest : in english, en español, en français.''' :"
		CA.time3 = os.clock()
		res = res .. p.tests_langs(args_known, args_source)
		--	res = res .. p.autotest_lang(CA.args_known, p.ArgtestEN, "en", "en : docdef docavant docligne", "Auto test in english.")
		--	res = res .. p.autotest_lang(CA.args_known, p.ArgtestES, "es", "es : docdef docavant docligne", "Auto test en español.")
		--	res = res .. p.autotest_lang(CA.args_known, p.ArgtestFR, "fr", "fr : docdef docavant docligne", "Auto test en français.")
	elseif CA.mode_name == "tests" then
		-- Generate normal wikitext, categories, and others
		res = res .. p.ControlArgs_result(CA.args_final)
		CA.time3 = os.clock()
		-- Detailed tests depends from options
		res = res .. p.ControlArgs_tests(CA.args_final) --[[ ]]
	else
		-- Generate normal wikitext, categories, and others
		res = res .. p.ControlArgs_result(CA.args_final)
		CA.time3 = os.clock()
	end
	--
--	if CA.option("tests") then
		-- Detailed tests depends from options
		--	res = res .. p.ControlArgs_tests(CA.args_final)
--	end
	CA.time4 = os.clock()
--	res = res .. p.tables_comptes("\n* Comptages des tables '''base''' : ")
	--
	if CA.option("tests") or CA.option("debug") then
		res = res .. CA.tests_time(true, "")
		res = res .. res_function
	end
	return res
end -- function p.base(frame, function_mode, mode_options)

------------------------------------------------------------
-- Interfaces, alias and functions to templates
-- Interfaces, alias y funciones para modelos
-- Interfaces, allias et fonctions pour les modèles
------------------------------------------------------------

function p.normal(frame)
	return p.base(frame, "normal", "noerr")
end

function p.doc(frame)
	return p.base(frame, "doc", " : docdef docavant docligne")
end

function p.langtest(frame)
	return p.base(frame, "langtest", " : docdef docavant docligne")
end

function p.tests(frame)
	return p.base(frame, "tests", " : docdata docdef docavant docligne tests ")
end

return p