Extension:Scribunto/Central modules

From MediaWiki.org
Jump to navigation Jump to search
This draft page and its talk must be in a better place, where you can copy it (in one or some pages).
  • This task T135845, seems enough advanced to share it.
  • That means enough defined, explicit and debug to permit at any developer to take a part of it and to work on it in coordination with others.
  • Then we can/must choose how to cooperate.
  • That means we can/must choose pages to discuss our works and changes.
  • This process also is a long term task for many central modules.
  • As a first step, on 2016-06-02, the initial developper creates this draft page to begin this process, and leave to others to take their parts of it.
  • At time, the initial developer Rical works on MW TestsCases .
  • Any developer can already #Convert a module as centralisable.


Some related pages
Draft documentation: Central modules.
Central libraries: Module:Central.
Simple examples of uses: Module:Central/Documentation
Full example: Victor_Hugo .

Task: Convert any module as central or centralisable[edit]

Scribunto permit to convert any module as central, or even centralisable before an efficient central repository exists.
That permits to use central modules in many languages, in many projects, even in many small wikis without enought helpers.
  • That provides an easier and more efficient peer review.
  • That enhanses the mean abilities of modules for a same global effort.
  • That reduces the duplication of effort for a same result.
  • That increases the mean availability of coders and helpers.
A central module can help users and helpers, in their own languages and the wiki languages, by errors, warnings, categories, reports and tests.
  • Example: display a category in the helper language and link to the category in wiki language.
  • Example: for each project and each language, choose detailed categories names or only categories "users modules errors" and "internal modules errors".
A central module must be very stable, understandable and strong against small usual misuses.
For that it permits managements of arguments, wikidata, errors, messages and modules versions.
The draft proposition for this task:task T135845 is in fr.wikisource Central modules.

What is a central module?[edit]

From actual live developments we can at least say:

It is able to use translations, in some or many languages, of its arguments names, catégories names, and errors messages that it produces.
Translations are in a /I18N submodule to not disturb it, except for minimal internal translations.
It is able to automaticly use any available translated languages.
It is able to use the local wiki language and the user language at the same time.
It can use a version management ability, at local and at central repository.
It can work at local like at central repository, for local tests without disturb central version, or for uses waiting central availability.
It is stable and contains necessary MW tests cases.
It is protected against too easy edit for a better stability.
If sought, it is able to help readers, helpers and developers in doc, edit and tests mode, showing internal documentation, reports and tests of complex basic functions.
These abilities come from one or some scribunto libraries, depending of the complexity of the module an its submomules.
Its uses of central libraries must be very simple in any simple or complex modules.
Functions verify parameters types and replace missing parameters by default values.
Functions are strong enough to accept little calling faults when non ambiguous.

How to support central modules?[edit]

Like modules in talk pages? And like phab tasks? And sharing tasks?
Use a common sharing page: Talk:Central modules?
How to name a Lua developer? Developer? Coder? Lua coder?
Use the versions management, in tests places or in final places.
The rights of Global interface editors could give global ability.
To ask in Requests for other global permissions could give global ability.
The rights of Interface editors could give global ability only from local login.
Waiting an efficient central repository, some bots could repeat validated centralisable modules in some places where active coders experiment them.

Easier, faster and stable development[edit]

Keep in one module the example of central module, and its libraries until they will be stable:
  • to easy change groups of functions in libraries, or in object,
  • to easy coordinate changes in several parts of the code,
  • to easy install and update all central libraries in a new place where use the code or where change it.
In development phase, to show the abilities of central modules, keep some languages, errors, messages, categories...
Alias of functions insure the continuity of service across change in sub-module, then in calling module, then in sub-module to delete the alias.
function tools.maini18n_lang_v_t(i18n, txt) -- Deprecated name of the function
	return tools.form_i18n_counts(i18n, txt) -- Better name or change in 
end -- Count available translations and languages
In development phase, when many functions or even some libraries are not well defined, put them in the same module and re-distribute functions and parameters.
function centre.init(frame, args_known, mode_name, options_for_modes, itemid) -- In an easier function, group some others, before change in calling module.
	tools.init_tools(frame, options_for_modes)
	centre.bindlibraries() -- Install central libraries, waiting true central libraries.
	centre.bindmodules(p)
	tools.get_arg_mode(mode_name, source_key, try_lang, args_source)
end
To try evolutions in a module or restructuration of some ones, use the versions management.
p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module.
	versionName = "Central", versionNumber = "1.03", versionDate = "2016-02-21 23:53",
	sought = "Central01,Central 2,mathroman", -- Sought module and submodules versions
	known = " Central01,Central 2 * mathroman,mathroman3 ", -- Known module and submodules versions
}

Short story of development[edit]

  • The previous templates was based on the oldest LISP programmation langage style.
  • On 2012-04-16, Mediawiki offered Lua in Scribunto. This language is very simple to use, but very complete, all in objects, with the "meta" table to replace the words "inherited" or "class" (even sub-threads out of Mediawiki).
  • Of course then, many users began to convert each old templates in new Lua modules which was simple due to the already existing LISP-like templates.
  • But the previous French Template:Author was already a complex template, needing 6 sub-templates, see "liés".
  • On 2013-01-18, i18n tables was used to translate errors.
  • On 2013-01-25, in the Module:Author, the generic management of arguments, and the table to group their definitions, came from its large number of arguments, see "args_known".
  • On 2013-03-12, the Module:ControlArgs groups complex translations and management of arguments to support other modules to become centralisable.
  • On 2015-02-25, the Module:Author3 include the versions management for a better stability.
  • On 2016-01-30, the Module:Central convert modules in libraries.
  • On 2016-05-20, task T135845: a task propose to "Convert any module as centralizable".

State of development[edit]

In phase of development, some errors are needed to show them in some reports and to choose their better places.
Do not correct these errors, or even activate some ones.
Central translatable libraries are: centre and tools.
Each translatable library contains internal translations in english, french and spanish.
The library mathroman is a very small exemple of translatable library, only detects errors and has no mode nor options.
The centre library binds modules in sought versions management and easy translates parametrable strings.
The tools library support simple to complex modules.
Their supports are to translate, collect, manage and display views.
Translate is for arguments names from template, for images and texts on page and for categories and errors.
Waiting final true libraries, for local or central developments, the libraries and their translations can come from Module:Central and Module:Central/I18N.
Where to place the i18n translations out of the final libraries to not disturb it when translations change?
Proposition: put the centre library in Module:Library/centre/I18N.
The arguments management collects and keeps strings to translate and their parameters. Later also display lists of translated strings in right places (warning, errors, categories, categorize).
Manage arguments means also coming from wikidata, help for better argument name orthograph, auto correction of arguments names when non ambiguous, alias arguments names, verify if value is in the parametrable list of values, needed but absent, warning when twice defined, arguments descriptions.
The versions management require() adequate versions of submodules to test, following known and sought versions, like Module:Vers2.4.
This versions management reports versions used, errors, missing or replaced by normal ones... then helpers can better select and understand what happens.
Any helper of main module can select versions of its submodules from internal arguments or from template arguments.
Central libraries permit to easy generates categories, single or in group, translatable dropboxs, tables views, tests views...

Unavailable or sought abilities[edit]

on 2016-05-20

  • Central libraries are NOT stable and need to contain necessary MW tests cases.
  • For MW tests cases, we can also display the results in tableviews, like for many other tests.
  • Auto correction of arguments names when they are non ambiguous (see available levenstein).
  • Waiting the tasks debug, config arguments simulate informations depending of blocking tasks.
  • In the list of available languages, when it is large, we could display first a list of "near languages", like tools_near_languages = "fr,es,it", defined in i18n translations for each language. Others are in alphabetic order of languages codes. See tools.maini18n_languages_list() which returns "This module can translate 171 texts in 3 languages: English(en=English), español(es=Spanish), français(fr=French),".
  • For MW tests cases of the logic of centre.bindmodules(), replace existing modules by a simulation of package.loaded.
  • Make a testviewer based on MW tests cases.
  • Main options for dropbox (title, content, image) also could be in the style options.
  • Tests of multiple values arguments must be explicit.
Tasks to open?
  • T00000: Add module and library types in scribunto ?
  • T00001: Sorted tableview do not sort date-time, in template and in module.
  • T00002: In a dropbox after \n* the content is after the box. Better define the case. Insert "\n------" before correct that. Try that out of fr.wikisource, in test2 or mediawiki...
  • T00003: bindI18N() after bindmodules to protect sought translatios against un-sought ones.
  • T00011: Sorted tableview do not sort date-time
  • T00012: In a dropbox after \n* the content is not inside the box. Better define the case. Insert "\n------" before to correct that.
  • T00013: Insert and mask structured datas and errors in resulting wikitext for bots. In xml or json or template style.
  • T00014: Display changes in test_init() arguments, in a dropbox.
  • T00015: Convert some groups of functions as new objects types: tableview with its headers and options, luatable() and its luatablecount(), dropbox() and dropdownfunc() and their options, get{} output from centre.get_module_and_time() for modules and libraries.

Blocked tasks[edit]

task T41610: Scribunto should support global module invocations
task T127354: Consider helping some smaller Wikipedias' communities
task T122086: RFC: Sharing templates and modules between wikis - poor man's version (investigation)
task T89598: Convert Template:Authority_control to Lua and use Wikidata

Blocking tasks[edit]

Some blocking tasks are detected by the module itself.

{{#invoke:Central | doc | tools_tasks_table_report_title }}

Important support tasks[edit]

task T53660: Detect the edit state to adapt help messages to user errors.
  • To show edit or test mode only in edit state.
task T68051: Get the user language to help admins to maintain a module or a template
  • Permit to use the same module in many languages in many projects. This enlarge the use of modules in many more small wikis. This also enhanse the mean abilities of modules for a same global effort.
  • Help helpers, from large wikis in their own langages, to help small wikis in other languages. Example: display a category in the helper language and link to the category in wiki language.
task T119978: Get the own module name and last record date-time from each module
  • This task is necessary to reduce human errors:
  • to rightly collect /I18N translations,
  • and for a more confident versions management.
  • search this task id below for details.
task T122752: #invoke seems do not record the module
  • This task is a true bug which impacts the versions management.
  • But the centre library correct it for the main module. Other modules come by require() and are not impacted.
  • In most other uses, this bug has no impact.
See
  • tools.task_T122752_get_state() -- Detect T122752 : #invoke seems do not record the module
  • tools.task_T122752_correct_once() -- Debug T122752 : #invoke seems do not record the module

Central repository tasks[edit]

  • These tasks impact the final stage of true central usage.
  • But the full development of central libraries is possible without central repository.
  • And the use of central libraries is possible in any local wiki with exactly the same modules, and only new i18n tranlations.
task T121470: Central Global Repository for Templates, Lua modules, and Gadgets
task T52329: We need a common repository for Scribunto modules and templates
task T41610: Scribunto should support global module invocations

Marginal tasks[edit]

  • These tasks are interesting to optimize somefunctions but have no link to any central aspects.
task T48160: Lua: Allow using labels in mw.wikibase.entity.formatPropertyValues
task T63958: Use existing $dateFormats to format dates on Wikidata
task T85412: The formatPropertyValues needs an option to format data from date-time, angle or geographic coordinates
task T75460: [Story] Make Luafunctions default to the user's language on multilingual wikis
task T85419: User groups should be exposed to Scribunto ( This permit to adapt errors and warning for administrators or modules coders )

Documentations examples[edit]

{{#invoke:Central|read|itemid=Q8023}}

Nelson Mandela Central v160603
Flag of England.svg , label = Nelson Mandela , , birthyear = 1918 , deathyear = 2013 , int2roman = nil , roman2int = nil , int2roman = nil
This module can translate 208 sentences in 3 languages: English(en=English), español(es=Spanish), français(fr=French),


{{#invoke:Central|doc|tools_tasks_table_report_title}} ?


{{#invoke:Central|doc|tools_wikidata_arbitrary_test_title|Q535}}


Convert a module as centralisable[edit]

Translate arguments, errors, categories...[edit]

Translate arguments names (and their descriptions), errors, categories, title...
p.i18n.en = { -- English
	mode 						= "mode", -- All arguments must be translated in all languages to operate.
	mode_descr					= "Type of use of the module or template: read, edit, doc, test.", -- Describe the argument for documentation.
	options 					= "options",
	options_descr				= "Options to form the module or model result.",
	firstname					= 'firstname', -- Other argument and description
	firstname_descr				= "First name. Please specify to correct the sort key.",
	mathroman_J_before_end_err	= "character J before the end", -- Example of error.
	mathroman_dig2romtest_title = "Test from digital to roman numbers", -- Example of title of a group of tests.
	tools_language_cat			= 'Speaking %1', -- Example of category.
	tools_date_to_part_call_cat	= "Module with internal error", -- Several errors are grouped in a same category, defined at translation level.
	tools_needed_to_verify		= "(required, to be checked)", -- In the list of arguments, an argument is needed
}

Define arguments[edit]

  • All arguments must be translated in all languages to operate.
p.args_known = { -- Table of the definitions of all known arguments at module level.
	birthyear =		{typ = "dat", need = 0, keyword = "birthyear", prop = "P569", format = "year"},
	firstname =		{typ = "dat", need = 0, keyword = "firstname"},
}

Initialize a module[edit]

p.options_for_modes = { -- default options
	read	= " noerr ",
	doc		= " noerr nobox nocat ",
	edit	= " : catview docview docdef docline docsrc docdata ",
	tests	= " : catview docview docdef docline docsrc docdata tests ",
	-- Option nocat means "Do not categorize and do not show categories."
}

function p.read(frame) -- Forms the text to read by users.
	local res = ""
	centre.init(frame, p.args_known, "read", p.options_for_modes)
	tools.args_final = p.interact_args_final(tools.args_import) -- Interactions between arguments
	res = res .. p.form_result() -- forms the resulting wikitext
	return res
end -- function p.read(frame)

Minimal centalisable module[edit]

A module without interface can form translated errors or categories in any function, without any p.interface(frame) functions.
It can also use translated arguments and/or form report to display later if sought.
The centre library and the mathroman library are in this case.
Any module using central library can contain, or none, internal translations in english and some other languages.
Minimal example:
p.i18n.en = { -- Define translations of arguments names, categories names, and errors messages to produce.
	birthyear = "birthyear", -- example
	centre_luatable_counts = "%1 variables, %2 functions, %3 sub-tables", -- example
} -- p.i18n.en

p.args_known = { -- Define all known arguments at the main module level.
	birthyear = {typ = "dat", need = 0, list = 2, keyword = "birthyear", prop = "P569", format = "year"},
} -- p.args_known

p.options_for_modes = { -- default options
	read	= " noerr ",
}

function p.read(frame) -- Forms the text to read for users.
	local res = ""
	centre.init(frame, p.args_known, "read", p.options_for_modes) -- Default init from the centre library.
	res = res .. "Hello world !" -- Forms the resulting wikitext
	return res
end -- function p.read(frame)

Modes and options[edit]

Really used options come from p.options_for_modes and from options arguments.
Modes are composed of options to choose what and how to display. Default modes:
p.options_for_modes = { -- default options
	read	= " noerr ",
	doc		= " noerr nobox nocat ",
	edit	= " : catview docview docdef docline docsrc docdata ",
	tests	= " : catview docview docdef docline docsrc docdata tests ",
	-- Option nocat means "Do not categorize and do not show categories."
}

function p.read(frame) -- Normal use for simple readers of pages
	local res = ""
	centre.init(frame, p.args_known, "read", p.options_for_modes) -- Default init from the centre library.
	res = res .. try.form_result() -- Forms the resulting wikitext
end

function p.doc(frame) -- To include some pieces of documentations directly from the module in its template or module documentation page.
	centre.init(frame, p.args_known, "doc", p.options_for_modes) -- Default init from the centre library.
	res = res .. tools.dropdownfunc(select, "tools_similar_args_test_title", tools.similar_args_test)
end

function p.edit(frame) -- To support the user to modify arguments in case of errors. To light support of helpers in their own laguages.
	centre.init(frame, p.args_known, "edit", p.options_for_modes) -- Default init from the centre library.
	res = res .. formDocBox() -- A panel to help users when they dit the use of a template or module.
	-- With a dropbox for helpers, displaying availables languages, versions used, number of admins in a wiki...
	res = res .. try.form_result() -- Forms the resulting wikitext
end

function p.tests(frame) -- The most extended support for helpers.
	centre.init(frame, p.args_known, "tests", p.options_for_modes) -- Default init from the centre library.
	res = res .. formDocBox() -- A panel to help users when they dit the use of a template or module.
	-- With a dropbox for helpers, displaying availables languages, versions used, number of admins in a wiki...
	res = res .. try.form_result() -- Forms the resulting wikitext
	res = res .. try.testsview("allwaysview")
end

p.options_for_modes = { -- default options					for anyother mode
	read	= " noerr ",
	doc		= " noerr nobox nocat ",
	edit	= " : catview docview docdef docline docsrc docdata ",
	tests	= " : catview docview docdef docline docsrc docdata tests ",
	anyother = " noerr other noother ", -- Other mode, to manage in code.
}

Versions management[edit]

Each centralisable main module can start with a definition of alternative versions of its sub-modules.
Then its versions management is available.
p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module.
	versionName = "Main", versionNumber = "1.03", versionDate = "2016-04-27 23:23",
	sought = "Main, Box 2, Item.3", -- Sought module and submodules versions
	known = " Main,Main2 * Box,Box 2 * Item,Item.2,Item.3 ", -- Known module and submodules versions
}
Template or invoke arguments can replace soughtversions and knownversions to try them without record, or in a test template.
In known versions, the first of each group of versions is the normal one and can replace any other if not available.
The versions management require() adequate versions of submodules to test, following known and sought versions, like Module:Vers2.4.
This versions management reports versions: used, errors, missing or replaced by normal ones... then helpers can better select and understand what happens.
Any helper of main module can select versions of its submodules from internal arguments or from template arguments.
When the developer copies or rename this file in a new version, he can forget to adapt that definition and then disturb the versions management.
To reduce this risk, each module need to know its own name.
To document the version date-time, we need that for each module or sub-module.
See the task task T119978: Get the own module name and last record date-time from each module

{{#invoke:Central | doc | dockey = tools_bindmodules_test_title | itemid = Q535 }}

Translations management[edit]

Any translation must not involuntarily disturb an other and we must insure that this cannot happens, especially in new modules or libraries.
For this need we can/must start any translation key with the name of the module or library.
An alternative version can modify any translation of the normal version.
A main module can modify any translation from any submodule to adapt it to a new context.
A /I18N submodule can adjust or correct any translation from a normal or new version.

Then the centre.bindmodules(p)function follows these rules:

  • starts with the libraries translations,
  • starts with the internal translations,
  • then add or mix translations from normal /I18N,
  • then add or mix translations from the /I18N alternative versions,
  • continue with the modules translations,
  • starts with the internal translations,
  • then add or mix translations from normal /I18N,
  • then add or mix translations from the /I18N alternative versions.
In doc or test mode, a report display missing or modified translations.
To reduce errors risks in the binding of translations, we need to base each /I18N sub-module name on the name of each module itself.
See the task task T119978: Get the own module name and last record date-time from each module

{{#invoke:Central | doc | dockey = tools_missing_translations_title | itemid = Q535 }}

Structures and guidelines[edit]

In development phase keep some light errors to show how reports form errors.
The central code must be strong with or without central repository, libraries, known bugs and weak use.
Then central functions must specialy verify their arguments, run only once if needed, tested by tests cases, and tests shown for users.

Process of arguments and translations[edit]

-- Process of arguments and translations along their transformations :
	tools.args_known = {} -- Known arguments, at main module level
	tools.args_invoke = {} -- Invoke arguments, at {{#invoke: ... }} level
	tools.args_template = {} -- Template arguments, at {{Template| ... }} level
	tools.args_source = {} -- Source arguments = args_template + args_invoke
	tools.args_config = {} -- Config arguments, without translation, for helpers
	tools.args_unknown = {} -- Unknown arguments
	tools.args_wikidata = {} -- Wikidata arguments, from Wikibase
	tools.args_import = {} -- Import arguments
	tools.args_final = p.interact_args_final() -- Final arguments, after interactions between them
	tools.args_selected = {} -- Selected arguments, in some modules
	tools.wiki_translations = {} -- Wiki translations
	tools.user_translations = {} -- User translations
	tools.errors_list = {} -- Errors list
	tools.categories_list = {} -- Categories lists
Steps in arguments process:
tools.args_known : The main module defines all arguments, and they all must have translations in all availables languages.
tools.args_source : The source arguments come from template, else from #invoke, for each argument.
tools.args_config : Memorize direct configuration arguments.
tools.args_wikidata : An argument can come from wikidata if its definition have a wikidata property like prop = "P21".
The priority in origin of an argument is always: first the template, else the { {#invoke:module, else the internal interaction between arguments in the module, else the internal default value in the module.
tools.args_config : The config arguments come without translations from source arguments. Translations are identical in all available languages.
p.args_known = { -- Table of the definitions of all known arguments at module level.
	birthyear = {				-- Key of the argument.
		--
		keyword = "birthyear",	-- The keyword is the same as Key to identify the argument in some cases.
		syn = 1,				-- A synonym of an argument defined in the args_known table.
		keyword = "birthyear2",	-- For a synonym, the keyword identify the referal argument.
		-- A synonym can be another argument. Then interact_args_final(args_import) mixes them.
		--
		typ = "dat",			-- The type "dat" is the basic type of arguments.
		typ = "config",			-- The type "config" groups direct arguments from tools.args_source, without translation.
		--
		need = 1,				-- If need == 1 the argument can be automatic.
		need = 2,				-- If need == 2 the argument must come from the template or wikidata.
		--
		prop = "P569",			-- Wikidata property to automatic import an argument, if available.
		format = "year",		-- Extract the year from a Wikidata property.
	},
}
tools.args_wikidata = tools.import_wikidata(tools.args_known)
tools.args_import = tools.import_arguments() -- Import arguments from all origins, normaly in p.init().
tools.args_final = p.interact_args_final(tools.args_import) -- Special interactions between arguments in the main module, even special in a mode.

{{#invoke:Central | doc | tools_list_all_args_title }}

Arguments properties[edit]

{{#invoke:Central | doc | tools_args_known_structure_title }}

They can be needed, synonym, limited to some values ... typical examples:

	language =	{keyword = "language", typ = "dat", need = 0, prop = "P103", }, -- Simple argument, with wikidata property.
	--
	[1] =		{keyword = "mode", typ = "sys", need = 0, syn = 2, }, -- Synonym or alias of an argument defined by position.
	--
	c =			{keyword = "c", typ = "dat", need = 0, syn = 1, }, -- Synonym or alias arguments.
	options =	{keyword = "c", typ = "dat", need = 0, syn = 2, }, -- Synonym or alias arguments.
	--
	-- Argument limited to some values.
	region =	{keyword = "region", typ = "dat", need = 0, -- like Simple argument
		arg_values = "region_values", key_values = "other,china,india,century" }, -- arg_values translation key for 
	region_values	= "autre,chine,inde,siècle", -- i18n french translations for region argument.
	region_values	= 'otros,china,india,siglo', -- i18n spanish translations for region argument.
	--
	-- Argument and its description.
	options			= 'options', -- Arguments can be described for documentation in tests or in doc mode.
	options_descr	= 'Options to add with mode options.',

Config support arguments[edit]

They drive directly support aspects, without translations:

	userlang =	"", -- user language for i18n translations.
	wikilang =	"", -- wiki language for i18n translations.
	--
	mode_name = tools.args_source.mode
	options =	"",
	c =	"",
	--
	selectversions =	"", -- Helpers can change sought versions in edit or tests modes.
	allversions =	"", -- Helpers can change known versions in edit or tests modes.
	--
	dockey =	"", -- key of document to display in doc mode.
	id =	"Q535", -- wikidata element to display in doc mode.
	entityid =	"Q535", -- wikidata element to display in doc mode.
	--
	local doc1_doc = tools.args_source.dockey or tools.args_source[1]
	local doc1_id = tools.args_source.entityid or tools.args_source.id or tools.args_source[2]

Translations texts keys[edit]

They follow these guideline. That enable to group them in documentations for errors, categories and other:

	library_ident_words_err			= "parametrable string", -- <b>Basic</b> structure: key = "text".
	--
	tools_auto_val_warning_msg		= "Verify the automatic argument: %1 = <b>%2</b>.", -- Example of <b>message</b>.
	tools_lang_not_exist_err		= "Error: The language <b>%1</b> is not available.", -- Example of <b>error</b>.
	tools_lang_table_err_cat		= "Module with internal error", -- Example of <b>category</b>.
	tools_page_tests_h3_title		= "Tests of this page", -- Example of <b>title</b> of DropBox, or anywhere.
	tools_loaded_modules_headers	= "Title, Version, Date, I18N, Translations / Languages", -- Example of <b>headers in a tableview</b>.
	tools_versionsmanagement_report	= "Versions management report", -- Example of <b>title of report</b>.
	--
	options							= 'options', -- Argument to describe.
	options_descr					= 'Options to add with mode options.', -- <b>Description</b> for an argument.
	-- The key of the description is the key of the argument, plus <b>_descr</b>.

Central libraries[edit]

How to name central libraries ?[edit]

How to distribute functions in one or some libraries ?
How to name also all the functions of these libraries ?
The centre library mainly binds modules. Eventual names:
  • centre as international noun and to support to move in a central place.
  • center as USA english noun and to support to move in a central place.
  • central as the place in the middle.
  • centralize as support to move in the middle.
  • centralizer as support to move in the middle.
The tools library mainly extends the translation service and translatable usual viewers. Eventual names:
  • centretools as tools for the centre library.
  • centraltools as available tools shared in the central space.
  • translatabletools as available tools shared in the central space.
Whe could make a viewer or viewers library to group:
  • tableviewer for table of raws and columns.
  • dropbox and dropdownfunc with title, content and style options.
  • cat_add for parametrable and bilingual categories, and to group their list.
  • msg_add for parametrable messages, and to group their list.
  • luatable for counts and structures of luatable.

centre library[edit]

The centre library binds modules in sought versions and their translations.

centre.new_library[edit]

Record a library in package.loaded from a table object.
	centre.new_library(name, library, options)

centre.bindlibraries[edit]

	function centre.bindlibraries() -- Install central libraries, waiting true central libraries.

centre.bindmodules[edit]

Bind all modules, versions and translations. Cumulate in centre.maini18n all translations from i18n tables from modules.
	res = res .. centre.bindmodules(p) -- Example of use in the main module.
	res = res .. centre.bindmodules() -- Without (p), bindmodules find itself the main module.
	res = res .. centre.bindmodules(other) -- The main module can choose another main module.

centre.get_module_and_time[edit]

This function can create a module and/or collect and complete data on a module or a library.
This code roughly describe it:
	local get = centre.get_module_and_time("Module:Example")
	-- Get the module from require("Module:Example") but not fails if it not exists.
	-- Then get datas on the module and report them.
	
	local get = centre.get_module_and_time("Module:Example", module)
	-- Record the module with the title "Module:Example" in package.loaded.
	-- Then get datas on the module and report them.
	
	local get = centre.get_module_and_time(title, module) -- Get a descriptor of one loaded object
	-- After that, get is roughly equivalent to:
	
	get.title = title -- Like "Module:Example" for a module
	get.module = module -- The module code itself (compiled).
	get.isNil = not module
	get.isLoaded = true and package.loaded[title]
	get.isFunction = (type(module) == "function")
	get.isTable = (type(module) == "table")
	get.isModule = true if the title looklikes to "Module:Example"
	get.isLibrary = true if the title looklikes to "example"
	get.i18n = module.i18n -- translations tables from the module
	get.versions = module.versions -- descriptor for the versions management {sought, known...}
	get.hasi18n = true and module.i18n
	get.versionName = title without "Module:", but perhaps with "/I18N"
	get.isI18N = true if title include "/I18N"
	get.lessI18N = title without "/I18N"
	get.simplename = title without "Module:" and without "/I18N"
	if get.isModule then
		get.lessI18N = title without "/I18N"
	--	get.versionI18N = "Module:Example/I18N" -- eventual /I18N module to search
		get.subI18N = get.title .. "/I18N" -- eventual sub-module "/I18N"
		get.revistamp = "20160501122359" -- The compact record date-time of the module. Here for 01 May 2016 at 12:23:59
	end
	if get.isLibrary then
		get.lessI18N = title looklikes to "example" without "/I18N"
	--	get.versionI18N = "Module:Library/example/I18N" -- eventual /I18N module to search
		get.subI18N = centre.ModuleNS .. "Library/" .. get.title .. "/I18N" -- eventual sub-module "/I18N"
		get.revistamp = "20010101000000" -- Default compact date-time for all libraries on 1st January 2001 00:00:00. Or perhaps true date-time.
	end

tools library[edit]

Internalfunctions to implement mainfunctions are not described.

tools.str_vars[edit]

	tools.str_vars(ref, v1, v2, v3, v4, v5, v6, v7, v8, v9)
	tools.str_vars("Module with internal error") -- example with text
	tools.str_vars("tools_luatable_counts", tot_vars, tot_func, tot_tabs) -- example with key.
	tools.str_vars("%1 variables, %2functions, %3 sub-tables", 30, 10, 4) -- example with text and values.

Result in a parametrable string based on ref.

  • If ref is a key of translatable string in i18n table, it is first translated.
  • If ref is not a translatable key, thisfunction uses it like translated.
  • If the translated string contains %1 to %9 thisfunction replaces them by v1 to v9 respectively, after thisfunction converts them in strings.
  • If ref is any other string, thefunction return it as is.

This is roughly equivalent to:

function tools.str_vars(ref, v1, v2, v3, v4, v5, v6, v7, v8, v9)
	ref = tostring(ref)
	if translations[ref] then wt = tostring(translations[ref])
	elseif ref then wt = tostring(ref)
	else wt = tostring("noref") end
	v1 = v1 or " 1"
	...
	v9 = v9 or " 9"
	if v1 then wt = string.gsub(wt, "%%1", tostring(v1) ) end
	...
	if v9 then wt = string.gsub(wt, "%%9", tostring(v9) ) end
	return tostring(wt)
end

tools.str_test_case[edit]

This is a first step to work on tests_cases. See also mathroman.tests_cases
This function for test case do not translate but convert it like in: forest_t_trees_b_birds-7-trees-1000-birds
This is better for tests cases:
  • Then tests cases depend of values but not of the languages.
  • Different translations have different keys but can have a same text.
This is roughly equivalent to:
function tools.str_test_case(ref, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- add v1 to v9 to the ref
	return ref .. "-" .. v1 .. "-" .. v2 .. "-" .. v3 ...
	-- which looklikes in:
	return "forest_t_trees_b_birds-7-trees-1000-birds"
end
For tests cases search : class ClassNameTest extends Scribunto_LuaEngineTestBase

tools.is_in[edit]

Returns true if the word is in the text, even inside another word. Else return false.
	function tools.is_in(word, text) -- return true if the word is in the text. Else return false.

This is roughly equivalent to:

function tools.is_in(word, text)
	return string.find(text, word)
end

tools.is_in_sp[edit]

Returns true if the word is in the text, beetwen spaces or separators, not inside another word. Else return false.
This function is in centre which use it to find versions in list.

This is roughly equivalent to:

function tools.is_in_sp(word, text, sep)
	sep = sep or " "
	return string.find(sep .. text .. sep, sep .. word .. sep)
end

tools.cat_add[edit]

tools.cat_add(ref, v1, v2, v3, v4, v5, v6, v7, v8, v9)
Record a category in categories_list, parametrable like tools.str_vars().

tools.catGroup[edit]

Generate categories from plural values in only one string argument divided by comas.
function tools.catGroup(groupCat, groupList)
Record a groupCat group of categories in categories_list.
Each part is translatable like in tools.str_vars(one of parts of groupList).
Example wich give Category:Country France , Category:Country Italy
tools.catGroup("Country %1", "France,Italy")

This is roughly equivalent to:

function tools.cat_add(ref, v1, v2, v3, v4, v5)
For each part of ref divided by a coma.

tools.err_add[edit]

tools.err_add(ref, v1, v2, v3, v4, v5, v6, v7, v8, v9)
Returns a error, parametrable like tools.str_vars().
Record also these errors in errors_list.

tools.msg_add[edit]

tools.msg_add(ref, v1, v2, v3, v4, v5, v6, v7, v8, v9)
Returns a message, parametrable like tools.str_vars().
Record also these messages in errors_list.

tools.errors_lister[edit]

tools.errors_lister()
Returns the list of all recorded messages first, then all errors.
Does not return duplicates errors or messages.

tools.Th tableview[edit]

That could become the tableview object.
function tools.Th(t) -- Header of a tableview
function tools.Tc(t) -- Header of one column of a tableview
function tools.Tr(t) -- Row of a tableviewtableview
function tools.Td(t) -- Data cell of a tableview
function tools.Te(t) -- End of a tableview

	-- Example of sortable tableview (but after sort, intermediate headers are not at the right place)
	t = t .. tools.Th("wikitable sortable") .. tools.Tc("Name") .. tools.Tc("Year") .. tools.Tc("Size") -- First headers
	t = t .. tools.Tr() .. tools.Td("Sara") .. tools.Td("1983") .. tools.Td("167")
	t = t .. tools.Tr() .. tools.Tc("Surname") .. tools.Tc("Epoch") .. tools.Tc("Size maxi") -- Intermediate headers
	t = t .. tools.Tr() .. tools.Td("Alan") .. tools.Td("1987") .. tools.Td("175")
	t = t .. tools.Te()

tools.dropbox[edit]

dropbox, documentation in a single dropbox, series of dropboxes.

options to select

tools.dropbox(title, content, boxstyle)
Returns a dropbox with parametrable title and style.
The optional boxstyle parameter is a table containing options to define the style of the dropbox.

tools.dropdownfunc[edit]

tools.dropdownfunc(select, title, content, ...)
Like tools.dropbox().
  • This function forms the dropbox if select is "allwaysview" or "enforcerun" or true or the title key before translation.
If the function fails the dropbox displays <red>INTERNAL ERROR</red>, to protect the displaying of the rest of the page.
Then a developer can replace (select, with ("enforcerun", for this box. Then he/she can debug the code error. See examples below.
The content parameter can be a string or a function followed by any number of its parameters.
Options for the dropbox are in a table identified by one of its contents:
boxstyle = { ..., boxstyle = "boxstyle", ...}
Options and their default values are:
tools.maini18n_languages_list()
	alignT = alignT or "left", -- align
	alignB = alignB or "left", -- align
	margin_all = margin_all or "0px", -- margin
	margin_bottom = margin_bottom or "1em", -- margin-bottom
	width = width or "99%", -- width
	border_radius = border_radius or "0", -- -moz-border-radius
	text_color = text_color or "black", -- color
	background_color = background_color or "#FFFFFF", -- background-color
	border_color = border_color or "#AAAAAA", -- border-color
	height = height or "1.6em", -- height
	label = "&#x25bc; &nbsp; /&#x25b6; &nbsp; ", --	 = "Unwrap/Wrap",
Options are not but also could be title, content, image.
Example of dropbox style options:

{{#invoke:Central | doc | dockey = tools_options_from_mode_title | itemid = Q535 }}

tools.maini18n_languages_list[edit]

tools.maini18n_languages_list()
Returns the list of available languages.
Example: "This module can translate 171 texts in 3 languages: English(en=English), español(es=Spanish), français(fr=French),".

tools.luatablecount[edit]

local res, tot_vars, tot_func, tot_tabs = tools.luatablecount(tab, tabname)
tab is a luatable or a name of table in tools library like tools.args_known
tabname is a name of the tab table.
res is a string like "The table mathroman.i18n counts 30 texts, 0 functions, 3 sub-tables."
In whole the table, the number of string is tot_vars, of functions is tot_func, of sub-tables is tot_tabs,

tools.form_i18n_counts[edit]

res = tools.form_i18n_counts(centre.maini18n, "maini18n = %1 texts translated in %2 languages.")
Then res is a string like "maini18n = 157 sentences translated in 48 languages."

mathroman library[edit]

It converts decimal to roman numbers or reverse. It produces errors messages to explicite them. It have none interface(frame).

mathroman.int2roman[edit]

	mathroman.int2roman(int)
Returns the roman number first, then eventual text of errors.
Record also these errors in tools.errors_list.

mathroman.roman2int[edit]

	mathroman.roman2int(roman)
Returns the decimal integer first, then eventual text of errors.
Record also these errors in tools.errors_list.

mathroman.tests_cases[edit]

This is a first step to work on tests_cases. See also tools.str_test_case
	mathroman.roman2int(roman)
Returns the decimal integer first, then eventual text of errors.
Record also these errors in tools.errors_list.
--	Tests : class ClassNameTest extends Scribunto_LuaEngineTestBase
--	protected static $moduleName = 'ClassNameTest';
mathroman.tests_cases = { -- Autotest cases to validate the mathroman library at mediawiki level.
	-- Each test_case defines a name, a function, an input, an output. See also tools.str_test_case.
	{ name = 'mathroman.int2roman (1)', func = mathroman.int2roman, args = { 1 }, expect = { "I" } },
	{ name = 'mathroman.int2roman (2)', func = mathroman.int2roman, args = { 2 }, expect = { "II" } },
	{ name = 'mathroman.int2roman (3)', func = mathroman.int2roman, args = { 3 }, expect = { "III" } },
	--
	{ name = 'mathroman.roman2int (1)', func = mathroman.roman2int, args = { "I" }, expect = { 1 } },
	{ name = 'mathroman.roman2int (2)', func = mathroman.roman2int, args = { "II" }, expect = { 2 } },
	{ name = 'mathroman.roman2int (3)', func = mathroman.roman2int, args = { "III" }, expect = { 6 } },
}
Where to find documents or examples?
Rical: I have search in phab, gerrit, mediawiki without success.
For tests cases search "ClassNameTest" or "LuaEngineTestBase" or "LuaEngineTestBase::testLua" in class Lua reference manual.
I found only my own code in 2013 in Module:Unitest_Scribunto
But I don't know if it is efficient. How to submit a library to mediawiki check in gerrit?
See also phab:T48635 Scribunto_LuaLibraryBase registerInterface() produces internal error on Windows platform