Module:Central-mw-en
Jump to navigation
Jump to search
You must remove this documentation before recording.
Remove all modes to return to read mode.
Internal error : no source or no known arguments !
Internal error : no source or no known arguments !
User support about parameters:
⦁ translate_translations_key_missing
⦁ docDropBoxTitle
⦁ Mathroman2
⦁ TestRequire
⦁ This module can translate 765 sentences into 7 languages: brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
Module with internal error Module with usage error Module with error Module with internal error Module with usage error Module with error
Debe quitar esta documentación antes de grabar.
Retire todos los modos para volver al modo read.
Internal error : no source or no known arguments !
Internal error : no source or no known arguments !
Asistencia de los parámetros de este modelo:
⦁ translate_translations_key_missing
⦁ docDropBoxTitle
⦁ Mathroman2
⦁ TestRequire
⦁ Este módulo puede traducir 765 frases en 7 idiomas: brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
Módulo con interno error Módulo con error del uso Módulo con error Módulo con interno error Módulo con error del uso Módulo con error
Vous devez supprimer cette documentation avant d'enregistrer.
Supprimez tous les modes pour revenir en mode read.
Internal error : no source or no known arguments !
Internal error : no source or no known arguments !
Assistance sur les paramètres de ce modèle :
⦁ translate_translations_key_missing
⦁ docDropBoxTitle
⦁ Mathroman2
⦁ TestRequire
⦁ Ce module peut traduire 765 phrases en 7 langues : brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
Module avec erreur interne Module avec erreur d'utilisation Module avec erreur Module avec erreur interne Module avec erreur d'utilisation Module avec erreur
Some live examples
Examples of modules and their uses in live demo in debug phase:
- Module:Central-s-fr, Module:Central-s-fr/Documentation, Module:Author3
- Utilisateur:Rical/Victor_Hugo with tests.
Central Normal mode example
{{Central | read }}
- versioning.bind_main_module_and_i18n()
Central Doc mode example
{{Central | doc | dockey = versioning_sort_central_modules_title | itemid = Q535 }}
- , modes.mode_options = nobox noerr nocat , modes.invoke_options =
versioning.sort_central_modules_report() Sorted list of central modules and libraries.
- versioning.sort_central_modules_report() -- Sorted list of central modules and libraries.
- versioning.loaded_modules_track : , #versioning.loaded_modules_and_libraries = 11
Title | Version | Date | Translations / Languages |
---|---|---|---|
Module:Central-mw-en | Central-mw-en | 2019-11-30 04:58 v191130 in:xx |
this: + 192/3 T/L, |
Library:begin | begin | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 336/7 T/L, |
Library:datas | datas | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 84/3 T/L, |
Library:events | events | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 104/3 T/L, |
Library:luaTable | luaTable | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 108/3 T/L, |
Library:mathroman | mathroman | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 96/3 T/L, |
Library:modes | modes | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 503/3 T/L, |
Library:testsCases | testsCases | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 96/3 T/L, |
Library:translate | translate | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 187/3 T/L, |
Library:versioning | versioning | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 606/7 T/L, |
Library:viewer | viewer | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 108/3 T/L, |
versioning.antiCrash_tests() selector=nocontent
- Test viewer.simpleList(list, sep1, sep2, sep3):
- Remove repeats in a string list with separators. Can also sort.
input | sep1 | sep2 | sep3 | sep4 | output |
---|---|---|---|---|---|
"abc;def;abc" | ";" | "-" | " | nil | "abc;def" |
"xyz;def;abc" | ";" | "sort" | nil | nil | "xyz;def;abc" |
"abc-def=abc" | "-" | "=" | nil | nil | "abc-def=abc" |
"abc - def = abc" | "-" | "=" | "sort" | nil | "abc - def = abc" |
"abc - def = abc" | "-" | "=" | "sort" | "trim" | "abc - def = abc" |
";;" | ";" | ";" | "," | nil | "" |
"abc/def;abc" | ";" | "/" | nil | nil | "abc/def;abc" |
"abc;def/abc/def;abc;def;abc" | ";" | "/" | "-" | nil | "abc;def/abc/def;def" |
"abc;def;abc" | ";" | ";" | "" | nil | "abc;def" |
English user / French wiki, Edit mode example
{{Central | edit | userlang= en | wikilang= fr | itemid = Q535 }}
- versioning.bind_main_module_and_i18n()
Remove all modes to return to read mode.
Support desk for Central-s-fr 03 22:57 : 765 translations in 7 languages
- Discreet main version: Central-s-fr 03 22:57This module can translate 765 sentences into 7 languages: brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
- Start versions from main module: bind_verif_modules_report_start missing
- Versions management_details:
, sought_report = Central-s-fr;Mathroman2;TestRequire
, known_report = Central-s-fr;Central-14 * Mathroman2;Mathroman34 * TestRequire;TestRequ * TestBug;TestBug4
To understand:
, loaded_report =
, used_report =
, missing_report = Mathroman2;TestRequire;
, replaced_report = ;
, unknown_report = Mathroman2;TestRequire;; - versioning.sort_central_modules_report() -- Sorted list of central modules and libraries.
- versioning.loaded_modules_track : , #versioning.loaded_modules_and_libraries = 11
Title | Version | Date | Translations / Languages |
---|---|---|---|
Module:Central-mw-en | Central-mw-en | 2019-11-30 04:58 v191130 in:xx |
this: + 192/3 T/L, |
Library:begin | begin | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 336/7 T/L, |
Library:datas | datas | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 84/3 T/L, |
Library:events | events | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 104/3 T/L, |
Library:luaTable | luaTable | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 108/3 T/L, |
Library:mathroman | mathroman | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 96/3 T/L, |
Library:modes | modes | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 503/3 T/L, |
Library:testsCases | testsCases | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 96/3 T/L, |
Library:translate | translate | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 187/3 T/L, |
Library:versioning | versioning | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 606/7 T/L, |
Library:viewer | viewer | 2024-11-14 00:37 v-14 00:37 in:LD |
this: + 108/3 T/L, |
- , Local MediaWiki version = 1.35.0
- . Modules: , Main module = Module:Central-mw-en , Proto version = Central-s-fr , Modules in this wiki = 428
- Users activities: , activeUsers = 1 , Administrators(sysop) = 4 , bots(bot) = 1 , patrollers(patroller) = 0 , bureaucrats(bureaucrat) = 18
- Statistics on users and content mw mw:Special:ListGroupRights
- Last revision: , REVISIONTIMESTAMP = 20191130045843 , REVISIONUSER = Joelmartin
- Languages: , PAGELANGUAGE = en , CONTENTLANGUAGE = en
- User language: , USERLANG = Template:USERLANG , UILANGCODE = ⧼lang⧽ , USERLANG = Template:USERLANG , USERLANGUAGE = Template:USERLANGUAGE , USERIFCODE = Template:USERIFCODE
- Scribunto: , Extension:Scribunto , Lua manual , version: = Lua 5.1
- Server mw.uri.new: , protocol = http , user = nil , password = nil , host = OCRobotx.org , port = nil , path = /mediawiki/index.php/Module:Central-mw-en , query = nil , fragment = nil , userInfo = nil , hostPort = OCRobotx.org , authority = OCRobotx.org , queryString = nil , relativePath = /mediawiki/index.php/Module:Central-mw-en
- Execution time and page: 2024-11-14 00:37:33 UTC , url = http://OCRobotx.org/mediawiki/index.php/Module:Central-mw-en
- Running times: , start in page = 320 mS , import + 0 mS , form result + 0 mS , tests + 0 mS , duration = 0 mS
⦁ translate_translations_key_missing
⦁ docDropBoxTitle
⦁ Mathroman2
⦁ TestRequire
⦁ This module can translate 765 sentences into 7 languages: brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
Spanish user / French wiki, Edit mode example
{{Central | edit | userlang= es | wikilang= fr | itemid = Q535 }}
- versioning.bind_main_module_and_i18n()
Retire todos los modos para volver al modo read.
De apoyo de oficina para Central-s-fr 03 22:57 : 765 traducciones en 7 idiomas
- Discreet main version: Central-s-fr 03 22:57Este módulo puede traducir 765 frases en 7 idiomas: brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
- Start versions from main module: bind_verif_modules_report_start missing
- Versions management_details:
, sought_report = Central-s-fr;Mathroman2;TestRequire
, known_report = Central-s-fr;Central-14 * Mathroman2;Mathroman34 * TestRequire;TestRequ * TestBug;TestBug4
To understand:
, loaded_report =
, used_report =
, missing_report = Mathroman2;TestRequire;
, replaced_report = ;
, unknown_report = Mathroman2;TestRequire;; - versioning.sort_central_modules_report() -- Sorted list of central modules and libraries.
- versioning.loaded_modules_track : , #versioning.loaded_modules_and_libraries = 11
Título | Versión | Fecha | Traducciones / Idiomas |
---|---|---|---|
Module:Central-mw-en | Central-mw-en | 2019-11-30 04:58 v191130 in:xx |
esta + 192/3 T/I, |
Library:begin | begin | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 336/7 T/I, |
Library:datas | datas | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 84/3 T/I, |
Library:events | events | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 104/3 T/I, |
Library:luaTable | luaTable | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 108/3 T/I, |
Library:mathroman | mathroman | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 96/3 T/I, |
Library:modes | modes | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 503/3 T/I, |
Library:testsCases | testsCases | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 96/3 T/I, |
Library:translate | translate | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 187/3 T/I, |
Library:versioning | versioning | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 606/7 T/I, |
Library:viewer | viewer | 2024-11-14 00:37 v-14 00:37 in:LD |
esta + 108/3 T/I, |
- , Local MediaWiki version = 1.35.0
- . Modules: , Main module = Module:Central-mw-en , Proto version = Central-s-fr , Modules in this wiki = 428
- Users activities: , activeUsers = 1 , Administrators(sysop) = 4 , bots(bot) = 1 , patrollers(patroller) = 0 , bureaucrats(bureaucrat) = 18
- Statistics on users and content mw mw:Special:ListGroupRights
- Last revision: , REVISIONTIMESTAMP = 20191130045843 , REVISIONUSER = Joelmartin
- Languages: , PAGELANGUAGE = en , CONTENTLANGUAGE = en
- User language: , USERLANG = Template:USERLANG , UILANGCODE = ⧼lang⧽ , USERLANG = Template:USERLANG , USERLANGUAGE = Template:USERLANGUAGE , USERIFCODE = Template:USERIFCODE
- Scribunto: , Extension:Scribunto , Lua manual , version: = Lua 5.1
- Server mw.uri.new: , protocol = http , user = nil , password = nil , host = OCRobotx.org , port = nil , path = /mediawiki/index.php/Module:Central-mw-en , query = nil , fragment = nil , userInfo = nil , hostPort = OCRobotx.org , authority = OCRobotx.org , queryString = nil , relativePath = /mediawiki/index.php/Module:Central-mw-en
- Execution time and page: 2024-11-14 00:37:33 UTC , url = http://OCRobotx.org/mediawiki/index.php/Module:Central-mw-en
- Running times: , start in page = 410 mS , import + 0 mS , form result + 0 mS , tests + 0 mS , duration = 0 mS
⦁ translate_translations_key_missing
⦁ docDropBoxTitle
⦁ Mathroman2
⦁ TestRequire
⦁ Este módulo puede traducir 765 frases en 7 idiomas: brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
French user / English wiki, Edit mode example
{{Central | edit | userlang= fr |wikilang= en | itemid = Q535 }}
- versioning.bind_main_module_and_i18n()
Supprimez tous les modes pour revenir en mode read.
Bureau de support pour Central-s-fr 03 22:57 : 765 traductions en 7 langues
- Discreet main version: Central-s-fr 03 22:57Ce module peut traduire 765 phrases en 7 langues : brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
- Start versions from main module: bind_verif_modules_report_start missing
- Versions management_details:
, sought_report = Central-s-fr;Mathroman2;TestRequire
, known_report = Central-s-fr;Central-14 * Mathroman2;Mathroman34 * TestRequire;TestRequ * TestBug;TestBug4
To understand:
, loaded_report =
, used_report =
, missing_report = Mathroman2;TestRequire;
, replaced_report = ;
, unknown_report = Mathroman2;TestRequire;; - versioning.sort_central_modules_report() -- Sorted list of central modules and libraries.
- versioning.loaded_modules_track : , #versioning.loaded_modules_and_libraries = 11
Titre | Version | Date | Traductions / Langues |
---|---|---|---|
Module:Central-mw-en | Central-mw-en | 2019-11-30 04:58 v191130 in:xx |
ceci: + 192/3 T/L, |
Library:begin | begin | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 336/7 T/L, |
Library:datas | datas | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 84/3 T/L, |
Library:events | events | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 104/3 T/L, |
Library:luaTable | luaTable | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 108/3 T/L, |
Library:mathroman | mathroman | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 96/3 T/L, |
Library:modes | modes | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 503/3 T/L, |
Library:testsCases | testsCases | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 96/3 T/L, |
Library:translate | translate | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 187/3 T/L, |
Library:versioning | versioning | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 606/7 T/L, |
Library:viewer | viewer | 2024-11-14 00:37 v-14 00:37 in:LD |
ceci: + 108/3 T/L, |
- , Local MediaWiki version = 1.35.0
- . Modules: , Main module = Module:Central-mw-en , Proto version = Central-s-fr , Modules in this wiki = 428
- Users activities: , activeUsers = 1 , Administrators(sysop) = 4 , bots(bot) = 1 , patrollers(patroller) = 0 , bureaucrats(bureaucrat) = 18
- Statistics on users and content mw mw:Special:ListGroupRights
- Last revision: , REVISIONTIMESTAMP = 20191130045843 , REVISIONUSER = Joelmartin
- Languages: , PAGELANGUAGE = en , CONTENTLANGUAGE = en
- User language: , USERLANG = Template:USERLANG , UILANGCODE = ⧼lang⧽ , USERLANG = Template:USERLANG , USERLANGUAGE = Template:USERLANGUAGE , USERIFCODE = Template:USERIFCODE
- Scribunto: , Extension:Scribunto , Lua manual , version: = Lua 5.1
- Server mw.uri.new: , protocol = http , user = nil , password = nil , host = OCRobotx.org , port = nil , path = /mediawiki/index.php/Module:Central-mw-en , query = nil , fragment = nil , userInfo = nil , hostPort = OCRobotx.org , authority = OCRobotx.org , queryString = nil , relativePath = /mediawiki/index.php/Module:Central-mw-en
- Execution time and page: 2024-11-14 00:37:33 UTC , url = http://OCRobotx.org/mediawiki/index.php/Module:Central-mw-en
- Running times: , start in page = 510 mS , import + 0 mS , form result + 0 mS , tests + 0 mS , duration = 0 mS
⦁ translate_translations_key_missing
⦁ docDropBoxTitle
⦁ Mathroman2
⦁ TestRequire
⦁ Ce module peut traduire 765 phrases en 7 langues : brezhoneg(br=brezhoneg), Deutsch(de=Deutsch), English(en=English), español(es=español), français(fr=français), magyar(hu=magyar), Tiếng Việt(vi=Tiếng Việt),
Tests mode example
{{Central | tests | itemid = Q535 }} Lua error at line 9975: attempt to index field 'wikibase' (a nil value).
-- Tests pages using this module, to help to change the rigth page when edit it : -- Utilisateur:Rical/Central modules reference manual -- Utilisateur:Rical/Victor Hugo {{#invoke:p.v.version|read}} fr = French = Français = Français -- Module:Author3/Documentation {{#invoke:p.v.version|read}} fr = French = Français = Français -- Module:Central/Documentation {{#invoke:Central|read}} fr = French = Français = Français -- Usual pages for Translations -- Utilisateur:Rical/Victor Hugo -- Modulenn:Central-s-br/doc {{#invoke:Central-s-br|read}} br = Breton = Brezhoneg -- Modul:Central-s-de/Doku {{#invoke:Central-s-de|read}} de = German = Deutsch -- Module:Central-s-en/Documentation {{#invoke:Central-s-en|read}} en = English = English -- Module:Central-s-es/Documentación {{#invoke:Central-s-es|read}} es = Spanish = español -- Module:Central-s-fr/Documentation {{#invoke:Central-s-fr|read}} fr = French = Français -- Modul:Central-w-hu/doc {{#invoke:Central-w-hu|read}} hu = Hungarian = Magyar -- Module:Central-mw-en/doc", {{#invoke:Central-mw-en|read}} en = English = English -- Mô đun:Central-w-vi/tài liệu {{#invoke:Central-w-vi|read}} vi = Vietnamese = Tiếng việt -- MediaWiki:Scribunto/Central modules reference manual local p = {} p.v = {} -- Version descriptor for central modules updated by versioning.get_one_module_or_library() p.v.version = "p.v.version" -- The main module select this version, from its p.versions{}, to replace its main version. p.v.version = "[[w:vi:Central-s-vi]]" -- The main module select this version, from its p.versions{}, to replace its main version. p.v.version = "Central-s-fr" -- The main module select this version, from its p.versions{}, to replace its main version. p.v.main_version = "Central" -- Central modules share the main version from the central repositoty to any projects. -- Later, versioning.get_one_module_or_library() -- Get a module or a library, then form and record its descriptor. local Central = p p.Module_Central_version = "p.v.version" -- To adapt the version of Module:Central in any translated text. p.ModuleNS = mw.site.namespaces.Module.name .. ":" p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module. versionName = "Central-s-fr", versionNumber = "03 22:57", versionDate = "2017-04-03 22:57", sought = "Central-s-fr;Mathroman2;TestRequire", -- Sought module and submodules versions known = "Central-s-fr;Central-14 * Mathroman2;Mathroman34 * TestRequire;TestRequ * TestBug;TestBug4", -- Known module and submodules versions -- known = "Central-s-fr;p.v.version;ControlArgs1;Mathroman2;TestRequire;TestBug;Testpages", -- Known module and submodules versions -- loaded_list = ";Central;p.v.version;",-- Module:Central -- currentVersion = "", -- show if the mediawiki version has change ( for debug ) -- Central.fr.ws is in conflict with LUA syntax table.intable.subtable and results in overflow at runtime. -- Then Rical renames Central.fr.ws in Central-s-fr at 16 decembre 2016-12-16 18:03. } -- Todo: Modèle:DP-ONU-Auteur, see: https://fr.wikisource.org/wiki/Mod%C3%A8le:DP-ONU -- rights_values_box_70 -- Todo: Tpt 20121005 19:48 : J'ai intégré le microformat hcard dans le modèle auteur afin de pouvoir y ajouter l'image. -- Todo: Tpt 20121005 19:48 : Par contre, j'ai ajouté deux lignes incluant de manière caché les dates de naissance et de décès directement dans le modèle auteur. -- Todo: Tpt 20121005 19:48 : Voici la diff. Pourrais-tu les intégrer dans un des sous-modèles que tu as créés pour la manipulation des dates avec la structure suivante : -- Todo: Tpt 20121005 19:48 : <span class="(b|d)day" title="DATE AU FORMAT YYYY">AFFICHAGE DE LA DATE</span> Tpt (d) 5 septembre 2012 à 19:48 (UTC) -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- Development guide line for modules -- -- For an easier and faster work, group several modules and libraries and their tests simulations in the same true module. -- Whith several modules and libraries in 1 module, we can move and change variables and functions, several at once. -- Simulate libraries in _G space, waiting a true implementation. -- There is a bug report by Rical: T122752 : #invoke do not record the main module in package.loaded. -- https://phabricator.wikimedia.org/T122752 Rical created this task.Via Web ·Sat, Jan 2, 2016-01-02 23:08 -- Simulate Modules in _G space, waiting the DEBUG of T122752#invoke. -- Simulate old and new versions of modules and libraries to satisfy the main module calls until need to change it. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- Development guide line for i18n translations -- -- A central module could need a translation service and a versioning service to enhance its functions or its stability without disturbing the preview normal use. -- A main module can define its sought sub-modules versions names and its known sub-modules versions names. -- The Library:versioning installs other libraries, supports versions, binds modules, libraries and i18n translations. -- A central module and its translations can inpedendently change. Its p.versions{} identifications change also. -- For this goal a module contains at least one i18n tranlations table. Its /I18N sub-modules contains translations in several languages. -- Central Libraries, like modules, contain their own p.versions{} identifications and i18n translations in Module:Library/library_name/I18N. -- The adaptation to any number of languages is automatic. -- The highest level is the main module. The lowest level is the libraries level. -- -- Any module or library can contain i18n tables. -- i18n tables are mixed from the lowest to the highest level, to permit at upper module to adapt the meaning of texts to a new use. -- Each library is independent of other ones and they can be mixed in any order. -- To avoid conflict of translations keys between libraries, all translations keys names start with the library name. -- -- The library testsCases contains internal auto tests cases to verify or to understand the functions and the use cases. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The central system based on MediaWiki makes it easy to embed wikicontent. -- The central system permit to convert any module as versioning.central_ It is build on Mediawiki, Scribunto and Wikibase. -- Here the Module:Central declares some libraries, waiting stable Scribunto central libraries: begin = {} -- The Library:begin begins to support other tests wikis. It translates tests pages names for these wikis. datas = {} -- The Library:datas form some viewers for tables(in lines and columns), dropboxes, luatables... events = {} -- The Library:events form events like erros, warnings and categories. luaTable = {} -- The Library:luaTable enhances previous table library, to avoid ambiguities. To enhance, we could write here : luaTable = table. modes = {} -- The Library:modes support modes and their options, like p.read(frame). -- texts = {} -- The Library:texts come from Scribunto. The Module:Central add some functions to it. testsCases = {} -- The Library:testsCases implements recursive mediawiki tests cases and reports them for Lua coders. texts = {} -- The Library:texts supports i18n translations. -- tools = {} -- The Library:tools supports micenalous functions for arguments, translations, reports on other processes... translate = {} -- The Library:translate supports i18n translations. -- versioning = {} -- The Library:versioning installs other libraries, bind modules and libraries, bind i18n translations, manage versions. -- versioning = {} -- The Library:versioning must stay in _G global space, to not change in init phase. viewer = {} -- The Library:viewer form some viewers for tables(in lines and columns), dropboxes, luatables... -- mathroman = {} -- The Library:mathroman is here as an example of very small central library. It becomes central using the central modules system. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:begin begins to support other tests wikis. It translates tests pages names for these wikis. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- --[[ == Central modules == https://vi.wikipedia.org/wiki/Th%E1%BA%A3o_lu%E1%BA%ADn_Th%C3%A0nh_vi%C3%AAn:Rical#Hoan_ngh.C3.AAnh :Thanks [ [Thành viên:Lê Thy|Lê Thy] ] to welcome me. I work on [ [ :s:fr:Module:Central-s-fr/Documentation | central modules(example) ] ] and I an near to ask to some admins in different languages/project to use these central modules. See their [ [ :s:fr:Utilisateur:Rical/Central_modules | documentation] ]. :The first step to use central module is to install one (I already done that in this wiki) and to translate some sentence. :Of course I will support you to understand any point you need. :And I also collect any point and any change in modules to enhance them. :Then I invite you to do so. Thanks for your attention and probably your cooperation. :I must find 10 admins in 10 wikis and in 10 languages. Look at Library:Begin in the example page. :If you want we could speak french. --Rical (thảo luận) 22:05, ngày 11 tháng 4 năm 2017 (UTC) 20170711 22:05 --]] -- begin = {} -- already declared by Scribunto, else in _G space. -- Translations for datas library begin.i18n = {} begin.i18n.br = { -- br = Breton = Brezhoneg -- Modulenn:Central-s-br/doc {{#invoke:Central-s-br|read}} br = Breton = Brezhoneg begin_translate_texts_guide = "Pour traduire, ne traduisez pas les parties comme celles-ci : <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", begin_Module_Central_central_version = "Modulenn:Central", begin_Module_Central_local_version = "Modulenn:p.v.version", begin_Module_Central_local_document = "Modulenn:p.v.version/doc", begin_Library_translate_I18N = "Modulenn:Library/translate/I18N", begin_Central_modules_reference_manual = "Scribunto/Lua reference manual", begin_support_central_modules_title = "begin.support_begin_central_modules() Support du début d'utilisation des modules centraux.", begin_support_central_modules_headers = "%1 Projets; %2 Langues; Admins; Actifs; %3 Modules principaux; doc; Installé; Utilisé; %4 Utilisateurs", begin_survey_sub_tasks_title = "begin.survey_sub_tasks(t) Surveiller l'état actuel des sous-tâches", begin_central_count_admins_active_users = "Ce site, br.wikisource.org, compte %1 administrateurs pour %2 utilisateurs actifs.", begin_links_to_central_modules_title = "begin.links_to_central_modules() Links to begin with central modules.", begin_links_to_central_modules_headers = "Project; Admins; Active users; Language; Code; Version; Documentation", } -- begin.i18n.br begin.i18n.de = { -- de = German = Deutsche -- Modul:Central-s-de/Doku {{#invoke:Central-s-de|read}} de = German = Deutsch begin_translate_texts_guide = "Zu übersetzen, übersetzen keine Teile wie diese : <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", begin_Module_Central_central_version = "Modul:Central", begin_Module_Central_local_version = "Modul:p.v.version", begin_Module_Central_local_document = "Modul:p.v.version/Doku", begin_Library_translate_I18N = "Modul:Library/translate/I18N", begin_Central_modules_reference_manual = "Scribunto/Central modules reference manual", begin_support_central_modules_title = "begin.support_begin_central_modules() Unterstützung des Beginns der Nutzung von zentralen Modulen.", begin_support_central_modules_headers = "%1 Projekts; %2 Spraches; Admins; Vermögenswerte; %3 Hauptmoduls ; doc; Starten; verwendet; %4 Benutzers", begin_survey_sub_tasks_title = "begin.survey_sub_tasks(t) Überwachen Sie den aktuellen Stand der subtasks", begin_central_count_admins_active_users = "Für diese Seite, br.wikisource.org, Konto 1% Direktoren für %2 aktive Nutzer.", begin_links_to_central_modules_title = "begin.links_to_central_modules() Links zu zentralen Module Debüt.", begin_links_to_central_modules_headers = "Projekt; Direktoren; Vermögenswerte; Sprache; Code; Version; Dokumentation", } -- begin.i18n.de begin.i18n.en = { -- en = English = English begin_translate_texts_guide = "To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", begin_Module_Central_central_version = "Mô đun:Central", begin_Module_Central_local_version = "Mô đun:p.v.version", begin_Module_Central_local_document = "Mô đun:p.v.version/Documentation", begin_Library_translate_I18N = "Mô đun:Library/translate/I18N", begin_Central_modules_reference_manual = "Scribunto/Central modules reference manual", begin_support_central_modules_title = "begin.support_begin_central_modules() Support of the start of use of central modules.", begin_support_central_modules_headers = "%1 Projects; %2 Languages; Admins; Assets; %3 Main modules; doc; Start on; Used from; %4 Users", begin_survey_sub_tasks_title = "begin.survey_sub_tasks(t) Monitor the current state of subtasks", begin_central_count_admins_active_users = "This site, br.wikisource.org, count %1 administrators for %2 active users.", begin_links_to_central_modules_title = "begin.links_to_central_modules() Links to begin with central modules.", begin_links_to_central_modules_headers = "Project; Admins; Active users; Language; Code; Version; Documentation", } -- begin.i18n.en begin.i18n.es = { -- es = Spanish = español -- Módulo:Central-s-es/Documentación {{#invoke:Central-s-es|read}} es = Spanish = español begin_translate_texts_guide = "Para traducir, no traducir partes como estas: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", begin_Module_Central_central_version = "Módulo:Central", begin_Module_Central_local_version = "Módulo:p.v.version", begin_Module_Central_local_document = "Módulo:p.v.version/Documentación", begin_Library_translate_I18N = "Módulo:Library/translate/I18N", begin_Central_modules_reference_manual = "Scribunto/Central modules reference manual", begin_support_central_modules_title = "begin.support_begin_central_modules() Apoyo del inicio del uso de módulos centrales.", begin_support_central_modules_headers = "%1 Proyectos; %2 Lenguajes; Admins; Activos; %3 Módulos principals; doc; Iniciar en; Utilizado desde; %4 Usuarios", begin_survey_sub_tasks_title = "begin.survey_sub_tasks(t) Monitorear el estado actual de subtareas", begin_central_count_admins_active_users = "Este sitio, br.wikisource.org, cuenta %1 administradores para %2 usuarios activos.", begin_links_to_central_modules_title = "begin.links_to_central_modules() Enlaces a de inicios de módulos centrales.", begin_links_to_central_modules_headers = "Proyecto; Administradores; Usuarios activos; Idioma; doc; Versión; Documentación", } -- begin.i18n.es begin.i18n.fr = { -- fr = French = Français begin_translate_texts_guide = "Pour traduire, ne traduisez pas les parties comme celles-ci : <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", begin_Module_Central_central_version = "Module:Central", begin_Module_Central_local_version = "Module:p.v.version", begin_Module_Central_local_document = "Module:p.v.version/Documentation", begin_Library_translate_I18N = "Module:Library/translate/I18N", begin_Central_modules_reference_manual = "Scribunto/Central modules reference manual", begin_support_central_modules_title = "begin.support_begin_central_modules() Support du début d'utilisation des modules centraux.", begin_support_central_modules_headers = "%1 Projets; %2 Langues; Admins; Actifs; %3 Modules principaux; doc; Installé; Utilisé; %4 Utilisateurs", begin_survey_sub_tasks_title = "begin.survey_sub_tasks(t) Surveiller l'état actuel des sous-tâches", begin_central_count_admins_active_users = "Ce site, fr.wikisource.org, compte %1 administrateurs pour %2 utilisateurs actifs.", begin_links_to_central_modules_title = "begin.links_to_central_modules() Liens vers des débuts de modules centraux.", begin_links_to_central_modules_headers = "Projet; Administrateurs; Utilisateurs actifs; %1 Langue; Code; Version; Documentation", } -- begin.i18n.fr begin.i18n.hu = { -- hu = Hungarian = Magyar -- Il n'y a aucun module dans l'espace module Modul:Central-w-hu/doc {{#invoke:Central-w-hu|read}} begin_translate_texts_guide = "Töltsd le a szöveget, és nyomd le a partit a cellák között: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", begin_Module_Central_central_version = "Modul:Central", begin_Module_Central_local_version = "Modul:p.v.version", begin_Module_Central_local_document = "Modul:p.v.version/doc", begin_Library_translate_I18N = "Modul:Library/translate/I18N", begin_Central_modules_reference_manual = "Scribunto/Central modules reference manual", begin_support_central_modules_title = "begin.support_begin_central_modules() A központi modulok használatának megkezdésének támogatása", begin_support_central_modules_headers = "%1 Projekts; %2 Nyelvs; Adminok; Eszközöket; %3 Fő moduls; doc; Kezdés; Használt; %4 Használós", begin_survey_sub_tasks_title = "begin.survey_sub_tasks(t) Kíséri a jelenlegi állapotában részfeladatok", begin_central_count_admins_active_users = "Ez az oldal, br.wikisource.org, fiók %1 rendszergazdák és %2 felhasználók aktív.", begin_links_to_central_modules_title = "begin.links_to_central_modules() Hivatkozások központi modulok debütált.", begin_links_to_central_modules_headers = "Projekt; Igazgatók; Aktív felhasználók számára; Nyelv; Kód; Verzió; Dokumentáció", } -- begin.i18n.hu begin.i18n.vi = { -- vi = Vietnamese = Tiếng việt begin_translate_texts_guide = "Để dịch, không dịch các phần như thế này : <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", begin_Module_Central_central_version = "Mô đun:Central", begin_Module_Central_local_version = "Mô đun:p.v.version", begin_Module_Central_local_document = "Mô đun:p.v.version/Documentation", begin_Library_translate_I18N = "Mô đun:Library/translate/I18N", begin_Central_modules_reference_manual = "Scribunto/Central modules reference manual", begin_support_central_modules_title = "begin.support_begin_central_modules() Quan trắc việc dùng sớm của mô-đun lõi.", begin_support_central_modules_headers = "%1 Dự án; %2 Ngôn ngữ; Quản trị viên; Tài sản; %3 Mô đun chính; doc; Bắt đầu; Dược sử dụng; %4 sNgười sử dụng", begin_survey_sub_tasks_title = "begin.survey_sub_tasks(t) Theo dõi tình trạng hiện tại của subtasks", begin_central_count_admins_active_users = "Trang web này, Br.wikisource.org có %1 quản trị viên cho %2 người dùng hoạt động.", begin_links_to_central_modules_title = "begin.links_to_central_modules() Liên kết đến sự khởi đầu của module trung tâm.", begin_links_to_central_modules_headers = "dự án; quản trị; tài sản; ngôn ngữ; mã; phiên bản; tài liệu", -- -- Mô đun:Central-s-vi/tài liệu {{#invoke:Central-s-vi|read}} } -- begin.i18n.vi begin.proto_version = "Central-s-fr" begin.known_wikis = { -- br.wikisource.org/wiki/Modulenn:Central-s-br/doc {{#invoke:Central-s-br|read}} fr = Breton = Breton = Breitz { url_doc = "br.wikisource.org/wiki/Modulenn:Central-s-br/doc", enforce_main_version = "br.wikisource.org", beginon = "20170305", usedfrom = "20170330 ?", user = "VIGNERON", template = "Modèle", admins = "16", assets = "236", -- 16 administrators for 236 -- hostPort = "br.wikisource.org", project = "s", lang = "br", doc = "doc", -- template = "Modèle", moduleSpace = "Modulenn", modulename = "Central-s-br", }, -- de.wikisource.org/wiki/Modul:Central-s-de/Doku {{#invoke:Central-s-de|read}} de = German = Deutsch { url_doc = "de.wikisource.org/wiki/Modul:Central-s-de/Doku", enforce_main_version = "de.wikisource.org", beginon = "20170405 ?", usedfrom = "20170430 ?", user = "Wer?", template = "Modèle", admins = "16 ?", assets = "236 ?", -- 16 administrators for 236 -- hostPort = "de.wikisource.org", project = "s", lang = "de", doc = "Doku", -- moduleSpace = "Modul", modulename = "Central-s-de", }, -- en.wikipedia.org/wiki/Module:Central-w-en/Documentation {{#invoke:Central-w-en|read}} en = English = English { url_doc = "en.wikipedia.org/wiki/Module:Central-w-en/Documentation", enforce_main_version = "en.wikipedia.org", beginon = "20170215 ?", usedfrom = "20170304 ?", user = "Who?", template = "Modèle", admins = "16 ?", assets = "236 ?", -- 16 administrators for 236 active users -- hostPort = 'en.wikipedia.org', project = "w", lang = "en", doc = "Documentation", -- vers = "Central-w-en", centralmodule = "Module:Central-w-en", centraldoc = "Module:Central-w-en/Documentation", }, -- es.wikipedia.org/wiki/Módulo:Central-w-es/Documentación {{#invoke:Central-w-es|read}} es = Spanish = español { url_doc = "es.wikipedia.org/wiki/Módulo:Central-w-es/Documentación", enforce_main_version = "es.wikisource.org", beginon = "20170215 ?", usedfrom = "20170304 ?", user = "¿Quién?", template = "Modèle", admins = "16 ?", assets = "236 ?", -- 16 administrators for 236 active users -- hostPort = 'es.wikipedia.org', project = "w", lang = "es", doc = "Documentación", -- vers = "Central-w-es", centralmodule = "Módulo:Central-w-es", centraldoc = "Módulo: Central-w-es/Documentación", }, -- fr.wikisource.org/wiki/Module:Central-s-fr/Documentation {{#invoke:Central-s-fr|read}} fr = French = Français { url_doc = "fr.wikisource.org/wiki/Module:Central-s-fr/Documentation", enforce_main_version = "fr.wikisource.org", beginon = "20170215", usedfrom = "20170304 ?", user = "Rical", template = "Modèle", admins = "16", assets = "294", -- 16 administrators for 236 active users -- hostPort = "fr.wikisource.org", project = "s", lang = "fr", doc = "Documentation", -- moduleSpace = "Module", modulename = "Central-s-fr", }, -- hu.wikipedia.org/wiki/Modul:Central-w-hu/doc {{#invoke:Central-w-hu|read}} hu = Hungarian = Magyar { url_doc = "hu.wikipedia.org/wiki/Modul:Central-w-hu/doc", enforce_main_version = "hu.wikipedia.org", beginon = "20170505 ?", usedfrom = "20170530 ?", user = "Ki?", template = "Modul", admins = "23", assets = "1513", -- 23 administrators for 1513 active users -- moduleSpace = "Modul", modulename = "Central-w-hu", }, -- https://phabricator.wikimedia.org/T135845 = T135845 = Convert any module as central or centralisable -- https://www.mediawiki.org/wiki/Module:Central-mw-en {{#invoke:Central-mw-en|read}} en = English = English { url_doc = "www.mediawiki.org/wiki/Module:Central-mw-en/doc", enforce_main_version = "www.mediawiki.org", beginon = "20170427", usedfrom = "20170505", user = "Rical", template = "Template", admins = "184", assets = "1215", -- 184 administrators for 1215 active users on 20170427 -- moduleSpace = "Modul", modulename = "Central-w-hu", -- hostPort = "hu.wikipedia.org", proj = "w", lang = "hu", doc = "doc", }, -- vi.wikipedia.org/wiki/Mô đun:Central-w-vi/tài liệu {{#invoke:Central-w-vi|read}} vi = Vietnamese = Tiếng Việt { url_doc = "vi.wikipedia.org/wiki/Mô đun:Central-w-vi/tài liệu", enforce_main_version = "vi.wikipedia.org", beginon = "20170412 ?", usedfrom = "20170530 ?", user = "Lê Thy ?", template = "Modèle", admins = "23", assets = "1513", -- 23 administrators for 1513 active users -- hostPort = "vi.wikipedia.org", proj = "w", lang = "vi", doc = "tài liệu", -- moduleSpace = "Mô đun", modulename = "Central-w-vi", }, } begin.wikis_names = { b = 'wikibooks', cm = 'commons', meta = 'meta', mw = 'mediawiki', n = 'wikinews', p = 'wiki', q = 'wikiquote', s = 'wikisource', species = 'species', t = 'wiktionary', test2 = 'test2', v = 'wikiversity', wm = 'wikimedia', y = 'wikivoyage', } -- begin.wikis_names begin.kiwis_names = { commons = 'cm', meta = 'meta', mediawiki = 'mw', species = 'species', test2 = 'test2', wiki = 'p', wikibooks = 'b', wikimedia = 'wm', wikinews = 'n', wikiquote = 'q', wikisource = 's', wikiversity = 'v', wikivoyage = 'y', wiktionary = 't', } function begin.central_module_descriptor(known_wikis, selector) -- Adapt this main central module version to a kwnow wiki, in begin phase. if (type(known_wikis) ~= "table") then known_wikis = begin.known_wikis end local mwuri = mw.uri.new() local hostPort = mwuri.port local hostPort = mwuri.hostPort local hostPort = mwuri.host if type(selector ~= "string") then selector = hostPort end -- actual wiki as default for i, wiki in pairs(known_wikis) do if (type(wiki.url_doc) == "string") and viewer.is_in(selector, wiki.url_doc) then selected = wiki wiki.url_split = mw.text.split(wiki.url_doc, '/') -- fr ; wikisource ; org wiki.hostPort = wiki.url_split[1] -- fr.wikisource.org wiki.central_project_lang = mw.text.split(wiki.hostPort, '.') -- fr wikisource org if (type(wiki.enforce_main_version) == "string") then wiki.central_project_lang = wiki.enforce_main_version end wiki.lang = wiki.central_project_lang[1] or "fr" -- fr wiki.project = wiki.central_project_lang[2] or "wikisource" -- wikisource wiki.proj = begin.kiwis_names[wiki.project] -- or wiki.project -- s or wikisource wiki.hostPort = wiki.lang .. "." .. wiki.project .. ".org" -- fr.wikisource.org wiki.version = "Central-" .. wiki.proj .. "-" .. wiki.lang -- wiki.url_split = wiki.url_split[2] -- /wiki/ -- fr.wikisource.org/wiki/Module:Central-s-fr/Documentation wiki.mod_vers = wiki.url_split[3] -- Module:Central-s-fr wiki.mod_vers_split = mw.text.split(wiki.mod_vers, ':') -- Module ; Central-s-fr wiki.modulename = wiki.mod_vers_split[1] -- Module:Central-s-fr wiki.docname = wiki.url_split[4] -- Documentation wiki.link = "[[h_o_s_t:M_o_d_u_l_e:v_e_r_s_i_o_n|M_o_d_u_l_e:v_e_r_s_i_o_n]]" wiki.link = string.gsub(wiki.link, "v_e_r_s_i_o_n", wiki.version) wiki.link = string.gsub(wiki.link, "M_o_d_u_l_e", wiki.modulename) wiki.link = string.gsub(wiki.link, "h_o_s_t", ":" .. wiki.proj .. ":" .. wiki.lang) wiki.doc_link = "[[ :" .. wiki.proj .. ":" .. wiki.lang .. ":" .. wiki.modulename .. ":" .. wiki.version .. "/" .. wiki.docname .. " | doc ]]" end end return wiki end -- function begin.central_module_descriptor(known_wikis, selector) function begin.count_used_central_wikis(known_wikis) -- Count using of central modules in wikis, in begin phase. if (type(known_wikis) ~= "table") then known_wikis = begin.known_wikis end local project_T = {} local module_T = {} local lang_T = {} local user_T = {} local tabs = { project = {}, modulename = {}, lang = {}, user = {}, } local counts = { project = 0, modulename = 0, lang = 0, user = 0, } for field, n in pairs(counts) do for i, wiki in pairs(known_wikis) do if (type(wiki.project) == "string") then tabs.project[wiki.project] = wiki.project end if (type(wiki.modulename) == "string") then tabs.modulename[wiki.modulename] = wiki.modulename end if (type(wiki.lang) == "string") then tabs.lang[wiki.lang] = wiki.lang end if (type(wiki.user) == "string") then tabs.user[wiki.user] = wiki.user end end end counts.project = luaTable.level_count(tabs.project) counts.modulename = luaTable.level_count(tabs.modulename) counts.lang = luaTable.level_count(tabs.lang) counts.user = luaTable.level_count(tabs.user) return counts end -- function begin.count_used_central_wikis(known_wikis) function begin.init_a_wiki(wiki) -- Detail and re-build a wiki descriptor -- From a predefined descriptor, and from the url, and from enforce value. if type(wiki.url_doc) == "string" then wiki.url_split = mw.text.split(wiki.url_doc, '/') -- fr wikisource org wiki.hostPort = wiki.url_split[1] -- fr.wikisource.org -- wiki._wiki_ = wiki.url_split[2] -- /wiki/ wiki.mod_vers = wiki.url_split[3] -- Module:Central-s-fr wiki.doc_name = wiki.url_split[4] -- Documentation wiki.mod_space = wiki.mod_vers[1] -- Módulo wiki.central_proj_lang = wiki.mod_vers[2] -- "Central-s-fr" -- Re-build central_proj_lang if unknown if (type(wiki.central_proj_lang) ~= "string") and (type(wiki.hostPort) == "string") then -- fr.wikisource.org wiki.hostPort_split = mw.text.split(wiki.hostPort, '.') -- fr wikisource org wiki.lang_short = wiki.hostPort_split[1] -- fr wiki.proj_short = wiki.hostPort_split[2] -- wikisource wiki.proj_short = begin.kiwis_names[wiki.proj_short] or wiki.proj_short -- s = wikisource wiki.central_proj_lang = "Central-" .. wiki.proj_short .. "-" .. wiki.lang_short end end -- Activate if enforce_main_version if type(wiki.enforce_main_version) == "string" then wiki.central_proj_lang = wiki.enforce_main_version end --[[ p.v.version = "Central-s-fr" -- The main module select this version, from its p.versions{}, to replace its main version. p.v.main_version = "Central" -- Central modules share the main version from the central repositoty to any projects. p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module. versionName = "Central-s-fr", versionNumber = "03 22:57", versionDate = "2017-04-03 22:57", sought = "Central-s-fr;Mathroman2;TestRequire", -- Sought module and submodules versions known = "Central-s-fr;Mathroman2;TestRequire;TestBug", -- Known module and submodules versions } --]] p.v.version = wiki.central_proj_lang -- The main module select this version, from its p.versions{}, to replace its main version. p.versions.versionName = wiki.central_proj_lang -- The main module select this version, from its p.versions{}, to replace its main version. p.versions.sought = string.gsub(p.versions.sought or "-", begin.master_version or "-", wiki.central_proj_lang or "-") p.versions.known = string.gsub(p.versions.known or "-", begin.master_version or "-", wiki.central_proj_lang) or "-" return wiki end -- function begin.init_a_wiki(wiki) -- Detail and re-build a wiki descriptor function begin.init_selected_wiki(known_wikis, selector) -- Select the rigth wiki descriptor to init it. local wiki = begin.central_module_descriptor(known_wikis, selector) -- Adapt this main central module version to a kwnow wiki, in begin phase. --[[ p.v.version = "Central-s-fr" -- The main module select this version, from its p.versions{}, to replace its main version. p.v.main_version = "Central" -- Central modules share the main version from the central repositoty to any projects. p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module. versionName = "Central-s-fr", versionNumber = "03 22:57", versionDate = "2017-04-03 22:57", sought = "Central-s-fr;Mathroman2;TestRequire", -- Sought module and submodules versions known = "Central-s-fr;Mathroman2;TestRequire;TestBug", -- Known module and submodules versions } --]] -- wiki.central_proj_lang = wiki.enforce_main_version if (type(wiki) == "table") then p.v.version = wiki.version -- The main module select this version, from its p.versions{}, to replace its main version. p.versions.versionName = wiki.version -- The main module select this version, from its p.versions{}, to replace its main version. p.versions.sought = string.gsub(p.versions.sought or "-", begin.proto_version or "-", wiki.central_proj_lang or "-") p.versions.known = string.gsub(p.versions.known or "-", begin.proto_version or "-", wiki.central_proj_lang) or "-" end return wiki end -- function begin.init_selected_wiki(known_wikis, host_name) function begin.init_selected_wiki_test(t) -- begin.init_selected_wiki() Test some wiki inits. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>begin.init_selected_wiki()</b> Test some wiki inits :" if (type(known_wikis) ~= "table") then known_wikis = begin.known_wikis end local tabView = { testGroup = { { url_doc = "br.wikisource.org/wiki/Modulenn:Central-s-br/doc", what_to_test = "normal master central wiki", }, { url_doc = "fr.wikisource.org/wiki/Module:Central-s-fr/Documentation", master_version = "Central-s-fr", what_to_test = "abnormal hostPort central wiki", enforce_main_version = "Central-s-br", }, { url_doc = "hu.wikipedia.org/wiki/Module:Central-w-hu/doc", what_to_test = "normal other wiki", }, { url_doc = "vi.wikipedia.org/wiki/Mô đun:Central-w-vi/tài liệu", what_to_test = "abnormal hostPort other wiki", enforce_main_version = "Central-w-vi", }, }, headers = "what_to_test + url_doc ; hostPort; enforce_main_version; local version; master version", } t = t .. viewer.ta("#testGroup: ", #tabView.testGroup) function tabView.tableView_form_one_case(wiki) -- Convert a case from testGroup to rowGroup. wiki.url_split = mw.text.split(wiki.url_doc, '/') -- fr wikisource org wiki.hostPort = wiki.url_split[1] -- fr.wikisource.org local wiki = begin.init_selected_wiki(known_wikis, wiki.hostPort) -- normal master central wiki. local tocase = nil if (type(wiki) == "table") then tocase = { (wiki.what_to_test or "what_to_test") .. "<br>" .. wiki.url_doc, wiki.hostPort, wiki.enforce_main_version, wiki.central_proj_lang, wiki.master_version, } end return tocase end tabView.headers = "Project; Language; Admins; Assets; Main module; doc; Start on; Used from; User" tabView.headers = "what_to_test + url_doc ; hostPort; enforce_main_version; local version; master version" local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. local vers, url, urldoc, link = begin.links_to_central_modules("br.wikisource.org") -- Form links for standard central modules version in any wiki tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function begin.init_selected_wiki_test(known_wikis) function begin.init_central_versions(wiki, central, main, known_wikis) -- Automatic adaptation of central versions in main and central modules. --[[ GUIDE-LINE In the begin phase, the main version of each central test wiki follow the format "Central-s-fr". After this phase and when the central repository become stable, the format "Central-s-fr" is not needed. In debug phase, the format "Central-s-fr" is not needed for enough efficient Lua-coders. To emplement this guide-line init_central_versions() enforce the main version name if enforce_main_version is defined for a wiki. --]] -- local vers, url, urldoc, link = begin.links_to_central_modules() -- Form links for standard central modules version in any wiki -- See: $wmincProjectDatabases in https://www.mediawiki.org/wiki/Extension:WikimediaIncubator -- translate.Central_x_y = p.Central_x_y -- To adapt the version of Module:Central in any translated text. -- translate.Module_Central_version = p.Module_Central_version -- To adapt the version of Module:Central in any translated text. -- enforce_main_version = "Central-s-br", if type(wiki) ~= "table" then wiki = begin.wiki end if type(central) ~= "table" then central = begin.central end if type(main) ~= "table" then main = begin.main end if type(known_wikis) ~= "table" then known_wikis = begin.known_wikis end -- begin.ref = {} -- main reference of central versions begin.loc = {} -- local reference of central versions -- if type(id) ~= "string" then id = nil end local t, adr, val, proplabel = "", nil, nil, nil local wd = {} local wd_mng = {} -- wikidata manager local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>begin.links_to_central_modules()</b> : Form links for standard central modules version in any wiki." local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. local vers, url, urldoc, link = begin.links_to_central_modules("br.wikisource.org") -- Form links for standard central modules version in any wiki tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function begin.init_central_versions(central, main, wiki) function begin.support_begin_central_modules(t) -- Tests of main central modules local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>Tests of main central modules:</b> :" t = t .. "\n* " .. viewer.form9user("begin_central_count_admins_active_users", mw.site.stats.admins, mw.site.stats.activeUsers) t = t .. " - " .. translate.formTestCase("begin_central_count_admins_active_users", mw.site.stats.admins, mw.site.stats.activeUsers) --[[ Table holding site statistics. Available statistics are: mw.site.stats{} pages: Number of pages in the wiki. articles: Number of articles in the wiki. files: Number of files in the wiki. edits: Number of edits in the wiki. views: Number of views in the wiki. Not available if $wgDisableCounters is set. users: Number of users in the wiki. activeUsers: Number of active users in the wiki. admins: Number of users in group 'sysop' in the wiki. --]] local tabView = { testGroup = { -- https://en.wikipedia.org/wiki/Template:Central -- Modulenn:Central-s-br/doc {{#invoke:Central-s-br|read}} fr = Breton = Breton = Breitz { hostPort = "br.wikisource.org", project = "s", lang = "br", doc = "doc", admins = "16", assets = "236", -- 16 administrateurs pour 236 template = "Modèle", moduleSpace = "Modulenn", modulename = "Central-s-br", beginon = "20170305", usedfrom = "20170330 ?", user = "VIGNERON", }, -- https://en.wikipedia.org/wiki/Template:Central -- Modul:Central-s-de/Documentation {{#invoke:Central-s-de|read}} de = German = Deutsch { hostPort = "de.wikisource.org", project = "s", lang = "de", doc = "Doku", admins = "16 ?", assets = "236 ?", -- 16 administrateurs pour 236 moduleSpace = "Modul", modulename = "Central-s-de", beginon = "20170405 ?", usedfrom = "20170430 ?", user = "Wer?", }, -- -- -- Module:Central-s-en/Documentation {{#invoke:Central-w-en|read}} en = English = English { hostPort = 'en.wikipedia.org', project = "w", lang = "en", moduleSpace = "Module", doc = "Documentation", vers = "Central-w-en", centralmodule = "Module:Central-w-en", centraldoc = "Module:Central-w-en/Documentation", admins = "16 ?", assets = "236 ?", beginon = "20170215 ?", usedfrom = "20170304 ?", user = "Who?", }, -- -- Module:Central-s-es/Documentación {{#invoke:Central-w-es|read}} es = Spanish = español { hostPort = 'es.wikipedia.org', project = "w", lang = "es", moduleSpace = "Módulo", doc = "Documentación", vers = "Central-w-es", centralmodule = "Módulo:Central-w-es", centraldoc = "Módulo: Central-w-es/Documentación", admins = "16 ?", assets = "236 ?", beginon = "20170215 ?", usedfrom = "20170304 ?", user = "¿Quién?", }, -- es = ¿Quién? -- -- -- https://fr.wikipedia.org/wiki/Modèle:Central -- Module:Central-s-fr/Documentation {{#invoke:Central-s-fr|read}} fr = French = Français = Français { hostPort = "fr.wikisource.org", project = "s", lang = "fr", doc = "Documentation", admins = "16", assets = "294", -- 16 administrateurs pour 236 template = "Modèle", moduleSpace = "Module", modulename = "Central-s-fr", beginon = "20170215", usedfrom = "20170304 ?", user = "Rical", }, -- https://hu.wikipedia.org/wiki/Sablon:Central -- Modul:Central-w-hu/doc {{#invoke:Central-w-hu|read}} hu = Hungarian = Magyar { hostPort = "hu.wikipedia.org", project = "w", lang = "hu", doc = "doc", admins = "23", assets = "1513", -- 23 administrateurs pour 1513 template = "Modèle", moduleSpace = "Modul", modulename = "Central-w-hu", beginon = "20170505 ?", usedfrom = "20170530 ?", user = "Ki?", }, -- https://vn.wikipedia.org/wiki/Sablon:Central -- Mô đun:Central-w-vi/tài liệu {{#invoke:Central-w-vi|read}} fr = Vietnamese = Vietnamien = Tiếng Việt { hostPort = "vi.wikipedia.org", project = "w", lang = "vi", doc = "tài liệu", admins = "23", assets = "1513", -- 23 administrateurs pour 1513 template = "Modèle", moduleSpace = "Mô đun", modulename = "Central-w-vi", beginon = "20170412 ?", usedfrom = "20170530 ?", user = "Lê Thy ?", }, }, testGroup = begin.known_wikis, headers = "begin_support_central_modules_headers", headers = "Project; Language; Admins; Assets; Main module; doc; Start on; Used from; User", } tabView.testGroup = begin.known_wikis tabView.all_cases = tabView.testGroup tabView.headers = "begin_support_central_modules_headers" -- local list, count, level, split = luaTable.level_list(tab, typ, select, field) -- Get only the first level of the table. -- Get only the first level of the table. Select only keys containing select. Select the field as key if defined. ---------------------------- t = (t or "") .. viewer.ta("support_central_modules: ", "start") t = t .. viewer.ta("#testGroup: ", #tabView.testGroup) function tabView.tableView_form_one_case(wiki) -- Generally to define: Convert a case from testGroup to rowGroup. -- local mwtitle = mw.title.getCurrentTitle() -- Count each column -- if (type(wiki.project) == "string") then wiki.project = wiki.project end -- if (type(wiki.modulename) == "string") then wiki.modulename = wiki.modulename end -- if (type(wiki.lang) == "string") then wiki.lang = wiki.lang end -- if (type(wiki.user) == "string") then wiki.user = wiki.user end return { wiki.project, wiki.lang, wiki.admins, wiki.assets, wiki.link, wiki.doc_link, wiki.beginon, wiki.usedfrom, wiki.user, } end tabView.headers = "Project; Language; Admins; Assets; Main module; doc; Start on; Used from; User" local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. local vers, url, urldoc, link = begin.links_to_central_modules("br.wikisource.org") -- Form links for standard central modules version in any wiki tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() t = (t or "") .. viewer.ta("support_central_modules: ", "end") ---------------------------- local list, count, level, split = luaTable.level_list(tabView.testGroup, "number") t = t .. "\n* <b>begin.follow_central_modules()</b> all. " .. viewer.form9user("There are <b>%1</b> cases in testGroup: <b>%2</b>", count, list) local interwikiMap = mw.site.interwikiMap() -- Returns a table holding data about available interwiki prefixes. -- t = t .. luaTable.roughView(interwikiMap, "string", "lang", "fr") --[[ interwikiMap examples : fr = { isProtocolRelative = false, ["prefix"] = "fr", isExtraLanguageLink = false, isTranscludable = false, url = "https://fr.wikisource.org/wiki/$1", isCurrentWiki = true, isLocal = true, } wurmpedia = { isProtocolRelative = false, ["prefix"] = "wurmpedia", isExtraLanguageLink = false, isTranscludable = false, url = "http://wurmpedia.com/index.php/$1", isCurrentWiki = false, isLocal = false, } w = { isProtocolRelative = false, ["prefix"] = "w", isExtraLanguageLink = false, isTranscludable = false, url = "https://fr.wikipedia.org/wiki/$1", isCurrentWiki = false, isLocal = true, } --]] t = t .. '\n* <b>interwikiMap</b> fr example: <b>fr</b> = { isProtocolRelative = false, ["prefix"] = "fr", isExtraLanguageLink = false, isTranscludable = false, url = "https://fr.wikisource.org/wiki/$1", isCurrentWiki = true, isLocal = true, }' t = t .. '\n* <b>interwikiMap</b> w example: <b>w</b> = { isProtocolRelative = false, ["prefix"] = "w", isExtraLanguageLink = false, isTranscludable = false, url = "https://fr.wikipedia.org/wiki/$1", isCurrentWiki = false, isLocal = true, }' local list, count, level, split = luaTable.level_list(interwikiMap, "string", "/vi.", "url") t = t .. "\n* <b>interwikiMap</b> selection: " .. viewer.form9user("There are <b>%1</b> in <b>%2</b> projects from interwikiMap: <b>%3</b>", count, "/vi.", "url") local list, count, level, split = luaTable.level_list(interwikiMap, "string", "/fr.", "url") t = t .. "\n* <b>interwikiMap</b> selection: " .. viewer.form9user("There are <b>%1</b> in <b>%2</b> projects from interwikiMap: <b>%3</b>", count, "/fr.", "url") local list, count, level, split = luaTable.level_list(interwikiMap, "string", "/fr.", "url") -- "There are wikisource projects in <b>%1</b> languages: <b>%2</b>", t = t .. "\n* <b>interwikiMap</b> selection: " .. viewer.form9user("There are <b>%1</b> in <b>%2</b> projects from interwikiMap: <b>%3</b>", count, ".s.", "url") local list, count, level, split = luaTable.level_list(interwikiMap, "string", "true") t = t .. "\n* <b>interwikiMap</b> all " .. count .. " keys: " .. list -- phab = phabricator --[[ interwikiMap selection: There are 751 Vietnamize projects in interwikiMap: //libreplanet.org/wiki/$1, //wiki.openstreetmap.org/wiki/$1, https://www.wikidata.org/wiki/$1, http://www.dmoz.org/cgi-bin/search?search=$1, https://wikimania.wikimedia.org/wiki/$1, http://www.EcoReality.org/wiki/$1, https://oc.wikisource.org/wiki/$1, https://phabricator.wikimedia.org/$1, -- p.ModuleNS = mw.site.namespaces.Module.name .. ":" -- local wiki_Module_space = mw.site.namespaces.Module.name -- name: Local namespace name. --]] events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- t = begin.support_begin_central_modules(t) function begin.links_to_central_modules(hostPort) -- Form links for standard central modules version in any wiki -- local vers, url, urldoc, link = begin.links_to_central_modules() -- Form links for standard central modules version in any wiki -- See: $wmincProjectDatabases in https://www.mediawiki.org/wiki/Extension:WikimediaIncubator -- translate.Central_x_y = p.Central_x_y -- To adapt the version of Module:Central in any translated text. -- translate.Module_Central_version = p.Module_Central_version -- To adapt the version of Module:Central in any translated text. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>begin.links_to_central_modules()</b> : Form links for standard central modules version in any wiki." t = t .. "\n* " .. viewer.form9user("begin_central_count_admins_active_users", mw.site.stats.admins, mw.site.stats.activeUsers) local wikis = { cm = 'commons', test2 = 'test2', p = 'wiki', b = 'wikibooks', wm = 'wikimedia', meta = 'meta', n = 'wikinews', q = 'wikiquote', s = 'wikisource', species = 'species', t = 'wiktionary', v = 'wikiversity', y = 'wikivoyage', } local kiwis = { commons = 'cm', test2 = 'test2', wiki = 'p', wikibooks = 'b', wikimedia = 'wm', meta = 'meta', wikinews = 'n', wikiquote = 'q', wikisource = 's', species = 'species', wiktionary = 't', wikiversity = 'v', wikivoyage = 'y', } -- tabView.testGroup local tabView = { testGroup = { -- español(es=Spanish), français(fr=French), Tiếng Việt(vi=Vietnamese), -- local Central_connections = { -- español(es=Spanish), français(fr=French), Tiếng Việt(vi=Vietnamese), -- -- Modulenn:Central-s-br/doc {{#invoke:Central-s-br|read}} br = Breton = Brezhoneg { hostPort = 'br.wikisource.org', moduleSpace = "Modulenn", doc = "doc", user = "VIGNERON", -- vers = "Central-w-br", centralmodule = "Modulenn:Central-w-br", centraldoc = "Modulenn:Central-w-br/doc", admins = "16 ?", assets = "236 ?", beginon = "20170215", usedfrom = "20170304 ?", update = "20170410", }, -- Modul:Central-s-de/Doku {{#invoke:Central-s-de|read}} de = German = Deutsch { hostPort = 'de.wikisource.org', moduleSpace = "Modul", doc = "Doku", user = "Wer?", -- vers = "Central-w-de", centralmodule = "Modul:Central-s-de", centraldoc = "Modul:Central-s-de/Doku", admins = "16 ?", assets = "236 ?", beginon = "20170215 ?", usedfrom = "20170304 ?", update = "20170410", }, -- Module:Central-s-en/Documentation {{#invoke:Central-s-en|read}} en = English = English { hostPort = 'en.wikipedia.org', moduleSpace = "Module", doc = "Documentation", user = "Who?", -- lang = "en", project = "wikipedia", -- vers = "Central-w-en", centralmodule = "Module:Central-w-en", centraldoc = "Module:Central-w-en/Documentation", admins = "16 ?", assets = "236 ?", beginon = "20170215 ?", usedfrom = "20170304 ?", update = "20170410", }, -- -- Module:Central-s-es/Documentación {{#invoke:Central-s-es|read}} es = Spanish = español { hostPort = 'es.wikipedia.org', moduleSpace = "Módulo", doc = "Documentación", user = "Quien?", -- lang = "es", project = "wikipedia", -- vers = "Central-w-es", centralmodule = "Módulo:Central-w-es", centraldoc = "Módulo: Central-w-es/Documentación", admins = "16 ?", assets = "236 ?", beginon = "20170215 ?", usedfrom = "20170304 ?", update = "20170410", }, -- -- Module:Central-s-fr/Documentation {{#invoke:Central-s-fr|read}} fr = French = français { hostPort = 'fr.wikisource.org', moduleSpace = "Module", doc = "Documentation", user = "Rical", -- lang = "fr", project = "wikisource", -- vers = "Central-s-fr", centralmodule = "Module:Central-s-fr", centraldoc = "Module:Central-s-fr/Documentation", admins = "16 ?", assets = "236 ?", beginon = "20170215 ?", usedfrom = "20170304 ?", update = "20170410", }, -- -- Modul:Central-w-hu/doc {{#invoke:Central-w-hu|read}} hu = Hungarian = Magyar { hostPort = 'hu.wikipedia.org', moduleSpace = "Modul", doc = "Doc", user = "Rical", -- lang = "hu", project = "wikipedia", -- vers = "Central-w-hu", centralmodule = "Modul:Central-w-hu", centraldoc = "Modul:Central-w-hu/doc", admins = "16 ?", assets = "236 ?", beginon = "20170215 ?", usedfrom = "20170304 ?", update = "20170410", }, -- -- Mô đun:Central-w-vi/tài liệu {{#invoke:Central-w-vi|read}} vi = Vietnamese = Tiếng Việt { hostPort = 'vi.wikipedia.org', moduleSpace = "Mô đun", doc = "tài liệu", user = "Rical", -- lang = "vi", project = "wikipedia", -- vers = "Central-w-vi", centralmodule = "Mô đun:Central-w-vi", centraldoc = "Mô đun:Central-w-vi/tài liệu", admins = "16 ?", assets = "236 ?", beginon = "20170215 ?", usedfrom = "20170304 ?", update = "20170410", }, }, title_memo = "begin_links_to_central_modules_title", -- "begin.links_to_central_modules() Links to begin with central modules.", headers_class = "wikitable alternative center sortable", headers = "begin_links_to_central_modules_headers", } table.sort(tabView.testGroup, function (a, b) return (a.hostPort > b.hostPort) end ) -- alphabetic sort of translated arguments function tabView.tableView_form_one_case(wiki) -- Generally to define: Convert a case from testGroup to rowGroup. -- local all_cases = all_cases or tabView.all_cases local wiki = begin.central_module_descriptor(known_wikis, wiki.hostPort) -- Adapt this main central module version to a kwnow wiki, in begin phase. return wiki end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function begin.links_to_central_modules(hostPort) function begin.rough_delay_stamps(stamp1, stamp2) -- Rough delay between two time stamps. local delay, years, months, days = 0, 0, 0, 0 if (type(stamp1) ~= "string") or (type(stamp2) ~= "string") then return delay end local y1 = tonumber(string.sub(stamp1,1,4)) local y2 = tonumber(string.sub(stamp2,1,4)) if y1 and y2 then years = y2 - y1 end local m1 = tonumber(string.sub(stamp1,5,6)) local m2 = tonumber(string.sub(stamp2,5,6)) if m1 and m2 then months = m2 - m1 end local d1 = tonumber(string.sub(stamp1,7,8)) local d2 = tonumber(string.sub(stamp2,7,8)) if d1 and d2 then days = d2 - d1 end delay = years * 365 + months * 30 + days return delay end -- begin.follow_central_modules() Suivre le début de l'utilisation des modules centraux. function begin.survey_sub_tasks(t) -- Survey the current state of sub tasks to debug. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>begin.survey_sub_tasks()</b> -- Report the current state of debug steps." local tabView = { testGroup = { -- get.subI18N -- Todo later TestsCases { "20170617", "20170618", "later", "Rical", "viewer.CSS_styles() -- Define viewers CSS_styles.", }, { "20170616", "20170616", "later", "Rical", "translate.abnormal_char_in_text() fails", }, { "20170605", "20170615", "later", "Rical", "Debug all functions tests in dropboxes", }, { "20170603", "20170604", "later", "Rical", "Enhance datas.import_wikidata() from 20170403 ModuleCentral 6a clean display.lua", }, { "20170530", "20170602", "later", "Rical", "debug antiLoop() modules libraries runTestsCases counts init time tables", }, { "20170528", "20170529", "later", "Rical", "debug antiCrash() + tests", }, { "20170525", "20170527", "later", "Rical", "debug testsCases.runTestsCases()", }, { "20170523", "20170524", "later", "Rical", "debug testsCases.searchDiffs()", }, { "20170521", "20170522", "later", "Rical", "Begin: Automatic count coders, languages, projects and detect the end of the Begin task", }, { "20170519", "20170520", "later", "Rical", "cat:mw+central versions in internal error .last_scribunto_versions()", }, { "20170515", "20170518", "later", "Rical", "use viewer.tableView for all tables", }, { "20170512", "20170712", "later", "Rical", "Begin: Integrate central changes from other coders", }, { "20170512", "20170712", "later", "Rical", "Begin: Survey sub tasks in 10 projects", }, { "20170506", "20170508", "later", "Rical", "Colors for easier understand errors on sough/known in versioning.versions_management_report()", }, { "20170506", "20170508", "later", "Rical", "Bind i18n in reverse order of versioning.bind_sub_modules()", }, { "20170506", "20170508", "later", "Rical", "Bind the main module versioning.bind_main_module_and_i18n()", }, { "20170504", "20170505", "later", "Rical", "Include main module in versioning.bind_sub_modules()", }, { "20170502", "20170503", "later", "Rical", "Ask translations to the meta [https://meta.wikimedia.org/wiki/Translation_requests Translation_requests]", }, -- https://meta.wikimedia.org/wiki/Translation_requests { "20170506", "20170511", "later", "Rical", "Begin: Find 10 Lua-coders in 10 projects, small or big", }, { "20170503", "20170504", "later", "Rical", "inform [https://meta.wikimedia.org/wiki/Tech/News#contribute Tech News] about central modules begin phase", }, -- https://meta.wikimedia.org/wiki/Tech/News#contribute { "20170501", "20170502", "later", "Rical", "Create T20170130 Begin to use central modules", }, { "20170419", "20170420", "later", "Rical", "Update [[ MediaWiki:Scribunto/Central modules | central modules ]] and [[ MediaWiki:Scribunto/Central modules reference manual | reference manual ]] reference manual docs", }, -- MediaWiki:Scribunto/Central modules reference manual -- Todo now { "20170419", "20170419", "now", "Rical", "List all tests which need to debug. See -- to_debug_on 20170409", }, { "20170404", "20170408", "now", "Rical", "Rename, sort, clean libraries and functions", }, { "20170408", "20170408", "now", "Rical", "Update tests examples: Pascal, Montaigne", }, { "20170408", "20170408", "now", "Rical", "Update tests structures: module, module doc, template, template doc + example, example 1/2, example 1/2 doc", }, { "20170404", "20170407", "now", "Rical", "Test in Central-s-fr and Utilisateur:Rical/Victor Hugo", }, -- Already done { "20170317", "20170409", "done", "Rical", "from_subnames() fails, ok on 20170409", }, { "20170408", "20170408", "done", "Rical", "Restore the stable datas.import_wikidata() from 20160816 ModuleCentral 3a luaTable.tolist.lua", }, { "20170402", "20170404", "done", "Rical", "bind_i18n_translations() ok to sort", }, { "20170201", "20170402", "done", "Rical", "formSubCounts() fails", }, { "20170110", "20170402", "done", "Rical", "translations missing in dropbox titles...","translate.track_i18n_t", }, { "20170328", "20170401", "done", "Rical", "versioning.bind_central_libraries() fails","library.binded_in = 'LD' ok", }, }, title_memo = "begin_survey_sub_tasks_title", -- "begin.survey_sub_tasks(t) Monitor the current state of subtasks to correct", headers = " start; end; state; user; bug description; delay ", headers_class = "wikitable alternative center sortable", } table.sort(tabView.testGroup, function (a, b) return (a[3] < b[3]) end ) -- alphabetic sort of translated arguments table.sort(tabView.testGroup, function (a, b) return (a[2] > b[2]) end ) -- alphabetic sort of translated arguments function tabView.tableView_form_one_case(bug, all_cases) -- Generally to define: Convert a case from testGroup to rowGroup. bug[6] = begin.rough_delay_stamps(bug[1], bug[2]) return bug end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- t = function begin.survey_sub_tasks(t) -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- The Library:datas imports datas of Wikidata from mw.wikibase -- function datas.import_wikidata(args_known, id) -- Import datas of Wikidata from mw.wikibase -- see Extension:Wikibase Client/Lua -- see Extension:Scribunto/Lua reference manual : class nameTest extends Scribunto_LuaEngineTestBase -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- datas = {} -- already declared by Scribunto, else in _G space. -- Translations for datas library datas.i18n = {} datas.i18n.en = { -- Wikidata datas_wikidata_wikibase_err = "Error: Wikibase is not available.", datas_wikidata_getEntity_err = "Error: getEntity Wikidata is not available.", datas_wikidata_getEntityObject_err = "Error: Element Wikidata <b>%1</b> is not found.", datas_wikidata_property_err = "Error: Wikidata property <b>%1</b> is not found.", datas_wikidata_error_err = "Error Wikidata: <b>%1</b> ", -- datas_wikidata_cat_err = "Error Wikidata", datas_wikidata_cat_err = "Module with internal error", -- modes_no_source_arguments_cat datas_structured_data_txt = 'Datas from Wikidata', datas_wikidata_any_page_title = "Wikidata for any page:", datas_wikidata_details_test_title = "Tests and imported datas from wikidata", datas_wikidata_arbitrary_tests_title = "datas.import_wikidata() Test of Wikidata arbitrary access", datas_wikidata_arbitrary_access_text = "Wikidata for another Title: ", datas_wikidata_time_details_title = "datas.wikidata_time_details{} Wikidata time properties for more details", -- Miscellaneous warnings and errors datas_no_args_wikidata_err = "Error: Module without wikidata arguments table.", datas_sources_of_datas = "Informations from: /Wikidata, /template or module, /other, /warning, /error", } -- datas.i18n.en datas.i18n.es = { -- Wikidata datas_wikidata_wikibase_err = "Error: Wikibase no está disponible.", datas_wikidata_getEntity_err = "Error: getEntity Wikidata no está disponible.", datas_wikidata_getEntityObject_err = "Error: Elemento <b>%1</b> de Wikidata no se encuentra.", datas_wikidata_property_err = "Error: La propiedad <b>%1</b> de Wikidata no se encuentra.", datas_wikidata_error_err = "Error Wikidata : <b>%1</b> ", datas_wikidata_cat_err = "Módulo con error interno", -- modes_no_source_arguments_cat datas_structured_data_txt = 'Datos de Wikidata', datas_wikidata_any_page_title = "Wikidata para cualquier página:", datas_wikidata_details_test_title = "Pruebas y datos importados de wikidata", datas_wikidata_arbitrary_tests_title = "datas.import_wikidata() Prueba de Wikidata acceso arbitrario", datas_wikidata_arbitrary_access_text = "Wikidata por otro título: ", datas_wikidata_time_details_title = "datas.wikidata_time_details{} Wikidata propiedades de tiempo para más detalles", -- Diversos mensajes y errores datas_no_args_wikidata_err = "Error: Módulo sin argumentos wikidata tabla.", datas_sources_of_datas = "Informaciones de: /Wikidata, /template o module, /other, /warning, /error", } -- datas.i18n.es datas.i18n.fr = { -- Wikidata datas_wikidata_wikibase_err = "Erreur : Wikibase n'est pas disponible.", datas_wikidata_getEntity_err = "Erreur : getEntity Wikidata n'est pas disponible.", datas_wikidata_getEntityObject_err = "Erreur : L'élément <b>%1</b> de Wikidata n'est pas trouvé.", datas_wikidata_property_err = "Erreur : La propriété <b>%1</b> de Wikidata n'est pas trouvée.", datas_wikidata_error_err = "Erreur Wikidata : <b>%1</b> ", -- datas_wikidata_cat_err = "modes_no_source_arguments_cat", datas_wikidata_cat_err = "Module with internal error", -- modes_no_source_arguments_cat datas_structured_data_txt = 'Données de Wikidata', datas_wikidata_any_page_title = "Wikidata pour une autre page :", datas_wikidata_details_test_title = "Tests et données importées de wikidata", datas_wikidata_arbitrary_tests_title = "datas.import_wikidata() Test de Wikidata accès arbitraire", datas_wikidata_arbitrary_access_text = "Wikidata pour une autre page: ", datas_wikidata_time_details_title = "datas.wikidata_time_details{} Wikidata propriétés de temps pour plus de détails", -- Messages et erreurs divers datas_no_args_wikidata_err = "Erreur interne : Module sans table d'arguments wikidata.", datas_sources_of_datas = "Informations de : /Wikidata, /modèle ou module, /autres, /warning, /erreur", } -- datas.i18n.fr -- from 2016-08-16 ModuleCentral 3a luaTable.tolist.lua function datas.import_wikidata(args_known, id) -- id = itemid -- wikidata structure args_known.father = mw.wikibase.label( "Q" .. entity.claims.p107[0].mainsnak.datavalue.value["numeric-id"]) if type(args_known) ~= "table" then args_known = tools.args_known end if type(id) ~= "string" then id = nil end local t, adr, val, proplabel = "", nil, nil, nil local wd = {} local wd_mng = {} -- wikidata manager wd_mng.wd_base = mw.wikibase if not wd_mng.wd_base then -- Wikibase available ? wd_mng.wd_error = "wd_base" t = t .. tools.viewer.ta("wd_error", wd_mng.wd_error) wd_mng.t = t tools.args_wikidata = wd return wd, t, wd_mng end function pcall_getEntityObject( wd_id ) -- wikidata arbitrary access must not fail and block the page. local success, entity = pcall( mw.wikibase.getEntity, wd_id ) -- pcall or xpcall can run any function without blocking page. if success then return entity else return nil end -- T49930 Allow accessing data from a Wikidata item not connected to the current page - arbitrary access (tracking) end if id then -- Wikidata item available ? wd_mng.wd_entity = pcall_getEntityObject( id ) else wd_mng.wd_id = mw.wikibase.getEntityIdForCurrentPage() -- Returns the Item id as string, like "Q42" if wd_mng.wd_id then -- Wikidata item available ? wd_mng.wd_entity = mw.wikibase.getEntityObject(wd_mng.wd_id) wd_mng.wd_entity.id = mw.wikibase.getEntityIdForCurrentPage() -- Returns the Item id as string, like "Q42" end -- wd_mng.wd_entity = mw.wikibase.getEntity() -- ex getEntityObject end if wd_mng.wd_entity then -- Page Wikidata disponible ? if wd_mng.wd_entity.claimRanks then wd_mng.wd_claimRanks = wd_mng.wd_entity.claimRanks wd_mng.wd_RANK_TRUTH = wd_mng.wd_entity.claimRanks.RANK_TRUTH wd_mng.wd_RANK_PREFERRED = wd_mng.wd_entity.claimRanks.RANK_PREFERRED wd_mng.wd_RANK_NORMAL = wd_mng.wd_entity.claimRanks.RANK_NORMAL wd_mng.wd_RANK_DEPRECATED = wd_mng.wd_entity.claimRanks.RANK_DEPRECATED -- https://www.mediawiki.org/wiki/Extension:WikibaseClient/Lua#mw.wikibase.entity.claimRanks -- Return the normal ranked claims with the property id P5 -- entity:formatPropertyValues( 'P5', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ) -- Return all claims with id P123 (as the table passed contains all possible claim ranks) -- entity:formatPropertyValues( 'P123', mw.wikibase.entity.claimRanks ) -- mw.wikibase.entity.claimRanks = RANK_TRUTH, RANK_PREFERRED, RANK_NORMAL, RANK_DEPRECATED end wd_mng.sitelink = wd_mng.wd_entity:getSitelink( ) wd_mng.label = wd_mng.wd_entity:getLabel( ) -- Returns a string, like "Berlin" with 'de' wd_mng.props = wd_mng.wd_entity:getProperties() -- or {} Returns a table like: { "P123", "P1337" } wd_mng.props_maxn = tostring(table.maxn( wd_mng.props ) ) wd_mng.props_txt = "T " .. mw.text.listToText( wd_mng.props ) -- wd_mng.props_list = " " for i, pp in ipairs(wd_mng.props) do -- Properties list wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp ) if wd_mng.wd_claimRanks then wd_mng.formatPropertyValues_claimRanks = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_claimRanks } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_RANK_TRUTH = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_TRUTH } ) end if wd_mng.wd_RANK_PREFERRED then wd_mng.formatPropertyValues_RANK_PREFERRED = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_PREFERRED } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_wd_RANK_NORMAL = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_NORMAL } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_RANK_DEPRECATED = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_DEPRECATED } ) end val = wd_mng.formatPropertyValues.value proplabel = wd_mng.formatPropertyValues.label wd_mng.props_list = wd_mng.props_list .. " , " .. i .. "=" .. pp .. "=" .. tools.viewer.ta(proplabel, val) -- .. "/" .. tools.viewer.ta(proplabel, wd_mng.formatPropertyNORMAL) if pp == "P569" then -- birthyear P569 for test DEBUG tools.TimeName = pp .. ".1.mainsnak" ; tools.WikidataTimeDetails = wd_mng.wd_entity.claims[pp][1].mainsnak end if pp == "P570" then -- deathyear P570 for test DEBUG tools.TimeName = pp .. ".1.mainsnak" ; tools.WikidataTimeDetails = wd_mng.wd_entity.claims[pp][1].mainsnak end -- https://www.wikidata.org/wiki/Wikidata:Bistro#Date de décès inconnue -- Dans la propriete :Il y a trois petits rectangles à gauche qui permettent de dire si il n'y a pas de valeur (donc pas mort) où si la date est inconnue, le modèle ici ne tient pas compte de ces éléments. --[[User:Pino~eowiki|Pino~eowiki]] ([[User talk:Pino~eowiki|<span class="signature-talk">{{int:Talkpagelinktext}}</span>]]) 16:40, 27 January 2016 (UTC) end else -- if not wd_mng.wd_entity then entity unknown for the page. entity introuvable pour la page. wd_mng.wd_error = "wd_entity" t = t .. tools.viewer.ta("wd_error", wd_mng.wd_error) wd_mng.t = t tools.args_wikidata = wd return wd, t, wd_mng end if wd_mng.wd_error then -- Show an error, Signaler une erreur if wd_mng.wd_error == "wikidata_props" then err = tools.strVars("tools_wikidata_error_err", "wikidata_props") end if wd_mng.wd_error == "wd_base" then err = tools.strVars("tools_wikidata_wikibase_err") end if wd_mng.wd_error == "wd_entity" then err = tools.strVars("tools_wikidata_getEntity_err", wd_mng.wd_entity) end if wd_mng.wd_error == "wd_property" then err = tools.strVars("tools_wikidata_property_err", wd_mng.wd_property) end -- elem -> id if wd_mng.wd_error == "wd_id" then err = tools.strVars("tools_wikidata_getEntityObject_err", wd_mng.wd_id) end err = tools.err_add(err) t = t .. err local tools_wikidata_cat_err = tools.cat_add("tools_wikidata_cat_err") else if type(args_known) ~= "table" then args_known = {} end for key, pp in pairs(args_known) do -- Pour tous les paramètres connus if pp.prop then if pp.prop == "label" then val = wd_mng.label elseif pp.prop == "sitelink" then val = wd_mng.sitelink elseif pp.prop == "itemid" then val = wd_mng.wd_entity.id elseif pp.prop == "description" then val = wd_mng.wd_base.description( wd_mng.wd_id ) -- wikibase.description( id ) elseif pp.prop == "claims" then val = wd_mng.wd_base.renderSnak( wd_mng.wd_entity['claims'] ) -- Returns the given Snaks formatted as wiki text. -- local entity = mw.wikibase.getEntityObject() -- local snaks = entity['claims']['P342'][1]['qualifiers'] -- mw.wikibase.renderSnaks( snaks ) -- Returns the given Snaks formatted as wiki text. else wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp.prop ) -- "P" .. pp.prop -- Returns a table like: { value = "Formatted claim value", label = "Label of the Property" } if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_TRUTH } ) end if wd_mng.wd_claimRanks then wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_claimRanks } ) end val = wd_mng.formatPropertyValues.value proplabel = wd_mng.formatPropertyValues.label end if pp.format == "year" then val = mw.ustring.sub( val, -4, -1 ) end wd[key] = val t = t .. tools.viewer.ta(key, val) -- .. tools.viewer.ta(key, wd_mng.formatPropertyNORMAL) end end end -- wd.lastname = wd.label wd_mng.t = t tools.args_wikidata = wd return wd, t, wd_mng end -- function datas.import_wikidata(args_known, id) function datas.import_wikidata_new(args_known, wd_id) -- Import datas of Wikidata from mw.wikibase -- wikidata structure args_known.father = mw.wikibase.label( "Q" .. entity.claims.p107[0].mainsnak.datavalue.value["numeric-id"]) if type(args_known) ~= "table" then args_known = modes.args_known end if type(wd_id) ~= "string" then wd_id = nil end local t, adr, val, proplabel = "", nil, nil, nil local wd = {} local wd_mng = {} -- wikidata manager wd_mng.wd_base = mw.wikibase if not wd_mng.wd_base then -- Wikibase available ? wd_mng.wd_error = "wd_base" t = t .. viewer.ta("wd_error", wd_mng.wd_error) wd_mng.t = t datas.args_wikidata = wd return wd, t, wd_mng end local function getEntityObject_pcall( wd_id ) -- wikidata arbitrary access must not fail and block the page. local success, entity = pcall( mw.wikibase.getEntity, wd_id ) -- pcall or xpcall can run any function without blocking page. if success then return entity else return nil end -- T49930 Allow accessing data from a Wikidata item not connected to the current page - arbitrary access (tracking) end local pcall_wd_id = getEntityObject_pcall( wd_id ) if pcall_wd_id then -- Wikidata item available ? wd_mng.wd_entity = getEntityObject_pcall( wd_id ) else wd_mng.wd_id = mw.wikibase.getEntityIdForCurrentPage() -- Returns the Item id as string, like "Q42" if wd_mng.wd_id then -- Wikidata item available ? wd_mng.wd_entity = mw.wikibase.getEntityObject(wd_mng.wd_id) wd_mng.wd_entity.id = mw.wikibase.getEntityIdForCurrentPage() -- Returns the Item id as string, like "Q42" end -- wd_mng.wd_entity = mw.wikibase.getEntity() -- ex getEntityObject end if wd_mng.wd_entity then -- Page Wikidata disponible ? if wd_mng.wd_entity.claimRanks then wd_mng.wd_claimRanks = wd_mng.wd_entity.claimRanks wd_mng.wd_RANK_TRUTH = wd_mng.wd_entity.claimRanks.RANK_TRUTH wd_mng.wd_RANK_PREFERRED = wd_mng.wd_entity.claimRanks.RANK_PREFERRED wd_mng.wd_RANK_NORMAL = wd_mng.wd_entity.claimRanks.RANK_NORMAL wd_mng.wd_RANK_DEPRECATED = wd_mng.wd_entity.claimRanks.RANK_DEPRECATED -- https://www.mediawiki.org/wiki/Extension:WikibaseClient/Lua#mw.wikibase.entity.claimRanks -- Return the normal ranked claims with the property id P5 -- entity:formatPropertyValues( 'P5', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ) -- Return all claims with id P123 (as the table passed contains all possible claim ranks) -- entity:formatPropertyValues( 'P123', mw.wikibase.entity.claimRanks ) -- mw.wikibase.entity.claimRanks = RANK_TRUTH, RANK_PREFERRED, RANK_NORMAL, RANK_DEPRECATED end wd_mng.sitelink = wd_mng.wd_entity:getSitelink( ) wd_mng.label = wd_mng.wd_entity:getLabel( ) -- Returns a string, like "Berlin" with 'de' wd_mng.props = wd_mng.wd_entity:getProperties() -- or {} Returns a table like: { "P123", "P1337" } wd_mng.props_maxn = tostring(table.maxn( wd_mng.props ) ) wd_mng.props_txt = "T " .. mw.text.listToText( wd_mng.props ) -- wd_mng.props_list = " " for i, pp in ipairs(wd_mng.props) do -- Properties list wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp ) if wd_mng.wd_claimRanks then wd_mng.formatPropertyValues_claimRanks = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_claimRanks } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_RANK_TRUTH = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_TRUTH } ) end if wd_mng.wd_RANK_PREFERRED then wd_mng.formatPropertyValues_RANK_PREFERRED = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_PREFERRED } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_wd_RANK_NORMAL = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_NORMAL } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_RANK_DEPRECATED = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_DEPRECATED } ) end val = wd_mng.formatPropertyValues.value proplabel = wd_mng.formatPropertyValues.label wd_mng.props_list = wd_mng.props_list .. " , " .. i .. "=" .. pp .. "=" .. viewer.ta(proplabel, val) -- .. "/" .. viewer.ta(proplabel, wd_mng.formatPropertyNORMAL) if pp == "P569" then -- birthyear P569 for test DEBUG datas.TimeName = pp .. ".1.mainsnak" ; datas.wikidata_time_details = wd_mng.wd_entity.claims[pp][1].mainsnak end if pp == "P570" then -- deathyear P570 for test DEBUG datas.TimeName = pp .. ".1.mainsnak" ; datas.wikidata_time_details = wd_mng.wd_entity.claims[pp][1].mainsnak end -- https://www.wikidata.org/wiki/Wikidata:Bistro#Date de décès inconnue -- Dans la propriete :Il y a trois petits rectangles à gauche qui permettent de dire si il n'y a pas de valeur (donc pas mort) où si la date est inconnue, le modèle ici ne tient pas compte de ces éléments. --[[User:Pino~eowiki|Pino~eowiki]] ([[User talk:Pino~eowiki|<span class="signature-talk">{{int:Talkpagelinktext}}</span>]]) 16:40, 27 January 2016 (UTC) end else -- if not wd_mng.wd_entity then entity unknown for the page. entity introuvable pour la page. wd_mng.wd_error = "wd_entity" t = t .. viewer.ta("wd_error", wd_mng.wd_error) wd_mng.t = t datas.args_wikidata = wd return wd, t, wd_mng end if wd_mng.wd_error then -- Show an error, Signaler une erreur if wd_mng.wd_error == "wikidata_props" then err = viewer.form9user("datas_wikidata_error_err", "wikidata_props") end if wd_mng.wd_error == "wd_base" then err = viewer.form9user("datas_wikidata_wikibase_err") end if wd_mng.wd_error == "wd_entity" then err = viewer.form9user("datas_wikidata_getEntity_err", wd_mng.wd_entity) end if wd_mng.wd_error == "wd_property" then err = viewer.form9user("datas_wikidata_property_err", wd_mng.wd_property) end -- elem -> id if wd_mng.wd_error == "wd_id" then err = viewer.form9user("datas_wikidata_getEntityObject_err", wd_mng.wd_id) end err = events.add_err(err) .. ";" t = t .. err local datas_wikidata_cat_err = events.add_cat("datas_wikidata_cat_err") else if type(args_known) ~= "table" then args_known = {} end for key, pp in pairs(args_known) do -- Pour tous les paramètres connus if pp.prop then if pp.prop == "label" then val = wd_mng.label elseif pp.prop == "sitelink" then val = wd_mng.sitelink elseif pp.prop == "itemid" then val = wd_mng.wd_entity.id elseif pp.prop == "description" then val = wd_mng.wd_base.description( wd_mng.wd_id ) -- wikibase.description( id ) elseif pp.prop == "claims" then val = wd_mng.wd_base.renderSnak( wd_mng.wd_entity['claims'] ) -- Returns the given Snaks formatted as wiki text. -- local entity = mw.wikibase.getEntityObject() -- local snaks = entity['claims']['P342'][1]['qualifiers'] -- mw.wikibase.renderSnaks( snaks ) -- Returns the given Snaks formatted as wiki text. else wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp.prop ) -- "P" .. pp.prop -- Returns a table like: { value = "Formatted claim value", label = "Label of the Property" } if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_TRUTH } ) end if wd_mng.wd_claimRanks then wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_claimRanks } ) end val = wd_mng.formatPropertyValues.value proplabel = wd_mng.formatPropertyValues.label end if pp.format == "year" then val = mw.ustring.sub( val, -4, -1 ) end wd[key] = val t = t .. viewer.ta(key, val) -- .. viewer.ta(key, wd_mng.formatPropertyNORMAL) end end end -- wd.lastname = wd.label wd_mng.t = t datas.args_wikidata = wd return wd, t, wd_mng end -- function datas.import_wikidata_new(args_known, id) function datas.import_wikidata_new_2(args_known, id) -- wikidata structure args_known.father = mw.wikibase.label( "Q" .. entity.claims.p107[0].mainsnak.datavalue.value["numeric-id"]) if type(args_known) ~= "table" then args_known = modes.args_known end -- or p.args_known local t, adr, val, proplabel = "", nil, nil, nil local wd = {} local wd_mng = {} -- wikidata manager if type(id) == "string" then -- Le 2013-06-19 acces restreint par Lua pour un autre élément -- https://bugzilla.wikimedia.org/show_bug.cgi?id=49805 -- T49930 Allow accessing data from a Wikidata item not connected to the current page - arbitrary access (tracking) -- Reported: 2013-06-19 10:52 UTC by Rical wd_mng.wd_id = id -- t = t .. viewer.ta("wd_error", wd.wd_error) -- t = t .. "\n* " .. viewer.ta("wd_id", wd_mng.wd_id) -- t = t .. " see [https://phabricator.wikimedia.org/T49930 bug T49930]" -- DEBUG wd_mng.t = t or "" -- wd_mng.wd_error = "wd_id" -- wd_mng.wd_id = nil -- anti-bug 47930 -- datas.args_wikidata = wd -- return wd, t, wd_mng end wd_mng.wd_base = mw.wikibase if not wd_mng.wd_base then -- Wikidata disponible ? wd_mng.wd_error = "wd_base" t = t .. viewer.ta("wd_error", wd_mng.wd_error) wd_mng.t = t datas.args_wikidata = wd return wd, t, wd_mng end -- local function getEntityObject_xpcall( wd_id ) -- wikidata arbitrary access must not fail and block the page. -- local entity = mw.wikibase.getEntityObject( wd_id ) -- if type(wd_id) ~= "string" then wd_id = nil end local success, entity = pcall( mw.wikibase.getEntity, wd_id ) -- pcall or xpcall can run any function without blocking page. if success then return entity else return nil end -- T49930 Allow accessing data from a Wikidata item not connected to the current page - arbitrary access (tracking) end -- wd_mng.wd_entity = getEntityObject_xpcall( wd_mng.wd_id ) if getEntityObject_xpcall( wd_mng.wd_id ) then -- Page Wikidata disponible ? wd_mng.wd_entity = mw.wikibase.getEntity( wd_mng.wd_id ) -- ex getEntityObject end -- -- wd_mng.wd_entity = mw.wikibase.getEntityObject( ) -- anti-bug 47930 if wd_mng.wd_entity then -- Page Wikidata disponible ? if wd_mng.wd_entity.claimRanks then wd_mng.wd_claimRanks = wd_mng.wd_entity.claimRanks wd_mng.wd_RANK_TRUTH = wd_mng.wd_entity.claimRanks.RANK_TRUTH wd_mng.wd_RANK_PREFERRED = wd_mng.wd_entity.claimRanks.RANK_PREFERRED wd_mng.wd_RANK_NORMAL = wd_mng.wd_entity.claimRanks.RANK_NORMAL wd_mng.wd_RANK_DEPRECATED = wd_mng.wd_entity.claimRanks.RANK_DEPRECATED -- https://www.mediawiki.org/wiki/Extension:WikibaseClient/Lua#mw.wikibase.entity.claimRanks -- Return the normal ranked claims with the property id P5 -- entity:formatPropertyValues( 'P5', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ) -- Return all claims with id P123 (as the table passed contains all possible claim ranks) -- entity:formatPropertyValues( 'P123', mw.wikibase.entity.claimRanks ) -- mw.wikibase.entity.claimRanks = RANK_TRUTH, RANK_PREFERRED, RANK_NORMAL, RANK_DEPRECATED end wd_mng.sitelink = wd_mng.wd_entity:getSitelink( ) wd_mng.label = wd_mng.wd_entity:getLabel( ) -- Returns a string, like "Berlin" with 'de' wd_mng.props = wd_mng.wd_entity:getProperties() -- or {} Returns a table like: { "P123", "P1337" } wd_mng.props_maxn = tostring(table.maxn( wd_mng.props ) ) wd_mng.props_txt = "T " .. mw.text.listToText( wd_mng.props ) -- wd_mng.props_list = " " for i, pp in ipairs(wd_mng.props) do -- Properties list wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp ) if wd_mng.wd_claimRanks then wd_mng.formatPropertyValues_claimRanks = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_claimRanks } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_RANK_TRUTH = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_TRUTH } ) end if wd_mng.wd_RANK_PREFERRED then wd_mng.formatPropertyValues_RANK_PREFERRED = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_PREFERRED } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_wd_RANK_NORMAL = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_NORMAL } ) end if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues_RANK_DEPRECATED = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_DEPRECATED } ) end val = wd_mng.formatPropertyValues.value proplabel = wd_mng.formatPropertyValues.label wd_mng.props_list = wd_mng.props_list .. " , " .. i .. "=" .. pp .. "=" .. viewer.ta(proplabel, val) -- .. "/" .. viewer.ta(proplabel, wd_mng.formatPropertyNORMAL) if pp == "P569" then -- birthyear P569 for test DEBUG datas.TimeName = pp .. ".1.mainsnak" ; datas.TimeTest = wd_mng.wd_entity.claims[pp][1].mainsnak end if pp == "P570" then -- deathyear P570 for test DEBUG datas.TimeName = pp .. ".1.mainsnak" ; datas.TimeTest = wd_mng.wd_entity.claims[pp][1].mainsnak end -- https://www.wikidata.org/wiki/Wikidata:Bistro#Date de décès inconnue -- Dans la propriete :Il y a trois petits rectangles à gauche qui permettent de dire si il n'y a pas de valeur (donc pas mort) où si la date est inconnue, le modèle ici ne tient pas compte de ces éléments. --[[User:Pino~eowiki|Pino~eowiki]] ([[User talk:Pino~eowiki|<span class="signature-talk">{{int:Talkpagelinktext}}</span>]]) 16:40, 27 January 2016 (UTC) end else -- entity unknown for the page. entity introuvable pour la page. wd_mng.wd_error = "wd_entity" t = t .. viewer.ta("wd_error", wd_mng.wd_error) wd_mng.t = t datas.args_wikidata = wd return wd, t, wd_mng end if wd_mng.wd_error then -- Show an error, Signaler une erreur if wd_mng.wd_error == "wikidata_props" then err = viewer.form9user("datas_wikidata_error_err", "wikidata_props") end if wd_mng.wd_error == "wd_base" then err = viewer.form9user("datas_wikidata_wikibase_err") end if wd_mng.wd_error == "wd_entity" then err = viewer.form9user("datas_wikidata_getEntity_err", wd_mng.wd_entity) end if wd_mng.wd_error == "wd_property" then err = viewer.form9user("datas_wikidata_property_err", wd_mng.wd_property) end -- elem -> id if wd_mng.wd_error == "wd_id" then err = viewer.form9user("datas_wikidata_getEntityObject_err", wd_mng.wd_id) end err = events.err_add(err) t = t .. err local datas_wikidata_cat_err = events.cat_add("datas_wikidata_cat_err") else for key, pp in pairs(args_known) do -- For all known parameters if pp.prop then if pp.prop == "label" then val = wd_mng.label elseif pp.prop == "sitelink" then val = wd_mng.sitelink elseif pp.prop == "entityid" then val = wd_mng.wd_entity.id elseif pp.prop == "description" then val = wd_mng.wd_base.description( wd_mng.wd_id ) -- wikibase.description( id ) elseif pp.prop == "claims" then val = wd_mng.wd_base.renderSnak( wd_mng.wd_entity['claims'] ) -- Returns the given Snaks formatted as wiki text. -- local entity = mw.wikibase.getEntityObject() -- local snaks = entity['claims']['P342'][1]['qualifiers'] -- mw.wikibase.renderSnaks( snaks ) -- Returns the given Snaks formatted as wiki text. else wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp.prop ) -- "P" .. pp.prop -- Returns a table like: { value = "Formatted claim value", label = "Label of the Property" } if wd_mng.wd_RANK_TRUTH then wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_RANK_TRUTH } ) end if wd_mng.wd_claimRanks then wd_mng.formatPropertyValues = wd_mng.wd_entity:formatPropertyValues( pp, { wd_mng.wd_claimRanks } ) end val = wd_mng.formatPropertyValues.value proplabel = wd_mng.formatPropertyValues.label end if pp.format == "year" then val = mw.ustring.sub( val, -4, -1 ) end wd[key] = val t = t .. viewer.ta(key, val) -- .. viewer.ta(key, wd_mng.formatPropertyNORMAL) end end end -- wd.lastname = wd.label wd_mng.t = t datas.args_wikidata = wd return wd, t, wd_mng end -- function datas.import_wikidata_new_2(args_known, id) function datas.wikidata_details_test(t) local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>wikidata_details_test</b> :" t = t .. "<br>" .. luaTable.formSubCounts("datas.i18n") local wd, tw, wd_mng -- t = t .. datas.wikidata_arbitrary_tests() wd, tw, wd_mng = datas.import_wikidata( modes.args_known ) -- for present page if wd_mng and wd_mng.wd_entity and wd_mng.wd_entity.id then t = t .. "\n* Entity.id: " .. (wd_mng.wd_entity.id or "") -- itemid local datas_structured_data_txt = viewer.form9user("datas_structured_data_txt") t = t .. ' <span style="color:#232388; font-size:140%; line-height:120%; ">⦁ </span>[[d:' .. wd_mng.wd_entity.id .. '|' .. datas_structured_data_txt .. ']]<br>' end t = t .. "\n* Sought properties: " .. tw t = t .. "\n* Properties number maxn: " .. (wd_mng.props_maxn or "") -- t = t .. "\n* Properties txt: " .. (wd_mng.props_txt or "") t = t .. "\n* Properties list: " .. (wd_mng.props_list or "") events.restore_configs(memo) -- Restore global configurations after eventual changes. return t -- .init_configs(=14 -- .save_configs(=48 -- .restore_configs(=58 -- end -- function datas.wikidata_details_test(t) function datas.wikidata_arbitrary_tests(t) local memo = events.save_configs() -- Save global configuration before eventual changes. -- T49930 Allow accessing data from a Wikidata item not connected to the current page - arbitrary access (tracking) local t = t or "\n* wikidata_arbitrary_tests: " local function one_arbitrary_access(id) local t = "" local wd, tw, wd_mng = datas.import_wikidata(modes.args_known, id) -- example Q535 = Victor Hugo if wd_mng and wd_mng.wd_entity and wd_mng.wd_entity.id then t = t .. "\n* " .. viewer.form9user("datas_wikidata_arbitrary_access_text") .. (wd.itemid or "") .. ", " .. (wd.label or "") .. " ( " .. (wd.birthyear or "") .. " - " .. (wd.deathyear or "") .. " ) " local datas_structured_data_txt = viewer.form9user("datas_structured_data_txt") t = t .. ' <span style="color:#232388; font-size:140%; line-height:120%; ">⦁ </span>[[d:' .. wd_mng.wd_entity.id .. '|' .. datas_structured_data_txt .. ']]' t = t .. ", " .. (wd_mng.props_maxn or "") .. " properties. " -- "\n* Properties number maxn: " t = t .. "\n* Sought properties: " .. tw else t = "<br>* No arbitrary access for: " .. tostring(id) end return t end t = t .. one_arbitrary_access("Q535") -- Q535 = Victor Hugo = Victor Marie Hugo -- t = t .. one_arbitrary_access("Victor Hugo") -- Q535 = Victor Hugo = Victor Marie Hugo t = t .. one_arbitrary_access("Q8023") -- Q899264 = Nelson Mandela -- t = t .. one_arbitrary_access("Q899264") -- Q899264 = Martin Fleischmann events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function datas.wikidata_arbitrary_tests(t) -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:events support events of types erros, warnings and categories. -- events.init_configs( base, tabOptions, group ) -- Init a new events group -- events.add_err(key, ... ) -- Add an error in the actual table of events. -- events.catGroup(groupCat, groupList) -- Add some categories in the actual table of events. -- events.form(evt) -- Format events types -- events.categ_Test(t) -- tester les categories -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- events = {} -- already declared by Scribunto, else in _G space. -- Translations for Library:events events.i18n = {} events.i18n.en = { events_test_tests_title = "List a table, test with limits:", events_categ_Test_title = "events.categ_Test() Test: Creation of categories in some languages", events_test_resTest_title = "List a table, test with limits:", events_test_projects_title = "Test and display tests events for projects", events_test_projects_headers = "Type;Key;Name test and values;result of the test", events_test_mediawiki_title = "Test and display tests events for mediawiki", events_test_mediawiki_headers = "Type;Key;Name test and values;result of the test", events_test_categ_Test_title = "categ_Test test : classes in some languages", events_test_categ_Test_headers = "Test type;user language;wiki language;Categories", events_all_kinds_tests_title = "events.all_kinds_test() Test: all kinds of events (err, wng, cat)", events_close_without_memo_err = "events.restore_configs(memo) without <b>memo</b> in module <b>%1</b>.", events_selectLang_tests_title = "events.selectLang() Tests: Select a language for tests or other", events_selectLang_test_headers = "Wiki language; User language; Sought language; Selected language; Example", events_selectLang_test_example = "Language: wiki = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.", events_selectLang_test_err = "Internal error : events.selectLang(lang) has no tests table.", events_selectLang_test_cat = "Module with internal error", } -- events.i18n.en events.i18n.es = { events_test_tests_title = "List a table, test with limits:", events_categ_Test_title = "events.categ_Test() Prueba: Creación de categorías en algunos idiomas", events_test_resTest_title = "List a table, test with limits:", events_test_projects_title = "Test and display tests events for projects", events_test_projects_headers = "Type;Key;Name test and values;result of the test", events_test_mediawiki_title = "Test and display tests events for mediawiki", events_test_mediawiki_headers = "Type;Key;Name test and values;result of the test", events_test_categ_Test_title = "Prueba categ_Test: clases en algunos lenguajes", events_test_categ_Test_headers = "Tipo de prueba;Lenguaje usuario;Lenguaje wiki;Categorías", events_all_kinds_tests_title = "events.all_kinds_test() Prueba: todo tipo de eventos (err, wng, cat)", events_add_cat_deprecated = "Función obsoleto en módulo principal.", events_close_without_memo_err = "events.restore_configs(memo) sin <b>memo</b> en el módulo <b>%1</b>.", events_selectLang_tests_title = "events.selectLang() Pruebas: Seleccione un idioma para pruebas u otro", events_selectLang_test_headers = "Lengua del Wiki; Idioma del usuario; Lengua buscada; Idioma seleccionado; Ejemplo", events_selectLang_test_example = "Idioma: wiki = <b>%1</b>, usuario = <b>%2</b>, seleccionada = <b>%3</b>.", events_selectLang_test_err = "Error interno: events.selectLang(lang) no tiene tabla de pruebas.", events_selectLang_test_cat = "Módulo con error interno", versioning_defaultCrashResult_ref_err = "La función antiCrash() protege esta página contra un colapso completo debido a un error interna: %1.", } -- events.i18n.es events.i18n.fr = { events_test_tests_title = "List a table, test with limits:", events_categ_Test_title = "events.categ_Test() Test: Création des catégories dans quelques langues", events_test_resTest_title = "List a table, test with limits:", events_test_projects_title = "Test and display tests events for projects", events_test_projects_headers = "Type;Key;Name test and values;result of the test", events_test_mediawiki_title = "Test and display tests events for mediawiki", events_test_mediawiki_headers = "Type;Key;Name test and values;result of the test", events_test_categ_Test_title = "Tester categ_Test : catégories dans quelques langues", events_test_categ_Test_headers = "Type de test;Langue utilisateur;Langue wiki;Catégories", events_all_kinds_tests_title = "events.all_kinds_test() Test: toutes les sortes d'événements (err, wng, cat)", events_add_cat_deprecated = "Fonction obsolète dans le module principal.", events_close_without_memo_err = "events.restore_configs(memo) sans <b>memo</b> dans le module <b>%1</b>.", events_selectLang_tests_title = "events.selectLang() Tests: Sélectionnez une langue pour les tests ou autres", events_selectLang_test_headers = "Langue du wiki; Langue utilisateur; Langue cherchée; Langue choisie; Exemple", events_selectLang_test_example = "Langues : wiki = <b>%1</b>, utilisateur = <b>%2</b>, choisie = <b>%3</b>.", events_selectLang_test_err = "Erreur interne: events.selectLang(lang) n'a pas de table de tests.", events_selectLang_test_cat = "Module avec erreur interne", } -- events.i18n.fr events.testGroup = {} events.rowGroup = {} events.tabOptions = {} events.tabOptions.testGroup = {} events.tabOptions.rowGroup = {} function events.init_configs(base, tabOptions, group) -- Initialize global configurations and save them before eventual changes. local memo = events.save_configs() -- Save global configuration before eventual changes. -- actual init if type(base) ~= "table" then base = {} end if type(group) ~= "table" then group = nil end if type(tabOptions) ~= "table" then tabOptions = events.tabOptions or {} end base.events = events -- A new events process/object come from the events process/object in this module. base.events.tabOptions = tabOptions or base.events.tabOptions or events.tabOptions base.events.catview = tabOptions.catview or base.events.catview or modes.catView base.events.default_group = tabOptions.default_group or base.events.group_all_types_test base.events.dropboxStyle = tabOptions.dropboxStyle or base.events.dropboxStyle base.events.testGroup = group or tabOptions.testGroup or base.events.testGroup or events.testGroup or {} base.events.headers = tabOptions.headers or base.events.headers base.events.kind = tabOptions.kind or base.events.kind base.events.tableViewStyle = tabOptions.tableViewStyle or base.events.dropboxStyle base.events.testsFunction = tabOptions.testsFunction or base.events.testsFunction base.events.typ = tabOptions.typ or base.events.typ base.events.user_lang = tabOptions.user_lang or base.events.user_lang base.events.wiki_lang = tabOptions.wiki_lang or base.events.wiki_lang base.events.recursiveLevel = tabOptions.recursiveLevel or base.events.recursiveLevel base.events.recursiveLimit = tabOptions.recursiveLimit or base.events.recursiveLimit or 11111 base.events.testGroup = events.testGroup or base.events.testGroup or {} translate.init_wiki_user_page_lang(base.events.wiki_lang, base.events.user_lang) return memo, base.events end -- function events.init_configs(base, tabOptions, group) function events.save_configs() -- Save global configuration before eventual changes. local memo = {} memo.memo_testGroup = events.testGroup memo.memo_tabOptions = events.tabOptions memo.memo_versioning_actual_modules = versioning.actual_modules memo.memo_versioning_main_i18n = versioning.main_i18n memo.memo_translate_main_i18n = translate.main_i18n memo.memo_wiki_lang = translate.wiki_lang memo.memo_user_lang = translate.user_lang memo.memo_page_lang = translate.page_lang memo.memo_categories_list = events.categories_list memo.memo_modes_catView = modes.catView memo.memo_recursiveLimit = modes.recursiveLimit memo.memo_mode_name = modes.mode_name memo.memo_mode_options = modes.mode_options memo.memo_invoke_options = modes.invoke_options memo.memo_used_options = modes.used_options memo.memo_options_for_modes = modes.options_for_modes memo.memo_report_trackOptions = modes.report_trackOptions return memo end -- function events.save_configs() -- function events.init_configs(=3 -- function events.save_configs(=3 -- function events.restore_configs(=2 -- -- .init_configs(=16-3=13 -- .save_configs(=50-3-init-deprecated=45 -- .restore_configs(=60-2=58 -- OK : 16+50-3-1-1 = 13+45 = 58 = 60-2 function events.restore_configs(memo) -- Restore global configurations after eventual changes. -- Close categories and errors tables for one test or a group of tests. if type(memo) ~= "table" then events.add_err("events_close_without_memo_err", versioning.main_versions.versionName) -- Add an error in the actual table of events. return end events.testGroup = memo.memo_testGroup events.tabOptions = memo.memo_tabOptions versioning.actual_modules = memo.memo_versioning_actual_modules versioning.main_i18n = memo.memo_versioning_main_i18n translate.main_i18n = memo.memo_translate_main_i18n translate.wiki_lang = memo.memo_wiki_lang translate.user_lang = memo.memo_user_lang translate.page_lang = memo.memo_page_lang translate.init_wiki_user_page_lang(translate.wiki_lang, translate.user_lang, translate.page_lang) events.categories_list = memo.memo_categories_list modes.catView = memo.memo_modes_catView modes.recursiveLimit = memo.memo_recursiveLimit modes.mode_name = memo.memo_mode_name modes.mode_options = memo.memo_mode_options modes.invoke_options = memo.memo_invoke_options modes.used_options = memo.memo_used_options modes.options_for_modes = memo.memo_options_for_modes modes.report_trackOptions = memo.memo_report_trackOptions end -- function events.restore_configs(memo) function events.select_typ(typ) -- Select events by one type local is = {} for i, evt in pairs(events.testGroup) do if evt.typ == typ then table.insert( is, evt.idargs ) end end return is end function events.sort_typ() -- Sort events by type in wng, err, cat. local wng, err, cat = {}, {}, {} for i, evt in pairs(events.testGroup) do if evt.typ == "wng" then table.insert( wng, evt ) end if evt.typ == "err" then table.insert( err, evt ) end if evt.typ == "cat" then table.insert( cat, evt ) end end return wng, err, cat end -- function events.sort_typ() function events.form(evt) -- Format events types if type(evt) ~= "table" then return end evt.tableStyle = evt.tableStyle or "" -- Could change the style of the wikitext. Not available on 20160916 if type(evt.name) ~= "string" then evt.name = "" elseif evt.name ~= "" then evt.name = evt.name .. "_" end evt.idargs = evt.name .. tostring( viewer.form9user( tostring(evt.key), luaTable.toList( evt.v ) ) ) -- Each type of event forms its own type of wikitext evt.user_wkt = viewer.trans9vars(translate.user_translations, evt.key, luaTable.toList( evt.v ) ) evt.wiki_wkt = viewer.trans9vars(translate.wiki_translations, evt.key, luaTable.toList( evt.v ) ) evt.res = evt.wkt or "" if evt.typ == "err" then evt.res = viewer.errorColor(evt.user_wkt) end if evt.typ == "wng" then evt.res = viewer.warningColor(evt.user_wkt) end local c = events.catview or ":" local wiki_catspace = mw.site.namespaces.Category.name -- name: Local namespace name. if evt.typ == "cat" then -- Format a category to display or activate evt.res = " [[" .. c .. wiki_catspace .. ":" .. evt.wiki_wkt .. "|" .. evt.user_wkt .. "]] " end viewer.trc = viewer.trc or "? form " .. translate.formTestCase(".form evt.key=%1, evt.res=%2, ", evt.key, evt.res ) return evt.res, evt end -- function events.form(evt) function events.add(typ, key, ...) -- Add an event to a group. local evt = {} -- actual event if type(typ) == "table" then evt = typ else evt = {} end -- actual event evt.typ = evt.typ or typ -- Type of event: err, wng, cat evt.key = evt.key or key -- Translation key, simple or extended by name if type(typ) ~= "string" then typ = "notyp" end -- To debug abnormal type of event if type(key) ~= "string" then key = "nokey" end -- To debug abnormal translation key evt.name = evt.name or "" -- Translation key, simple or extended by name evt.v = evt.v or { ... } -- table of detail values evt.res, evt = events.form( evt ) -- Insert only new events local new_evt = translate.formTestCase( tostring(evt.key), luaTable.toList( evt.v ) ) for i, event in pairs(events.testGroup) do local old_evt = translate.formTestCase( tostring(event.key), luaTable.toList( event.v ) ) if new_evt == old_evt then new_evt = nil end -- delete the new event if it already exists. end if new_evt then table.insert( events.testGroup, evt ) end -- table.insert( events.testGroup, evt ) -- { evt.typ, evt.key, evt.name, evt.wkt } ) return evt.res, evt end -- function events.add(typ, key, ...) function events.add_err(key, ... ) -- Add an error in the actual table of events. local res, evt = events.add("err", key, ...) -- Add an event to a group. viewer.trc = viewer.trc .. translate.formTestCase("\n* err_add evt.typ=%1, evt.key=%2, ", evt.typ, evt.key) return res, evt end function events.add_wng(key, ... ) -- Add a warning in the actual table of events. local res, evt = events.add("wng", key, ...) -- Add an event to a group. viewer.trc = viewer.trc .. translate.formTestCase("\n* msg_add evt.typ=%1, evt.key=%2, ", evt.typ, evt.key) return res, evt end function events.add_cat(key, ... ) -- Add a category in the actual table of events. local res, evt = events.add("cat", key, ...) -- Add an event to a group. viewer.trc = viewer.trc .. translate.formTestCase("\n* add_cat evt.typ=%1, evt.key=%2, ", evt.typ, evt.key) return res, evt end function events.catGroup(groupCat, groupList) -- Add some categories in the actual table of events. -- catGroup("Country %1", "France,Italia") -> [[Category:Country France]] [[Category:Country Italia]] if type(groupCat) ~= "string" then groupCat = "%1" end if type(groupList) ~= "string" then return "" end local cats = "" -- local t = "" -- t = t .. viewer.ta("groupList", groupList) for i, str in mw.text.gsplit(groupList, ";", true) do local wkt = viewer.form9user(groupCat, str) cats = cats .. events.add_cat(groupCat, wkt) end local res, evt = events.add("catGroup", groupCat, cats) -- Add an event to a group. -- viewer.trc = viewer.trc .. viewer.form9user("\n* add_cat evt.typ=%1, evt.key=%2, ", evt.typ, evt.key) return res, evt end -- function events.catGroup(groupCat, groupList) function events.selector( tabOptions, evt ) if type(evt) ~= "table" then evt = { -- options for viewer.tableView() -- Form a table with lines and columns. headers = "typ;key;selector-name;wkt", style = "", typ = "err", rowGroup = {}, } else evt.headers = evt.headers or "typ;key;else-name;wkt" evt.tableStyle = evt.tableStyle or "" evt.name = evt.name or "_" evt.typ = evt.typ or "nil" end if (type(tabOptions) == "table") and (type(tabOptions.typ) == "string") and (tabOptions.typ == evt.typ) then table.insert( tabOptions.testGroup, { evt.typ, evt.key, evt.name, evt.wkt } ) elseif (type(tabOptions) == "table") and (type(tabOptions.typ) == "string") and (tabOptions.typ == "v") then table.insert( tabOptions.testGroup, { evt.typ, evt.key, evt.name, evt.wkt } ) else tabOptions = {} table.insert( tabOptions.testGroup, { evt.typ, evt.key, evt.name, evt.wkt } ) end end -- function events.selector( tabOptions, evt ) function events.categ_Test(t) -- test of categories local memo = events.save_configs() -- Save global configuration before eventual changes. translate.init_wiki_user_page_lang() -- restore previous langages local t = t or "\n* These categ_Test test the function <b>add_cat</b> : " .. viewer.ta("user_lang", translate.user_lang) .. viewer.ta("wiki_lang", translate.wiki_lang) t = t .. "<br>" .. luaTable.formSubCounts("events.i18n") local tabView = { testGroup = { -- events.testGroup { typ = "cat", funcname = "add_cat", user_lang = nil, wiki_lang = nil, key = "datas_no_args_wikidata_err", }, { typ = "cat", funcname = "add_cat", user_lang = nil, wiki_lang = nil, key = "versioning_module_usage_error_cat", }, { typ = "cat", funcname = "add_cat", user_lang = "en", wiki_lang = nil, key = "modes_no_source_arguments_cat", }, { typ = "cat", funcname = "add_cat", user_lang = "es", wiki_lang = nil, key = "modes_no_source_arguments_err", }, { typ = "cat", funcname = "add_cat", user_lang = "en", wiki_lang = "es", key = "datas_no_args_wikidata_err", }, { typ = "cat", funcname = "add_cat", user_lang = "fr", wiki_lang = "en", key = "modes_no_source_arguments_cat", }, { typ = "cat", funcname = "add_cat", user_lang = "es", wiki_lang = "en", key = "modes_no_source_arguments_cat", }, { typ = "cat", funcname = "add_cat", user_lang = "en", wiki_lang = "x-y-z", key = "modes_no_source_arguments_cat", }, { typ = "cat", funcname = "add_cat", user_lang = "x-y-z", wiki_lang = "en", key = "modes_no_source_arguments_cat", }, }, headers = "events_test_categ_Test_headers", -- headers = "Test type;user language;wiki language;Categories", } modes.catView = ":" local cat_test = {} -- cat_test.memo, cat_test.events = events.init_configs(cat_test, tabOptions, add_cat_tests) -- Initialize global configurations and save them before eventual changes. function tabView.tableView_form_one_case(test) -- For each case: ac_opt = testOptions.testGroup[i] if test.funcname == "add_cat" then test.catext = events.form(test) --, luaTable.toList(test.vals) ) return { (test.funcname or "-"), (test.user_lang or "-"), (test.wiki_lang or "-"), (test.catext or "-") } elseif test.funcname == "catGroup" then test.catext = events.catGroup(test.key) --, luaTable.toList(test.vals) ) return { (test.funcname or "-"), (test.user_lang or "-"), (test.wiki_lang or "-"), (test.catext or "-") } end end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function events.categ_Test(t) function events.all_kinds_test(t) -- Test: all kinds of events (err, wng, cat) local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* Test the function <b>add_cat</b> : " .. viewer.ta("user_lang", translate.user_lang) .. viewer.ta("wiki_lang", translate.wiki_lang) local tabView = { testGroup = { -- events_all_kinds_tests_title { typ = "err", key= "mathroman_char_X_in_N_err", v = { [1] = "Y", [2] = 5 }, name = "mathroman_roman2int", wkt = "character Y in 5", }, { typ = "cat", key= "modes_no_source_arguments_cat", name = "math_ro_man", wkt = "Module with internal error", }, { typ = "err", key= "modes_is_undefined_err", v = { [1] = "birthyear", [2] = 1989 }, name = "xyz", wkt = "The argument birth:<b>1789</b> is not defined.", }, { typ = "XXXXX", key= "tools_strange_XXXXX", v = { [1] = "blabla", }, name = "xyz", wkt = "The argument birth:<b>1789</b> is not defined.", }, { typ = "wng", key= "translate_user_wiki_lang_msg", v = { [1] = "Spanish", [2] = "French" }, name = "modes_no_source_arguments_cat", wkt = "Languages: user: Polish, wiki: Greek.", }, { typ = "cat", key= "modes_language_cat", v = { [1] = "Spanish", }, wkt = "Speaking Spanish", }, }, headers = "typ;key;idargs;result", } function tabView.tableView_form_one_case(evt) -- Generally to define: Convert a case from testGroup to rowGroup. local res, evt = events.form(evt) return { evt.typ or "t", evt.key or "k", evt.idargs or "i", evt.res or "r" } end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function events.all_kinds_test(t) function events.selectLang( lang ) -- Select a language for tests or other purpose. if type(lang) ~= "string" then lang = "user_lang" end -- default is user language -- Select between : user_lang wiki_lang tests en es fr or any available in i18n. if lang == "tests" then lang = "tests" elseif translate.main_i18n and translate.main_i18n[lang] then lang = lang -- available in i18n elseif lang == "user_lang" then lang = translate.user_lang elseif lang == "wiki_lang" then lang = translate.wiki_lang else lang = translate.user_lang end -- default is user language return lang end -- function events.selectLang( lang ) function events.selectLang_test(t) -- Tests: Select a language for tests or other purpose. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* Test <b>events.selectLang()</b> :" -- events_selectLang_tests_title local tabView = { testGroup = { -- events.testGroup { wiki_lang = "en", user_lang = "fr", sought = "wiki_lang", }, { wiki_lang = "en", user_lang = "es", sought = "user_lang", }, { wiki_lang = "en", user_lang = nil , sought = "wiki_lang", }, { wiki_lang = nil , user_lang = "es", sought = "user_lang", }, { wiki_lang = "fr", user_lang = "es", sought = "tests", }, }, headers = "events_selectLang_test_headers" -- headers = "Wiki language; User language; Sought language; Selected language; Example", } function tabView.tableView_form_one_case(case) -- Generally to define: Convert a case from testGroup to rowGroup. local selected = events.selectLang( lang ) local example = viewer.form9user("events_selectLang_test_example") if selected == "tests" then example = translate.formTestCase("selectLang", case.wiki_lang, case.user_lang, case.sought) end return { tostring(case.wiki_lang), tostring(case.user_lang), tostring(case.sought), tostring(selected), tostring(example), } end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- events.selectLang_test( lang ) function events.tableView_form_all_cases_old(testOptions) -- Run tableView_form_one_case() for all cases in testGroup{}. Can reject some cases as nil. if type(testOptions) ~= "table" then testOptions = { -- options for viewer.tableView() -- Form a table with lines and columns. headers = "typ;key;idargs;result", kind = "projects", -- mediawiki or projects typ = "err", testGroup = {}, -- tests or testOptions.testGroup or rowGroup = {}, -- tests or testOptions.testGroup or } end if type(testOptions.testGroup) ~= "table" then testOptions.testGroup = { -- cases for tests { typ = "err", key = "events_err", idargs = "arg1", }, { typ = "wng", key = "events_wng", idargs = "arg1", }, { typ = "cat", key = "events_cat", idargs = "arg1", }, } end function test1(evt) -- For each case: ac_opt = testOptions.testGroup[i] local res, evt = events.form(evt) -- evt.res, evt = events.form(evt) return { evt.typ or "t", evt.key or "k", evt.idargs or "i", evt.res or "r" } end if type(testOptions.cccccccccccccccccccccccc) ~= "function" then testOptions.tableView_form_one_case = test1 end testOptions.rowGroup = testOptions.rowGroup or {} local j = 0 for i, case_opt in ipairs(testOptions.testGroup) do local case_result = testOptions.tableView_form_one_case(case_opt) -- A case can be nil and rejected if case_result then j = j + 1 table.insert( testOptions.rowGroup, case_result ) end -- table.insert( testOptions.rowGroup, testOptions.tableView_form_one_case(case_opt) ) end return testOptions.rowGroup, j end -- function events.tableView_form_all_cases(testOptions) function events.tableView_form_all_cases(testOptions) -- Run tableView_form_one_case() for all cases in testGroup{}. Can reject some cases as nil. testOptions.rowGroup = testOptions.rowGroup or {} for i, case_in in ipairs(testOptions.testGroup) do local case_out = testOptions.tableView_form_one_case(case_in) -- A case can be nil and rejected if case_out then table.insert(testOptions.rowGroup, case_out) end end return testOptions.rowGroup end -- function events.tableView_form_all_cases(testOptions) events.errors_list = {} -- Deprecated: Table to collect errors and warnings events.erron = true -- Activated or not errors. Errores activado o no. Erreurs activées ou non. events.categories_list = {} -- Table to collect all categories to generate in wikitext modes.catView = "" -- = ":" to document a category rather than truly categorize it function events.error_add(typ, ref, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- Add a warning, error or category to le lists. -- events.add_err("modes_value_re_defined_err", k, key, xyz) if not events.erron then return "" end local wng = { ["typ"] = typ, ["ref"] = ref, ["v1"] = v1, ["v2"] = v2, ["v3"] = v3, ["v4"] = v4, ["v5"] = v5, ["v6"] = v6, ["v7"] = v7, ["v8"] = v8, ["v9"] = v9 } local str = viewer.form9user(wng.ref, wng.v1, wng.v2, wng.v3, wng.v4, wng.v5, wng.v6, wng.v7, wng.v8, wng.v9) local do_it = true for k, reg in ipairs(events.errors_list) do -- If the new error was previously registered, do not add it. local reg_txt = viewer.form9user(reg.ref, reg.v1, reg.v2, reg.v3, reg.v4, reg.v5, reg.v6, reg.v7, reg.v8, reg.v9) if str == reg_txt then do_it = false end end if do_it then table.insert(events.errors_list, wng) end local res = "" if wng.typ == "wng" then res = '<br>⦁ ' .. viewer.warningColor(str) end if wng.typ == "err" then res = '<br>⦁ ' .. viewer.errorColor(str) end return tostring(res) end -- function events.error_add(typ, ref, v1, v2, v3, v4, v5, v6, v7, v8, v9) function events.add_err(key, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- return events.error_add("err", ref, v1, v2, v3, v4, v5, v6, v7, v8, v9) .. ";" -- return viewer.form9user(key, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- events.error_add("err", ref, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- events.add_err(key, v1, v2, v3, v4, v5, v6, v7, v8, v9) return events.error_add("err", v1, v2, v3, v4, v5, v6, v7, v8, v9) end function events.add_wng(key, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- return viewer.form9user(key, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- events.error_add("wng", ref, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- events.add_err(key, v1, v2, v3, v4, v5, v6, v7, v8, v9) return events.error_add("wng", v1, v2, v3, v4, v5, v6, v7, v8, v9) end function events.errors_lister(title, v1, v2, v3, v4, v5, v6, v7, v8, v9) local res, msgref = "", "" local mwtitle = mw.title.getCurrentTitle() local page = tostring(mwtitle.nsText) .. ":" .. tostring(mwtitle.text) if type(title) ~= "string" then title = "modes_error_list_header_err" end res = res .. '\n*' .. viewer.form9user(title, page, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- .. ' - ' .. page local n = 0 for k, wng in ipairs(events.errors_list) do msgref = viewer.form9user(wng.ref, wng.v1, wng.v2, wng.v3, wng.v4, wng.v5, wng.v6, wng.v7, wng.v8, wng.v9) -- texte traduit ou direct if wng.typ == "wng" then res = res .. '<br>⦁ ' .. viewer.warningColor(msgref) end end for k, wng in ipairs(events.errors_list) do msgref = viewer.form9user(wng.ref, wng.v1, wng.v2, wng.v3, wng.v4, wng.v5, wng.v6, wng.v7, wng.v8, wng.v9) -- texte traduit ou direct if wng.typ == "err" then res = res .. '<br>⦁ ' .. viewer.errorColor(msgref) n = n + 1 end end if n > 0 then events.add_cat("versioning_module_with_error_err") end return res end -- function events.errors_lister(title, v1, v2, v3, v4, v5, v6, v7, v8, v9) function events.gener_categories(args_final) -- Only for this library, form categories without activate them local args_final = args_final if type(args_final) ~= "table" then args_final = modes.args_final end if args_final.birthyear then events.add_cat("p_authors_birthyear_cat", args_final.birthyear) end if args_final.deathyear then events.add_cat("p_authors_deathyear_cat", args_final.deathyear) end if args_final.description then -- events.add_cat("p_authors_deathyear_cat", args_final.description) end return end -- function events.gener_categories(args_final) -- - - - ------------------ - - - - --------------------------------- -- Manage categories. Administrar categorías. Gérer les catégories. -- - - - ------------------ - - - - --------------------------------- -- Record in categories_list and generate the wikitext of a category function events.add_cat(ref, v1, v2, v3, v4, v5, v6, v7, v8, v9) -- add a category to the categories_list local cat = { ["typ"] = "cat", ["ref"] = ref, ["v1"] = v1, ["v2"] = v2, ["v3"] = v3, ["v4"] = v4, ["v5"] = v5, ["v6"] = v6, ["v7"] = v7, ["v8"] = v8, ["v9"] = v9 } local str = viewer.form9user(cat.ref, cat.v1, cat.v2, cat.v3, cat.v4, cat.v5, cat.v6, cat.v7, cat.v8, cat.v9) local do_it = true for k, reg in ipairs(events.categories_list) do -- If the new category was previously registered, do not add it. local reg_txt = viewer.form9user(reg.ref, reg.v1, reg.v2, reg.v3, reg.v4, reg.v5, reg.v6, reg.v7, reg.v8, reg.v9) if str == reg_txt then do_it = false end end if do_it then table.insert(events.categories_list, cat) end -- local c = modes.catView or modes.catView or "" -- if modes.catView == true or modes.catView == true then c = ":" else c = "" end local wiki_catspace = mw.site.namespaces.Category.name -- translate.wiki_translations.category or local user_catspace = mw.site.namespaces.Category.name -- translate.user_translations.category or local user_cat = viewer.trans9vars(translate.user_translations, cat.ref, cat.v1, cat.v2, cat.v3, cat.v4, cat.v5, cat.v6, cat.v7, cat.v8, cat.v9) local wiki_cat = viewer.trans9vars(translate.wiki_translations, cat.ref, cat.v1, cat.v2, cat.v3, cat.v4, cat.v5, cat.v6, cat.v7, cat.v8, cat.v9) -- user_cat = (user_cat or "") local user_verif = string.match( user_cat, "([%w_])") -- verif content with all alphanumeric characters. if not user_verif then user_verif = ":" .. user_cat .. ":" end -- user_cat = user_verif or ("<" .. user_cat .. ">") -- user_catspace = "" -- without "Category" word local wiki_catspace = mw.site.namespaces.Category.name -- name: Local namespace name. local res = " [[" .. c .. wiki_catspace .. ":" .. wiki_cat .. "|" .. user_catspace .. " " .. user_cat .. "]] " local link = " [[:" .. wiki_catspace .. ":" .. wiki_cat .. "|" .. user_catspace .. " " .. user_cat .. "]] " return res, link end -- function events.add_cat(ref, v1, v2, v3, v4, v5) -- - - - ------------------ - - - - --------------------------------- tools -- generate the wikitext of the list of categories to only display them function events.categories_lister(c) local res = "" -- "\n* Catégories : " local wiki_cat = "" local user_cat = "" modes.options_to_catView() -- c can replace catView to enforce the documentation or the categorisation -- c peut remplacer catView pour forcer la documentation ou la catégorisation c = c or modes.catView or "" local user_catspace = mw.site.namespaces.Category.name -- Local namespace name. local wiki_catspace = mw.site.namespaces.Category.name -- Local namespace name. for k, cat in ipairs(events.categories_list) do user_cat = viewer.trans9vars(translate.user_translations, cat.ref, cat.v1, cat.v2, cat.v3, cat.v4, cat.v5, cat.v6, cat.v7, cat.v8, cat.v9) wiki_cat = viewer.trans9vars(translate.wiki_translations, cat.ref, cat.v1, cat.v2, cat.v3, cat.v4, cat.v5, cat.v6, cat.v7, cat.v8, cat.v9) user_catspace = "" -- without "Category" word user_cat = (user_cat or "") -- prize if user_cat == " " then user_cat = "" end if user_cat == " " then user_cat = "" end if user_cat == " " then user_cat = "" end -- local user_verif = string.match( user_cat, "([%w_])") -- verif content with all alphanumeric characters. -- user_verif = mw.ustring.gsub( user_cat, "(%s)", "") -- verif content with all alphanumeric characters. local user_verif = mw.ustring.gsub( user_cat, "%s", "") -- verif content with all alphanumeric characters. if not user_verif then user_verif = "1" .. user_cat .. "2" end -- user_cat = user_verif or ("<" .. user_cat .. ">") res = res .. " [[" .. c .. wiki_catspace .. ":" .. wiki_cat .. "|" .. user_catspace .. user_cat .. "]] " end -- Category namespaces = 14 Category -- https://en.wikipedia.org/wiki/IETF_language_tag -- https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes return res end -- function events.categories_lister(c) -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:luaTable enhances the support of previous table library from Lua. -- "luaTable" avoids ambiguities with other kind of tables. -- To enhance, we could write here : luaTable = table. -- see Extension:Scribunto/Lua reference manual : class nameTest extends Scribunto_LuaEngineTestBase -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- luaTable = {} -- already declared by Scribunto, else in _G space. -- Translations for luaTable library luaTable.i18n = {} luaTable.i18n.en = { luaTable_recursive_luaTable_title = "Mediawiki recursive luaTable", luaTable_from_subnames_test_title = "<b>luaTable.from_subnames_test()</b> Test: Get the last sub-table from a sub-table name.", luaTable_roughView_tests_title = "luaTable.roughView() Test: Form a rough LUA code of a table", luaTable_structure_level_maxi = "Level limit recursiveLimit = <b>%1</b> ", luaTable_table_listlimit_max_n = "Length limit max_n = <b>%1</b> ", luaTable_structure_nolimits_title = "luaTable.structure() List a table, test without limits:", luaTable_structure_limits_title = "luaTable.structure() List a table, test with limits:", luaTable_toList_tests_title = "luaTable.toList() Return a list from a LUA table.", luaTable_toTable_tests_title = "luaTable.toTable() Test: convert a string to a table of words", luatable_form_subcounts_subtables = "The table <b>%1</b> counts <b>%2</b> values, <b>%3</b> sub-tables and <b>%4</b> functions.", luaTable_from_subnames_base_err = "Internal error: in luaTable.from_subnames(), base unavailable for the subnames table %1.", luaTable_from_subnames_subtable_err = "Internal error: in luaTable.from_subnames(), <b>%1</b> is not a sub-table in subnames <b>%2</b>.", luaTable_formSubCounts_type_err = "A <b>%1</b> replaces the table: <b>%2</b>.", luaTable_fromSubNames_missing_err = "Internal error: in luaTable.formSubCounts() The search for this sub-table <b>%1</b> found only this one <b>%2</b>.", luaTable_from_subnames_tests_headers = "Sub name; Base table; Table count; Input luaTable.roughView", -- Miscellaneous warnings and errors luaTable_table_dont_exists_err = "The table <b>%1</b> does not exist.", -- Titles of tests luaTable_table_args_source_title = "luaTable.structure() Table of received arguments, args_source:", luaTable_table_args_unknown_title = "luaTable.structure() Table of unknown arguments, args_unknown:", } -- luaTable.i18n.en luaTable.i18n.es = { luaTable_recursive_luaTable_title = "Mediawiki luaTable recursiva", luaTable_from_subnames_test_title = "<b>luaTable.from_subnames_test()</b> Prueba: Obtener la última sub-tabla de un nombre de sub-tabla.", luaTable_roughView_tests_title = "luaTable.roughView() Prueba: Formar un código de LUA grueso de una tabla", luaTable_structure_level_maxi = "Límite de nivel recursiveLimit = <b>%1</b> ", luaTable_table_listlimit_max_n = "Límite de longitud max_n = <b>%1</b> ", luaTable_structure_nolimits_title = "luaTable.structure() Enumerar una tabla, prueba sin límites:", luaTable_structure_limits_title = "luaTable.structure() Enumerar una tabla, prueba con límites:", luaTable_toList_tests_title = "luaTable.toList() Devolver una lista de una tabla LUA.", luaTable_toTable_tests_title = "Prueba: convertir una cadena en una tabla de palabras", luatable_form_subcounts_subtables = "La tabla <b>%1</b> cuenta <b>%2</b> valores, <b>%3</b> sub-tablas y <b>%4</b> funciones.", luaTable_from_subnames_base_err = "Error interno: en luaTable.from_subnames(), base no disponible para la tabla subnames %1.", luaTable_from_subnames_subtable_err = "Error interno: en luaTable.from_subnames(), %1 no es una sub-tabla en subnames <b>%2</b>.", luaTable_formSubCounts_type_err = "Un <b>%1</b> reemplaza la tabla: <b>%2</b>.", luaTable_fromSubNames_missing_err = "Error interno: in luaTable.formSubCounts() La búsqueda de este subtabla <b>%1</b> encontró que <b>%2</b>.", luaTable_from_subnames_tests_headers = "Sub nombre; Mesa base; Tamaño de la mesa; luaTable.roughView de entrada", -- Textos principales, errores y categorías de instrumentos -- Diversos mensajes y errores luaTable_table_dont_exists_err = "La tabla <b>%1</b> no existe.", -- Titres des pruebas luaTable_table_args_source_title = "luaTable.structure() Tabla de argumentos recibido, args_source:", luaTable_table_args_unknown_title = "luaTable.structure() Tabla de argumentos desconocidos, args_unknown:", } -- luaTable.i18n.es luaTable.i18n.fr = { luaTable_recursive_luaTable_title = "Mediawiki luaTable récursive", luaTable_from_subnames_test_title = "<b>luaTable.from_subnames_test()</b> Test: Obtenir la dernière sous-table à partir d'un nom de sous-table.", luaTable_roughView_tests_title = "luaTable.roughView() Test: Former un code LUA grossier d'une table", luaTable_structure_level_maxi = "Limite de niveau recursiveLimit = <b>%1</b> ", luaTable_table_listlimit_max_n = "Limite de longueur max_n = <b>%1</b> ", luaTable_structure_nolimits_title = "luaTable.structure() Lister une table, test sans limites :", luaTable_structure_limits_title = "luaTable.structure() Lister une table, test avec limites :", luaTable_toList_tests_title = "luaTable.toList() Retourne une liste à partir d'une table LUA.", luaTable_toTable_tests_title = "luaTable.toTable() Test: convertir une phrase en table de mots", luatable_form_subcounts_subtables = "La table <b>%1</b> compte <b>%2</b> variables, <b>%3</b> sous-tables, <b>%4</b> fonctions.", luaTable_from_subnames_base_err = "Erreur interne: dans luaTable.from_subnames(), base indisponible pour la table subnames %1.", luaTable_from_subnames_subtable_err = "Erreur interne: dans luaTable.from_subnames(), %1 n'est pas une sous-table dans subnames <b>%2</b>.", luaTable_formSubCounts_type_err = "Un <b>%1</b> remplace la table : <b>%2</b>.", luaTable_fromSubNames_missing_err = "Erreur interne : in luaTable.formSubCounts() La recherche de cette sous-table <b>%1</b> n'a trouvé que celle-ci <b>%2</b>.", luaTable_from_subnames_tests_headers = "Sous-nom; Table de base; Taille de la table; Entrée luaTable.roughView", -- Principaux textes, erreurs et catégories des outils -- Messages et erreurs divers luaTable_table_dont_exists_err = "La table <b>%1</b> n'existe pas.", -- Titres des tests luaTable_table_args_source_title = "luaTable.structure() Table des arguments reçus, args_source :", luaTable_table_args_unknown_title = "luaTable.structure() Table des arguments inconnus, args_unknown :", } -- luaTable.i18n.fr function luaTable.formSubCounts(tabname, tablebase, text_form) -- Form text of translations counts of a i18n table. local opt, i18n_name = {}, "translate.main_i18n" -- for any tables local i, k, t = 0, 0, "" local subtab, err, t2, sub_name = {}, "", "", "" -- Adapt to available parameters. local default_form = "luatable_form_subcounts_subtables" -- "translate_main_i18n_languages_count" -- if (type(text_form) == "string") then text_form = text_form elseif (type(tablebase) == "string") then text_form = tablebase else text_form = default_form end -- if (type(tablebase) ~= "table") then tablebase = package.loaded end -- if (type(tabname) == "string") then subtable, sub_names = luaTable.from_subnames(tabname, tablebase) -- Get the last sub-table from its sub-names --local object_loaded, sub_names, count = luaTable.from_subnames(subnames, base_table, sub_type) else subtable, sub_names = nil, "" end local tot_vars, tot_tabs, tot_func, vr_tb = luaTable.SubCounts(subtable, tabname) t = t .. viewer.form9user(text_form, tabname, tot_vars, tot_tabs, tot_func) return t, tot_vars, tot_tabs, tot_func, vr_tb end -- local t, tot_vars, tot_tabs, tot_func, vr_tb = luaTable.formSubCounts(tabname, tablebase, text_form) function luaTable.from_subnames(subnames, base_table, sub_type) -- Get the last sub-table from its sub-names. if (type(subnames) ~= "string") then subnames = "." end -- if (type(base_table) ~= "table") then base_table = package.loaded end -- Default base_table for libraries and modules. -- if (type(base_table) ~= "table") then base_table = _G end -- Default base_table for not loaded libraries. -- luaTable_from_subnames_base_err = "Internal error: in luaTable.from_subnames(), base unavailable for the subnames table %1.", local part_names, k = "", "" local count, errs = 0, ", errs: " local sub_names = mw.text.split(subnames, '.', true) local sub_names_1 = sub_names[1] -- Default base_table for libraries and modules. if (type(base_table) ~= "table") and (type(sub_names_1) == "string") and (type(package.loaded[sub_names_1]) == "table") then base_table = package.loaded end -- if (type(base_table) ~= "table") then base_table = _G end -- Default base_table for not loaded libraries. if (type(base_table) ~= "table") and (type(sub_names_1) == "string") and (type(_G[sub_names_1]) == "table") then base_table = _G end -- if (type(base_table) ~= "table") then base_table = _G end local sub_table = base_table local object_loaded = sub_table if (type(base_table) == "table") then for i, partname in ipairs(sub_names) do k = k .. viewer.ta('<br> i', i) .. viewer.ta('partname', partname) object_loaded = sub_table[partname] if (type(object_loaded) == "table") then part_names = part_names .. "." .. partname sub_table = object_loaded count = luaTable.level_count(object_loaded) k = k .. viewer.ta('count', count ) elseif (sub_type == "function") and (type(object_loaded) == "function") then return object_loaded, sub_names, count -- luaTable.from_subnames(subnames, base_table, "function") Content( elseif (sub_type == "string") and (type(object_loaded) == "string") then return object_loaded, sub_names, count -- luaTable.from_subnames(subnames, base_table, "string") else k = k .. viewer.ta('break') sub_table = nil errs = errs .. "; err = " .. events.add_err("luaTable_from_subnames_subtable_err", partname, subnames) -- luaTable_from_subnames_subtable_err = "Internal error: in luaTable.from_subnames(), <b>%1</b> is not a sub-table in subnames <b>%2</b>." errs = errs .. events.add_cat("versioning_with_internal_error_cat") -- Catégorie:Module avec erreur interne -- versioning_with_internal_error_cat = "Module with internal error", = "Module avec erreur interne", break end end else errs = errs .. "; err = " .. events.add_err("luaTable_from_subnames_subtable_err", partname, subnames) errs = errs .. events.add_cat("versioning_with_internal_error_cat") -- versioning_with_internal_error_cat = "Module with internal error", end sub_names = table.concat(sub_names, ".") -- return sub_table, k .. sub_names .. errs, count -- or nil object_loaded = object_loaded or sub_table return object_loaded, sub_names, count -- or nil -- local object_loaded, sub_names, count = luaTable.from_subnames(subnames, base_table, sub_type) end -- return subname, subtable, used_names -- = luaTable.formSubCounts(subname, subtable) -- Get the last sub-table from a sub-table name. function luaTable.from_subnames_test(t) -- Test: Get the last sub-table from a sub-table name. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>luaTable.from_subnames_test()</b> Test: Get the last sub-table from a sub-table name." -- local count = 0 local t3 ,t2 = "", "\n* from_subnames_test() details: " local object_loaded, sub_names, count = luaTable.from_subnames("datas", nil) if sub_table then t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else t3 = "" end t2 = t2 .. "\n* " .. viewer.ta("datas, nil", part_names) .. viewer.ta("count", count) .. t3 local object_loaded, sub_names, count = luaTable.from_subnames("modes", _G) if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* " .. viewer.ta("modes, _G", part_names) .. viewer.ta("count", count) .. t3 local object_loaded, sub_names, count = luaTable.from_subnames("versioning", nil) if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* " .. viewer.ta("versioning, nil", part_names) .. viewer.ta("count", count) .. t3 local object_loaded, sub_names, count = luaTable.from_subnames("viewer", _G) if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* " .. viewer.ta("viewer, _G", part_names) .. viewer.ta("count", count) .. t3 -- local object_loaded, sub_names, count = luaTable.from_subnames("luaTable.i18n") if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* " .. viewer.ta("luaTable.i18n, nil", part_names) .. viewer.ta("count", count) .. t3 local object_loaded, sub_names, count = luaTable.from_subnames("luaTable.i18n.es") if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* normal: " .. viewer.ta("luaTable.i18n.es, nil", part_names) .. viewer.ta("count", count) .. t3 local object_loaded, sub_names, count = luaTable.from_subnames("i18n.es", events) if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* " .. viewer.ta("i18n.es, events", part_names) .. viewer.ta("count", count) .. t3 local object_loaded, sub_names, count = luaTable.from_subnames("es", events.i18n) if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* " .. viewer.ta("es, events.i18n", part_names) .. viewer.ta("count", count) .. t3 local object_loaded, sub_names, count = luaTable.from_subnames("", events.i18n.es) if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* missing names: " .. viewer.ta("-events-", luaTable.i18n.es, part_names) .. viewer.ta("count", count) .. t3 -- local object_loaded, sub_names, count = luaTable.from_subnames(".", luaTable.i18n.es) if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* " .. viewer.ta(".", luaTable.i18n.es, part_names) .. viewer.ta("count", count) .. t3 local object_loaded, sub_names, count = luaTable.from_subnames("xyz", luaTable.i18n.es) if sub_table then count = count ; t3 = viewer.ta("library.is_binded_in", sub_table.is_binded_in) else count = 3 ; t3 = "" end t2 = t2 .. "\n* " .. viewer.ta("xyz", luaTable.i18n.es, part_names) .. viewer.ta("count", count) .. t3 -- local tabTest = { aa1 = { bb1 = { cc2 = { "v1", "v2" }, cc3 = { "v1", "v2", "v3" }, }, bb2 = { "b1", "b2" }, }, aa2 = { "a1", "a2" } } local tabView = { testGroup = { -- versioning.deprecatedFunctionGroup { "one_two_three", { "one", "two", "three" }, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "tabTest", tabTest, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "aa1", tabTest, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "aa1.bb1", tabTest, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "aa1.bb1.cc2", tabTest, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "aa2", tabTest, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "aa2.bb1", tabTest, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "aa1.bb1.cc3", tabTest, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "aa1.bb1.cc4", tabTest, "luaTable : name=%1, t=%2, l=%3, t/l=%4." }, { "luaTable.i18n", luaTable.i18n, "luaTable.i18n : name=%1, t=%2, l=%3, f() n=%4." }, { "luaTable.i18n.es", luaTable.i18n.es,"luaTable.i18n.es : name=%1, t=%2, l=%3, f() n=%4." }, { "begin.i18n", begin.i18n, "luatable_form_subcounts_subtables" }, { "begin.i18n.vi", begin.i18n.vi, "luatable_form_subcounts_subtables" }, { "begin", "luatable_form_subcounts_subtables" }, -- debug { "begin.i18n", "luatable_form_subcounts_subtables" }, -- debug { "luaTable.i18n", "luaTable.i18n : name=%1, t=%2, l=%3, f() n=%4." }, { "luaTable.i18n.en", "luaTable.i18n.en : name=%1, t=%2, l=%3, f() n=%4." }, { "versioning.i18n", versioning.i18n }, -- { "versioning.i18n", "versioning : name=%1, t=%2, l=%3, f() n=%4." }, -- { "versioning.main_i18n",versioning.main_i18n }, -- debug -- { "versioning.main_i18n", "versioning : name=%1, t=%2, l=%3, f() n=%4." }, { "translate.main_i18n",translate.main_i18n }, -- debug { "translate.main_i18n.fr",translate.main_i18n.fr }, -- debug -- { "translate.main_i18n", "translate : name=%1, t=%2, l=%3, f() n=%4." }, -- debug }, title_memo = "versioning_tasks_report_title", -- "versioning.versioning_tasks_report() States of known tasks", headers = "versioning_tasks_report_headers", -- "Importance; Task; State; Title; In short", headers = "sub name; sub_name; table count; input luaTable.roughView ...", } function tabView.tableView_form_one_case(case) -- Generally to define: Convert a case from testGroup to rowGroup. local sub_name_1, sub_table_1, form_counts = case[1], case[2], case[3], case[4] local errs = "" local subtable, sub_names, count = luaTable.from_subnames(sub_name_1, sub_table_1) -- Get the last sub-table from a sub-table name. local tot_vars, tot_tabs, tot_func, vr_tb = luaTable.SubCounts(subtable, sub_name_1) t = t .. viewer.form9user(form_counts, tabname, tot_vars, tot_tabs, tot_func) form_counts = tostring(form_counts) local roughView = luaTable.roughView(subtable) -- Form a rough LUA code to understand the structure of the input table. if string.len(roughView) > 333 then roughView = string.sub(roughView, 1, 333) .. " <br/><b>. . . limited display.</b>" end return { sub_name, viewer.ta("used_tables", used_names) .. viewer.ta("sub_table_count", sub_table_count) .. (errs2 or ""), form_counts, viewer.ta("used_name", used_name) .. viewer.ta("used_names", used_names) .. " roughView = " .. roughView } end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.headers = "formSubCounts; used_names + sub_table_count; form_counts .. errs; result roughView" -- tabView.testGroup = testGroup tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t2 .. t end -- function luaTable.from_subnames_test(t) function luaTable.toList(tab, ...) -- Return a list from a LUA sequence table where i = 1 to n. -- This function is the reverse of func( ... ) if (type(tab) ~= "table") then tab = {} end local tab = mw.clone(tab) -- to not disturb original table local maxn = table.maxn(tab) local function tabN_to_list1(tab, n, ...) local max_tab = table.maxn(tab) local listab = {...} local max_list = table.maxn(listab) local tab_last = mw.clone(tab[n]) -- last element, even a table to not delete below tab_last = tostring(tab_last) if tab_last and (n <= max_tab) then tab[n] = nil return tab_last , tabN_to_list1(tab, n + 1, ...) else return end end return tabN_to_list1(tab, 1, ...) end -- function luaTable.toList(tab, ...) function luaTable.toList_tests(t) -- Return a list from a LUA table. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "Test the <b>luaTable.toList( tab )</b> which return a list from a LUA table." local function toList_tests1( case, tab ) local tabview = luaTable.roughView( tab ) local res_tab = { luaTable.toList( tab ) } local t1 = "" for i, elem in ipairs(res_tab) do t1 = t1 .. viewer.ta( "[" .. i .. "]", tostring(elem) ) end local t = viewer.Tr() .. viewer.Td(case) .. viewer.Td(tabview) .. viewer.Td(t1) return t end t = t .. viewer.Th() .. viewer.Tc("Tested case") .. viewer.Tc("Input table, roughView") .. viewer.Tc("Output list") t = t .. toList_tests1( "Simple table", { 123, "abc", key = "txt"} ) t = t .. toList_tests1( "All types transmited", { "name", 111, true, false, { 789, "xyz"}, function()end,} ) t = t .. toList_tests1( "10 values in the table", { "a", "b", "c", "d", "e", "f", "g", "h", "i9", "j10" } ) t = t .. toList_tests1( "Any number of values", { "a", "b", "c", "d", "e", "f", "g", "h", "i09", "j10", "a", "b", "c", "d", "e", "f", "g", "h", "i19", "j20", "a", "b", "c", "d", "e", "f", "g", "h", "i29", "j30", "a", "b", "c", "d", "e", "f", "g", "h", "i39", "j40", "a", "b", "c", "d", "e", "f", "g", "h", "i49", "j50", "a", "b", "c", "d", "e", "f", "g", "h", "i59", "j60", } ) t = t .. viewer.Te() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function luaTable.toList_tests(t) function luaTable.toTable(stringList, pattern, plain) -- convert a string to a table of words if type(stringList) ~= "string" then stringList = "" end if type(pattern) ~= "string" then pattern = "" end -- plain = plain or true if plain then plain = true else plain = false end plain = true local tab = mw.text.split(stringList, pattern, plain) local tab2 = {} for i, word in ipairs(tab) do -- for all names -- word = mw.text.trim(word) -- clean spaces in each name tab2[word] = word -- table.insert(tab2, name) end return tab2 end function luaTable.toTable_test(t) -- Test: convert a string to a table of words local memo = events.save_configs() -- Save global configuration before eventual changes. if type(stringList) ~= "string" then stringList = "" end if type(pattern) ~= "string" then pattern = "" end -- if type(plain) ~= "boolean" then plain = false end local t = t or "\n* stringToTable_test: " local group_test = { -- events.testGroup { stringList = "docview nocat : tests docline", pattern = nil, }, { stringList = "docview nocat : tests docline", pattern = " ", plain = nil, }, { stringList = "docview,nocat, : ,tests docline", pattern = ",", plain = true, }, { stringList = "docview docline : tests", pattern = " ", plain = true, }, { stringList = "docview; nocat; : tests; docline", pattern = ";", plain = false, }, { stringList = "abc ; ; def.;ghi;,jkl", pattern = ";", }, } local tabOptions = {} tabOptions.headers = viewer.form9user("stringList; pattern; plain; result") tabOptions.testGroup = group_test tabOptions.rowGroup = {} local function stringToTable_1(stringList, pattern, plain) -- convert a string to a table of words local test = {} test.result = luaTable.toTable(stringList, pattern, plain) test.result = table.concat(test.result) table.insert( tabOptions.rowGroup, { (test.stringList or "nil"), (test.pattern or "nil"), (test.plain or "nil"), (test.result or "nil") } ) table.insert( tabOptions.rowGroup, { tostring(test.stringList) .. "xx", tostring(test.pattern), tostring(test.plain) or "plain", tostring(test.result) } ) end if type(group_test) == "table" then for key, test in pairs(group_test) do test.table = luaTable.toTable(test.stringList, test.pattern, test.plain) test.result = " " for key, val in pairs(test.table) do test.result = test.result .. val .. " " end table.insert( tabOptions.rowGroup, { tostring(test.stringList), tostring(test.pattern), tostring(test.plain), luaTable.roughView(test.table) } ) end else t = t .. "error : stringToTable_test has no table. " end t = t .. viewer.tableView(tabOptions) -- Form a table with lines and columns. events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function luaTable.toTable_test(t) -- local tot_vars, tot_tabs, tot_func, vr_tb = luaTable.SubCounts(tablebase, tabname, opt, recursiveLevel) function luaTable.SubCounts(tablebase, tabname, opt, recursiveLevel) -- In a table, recursive counts of vars, sub-tables and functions. local opt = opt or {} opt.recursiveLevel = recursiveLevel or opt.recursiveLevel -- opt.recursiveLevel, opt.recursiveLimit, opt.recursiveLevel_err = modes.recursiveNormal(opt.recursiveLevel, opt.recursiveLimit) opt.recursiveLevel, opt.recursiveLimit, opt.recursiveLevel_err = modes.recursiveNormal(opt.recursiveLevel, modes.recursiveLimit) local isempty = true local tot_vars, tot_tabs, tot_func = opt.tot_vars or 0, opt.tot_tabs or 0, opt.tot_func or 0 -- luaTable.SubCounts(get.i18n, get.pagename) -- : attempt to index local 'opt' (a nil value). local nbr_vars, nbr_tabs, nbr_func = 0, 0, 0 local txt, vr, tb, fn, vrtb, vr_tb = "", 0, 0, 0, 0, 0 local case = "" if (type(tablebase) == "table") and (type(tabname) == "string") then -- for any tables -- normal case OK, do nothing case = " tab+name" elseif (type(tablebase) == "table") and (type(tabname) ~= "string") then -- for abnormal or missing tabname tabname = "tabname=" .. tostring(tablebase) .. "?" tabname = viewer.errorColor(tabname) case = " tab+noname" elseif (type(tablebase) ~= "table") and (type(tabname) == "string") then -- for abnormal table tabname = "tabname=" .. tostring(tabname) .. "?" tabname = viewer.errorColor(tabname) case = " notab+name" elseif type(tablebase) == "string" then -- for viewer.tables tabname = "package.loaded." .. tablebase -- tab = tools[tab] case = " tab=name" else tabname = "tabname=" .. tostring(tablebase) .. "?" tabname = viewer.errorColor(tabname) case = " notab+noname" end if (type(tablebase) == "table") and (type(tabname) == "string") then -- for normal cases for key, var in pairs(tablebase) do -- List and count vars, functions and sub tables local sub_tabname = tostring(key) if type(var) == "table" then local sub_tablebase = var nbr_tabs = nbr_tabs + 1 if (opt.recursiveLevel < opt.recursiveLimit) then -- if (opt.recursiveLevel > 0) and (opt.recursiveLevel < opt.recursiveLimit) then -- vr, tb, fn, vrtb, opt.recursiveLevel = luaTable.SubCounts(var, tabname, opt) opt.recursiveLevel = opt.recursiveLevel + 111 vr, tb, fn, vrtb = luaTable.SubCounts(sub_tablebase, sub_tabname, opt, opt.recursiveLevel) tot_vars = tot_vars + vr tot_tabs = tot_tabs + tb + 1 tot_func = tot_func + fn end elseif type(var) == "function" then nbr_func = nbr_func + 1 tot_func = tot_func + 1 isempty = false else -- type(var) == other nbr_vars = nbr_vars + 1 tot_vars = tot_vars + 1 isempty = false end end end local vr_tb = 0 if tot_tabs == 0 then vr_tb = tot_vars -- texts number in all languages else -- How many translations in each language? Approximative if not equal. vr_tb = tot_vars / tot_tabs -- texts number in one language, like + 33.49 vr_tb = math.floor( vr_tb ) -- digital texts number in each language end opt.tot_vars = tot_vars -- total number of variables in the table opt.tot_tabs = tot_tabs -- total number of sub-tables in the table opt.tot_func = tot_func -- total number of functions in the table opt.vr_tb = vr_tb -- digital texts number in each language return tot_vars, tot_tabs, tot_func, vr_tb -- , opt.recursiveLevel end -- local tot_vars, tot_tabs, tot_func, vr_tb = luaTable.SubCounts(tablebase, tabname, opt, recursiveLevel) function luaTable.level_count(tab) -- Count all objects in the table, or 0 if tab is not a table. local count = 0 if (type(tab) ~= "table") then return c end for k,v in pairs(tab) do count = count + 1 end return c end -- function luaTable.level_count(tab) function luaTable.level_get(tab, typ) -- Get only the first level of the table. Get only one key type if asked. local level = {} local count = 0 if (type(tab) ~= "table") then return level, count end for key, val in pairs(tab) do if (type(typ) == "string") and (type(val) == typ) then level[key] = val ; count = count + 1 else level[key] = val ; count = count + 1 end end return level, count end -- function luaTable.level_get(tab, typ) function luaTable.level_list(tab, typ, select, field) -- Get only the first level of the table. -- Get only the first level of the table. Select only keys containing select. Select the field as key if defined. -- for T20170130 Begin to use local list, count, level, split, ok = "", 0, {}, {}, false local sort = typ if sort == "sort" then typ = "string" end if (type(tab) ~= "table") then return list, count, level, split end for key, val in pairs(tab) do table.insert(level, val) ok = false if select == "true" then ok = true end if (type(val) == "table") and (type(field) == "string") and (type(key) == "string") then key = val[field] end if (type(typ) == "string") and (type(key) == "string") and viewer.is_in(key, select) then ok = true else ok = true ; key = tostring(key) end if ok then table.insert(split, key) count = count + 1 list = list .. key .. ", " end end -- split = level if sort == "sort" then table.sort(split, function (a, b, field) -- in recording order return ( a[field] < b[field] ) end ) end list = table.concat(split, ", ") return list, count, level, split end -- local list, count, level, split = luaTable.level_list(tab, typ, select, field) function luaTable.roughView(table, option) -- Form a rough LUA code to understand the structure of the table. if type(table) ~= "table" then return viewer.value(table) end local opt = option if type(opt) ~= "table" then opt = {} end -- local opt = opt or {} opt.level = (opt.level or 1) opt.recursiveLimit = tonumber(opt.recursiveLimit) or 11111 opt.max_n = tonumber(opt.max_n) or 11111 local shift = "\n" .. string.rep(":", opt.level) local t = "" local n = 0 local continue = true if opt.level > opt.recursiveLimit then -- Limit the number of levels of sub-tables to opt.recursiveLimit local col = viewer.warningColor( viewer.form9user( '%1 = %2', "recursiveLimit", opt.recursiveLimit) ) t = t .. viewer.form9user( '{ %1 }', col ) else shift = "\n" .. string.rep(":", opt.level) for k, v in pairs(table) do n = n + 1 if n > opt.max_n then -- Limit the number of elements in each-subtable to opt.max_n. local col = viewer.warningColor( viewer.form9user( '%1 = %2', "max_n", opt.max_n ) ) continue = false end if continue then if (type(v) == "string") then if (type(k) == "string") then -- t = t .. viewer.form9user( '%1 = "%2", ', k, v, shift ) if (string.gsub(k, "%x", "") == k) then t = t .. viewer.form9user( '%1 = "%2", ', tostring(k), v ) else t = t .. viewer.form9user( '["%1"] = "%2", ', tostring(k), v ) end else t = t .. viewer.form9user( '[%1] = "%2", ', tostring(k), v ) end -- if n == (#table - 0) then t = t .. ' }s# ' end elseif (type(v) == "table") or (type(v) == "function") then else if (type(k) == "string") then t = t .. viewer.form9user( '%1 = %2, ', k, tostring(v), shift ) else t = t .. viewer.form9user( '[%1] = %2, ', tostring(k), tostring(v), shift ) end end end end for k, v in pairs(table) do n = n + 1 if n > opt.max_n then local col = viewer.warningColor( viewer.form9user( '%1 = %2', "max_n", opt.max_n ) ) continue = false end if continue then -- Do not list if exclude1, exclude2 or exclude3 are in the table name. if (type(v) == "table") and (k ~= opt.exclude1) and (k ~= opt.exclude2) and (k ~= opt.exclude3) then opt.level = (opt.level or 1) + 1 shift = "\n" .. string.rep(":", opt.level) local tt = luaTable.roughView(v, opt) opt.level = (opt.level or 1) - 1 shift = "\n" .. string.rep(":", opt.level) t = t .. viewer.form9user( '%3 %1 = %2 ', k, tt, shift ) elseif (type(v) == "function") then t = t .. viewer.form9user( '%3 %1 = %2() ', k, "function", shift ) elseif (type(v) == "nil") then t = t .. viewer.form9user( '%3 %1 = %2() ', k, "nil", shift ) end end end end t = "{ " .. t .. " }" return t end -- function luaTable.roughView(table, opt) function testsCases.luaTabView(table, opt) return luaTable.roughView(table, opt) end -- Form a rough LUA code to understand the structure of the table. function testsCases.luaTabView_test(t) -- Deprecated alias function versioning.deprecatedFunction("testsCases.luaTabView_test", "luaTable.roughView_test") return luaTable.roughView_test(t) end function luaTable.roughView_test(t) -- Form a rough LUA code to understand the structure of the table. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "luaTable.roughView_test(t) : From a LUA table, re-form a string roughly equivalent to the table." local table_key = { "A table used as key.", key = "string", bar = "bartxt", } local table_value = { "A table used as value is expended in the main table.", abc = "ABC", [5] = "five", ghi = "JKL", } local tae_val = "A table used as value is expended in the main table." local function funcView() return "A function result in this string." end local test_table = { key = "string", "string one without key", [12] = "number key twelve", ["12"] = "string key twelve in brace", sub_table = { [4] = "four", abc = "ABC", [5] = "five", ghi = "JKL", }, func = funcView(), "string two without key", [tonumber] = "A function used as key.", -- [table_key] = "A table used as key.", -- table_as_value = table_value, [true] = "A LUA reserved value used as key.", } local t = t .. luaTable.roughView(test_table) events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function luaTable.roughView_test(t) -- - - - ------------------ - - - - --------------------------------- -- 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 luaTable.structure_recursive(tbl, uppername, name, recursiveLevel, opt) -- countonly, level_maxi, 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 list = not opt.countonly if recursiveLevel > opt.level_maxi then -- limit the number of the level of sub-tables local t_levelmaxi = viewer.form9user("luaTable_structure_level_maxi", recursiveLevel) return viewer.warningColor( tostring(t_levelmaxi ) ), tot_vars, tot_func, tot_tabs end opt.max_n = tonumber(opt.max_n) or 11111 shift = string.rep("*", recursiveLevel) -- Do not list if exclude1, exclude2 or exclude3 is in the table name. if type(opt.exclude1) == "string" and opt.exclude1 ~= "" and string.find(name, opt.exclude1) ~= nil then return "", tot_vars, tot_func, tot_tabs end if type(opt.exclude2) == "string" and opt.exclude2 ~= "" and string.find(name, opt.exclude2) ~= nil then return "", tot_vars, tot_func, tot_tabs end if type(opt.exclude3) == "string" and opt.exclude3 ~= "" and string.find(name, opt.exclude3) ~= nil then return "", tot_vars, tot_func, tot_tabs end if type(tbl) ~= "table" then -- display table error return '<br>The variable "' .. tostring(name) .. '" is not a table.<br>', tot_vars, tot_func, tot_tabs end for k, v in pairs(tbl) do -- List and count vars, functions and sub tables 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 if recursiveLevel <= opt.level_maxi then -- List recursively each sub-table st, vr, fn, tb = luaTable.structure_recursive(v, levelname, newname, recursiveLevel + 1, opt) -- countonly, level_maxi, max_n, exclude1, exclude2, exclude3) tot_vars = tot_vars + vr tot_func = tot_func + fn tot_tabs = tot_tabs + tb + 1 if list then lst_subtabs = lst_subtabs .. st end else local t_levelmaxi = viewer.form9user("luaTable_structure_level_maxi", recursiveLevel) if list then res = res .. " " .. viewer.warningColor( t_levelmaxi ) end end local sep = "" if max == opt.max_n then local luaTable_table_listlimit_max_n = viewer.form9user("luaTable_table_listlimit_max_n", opt.max_n) if list then res = res .. "\n" .. shift .. " Table <b>" .. levelname .. "</b> " .. viewer.warningColor(luaTable_table_listlimit_max_n) end break end elseif type(v) == "function" then nbr_func = nbr_func + 1 tot_func = tot_func + 1 isempty = false if list then lst_func = lst_func .. k .. sep end else -- type(v) == other nbr_vars = nbr_vars + 1 tot_vars = tot_vars + 1 isempty = false if list then lst_vars = lst_vars .. type(v) .. " - <b>" .. tostring(k) .. "</b> = " .. tostring(v) .. " " .. sep end end end if list then res = res .. "\n" .. shift .. " Table <b>" .. levelname .. "</b>, " .. tostring(nbr_vars) .. " vars: " .. lst_vars end if list then res = res .. "\n" .. shift .. " Table <b>" .. levelname .. "</b>, " .. tostring(nbr_func) .. " functions: " .. lst_func end if list then res = res .. "\n" .. shift .. " Table <b>" .. levelname .. "</b>, " .. tostring(nbr_tabs) .. " tables: " .. lst_tabs .. lst_subtabs end return res, tot_vars, tot_func, tot_tabs end -- function luaTable.structure_recursive(tbl, uppername, name, recursiveLevel, opt) -- countonly, level_maxi, max_n, exclude1, exclude2, exclude3) -- opt = { boxstyle = "boxstyle", level_maxi = 3, max_n = 2, exclude1 = "hou" } ) -- , {width = "88%", text_color = "blue"} function luaTable.structure(table, tablename, opt) -- luaTable_structure_limits_title = "List a table, test with limits:", local recursiveLevel, recursiveLimit, recursiveLevel_err = 1, 1111, "" local res = "\n* Content of the <b>" .. tostring(tablename) .. "</b> table, begin:" if not opt then opt = { recursiveLimit = 11111 } end local recursiveLevel = opt.recursiveLevel or 1 if versioning.main_i18n_complete then recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, modes.recursiveLimit) end -- local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, modes.recursiveLimit) if type(opt.level_maxi) ~= "number" then opt.level_maxi = 222 end -- opt.level_maxi = opt.level_maxi or 222 if type(opt.max_n) ~= "number" then opt.max_n = 3333 end opt.max_n = opt.max_n or 3333 opt.recursiveLevel = opt.recursiveLevel or recursiveLevel or 1 opt.exclude1 = opt.exclude1 or "" opt.exclude2 = opt.exclude2 or "" opt.exclude3 = opt.exclude3 or "" opt.countonly = opt.countonly and true local tot_vars, tot_func, tot_tabs = 0, 0, 0 if recursiveLevel > opt.level_maxi then -- even for abnormal limit -- Erreur Lua dans Module:Central-s-fr à la ligne 7271 : attempt to compare number with nil. return "", tot_vars, tot_func, tot_tabs end local st, vr, fn, tb = luaTable.structure_recursive(table, "", tablename, 1, opt) -- countonly, level_maxi, 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* Content of the <b>" .. tostring(tablename) .. "</b> table, end: " res = res .. viewer.form9user(" %1 variables, %2 functions, %3 sub-tables.\n", vr, fn, tb) return res, tot_vars, tot_func, tot_tabs end -- function luaTable.structure(table, tablename, opt) -- Auto test of limits of the table list. -- Auto test des limites de liste de table. luaTable.tablim = { "one", "two", max1 = "MAX1", max2 = "MAX2", max3 = "MAX3"} luaTable.tablim.life = { animal = "dog", vegetal = { big = "tree", small = "flower"} } luaTable.tablim.life.animals = { "turtle"} luaTable.tablim.comfort = { "tv", mobile = "car"} luaTable.tablim.house = { "kitcheen", "bedroom"} luaTable.tablim.house.garden = { flower = "rose", nature = "river"} -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:mathroman is here as an example of very small central library. It becomes central using the central modules system. -- function mathroman.roman2int(rm, testcase) -- Convert a roman number to decimal -- function mathroman.int2roman(i, testcase) -- Convert a integer number to roman -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- mathroman = {} -- already declared by Scribunto, else in _G space. mathroman.i18n = {} -- translations tables known in the module mathroman.i18n.en = { mathroman_errors_head_err = "Error: ", mathroman_roman_err = "Roman error: ", mathroman_value_error_err = "Value error: ", mathroman_J_before_end_err = "character J before the end", mathroman_char_X_in_N_err = "character %1 in %2", mathroman_char_increase_err = "3 increasing characters", mathroman_greater_4999_err = "value > 4999", mathroman_null_value_err = "null value", mathroman_rom2dig_value_err = "roman value error", mathroman_dig2rom_value_err = "digital value error", mathroman_roman2int_tests_title = "mathroman.roman2int() Test roman to digital numbers", mathroman_roman2int_tests_headers = "Roman number; Digital value; Correct; Error(s)", mathroman_int2roman_test_title = "mathroman.int2roman() Test digital numbers to roman numbers", mathroman_int_is_not_integer_err = "The not integer number <b>%1</b> is not convertible to Roman numeral", mathroman_int_is_not_number_err = "The value <b>%1</b> is not a convertible number to Roman numeral", mathroman_is_not_string_err = "The value <b>%1</b> is not a text convertible to number" } -- mathroman.i18n.en mathroman.i18n.es = { mathroman_errors_head_err = "Error: ", mathroman_roman_err = "Error de romano: ", mathroman_value_error_err = "Error de valor: ", mathroman_J_before_end_err = "carácter J antes del fin", mathroman_char_X_in_N_err = "carácter 1% en %2", mathroman_char_increase_err = "3 crecientes caracteres", mathroman_greater_4999_err = "valor > 4999", mathroman_null_value_err = "valor null", mathroman_rom2dig_value_err = "romano valor error", mathroman_dig2rom_value_err = "decimale valor error", mathroman_roman2int_tests_title = "mathroman.roman2int() Prueba de números romanos a números decimales", mathroman_roman2int_tests_headers = "Número romano; Valor digital; Corregido; Error(s)", mathroman_int2roman_test_title = "mathroman.int2roman() Prueba de números decimales a números romanos", mathroman_int_is_not_integer_err = "El no entero <b>%1</b> no se puede convertir en número romano", mathroman_int_is_not_number_err = "El valor <b>%1</b> no es un número y no se puede convertir en número romano", mathroman_is_not_string_err = "El valor <b>%1</b> no es un texto y no se puede convertir en número", } -- mathroman.i18n.es mathroman.i18n.fr = { mathroman_errors_head_err = "Erreur : ", mathroman_roman_err = "Erreur de romain : ", mathroman_value_error_err = "Erreur de valeur : ", mathroman_J_before_end_err = "caractère J avant la fin", mathroman_char_X_in_N_err = "caractère %1 en %2", mathroman_char_increase_err = "3 caractères croissants", mathroman_greater_4999_err = "valeur > 4999", mathroman_null_value_err = "valeur nulle", mathroman_rom2dig_value_err = "erreur de valeur de romain", mathroman_dig2rom_value_err = "erreur de valeur de décimal", mathroman_roman2int_tests_title = "mathroman.roman2int() Test des nombres romains en nombres décimaux", mathroman_roman2int_tests_headers = "Nombre romain; Valeur décimale; Correct; Erreur(s)", mathroman_int2roman_test_title = "mathroman.int2roman() Test des nombres décimaux en nombres romains", mathroman_int_is_not_integer_err = "Le nombre non entier <b>%1</b> n'est pas convertible en nombre romain", mathroman_int_is_not_number_err = "La valeur <b>%1</b> n'est pas un nombre convertible en nombre romain", mathroman_is_not_string_err = "La valeur <b>%1</b> n'est pas un texte convertible en nombre", } -- mathroman.i18n.fr -- vueRomains : XIJ=12 MCXI=1111 MCDXLIV=1444 MDCLXVI=1666 MCMXCIX=1999 MMCCXXII=2222 MMMMCMXCIX=4999 ERREURS=0 erreur caractere S en 7. XIA=11 erreur caractere A en 3. XJI=12 erreur caractere J avant la fin. IXC=89 erreur caracteres croissants. VLD=445 erreur caracteres croissants. MMMMM=5000 erreur > 4999. MMMMMYJXC=5089 erreur > 4999. erreur caractere Y en 6. erreur caractere J avant la fin. function mathroman.pcall_int2roman(val, errs) -- DEBUG : mathroman.int2roman() can fail without blocking page. -- EBUG: Without this patch the mathroman.int2roman() get the parser error "attempt to call field 'int2roman' ". Patched by Rical 2015-04-20. -- local event_century_roman = "" -- word, errx = mathroman.int2roman(val, errs) -- See Maniphest T27845 Support loading wiki pages through mediaWiki.loader.load() -- DEBUG code: local success, word, errs = pcall(mathroman.int2roman, val, errs) -- pcall or xpcall can run any function without blocking page. if success then return word, errs else return nil, errs end end function mathroman.pcall_roman2int(word, errs) -- DEBUG : mathroman.roman2int() can fail without blocking page. -- DEBUG: Without this patch the mathroman.int2roman() get the parser error "attempt to call field 'roman2int' ". Patched by Rical 2015-04-20. -- val, errs = mathroman.roman2int(word, errs) local success, val, errs = pcall(mathroman.roman2int, word, errs) -- pcall or xpcall can run any function without blocking page. if success then return val, errs else return nil, errs end end -- Romans view : XIJ=12 MCXI=1111 MCDXLIV=1444 MDCLXVI=1666 MCMXCIX=1999 MMCCXXII=2222 MMMMCMXCIX=4999 ERREURS=0 erreur caractere S en 7. XIA=11 erreur caractere A en 3. XJI=12 erreur caractere J avant la fin. IXC=89 erreur caracteres croissants. VLD=445 erreur caracteres croissants. MMMMM=5000 erreur > 4999. MMMMMYJXC=5089 erreur > 4999. erreur caractere Y en 6. erreur caractere J avant la fin. function mathroman.roman2int(rm) -- Convert a roman number to integer local v = 0 -- valeur totale local v1 = 0 -- valeur de derniere lettre local v2 = 0 -- valeur de lettre precedente local v3 = 0 -- valeur de lettre precedente local x = '-' -- caractere en cours d'evaluation local i = 1 -- numero du caractere en cours d'evaluation local j = 0 -- numero du caractere de reference courant (debut en Lua) local k = 0 -- numero du caractere de reference courant (fin en Lua) local errs, errtab = "", {} if type(rm) ~= "string" then -- errs = errs .. events.add_err("mathroman_is_not_string_err", tostring(rm) ) table.insert(errtab, tostring(events.add_err("mathroman_is_not_string_err", tostring(rm) ) ) ) return 0, errs end if rm == "" then errs = errs .. events.add_err("mathroman_is_not_string_err", '""') table.insert(errtab, tostring(events.add_err("mathroman_is_not_string_err", '""') ) ) return 0, errs end if type(rm) ~= "string" then rm = "-" end local lst = '-MDCLXVIJ' -- caracteres autorises x = string.sub(rm, i, i) or '' while (x ~= '') do v3 = v2 v2 = v1 v1 = 0 -- x = string.gsub(rm, i, i) if ( x == 'M' ) then v1 = 1000 end if ( x == 'D' ) then v1 = 500 end if ( x == 'C' ) then v1 = 100 end if ( x == 'L' ) then v1 = 50 end if ( x == 'X' ) then v1 = 10 end if ( x == 'V' ) then v1 = 5 end if ( x == 'I' ) then v1 = 1 end if ( x == 'J' ) then v1 = 1 end if ( x == 'J' ) and ( i < string.len(rm) ) then errs = errs .. events.add_err("mathroman_J_before_end_err") -- e4 = 'character J before the end' table.insert(errtab, tostring(events.add_err("mathroman_J_before_end_err") ) ) -- e4 = 'character J before the end' end if ( v1 == 0 ) then errs = errs .. events.add_err("mathroman_char_X_in_N_err", x, i) -- e3 = "character K in 3" table.insert(errtab, tostring(events.add_err("mathroman_char_X_in_N_err", x, i) ) ) end v = v + v1 if ( (v1 == 5*v2) or (v1 == 10*v2) ) then v = v - (2*v2) end -- adjust 4, 9, 40, 90 ... j, k = string.find(lst, x) if ( j == nil ) then j = -1 end if ( k == nil ) then k = -1 end if (v1 > v2) and (v2 > v3) and (v3 > 0) then errs = errs .. events.add_err("mathroman_char_increase_err") -- e2 = ' increasing chars.' table.insert(errtab, tostring(events.add_err("mathroman_char_increase_err") ) ) end i = i + 1 x = string.sub(rm, i, i) or '' end -- if ( v == 0 ) then -- e0 = ' valeur nulle.' if ( v < 1 ) then -- e0 = ' valeur nulle.' errs = errs .. events.add_err("mathroman_null_value_err") table.insert(errtab, tostring(events.add_err("mathroman_null_value_err") ) ) -- v = 1 end if ( v > 4999 ) then -- e1 = ' valeur > 4999.' errs = errs .. events.add_err("mathroman_greater_4999_err") table.insert(errtab, tostring(events.add_err("mathroman_greater_4999_err") ) ) -- v = 4999 end -- { name = "mathroman.roman2int (4)', func = mathroman.roman2int, args = { "VI", }, expect = { 123 } }, -- errs = errs .. ":" .. tostring(v) .. ":" .. tostring(rm) .. ":" -- runOneTest errs = table.concat(errtab, " ; ") return v, errs -- with or without errors end -- function mathroman.roman2int(rm) function mathroman.romani2r(i, j) if ( j == nil ) then j = '' end local rm='' if ( i == 1000 ) then rm = 'M' end if ( i == 500 ) then rm = 'D' end if ( i == 100 ) then rm = 'C' end if ( i == 50 ) then rm = 'L' end if ( i == 10 ) then rm = 'X' end if ( i == 5 ) then rm = 'V' end if ( i == 1 ) then rm = 'I' if ( j == 'J' ) then rm = 'J' end end return rm end -- function mathroman.romani2r(i, j) function mathroman.int2roman(int) -- Convert an integer to a roman number, also if int is a string local errs = "" -- local collection of errors local n = tonumber(int) --[ [ if n then local floor = math.floor(n) if n ~= floor then errs = errs .. events.add_err("mathroman_int_is_not_integer_err", tostring(int) ) roman = "" return roman, errs -- with error end elseif int == "" then errs = errs .. events.add_err("mathroman_is_not_string_err", '""' ) return "", errs else errs = errs .. events.add_err("mathroman_int_is_not_number_err", tostring(int) ) roman = "" return roman, errs -- with error end --] ] if type(n) ~= "number" then n = 0 end n = math.floor(n) n = n or 0 -- delete after debug local v100 = 100 local v500 = v100*5 local v1000 = v100*10 -- roman cycle romain 1000, 100, 10, 1 local v, v1, v2, v3 = 0, 0, 0, 0 -- Total value, last, and previous. Valeur totale, derniere, et precedentes. local reste, reduction = 0, 0 -- Rest to convert, last reduction. Reste a convertir, derniere reduction. local rm = '' local roman = '' -- chiffre et nombre romain resultant reste = n if ( n > 4999 ) then errs = errs .. events.add_err("mathroman_greater_4999_err") -- e1 = ' valeur > 4999.' reste = 0 roman = "" -- 'ERROR' end if ( n < 1 ) then -- n = 0 errs = errs .. events.add_err("mathroman_null_value_err") -- e2 = ' valeur < 1.' reste = 0 roman = "" -- 'ERROR' end while (reste > 0) do v3 = v2 v2 = v1 v1 = reste reduction = 0 if ( reste >= v1000 ) then reduction = v1000 elseif ( reste >= v100*9 ) then reduction = v100 reste = reste + v100*2 elseif ( reste >= v500 ) then reduction = v500 elseif ( reste >= v100*4 ) then reduction = v100 reste = reste + v100*2 elseif ( reste >= v100 ) then reduction = v100 elseif ( reste >= 1000 ) then v100 = 100 v1000 = 1000 reduction = v1000 end rm = mathroman.romani2r(reduction) roman = roman .. rm reste = reste - reduction if ( reste < v100 ) then if ( v100 >= 10 ) then v100 = v100/10 v500 = v100*5 v1000 = v100*10 end end end -- { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { int = 444 }, expect = { "CDXLIV" } }, -- errs = errs .. ":" .. tostring(roman) .. ":" .. tostring(int) .. ":" -- runOneTest return roman, errs -- with or without errors end -- function mathroman.int2roman(int) function mathroman.roman2int_tests(t) -- Tests of main central modules local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* " .. viewer.form9user("mathroman_roman2int_tests_title") t = t .. "<br>" .. luaTable.formSubCounts("mathroman.i18n") local tabView = { testGroup = { { 123, }, { 2.78, }, { "-X", }, { "", }, { "0", }, { "MCXI", }, { "XIJ", }, { "XJI", }, { "XIA", }, { "VLD", }, { "IXC", }, { "MMMMCMXCIX", }, { "MMMMM", }, { "MMMMMYJXC", }, { {x}, }, { function()end, }, }, headers = "mathroman_roman2int_tests_headers", -- mathroman_roman2int_tests_title -- mathroman_roman2int_tests_headers = "Roman number; Digital value; Correct; Error(s)", -- mathroman_roman2int_tests_headers = "Número romano; Valor digital; Corregido; Error(s)", -- mathroman_roman2int_tests_headers = "Nombre romain; Valeur décimale; Correct; Erreur(s)", } tabView.t = (tabView.t or "") .. viewer.ta("roman2int_tests: ", "start") tabView.t = tabView.t .. viewer.ta("#testGroup: ", #tabView.testGroup) function tabView.tableView_form_one_case(case) -- Generally to define: Convert a case from testGroup to rowGroup. local word = case[1] -- DEBUG : mathroman.roman2int() can fail without blocking page. local valX, errs = mathroman.roman2int(word) -- DEBUG : mathroman.roman2int() can fail without blocking page. local wordX, errsX = mathroman.int2roman(valX) -- DEBUG : mathroman.roman2int() can fail without blocking page. -- local case = { word, valX, wordX, errs .. " " .. errsX, } return { word, valX, wordX, errs .. " " .. errsX, } end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track to debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function mathroman.roman2int_tests(t) function mathroman.int2roman_test(t, val) -- Unitary tests of mathroman.int2roman local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "int2roman_test" t = "\n:*<b>" .. t .. "</b>:" t = t .. "<br>" .. luaTable.formSubCounts("mathroman.i18n") t = t .. viewer.Th() .. viewer.Tc("Digital value") .. viewer.Tc("Roman number") .. viewer.Tc("Error") local function int2roman_test1( t, val) -- local word, errs = mathroman.pcall_int2roman(val, " ") -- DEBUG : mathroman.int2roman() can fail without blocking page. local word, errs = mathroman.int2roman(val, " ") -- DEBUG : mathroman.int2roman() can fail without blocking page. t = (t or "") .. viewer.Tr() .. viewer.Td(val) .. viewer.Td(word or "") .. viewer.Td(errs or "") return t end t = int2roman_test1( t, -10) t = int2roman_test1( t, 3.14) t = int2roman_test1( t, "not-a-number" ) t = int2roman_test1( t, "") t = int2roman_test1( t, 0) t = int2roman_test1( t, 12) t = int2roman_test1( t, 17) t = int2roman_test1( t, "18") t = int2roman_test1( t, "19") t = int2roman_test1( t, 111) t = int2roman_test1( t, 444) t = int2roman_test1( t, 555) t = int2roman_test1( t, "777") t = int2roman_test1( t, "1111") t = int2roman_test1( t, "4999") t = int2roman_test1( t, "5000") t = t .. viewer.Te() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function mathroman.int2roman_test(t, val) -- vueRomains : XIJ=12 MCXI=1111 MCDXLIV=1444 MDCLXVI=1666 MCMXCIX=1999 MMCCXXII=2222 MMMMCMXCIX=4999 ERREURS=0 erreur caractere S en 7. XIA=11 erreur caractere A en 3. XJI=12 erreur caractere J avant la fin. IXC=89 erreur caracteres croissants. VLD=445 erreur caracteres croissants. MMMMM=5000 erreur > 4999. MMMMMYJXC=5089 erreur > 4999. erreur caractere Y en 6. erreur caractere J avant la fin. -- { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", group = mathroman.TestsCasesGroup, }, -- { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 1 }, expect = { "I" } }, mathroman.TestsCasesGroup = { -- Autotest cases to validate the mathroman library at mediawiki level. -- each test_case defines a name, a function, an input, an output. See also viewer.strTestCase. 8 cases --[[ { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 1 }, expect = { "I" }, }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 3 }, expect = { "III" }, }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 6 }, expect = { "VIII" }, }, -- { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "IV", }, expect = { 4 }, }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "V", }, expect = { 5 }, }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "III", }, expect = { 6 }, }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "VI", }, expect = { 6 }, }, --]] { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "XXII" }, expect = { 22 }, }, } 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 viewer.strTestCase. 5 cases { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 12, }, expect = { "XII" }, }, --[[ { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 17, }, expect = { "II" }, }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 3, }, expect = { "III" }, }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 4, }, expect = { "IX" }, }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 5, }, expect = { "V" }, }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 6, }, expect = { "VI" }, }, -- { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "I" }, expect = { 1 }, }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "II" }, expect = { 2 }, }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "III", }, expect = { 6 }, }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "VI", }, expect = { 123 }, }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "V", }, expect = { 1 }, }, --]] { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "VIA", }, expect = { 6, "mathroman_char_X_in_N_err-A-3" }, }, } mathroman.int2romanTests = { -- Autotest cases to validate the mathroman library at mediawiki level. -- each test_case defines a name, a function, an input, an output. See also viewer.strTestCase. 8 - 1 = 7 + 8 = 15 cases { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { "19" }, expect = { "XII" } }, -- diffs = mathroman_char_increase_err;mathroman_char_increase_err;mathroman_char_X_in_N_err-0-1; mathroman_char_X_in_N_err---1;mathroman_char_X_in_N_err-A-3;mathroman_char_X_in_N_err-Y-6; mathroman_char_X_in_N_err-Y-6nil;mathroman_greater_4999_err;mathroman_J_before_end_err;mathroman_J_before_end_errnil; mathroman_null_value_err;testsCases_subDiffs_string_error-mathroman_J_before_end_err-XJI-nil, errors = --[[ { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 12 }, expect = { "XII" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 17 }, expect = { "XVII" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 18 }, expect = { "XVIII" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 111 }, expect = { "CXI" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 444 }, expect = { "CDXLIV" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 555 }, expect = { "DLV" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 777 }, expect = { "DCCLXXVII" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 1111 }, expect = { "MCXI" } }, --]] { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 4999 }, expect = { "MMMMCMXCIX" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 5000 }, expect = { "0", "mathroman_greater_4999_err-0" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { -10 }, expect = { "X", "mathroman_null_value_err" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 0 }, expect = { "0", "mathroman_null_value_err" } }, --[[ { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { 3.14 }, expect = { "3.3.3" } }, { errorsKey = 2, modulename = "mathroman", funcname = "int2roman", func = mathroman.int2roman, args = { "not-a-number" }, expect = { "xxx" } }, -- { name = "mathroman", func = testsCases.runGroups, group = mathroman.TestsCasesGroup, modulename = "mathroman", funcname = "runGroups", groupname = "mathroman.TestsCasesGroup", }, -- --]] } mathroman.roman2intTests = { -- Autotest cases to validate the mathroman library at mediawiki level. -- each test_case defines a name, a function, an input, an output. See also viewer.strTestCase. 6 cases { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "-X" }, expect = { 10, "mathroman_char_X_in_N_err---1-" } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "0" }, expect = { 0, "mathroman_char_X_in_N_err-0-1-" } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "XIA" }, expect = { 11, "mathroman_char_X_in_N_err-A" } }, --[[ { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "" }, expect = { 0 } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "MCXI" }, expect = { 1111 } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "XIJ" }, expect = { 12 } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "XJI" }, expect = { 12, "X Y Z" } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "XJI" }, expect = { 12, "mathroman_char_increase_err" } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "VLD" }, expect = { 445 } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "IXC" }, expect = { 89 } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "MMMMCMXCIX" }, expect = { 4999 } }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "MMMMM" }, expect = { 5000, "mathroman_J_before_end_err-XJI" } }, --]] { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "MMMMMYJXC" }, expect = { 5089, ";mathroman_J_before_end_err;mathroman_char_increase_err;mathroman_char_X_in_N_err-Y-6;mathroman_greater_4999_err;" } }, } mathroman.testsRecursive = { -- Autotest cases to validate the mathroman library at mediawiki level. { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "XXIJ" }, expect = { 22 } }, -- { errorsKey = 2, modulename = "mathroman", funcname = 'recurse', group = mathroman.testsRecursive, }, { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "MCXI" }, expect = { 1111 } }, -- { errorsKey = 2, modulename = "mathroman", funcname = 'recurse', group = mathroman.testsRecursive, }, } mathroman.testsGroups = { -- Autotest cases to validate the mathroman library at mediawiki level. -- Each test_case defines a name, a function, an input, an output. Else a sub-group of testsCases. { name = "mathroman", func = testsCases.runGroups, group = mathroman.Tests_cases, modulename = "mathroman", funcname = "runGroups", groupname = "mathroman.Tests_cases", }, -- { name = "mathroman", func = testsCases.runGroups, group = mathroman.int2romanTests, modulename = "mathroman", funcname = "runGroups", groupname = "mathroman.int2romanTests", }, -- { name = "mathroman", func = testsCases.runGroups, group = mathroman.roman2intTests, modulename = "mathroman", funcname = "runGroups", groupname = "mathroman.roman2intTests", }, -- -- { name = "mathroman", func = testsCases.runGroups, group = mathroman.testsRecursive, -- recursive until recursiveLimit -- modulename = "mathroman", funcname = "runGroups", groupname = "mathroman.testsRecursive", }, } -- Define ClassCentralMathromanTests.lua -- mathroman.count = 0 -- generic testcase for mathroman.tests_cases function mathroman.provide(n, test_name, okString) -- see Extension:Scribunto/Lua reference manual: -- Function that returns three values: n, the name of test n, and a string that is the expected output for test n. return n, test_name, okString end function mathroman.run( n, testcase ) -- Function that runs test n and returns one string. return testsCases.run_testcase( n, testcase ) end function mathroman.getEnv( func, name, recursiveLevel, opt ) -- Get the environment of the module or library -- local fenv = getfenv() -- Not functional because not activated in fr.wikisource.org. local t = luaTable.formSubCounts("_G", { recursiveLimit = 2 }, 1 ) -- rougly equivalent to getfenv() return t end -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:modes support modes and their options, like p.read(frame). -- count = number of tests; provide( n ) returns three values: n, and expected output; run( n ) returns one string. -- see Extension:Scribunto/Lua reference manual : class nameTest extends Scribunto_LuaEngineTestBase -- This library support modules to: -- * Define their modes, used with frame: p.read(frame) -- * Default modes are read, edit, doc or tests -- * And their options -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- modes = {} -- already declared by Scribunto, else in _G space. -- Translations for modes library modes.i18n = {} -- 12 modes.i18n. modes.i18n.en = { -- 182 <tab>mode_... -- Names and descriptions of configurations arguments [1] = "1", [2] = "2", [3] = "3", [4] = "4", label = 'label', label_descr = "Automatic Wikidata argument.", sitelink = 'sitelink', sitelink_descr = "Automatic Wikidata argument.", userlang = "userlang", userlang_descr = "Language of the user or the helper.", wikilang = "wikilang", wikilang_descr = "Language of the wiki.", itemid = 'itemid', itemid_descr = "Identifier of Wikidata data, such as <code>Q535</code> for Victor Hugo.", itemid2 = 'id', itemid2_descr = "Identifier of Wikidata data, such as <code>Q535</code> for Victor Hugo.", debug = 'debug', category = 'Category', mode = "mode", mode_descr = "Type of use of the module or template: read, edit, document, test.", options = "options", options_descr = "Display options of a module or a model.", c = "c", c_descr = "Display options of a module or a model.", knownversions = "knownversions", knownversions_descr = "Known versions, to manage them.", soughtversions = "soughtversions", soughtversions_descr = "Sought versions, to manage them.", -- Main texts, errors and categories of tools -- Versions management -- Titles of tests modes_list_all_args_main_title = "modes.list_all_args_main() List of all accepted arguments", modes_used_options_title = "modes.used_options_list() Options and their uses:", modes_brief_options_mode_title = "modes.options_from_mode_tests() Modes and options in brief", modes_options_from_args_tests_title = "modes.options_from_args_tests() Test options from modes", modes_options_from_args_title = "Test options from arguments", -- Groups of arguments modes_needed_to_verify = "(required, to be checked)", modes_list_needed_args = "List of needed arguments:", modes_list_all_config_arguments = "List of all config arguments:", modes_list_all_system_arguments = "List of all system arguments:", modes_list_all_other_args = "List of all other arguments:", -- Main texts, errors and categories of tools modes_language_cat = 'Speaking %1', modes_date_months_names = "January, February, March, April, May, June, July, August, September, October, November, December", modes_date_to_part_format = "dd yyyy mmmm", modes_date_to_part_call_err = "Internal Error: Abnormal calling arguments in date <b>%1</b>.", modes_date_to_part_call_cat = "Module with internal error", modes_date_to_part_not_found_err = "Internal Error: No part found in date <b>%1</b>.", -- Arguments management modes_error_list_header_err = "User support about parameters:", modes_need_arg_value_err = "Error: This argument is required but absent : <b>%1</b>. Should define it.", modes_none_value_err = "Error: No argument has been defined.", modes_unknown_argument_err = "Error: parameter <b>%1</b> is unknown in this template. Check the name or flag this gap.", modes_too_unnamed_arguments_err = "Error: This unnamed argument is too many: <b>%1</b> = <b>%2</b>.", modes_without_translation_wsid_err = "Internal Error: Notify the developer that the internal argument <b>%1</b> is unknown in the records.", modes_is_defined_err = "The argument %1:<b>%2</b> is defined.", modes_is_undefined_err = "The argument %1:<b>%2</b> is not defined.", modes_args_values_err = "Abnormal value of the argument <b>%1 = %2</b> including (%3) ", modes_nearest_argument_err = "Error: Do you need the known argument <b>%1</b> ?", modes_max_nearest_argument_msg = "A longer name argument accepts more letter errors.", modes_value_re_defined_err = "Error: The value of the argument <b>%1</b> is already defined. Choose only one value of a single synonymous.", modes_lang_table_err = "Error: The <b>%1</b> language or its table is incorrect.", -- modes_lang_table_err_cat = "Module avec langue d'arguments erronée", modes_lang_table_err_cat = "Module avec erreur interne", -- modes_lang_table_err_cat modes_lang_not_translated_err = "Error: The language <b>%1</b> is not translated.", modes_generDoc1_paramName_err = "Internal Error: in generDoc1, bad argument <b>%1</b>.", -- modes_unknown_auto_arg_err = "Internal Error: Unknown automatic argument: %1 = <b>%2</b>.", modes_delete_docbox_wng = "You must remove this documentation before recording.<br>Remove all modes to return to read mode.", modes_auto_val_warning_wng = "Verify the automatic argument: %1 = <b>%2</b>.", -- modes_assist_user_param_err = "User support for checking the settings:", modes_no_known_arguments_err = "Module without known arguments table.", modes_args_values_err = "Abnormal value of the argument <b>%1 = %2</b> (%3)", -- modes_no_known_arguments_err = "Internal Error: Module without known arguments table.", -- modes_no_known_args_cat = "Module without known arguments table.", modes_no_known_args_cat = "Module with internal error", -- modes_no_source_arguments_cat modes_no_source_arguments_err = "Internal Error: Module without source arguments table.", -- modes_no_source_arguments_cat = "Module without source arguments table.", modes_no_source_arguments_cat = "Module with internal error", -- modes_no_source_arguments_cat modes_list_all_args_main_title = "modes.list_all_args_main() List of all accepted arguments", modes_similar_levenshtein_tests_title= "modes.levenshtein() Test the distances between words <b>[https://en.wikipedia.org/wiki/Levenshtein_distance Levenshtein]</b>:", modes_args_known_structure_title = "modes.args_known_structure() Arguments definitions", modes_similar_args_searchs_title = "modes.similar_args_search() Test close similar words:", modes_normal_box_main_text_1 = "Simple infobox: page title: <b>%1</b>, description: <b>%2</b>", modes_normal_box_main_text_2 = "<br/>He was <b>%1</b>, named <b>%2</b> <b>%3</b> was dead in <b>%4</b>.", -- These texts are used to title some tests. modes_list_wiki_selectors_title = "List of selectors of this module:", modes_all_categories_list_title = "modes.all_categories_list() List of eventual categories of this module:", modes_all_errors_list_title = "modes.all_errors_list() List of detectable errors in this module:", modes_multiple_values_tests_title = "modes.multiple_values() Test of multiple values arguments", modes_multiple_selection_tests_title= "modes.multiple_selection() Multiple selection test", modes_multiple_selection_test_headers= "Options;Selector;To selector;Selected", modes_multiple_selection_test_select= "2;nobel;president;deputy;price", modes_recursiveLevel_err = "Recursive level error <b>%1 > %2</b>", modes_recursiveNormal_tests_title = "modes.recursiveNormal() Test: Normalize the recursive level and the recursive limit", modes_spaces_names_page_title = "modes.spacesNamesPageTest() Module, namespaces, and page names:", } -- modes.i18n.en modes.i18n.es = { -- Nombres y descripciones de argumentos de configuraciones [1] = "1", [2] = "2", [3] = "3", [4] = "4", label = 'label', label_descr = "Wikidata automática argumento.", sitelink = 'sitelink', sitelink_descr = "Wikidata automática argumento.", userlang = "userlang", userlang_descr = "Idioma del usuario o del encargado.", wikilang = "wikilang", wikilang_descr = "Idioma del wiki.", itemid = 'itemid', itemid_descr = "Nombre de los datos Wikidata, como <code>Q535</code> para Victor Hugo.", itemid2 = 'id', itemid2_descr = "Nombre de los datos Wikidata, como <code>Q535</code> para Victor Hugo.", debug = 'debug', category = 'Categoría', mode = "modo", mode_descr = "Tipo de uso del módulo o modelo: leer, editar, documentar, probar.", options = 'opciones', options_descr = "Opciones de visualización de un módulo o un modelo.", c = "c", c_descr = "Opciones de visualización de un módulo o un modelo.", knownversions = "knownversions", knownversions_descr = "Conocidas versiones, para manejarlos.", soughtversions = "soughtversions", soughtversions_descr = "Versiones demanda, para manejarlos.", -- events_test_OK_cat = "Test category generation OK", -- Textos principales, errores y categorías de instrumentos events_test_OK_cat = "Prueba generación categoría en OK", events_test_OK_cat = "Test de génération de catégorie OK", -- -- Titres des pruebas modes_used_options_title = "modes.used_options_list() Opciones y sus usos:", modes_brief_options_mode_title = "modes.options_from_mode_tests() Modos y opciones en brief", modes_options_from_args_tests_title = "modes.options_from_args_tests() Prueba de opciones de modos", modes_options_from_args_title = "Prueba de opciones de argumentos", -- Grupos de argumentos modes_needed_to_verify = "(obligatorio, se debe comprobar)", modes_list_needed_args = "Lista de argumentos necesarios:", modes_list_all_config_arguments = "Lista de argumentos de configuración:", modes_list_all_system_arguments = "Lista de argumentos del sistema:", modes_list_all_other_args = "Lista de los otros argumentos:", -- Textos principales, errores y categorías de instrumentos modes_language_cat = 'Hablando %1', modes_date_months_names = "Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre", modes_date_to_part_format = "dd mmmm yyyy", modes_date_to_part_call_err = "Error interno: argumentos de llamadas anómala en fecha <b>%1</b>.", modes_date_to_part_call_cat = "Módulo con error interno", modes_date_to_part_not_found_err = "Error interno: No se encuentra en fecha <b>%1</b>.", -- Control de argumentos modes_error_list_header_err = "Asistencia de los parámetros de este modelo:", modes_need_arg_value_err = "Error: Usted tiene que fijar este argumento necesario, pero falta: <b>%1</b>.", modes_none_value_err = "Error: No hay argumento se ha definido.", modes_unknown_argument_err = "Error: El parámetro <b>%1</b> es desconocido en este modelo. Compruebe el nombre o reportar esta falta.", modes_too_unnamed_arguments_err = "Error: Demasiado argumento sin nombre: <b>%1</b> = <b>%2</b>.", modes_without_translation_wsid_err = "Error interno: Informar al el desarrollador que el argumento interno <b>%1</b> es desconocido en los registros.", modes_is_defined_err = "El argumento %1:<b>%2</b> está definido.", modes_is_undefined_err = "El argumento %1:<b>%2</b> no está definido.", modes_args_values_err = "Valor anormal del argumento <b>%1 = %2</b> entre: (%3) ", modes_nearest_argument_err = "Error : ¿Es usted conocido argumento <b>%1</b> ?", modes_max_nearest_argument_msg = "Un argumento nombre más largo acepta más letras errores.", modes_value_re_defined_err = "Error: El valor del argumento <b>%1</b> ya está definido. Elija sólo un valor de un solo sinónimo", modes_lang_table_err = "Error: La <b>1%</b> idioma o su tabla es incorrecta.", modes_lang_table_err_cat = "Módulo con lenguaje de argumentos erróneos", -- modes_no_source_arguments_cat modes_lang_table_err_cat = "Módulo con error interno", -- modes_lang_table_err_cat modes_lang_not_translated_err = "Error: El lenguaje <b>%1</b> no se traduce.", modes_generDoc1_paramName_err = "Error interno: en generDoc1, mal argumento <b>%1</b>.", -- modes_unknown_auto_arg_err = "Error interno: Argumento desconocido automático: %1 = <b>%2</b>.", modes_delete_docbox_wng = "Debe quitar esta documentación antes de grabar.<br>Retire todos los modos para volver al modo read.", modes_auto_val_warning_wng = "Verifique el argumento automático: %1 = <b>%2</b>.", -- modes_assist_user_param_err = "Apoyo al usuario para comprobar la configuración:", modes_no_known_arguments_err = "Módulo sin argumentos tabla conocida.", modes_args_values_err = "Valor anormal del argumento <b>%1 = %2</b> (%3)", -- modes_no_known_arguments_err = "Error interno: Módulo sin tabla de argumentos conocidos.", modes_no_known_args_cat = "Módulo con error interno", -- modes_no_source_arguments_cat modes_no_source_arguments_err = "Error interno: Módulo sin tabla de argumentos fuentes.", modes_no_source_arguments_cat = "Módulo con error interno", -- modes_no_source_arguments_cat modes_list_all_args_main_title = "modes.list_all_args_main() Lista de todos los argumentos aceptados", modes_similar_levenshtein_tests_title= "modes.levenshtein() Prueba de las distancias <b>[https://es.wikipedia.org/wiki/Distancia_de_Levenshtein Levenshtein]</b> entre las palabras:", modes_args_known_structure_title = "modes.args_known_structure() Definiciones de argumentos", modes_similar_args_searchs_title = "modes.similar_args_search() Prueba de palabras similares cercanos:", modes_normal_box_main_text_1 = "Simple caja de información: Título de la página: <b>%1</b>, descripción: <b>%2</b>", modes_normal_box_main_text_2 = "<br/>Él era un <b>%1</b>, es nombrado <b>%2</b> <b>%3</b> había muerto en <b>%4</b>.", -- Estos textos se utilizan para titular algunas pruebas. modes_list_wiki_selectors_title = "Lista de las selectores de este modulo:", modes_all_categories_list_title = "modes.all_categories_list() Lista de las posibles categorías de este modulo:", modes_all_errors_list_title = "modes.all_errors_list() Lista de los errores detectables de este modulo:", modes_multiple_values_tests_title = "modes.multiple_values() Prueba de múltiples valores argumentos", modes_multiple_selection_tests_title= "modes.multiple_selection() Prueba de selección múltiple", modes_multiple_selection_test_headers= "Opciones;Selector;Para seleccionar;Seleccionadas", modes_multiple_selection_test_select= "2;nobel;presidente;diputado;precio", modes_recursiveLevel_err = "Error de nivel recursivo <b>%1 > %2</b>", modes_recursiveNormal_tests_title = "modes.recursiveNormal() Prueba: Normalizar el nivel recursivo y el límite recursiva", modes_spaces_names_page_title = "modes.spacesNamesPageTest() Módulo, namespaces, y nombres de páginas:", } -- modes.i18n.es modes.i18n.fr = { -- Noms et descriptions des arguments de configurations [1] = "1", [2] = "2", [3] = "3", [4] = "4", label = 'label', label_descr = "Argument automatique de Wikidata.", sitelink = 'sitelink', sitelink_descr = "Argument automatique de Wikidata.", userlang = "userlang", userlang_descr = "Langue de l'utilisateur ou de l'aidant.", wikilang = "wikilang", wikilang_descr = "Langue du wiki.", itemid = 'itemid', itemid_descr = "Identifiant des données de wikidata, comme <code>Q535</code> pour Victor Hugo.", itemid2 = 'id', itemid2_descr = "Identifiant 2 des données de wikidata, comme <code>Q535</code> pour Victor Hugo.", debug = 'debug', category = 'Catégorie', mode = "mode", mode_descr = "Type d'utilisation du module ou du modèle : lire, éditer, documenter, tester.", options = "options", options_descr = "Options d'affichage d'un module ou d'un modèle.", c = "c", c_descr = "Options d'affichage d'un module ou d'un modèle.", knownversions = "knownversions", knownversions_descr = "Versions connues, pour les gérer.", soughtversions = "soughtversions", soughtversions_descr = "Versions demandées, pour les gérer.", -- Principaux textes, erreurs et catégories des outils language = 'langue', -- Gestion des versions -- Messages et erreurs divers -- tools_no_args_known_err = "Erreur interne : Module sans table d'arguments connus.", -- tools_no_args_source_err = "Erreur interne : Module sans table d'arguments sources.", modes_used_options_title = "modes.used_options_list() Options et leurs utilisations :", modes_brief_options_mode_title = "modes.options_from_mode_tests() Modes et options en bref", modes_options_from_args_tests_title = "modes.options_from_args_tests() Test des options de modes", modes_options_from_args_title = "Test des options des arguments", -- Groupes d'arguments modes_needed_to_verify = "(obligatoire, à vérifier)", modes_list_needed_args = "Liste des arguments nécessaires :", modes_list_all_config_arguments = "Liste des arguments de configuration :", modes_list_all_system_arguments = "Liste des arguments système :", modes_list_all_other_args = "Liste des autres arguments :", modes_language_cat = 'Parle %1', modes_date_months_names = "Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre", modes_date_to_part_format = "dd yyyy mmmm", modes_date_to_part_call_err = "Erreur interne : Argument anormal de définition de date <b>%1</b>.", modes_date_to_part_call_cat = "Module avec erreur interne", modes_date_to_part_not_found_err = "Erreur interne : partie non définie de date <b>%1</b>.", -- Gestion des arguments modes_error_list_header_err = "Assistance sur les paramètres de ce modèle :", modes_need_arg_value_err = "Erreur : Vous devez définir cet argument nécessaire mais absent : <b>%1</b>.", modes_none_value_err = "Erreur : Aucun argument n'a été défini.", modes_unknown_argument_err = "Erreur : Le paramètre <b>%1</b> est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.", modes_too_unnamed_arguments_err = "Erreur : Ce paramètre non nommé est en trop : <b>%1</b> = <b>%2</b>.", modes_without_translation_wsid_err = "Erreur interne : Signaler au développeur que l'argument interne <b>%1</b> est inconnu dans les notices.", modes_is_defined_err = "L'argument %1:<b>%2</b> est défini.", modes_is_undefined_err = "L'argument %1:<b>%2</b> n'est pas défini.", modes_args_values_err = "Valeur anormale de l'argument <b>%1 = %2</b> parmi : (%3) ", -- Messages et erreurs divers modes_nearest_argument_err = "Erreur : Voulez vous l'argument connu <b>%1</b> ?", modes_max_nearest_argument_msg = "Un nom d'argument plus long accepte plus d'erreurs de lettres.", modes_value_re_defined_err = "Erreur : La valeur de l'argument <b>%1</b> est déjà définie. Choisir une seule valeur d'un seul synonyme.", modes_lang_table_err = "Erreur interne : La langue <b>%1</b> ou sa table est erronée.", -- modes_lang_table_err_cat = "Module avec langue d'arguments erronée", modes_lang_table_err_cat = "Module avec erreur interne", -- modes_no_source_arguments_cat modes_lang_not_translated_err = "Erreur : La langue <b>%1</b> n'est pas traduite.", modes_generDoc1_paramName_err = "Erreur interne : en generDoc1, mauvais argument <b>%1</b>.", modes_unknown_auto_arg_err = "Erreur interne: Argument automatique inconnu : %1 = <b>%2</b>.", -- modes_delete_docbox_wng = "Vous devez supprimer cette documentation avant d'enregistrer.<br>Supprimez tous les modes pour revenir en mode read.", modes_auto_val_warning_wng = "Vérifiez l'argument automatique : %1 = <b>%2</b>.", -- modes_assist_user_param_err = "Support aux utilisateurs pour vérifier les paramètres :", modes_no_known_arguments_err = "Module sans table d'arguments connus.", modes_args_values_err = "Valeur anormale de l'argument <b>%1 = %2</b> (%3)", -- modes_no_known_arguments_err = "Erreur interne : Module sans table d'arguments connus.", -- modes_no_known_args_cat = "Module sans table d'arguments connus.", modes_no_known_args_cat = "Module avec erreur interne", -- modes_no_source_arguments_cat modes_no_source_arguments_err = "Erreur interne : Module sans table d'arguments sources.", -- modes_no_source_arguments_cat = "Module sans table d'arguments sources.", modes_no_source_arguments_cat = "Module avec erreur interne", -- modes_no_source_arguments_cat modes_list_all_args_main_title = "modes.list_all_args_main() Liste de tous les arguments acceptés", modes_similar_levenshtein_tests_title = "modes.levenshtein() Test des distances de <b>[https://fr.wikipedia.org/wiki/Distance_de_Levenshtein Levenshtein]</b> entre mots:", modes_args_known_structure_title = "modes.args_known_structure() Définitions des arguments", modes_similar_args_searchs_title = "modes.similar_args_search() Test des mots proches similaires :", modes_normal_box_main_text_1 = "Boîte d'information simple : titre de cette page <b>%1</b>, description : <b>%2</b>", modes_normal_box_main_text_2 = "<br/>Il était <b>%1</b>, se nommait <b>%2</b> <b>%3</b>, il est mort en <b>%4</b>.", -- Ces textes sont utilisés pour titrer des tests. modes_list_wiki_selectors_title = "Liste des sélecteurs de ce module :", modes_all_categories_list_title = "modes.all_categories_list() Liste des catégories éventuelles de ce module :", modes_all_errors_list_title = "modes.all_errors_list() Liste des erreurs détectables de ce module :", modes_multiple_values_tests_title = "modes.multiple_values() Test des arguments à valeurs multiples", modes_multiple_selection_tests_title= "modes.multiple_selection() Test de sélection multiple", modes_multiple_selection_test_headers= "Options;Sélecteur;À sélectionner;Sélectionnés", modes_multiple_selection_test_select= "2;nobel;président;député;prix", modes_recursiveLevel_err = "Erreur de niveau récursif <b>%1 > %2</b>", modes_recursiveNormal_tests_title = "modes.recursiveNormal() Test: Normalise le niveau récursif et la limite récursive", modes_spaces_names_page_title = "modes.spacesNamesPageTest() Module, namespaces, et noms de pages :", } -- modes.i18n.fr -- - - - ------------------ - - - - --------------------------------- -- Support of the management of options. Sostén de la gestión de las opciones. Soutien de la gestion des options. -- - - - ------------------ - - - - --------------------------------- modes.options_for_modes = { -- default options_for_modes read = " noerr ", edit = " docdef docline docsrc docdata catview docview : ", doc = " nobox noerr nocat ", tests = " docdef docline docsrc docdata catview docview : tests ", -- List of parameters for module documentation -- "docview" or ":" add the documentation panel -- "docmin" list only some basic parameters -- "docdef" list only the parameters defined, having a non-zero value -- "docmax" list all known parameters -- "docnotice" generate documentations of records -- "docline" put all parameters on a single line -- "docsrc" put the parameters in colors according to the sources -- modes.options = " docdata docmin docdef docmax docline docview docafter docnotice docsrc : " -- for standard documentation -- modes.options = " erron noerr nobox nocat " -- do not form normal result -- modes.options = " debug tests en es fr " -- enforce a language for debug -- Option nocat means "Do not categorize and do not show categories." } function modes.trackOptions(where, no_track) if modes.no_track then return "" end -- if modes.no_track then modes.no_track = no_track end -- if no_track then mask all next modes.trackOptions(). local t = viewer.form9user("\n* trackOptions where=%1, mode_options=%2, invoke_options=%3", where, modes.mode_options, modes.invoke_options) modes.report_trackOptions = (modes.report_trackOptions or"") .. t return "" -- t or "" end function modes.init_options(invoke_options) -- modes.invoke_options = modes.init_options(args.options) -- modes.invoke_options = modes.init_options("fr params docview docmin docmax docdef docnotice docafter docline docsrc") modes.mode_name = modes.mode_name if (type(invoke_options) == "string") then modes.invoke_options = invoke_options end -- and (new ~= "") -- Early effects on options which modify other ones. -- modes.options = " : docdata docmin docdef docmax docline docview docafter docnotice docsrc" -- for documentation -- modes.options = " erron noerr nobox nocat " -- without normal result -- modes.options = " debug tests en es fr " -- for debug or enforce language modes.options_to_catView() if modes.option("noerr") then events.erron = false end if modes.option("erron") then events.erron = true end if modes.option("docolor") then modes.docolor = true end -- If an option is a language, enable this language for the user. -- Si una opción es un lenguaje, activar esta lengua para usuario. -- Si une option est une langue, activer cette langue pour l'utilisateur. for lang, tab in pairs(versioning.i18n) do if modes.option(lang) then translate.init_wiki_user_page_lang(translate.wiki_lang, lang) -- translate.wiki_lang, translate.user_lang end end return modes.invoke_options end -- function modes.init_options(invoke_options) -- Manage Library:modes options. Administrar opciones. Gérer les options. modes.invoke_options = "" -- Normal options from the template. No default values. Options normales venant du modèle. Aucune par defaut. -- In the template : options = "params docview docmin docmax docdef docnotice docafter docline docsrc" modes.mode_options = "" -- Options de debug du module par edit. Aucune par defaut. -- modes.mode_options = "unitest debug noerr erron params docview nobox nocat docin docmax docnotice docdef docline docsrc notices " -- modes.mode_options change only by editing this module code or the calling module. Empty default value. -- modes.mode_options change n'est modifié que par ce module ou celui qui l'appele. Valeur par defaut vide. modes.used_options = {} -- table to collect tested options then list them at end of tests. modes.available_options = "" -- table to collect all available options, at any time. function modes.options_from_mode(mode_name, options_for_modes) -- mode_name = mode_name or (modes.args_final and modes.args_final.mode) or (modes.args_import and modes.args_import.mode) or p.mode_name or modes.mode_name or "read" -- local mode_options = "" modes.options_for_modes = options_for_modes or modes.options_for_modes mode_name = mode_name or "read" if modes.options_for_modes and modes.options_for_modes[mode_name] then modes.mode_options = modes.options_for_modes[mode_name] end -- modes.mode_options = mode_options -- modes.mode_options = modes.options_for_modes return modes.mode_options, mode_name end function modes.option(key, opt) -- Is one option in available options? -- Language identifiers allow to enforce some languages. -- Errors appear only in Template or Module namespace, waiting the task T53660. -- local opt = other if type(key) ~= "string" then key = "" end key = mw.text.trim(key) if type(opt) ~= "string" then opt = "" end opt = mw.text.trim(opt) -- available_options = modes.available_options -- local available_options = " " .. (modes.invoke_options or "") .. " " local available_options = (modes.invoke_options or "") if available_options and modes.mode_options -- other param can replace modes.mode_options then available_options = " " .. available_options .. " " .. modes.mode_options .. " " elseif available_options and opt then available_options = " " .. available_options .. " " .. opt .. " " end -- available_options = string.gsub(available_options, " ", ";") available_options = viewer.simpleList(available_options, " ") -- The searched keyword is it among the options words? And not included in another word. local ifyes = viewer.is_in_sp(key or "", available_options) -- and true -- Collect options tested along the execution of the module modes.used_options = modes.used_options or {} if ifyes then modes.used_options[key] = "y" else modes.used_options[key] = "n" end local used = "" for key, xx in pairs(modes.used_options) do if xx == "y" then used = used .. ", <b>" .. tostring(key) .. "</b> " .. xx else used = used .. " " .. tostring(key) .. ", " .. xx end end modes.available_options = available_options modes.used_opts = used -- yes is not nil return ifyes, used, available_options -- yes is not nil end -- function modes.option(key, opt) function modes.options_from_mode_tests(t) local memo = events.save_configs() -- Save global configuration before eventual changes. local t = "options_from_mode_test:" or t for md, opt in pairs(modes.options_for_modes) do t = t .. "<br>- " .. viewer.ta(md, opt) end t = t .. viewer.Th() .. viewer.Tc("Mode") .. viewer.Tc("List of options") .. viewer.Tc("noerr value") .. viewer.Tc("docview value") .. viewer.Tc("tests value") local function test_options_from_mode(md, op1, op2, op3) modes.available_options = "" local opstest = modes.options_from_mode(md) or "" -- return viewer.Tr() .. viewer.Td(md) .. viewer.Td(opstest) .. viewer.Td( modes.option(op1, opstest) ) .. viewer.Td( modes.option(op2, opstest) ) return viewer.Tr() .. viewer.Td(md) .. viewer.Td(opstest) .. viewer.Td( modes.option(op1, opstest) ) .. viewer.Td(modes.option(op2, opstest)) .. viewer.Td(modes.option(op3, opstest)) end t = t .. "<br>options_from_mode_test:" t = t .. test_options_from_mode("read", "noerr", "docview", "tests") t = t .. test_options_from_mode("edit", "noerr", "docview", "tests") t = t .. test_options_from_mode("tests", "noerr", "docview", "tests") t = t .. viewer.Te() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function modes.options_from_mode_tests(t) function modes.trackModes(where, xyz) -- Track formation of modes modes.trackModes_txt = (modes.trackModes_txt or "") .. viewer.ta("\n* trackModes", where) .. viewer.ta("mode_options", modes.mode_options) .. viewer.ta("invoke_options", modes.invoke_options) .. viewer.ta("available_options", modes.available_options) .. " used_opts = " .. (modes.used_opts or "") return modes.trackModes_txt end function modes.options_to_catView() -- Init or restaure modes.catView = modes.catView from options if modes.option(":") or modes.option("catview") then modes.catView = ":" else modes.catView = "" end return modes.catView end -- function modes.options_to_catView() function modes.used_options_list(t, used_options) local t = "List of modes:" or t used_options = used_options or modes.used_options modes.mode_name = modes.mode_name for md, opt in pairs(modes.options_for_modes) do t = t .. "<br>- " .. viewer.ta(md, opt) end -- List of used options after collect them t = t or "" t = t .. "\n* " .. viewer.form9user("translate_user_wiki_lang_msg", translate.user_lang, translate.wiki_lang) -- ( or viewer.form9user("translate_user_wiki_lang_msg", translate.user_lang, translate.wiki_lang) or " missing user_wiki_lang_msg " ) t = t .. "\n* Actual mode used: <b>" .. modes.mode_name .. "</b>" t = t .. "\n* Options read the last time in these tests, ones <b>activated</b> are in bold: " t = t .. "\n* Options lues pour la dernière fois pendant ces tests, celles <b>activées</b> sont en gras : " t = t .. "<br>" local used = "" for key, x in pairs(modes.used_options) do if x == "y" then used = used .. ", <b>" .. tostring(key) .. "</b> " else used = used .. ", " .. tostring(key) .. " " end end t = t .. used -- t = t .. "\n* import_arguments_track : " .. modes.import_arguments_track return t, used end -- function modes.used_options_list(t, used_options) function modes.options_from_args_tests(t) local memo = events.save_configs() -- Save global configuration before eventual changes. local mode_options_memo = modes.mode_options -- save local invoke_options_memo = modes.invoke_options -- save local used_options_memo = mw.clone(modes.used_options) -- save modes.used_options = {} -- for test local t = "options_from_args_tests:" or t t = t .. "<br>" .. luaTable.formSubCounts("modes.i18n") t = t .. viewer.Th() .. viewer.Tc("mode_options") .. viewer.Tc("invoke_options") .. viewer.Tc("opt can replace mode_options") .. viewer.Tc("available options") .. viewer.Tc("option result") .. viewer.Tc("valid result") local function options_from_args(mode_options, invoke_options, opt, key, verif) modes.available_options = "" modes.mode_options = mode_options or "" modes.invoke_options = invoke_options or "" local ifyes, available_options = modes.option(key, opt) local testOK = "" if tostring(ifyes) == tostring(verif) then testOK = "true" else testOK = "false" end return viewer.Tr() .. viewer.Td( mode_options or "" ) .. viewer.Td( invoke_options or "" ) .. viewer.Td( opt or "" ) .. viewer.Td( modes.available_options ) .. viewer.Td( viewer.ta(key, ifyes) ) .. viewer.Td( testOK ) end t = t .. options_from_args("nobox nocat", "en docview", nil, "nobox", "true") t = t .. options_from_args("nobox nocat", "en docview", nil, "nocat", "true") t = t .. options_from_args("nobox nocat", "en docview", nil, "en", "true") t = t .. options_from_args("nobox nocat", "en docview", nil, "docview", "true") t = t .. options_from_args("nobox nocat", ": docview", nil, ":", "true") t = t .. options_from_args("nobox nocat", "en docview", "docline fr", "docline", "false") t = t .. options_from_args("nobox nocat", "en docview", "docline fr", "docline", "false") t = t .. options_from_args(" ", nil, "docline fr", "docline", "false") t = t .. options_from_args(" ", nil, "docline fr", "fr", "false") t = t .. options_from_args(" ", "en docview", "docline fr", "en", "true") t = t .. options_from_args("nobox nocat", nil, "docline fr", "docline", "false") t = t .. options_from_args("nobox nocat", "en docview", "docline fr", nil, "true") t = t .. options_from_args("nobox nocat", "en docview", nil, "docline", "false") t = t .. viewer.Te() t = t .. modes.used_options_list(nil, modes.used_options) t = t .. "\n* After these tests, previous options are restored. Après ces tests, les options antérieures sont restaurés." modes.mode_options = mode_options_memo -- restore modes.invoke_options = invoke_options_memo -- restore modes.used_options = used_options_memo -- restore events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function modes.options_from_args_tests(t) function p.form_result(args_final) versioning.deprecatedFunction("p.form_result", "modes.form_result") return modes.form_result(args_final) end -- translate -- Normal result of the module -- Resultado normal del módulo -- Résultat normal du module function modes.form_result(args_final) local memo = events.init_configs() -- Initialize global configurations and save them before eventual changes. if type(args_final) ~= "table" then args_final = modes.args_final end -- optional arguments local res = "" events.gener_categories(args_final) -- Form all categories without activate them -- List of parameters for module documentation -- "docview" or ":" add the documentation panel -- "docmin" list only some basic parameters -- "docdef" list only the parameters defined, having a non-zero value -- "docmax" list all known parameters -- "docnotice" generate documentations of records -- "docline" put all parameters on a single line -- "docsrc" put the parameters in colors according to the sources -- modes.options = " docdata docmin docdef docmax docline docview docafter docnotice docsrc : " -- for standard documentation -- modes.options = " erron noerr nobox nocat " -- do not form normal result -- modes.options = " debug tests en es fr " -- enforce a language for debug -- Option nocat means "Do not categorize and do not show categories." if modes.option("docview") or modes.option(":") or modes.option("tests") or (modes.args_final.mode == "edit") then -- res = res .. viewer.docDropBox("allwaysview", "versioning_support_desk_title", versioning.form_support_desk_report ) res = res .. p.formDocBox(args_final) end if not modes.option("nobox") then res = res .. p.normal_box(args_final) end -- Display categories. Afficher les catégories. if ( not modes.option("nobox") ) and ( modes.option("catview") or modes.option(":") ) then res = res .. events.categories_lister(":") end modes.time3 = os.clock() -- res = res .. modes.used_options_list() if modes.option("tests") or (modes.args_final.mode == "tests") then local memo2 = events.init_configs() -- Initialize global configurations and save them before eventual changes. res = res .. viewer.docGroup("allwaysview") events.restore_configs(memo2) -- Restore global configurations after eventual changes. res = res .. versioning.running_times(false, "") end events.restore_configs(memo) -- Restore global configurations after eventual changes. return res end -- function modes.form_result(args_final) --[[ Management of arguments and translations along their transformations : datas.args_wikidata = {} -- Wikidata arguments, from Wikidata events.errors_list = {} -- Errors list events.categories_list = {} -- Categories lists modes.args_known = {} -- Known arguments, at main module level modes.args_invoke = {} -- Invoke arguments, at {{#invoke: ... }} level modes.args_template = {} -- Template arguments, at {{Template| ... }} level modes.args_source = {} -- Source arguments = args_template + args_invoke modes.args_unknown = {} -- Unknown arguments modes.args_import = {} -- Import arguments modes.args_final = {} -- Final arguments, interactions in p.interact_args_final() modes.args_selected = {} -- Selected arguments, in some modules translate.wiki_translations = {} -- Wiki translations translate.user_translations = {} -- User translations versioning.loaded_pack = {} -- loaded packages of modules and libraries versioning.loaded_vers = {} -- loaded versions of modules and libraries --]] function modes.argsConfigIinit(args_source) -- Memorize direct configuration arguments, without translation, for helpers. if type(args_source) ~= "table" then args_source = modes.args_source end local new_source = mw.clone(args_source) -- To ensure not disturb original local args_config = {} args_config.userlang = args_source.userlang -- user language argument new_source.userlang = nil args_config.wikilang = args_source.wikilang -- wiki language argument new_source.wikilang = nil args_config.mode = args_source.mode -- mode argument new_source.mode = nil args_config.c = args_source.c -- invoke options argument new_source.c = nil args_config.dockey = args_source.dockey or args_source[1] -- doc selector argument new_source.dockey = nil args_config.itemid = args_source.itemid or args_source.id or args_source[2] -- wikidata item id argument new_source.itemid = nil args_config.soughtversions = args_source.soughtversions -- sought_versions argument new_source.soughtversions = nil args_config.knownversions = args_source.knownversions -- knownversions argument new_source.knownversions = nil modes.args_source = new_source modes.args_config = args_config return args_config, new_source end -- function modes.argsConfigIinit() function modes.change_itemid(id_in) -- Select a wikidata default item if needed. Default "Q41568" local id = "" if id_in then -- Local function parameter have priority. id = id_in else -- Else use the template arguments or inforce itemid here. id = modes.args_config.id -- id = "Q535" -- (1802 – 1885) Victor Hugo -- id = "Q8739" -- (near 287 av. J.-C. – 212 av. J.-C.) Archimède, Machine d'Archimède -- id = "Q20882" -- (1832 – 1923) Gustave Eiffel id = "Q1290" -- (1623 – 1662) Blaise Pascal -- id = "Q41568" -- (1533 – 1592) Michel de Montaigne -- id = "Q83428" -- (near 1493 – 1541) Paracelse -- id = "Q131671" -- (VIe siècle av. J.-C. – Ve siècle av. J.-C.) Xénophane -- id = "Q213330" -- (1330 – 1418) Nicolas Flamel -- id = "Q21157618"-- ( – 1932) Charles Maumené -- id = "Q9364" -- (1905 – 1980) Jean-Paul Sartre end local nst = 10 -- mw.site.namespaces.Template local nsm = 828 -- mw.site.namespaces.Module local mwtitle = mw.title.getCurrentTitle() local nsX = mw.title.getCurrentTitle():inNamespaces("10", "11", "828", "829") local ns = tostring(mw.site.namespaces.id) if viewer.is_in_sp(ns, "10;11;828;829", ";") then -- Change itemid only where title cannot be in wikidata. modes.args_config.id = id modes.args_config.itemid = id end -- modes.args_config.id = id -- always inforce -- modes.args_config.itemid = id -- always inforce return id end -- function modes.change_itemid(id_in) function modes.args_known_structure(t, args_known) -- modes_args_known_structure_title = Table structure of arguments -- if true then return "" end -- to bypass in DEBUG local t = t or "\n* <b>args_known_structure :</b> " -- modes_list_all_args_main_title local tt if type(args_known) ~= "table" then args_known = modes.args_known end if type(args_known) == "table" then for key, elem in pairs(args_known) do tt = viewer.tam("typ", elem.typ) .. viewer.tam("keyword", elem.keyword) .. viewer.tam("syn", elem.syn) tt = tt .. viewer.tam("need", elem.need) .. viewer.tam("prop", elem.prop) .. viewer.tam("format", elem.format) tt = string.sub(tt, 3, -1) t = t .. '\n: ' .. tostring(key) .. ' = { ' .. tt .. ' } ' end end return t end -- function modes.args_known_structure(t, args_known) function modes.levenshtein(word1, word2) -- Compute the Levenshtein distance between 2 ASCII words. -- prevent exceptions local cout = 0 if (word1 == nil) or (word2 == nil) then return 999, "<br>lev: " .. viewer.ta("word1", word1) .. viewer.ta("word2", word2) end local len1 = string.len(word1) local len2 = string.len(word2) local lev = 0 local t = "<br>lev: " .. viewer.ta("word1", word1) .. viewer.ta("word2", word2) if (type(word1) ~= "string") or (type(word2) ~= "string") or (word1 == "") or (word2 == "") then lev = len1 + len2 return lev, t .. viewer.ta("lev", lev) end -- simple case if (word1 == word2) then lev = 0 return lev, t .. viewer.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 -- simulate double dimensions tables 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(word1, i-1) local c2 = string.byte(word2, 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 .. viewer.ta("lev", lev) end -- function modes.levenshtein(word1, word2) function modes.levenshtein_test_1(search, word, max) -- search = mot cherché dans la liste -- word = un des mot de la liste local diffmaxi = modes.similar_args_diffmaxi( string.len(search) ) local len1, len2, lev, tlev, t, diff -- t = t .. "<br>- diff: " .. viewer.ta("mot1", mot1) .. viewer.ta("mot2", mot2) .. viewer.ta("diff", diff) t = "<br>levenshtein : " if (not search ) or (not word) then diff = 99 t = t .. viewer.ta("diff", diff) .. " no word. " elseif search == word then diff = 0 t = t .. viewer.ta("diff", diff) .. " , " .. search .. " = " .. word .. " " else -- len1 = string.len(search) -- len2 = string.len(word) lev, tlev = modes.levenshtein(search, word) if (lev <= diffmaxi) then t = t .. viewer.ta("diffmaxi", diffmaxi) .. " >= " .. viewer.ta("lev", lev) .. " <b>" .. search .. " ==> " .. word .. "</b> " else t = t .. viewer.ta("diffmaxi", diffmaxi) .. " >= " .. viewer.ta("lev", lev) .. " " .. search .. " / " .. word .. " " end diff = lev end return diff, t, search, word end -- function modes.levenshtein_test_1(search, word, max) function modes.similar_levenshtein_tests(res, c) local memo = events.save_configs() -- Save global configuration before eventual changes. if type(res) ~= "string" then res = nil end local res = res or ("\n* " .. viewer.form9user("modes_max_nearest_argument_msg") ) local errors = "" local n, t = modes.levenshtein_test_1( "nom", "nom") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "nom", "Nom") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "top", "pot") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "ami", "amis") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "nom", "name") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "m", "mu") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "m", "mur") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "mur", "m") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "c", "C") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "c", "cf") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "c", "long") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "xxx", "") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "", "xyz") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "xxx", "xyz") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "prénom", "Prenom") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "catégorie", "Category") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "description", "Description") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "anneeDeces", "anneeNaissance") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "anoNacimiento", "anneeNaissance") res = res .. tostring(t) local n, t = modes.levenshtein_test_1( "avant-après", "après-avant") res = res .. tostring(t) if errors ~= "" then res = res .. "\n* <b>levenshtein_test</b> errors = " .. viewer.errorColor(errors) end events.restore_configs(memo) -- Restore global configurations after eventual changes. return res end -- function modes.similar_levenshtein_tests( res, c) modes.constants = modes.constants or {} -- Similar words search : diff on length -- Cerrar de palabras puscadas: diff en longitud -- Recherche de mots proches: diff sur longueur modes.constants.near_word_search_diff_coef = 0.30 -- Access to change these constants from anywhere. modes.constants.near_word_search_diff_const = 0.82 -- Maximum number of different letters between 2 argument names -- Número máximo de letras diferentes entre 2 nombres de argumento -- Nombre maximum de lettres différentes entre deux noms d'arguments function modes.similar_args_diffmaxi(length, t) -- diffmaxi from length of arg arglingual name local coef = modes.constants.near_word_search_diff_coef or 0.30 local constant = modes.constants.near_word_search_diff_const or 0.82 local diffmaxi = math.floor( coef * length + constant ) if t then t = t .. tostring(coef) .. " * length + " .. tostring(constant) end return diffmaxi, t end -- function modes.similar_args_diffmaxi(length, t) -- For an unknown argument, seeks the name of the closest among the known arguments translated function modes.similar_args_list(args_known) local list, arglingual = {}, "xxx" if type(args_known) ~= "table" then args_known = modes.args_known end if type(args_known) ~= "table" then return "similar_args_list", 1 end for key, argm in pairs(args_known) do -- List only all known arguments if not tonumber(key) then -- For named arguments only key = tostring(key) arglingual = tostring(translate.wiki_translations[key]) list[key] = arglingual end end return list end -- function modes.similar_args_list(args_known) -- For an unknown argument, seeking the name of the nearest argument among the known arguments function modes.similar_args_search(search, list) local dist, lengths, tlev = 9, 0 local trouve1, trouve2, trouve3 = nil, nil, nil local min1, min2, min3 = 99, 99, 99 local diffmaxi = modes.similar_args_diffmaxi( string.len(search) ) local t = ", " .. tostring(diffmaxi) .. " / " .. tostring(length) .. " " for key, arglingual in pairs(list) 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, tlev = modes.levenshtein(search, arglingual) if (dist <= min1) then trouve3 = trouve2 min3 = min2 trouve2 = trouve1 min2 = min1 min1 = dist trouve1 = tostring(arglingual) end end t = t .. "<br>" .. viewer.ta("cherche", cherche) .. viewer.ta("trouve1", trouve1) .. viewer.ta("min1", min1) .. viewer.ta("trouve2", trouve2) .. viewer.ta("min2", min2) .. " " .. t if trouve1 and min1 == 0 then t = t .. viewer.wikidataColor(viewer.ta("connu", trouve1)) end if trouve1 and min1 <= diffmaxi then t = t .. viewer.wikidataColor(viewer.ta("min1 "..min1.."<="..diffmaxi, trouve1)) end if trouve2 and min2 <= diffmaxi then t = t .. viewer.wikidataColor(viewer.ta("min2 "..min2.."<="..diffmaxi, trouve2)) end if trouve3 and min3 <= diffmaxi then t = t .. viewer.wikidataColor(viewer.ta("min3 "..min3.."<="..diffmaxi, trouve3)) end return trouve1, min1, trouve2, min2, t end -- function modes.similar_args_search(search, list) -- t = modes.similar_args_search_1( t, "nomm", "digit") function modes.similar_args_search_1( t, search, liste) local args_list = modes.similar_args_list(modes.args_known) local trouve1, min1, trouve2, min2 = modes.similar_args_search(search, args_list) -- local trouve1, min1, trouve2, min2 = "aaa", 1, "bbb", 22 t = t .. "\n* similar_args_search_1 : " .. viewer.ta("search", search) .. viewer.ta("trouve1", trouve1) .. viewer.ta("min1", min1) .. viewer.tam("trouve2", trouve2) .. viewer.tam("min2", min2) return t or " similar_args_search_1 " end -- function modes.similar_args_search_1( t, search, liste) function modes.similar_args_search_tests( t, args_known) local memo = events.save_configs() -- Save global configuration before eventual changes. if type(args_known) ~= "table" then args_known = modes.args_known end local err = modes.verify_args_tables(args_known, modes.args_source) if err then return err end -- local key, argsyn, arglingual, txt -- local coef = modes.constants.near_word_search_diff_coef -- local constant = modes.constants.near_word_search_diff_const t = "\n* " .. (t or "Formula to compute the near words limit: Formule de calcul de limite des mots proches : ") local diffmaxi diffmaxi, t = modes.similar_args_diffmaxi(10, t .. "diffmaxi = ") t = t .. "\n* List of diffmaxi / lengths : " for length = 1, 16 do -- For all lengths -- local diffmaxi = math.floor( coef * length + constant ) diffmaxi = modes.similar_args_diffmaxi(length) t = t .. ", " .. tostring(diffmaxi) .. " / " .. tostring(length) .. " " end t = t .. "\n* List of known arguments and <b>synonyms</b> : " local txt, lingual = "", "" local ref_words = {} for key_known, argm in pairs(args_known) do -- For all known parameters if argm.syn == 1 then key = argm.keyword argsyn = key_known .. ">" -- synonym argument else key = key_known argsyn = "" -- synonym argument end lingual = translate.wiki_translations[key] or "-" -- import one source argument txt = argsyn .. key .. "/" .. lingual if argm.syn == 1 then t = t .. ", <b>" .. txt .. "</b> " -- synonyms else t = t .. ", " .. txt .. " " end ref_words[key] = {} ref_words[key].argmt = key ref_words[key].lingual = lingual end t = t .. "\n* Test similar arguments 1." t = modes.similar_args_search_1( t, "anneedece", {["a"]="but", ["b"]="porter", ["c"]="anneedeces"}) t = t .. "\n* Test similar arguments 2." t = modes.similar_args_search_1( t, "porte", {["a"]="but", ["b"]="porter", ["c"]="pot"}) events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function modes.similar_args_search_tests( t, args_known) -- Check if the value of an argument is among the possible values. -- Vérifier si la valeur d'un argument est parmi les valeurs possibles. function modes.multiple_values(argmt, argvalue, args_final, args_known) if type(args_final) ~= "table" then args_final = modes.args_final or {} end if type(args_known) ~= "table" then args_known = modes.args_known end -- or p.args_known local argvalue = argvalue or args_final[argmt] local arg_values, key_values, keyword, keyval, argval, rank local argm = args_known[argmt] if argm then arg_values = translate.wiki_translations[argm.arg_values] or "" -- example "no;nada;cn;50;us;70;mpf" in local language key_values = argm.key_values or "" -- example "no;none;cn;50;us;70;mpf" in referal english end if type(arg_values) == "string" and type(key_values) == "string" then local arg_tab = mw.text.split(arg_values, ';') -- table of arg local key_tab = mw.text.split(key_values, ';') -- table of key -- Default values keyword = nil rank = 0 -- rank of local value and key value keyval = nil -- key value argval = nil if argm and arg_values and argvalue then for i, key in ipairs(arg_tab) do if key == argvalue then -- Search argvalue in arg_tab rank = i keyval = key_tab[i] -- Return correponding keyval in key_tab argval = argvalue keyword = argm.keyword end end end end return keyword, keyval, argval, rank, arg_values end -- function modes.multiple_values(argmt, argvalue, args_final, args_known) function modes.multiple_values_tests(t) -- Test: convert a string to a table of words local t = t or "\n* Test <b>multiple_values</b> :" local group_test = { -- events.testGroup { argm = "region", argvalue = "inde", }, { argm = "region", argvalue = nil, }, { argm = "rights", argvalue = "mpf", }, { argm = "rights", argvalue = "non", }, { argm = "rights", argvalue = nil, }, { argm = "sex", argvalue = "femme", }, { argm = "sex", argvalue = "homme", }, { argm = "sex", argvalue = "enfant", }, -- rights_values = '70,50,mpf,ONU,none', -- region = 'region', -- argument with verified multiple values } local tabOptions = {} tabOptions.headers = viewer.form9user("argm; all values; value; keyword; keyval; argval; rank") tabOptions.testGroup = group_test tabOptions.rowGroup = {} if type(group_test) == "table" then for key, test in pairs(group_test) do local keyword, keyval, argval, rank, arg_values = modes.multiple_values(test.argm, test.argvalue, test.args_final) table.insert( tabOptions.rowGroup, { tostring(test.argm or "-"), tostring(arg_values or "-"), tostring(test.argvalue or "-"), tostring(keyword or "-"), tostring(keyval or "-"), tostring(argval or "-"), tostring(rank or "-") } ) end else t = t .. "error : multiple_values_tests has no table. " end t = t .. viewer.tableView(tabOptions) -- Form a table with lines and columns. return t end -- function modes.multiple_values_tests(t) function modes.multiple_selection(opt, selector, to_select) -- Select items to selector containing selecting items local t, selected_txt, selector_txt, selector_tab, to_select_txt, to_select_tab, selected_tab = "", "" local cut = string.sub( opt, 1, 1 ) or ";" if type(selector) == "table" then selector_tab = selector end if type(selector) == "string" then selector_tab = mw.text.split(selector, cut, true) end if type(to_select) == "table" then to_select_tab = clone(to_select) end if type(to_select) == "string" then to_select_tab = mw.text.split(to_select, cut, true) end selected_tab = {} -- local k, Nsel, N, maxi, pos = 0, 0, 1, 999, nil local reject_select = false local equal = true for i, selector in ipairs(selector_tab) do -- selector authorities only following selectors if Nsel >= maxi then break end selector = mw.text.trim(selector) N = tonumber(selector) if selector == "+" then -- selector all items for key, val in pairs(to_select_tab) do Nsel = Nsel + 1 selected_tab[key] = val end elseif selector == "-" then -- minus sign rejects all reject_select = true elseif N and N < 1 then -- minus sign rejects all reject_select = true elseif N and (string.sub(selector, 1, 1) == "+") then -- selector +N more items maxi = Nsel + N elseif N then -- selector N maximum total items maxi = N else -- selector ONE item from to_select_tab if it matches selector ( not - or + or +N or N ) for key, val in pairs(to_select_tab) do local select_t, val_t = selector, val if not viewer.is_in("U", opt) then select_t = string.lower(select_t) end -- recognize lowercase and uppercase if not viewer.is_in("t", opt) then select_t = mw.text.trim(select_t) end -- recognize after trim if not viewer.is_in("U", opt) then val_t = string.lower(val_t) end -- recognize lowercase and uppercase if not viewer.is_in("t", opt) then val_t = mw.text.trim(val_t) end -- recognize after trim equal = viewer.is_in("=", opt) -- recognize only equal string if equal then equal = (selector == val) else equal = viewer.is_in(select_t, val_t) end -- if viewer.is_in(selector, val) then if equal then -- recognize if selector is equal or is inside an item from to_select_tab t = t .. viewer.ta(selector, val) selected_tab[selector] = val Nsel = Nsel + 1 to_select_tab[key] = " " -- Delete the selected item to use it only once selected_txt = selected_txt .. val .. ', ' end end end end -- selected_txt = table.concat(selected_tab) return selected_txt, selected_tab, t end -- function modes.multiple_selection(opt, selector, to_select) function modes.multiple_selection_tests(t) local memo = events.save_configs() -- Save global configuration before eventual changes. local t = (t or "") .. "\n* <b>multiple_selection</b> options: " .. viewer.ta("=", "equal only") .. viewer.ta("t", "not trim before and after") .. viewer.ta("U", "not lowercase and uppercase") local function multiple_selection_test1(t, opt, selector, to_select) local selected_txt, selected_tab, txt = modes.multiple_selection(opt, selector, to_select) t = t .. viewer.Tr() .. viewer.Td(opt) .. viewer.Td(selector) .. viewer.Td(to_select) .. viewer.Td( txt .. viewer.ta("selected_txt", selected_txt) ) return t, opt, selector, to_select -- , selected_txt, selected_tab end local opt = "; " t = t .. "\n: selector = <b>nobel,+1,président,3,député,prix</b> signifie : sélectionner le premier, puis 1 de plus parmi les suivants, puis 3 en tout au maximum." local head = mw.text.split( viewer.form9user("modes_multiple_selection_test_headers") , ';') t = t .. viewer.Th() .. viewer.Tc(head[1]) .. viewer.Tc(head[2]) .. viewer.Tc(head[3]) .. viewer.Tc(head[4]) -- Todo ? P39 = fonction = "président de Pologne, député à l'Assemblée, Prix Nehru, Nobel de la paix" -- modes_multiple_selection_test_select = "2, nobel, president, deputy, price", t = multiple_selection_test1( t, opt, "2; nobel; président; député; prix", "président de Pologne; député à l'Assemblée; Prix Nehru; Nobel de la paix" ) t = multiple_selection_test1( t, ";U", "2; nobel, président; député; prix", "président de Pologne; député à l'Assemblée; Prix Nehru; Nobel de la paix" ) t = multiple_selection_test1( t, opt, "3; député; prix; nobel; président", "président de Pologne; député à l'Assemblée; Prix Nehru, Nobel de la paix" ) t = multiple_selection_test1( t, ";=", "3; député; prix; nobel; président", "président de Pologne; député; Prix Nehru; Nobel" ) t = multiple_selection_test1( t, ";t", "3; député; prix; nobel; président", "président de Pologne; député; Prix Nehru; Nobel" ) t = multiple_selection_test1( t, ";", "3; prix; nobel;+1; président; député", "président de Pologne; député à l'Assemblée; Prix Nehru; Nobel de la paix" ) t = multiple_selection_test1( t, ";", "3; président; nobel; député; prix", "président de Pologne; député à l'Assemblée; Prix Nehru; Nobel de la paix" ) t = multiple_selection_test1( t, ";t", "3; député; prix; nobel; président", "président de Pologne; député; Prix Nehru; Nobel" ) t = multiple_selection_test1( t, ";U", "2; nobel; président; député; prix", "président de Pologne; député à l'Assemblée; Prix Nehru; Nobel de la paix" ) t = t .. viewer.Te() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function modes.multiple_selection_tests(t) function modes.verify_args_tables(_known, _source) -- initialize all the values to "" in arg table if type(_known) == "table" then modes.args_known = _known end if type(modes.args_known) ~= "table" then events.add_err("modes_no_known_arguments_err") -- events.add_cat("modes_no_known_args_cat") return viewer.errorColor(" Internal error : no source or no known arguments ! ") end if type(_source) == "table" then modes.args_source = _source end if type(modes.args_source) ~= "table" then events.add_err("modes_no_source_arguments_err") -- events.add_cat("modes_no_source_arguments_cat") return viewer.errorColor(" Internal error : no source or no known arguments ! ") end return end -- function modes.verify_args_tables(_known, _source) function modes.import_arguments(args_known, args_source, wiki_translations, args_wikidata) -- import all arguments from template, or invoke, or wikidata local args_import = {} -- table d'arguments internationale simple local err = nil local cats = "" -- default parameters if type(args_known) ~= "table" then args_known = modes.args_known end if type(args_source) ~= "table" then args_source = modes.args_source end wiki_translations = wiki_translations or translate.wiki_translations if type(args_wikidata) ~= "table" then args_wikidata = datas.args_wikidata end -- modes.nowyear = tonumber(os.date("%Y") ) -- now_date = os.date("%Y-%m-%d %H:%M:%S") args_import.nowyear = modes.nowyear modes.import_arguments_err = "" modes.import_arguments_track = "" local err = modes.verify_args_tables(args_known, args_source) if err then return args_import, err end -- local err, er1, t2 = "", "", "" local key, argval, argid = "kkk", "xxx", "" local argknw, arglingual, argreceived = nil, "", "" local argm = {} -- used arguments -- events.erron = true -- Errors actived or no. Errores activas o no. Erreurs activées ou non. -- events.errors_list = {} -- collect all errors local key_N, key_NN = 0, 0 local arg_found, rec_found, already_found = false, false, false -- for key_known, argm in pairs(args_known) do argm.found = 0 -- First, initialize all known arguments end -- modes.args_unknown = mw.clone(modes.args_source) -- unknown arguments to detect are source arguments without known arguments. local key_known_init = nil -- local argm_orig = nil local argm_syn = nil -- Try to read all known arguments. Intentar leer todos los argumentos conocidos. Essayer de lire tous les arguments connus. for key_known, argm in pairs(args_known) do argm.src = nil argm.trk = " n" key_known_init = key_known -- first initialise each known argument modes.import_arguments_track = tostring(modes.import_arguments_track) .. " - " .. tostring(key_known) argm_syn = args_known[argm.keyword] if argm.syn == 2 then -- Name an unnamed argument, positional, by its synonym. Nommer un argument non nommé, numéroté, par son synonyme. -- Rename a named argument, by its synonym. Renommer un argument nommé, par son synonyme. -- argm_orig = key_known -- DEBUG key_known = argm.keyword -- synonyms are defined with the stamp "syn = 2", then here stamp the basic argument with "syn = 1". args_known[key_known].syn = 1 argm = args_known[key_known] -- new variable argm argm.src = nil argm.trk = "s" modes.import_arguments_track = tostring(modes.import_arguments_track) .. ">" .. tostring(key_known) end -- initialiser un argument arg_found = false argval = nil argm.trk = argm.trk.."=" -- importer un argument wikidata if args_wikidata[key_known] then argval = args_wikidata[key_known] argm.src = "wd" argm.trk = argm.trk.."w" if argm_orig then -- args_known[argm_orig].src = "wd" -- args_known[argm_orig].trk = (args_known[argm_orig].trk or "").."w" end -- if argm_orig then argm_orig = key_known end -- DEBUG arg_found = true modes.import_arguments_track = modes.import_arguments_track .. "=<b>" .. tostring(argval) .. "</b> " end -- import a source argument. importer un argument source. arglingual = translate.wiki_translations[key_known] modes.import_arguments_track = modes.import_arguments_track .. "/" .. tostring(arglingual) if arglingual then -- The argument name has a translation in wiki language -- if modes.frame[arglingual] then -- argval = modes.frame[arglingual] -- argm.src = "inv" -- arg comes from invoke -- end if modes.frame.args[arglingual] then -- argval = modes.frame.args[arglingual] -- argm.src = "inv" -- arg comes from invoke -- arg_found = true end if modes.frame:getParent().args then -- argval = modes.frame:getParent().args[arglingual] -- argm.src = "tpl" -- arg comes from template -- arg_found = true end if args_source[arglingual] and not modes.args_config[arglingual] then -- the argument come from template else from invoke else from wikidata -- if argval then -- the argument value exist and come from template else from invoke else from wikidata argval = args_source[arglingual] argm.src = "args" argm.trk = argm.trk.." a" arg_found = true local arg_values = wiki_translations[argm.arg_values] if argm.keys_values and arg_values then -- The argument is limited to multiple values with arg_values and keys_values, and the values are defined. local pos = string.find(arg_values, argval) if pos then -- The value of the argument is in the multiple values of the arguments. -- argm.src = "args" argm.trk = argm.trk.."m" -- arg_found = true if argm_orig then -- args_known[argm_orig].src = "args" -- args_known[argm_orig].trk = (args_known[argm_orig].trk or "").."d" end else events.add_err("modes_args_values_err", argm.keyword, argval, arg_values) -- argval = nil end else -- argm.src = "args" argm.trk = argm.trk.."c" -- arg_found = true if argm_orig then -- args_known[argm_orig].src = "args" -- args_known[argm_orig].trk = (args_known[argm_orig].trk or "").."c" end end modes.import_arguments_track = modes.import_arguments_track .. "=<b>" .. tostring(argval) .. "</b> " end -- not args_source[arglingual] is normal else -- internal error and category -- events.add_err("versioning_module_miss_i18n_trad_err", key_known) -- Generate a category to list all modules with missing translation cats = cats .. events.add_cat( "versioning_err_module_miss_i18n_cat" ) end -- key_N = tonumber(key_known_init) if key_N and not args_known[key_N] then -- events.add_err("modes_too_unnamed_arguments_err", key_N, argval) end -- Record the argument. Guarde el argumento. Enregistrer l'argument. if arg_found == true then argm.found = argm.found + 1 -- compter les arguments redéfinis argm.val = argval args_import[key_known] = argval -- table d'arguments internationale simple if modes.args_unknown[arglingual] then modes.args_unknown[arglingual] = nil -- unknown arguments are source arguments without known arguments. end end end -- modes.import_arguments: after import itself, some surrounding checks. for key_known, argm in pairs(args_known) do -- For all known arguments -- Redefined arguments. Argumentos redefinieron. Arguments redéfinis. -- if argm.found and (argm.found > 1) then -- events.add_err("modes_value_re_defined_err", argm["keyword"]) -- cats = cats .. events.add_cat("versioning_module_usage_error_cat") -- end -- synonyms are defined with the stamp "syn = 2", then here stamp the basic argument with "syn = 1". -- if argm.keyword and args_known[argm.keyword] and args_known[argm.keyword].syn then -- if the argument is a synonym, increase the found level if argm.keyword and args_known[argm.keyword] and args_known[argm.keyword].syn then -- if the argument is a synonym, increase the found level if argm.found and (argm.found > 2) then events.add_err("modes_value_re_defined_err", (argm["keyword"] or "**") ) --.. ">2") cats = cats .. events.add_cat("versioning_module_usage_error_cat") end else if argm.found and (argm.found > 1) then events.add_err("modes_value_re_defined_err", (argm["keyword"] or "**") ) --.. ">1") cats = cats .. events.add_cat("versioning_module_usage_error_cat") end end -- need = 0 not necessary argument -- need = 1 necessary from argument -- need = 2 necessary from argument or module interaction -- Missing Arguments. Argumentos que faltan. Arguments manquants. if argm.need and (argm.need == 1) and (not argm.val) then arglingual = wiki_translations[key_known] if arglingual then events.add_err("modes_need_arg_value_err", arglingual) cats = cats .. events.add_cat("versioning_module_usage_error_cat") end end end -- All arguments sources have they been used? -- modes.args_unknown -- unknown arguments are source arguments without known arguments. local args_list = modes.similar_args_list(modes.args_known) for key_src, val_src in pairs(modes.args_unknown) do -- For all unknown source arguments. arglingual = tostring(key_src) -- chercher l'argument traduit key_N = tonumber(arglingual) -- No error for unmamed arguments -- Pas d'erreur pour les arguments non nommés if not key_N then events.add_err("modes_unknown_argument_err", arglingual, val_src) cats = cats .. events.add_cat("versioning_module_usage_error_cat") -- "Erreur : Le paramètre <b>%1</b> est inconnu dans ce modèle. Vérifier ce nom ou signaler ce manque.", -- Cherche un argument connu et de nom ressemblant local diffmaxi = modes.similar_args_diffmaxi( string.len(arglingual) ) local trouve1, min1, trouve2, min2 = modes.similar_args_search(arglingual, args_list) if min1 and (min1 <= diffmaxi) then events.add_err("modes_nearest_argument_err", trouve1) end if min2 and (min2 <= diffmaxi) then events.add_err("modes_nearest_argument_err", trouve2) end end key_N = tonumber(arglingual) if key_N and not args_known[key_N] then events.add_err("modes_too_unnamed_arguments_err", key_N, val_src) events.add_cat("versioning_module_usage_error_cat") end end -- For all unknown source arguments. modes.nowyear = tonumber(os.date("%Y") ) -- now_date = os.date("%Y-%m-%d %H:%M:%S") args_import.nowyear = modes.nowyear modes.args_import = args_import return modes.args_import end -- function modes.import_arguments(args_known, args_source, wiki_translations, args_wikidata) -- - - - ------------------ - - - - --------------------------------- -- Argts : Generate documentation. Generar documentación. Générer la documentation. -- - - - ------------------ - - - - --------------------------------- function modes.generDoc1(paramName, n, paramData, opt) -- t = t .. generDoc1("nom", "ws-name", "docline docdef") -- Normaliser les parametres et signaler les erreurs -- Toujours afficher quelque chose dans la documentation du module ou du modèle. if type(paramName) ~= "string" or type(paramData) ~= "string" then -- signaler l'erreur events.add_err("modes_generDoc1_paramName_err", tostring(paramName) ) return " " end opt = " "..tostring(opt).." " -- transparent, sinon peut donner nil, non génant -- -- former le texte à afficher local newline = "<br>" -- Chaque parametre non nommé est traité par son synonyme. if n then return "" end if modes.option("docline", opt) then newline = "" end local argm = modes.args_known[paramName] if argm then --[ [ if modes.docolor then -- Document the data sources by colors if argm.src == "wd" then paramData = viewer.wikidataColor(paramData) elseif argm.src == "args" then paramData = viewer.invokeColor(paramData) -- elseif argm.src == "inter" then -- paramData = viewer.inter_color(paramData) else paramData = viewer.normalColor(paramData) end end --] ] paramData = paramData -- .. (argm.trk or "") end return " | " .. paramName .. " = <b>" .. paramData .. "</b>" .. newline end -- function modes.generDoc1(paramName, paramId, opt) function modes.generDoc(opt, args_final, module_name) -- List of paramètres for the module documentation -- Lister des paramètres pour la documentation du module -- "docview" or ":" ajouter le panneau de documentation -- "docmin" quelques paramètres de base -- "docdef" seulement les paramètres définis, ayant une valeur non nulle -- "docmax" tous les paramètres connus -- "docnotice" generer les documentations des notices -- "docline" mettre tous les paramètres sur une seule ligne -- "docsrc" mettre les paramètres en couleurs selon les sources -- modes.options = " docdata docmin docdef docmax docline docview docafter docnotice docsrc: " -- for documentation -- modes.options = " erron noerr nobox nocat " -- without normal result -- modes.options = " debug tests en es fr " -- for debug or enforce language -- Option nocat means "Do not categorize and do not show categories." local args_known = modes.args_known local err = modes.verify_args_tables(args_known, modes.args_source) if err then return err end if type(module_name) ~= "string" then module_name = modes.module_name end if type(module_name) ~= "string" then module_name = modes.frame:getTitle() end -- main module, example "Auteur" if type(module_name) ~= "string" then module_name = "Central" end local n, t, val = 0, "", "" if type(args_final) ~= "table" then t = t.."err_args_final="..type(args_final).."<br>" end -- optional arguments if type(args_final) ~= "table" then args_final = modes.args_final end -- optional arguments local key, argknw, argval, arglingual = "", "", "" local lst = true local lst_doc, lst_1, lst_t = {}, {}, "" for key, parm in pairs(args_final) do -- for all known arguments val = "" n = tonumber(key) if n then key = tostring(parm["keyword"]) end -- key for unnamed arguments, in numeric sort argknw = args_known[key] arglingual = tostring(translate.user_translations[key]) -- multilingual name of the arg in the template if arglingual == "nil" then arglingual = key end -- if argument is translatable val = parm -- tostring(args_import[key]) if not viewer.isDef(val) then val = "" end lst = false opt = opt .. " docdef " -- optional display -- if modes.option("docmin", opt) and argknw and (argknw["list"] == 1) then lst = true end if modes.option("docmin", opt) and argknw and (argknw["need"] > 0) then lst = true end if modes.option("docdef", opt) and (val ~= "") then lst = true end if modes.option("docmax", opt) then lst = true end if not args_known[key] then lst = false end if key and args_known[key] and args_known[key].typ == "sys" then lst = false end if lst then -- list if found and selected lst_t = modes.generDoc1(arglingual, n, val, opt) table.insert(lst_doc, {lst_t = lst_t, key = key, user_lang_key = translate.user_translations[key] or "trans"} ) end end table.sort(lst_doc, function (a, b) return (a.user_lang_key < b.user_lang_key) end ) -- alphabetic sort of translated arguments for i, parm in ipairs(lst_doc) do -- List all found arguments t = t .. (parm.lst_t or "lst_t") end t = "\n{{" .. module_name .. " " .. t .. "}}" -- <br> return t end -- function modes.generDoc(opt, args_final, module_name) function modes.sources_of_datas_colors() local res = "" if modes.docolor then -- Document the data sources by colors local datas_sources_of_datas = viewer.form9user("datas_sources_of_datas") -- datas_sources_of_datas = "Informations from: /Wikidata, /template or module, /other, /warning, /error", local splitxt = mw.text.split(datas_sources_of_datas, "/", true) res = res .. splitxt[1] .. " <b> " .. viewer.wikidataColor(splitxt[2]) .. viewer.invokeColor(splitxt[3]) .. viewer.normalColor(splitxt[4]) .. viewer.warningColor(splitxt[5]) .. viewer.errorColor(splitxt[6]) .. ".</b> <br>" end return res end -- function modes.sources_of_datas_colors() function modes.module_init(frame) -- Get modes.args_source with modes.args_config local frame = frame or modes.frame or mw.getCurrentFrame() modes.frame = frame modes.nowyear = tonumber(os.date("%Y") ) -- now_date = os.date("%Y-%m-%d %H:%M:%S") -- Mix arguments from {{#invoke:}}, then arguments from the prioritary template which replace ones from {{#invoke:}}. local v2, nn, ni = 0, 0, 0 local args_tab, mode = {} local templat = frame:getParent().args -- arguments from template local invoked = frame.args -- arguments from #invoke module -- Mix invoked modified arguments from prioritary template arguments. -- Argument 1 from template become the mode in #invoke. Other i arguments must be shifted. local args_tab = mw.clone(invoked) for key, val in pairs(templat) do -- template arguments can modify #invoke arguments. local key = mw.text.trim(key) local val = mw.text.trim(val) local i = tonumber(key) if i then if i == 1 then mode = val -- mode = template[1] args_tab.mode = val else args_tab[i-1] = val end -- transmit other unnamed arguments template[i], but shifted because the mode is in template[1] else args_tab[key] = val end -- transmit any named template arguments template. Even the mode, which replace template[1], behind. end modes.args_source = args_tab modes.args_config = modes.argsConfigIinit(modes.args_source) -- Extract and put apart args_config from args_source -- Default values of main module version. if versioning.main_versions then versioning.main_versions.versionName = versioning.main_versions.versionName or "Central0" versioning.main_versions.versionNumber = versioning.main_versions.versionNumber or "0.00" versioning.main_versions.versionDate = versioning.main_versions.versionDate or "2013-03-24" end return -- modes.args_config end -- function modes.module_init(frame) function modes.init_options_for_modes(frame, options_for_modes, mode_name) local res = "" frame = frame or mw.getCurrentFrame() modes.frame = frame modes.options_for_modes = options_for_modes or modes.options_for_modes modes.mode_name = mode_name or modes.mode_name or "read" modes.mode_options = modes.options_from_mode(modes.mode_name, modes.options_for_modes) -- events.errors_list = {} -- Table to collect errors and warnings -- events.categories_list = {} -- init the collect of categories -- events.save_configs() -- Save global configuration before eventual changes. return res end -- function modes.init_options_for_modes(frame, options_for_modes, mode_name) function modes.get_arg_mode(mode_name, source_key, lang, args_source) local mode_key = "mode" local args_source = args_source or modes.args_source -- modes.wiki_lang = lang or args_source.wikilang or tostring(mw.language.getContentLanguage().code) or "en" -- try_lang = try_lang or mw.language.getContentLanguage:getCode() or "en" if type(args_source) == "table" -- and type(args_source[source_key]) == "string" then mode_name = mode_name or args_source[source_key] or "read" else modes.mode_name = mode_name or modes.mode_name or "read" end -- local mode_name = mode_name or args_source[source_key] or "read" -- modes.mode_name = mode_name or modes.mode_name or "read" return mode_name, source_key, try_lang end -- function modes.get_arg_mode(mode_name, source_key, lang, args_source) function modes.all_categories_list(t) -- all_categories_list_title local t = "\n* " .. (t or " <b>List all eventual categories of this wiki:</b>") for key, txt in pairs(translate.user_translations) do if viewer.is_in("cat_", key) or viewer.is_in("_cat", key) then txt = viewer.form9user(txt, "**", "**", "**", "**", "**", "**") t = t .. "<br>" .. viewer.ta(key, txt) end end return t end -- function modes.all_categories_list(t) function modes.all_errors_list(t) -- all_errors_list_title local t = "\n* " .. (t or " <b>List all detectable errors of this wiki:</b>") for key, txt in pairs(translate.user_translations) do if viewer.is_in("err_", key) or viewer.is_in("_err", key) then txt = viewer.form9user(txt, "**", "**", "**", "**", "**", "**") t = t .. "<br>" .. viewer.ta(key, txt) end end return t end -- function modes.all_errors_list(t) function modes.list_all_args_main(t, args_known) -- modes_list_all_args_main_title = List of all arguments for main local t = t or "\n* <b>list_all_args_main :</b> " if type(args_known) ~= "table" then args_known = modes.args_known end if type(args_known) ~= "table" then return (t .. "The known arguments table modes.args_known misses.") end t = t .. viewer.ta("args N", #args_known ) local descr, description = "", "" local args = mw.clone(args_known) local arglst = {} for key, elem in pairs(args) do elem.key = tostring(key) descr = key .. "_descr" -- key for description of an argument elem.description = translate.user_translations[descr] or "**missing translation**" elem.user_lang_key = translate.user_translations[elem.key] or "**missing key**" elem.user_lang_keyword = translate.user_translations[elem.keyword] or "**missing keyword**" -- elem.base_id = elem.base_id -- elem.base_base = elem.base_base -- elem.not_type = elem.not_type table.insert(arglst, elem) end -- insert in the arguments their own key table.sort(arglst, function (a, b) return (a.user_lang_key < b.user_lang_key) end ) -- alphabetic sort of translated arguments local gr_sys, gr_config, gr_need, gr_other, gr_authority = {}, {}, {}, {}, {} for i, elem in ipairs(arglst) do -- group arguments in some groups if elem.need == 1 or elem.need == 2 then table.insert(gr_need, elem) elseif elem.typ == "sys" then table.insert(gr_sys, elem) elseif elem.typ == "config" then table.insert(gr_config, elem) elseif elem.base_base then table.insert(gr_authority, elem) else table.insert(gr_other, elem) end end local needed = viewer.smallCapsStyle(viewer.form9user("modes_needed_to_verify")) local function list_group( group, needed ) needed = needed or "" local t = "" for key, elem in pairs(group or {}) do if elem.syn then t = t .. "<br>* <b>" .. tostring(elem.user_lang_key) .. "</b> => <b>" .. elem.user_lang_keyword .. "</b> : " .. needed .. " " .. tostring(elem.description) -- .. elem.lev_arg_txt else t = t .. "<br>* <b>" .. tostring(elem.user_lang_key) .. "</b> : " .. needed .. " " .. tostring(elem.description) end end return t end t = t .. "<br><br>* <b>" .. viewer.form9user("modes_list_needed_args") .. "</b> " .. list_group( gr_need, needed ) t = t .. "<br><br>* <b>" .. viewer.form9user("modes_list_all_other_args") .. "</b> " .. list_group( gr_other ) t = t .. "<br><br>* <b>" .. viewer.form9user("list_all_authorities") .. "</b> " .. list_group( gr_authority ) t = t .. "<br><br>* <b>" .. viewer.form9user("modes_list_all_config_arguments") .. "</b> " .. list_group( gr_config ) t = t .. "<br><br>* <b>" .. viewer.form9user("modes_list_all_system_arguments") .. "</b> " .. list_group( gr_sys ) return t end -- function modes.list_all_args_main(t, args_known) -- modes_list_all_args_main_title for main function modes.recursiveNormal( recursiveLevel_in, recursiveLimit_in, modes_recursiveLevel_err ) -- Normalize recursiveLevel and recursiveLimit -- recursiveLevel, recursiveLimit, recursiveLevel_err == modes.recursiveNormal(recursiveLevel, recursiveLimit) -- default modes.recursiveLimit local recursiveLevel, recursiveLimit = recursiveLevel_in, recursiveLimit_in -- local recursiveLevel_err = "" -- local modes_recursiveLevel_err = modes_recursiveLevel_err or "modes_recursiveLevel_err" -- default modes_recursiveLevel_err if type(modes_recursiveLevel_err) ~= "string" then modes_recursiveLevel_err = "modes_recursiveLevel_err" end if type(modes.recursiveLimit) ~= "number" then modes.recursiveLimit = 11111 end if modes.recursiveLimit < 1 then modes.recursiveLimit = 11111 end -- default recursiveLimit if type(recursiveLimit) ~= "number" then recursiveLimit = modes.recursiveLimit end -- If recursiveLimit is defined, it can be greater or lesser than modes.recursiveLimit recursiveLimit = math.floor(recursiveLimit) + 0.999999 if recursiveLimit < 1 then recursiveLimit = modes.recursiveLimit end -- default recursiveLevel if type(recursiveLevel) ~= "number" then recursiveLevel = 1 end recursiveLevel = math.floor( recursiveLevel ) + 0.999999 if recursiveLevel < 1 then recursiveLevel = 1 end -- if recursiveLevel > recursiveLimit then recursiveLevel_err = viewer.form9user( modes_recursiveLevel_err, recursiveLevel, recursiveLimit) recursiveLevel_err = viewer.errorColor( tostring(recursiveLevel_err) ) end return recursiveLevel, recursiveLimit, recursiveLevel_err end -- function modes.recursiveNormal( recursiveLevel_in, recursiveLimit_in, modes_recursiveLevel_err ) function modes.recursiveNormal_tests( t ) -- Test Normalize recursiveLevel and recursiveLimit local memo = events.save_configs() -- Save global configuration before eventual changes. -- recursiveLevel, recursiveLimit, recursiveLevel_err == modes.recursiveNormal(recursiveLevel, recursiveLimit) modes.recursiveLimitMemo = modes.recursiveLimit -- memorize before test value local t = t or "\n* modes.recursiveNormal_tests: " local function recursiveNormal_test1(recursiveLevel_in, recursiveLimit_in, modes_recursiveLevel_err) local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal( recursiveLevel_in, recursiveLimit_in, modes_recursiveLevel_err or "modes_recursiveLevel_err") -- modes.recursiveNormal( recursiveLevel_in or modes.recursiveLimit or 1, recursiveLimit_in or modes.recursiveLimit or 3 ) -- return "\n* " .. "recursiveLevel = " .. (recursiveLevel or "recursiveLevel") .. ", recursiveLimit = " .. (recursiveLimit or "recursiveLimit") return "\n* " .. ( recursiveLevel_err or ("recursiveLevel_err:" .. viewer.ta("recursiveLevel", recursiveLevel) .. viewer.ta("recursiveLimit", recursiveLimit) ) ) end t = t .. recursiveNormal_test1() t = t .. recursiveNormal_test1(-12, 5) t = t .. recursiveNormal_test1(0, 5) t = t .. recursiveNormal_test1(1, 5) t = t .. recursiveNormal_test1(2.718, 3.1416) t = t .. recursiveNormal_test1(3) t = t .. recursiveNormal_test1(5, 5) t = t .. recursiveNormal_test1(6, 5) t = t .. recursiveNormal_test1(11111, 5, "versioning_module_miss_i18n_txt_err") t = t .. recursiveNormal_test1(11112, 5, "versioning_module_miss_i18n_count_err") t = t .. recursiveNormal_test1(23456, 5, "modes_recursiveLevel_err") modes.recursiveLimit = modes.recursiveLimitMemo -- restaure before test value events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function modes.recursiveNormal_tests(recursiveLevel, recursiveLimit) function modes.spacesNamesPageTest(t) if type(t) ~= "string" then t = nil end local t = t or "\n* <b>spaces_page_names_test</b> :" local mwtitle = mw.title.getCurrentTitle() t = t .. viewer.ta("mwtitle", mwtitle) local nsText = mwtitle.nsText t = t .. viewer.ta("nsText", nsText) local baseText = mwtitle.baseText -- namespace for the page t = t .. viewer.ta("baseText", baseText) local url = tostring(mwtitle:canonicalUrl( )) t = t .. viewer.ta("url", url) -- t = t .. "\n* Module namespace : " local ns = mw.site.namespaces if ns and ns[828] then t = t .. viewer.ta("id828", ns[828].id) t = t .. viewer.ta("canonicalName828", ns[828].canonicalName) t = t .. viewer.ta("name828", ns[828].name) t = t .. viewer.ta("displayName828", ns[828].displayName) end t = t .. "\n* All namespaces (from 0 to 2000) : " local ns = "" for ins = 0, 2000 do -- if mw.site.contentNamespaces[ins] then if mw.site.namespaces[ins] then ns = mw.site.namespaces[ins].canonicalName t = t .. viewer.ta(ns, ins) end end return t end -- function modes.spacesNamesPageTest() function modes.warning_short() -- local warning_versions = modes.warning_short() -- in Module:Author3 -- versioning.deprecatedFunction("modes.interact_args_final", "p.interact_args_final") -- versioning.report_main_short = main_versions.versionName .. " " .. main_versions.versionNumber local warning_versions = versioning.report_main_short return warning_versions end -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:testsCases implements recursive mediawiki tests cases and reports them for Lua coders. -- New testsCases library part, to support tests cases -- count = number of tests; provide( n ) returns three values: n, and expected output; run( n ) returns one string. -- Starter is testsCases.report for recursive testsCases.runGroups -- see Extension:Scribunto/Lua reference manual#Test_cases : class nameTest extends Scribunto_LuaEngineTestBase -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- testsCases = {} -- already declared by Scribunto, else in _G space. -- Translations for testsCases library testsCases.i18n = {} testsCases.i18n.en = { testsCases_subDiffs_abnormal_error = "Internal error: abnormal subDiffs process", testsCases_subDiffs_boolean_error = "subDiffs boolean error", testsCases_subDiffs_function_error = "subDiffs function error", testsCases_subDiffs_nil_error = "subDiffs nil error", testsCases_subDiffs_number_error = "subDiffs number error", testsCases_subDiffs_string_error = "subDiffs string error", testsCases_subDiffs_table_error = "subDiffs table error", testsCases_subDiffs_tables_error = "subDiffs tables error", testsCases_subDiffs_type_error = "subDiffs type error", testsCases_subDiffs_types_error = "subDiffs types error", testsCases_recursiveLevel_error = "subDiffs recursion level exceeded error", testsCases_search_Diffs_tests_title = "testsCases.search_Diffs_tests() Search detailed differences in testsCases", testsCases_search_Diffs_tests_headers = "Expected value; Actual value; Test indentifier; Results + Errors : expected-actual-details", testsCases_tests_Cases_report_title = "testsCases.tests_Cases_report() Mediawiki recursive testsCases", testsCases_group_Diffs_tests_title = "testsCases.group_Diffs_tests() Tests: Report detailed differences, where, recursively", testsCases_group_Diffs_test_headers = "Expected value; Actual value; Test indentifier; Results + Errors : expected-actual-details", } -- testsCases.i18n.en testsCases.i18n.es = { testsCases_subDiffs_abnormal_error = "Error interno: subDiffs proceso anormal", testsCases_subDiffs_boolean_error = "subDiffs booleano error", testsCases_subDiffs_function_error = "subDiffs función error", testsCases_subDiffs_nil_error = "subDiffs nulo error", testsCases_subDiffs_number_error = "subDiffs numero error", testsCases_subDiffs_string_error = "subDiffs texto error", testsCases_subDiffs_table_error = "subDiffs tabla error", testsCases_subDiffs_tables_error = "subDiffs tablas error", testsCases_subDiffs_type_error = "subDiffs typo error", testsCases_subDiffs_types_error = "subDiffs typos error", testsCases_recursiveLevel_error = "subDiffs nivel de recursividad superó error", testsCases_search_Diffs_tests_title = "testsCases.search_Diffs_tests() Buscar diferencias detalladas en testsCases", testsCases_search_Diffs_tests_headers = "Valor prevista; Valor activa; Identificador del prueba; Resultados + Errores : prevista-activa-detalles", testsCases_tests_Cases_report_title = "testsCases.tests_Cases_report() Mediawiki testsCases recursivos", testsCases_group_Diffs_tests_title = "testsCases.group_Diffs_tests() Pruebas: Reporte detallado de las diferencias, ¿dónde? recursivamente", testsCases_group_Diffs_test_headers = "Valor prevista; Valor activa; Identificador del prueba; Resultados + Errores : prevista-activa-detalles", } -- testsCases.i18n.es testsCases.i18n.fr = { testsCases_subDiffs_abnormal_error = "Erreur interne : processus subDiffs anormal", testsCases_subDiffs_boolean_error = "subDiffs erreur de booléen", testsCases_subDiffs_function_error = "subDiffs erreur de fonction", testsCases_subDiffs_nil_error = "subDiffs erreur de nul", testsCases_subDiffs_number_error = "subDiffs erreur de nombre", testsCases_subDiffs_string_error = "subDiffs erreur de texte", testsCases_subDiffs_table_error = "subDiffs erreur de table", testsCases_subDiffs_tables_error = "subDiffs erreur de tables", testsCases_subDiffs_type_error = "subDiffs erreur de type", testsCases_subDiffs_types_error = "subDiffs erreur de types", testsCases_recursiveLevel_error = "subDiffs erreur de niveau de récursivité dépassé", testsCases_search_Diffs_tests_title = "testsCases.search_Diffs_tests() Chercher les différences détaillées dans les testsCases", testsCases_search_Diffs_tests_headers = "Valeur attendue; Valeur active; Identifiant du test; Résultats + Erreurs : attendue-active-détails", testsCases_tests_Cases_report_title = "testsCases.tests_Cases_report() Mediawiki testsCases recursifs", testsCases_group_Diffs_tests_title = "testsCases.group_Diffs_tests() Tests: Rapport detaillé des différences, où, recursivement", testsCases_group_Diffs_test_headers = "Valeur attendue; Valeur active; Identifiant du test; Résultats + Erreurs : attendue-active-détails", } -- testsCases.i18n.fr -- testsCases = {} -- already declared by Scribunto, else in _G space. testsCases.recursiveLimit = 11 testsCases.OK = "OK" testsCases.ERR = "ERR" testsCases.okStrings = "OK" -- local args = { ... } -- optional arguments -- Starter for testsCases.runGroups for testsCases.report -- protected static $moduleName = 'ClassNameTest'; -- See Extension:Scribunto/Lua_reference_manual#Test_cases function testsCases.debugGetGroup(group, groupname) -- DEBUG the bug T20160615 : Lua functions calls lost multilevel table arguments group = testsCases.groupMemoDebug -- Try to transmit the group across testsCases.groupMemoDebug if groupname and not group then -- OK t = t .. "DEBUG_group: " t = t .. viewer.ta("begin group", group) t = t .. viewer.ta("testsCases.groupMemoDebug", testsCases.groupMemoDebug) t = t .. viewer.ta("groupname", groupname) -- local subgroup = { errorsKey = 2, modulename = "mathroman", ..., groupname = "mathroman.testscases.TestsGroups", } -- Example of link to subgroup --[ [ Normal method: found the missing group from groupname local tab = mw.text.split(groupname, '.', true) -- from the subgroup in string form for i, part in ipairs(tab) do -- Build the subgroup table from the groupname string t = t .. viewer.ta("part", part) if i == 1 then -- The start point is always a recorded module or library module = package.loaded[ part ] if type(module) == "table" then group2use = module end else -- add a subgroup to the previous subgroup if type(group2use) == "table" then subgroup = group2use[ part ] group2use = subgroup end end end group = group2use t = t .. viewer.ta("end group", group) end return group, t end -- function testsCases.debugGetGroup(group, groupname) function testsCases.searchDiffs( subcase, name_key, expect, actual, recursiveLevelX ) -- Report all differences between expect and actual variables of any types. Recursivity limited to recursiveLimit local expect = subcase.expect local actual = subcase.actual local opt = mw.clone(subcase.Options) -- local recursiveLevel = recursiveLevel or 1 subcase.name = subcase.name or "group_Diffs" -- subcase.name_key = name_key or subcase.name_key or "searchDiffs" subcase.diffdetails = subcase.diffdetails or "" -- local name_key = subcase.name_key local diffs = {} subcase.all_diffs = subcase.all_diffs or "" if (type(actual) == "table") and (type(expect) == "table") then -- Compare 2 tables of elements -- if recursiveLevel <= (events.recursiveLimit or 3) then if opt.recursiveLevel <= opt.recursiveLimit then opt.recursiveLevel = opt.recursiveLevel + 1 for key, val in pairs(actual) do if not expect[key] then -- Detect actual values in args{} missing in expect{}, which is one difference. local txt_diffs = translate.formTestCase("testsCases_search_Diffs_tests_title", key, val) -- Report differences, for simple elements end end subcase.diffdetails = subcase.diffdetails .. "_r" .. opt.recursiveLevel for key, val in pairs(expect) do -- Compare all table elements local subcase = {} subcase.Options = opt if opt.recursiveLevel == 1 then subcase.name_key = subcase.name .. "_" .. tostring(key) else subcase.name_key = "searchDiffs_" .. tostring(key) end -- subcase.name_key = name_key or "searchDiffs" subcase.diffdetails = "" subcase.expect = expect[key] subcase.actual = actual[key] subcase.expect_t = viewer.value(subcase.expect) subcase.actual_t = viewer.value(subcase.actual) subcase.name = subcase.name or "group_Diffs" subcase.name_key = subcase.name .. "_" .. tostring(key) subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_tables_error" -- Report all differences between expect and actual variables of any types. Recursivity limited to recursiveLimit local sub_diffs = testsCases.searchDiffs( subcase, subcase.name_key, subcase.expect, subcase.actual, recursiveLevelX ) if (subcase.diffdetails ~= nil) and (subcase.diffdetails ~= "") then table.insert( sub_diffs, translate.formTestCase(subcase.result or "testsCases_subDiffs_tables_error", viewer.value(subcase.expect), viewer.value(subcase.actual) ) ) end for key, diff in pairs(sub_diffs) do -- Add all sub-diffs to diffs at this recursive level of details. table.insert( diffs, diff ) end end end end -- Report simple differences, for simple elements subcase.name_key = subcase.name -- .. "_" .. tostring(key) subcase.expect_t = viewer.value(subcase.expect) subcase.actual_t = viewer.value(subcase.actual) subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_boolean_error" diffs[(#diffs + 1)] = viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) --[ [ if subcase.expect_t ~= subcase.actual_t then if (actual ~= expect) and (type(expect) == "table") and (type(actual) == "table") then subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_tables_error" -- table.insert( diffs, (#diffs + 1), viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) ) diffs[(#diffs + 1)] = viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) elseif (actual ~= expect) and (actual == nil) then subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_nil_error" -- table.insert( diffs, (#diffs + 1), viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) ) diffs[(#diffs + 1)] = viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) elseif (actual ~= expect) and (actual == true) then subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_boolean_error" -- table.insert( diffs, (#diffs + 1), viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) ) diffs[(#diffs + 1)] = viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) elseif (actual ~= expect) and (type(actual) == "number") then subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_number_error" -- table.insert( diffs, (#diffs + 1), viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) ) diffs[(#diffs + 1)] = viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) elseif (actual ~= expect) and (type(actual) == "table") then subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_table_error" -- table.insert( diffs, (#diffs + 1), viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) ) diffs[(#diffs + 1)] = viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) elseif (actual ~= expect) and (type(actual) == "function") then subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_function_error" -- table.insert( diffs, (#diffs + 1), viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) ) diffs[(#diffs + 1)] = viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) else subcase.result = ( subcase.name_key .. subcase.diffdetails ) or "testsCases_subDiffs_other_error" -- table.insert( diffs, (#diffs + 1), viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) ) diffs[(#diffs + 1)] = viewer.form9user(subcase.result, subcase.expect_t, subcase.actual_t ) end end --] ] return diffs end -- function testsCases.searchDiffs( subcase, name_key, expect, actual, recursiveLevel ) function testsCases.group_Diffs_tests( t, casesgroup, tabOptions ) -- Tests a group of tests cases. local t = t or "\n* <b>testsCases.group_Diffs_tests()</b>" -- intern report to display for humans if type(casesgroup) ~= "table" then casesgroup = nil end if type(tabOptions) ~= "table" then tabOptions = nil end local default_group_test = { -- events.testGroup { expect = "abc", actual = "abc", name = "search_Diffs_tests", }, -- expect, actual, name, { expect = "ABC", actual = "abc", name = "search_Diffs_tests", }, { expect = 123, actual = 456, name = "search_Diffs_tests", }, { expect = 33, actual = nil, name = "search_Diffs_tests", }, { expect = 33, actual = true, name = "search_Diffs_tests", }, { expect = {"abc"}, actual = "ABC", name = "search_Diffs_tests", }, } local default_tabOptions = { headers = "testsCases_group_Diffs_test_headers", group = casesgroup or default_group_test, concat = "; <br/>", rowGroup = {}, recursiveLevel = 1, recursiveLimit = 3, } tabOptions = tabOptions or default_tabOptions tabOptions.testGroup = tabOptions.testGroup or default_group_test tabOptions.headers = tabOptions.headers or "testsCases_group_Diffs_test_headers" tabOptions.concat = tabOptions.concat or "; <br/>" tabOptions.rowGroup = {} tabOptions.run = tabOptions.run or testsCases.group_Diffs_tests if type(tabOptions.testGroup) == "table" then for key, subcase in pairs(tabOptions.testGroup) do -- local diffs = {} subcase.name = subcase.name or "group_Diffs" subcase.name_key = subcase.name .. "_" .. tostring(key) -- Report all differences between expect and actual variables of any types. Recursivity limited to recursiveLimit local sub_diffs = testsCases.searchDiffs( subcase, subcase.name_key, subcase.expect, subcase.actual, recursiveLevel ) for key, diff in pairs(sub_diffs) do -- Add all sub-diffs to diffs at this recursive level of details. if (diff ~= nil) and (diff ~= "") then -- diff = ( subcase.name_key .. diff ) -- or "testsCases_subDiffs_tables_error" subcase.result = subcase.result .. "\n* " .. viewer.errorColor(diff) end end table.insert( tabOptions.rowGroup, { viewer.value(subcase.expect), viewer.value(subcase.actual), tostring( subcase.name_key or "name_key"), tostring( subcase.result or "-"), } ) end else t = t .. "error : multiple_values_tests has no table. " end t = t .. viewer.tableView(tabOptions) -- Form a table with lines and columns. return t, diffs end -- function testsCases.group_Diffs_tests( t, casesgroup, tabOptions ) function testsCases.search_Diffs_tests( t ) -- Tests of report differences, which kind, where, recursively. local t = t or "\n* Test <b>testsCases.search_Diffs_tests():synthesis...</b>" -- intern report to display for humans local res_g, res_t, strResults, value_1 = "", "", "", "" local recursiveLevel = 1 local tabOptions = { -- Initialize global configurations and save them before eventual changes. headers = "typ;key;testcase idargs;result", -- headers of columns to display in a tableview for users and coders. kind = "projects", -- mediawiki or projects. How to run and to display testscases results. -- typ = "cat", -- Type of events to selector for list or for tests. catview = ":", -- "" to really categorize. ":" to display links to categories. user_lang = translate.user_lang, -- "en", -- User language to use for tests and/or to display tests. wiki_lang = translate.wiki_lang, -- "fr", -- Wiki language to use for tests and/or to display tests. recursiveLevel = 1, recursiveLimit = 3, -- tableViewStyle = "wikitable alternative center", -- example of style for a viewer.tableView() with lines and columns. -- testsFunction = function_name, -- Dedicated function for all tests in the eventsGroup of tests. } local function search_Diffs_tests1(t, i, expect, actual, name, expectKey, errorsKey) -- t, i = search_Diffs_tests1(t, i, {"abc"}, "ABC", "search_Diffs_tests") -- t, i = search_Diffs_tests1(t, i, {123, "err"}, {456, "err"}, "search_Diffs_tests-string", 2) subcase = {} -- testcase.Options = opt subcase.Options = tabOptions subcase.recursiveLevel = 1 subcase.recursiveLimit = 3 subcase.actual = actual subcase.expect = expect subcase.expect_t = viewer.value(expect) subcase.actual_t = viewer.value(actual) subcase.name = name or subcase.name or "search_Diffs_tests" if subcase.name == "search_Diffs_tests-recursiveLimit-5" then subcase.recursiveLimit = 5 -- default subcase.recursiveLimit = 3 end subcase.expectKey = expectKey or subcase.expectKey or 1 subcase.errorsKey = errorsKey or subcase.errorsKey or 2 subcase.name_key = subcase.name .. "_" .. i subcase.n_diffs = 0 subcase.all_diffs = "" local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal( subcase.recursiveLevel, subcase.recursiveLimit) -- subcase.actual_t = luaTable.roughView(actual) -- subcase.expect_t = luaTable.roughView(expect) local sub_diffs = testsCases.searchDiffs(subcase) -- Report simple differences, for simple elements subcase.n_diffs = #sub_diffs subcase.all_diffs = "" for i, diff in ipairs(sub_diffs) do -- List all diffs if (type(diff) == "string") then subcase.all_diffs = subcase.all_diffs .. "\n* " .. viewer.errorColor(diff) end end return subcase, t, (i + 1) end -- function search_Diffs_tests1(t, i, args, expected, name) local group_test = { -- events.testGroup { expect = "abc", actual = "abc", name = "search_Diffs_tests", }, -- expect, actual, name, { expect = "ABC", actual = "abc", name = "search_Diffs_tests", }, { expect = 123, actual = 123, name = "search_Diffs_tests", }, { expect = 123, actual = "123", name = "search_Diffs_tests", }, { expect = 321, actual = 123, name = "search_Diffs_tests", }, { expect = true, actual = true, name = "search_Diffs_tests", }, { expect = false, actual = true, name = "search_Diffs_tests", }, { expect = true, actual = false, name = "search_Diffs_tests", }, { expect = false, actual = false, name = "search_Diffs_tests", }, { expect = nil, actual = "nil", name = "search_Diffs_tests", }, { expect = nil, actual = nil, name = "search_Diffs_tests", }, { expect = 33, actual = nil, name = "search_Diffs_tests", }, { expect = 33, actual = true, name = "search_Diffs_tests", }, { expect = function() end, actual = "func", name = "search_Diffs_tests", }, { expect = "func", actual = function() end, name = "search_Diffs_tests", }, { expect = function() end, actual = function() end, name = "search_Diffs_tests", }, { expect = tostring, actual = tostring, name = "search_Diffs_tests-tostring()", }, { expect = "ABC", actual = {"abc"}, name = "search_Diffs_tests", }, { expect = {"abc"}, actual = "ABC", name = "search_Diffs_tests", }, { expect = {"abc", "def"}, actual = {"abc", "def"}, name = "search_Diffs_tests", }, { expect = {"ABC", "err"}, actual = {"abc", "err"}, name = "search_Diffs_tests", }, { expect = {123, "err"}, actual = {456, "err"}, name = "search_Diffs_tests-string", 2, }, { expect = {"ABC", "DEF"}, actual = {"abc", "def"}, name = "search_Diffs_tests", }, { expect = {123, 456}, actual = {"abc", "def"}, name = "search_Diffs_tests", }, { expect = { u = {"u1", "u2"}, x = {"x1", "x2"} }, actual = { u = {"u1", "u2"}, x = {"x1", "x2"} }, name = "search_Diffs_tests-2-levels-ident-tables", }, { expect = { u = {"u1", "u2"}, x = {"H1", "x2"} }, actual = { u = {"u1", "u2"}, x = {"x1", "x2"} }, name = "search_Diffs_tests-2-levels-diffs-tables", 2, }, { expect = { a1 = { a2 = { a3 = { a4 = { a5 = { a6 = { a7 = "A7" } } } } } } }, actual = { a1 = { a2 = { a3 = { XX = { a5 = { a6 = { a7 = "A7" } } } } } } }, name = "search_Diffs_tests-recursiveLimit-3", }, { expect = { a1 = { a2 = { a3 = { a4 = { a5 = { a6 = { a7 = "A7" } } } } } } }, actual = { a1 = { a2 = { a3 = { XX = { a5 = { a6 = { a7 = "A7" } } } } } } }, name = "search_Diffs_tests-recursiveLimit-5", }, } local tabOptions = {} tabOptions.headers = "testsCases_search_Diffs_tests_headers" tabOptions.testGroup = group_test tabOptions.concat = "; <br/>" tabOptions.rowGroup = {} if type(group_test) == "table" then for i, test in pairs(group_test) do local subcase = search_Diffs_tests1("", i, test.expect, test.actual, test.name, expectKey, errorsKey) table.insert( tabOptions.rowGroup, { tostring( subcase.expect_t), tostring( subcase.actual_t), tostring( subcase.name_key .. '<br>' .. viewer.ta("n_diffs", subcase.n_diffs) ), tostring( subcase.all_diffs), } ) end else t = t .. "error : multiple_values_tests has no table. " end t = t .. viewer.tableView(tabOptions) -- Form a table with lines and columns. return t end -- function testsCases.search_Diffs_tests() function testsCases.tests_Cases_report() -- Run a group of tests and returns one string. local res_g, res_t = testsCases.report( mathroman.testsGroups, "mathroman.testsGroups", 1 ) -- Run N groups of tests and returns one string. return res_t end -- function testsCases.tests_Cases_report() function testsCases.report( group, groupname, recursiveLevel ) -- , recursiveLevel ) -- Run a group of tests and returns one string. local group = group testsCases.groupMemoDebug = group if type(modes.recursiveLimit) ~= "number" then modes.recursiveLimit = 11 end -- debug 11111 local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, testsCases.recursiveLimit or 11 ) testsCases.recursiveLimit = recursiveLimit local t = "\n* testsCases.report()..." -- intern report to display for coders local res = "" events.strKeyOnly = true local ttcs = testsCases.ModuleOrName("testsCases") -- Search the name of a module or reverse. local cent = testsCases.ModuleOrName(versioning) -- Search the name of a module or reverse. local tls = testsCases.ModuleOrName(tools) -- Search the name of a module or reverse. -- local grp = testsCases.ModuleOrName(groupname) -- Search the name of a module or reverse. t = t .. viewer.ta( "\n* Group:ModuleOrName " .. groupname, type(groupname) ) .. viewer.ta( "testsCases", ttcs ) t = t .. viewer.ta( cent, versioning ) .. viewer.ta( tls, tools ) .. "<br>" -- t = t .. "\n* luaTable.roughView <b>mathroman.testsGroups</b> \n" .. luaTable.roughView(mathroman.testsGroups) --, { recursiveLimit = 11111, max_n = 11111, } ) t = t .. viewer.ta("report events.strKeyOnly", events.strKeyOnly) local st, vr, fn, tb = luaTable.formSubCounts(group, "group") -- count of internal .i18n t = t .. "\n* " .. st testsCases.trackTests_t = "" -- init debug track testsCases.countFullCompute( group, groupname, recursiveLevel ) -- Compute testsCases.countFull testsCases.trackTests_t = "" -- init debug track local res_g, res_t = testsCases.runTestsCases( group, groupname, 1 ) -- Run only all tests cases in one group. -- local errors_or_diffs = testcase.errors or string.gsub(testcase.all_diffs, ";", "; ") t = t .. viewer.form9user("\n* testsCases.report count/groups = <b>%1/%2</b>", testsCases.countFull, group.countGroups) t = t .. viewer.form9user("\n* report subkey + n = <b>%1 + %2</b>, recur=%3, bug group type=%4, ", group.subkey, group.subkey_n, recursiveLevel, type(group)) --[[ mathroman.testsGroups = { -- Autotest cases to validate the mathroman library at mediawiki level. -- Each test_case defines a name, a function, an input, an output. Else a sub-group of testsCases. { name = "mathroman", func = testsCases.runGroups, group = mathroman.Tests_cases, modulename = "mathroman", funcname = "runGroups", groupname = "mathroman.Tests_cases", }, -- --]] t = t .. res_t .. viewer.ta("res_g", res_g) events.strKeyOnly = false t = t .. viewer.ta("end events.strKeyOnly", events.strKeyOnly) -- t = t .. viewer.ta("\n* after rg type(group)", type(group) ) return res, t -- Extension:Scribunto/Lua reference manual : run( n ): Function that runs test n and returns one string. end -- function testsCases.report( group, groupname, recursiveLevel ) function testsCases.run_testcase( n, testcase ) -- Function that runs test n and returns one string. local memo = events.save_configs() -- Save global configuration before eventual changes. -- Record all input arguments and output results for any function with any number of arguments and results. -- For library.run( n, testcase ) -- see Extension:Scribunto/Lua reference manual: -- For testsCases.runOneTest( testcase, n, module ) -- see Extension:Scribunto/Lua reference manual: -- local tabOptions = { -- Initialize global configurations and save them before eventual changes. headers = "typ;key;testcase idargs;result", -- headers of columns to display in a tableview for users and coders. kind = "projects", -- mediawiki or projects. How to run and to display testscases results. -- typ = "cat", -- Type of events to selector for list or for tests. catview = ":", -- "" to really categorize. ":" to display links to categories. user_lang = translate.user_lang, -- "en", -- User language to use for tests and/or to display tests. wiki_lang = translate.wiki_lang, -- "fr", -- Wiki language to use for tests and/or to display tests. -- tableViewStyle = "wikitable alternative center", -- example of style for a viewer.tableView() with lines and columns. -- testsFunction = function_name, -- Dedicated function for all tests in the eventsGroup of tests. } testcase.Options = tabOptions events.init_configs(testcase, tabOptions, {}) -- Initialize global configurations and save them before eventual changes. -- This events group is init, used and closed from Mediawiki tests or from the main module in pages. testcase.events.startPoint = testsCases.run_testcase -- Start testcase.events for Gerrit tests testcase.diffs = {} testcase.all_diffs = "" testcase.expectKey = testcase.expectKey or 1 testcase.errorsKey = testcase.errorsKey or 2 -- testcase.runResults = { testcase.func( luaTable.toList( testcase.args ) ) } -- args table to list to a function which return a list received in a table. -- idargs .actual local x, evt = events.add_err(testcase.name or "idargs", luaTable.toList(testcase.runResults) ) -- error event -- testcase.runErrors = testcase.runResults[testcase.errorsKey] testcase.runResults[testcase.errorsKey] = testcase.runErrors -- function testsCases.searchDiffs( subcase, name_key, expect, actual, recursiveLevel ) local sub_diffs = testsCases.searchDiffs( testcase ) -- Report differences, recursiveLevel -- DEBUG 'name_key' (a nil value). testcase.runArgsRoughView = luaTable.roughView(testcase.args) testcase.runResultsRoughView = luaTable.roughView(testcase.runResults) testcase.runDetails = viewer.form9user("runDetails = <b>%1</b>(%2) = <b>%3</b>, \n** sub_diffs = <b>%4</b>, \n** testcase.runErrors = <b>%5</b>", testcase.name, testcase.runArgsRoughView, testcase.runResultsRoughView, sub_diffs.all_diffs, testcase.runErrors ) local nil_or_0 = ( (sub_diffs.all_diffs) and string.find(sub_diffs.all_diffs, "nil") ) or 0 testsCases.trackTests( testcase, "run_testcase nil?/len", nil_or_0, string.len(sub_diffs.all_diffs or "-" ) ) -- testcase.trackTests_t -- if testcase.events.startPoint == testsCases.run_testcase then testcase.events.restore_configs(testcase.memo) end -- Close testcase.events for Gerrit tests -- if testcase.memo and (testcase.events.startPoint == testsCases.run_testcase) then testcase.events.restore_configs(testcase.memo) end -- Close testcase.events for Gerrit tests -- testcase.events.restore_configs(testcase.memo) events.restore_configs(memo) -- Restore global configurations after eventual changes. return testcase.runErrors, value -- Function that runs test n and returns one string. end -- function testsCases.run_testcase( n, testcase ) function testsCases.runOneTest( testcase, n, module ) -- see Extension:Scribunto/Lua reference manual: -- run( n ): Function that runs test n and returns one string. (to compare with okStrings) testcase.runOneTest_t = "" local tabOptions = { -- Initialize global configurations and save them before eventual changes. headers = "typ;key;testcase idargs;result", -- headers of columns to display in a tableview for users and coders. kind = "projects", -- mediawiki or projects. How to run and to display testscases results. -- typ = "cat", -- Type of events to selector for list or for tests. catview = ":", -- "" to really categorize. ":" to display links to categories. user_lang = translate.user_lang, -- "en", -- User language to use for tests and/or to display tests. wiki_lang = translate.wiki_lang, -- "fr", -- Wiki language to use for tests and/or to display tests. -- tableViewStyle = "wikitable alternative center", -- example of style for a viewer.tableView() with lines and columns. -- testsFunction = function_name, -- Dedicated function for all tests in the eventsGroup of tests. } -- This events group is init, used and closed from Mediawiki tests or from the main module in pages. if not testcase.events then testcase.memo, testcase.events = events.init_configs(testcase, tabOptions, {}) end -- Initialize global configurations and save them before eventual changes. testcase.events.startPoint = testsCases.runOneTest -- For Modules tests testcase.diffs = {} testcase.all_diffs = "" testcase.expectKey = testcase.expectKey or 1 testcase.errorsKey = testcase.errorsKey or 2 local number_of_one_test, name_of_the_test, ok_expected_output = module.provide(testsCases.countRun, testcase.name, testsCases.OK) testsCases.trackTests( testcase, "provide out", name_of_the_test, ok_expected_output) -- testcase.runOneTest_t local errors, value = testsCases.run_testcase( n, testcase ) -- Function that runs test n and returns one string. -- local sub_diffs, recursiveLevel_err = testsCases.searchDiffs( testcase, 1 ) -- Report differences, recursiveLevel local sub_diffs, recursiveLevel_err = testsCases.searchDiffs( testcase, 1 ) -- Report differences, recursiveLevel testcase.n_diffs = sub_diffs.n_diffs -- testcase.n_diffs + -- See example in testcase: mathroman.roman2int, args = { "MMMMMYJXC" }, expect = { 5089, "mathroman_J_before_end_err;mathroman_char_increase_err" } }, -- Select errors from diffs, without expected errors coming from testcase.expect[testcase.errorsKey] testcase.errors = testcase.all_diffs or "" testsCases.trackTests( testcase, "runOneTest nil?", string.find(testcase.all_diffs, "nil") or 0, string.len(testcase.all_diffs or "-" ) ) -- testcase.trackTests_t if testcase.events.startPoint == testsCases.runOneTest then testcase.events = testcase.events.restore_configs(testcase.memo) end -- Close testcase.events for Modules tests return testcase.all_diffs, testcase.errors end -- function testsCases.runOneTest( testcase, n, module ) function testsCases.trackTests( testcase, where, x1, x2, x3, x4, x5, x6, x7, x8, x9 ) if not testcase then return end local t = "" testcase = testcase or testsCases.subgroup_memo t = t .. viewer.form9user(". %1 ", where) if x1 then t = t .. viewer.tam("1", x1 ) end if x2 then t = t .. viewer.tam("2", x2 ) end if x3 then t = t .. viewer.tam("3", x3 ) end if x4 then t = t .. viewer.tam("4", x4 ) end if x5 then t = t .. viewer.tam("5", x5 ) end if x6 then t = t .. viewer.tam("6", x6 ) end if x7 then t = t .. viewer.tam("7", x7 ) end if x8 then t = t .. viewer.tam("8", x8 ) end if x9 then t = t .. viewer.tam("9", x9 ) end testcase.trackTests_t = (testcase.trackTests_t or ".") .. t return t end function testsCases.countFullCompute( group, groupname, recursiveLevel ) -- Compute testsCases.countFull local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, testsCases.recursiveLimit or 111 ) testsCases.recursiveLimit = recursiveLimit if recursiveLevel == 1 then testsCases.countRun = 0 end if type(group) == "table" then -- Recursive run groups of tests cases. for k, testcase in ipairs(group) do -- Run only all tests cases in one group. if (type(testcase) == "table") and (type(testcase.args) == "table") and (type(testcase.expect) == "table") then -- Run tests cases with args and expect tables. local module = nil -- provide module = package.loaded[ tostring(testcase.modulename) ] -- Each testcase can change of module if (type(module) == "table") then -- If the module to test is in package.loaded testsCases.countRun = (testsCases.countRun or 0) + 1 end -- if module else -- if testcase and testcase.args and testcase.expect local subgroup = testcase.group if (type(subgroup) == "table") then -- Run all tests cases in one subgroup. if recursiveLevel < recursiveLimit then local res_g, res_t = testsCases.countFullCompute( subgroup, subgroup.groupname, recursiveLevel + 1 ) -- Run only all tests cases in one group. end end end end -- for k, testcase in ipairs(group) do end -- if type(group) == "table" then -- Recursive run groups of tests cases. testsCases.countFull = testsCases.countRun if recursiveLevel == 1 then testsCases.countRun = 0 end end -- function testsCases.countFullCompute( group, groupname, recursiveLevel ) function testsCases.runTestsCases( group, groupname, recursiveLevel ) -- Run only all tests cases in one group. -- Extension:Scribunto/Lua reference manual : run( n ): Function that runs test n and returns one string. -- events.strKeyOnly = true -- error no tests local memo = events.save_configs() -- Save global configuration before eventual changes. local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, testsCases.recursiveLimit or 11 ) testsCases.recursiveLimit = recursiveLimit local t = "" -- intern report to display for humans local res, res_g, tt, tt_g, module, diffs, sub_where = "", "", "", "", "", "", "", "" -- t = t .. viewer.ta( "\n* Group:runTestsCases start", type(group) ) .. viewer.ta( "recursiveLevel", recursiveLevel ) .. viewer.ta( "groupname", groupname ) if type(group) ~= "table" then group, tt = testsCases.debugGetGroup(group, groupname) end if type(group) ~= "table" then return res, t end if type(groupname) ~= "string" then return res, t end group.countGroups = #group group.countCases = 0 group.all_diffs = "" --[[ mathroman.testsGroups = { -- Autotest cases to validate the mathroman library at mediawiki level. -- Each test_case defines a name, a function, an input, an output. Else it defines a sub-group of testsCases. { name = "mathroman", func = testsCases.runGroups, group = mathroman.Tests_cases, modulename = "mathroman", funcname = "runGroups", groupname = "mathroman.Tests_cases", }, -- { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "MCXI" }, expect = { 1111 } }, --]] -- t = t .. viewer.ta( "\n* Group:runTestsCases type", tostring(group) ) .. viewer.ta( "group.countGroups", tostring(group.countGroups) ) -- #group -- t = t .. viewer.ta( "group.modulename", group.modulename ) .. viewer.ta( "group.funcname", group.funcname ) .. viewer.ta( "preview countRun", testsCases.countRun ) -- local groupOfTestsCases = (type(group) == "table") -- and (not group.args) and (not group.expect) if recursiveLevel == 1 then testsCases.runCount = 0 end if type(group) == "table" then -- Recursive run groups of tests cases. t = t .. viewer.ta( "group.args", group.args ) .. viewer.ta( "group.expect", group.expect ) for k, testcase in ipairs(group) do -- Run only all tests cases in one group. local testcase = mw.clone(testcase) -- debug ? -- The group (or the root of tests) contain some testsCases which could point to subgroup. group.countCases = k testcase.runOneTest_t = "" -- init main result track testcase.name = (testcase.name or group.name or "name") .. "_" .. group.countCases testcase.all_diffs = "" testsCases.trackTests_t = "" if (type(testcase) == "table") and (type(testcase.args) == "table") and (type(testcase.expect) == "table") then -- Run tests cases with args and expect tables. local memo = events.save_configs() -- Save global configuration before eventual changes. local module = nil -- provide testcase.name = group.name .. "." .. testcase.funcname .. "_" .. k group.countGroups = (group.countGroups or 0) + 0 testcase.all_diffs = "" local module = nil -- provide module = package.loaded[ tostring(testcase.modulename) ] -- Each testcase can change of module local fntn = testcase.func -- provide if (type(module) == "table") and (type(fntn) == "function") then -- If the module to test is in package.loaded testsCases.countRun = (testsCases.countRun or 0) + 1 testcase.all_diffs, testcase.errors = testsCases.runOneTest( testcase, testsCases.countRun, module ) -- rrt testcase.all_diffs = viewer.simpleList(testcase.all_diffs, ";") -- local errors_or_diffs = testcase.errors or testcase.all_diffs -- t = t .. "\n* " .. viewer.form9user("tc/gr/count = <b>%1/%2, %3/%4</b>, <b>%5</b>(%6) = <b>%7</b>, diffs/errors = <b>%8</b>", t = t .. "\n* " .. viewer.form9user("nTest/nGroup = <b>%1/%2</b>, count/groups = <b>%3/%4</b> ", group.countCases, group.countGroups, testsCases.countRun, testsCases.countFull) t = t .. "\n* " .. viewer.form9user("testcase.errors = <b>%1</b>, ", testcase.errors) t = t .. testcase.runDetails t = t .. testsCases.trackTests( testcase, "runTestsCases testcase nil?"..k, string.find(testcase.all_diffs, "nil") or 0, string.len(testcase.all_diffs or "-" ) ) -- testsCases.trackTests_t end -- if module events.restore_configs(memo) -- Restore global configurations after eventual changes. else -- if testcase and testcase.args and testcase.expect local subgroup = testcase.group if (type(subgroup) == "table") then -- Run all tests cases in one subgroup. --[[ Each test_case defines a name, a function, an input, an output. Else a sub-group of testsCases. mathroman.testsGroups = { -- Autotest cases to validate the mathroman library at mediawiki level. { errorsKey = 2, modulename = "mathroman", funcname = "roman2int", func = mathroman.roman2int, args = { "MCXI" }, expect = { 1111 } }, { name = "mathroman", func = testsCases.runGroups, group = mathroman.Tests_cases, modulename = "mathroman", funcname = "runGroups", groupname = "mathroman.Tests_cases", }, --]] -- subgroup.recursiveLimit = subgroup.recursiveLimit or modes.recursiveLimit subgroup.groupname = subgroup.groupname or group.groupname or groupname or "groupname" -- subgroup.modulename = subgroup.modulename or testcase.modulename or group.modulename or "modulename" subgroup.funcname = subgroup.funcname or "funcname" subgroup.name = group.name or subgroup.modulename or "name" subgroup.upername = subgroup.name subgroup.all_diffs = "" if recursiveLevel < recursiveLimit then testsCases.subgroup_memo = subgroup testsCases.trackTests( subgroup, "runTestsCases in args/groupname", tostring(subgroup.args), tostring(subgroup.groupname) ) local res_g, res_t = testsCases.runTestsCases( subgroup, subgroup.groupname, recursiveLevel + 1 ) -- Run only all tests cases in one group. subgroup.all_diffs = viewer.simpleList(subgroup.all_diffs, ";") t = t .. testsCases.trackTests( testcase, "runTestsCases subgroup nil?"..k, string.find(subgroup.all_diffs, "nil") or 0, string.len(subgroup.all_diffs or "-" ) ) -- testsCases.trackTests_t t = t .. res_g .. res_t testsCases.trackTests( subgroup, "runTestsCases out res_g/res_t", res_g, res_t) end end testcase.all_diffs = viewer.simpleList(testcase.all_diffs, ";") t = t .. viewer.form9user("\n* Group:synthesis : name=<b>%1</b>, count/groups=<b>%2/%3</b>, recursiveLevel=<b>%4</b>, ", -- .. testsCases.trackTests_t group.name, group.countCases, group.countGroups, recursiveLevel) --testcase .groupname end end -- for k, testcase in ipairs(group) do end -- if type(group) == "table" then -- Recursive run groups of tests cases. if recursiveLevel > 1 then -- In each sub-groups. testsCases.runCount = (testsCases.runCount or 0) + group.countCases t = t .. viewer.form9user("\n* Group:synthesis : name=<b>%1</b>, count/groups=<b>%2/%3</b>, recursiveLevel=<b>%4</b>, ", group.name, group.countCases, group.countGroups, recursiveLevel) --testcase .name t = t .. testsCases.trackTests_t else -- In the main group, after all sub-groups. testsCases.countCases = group.countCases testsCases.countGroups = group.countGroups t = t .. viewer.form9user("\n* All group:synthesis : name=<b>%1</b>, countCases/Groups=<b>%2/%3</b>, recursiveLevel=<b>%4</b>, ", group.name, testsCases.countFull, group.countGroups, recursiveLevel) t = t .. testsCases.trackTests_t end events.restore_configs(memo) -- Restore global configurations after eventual changes. return res_g, t end -- function testsCases.runTestsCases( group, groupname, recursiveLevel ) -- Run only all tests cases in one group. function testsCases.ModuleOrName(search) -- Search the name of a module or reverse. local result if type(search) == "string" then for name, module in pairs(package.loaded) do if search == name then result = module end -- Name to module. end elseif type(search) == "table" then for name, module in pairs(package.loaded) do -- Module to name. if search == module then result = name end end end return result end -- function testsCases.ModuleOrName(search) function testsCases.debugGetGroup(group, tabname) -- DEBUG the bug T20160615 : Lua functions calls lost multilevel table arguments group = testsCases.groupMemoDebug if tabname and not group then -- OK t = t .. "DEBUG_group: " t = t .. viewer.ta("begin group", group) t = t .. viewer.ta("testsCases.groupMemoDebug", testsCases.groupMemoDebug) t = t .. viewer.ta("tabname", tabname) -- local subgroup = { errorsKey = 2, modulename = "mathroman", ..., tabname = "mathroman.testscases.TestsGroups", } -- Example of link to subgroup --[ [ Normal method: found the missing group from tabname local tab = mw.text.split(tabname, '.', true) -- from the subgroup in string form for i, part in ipairs(tab) do -- Build the subgroup table from the tabname string t = t .. viewer.ta("part", part) if i == 1 then -- The start point is always a recorded module or library module = package.loaded[ part ] if type(module) == "table" then group2use = module end else -- add a subgroup to the previous subgroup if type(group2use) == "table" then subgroup = group2use[ part ] group2use = subgroup end end end group = group2use --] ] t = t .. viewer.ta("end group", group) end return group, t end -- function testsCases.debugGetGroup(group, tabname) -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:translate supports i18n translations. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- translate = {} -- already declared by Scribunto, else in _G space. -- Translations for translate library translate.i18n = {} translate.i18n.en = { language = 'language', translate_translationsCounts_title = "translate.translationsCounts() Counts of translations in tables", viewer_form9user_tests_title = "viewer.form9user() Test: Replace &%;1 to %9 by tostring( argN ) from arguments", translate_form9user_all_types_values = "Test: string=%1 number=%2 nil=%3 function=%4 table=%5.", viewer_form99user_tests_title = "in viewer.form99user() Test: Replace %01 to &%;29 by tostring( argN ) from arguments", translate_form99user_all_types_values = "in viewer.form99user() Values of all types: %1, %2, %3, %4, %5.", translate_form99user_no_tranlation = "in viewer.form99user() Lack of translation.", translate_form99user_a_value_is_table = "in viewer.form99user() A value is a table.", translate_translations_key_missing = "Internal error: Translations key missing or abnormal in viewer.trans9vars()", translate_lang_not_exist_err = "Error: The language <b>%1</b> is not available.", translate_abnormal_char_in_text_title = "translate.abnormal_char_in_text() Test: Detect abnormal characters in an unilingual text.", translate_abnormal_char_in_alphabet = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 013456789 ,;.:!?", translate_list_Mediawiki_languages_title= "translate.list_Mediawiki_languages() List all Mediawiki languages.", -- Main texts, errors and categories of tools translate_first_doc_languages = "Documentation of first languages", translate_user_wiki_lang_msg = "Languages: user: %1, wiki: %2.", translate_without_translation_err = "Known argument, but not translated: <b>%1</b>.", translate_without_translation_N_err = "There are %1 arguments untranslated.", translate_main_i18n_languages_count = "This module can translate <b>%1</b> sentences into <b>%2</b> languages: ", translate_i18n_list_all_texts = "This list show all the texts, but cannot replace the original declarations.", translate_languages_nbr_and_list = "\n* There are %1 tables of translations in these languages : %2 <br>", -- Miscellaneous warnings and errors translate_texts_translated_in_langs = "There are %1 texts translated in %2 languages.", translate_no_wiki_translations_err = "Error: Module without translated arguments table.", translate_list_in_translated_lang = "%1 translations in language %2 : %3 : %4", translate_missing_translations_title = "translate.missing_translations() Missing translations in i18n tables.", translate_transdiff_wanted_error_err = "Wanted error for minimal test of translate.missing_translations().", translate_missing_translations_headers = "Language; i18n Key; Previous translation; New translation; Module", translate_changing_translations_title = "translate.changing_translations() Changing (or missing) translations in i18n tables.", translate_changing_translations_headers = "Language; i18n Key; Previous translation; New translation; Module", translate_changing_translations_help = "See also %1 to ask for help to translate.", translate_mixed_translations_title = "translate.i18n_lister() Combined i18n translations tables:", translate_dummy_languages_title = "translate.dummy_languages() Languages Definitions:", translate_Module_Central_version = "Central-w-en", } -- translate.i18n.en translate.i18n.es = { -- ¿Quién es? language = 'lenguaje', translate_translationsCounts_title = "translate.translationsCounts() Condes des traducciones en tablas", viewer_form9user_tests_title = "viewer.form9user() Prueba: Reemplazar %1 a %9 por tostring( argN ) a partir de argumentos", translate_form9user_all_types_values = "Prueba: string=%1 number=%2 nil=%3 function=%4 table=%5.", viewer_form99user_tests_title = "en viewer.form99user() Prueba: Reemplazar %01 a %29 por tostring( argN ) a partir de argumentos", translate_form99user_all_types_values = "en viewer.form99user() Valores de todos los tipos: %1, %2, %3, %4, %5.", translate_form99user_no_tranlation = "en viewer.form99user() Falta de traducción.", translate_form99user_a_value_is_table = "en viewer.form99user() Un valor es una tabla.", translate_translations_key_missing = "Error interno: Traducciones clave que falta o anormal en viewer.trans9vars()", translate_lang_not_exist_err = "Error: El lenguaje <b>%1</b> no está disponible.", translate_abnormal_char_in_text_title = "translate.abnormal_char_in_text() Prueba: Detectar caracteres anormales en un texto monolingüe.", translate_abnormal_char_in_alphabet = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?", translate_list_Mediawiki_languages_title= "translate.list_Mediawiki_languages() Lista de todos los idiomas de Mediawiki.", -- Textos principales, errores y categorías de instrumentos translate_first_doc_languages = "Documentación de las primeras idiomas", translate_user_wiki_lang_msg = "Idiomas: usuario: %1, wiki: %2.", translate_without_translation_err = "Argumento conocido, pero no traducido: <b>%1</b>.", translate_without_translation_N_err = "Hay 1% argumentos no traducidos.", -- Diversos mensajes y errores translate_main_i18n_languages_count = "Este módulo puede traducir <b>%1</b> frases en <b>%2</b> idiomas: ", translate_languages_nbr_and_list = "\n* Hay %1 mesas de traducciones en estas idiomas: %2 <br>", translate_texts_translated_in_langs = "Hay 1% textos traducidos en 2% idiomas.", translate_no_wiki_translations_err = "Error: Módulo sin argumentos traducidos tabla.", translate_i18n_list_all_texts = "Esta lista muestra todos los textos, pero no puede sustituir a las declaraciones originales.", translate_list_in_translated_lang = "%1 traducciones en idioma %2 : %3 : %4", translate_missing_translations_title = "translate.missing_translations() Traducciones que falta de las tablas i18n.", translate_missing_translations_headers = "Idioma; Clave i18n; Traducción anterior; Nueva traducción; Módulo", translate_changing_translations_title = "translate.changing_translations() Traducciones que cambian (o falta de) en las tablas i18n.", translate_changing_translations_headers = "Idioma; Clave i18n; Traducción anterior; Nueva traducción; Módulo", translate_changing_translations_help = "Consulte también %1 para solicitar ayuda para traducir.", translate_mixed_translations_title = "Tablas traducciones i18n combinadas:", translate_dummy_languages_title = "translate.dummy_languages() Definiciones de idiomas:", translate_Module_Central_version = "Central-w-es", } -- translate.i18n.es translate.i18n.fr = { language = 'langue', translate_translationsCounts_title = "translate.translationsCounts() Comptages des traductions en tables", viewer_form9user_tests_title = "viewer.form9user() Test: Remplacer %1 à %9 par tostring( argN ) à partir des arguments", translate_form9user_all_types_values = "Test: string=%1 number=%2 nil=%3 function=%4 table=%5.", viewer_form99user_tests_title = "viewer.form99user() Test: Remplacer %01 à %29 par tostring( argN ) à partir des arguments", translate_form99user_all_types_values = "en viewer.form99user() Valeurs de tous types : %1, %2, %3, %4, %5.", translate_translations_key_missing = "Erreur interne: Clé de traduction manquante ou anormale dans viewer.trans9vars()", translate_form99user_no_tranlation = "en viewer.form99user() Manque de traduction.", translate_form99user_a_value_is_table = "en viewer.form99user() Une valeur est une table.", translate_lang_not_exist_err = "Erreur : La langue <b>%1</b> n'est pas disponible.", translate_abnormal_char_in_text_title = "translate.abnormal_char_in_text() Test: Détecter les caractères anormaux dans un texte unilingue.", translate_abnormal_char_in_alphabet = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?", translate_list_Mediawiki_languages_title= "translate.list_Mediawiki_languages() Liste de toutes les langues de Mediawiki.", -- Principaux textes, erreurs et catégories des outils translate_first_doc_languages = "Documentation des premières langues", translate_user_wiki_lang_msg = "Langues : utilisateur : %1, wiki : %2.", translate_without_translation_err = "Argument connu, mais non traduit : <b>%1</b>.", translate_without_translation_N_err = "Il y a %1 arguments non traduits.", translate_main_i18n_languages_count = "Ce module peut traduire <b>%1</b> phrases en <b>%2</b> langues : ", translate_i18n_list_all_texts = "Cette liste montre tous les textes, mais ne peut remplacer les déclarations originales.", translate_languages_nbr_and_list = "\n* Il y a %1 tables de traductions dans ces langues : %2 <br>", translate_texts_translated_in_langs = "Il y a %1 textes traduits en %2 langues.", translate_no_wiki_translations_err = "Erreur interne : Module sans table d'arguments traduits.", translate_list_in_translated_lang = "%1 traductions en langage %2 : %3 : %4", translate_missing_translations_title = "translate.missing_translations() Traductions manquantes dans les tables i18n.", translate_missing_translations_headers = "Langue; Clé i18n; Traduction précédente; Nouvelle traduction; Module", translate_changing_translations_title = "translate.changing_translations() Traductions changeantes (ou manquantes) dans les tables i18n.", translate_changing_translations_headers = "Langue; Clé i18n; Traduction précédente; Nouvelle traduction; Module", translate_changing_translations_help = "Voir aussi %1 pour demander de l'aide pour traduire.", translate_mixed_translations_title = "Tables de traductions i18n combinées :", translate_dummy_languages_title = "translate.dummy_languages() Définitions de langues :", translate_Module_Central_version = "Central-w-fr", } -- translate.i18n.fr function translate.track_counts(where, tabname, trans, tables, subtable) local tabname = (tabname or "versioning.main_i18n") -- local t, tot_vars, tot_tabs, tot_func, vr_tb = luaTable.formSubCounts(tabname) local tot_vars, tot_tabs, tot_func, vr_tb = luaTable.SubCounts(subtable, tabname) local trans, tables = (trans or tot_vars), (tables or tot_tabs) t = viewer.form9user("-*- %1:name/t/l=%2/%3/%4, ", tostring(where), tabname, trans, tables) translate.track_counts_t = (translate.track_counts_t or "") .. t return t end function translate.track_language(where) local res = "\n* " .. viewer.form9user(where) .. " : " res = res .. viewer.ta("wiki_lang", translate.wiki_lang) .. viewer.ta("user_lang", translate.user_lang) res = res .. viewer.form9user("language") -- translate.i18n.en = { language = 'language', res = res .. viewer.form9user("begin_support_central_modules_headers") return res -- res = res .. translate.track_language("begin_support_central_modules_title") end function translate.translationsCounts(t, ...) -- versioning.antiLoop("translate.translationsCounts", 3, translate.translationsCounts, t, ...) -- Limit the n-th reentrant call of any function. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or '\n* translate.translationsCounts("begin.i18n") Counts of contents of some tables, from their names: ' -- { "versioning.i18n", "versioning : name=%1, t=%2, l=%3, f() n=%4." }, -- p.v.version = "Central-s-fr" -- The main module select this version, from its p.versions{}, to replace its main version. t = t .. "\n* Translations in this module, if available: " -- local Central = p -- p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module. -- versionName = "Central-s-fr", versionNumber = "03 22:57", versionDate = "2017-04-03 22:57", t = t .. "<br>" .. luaTable.formSubCounts("Module:" .. Central.versions.versionName) -- not available in any module -- t = t .. "<br>" .. luaTable.formSubCounts("Module:" .. versioning.main_versions.versionName) -- not available in any module t = t .. "<br>" .. luaTable.formSubCounts("Module:Central") -- not available in any module t = t .. "\n* Translations in some languages: " t = t .. "<br>" .. luaTable.formSubCounts("translate.main_i18n") t = t .. "<br>" .. luaTable.formSubCounts("translate.main_i18n.br") t = t .. "<br>" .. luaTable.formSubCounts("translate.main_i18n.de") t = t .. "<br>" .. luaTable.formSubCounts("translate.main_i18n.en") t = t .. "<br>" .. luaTable.formSubCounts("translate.main_i18n.es") t = t .. "<br>" .. luaTable.formSubCounts("translate.main_i18n.hu") t = t .. "<br>" .. luaTable.formSubCounts("translate.main_i18n.fr") t = t .. "<br>" .. luaTable.formSubCounts("translate.main_i18n.vi") t = t .. "<br>" .. luaTable.formSubCounts("begin.i18n.es") t = t .. "<br>" .. luaTable.formSubCounts("begin.i18n.hu") t = t .. "<br>" .. luaTable.formSubCounts("begin.i18n.vi") t = t .. "<br>" .. luaTable.formSubCounts("viewer.i18n.fr") t = t .. "<br>" .. luaTable.formSubCounts("viewer.i18n.vi") t = t .. "<br>" .. luaTable.formSubCounts("modes.i18n.en") t = t .. "\n* Translations in some libraries: " t = t .. "<br>" .. luaTable.formSubCounts("begin.i18n") t = t .. "<br>" .. luaTable.formSubCounts("datas.i18n") t = t .. "<br>" .. luaTable.formSubCounts("events.i18n") t = t .. "<br>" .. luaTable.formSubCounts("luaTable.i18n") t = t .. "<br>" .. luaTable.formSubCounts("mathroman.i18n") t = t .. "<br>" .. luaTable.formSubCounts("modes.i18n") t = t .. "<br>" .. luaTable.formSubCounts("testsCases.i18n") t = t .. "<br>" .. luaTable.formSubCounts("translate.i18n") t = t .. "<br>" .. luaTable.formSubCounts("versioning.i18n") t = t .. "<br>" .. luaTable.formSubCounts("viewer.i18n") t = t .. "\n* Translations in wiki / user / page: " t = t .. "<br>" .. luaTable.formSubCounts("translate.wiki_translations") t = t .. "<br>" .. luaTable.formSubCounts("translate.user_translations") t = t .. "<br>" .. luaTable.formSubCounts("translate.page_translations") t = t .. "\n* Wanted errors cases:" t = t .. "<br>" .. luaTable.formSubCounts("tools.i18n") t = t .. "<br>" .. luaTable.formSubCounts("Empty table", {} ) -- do not fail in errors cases t = t .. "<br>" .. luaTable.formSubCounts("a string", "A string replaces the table.") -- do not fail in errors cases t = t .. "<br>" .. luaTable.formSubCounts(123.456, "A number replaces the table.") -- do not fail in errors cases t = t .. "<br>" .. luaTable.formSubCounts(function() end, "A function replaces the table.") -- do not fail in errors cases t = t .. "<br>" .. luaTable.formSubCounts(true , "A boolean value replaces the table.") -- do not fail in errors cases t = t .. "<br>" .. luaTable.formSubCounts(nil , "A nil value replaces the table.") -- do not fail in errors cases events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function translate.translationsCounts(t) function translate.key(key, lang) -- Translate the key in user, wiki and content languages. if (type(key) ~= "string") then key = "translate_missing_key_err" end if (type(lang) ~= "string") then lang = nil end local translate_i18n = translate.main_i18n function translate_one_key(translate_i18n, key, lang) if lang and (type(translate_i18n) == "table") then translate_i18n = translate_i18n[lang] end if key and (type(translate_i18n) == "table") then translate_i18n = translate_i18n[key] end return translate_i18n end translate_i18n = translate_one_key(translate_i18n, key, lang) if (type(lang) == "string") then -- Only the selected language return translate_i18n else return translate_one_key(translate_i18n, key, translate.user_lang), translate_one_key(translate_i18n, key, translate.wiki_lang), translate_one_key(translate_i18n, key, translate.page_lang) end -- Examples of uses -- local user, wiki, page = translate.key(key, lang) -- if translate.key(key, lang) ~= key then block end end -- function translate.key(key, lang) function translate.main_i18n_languages_list() -- List available translations languages -- if (type(versioning.main_i18n) == "table") and (type(translate.main_i18n) ~= "table") -- then translate.main_i18n = versioning.main_i18n end local main_i18n = translate.main_i18n or {} local tot_vars, tot_tabs, tot_func, vr_tb = luaTable.SubCounts(translate.main_i18n, "versioning.main_i18n") -- count of internal .i18n local tab_to_sort = {} for lang, modname in pairs(main_i18n) do table.insert(tab_to_sort, lang) -- build a table with only languages codes end table.sort(tab_to_sort, function (a, b) -- sort le languages codes in stable alphabetic order return ( a < b ) end ) local t = viewer.form9user("translate_main_i18n_languages_count", vr_tb, tot_tabs) -- #tab_to_sort) -- #tab_to_sort for i, lang in pairs(tab_to_sort) do -- describe each language local nativename = mw.language.fetchLanguageName(lang) local englishname = mw.language.fetchLanguageName(lang, "en") t = t .. viewer.form9user("<b>%1</b>(%2=%3), ", nativename, lang, englishname) end -- see events.selectLang return t -- translate_main_i18n_languages_count end -- function translate.main_i18n_languages_list() function translate.formTestCase(ref, ...) -- Form ref-v1-v2-v3-... local t = tostring(ref) for i, var in pairs( { ... } ) do if var then t = t .. "|" .. viewer.value(var) end -- tostring() or viewer.value() ? end return t end -- translate.Central_x_y = "<Central_x_y>" -- To adapt the version of Module:Central in any translated text. translate.Module_Central_version = "Central-s-fr" -- To adapt the version of Module:Central in any translated text. function viewer.trans9vars(translations, ref, ...) -- Replace %1 to %9 by tostring( argN ) from arguments, without any ambiguity in any string. local S9, repl, val, charN if type(ref) ~= "string" then ref = "translate_translations_key_missing" ref = translate.formTestCase(ref, ...) -- .. "+fTC" return ref -- .. "+t9v" end if type(translations) ~= "table" then return translate.formTestCase(ref .. "+notrans", ...) end if type(translations[ref]) == "string" then ref = translations[ref] end local args = {...} if #args > 0 then local n = 1 for n = 9, 1, -1 do S9 = tostring(n) charN = string.find(ref, "%".. S9, 1, true) if charN then -- If reference has %0 to %9 repl = tostring( args[n] or "" ) ref = string.sub(ref, 1, charN - 1) .. repl .. string.sub(ref, charN + string.len( "%".. S9 ) ) end end end ref = string.gsub(ref, p.v.version, translate.Module_Central_version or p.Module_Central_version or "p.v.version") -- Erreur Lua dans Module:Central-s-fr à la ligne 3274 : bad argument #3 to 'gsub' (string/function/table expected). return ref -- .. "+t9v" end -- function viewer.trans9vars(translations, key, ...) function viewer.form9wiki(ref, ...) -- replace %1 to %9 by v1 to v9 in the wiki translation of ref, else in ref local lang, tlts = "en", nil local form, n = "", 0 if not versioning.main_i18n_complete then return "" end -- Mask or Unmask all views to avoid failures. if (type(translate.wiki_translations) == "table") -- Only after versioning.bind_i18n_translations() -- and (type(translate.wiki_translations.en.versioning_luatable_counts) == "string") -- Only after versioning.bind_i18n_translations() then form = form .. viewer.trans9vars(translate.wiki_translations, ref, ...) -- .. "+f9w" else form = form .. translate.formTestCase(ref, ...) .. "+wTC" end return form end -- function viewer.form9wiki(ref, ...) function viewer.trans99vars(translations, ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string. local S99, repl, val, charN if type(translations) ~= "table" then return translate.formTestCase(ref, ...) end if type(ref) ~= "string" then ref = "translate_translations_key_missing" end if type(translations[ref]) == "string" then ref = translations[ref] end local args = {...} if #args > 0 then local n = 1 for n = 99, 1, -1 do S99 = tostring(n) if n < 10 then S99 = "0" .. S99 end charN = string.find(ref, "%".. S99, 1, true) if charN then -- If reference has %01 to %99 repl = tostring( args[n] or "" ) ref = string.sub(ref, 1, charN - 1) .. repl .. string.sub(ref, charN + string.len( "%".. S99 ) ) end end end return ref end -- function viewer.trans99vars(translations, ref, ...) function viewer.form99wiki(ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string. local form = viewer.trans99vars(translate.wiki_translations, ref, ...) return form end function viewer.form99user(ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string. local form = viewer.trans99vars(translate.user_translations, ref, ...) return form end function viewer.form9user(ref, ...) -- Replace %1 to %9 by tostring( argN ) from arguments, without any ambiguity in any string. -- local lang, tlts = "en", nil local form, n = "", 0 if not versioning.main_i18n_complete then return "" end -- Mask or Unmask all views to avoid failures. if (type(translate.user_translations) == "table") -- Only after versioning.bind_i18n_translations() -- and (type(translate.user_translations.en.versioning_luatable_counts) == "string") -- Only after versioning.bind_i18n_translations() then form = form .. viewer.trans9vars(translate.user_translations, ref, ...) -- .. "+f9u" else form = form .. translate.formTestCase(ref, ...) .. "+fTC" end return form end -- function viewer.form9user(ref, ...) function viewer.form9user_test(t) -- Tests of viewer.form9user_test(). local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>viewer.form9user_test(t, ref, ...)</b>:" t = t .. viewer.Th() .. viewer.Tc("input string and args") .. viewer.Tc("viewer.form9user_test") -- .. viewer.Tc("string.format") local function form9user_test1(ref, ...) -- local form9user, t9 = viewer.trans9vars(translate.user_translations, ref, ...) local form9user, t9 = viewer.form9user(ref, ...) return viewer.Tr() .. viewer.Td( ref ) .. viewer.Td( form9user ) -- .. t9 end t = t .. form9user_test1("translate_form9user_no_tranlation") t = t .. form9user_test1("viewer_test_no_values") -- translate_form9user_a_value_is_table t = t .. form9user_test1("translate_form9user_a_value_is_table", {}) t = t .. form9user_test1("translate_form9user_all_types_values", "abc", 4, nil, function(x) end, { 55, "xyz" } ) t = t .. form9user_test1("replace: abc%1efg%2ijk", "<b>D</b>", "<b>H</b>") t = t .. form9user_test1("repeat: a=%1 b=%2 c=%1 d=%2", "<b>1</b>", "<b>2</b>") t = t .. form9user_test1("altern: 1%13%25", "<b>2</b>", "<b>4</b>") t = t .. form9user_test1("list: %0<%1<%2<%3<%4<%5<%6<%7<%8<%9", "00", "11", "22", "33", "44", "55", "66", "77", "88", "99") t = t .. form9user_test1("mix: %1, %5, %2, %4, %3, ", "A", "B", "C", "D", "E") t = t .. form9user_test1("missing args: yes=%1 no=%5 no=%9 yes=%2", "args[1]", "args[2]") t = t .. form9user_test1("MATRIX 4 * 5<br>" .. "{ %1%5, %1%6, %1%7, %1%8, %1%9 }<br>" .. "{ %2%5, %2%6, %2%7, %2%8, %2%9 }<br>" .. "{ %3%5, %3%6, %3%7, %3%8, %3%9 }<br>" .. "{ %4%5, %4%6, %4%7, %4%8, %4%9 }<br>", "a", "b", "c", "d", "1", "2", "3", "4", "5") t = t .. viewer.Te() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function viewer.form9user_test(t) function viewer.form99user_test(t) -- Tests of viewer.form99user_test(). local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>viewer.form99user_test(t, ref, ...)</b>:" t = t .. viewer.Th() .. viewer.Tc("input string and args") .. viewer.Tc("viewer.form99user_test") local function form99user_test1(ref, ...) -- local form99user, t99 = viewer.trans99vars(translate.user_translations, ref, ...) local form99user, t99 = viewer.form99user(ref, ...) return viewer.Tr() .. viewer.Td( ref ) .. viewer.Td( form99user ) -- .. t9 end t = t .. form99user_test1("translate_form99user_no_tranlation") t = t .. form99user_test1("viewer_test_no_values") t = t .. form99user_test1("translate_form99user_a_value_is_table", {}) t = t .. form99user_test1("translate_form99user_all_types_values", "abc", 4, nil, function(x) end, { 55, "xyz" } ) t = t .. form99user_test1("replace: abc%01fg%02jk", "<b>DE</b>", "<b>HI</b>") t = t .. form99user_test1("repeat: a=%01 b=%02 c=%01 d=%02", "<b>01</b>", "<b>02</b>") t = t .. form99user_test1("altern: 01%0145%0289", "<b>23</b>", "<b>67</b>") t = t .. form99user_test1("list: %00<%01<%02<%03<%04<%05<%06<%07<%08<%09", "00", "11", "22", "33", "44", "55", "66", "77", "88", "99") t = t .. form99user_test1("mix: %01, %05, %02, %04, %03, ", "A", "B", "C", "D", "E") t = t .. form99user_test1("missing args: yes=%01 no=%05 no=%09 yes=%02", "args[1]", "args[2]") t = t .. form99user_test1("matrix: %10<br>" .. "{ %01%05, %01%06, %01%07, %01%08, %01%09 }<br>" .. "{ %02%05, %02%06, %02%07, %02%08, %02%09 }<br>" .. "{ %03%05, %03%06, %03%07, %03%08, %03%09 }<br>" .. "{ %04%05, %04%06, %04%07, %04%08, %04%09 }<br>", "a", "b", "c", "d", "1", "2", "3", "4", "5", "MATRIX 4 * 5") t = t .. viewer.Te() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function viewer.form99user_test(t) function translate.i18n_trac(id, t, count) -- track for i18n DEBUG -- translate.i18n_trac("base_func", "end", 1) -- example of use local t = t or "" t = t .. "<br><b>" .. (id or "") .. "</b> t=" .. t if count then t = t .. "<br>* " .. luaTable.formSubCounts("versioning.main_i18n") t = t .. "<br>* " .. luaTable.formSubCounts("wiki_translations") t = t .. "<br>* " .. luaTable.formSubCounts("user_translations") end return t end function modes.init_wiki_user_lang(wiki_lang, user_lang, page_lang) versioning.deprecatedFunction("modes.init_wiki_user_lang", "translate.init_wiki_user_page_lang") return translate.init_wiki_user_page_lang(wiki_lang, user_lang, page_lang) end -- en : Initialize or modify the language of the wiki and of the user and of the page and their tables. -- es : Inicializar o cambiar el idioma del wiki y del usuario y de la página y sus tablas. -- fr : Initialiser ou modifier la langue du wiki et de l'utilisateur et de la page et leurs tables. function translate.init_wiki_user_page_lang(wiki_lang, user_lang, page_lang) -- initialize or change the wiki, the user and the page languages and their tables -- See https://meta.wikimedia.org/wiki/Translate_extension and [[Special:PageLanguage]] 2016-12-19 local res = "" local getContentLanguage = mw.language.getContentLanguage().code -- default wiki_lang -- if (type(versioning.main_i18n) == "table") and (type(translate.main_i18n) ~= "table") -- then translate.main_i18n = versioning.main_i18n end if modes.args_config then wiki_lang = wiki_lang or modes.args_config.wikilang end if modes.args_config then user_lang = user_lang or modes.args_config.userlang end -- -- WIKI -- Activate the wiki language for errors, warnings and categories. if wiki_lang and translate.main_i18n and translate.main_i18n[wiki_lang] then -- Activate the wiki language for errors, warnings and categories. translate.wiki_lang = wiki_lang else -- if sought language is unavailable uses default value. translate.wiki_lang = getContentLanguage -- default wiki_lang end if translate.wiki_lang and translate.main_i18n and translate.main_i18n[translate.wiki_lang] then translate.wiki_translations = translate.main_i18n[translate.wiki_lang] else translate.wiki_translations = translate.i18n.en -- wiki's default translations end -- -- USER -- Activate the user language for errors, warnings and categories. translate.user_lang = translate.wiki_lang -- default user like wiki -- function object.setupInterface( options ) -- user_lang = user_lang or ParserOptions::getUserLang() -- does. See translate.user_lang -- T142906 Data access in user language do not obey the uselang get parameter / Apparently translate.user_translations = translate.wiki_translations -- default user like wiki if user_lang and translate.main_i18n and translate.main_i18n[user_lang] then -- Activate the wiki language for errors, warnings and categories. translate.user_lang = user_lang else -- if sought language is unavailable uses default value. translate.user_lang = getContentLanguage -- default user_lang end if translate.user_lang and translate.main_i18n and translate.main_i18n[translate.user_lang] then translate.user_translations = translate.main_i18n[translate.user_lang] else translate.user_translations = translate.i18n.en -- user's default translations -- translate.user_translations = translate.user_translations end -- -- PAGE -- Activate the page language for errors, warnings and categories. -- { 30, "Important", "T20161220", 0, "Close", "To test: Central modules need the page language to display errors categories and datas for helpers", "user language getContentLanguage()", }, -- T20161220 : ToDo: test: local getContentLanguage = mw.language.getContentLanguage().code -- default wiki_lang translate.page_lang = translate.wiki_lang -- default user like wiki translate.page_translations = translate.wiki_translations -- default user like wiki translate.page_lang = getContentLanguage -- default user_lang if translate.main_i18n then if not translate.page_lang then translate.page_lang = translate.wiki_lang end -- default user_lang translate.page_translations = translate.main_i18n[translate.page_lang] end return res end -- function translate.init_wiki_user_page_lang(wiki_lang, user_lang) function translate.list_Mediawiki_languages(t, lang) -- List all Mediawiki languages. local memo = events.save_configs() -- Save global configuration before eventual changes. if type(t) ~= "string" then t = "\n* <b>translate.list_Mediawiki_languages()</b> List all known Mediawiki languages:" end local lang = mw.language.new( translate.user_lang ) local LangCode = lang:getFallbackLanguages() local lang_code_name = mw.language.fetchLanguageNames() -- inLanguage, 'mwfile' ) local toSort, t2 = {}, "" t = t .. "\n* Infos lang_code_name: " .. viewer.ta("#lang_code_name", #lang_code_name) for code, name in pairs(lang_code_name) do -- make a true table in rough order table.insert(toSort, { code, name } ) -- insert detail { [1]=code, [2]=name } ) end -- t = t .. "\n* List of <b>known</b> languages of MediaWiki lang_code_name: <br/>" .. t2 table.sort(toSort, function (row_x, row_y) return ( row_x[1] < row_x[1] ) end ) -- Sort based on [1]=code table.sort(toSort, function (row_x, row_y) return ( row_x[2] < row_x[2] ) end ) -- Sort based on [2]=name t = t .. "\n* List of <b>known</b> languages of MediaWiki lang_code_name: <br/>" .. t2 t = t .. "\n* Infos: " .. viewer.ta("#lang_code_name", #lang_code_name) .. viewer.ta("#toSort", #toSort) .. viewer.ta("user_lang", translate.user_lang) -- t = t .. viewer.ta("#toSort[1]", #toSort[1] ) .. viewer.ta("toSort[1][1]", toSort[1][1] ) .. viewer.ta("toSort[1][2]", toSort[1][2] ) t2 = "" for i, lang in pairs(toSort) do local ok = translate.abnormal_char_in_text(lang[2], translate.user_lang) -- Detect abnormal characters in an unilingual text. local lang_2 = lang[2] if not ok then lang_2 = viewer.errorColor(lang_2) end t2 = t2 .. "\n* " .. viewer.ta( lang[1], lang_2 ) end t = t .. "\n* List of <b>known</b> languages of MediaWiki: <br/>" .. t2 events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function translate.list_Mediawiki_languages(t, lang) function translate.abnormal_char_in_text(t) -- Test: Detect abnormal characters in an unilingual text. if type(t) ~= "string" then return false end -- translate_abnormal_char_in_text_title local ok, normal = true, viewer.form9user("translate_abnormal_char_in_alphabet") -- local ok, normal = true, "ABCDEFGHIJKLMNOPQRSTUVWXYZ 013456789 abcdefghijklmnopqrstuvwxyz àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?" local letter, nn = "x", string.len(t .. " abcdef") - 3 -- local letter, nn = "x", mw.ustring.len(t) for i = 1, nn do -- for all chars in t letter = string.byte(t, i) if not viewer.is_in(letter, normal) then ok = false ; break end end return ok end -- function translate.abnormal_char_in_text(t) function translate.missing_translations(t) -- List all missing translations local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>translate.missing_translations()</b>: List all missing translations:" local errors = "*" local tabOptions, i18n, rowGroup if type(i18n) ~= "table" then i18n = translate.main_i18n or versioning.main_i18n end tabOptions = { -- options for viewer.tableView() -- Form a table with lines and columns. headers = "translate_missing_translations_headers", -- headers = "Language; Key; Previous translation; New translation; Module", kind = "projects", -- mediawiki or projects typ = "err", testGroup = i18n, -- tests or tabOptions.testGroup or rowGroup = {}, -- tests or tabOptions.testGroup or } tabOptions.rowGroup = {} -- tests or tabOptions.testGroup or rowGroup = tabOptions.rowGroup -- tests or tabOptions.testGroup or local missingGroup = {} -- versioning.translations_differences = versioning.translations_differences or {} -- local head = mw.text.split( viewer.form9user("translate_missing_translations_headers") , ',') -- t = t .. viewer.Th("wikitable sortable") .. viewer.Tc(head[1]) .. viewer.Tc(head[2]) .. viewer.Tc(head[3]) .. viewer.Tc(head[4]) .. viewer.Tc(head[5]) for key, trans in pairs(versioning.translations_differences ) do local trans1 = trans.trans1 local trans2 = trans.trans2 -- t = t .. viewer.Tr() .. viewer.Tc(trans1.dlang) .. viewer.Tc(trans1.dkey) .. viewer.Tc(trans1.dtrans) .. viewer.Tc(trans2.dtrans) .. viewer.Tc(trans2.dfile) end -- t = t .. viewer.tableView(tabOptions) -- Form a table with lines and columns. -- if type(i18n) ~= "table" then return " verif_i18n MISSING. " end local nerr, trans, err = 0, "", "" local nbr, nbr_in_lang, list = 0, 0, "" local nbr_in_lang_limit = 9 -- List any gaps of translations in i18n tables. local prev_table, next_table, max, nkeys = nil, nil, 0, 0 local lang, prev_lang, next_lang, cats = "", "", "", "" local all_txts = {} for lang, texts in pairs(i18n) do -- For all languages and texts to translate next_lang = lang -- next language next_table = texts -- next language table list = list .. lang .. ", " nbr = nbr + 1 nbr_in_lang = 0 if type(texts) == "table" then -- For each pair of languages to compare for keyi18n, stri18n in pairs(next_table) do -- List all texts translated in at least one language all_txts[keyi18n] = stri18n end if (prev_table ~= nil) and (next_table ~= nil) then -- For each pair of languages to compare nkeys = 0 for keyi18n, stri18n in pairs(all_txts) do -- For all texts to translate trans = next_table[keyi18n] nkeys = nkeys + 1 if (trans == nil) and (not tonumber(keyi18n) ) then -- and keyi18n ~= nil then -- args to a named argument err = events.add_err("versioning_module_miss_i18n_trad_err", next_lang, keyi18n) -- tools_module_miss_i18n_txt_err nerr = nerr + 1 local cut = string.find( keyi18n, "_") cut = cut or 11 local modul = string.sub( keyi18n, 1, cut - 1) if (nbr_in_lang == nbr_in_lang_limit) and (not tonumber(keyi18n) ) then -- and keyi18n ~= nil then -- args to a named argument table.insert( missingGroup, {next_lang, keyi18n, stri18n, viewer.errorColor("missing limit = " .. nbr_in_lang_limit), modul} ) nbr_in_lang = nbr_in_lang + 1 elseif (nbr_in_lang < nbr_in_lang_limit) and (not tonumber(keyi18n) ) then -- and keyi18n ~= nil then -- args to a named argument table.insert( missingGroup, {next_lang, keyi18n, stri18n, "missing: " .. nerr .. " / " .. nkeys, modul} ) -- table.insert( missingGroup, {next_lang, keyi18n, stri18n, "missing: " .. nerr .. " / " .. nkeys, modul} ) nerr = nerr + 1 nbr_in_lang = nbr_in_lang + 1 end end end if nkeys > max then max = nkeys end end end prev_lang = next_lang prev_table = next_table end if nerr > 0 then err = events.add_err("versioning_module_miss_i18n_count_err", nerr, max) errors = errors .. err cats = cats .. events.add_cat("versioning_err_module_miss_i18n_cat") else errors = errors .. " no errors " end tabOptions.headers = viewer.form9user("translate_missing_translations_headers") tabOptions.rowGroup, tabOptions.rowGroup_j = events.tableView_form_all_cases(tabOptions) -- Run tableView_form_one_case for all cases in testGroup{}. if errors ~= "" then errors = viewer.errorColor(errors) end local tabView = { testGroup = missingGroup, headers = "translate_missing_translations_headers", -- translate_missing_translations_headers = "Language; i18n Key; Previous translation; New translation; Module", } local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t --, errors -- translate_missing_translations_title end -- function translate.missing_translations(t) function translate.changing_translations(i18n , t) -- Translations missing and changing in i18n tables local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or ("\n* <b>translate.changing_translations(t)</b> Changing (or missing) translations in i18n tables.:") if (type(translate.main_i18n) ~= "table") then t = t .. "\n* <b>abnormal translate.main_i18n is not a table </b>" events.restore_configs(memo) -- Restore global configurations after eventual changes. return t --, errors -- translate_changing_translations_title end if (type(i18n) ~= "table") and (type(translate.i18n) == "table") then i18n = translate.i18n end local nerr, trad, err = 0, "", "", "" -- t = t .. "\n* translate.changing_translations( Comparer les langues : <b>" .. prev_lang .. "/" .. next_lang .. "</b>, " local nbr, list = 0, "" local tabOptions = { -- options for viewer.tableView() -- Form a table with lines and columns. headers = "translate_changing_translations_headers", -- headers = "Language; Key; Previous translation; New translation; Module", kind = "projects", -- mediawiki or projects typ = "err", testGroup = i18n, -- tests or tabOptions.testGroup or rowGroup = {}, -- tests or tabOptions.testGroup or } rowGroup = tabOptions.rowGroup -- tests or tabOptions.testGroup or local changingGroup = {} -- List any gaps of translations in i18n tables. local next_table, next_table, max, nkeys = nil, nil, 0, 0 local lang, prev_lang, next_lang, cats = "", "", "", "" local all_txts = {} -- ToDo: changing i18n, Rical 20170210 23:13 -- List of origins to compare for each translation: -- 1: internal minimal library or Module, example: datas or Module.Central-s-fr -- 2: /I18N submodule, example: datas or Module.Central-s-fr or Module:Library/versioning/I18N -- 3: external translate.i18n for all languages. -- 4: the same (1+2+3) for upper modules until the main module. Example: datas or/and Module.Central-s-fr or/and Module:Author3 -- 4: lo mismo (1+2+3) para los módulos superiores hasta al módulo principal. Ejemplo: datas o/y Módulo:Central-s-fr o/y Módulo:Author3 -- 4: les mêmes (1+2+3) pour les modules supérieurs jusqu'au module principal. Exemple: datas ou/et Module:Central-s-fr ou/et Module:Author3 -- Bind modules and submodules from the main module to all sub-modules recurcively, and memorize all the actual binding. -- Translate all translations in the exact reverse order, using the memorised binding order. Then upper modules can adapt translations. for lang, texts in pairs(i18n) do -- Pour toutes les langues et tous les textes à traduire next_lang = lang -- table suivante de traduction d'une langue next_table = texts -- table suivante de traduction d'une langue list = list .. lang .. ", " nbr = nbr + 1 if type(texts) == "table" then -- pour chaque couple de langues à comparer for keyi18n, v in pairs(texts) do -- Lister tous les textes traduits au moins dans une langue all_txts[keyi18n] = "x" end if next_table ~= nil and next_table ~= nil then -- pour chaque couple de langues à comparer t = t .. "\n* Comparer les langues : <b>" .. prev_lang .. "/" .. next_lang .. "</b>, " nkeys = 0 for keyi18n, x in pairs(all_txts) do -- Pour tous les textes à traduire trad = next_table[keyi18n] nkeys = nkeys + 1 if trad == nil then -- and keyi18n ~= nil then -- args vers un argument nommé err = events.add_err("versioning_module_miss_i18n_trad_err", keyi18n, next_lang) -- versioning_module_miss_i18n_txt_err t = t .. err .. " " -- .. "<br>" nerr = nerr + 1 end end if nkeys > max then max = nkeys end end end prev_lang = next_lang next_table = next_table end if nerr > 0 then err = events.add_err("versioning_module_miss_i18n_count_err", nerr, max) t = t .. "<br>" .. err .. " " cats = cats .. events.add_cat("versioning_err_module_miss_i18n_cat") -- cats = cats .. events.add_cat("modes_no_source_arguments_cat") else err = events.add_wng("versioning_module_miss_i18n_none_err") t = t .. "<br>" .. err .. " " end -- tester vr le nombre total de variables de traductions local st, vr, fn, tb = luaTable.structure(i18n, "i18n") if vr < 33 then err = events.add_err("versioning_module_miss_i18n_mini_err", vr) t = t .. "<br>" .. err .. " " cats = cats .. events.add_cat("versioning_err_module_miss_i18n_cat") -- cats = cats .. events.add_cat("modes_no_source_arguments_cat") end -- -- if (type(versioning.main_i18n) == "table") and (type(translate.main_i18n) ~= "table") -- then translate.main_i18n = versioning.main_i18n end -- translate.main_i18n = translate.main_i18n or versioning.main_i18n -- List all translated languages t = t .. "\n* Translated languages: Langues traduites : " local an, ln, Nadd, Nchange, Ntotal = 0, 0, 0, 0, 0 for lng, argmts in pairs(i18n) do -- For all languages to be imported if i18n[lng] then -- The language already exists, add or replace imported fields t = t .. viewer.form9user(", <b>Langue : %1</b> ", lng) ln = ln + 1 if type(texts) == "table" then -- For each pair of languages to be compared for argn, val in pairs(argmts) do -- For all imported fields if translate.main_i18n[lng] then if translate.main_i18n[lng][argn] then Nchange = Nchange + 1 table.insert( changingGroup, {next_lang, keyi18n, stri18n, "missing: " .. nerr .. " / " .. nkeys, modul} ) else Nadd = Nadd + 1 end -- Add or replace a field and its translation. Ajouter ou remplacer un champs et sa traduction translate.main_i18n[lng][argn] = val -- t = t .. viewer.form9user(", %1 ", argn) an = an + 1 end end end else -- Add the table and all its fields if it is not yet in translate.main_i18n if mw.language.isKnownLanguageTag(lng) then translate.main_i18n[lng] = i18n[lng] -- translate.main_i18n end end end local lst_lng = "" for lang, argmts in pairs(i18n) do -- Pour toutes les langues à importer Ntotal = 0 if type(translate.main_i18n[lang]) == "table" then -- For each pair of languages to be compared if type(texts) == "table" then -- pour chaque couple de langues à comparer for argn, val in pairs(translate.main_i18n[lang]) do -- For all existing fields Ntotal = Ntotal + 1 end local langname = mw.language.fetchLanguageName(lang, "en") local native = mw.language.fetchLanguageName(lang) lst_lng = lst_lng .. viewer.form9user("translate_list_in_translated_lang", Ntotal, lang, langname, native) -- translate_list_in_translated_lang = "%1 translations in language %2 : %3 : %4", end end end translate.user_wiki_lang_msg = viewer.form9user("translate_user_wiki_lang_msg", translate.user_lang, translate.wiki_lang) translate.user_wiki_lang_err = translate.user_wiki_lang_msg -- deprecated for Module:Author3 translate.Lang_list = lst_lng t = t .. viewer.form9user("translate_languages_nbr_and_list", nbr, list) .. lst_lng t = t .. "\n* Same example without translation for a test case : " .. translate.formTestCase("translate_languages_nbr_and_list", nbr, list) -- t = t .. translate.missing_translations() -- Compare all differences of translations -- translate_changing_translations_headers t = t .. viewer.tableView("translate_languages_nbr_and_list", nbr, list) .. lst_lng tabOptions.headers = viewer.form9user("translate_missing_translations_headers") tabOptions.rowGroup, tabOptions.rowGroup_j = events.tableView_form_all_cases(tabOptions) -- Run tableView_form_one_case for all cases in testGroup{}. if errors ~= "" then errors = viewer.errorColor(errors) end local tabView = { headers = "translate_missing_translations_headers", -- translate_missing_translations_headers = "Language; i18n Key; Previous translation; New translation; Module", testGroup = changingGroup } local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t --, errors -- translate_changing_translations_title end -- function translate.changing_translations(i18n , t) function translate.i18n_lister(t, i18n_tables) if type(i18n_tables) ~= "table" then i18n_tables = translate.main_i18n end local t = t or "\n* <b>i18n_lister</b> :" t = t .. viewer.errorColor("\n* <b>This list show all the texts, but cannot replace the original declarations.</b> ") t = t .. viewer.errorColor("\n* <b>" .. viewer.form9user("translate_i18n_list_all_texts") .. " </b> " ) for lang, lang_table in pairs(i18n_tables) do t = t .. "\np.i18n." .. lang .. ' = { ' if type(lang_table) == "table" then for key, text in pairs(lang_table) do if key and text then t = t .. "\n:" .. key .. ' = "' .. text .. '",' end end end t = t .. "\n}\n" end return t end -- function translate.i18n_lister(t, i18n_tables) -- - - - ------------------ - - - - --------------------------------- -- Manage translations of arguments and warnings -- Gestione traducciones de argumentos y advertencias -- Gérer les traductions des arguments et warnings -- - - - ------------------ - - - - --------------------------------- function translate.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:Central/I18N", -- english es = "Modul:Central/I18N", -- spanish fr = "Module:Central/I18N", -- french Fr = "Module:Central/I18N", -- error test als = "Modulen:Central/I18N", -- alemanish gsw = "Mod-gsw:Central/I18N", -- unknown ["bat-smg"] = "Mod-bat-smg:Central/I18N", -- alemanish sgs = "Mod-sgs:Central/I18N", -- unknown } local t = '\n* dummy_languages : ' .. viewer.ta("isTag", "isKnownLanguageTag(xx)") .. viewer.ta("isLang", "isSupportedLanguage(xx)") .. viewer.ta("isBuilt", "isValidBuiltInCode(xx)") t = t .. viewer.Th() .. viewer.Tc("lang") .. viewer.Tc("isTag") .. viewer.Tc("isLang") .. viewer.Tc("isBuilt") t = t .. viewer.Tc("langname") .. viewer.Tc("native") 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") -- see events.selectLang local native = mw.language.fetchLanguageName(lang) local space_name = tostring(mw.site.namespaces.Module.name) t = t .. viewer.Tr() .. viewer.Td(lang) .. viewer.Td(isTag) .. viewer.Td(isLang) .. viewer.Td(isBuilt) t = t .. viewer.Td(langname) .. viewer.Td(native) end t = t .. viewer.Te() return t end -- function translate.dummy_languages() -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:versioning installs other libraries, supports versions, then binds modules, libraries and i18n translations. -- This library support modules to: -- * Collect and bind modules and sub-modules depending from their p.versions{} -- * Collect and bind translations from modules or libraries itself, and their /I18N sub-modules -- * Form parametrable strings -- * Add a language needs only to add its own i18n subtable, like i18n.en = {} -- * Manage alternate versions of sub-modules sought in main, like Module:Sub, Module:Sub.2.1, Module:SubPlus. -- A central module and its translations can inpedendently change. Its p.versions{} identifications change also. -- For this goal a module contains at least one i18n tranlations table. Its /I18N sub-modules contains translations in several languages. -- Central Libraries, like modules, contain their own p.versions{} identifications and i18n translations in Module:Library/library_name/I18N. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- _G["versioning"] = {} -- versioning = {} -- The Library:versioning installs other libraries, bind modules and libraries, bind i18n translations, manage versions. -- versioning = {} -- The Library:versioning must stay in _G global space, to not change in init phase. -- local librariesList = librariesList or versioning.librariesList = { -- New libraries to record in package.loaded[] ["begin"] = begin, ["datas"] = datas, ["events"] = events, ["luaTable"] = luaTable, ["modes"] = modes, -- ["string"] = string, -- texts = {} The Library:texts come from Scribunto. The Module:Central add some functions to it. ["testsCases"] = testsCases, ["tools"] = tools, ["translate"] = translate, -- versioning = {} -- The Library:versioning installs other libraries, bind modules and libraries, bind i18n translations, manage versions. -- versioning = {} -- The Library:versioning must stay in _G global space, to not change in init phase. ["versioning"] = versioning, ["viewer"] = viewer, -- ["mathroman"] = mathroman, -- The Library:mathroman is here as an example of very small central library. It becomes central using the central modules system. } -- versioning = {} -- already declared by Scribunto, else in _G space. -- Translations for versioning library versioning.i18n = {} versioning.i18n.br = { versioning_support_desk_title = "Bureau de support pour %1 : %2 translations in %3 languages", -- br versioning_support_desk_table = "viewer.docDropBoxTitle", } -- versioning.i18n.br versioning.i18n.de = { versioning_support_desk_title = "Unterstützungsbüro für %1 : %2 Übersetzungen in %3 Sprachen", -- de versioning_support_desk_table = "viewer.docDropBoxTitle", } -- versioning.i18n.de versioning.i18n.en = { -- Main texts, errors and categories of tools versioning_dev_running_times_title = "versioning.running_times() Running times and references for Lua-coders.", versioning_luatable_counts = "%1 variables, %3 sub-tables, %2 functions", versioning_table_dont_exists = "The table <b>%1</b> does not exist.", versioning_table_listlimit_levelmaxi = "Level limit recursiveLimit = <b>%1</b> ", versioning_table_listlimit_max_n = "Length limit max_n = <b>%1</b> ", versioning_antiCrash_tests_title = "versioning.antiCrash() Test: in case of running error, do not crash the page.", versioning_antiCrash_reference_label = "References", versioning_antiLoop_function_err = "versioning.antiLoop() error in the <b>%3</b> <b>%1()</b>, loop n = <b>%2</b>, args = ", versioning_module_usage_error_cat = "Module with usage error", versioning_module_with_error_cat = "Module with error", versioning_module_with_error_err = "Module with error", versioning_with_internal_error_cat = "Module with internal error", -- Versions management versioning_versions_no_select_altern_err= "Versions error: no selection in the alternative <b>%1</b> of the module <b>%2</b>.", versioning_versions_too_select_altern_err= "Versions error: <b>%1</b> selections in the alternative <b>%2</b> of the module <b>%3</b>.", versioning_versions_select_not_used_err = "Versions error: <b>%1</b> selector is not in alternative <b>%2</b> of the module <b>%3</b>.", versioning_versions_missing_module_err = "Versions error: missing module for the version <b>%1</b> of the module <b>%2</b>.", versioning_main_module_missing_err = "The main module is not found.", versioning_select_unknown_module_err = "Internal error: The missing Module:<b>%1</b> is replaced by the normal Module:<b>%2</b>.", versioning_I18N_module_no_base_err = "The <b>%1</b> translations module has no basic version.", versioning_no_versions_module_err = "The module <b>%1</b> is not in the system of versions.", versioning_all_versions_tests = "Versions warning: <b>%1</b>, normal: <b>%2</b>, listall: <b>%3</b>.", versioning_all_versions_check = "Versions: missings: <b>%1</b>, unknowns: <b>%2</b>, normals: <b>%3</b>, excess: <b>%4</b>, all selected: <b>%5</b>.", versioning_missing_versions_err = "The module <b>%1</b> misses in the main module <b>%2</b>.", versioning_replaced_versions_err = "The module <b>%1</b> replaces the missing sub-module in the main module <b>%2</b>.", versioning_unknownversions_err = "The module <b>%1</b> is unknown in the main module <b>%2</b>.", versioning_module_miss_i18n_txt_err = "Internal Error: The text <b>%1</b> lack of translation in <b>%2</b> language, and/or others.", versioning_module_miss_i18n_count_err = "Internal Error: There are <b>%1</b> missings in <b>%2</b> translations.", versioning_module_miss_i18n_none_err = "OK, none missing translations.", versioning_module_miss_i18n_trad_err = "Internal Error: Module missing i18n translation for the argument <b>i18n.%1.%2</b>.", -- versioning_err_module_miss_i18n_cat = "Module missing i18n translation", versioning_err_module_miss_i18n_cat = "Module with internal error", versioning_module_miss_i18n_mini_err = "Error: I18n table has only <b>1%</b> translations.", versioning_module_error_err = "Module with error.", -- Titles of tests versioning_list_all_G_and_loaded_title = "versioning.list_all_G_and_loaded() List of variables in _G global space", versioning_support_desk_title = "Support desk for %1 : %2 translations in %3 languages", -- en versioning_support_desk_table = "viewer.docDropBoxTitle", versioning_bind_central_modules_title = "versioning.bind_central_modules_report() Versions of central libraries and modules", versioning_versions_management_report = "versioning.versions_management_report() Versions management report", -- versioning_bind_modules_tests_title = "versioning.bind_modules_test() Test for management of modules versions", versioning_verif_bind_modules_report = "Binding of modules and versions control", versioning_bind_modules_test_headers = "Sought versions; Used versions; Known versions; ACTUAL: Errors in the active module; SIMULATION: Errors in the active module", versioning_tasks_changes_report = "versioning.tasks_changes_report() Documentations, tasks and changes", versioning_sort_central_modules_title = "versioning.sort_central_modules_report() Sorted list of central modules and libraries.", versioning_sort_central_modules_headers = "Title; Version; Date; Translations / Languages", versioning_sort_central_modules_counts = "this: + %2/%3 T/L, ", versioning_try_waits_debug_T122752 = "#invoke has not loaded <b>%1</b>, but the debug of T122752 has loaded it.", versioning_tasks_report_title = "versioning.versioning_tasks_report() States of known tasks", versioning_tasks_report_headers = "Importance; Task; State; Title; In short", versioning_add_deprecated_err = "Deprecated function <b>%1(...)</b>. Replace it by <b>%2(...)</b> in the module <b>%3</b>.", versioning_deprecatedFunction_tests_title= "versioning.deprecatedFunction() Test: Deprecated function. Replace it in the module.", versioning_defaultCrashResult_ref_err = "The antiCrash() function protects this page against a complete crash due to an internal error: %1.", } -- versioning.i18n.en versioning.i18n.es = { -- Textos principales, errores y categorías de instrumentos versioning_dev_running_times_title = "versioning.running_times() Tiempos de ejecución y referencias para los codificadores Lua.", versioning_luatable_counts = "%1 variables, %3 subtablas, %2 funciones", versioning_table_dont_exists = "La tabla <b>%1</b> no existe.", versioning_table_listlimit_levelmaxi = "Límite de nivel recursiveLimit = <b>%1</b>", versioning_table_listlimit_max_n = "Límite de longitud max_n = <b>%1</b>", versioning_antiCrash_tests_title = "versioning.antiCrash() Prueba: en caso de error de ejecución, no sobrescribir la página.", versioning_antiCrash_reference_label = "Referencias", versioning_antiLoop_function_err = "versioning.antiLoop() Error en el <b>%3</b> <b>%1()</b>, bucle n = <b>%2</b>, args = ", versioning_module_usage_error_cat = "Módulo con error del uso", versioning_module_with_error_cat = "Módulo con error", versioning_module_with_error_err = "Módulo con error", versioning_with_internal_error_cat = "Módulo con interno error", -- Gestión de versiones versioning_versions_no_select_altern_err= "Error de versiones: no hay selección en alternativa <b>%1</b> del módulo <b>%2</b>.", versioning_versions_too_select_altern_err= "Error de versiones: <b>%1</b> selecciones en la alternativa <b>%2</b> del módulo <b>%3</b>.", versioning_versions_select_not_used_err = "Error de versiones: selector <b>%1</b> no es en alternativas <b>%2</b> del módulo <b>%3</b>.", versioning_versions_missing_module_err = "Error de versiones: módulo ausente para la versión <b>%1</b> del módulo <b>%2</b>.", versioning_main_module_missing_err = "El módulo principal no es encontrado.", versioning_select_unknown_module_err = "Internal error: El Modulo:<b>%1</b> faltante se reemplaza por lo normal Module:<b>%2</b>.", versioning_I18N_module_no_base_err = "El módulo de traducciones <b>%1</b> no tiene ninguna versión básica.", versioning_no_versions_module_err = "El <b>%1</b> módulo no está en el sistema de versiones.", versioning_all_versions_tests = "Versiones aviso: <b>%1</b>, normal: <b>%2</b>, lista: <b>%3</b>.", versioning_all_versions_check = "Versiones: falta: <b>%1</b>, incógnitas: <b>%2</b>, normales: <b>%3</b>, en exceso: <b>%4</b>, selecciona todo: <b>%5</b>.", versioning_missing_versions_err = "El módulo <b>%1</b> no disponible en el módulo principal <b>%2</b>.", versioning_replaced_versions_err = "El módulo <b>%1</b> reemplaza el sub-módulo ausente en el módulo principal <b>%2</b>.", versioning_unknownversions_err = "El módulo <b>%1</b> es desconocido en el módulo principal <b>%2</b>.", versioning_module_miss_i18n_txt_err = "Error Interno: El texto <b>%1</b> falta de traducción en <b>%2</b> lengua, y / o otras.", versioning_module_miss_i18n_count_err = "Error interno: Hay <b>%1</b> que falta en <b>%2</b> traducciones.", versioning_module_miss_i18n_none_err = "OK, ninguno traducciones que faltan.", versioning_module_miss_i18n_trad_err = "Error interno: translation faltan en Módulo i18n para el argumento <b>i18n.%1.%2</b>.", -- versioning_err_module_miss_i18n_cat = "Módulo traducción i18n que falta", versioning_err_module_miss_i18n_cat = "Módulo con error interno", versioning_module_miss_i18n_mini_err = "Error: la tabla i18n tiene solamente <b>1%</b> traducciones.", -- Titres des pruebas versioning_list_all_G_and_loaded_title = "versioning.list_all_G_and_loaded() Lista de todos las variables en el espacio global _G", versioning_support_desk_title = "De apoyo de oficina para %1 : %2 traducciones en %3 idiomas", -- es versioning_support_desk_table = "viewer.docDropBoxTitle", versioning_bind_central_modules_title = "versioning.bind_central_modules_report() Versiones de bibliotecas y módulos centrales", versioning_versions_management_report = "versioning.versions_management_report() Informe de gestión de versiones", -- versioning_bind_modules_tests_title = "versioning.bind_modules_test() Test for management of modules versions", versioning_verif_bind_modules_report = "Binding of modules and versions control", versioning_bind_modules_test_headers = "Sought versions; Used versions; Known versions; ACTUAL: Errors in the active module; SIMULATION: Errors in the active module", versioning_tasks_changes_report = "versioning.tasks_changes_report() Documentación, parches y modificaciones", versioning_sort_central_modules_title = "versioning.sort_central_modules_report() Lista ordenada de módulos y bibliotecas centrales.", versioning_sort_central_modules_headers = "Título; Versión; Fecha; Traducciones / Idiomas", versioning_sort_central_modules_counts = "esta + %2/%3 T/I, ", versioning_try_waits_debug_T122752 = "#invoke no ha cargado <b>%1</b>, pero la depuración de T122752 ha lo cargó.", versioning_tasks_report_title = "versioning.versioning_tasks_report() Estados del tareas conocidas", versioning_tasks_report_headers = "Importancia; Tarea; Estado; Título; En breve", versioning_add_deprecated_err = "Función obsoleta <b>%1(...)</b>. Sustitúyala por <b>%2(...)</b> en el módulo <b>%3</b>.", versioning_deprecatedFunction_tests_title= "versioning.deprecatedFunction() Prueba: Función obsoleta. Sustitúyala en el módulo.", } -- versioning.i18n.es versioning.i18n.fr = { -- Principaux textes, erreurs et catégories des outils versioning_dev_running_times_title = "versioning.running_times() Temps d'exécution et références pour les Lua-codeurs.", versioning_luatable_counts = "%1 variables, %3 sous-tables, %2 fonctions", versioning_table_dont_exists = "La table <b>%1</b> n'existe pas.", versioning_table_listlimit_levelmaxi = "Limite de niveau recursiveLimit = <b>%1</b> ", versioning_table_listlimit_max_n = "Limite de longueur max_n = <b>%1</b> ", versioning_antiCrash_tests_title = "versioning.antiCrash() Test: en cas d'erreur en cours d'exécution, ne pas écraser la page.", versioning_antiCrash_reference_label = "Références", versioning_antiLoop_function_err = "versioning.antiLoop() Erreur dans la <b>%3</b> <b>%1()</b>, boucle n = <b>%2</b>, args = ", versioning_module_usage_error_cat = "Module avec erreur d'utilisation", versioning_module_with_error_cat = "Module avec erreur", versioning_module_with_error_err = "Module avec erreur", versioning_with_internal_error_cat = "Module avec erreur interne", -- Gestion des versions versioning_versions_no_select_altern_err= "Erreur de versions : pas de sélection dans l'alternative <b>%1</b> du module <b>%2</b>.", versioning_versions_too_select_altern_err= "Erreur de versions : <b>%1</b> sélections dans l'alternative <b>%2</b> du module <b>%3</b>.", versioning_versions_select_not_used_err = "Erreur de versions : le sélecteur <b>%1</b> n'est pas dans les alternatives <b>%2</b> du module <b>%3</b>.", versioning_versions_missing_module_err = "Erreur de versions : module absent pour la version <b>%1</b> du module <b>%2</b>.", versioning_main_module_missing_err = "Le module principal est introuvable.", versioning_select_unknown_module_err = "Internal error: Le Module:<b>%1</b> manquant est remplacé par le module normal Module:<b>%2</b>.", versioning_I18N_module_no_base_err = "Le module de traductions <b>%1</b> n'a pas de version de base.", versioning_no_versions_module_err = "Le module <b>%1</b> n'est pas dans le système des versions.", versioning_all_versions_tests = "Versions avertissements : <b>%1</b>, normaux : <b>%2</b>, liste : <b>%3</b>.", versioning_all_versions_check = "Versions: manquantes: <b>%1</b>, inconnues: <b>%2</b>, normales: <b>%3</b>, en excès: <b>%4</b>, toutes selectionées : <b>%5</b>.", versioning_missing_versions_err = "Le module <b>%1</b> manque dans le module principal <b>%2</b>.", versioning_replaced_versions_err = "Le module <b>%1</b> remplace le sous-module absent dans le module principal <b>%2</b>.", versioning_unknownversions_err = "Le module <b>%1</b> est inconnu dans le module principal <b>%2</b>.", versioning_module_miss_i18n_txt_err = "Erreur interne : Le texte <b>%1</b> manque de traduction en langue <b>%2</b>, et/ou d'autres.", versioning_module_miss_i18n_count_err = "Erreur interne : Il y a <b>%1</b> manques parmi <b>%2</b> traductions.", versioning_module_miss_i18n_none_err = "OK, aucune traduction manquante.", versioning_module_miss_i18n_trad_err = "Erreur interne : manque de traduction pour l'argument <b>i18n.%1.%2</b>.", -- versioning_err_module_miss_i18n_cat = "Module manquant de traduction i18n", versioning_err_module_miss_i18n_cat = "Module avec erreur interne", versioning_module_miss_i18n_mini_err = "Erreur interne : La table i18n n'a que <b>%1</b> traductions.", versioning_module_error_err = "Module avec erreur", -- Titres des tests versioning_list_all_G_and_loaded_title = "versioning.list_all_G_and_loaded() Liste des variables dans l'espace global _G", versioning_support_desk_title = "Bureau de support pour %1 : %2 traductions en %3 langues", -- fr versioning_support_desk_table = "viewer.docDropBoxTitle", versioning_bind_central_modules_title = "versioning.bind_central_modules_report() Versions des bibliothèques et modules centraux", versioning_versions_management_report = "versioning.versions_management_report() Rapport de gestion des versions", -- versioning_bind_modules_tests_title = "versioning.bind_modules_test() Test de la gestion des versions des modules", versioning_verif_bind_modules_report = "Liaison des modules et contrôle des versions", versioning_bind_modules_test_headers = "Versions demandées; Versions utilisées; Versions connues; ACTUEL : Erreurs dans le module actif; SIMULATION : Erreurs dans le module actif", versioning_tasks_changes_report = "versioning.tasks_changes_report() Documentations, tâches et modifications", versioning_sort_central_modules_title = "versioning.sort_central_modules_report() Liste triée des modules et bibliothèques centraux.", versioning_sort_central_modules_headers = "Titre; Version; Date; Traductions / Langues", versioning_sort_central_modules_counts = "ceci: + %2/%3 T/L, ", versioning_try_waits_debug_T122752 = "#invoke n'a pas chargé <b>%1</b>, mais le débogage de T122752 l'a chargé.", versioning_tasks_report_title = "versioning.versioning_tasks_report() États des tâches connues", versioning_tasks_report_headers = "Importance; Tâche; Etat; Titre; En bref", versioning_add_deprecated_err = "Fonction obsolète <b>%1(...)</b>. Remplacez-la par <b>%2(...)</b> dans le module <b>%3</b>.", versioning_deprecatedFunction_tests_title= "versioning.deprecatedFunction() Test: Fonction obsolète. Remplacez-la dans le module.", versioning_defaultCrashResult_ref_err = "La fonction antiCrash() protège cette page contre un effondrement complet dû à une erreur interne : %1.", } -- versioning.i18n.fr versioning.i18n.hu = { versioning_support_desk_title = "Hivatalt a támogatja a %1 : %2 fordítás a %3 nyelven", -- hu versioning_support_desk_table = "viewer.docDropBoxTitle", } -- versioning.i18n.hu versioning.i18n.vi = { versioning_support_desk_title = "Hỗ trợ Văn phòng cho %1 : %2 dịch Dịch trong %3 ngôn ngữ ở", -- vi versioning_support_desk_table = "viewer.docDropBoxTitle", } -- versioning.i18n.vi versioning.ModuleNS = mw.site.namespaces.Module.name .. ":" function versioning.trackAllVersions(where, txt) versioning.report_trackAllVersions = (versioning.report_trackAllVersions or "function report_trackAllVersions ") .. viewer.ta(where, txt) return versioning.report_trackAllVersions -- search .all_versions end function versioning.form_version(vers) -- Form the version and the main version of a module or a library. local version = string.gsub(vers, "p.v.version", p.v.version ) local main_version = string.gsub(vers, "p.v.version", p.v.main_version ) return version, main_version end function versioning.pcallRequire(version) -- require() must not fail and block the page. if type(version) == "string" then version = string.gsub( version, versioning.ModuleNS, "" ) -- normalize for always one "Module:" version = versioning.ModuleNS .. version -- example Module:Central/I18N end local success, module = pcall( require, version ) -- pcall or xpcall can run any function without blocking page. if not success then module = nil end return module end function versioning.get_one_module_or_library(title, given_module) -- Get a module or a library, then form and record its descriptor. -- local get, module = versioning.get_one_module_or_library("Module:Central") -- basic example of use local get = {} local module, required, loaded if type(title) ~= "string" then get.title = "abnormal title : " .. tostring(title) get.isNil = true return get end -- If not loaded, return only an empty get if (type(given_module) == "table") or (type(given_module) == "function") then module = given_module else -- to require a new module loaded = versioning.pcallRequire(title) -- require() must not fail and block the page if the module do not exists. if (type(loaded) == "table") or (type(loaded) == "function") then module = loaded -- The module is well loaded in package.loaded else return get end -- If not loaded, return only get.isTitled and get.title end get.title = title -- like Module:Author, or the versioning library get.module = module -- like {...} get.isNil = not module -- like true or false get.isLoaded = true and package.loaded[title] -- true if the module is in package.loaded get.isFunction = (type(module) == "function") -- true if the module is a function get.isTable = (type(module) == "table") -- true if the module is a table get.i18n = module.i18n -- i18n table of the module get.versions = module.versions -- table including module.versions.known and module.versions.sought -- get.isLibrary = (type(module)=="table") and not (type(module)=="function") and not (viewer.is_in(versioning.ModuleNS, title) ) -- true if the object is a library get.isLibrary = (type(module)=="table") and not (type(module)=="function") and not (string.find(title, versioning.ModuleNS, 1, true) ) -- true if the object is a library -- T20160616 Rical task: Add module and library types in scribunto ? get.hasi18n = (type(module) == "table") and (type(get.i18n) == "table") -- true if the object has a i18n translations table get.versionName = string.gsub(get.title or "", versioning.ModuleNS, "") -- without Module: like versioning or Author get.versionTitle = versioning.ModuleNS .. get.versionName -- normalize title like Module:Author get.isModule = string.find(get.title, versioning.ModuleNS) -- true if the object is like Module:Author get.isI18N = true and string.find(get.title, "/I18N") -- true if the title contains /I18N like Module:Author/I18N get.withoutI18N = string.gsub(get.versionName, "/I18N", "") -- version without /I18N like versioning or Module:Author get.versionI18N = get.withoutI18N .. "/I18N" -- version with /I18N like Module:Author/I18N get.nowstamp = os.date("%Y%m%d%H%M%S") -- like YYYYMMDDhhmmss from module -- Special for isModule, isLibrary, isFunction if get.isLibrary then -- get.revistamp = "20010101000000" -- default libraries timestamp at 2000-01-01T00:00:00Z, see ISO 8601 time format get.revistamp = get.nowstamp get.TitleI18N = versioning.ModuleNS .. "Library/" .. get.withoutI18N .. "/I18N" -- like Module:Library/versioning/I18N get.pagename = TitleI18N -- Locate translations like Module:Library/versioning/I18N get.i18nRoot = get.versionName -- Where locate translations are like versioning elseif get.isModule then get.revistamp = mw.getCurrentFrame():preprocess( "{{REVISIONTIMESTAMP:" .. get.title .. "}}" ) get.pagename = "Module:" .. get.versionName -- Locate translations like Module:Central/I18N get.i18nRoot = get.pagename -- Where locate translations are like Module:Author get.TitleI18N = versioning.ModuleNS .. get.withoutI18N .. "/I18N" -- like Module:Central/I18N else get.revistamp = mw.getCurrentFrame():preprocess( "{{REVISIONTIMESTAMP:" .. get.title .. "}}" ) end get.versionName = string.gsub(get.title or "", versioning.ModuleNS, "") -- full version name with perhaps /I18N -- get.simplename = string.gsub(get.title or "", versioning.ModuleNS, "") -- delete "Module:" if any get.simplename = string.gsub(get.versionName, "/I18N", "") -- delete "/I18N" if any get.viewI18N = get.simplename if type(module) == "function" then get.isFunction = true -- isFunction get.isModule = false get.isLibrary = false get.functionName = get.simplename -- like tostring get.pagename = "function:" .. get.simplename -- like function:tostring elseif string.find(get.title, versioning.ModuleNS) then -- If the module title begin with "Module:" get.isFunction = false get.isModule = true -- isModule get.isLibrary = false get.moduleName = get.title -- complete the title with "Module:" like Module:Central get.subI18N = get.title .. "/I18N" -- eventual sub-module "/I18N" like Module:Central/I18N get.pagename = versioning.ModuleNS .. get.simplename -- like Module:Central if get.isI18N then get.pagename = get.pagename .. "/I18N" end -- like Module:Central/I18N if get.isI18N then get.viewI18N = get.simplename .. "/I18N" end -- like Central/I18N else -- If the module is a library get.isFunction = false get.isModule = false get.isLibrary = true -- isLibrary get.libraryName = get.title -- standard library name like versioning get.versionName = get.libraryName -- like versioning get.pagename = versioning.ModuleNS .. "Library/" .. get.title -- like Module:Library/versioning get.subI18N = get.pagename .. "/I18N" -- /I18N sub-module like Module:Library/versioning/I18N if get.isI18N then get.pagename = get.subI18N end -- like Module:Library/versioning/I18N if get.isI18N then get.viewI18N = get.simplename .. "/I18N" end -- like versioning/I18N end if get.isI18N and (type(get.module) == "table") and (type(get.module.i18n) == "table") then get.sub_i18n = get.module.i18n end -- stamp, date and time local function days(stamp) -- approximate the number of days from 0000-01-01 local day = 0 if (type(stamp) == "string") and (string.len(stamp) > 7) then day = tonumber(string.sub(stamp,1,4)) * 365 + tonumber(string.sub(stamp,5,6)) * 30 + tonumber(string.sub(stamp,7,8)) end return day end if get.revistamp then get.days_revis = days(get.revistamp) get.days_now = days(get.nowstamp) get.delay = get.days_now - get.days_revis get.revistime = string.sub(get.revistamp,1,4) .. "-" .. string.sub(get.revistamp,5,6) .. "-" .. string.sub(get.revistamp,7,8) .. " " .. string.sub(get.revistamp,-6,-5) .. ":" .. string.sub(get.revistamp,-4,-3) get.shortdays = string.sub(get.revistamp or "", 3, 8) get.shorttime = string.sub(get.revistime or "", -9, -1) if get.delay < 25 then get.shortVersion = "v" .. get.shorttime -- short version in "vDD hh:mm" until around 25 days else get.shortVersion = "v" .. get.shortdays -- later in date vYYMMDD end get.versionDate = get.revistime get.versionNumber = get.shortVersion get.versionName = string.gsub(get.title or "", versioning.ModuleNS, "") -- full version name with perhaps /I18N get.versionDate = get.revistime if type(get.module.versions) == "table" then -- For central modules or libraries only: get.module.versionName = get.versionName -- Record in each module to later IDENTIFY any module. See task T119978, "own module name" get.module.versionDate = get.versionDate -- Record in each module to later DATE any module. See task T119978, "own module name" end end if get.versions then get.sought = get.versions.sought or get.versions.selector or "" get.known = get.versions.known or get.versions.all_versions or "" -- local str = string.gsub(get.sought, " ", ";") get.sought_tab = mw.text.split(str, ";", true) get.sought_count = #get.sought_tab -- local str = string.gsub(get.known, "*", ";") get.known_tab = mw.text.split(str, ";", true) get.known_count = #get.known_tab end -- Record the get descriptor with others versioning.loaded_modules_and_libraries = versioning.loaded_modules_and_libraries or {} if get.i18n then table.insert(versioning.loaded_modules_and_libraries, get) end -- versioning.bind_main_and_sub_modules_get = versioning.bind_main_and_sub_modules_get or {} versioning.bind_main_and_sub_modules_get[get.title] = get -- versioning.trackAllVersions("getModuleAndTime " .. get.versionName, get.all_versions) return get, module -- table.sort(versioning.loaded_modules_and_libraries, function (a, b) return (a.moduleName < b.moduleName) end ) -- alphabetic sort of translated arguments -- loaded_modules_and_libraries is the always sorted group of loaded modules and libraries. -- see package_loaded -- versioning.loaded_modules_and_libraries = versioning.loaded_modules_and_libraries or {} -- get = { isTitled, title, module, isLoaded, isLibrary, hasi18n, versionName, versionTitle, versionDate, versionNumber, shortVersion, -- i18n, versions, sought, known, sought_tab, sought_count, known_tab, known_count, , -- isModule, isI18N, lessI18N, versionI18N, nowstamp, revistamp, revistime, shortdays, shorttime, nowstamp, delay } -- title = Module:Central, revistamp = 20151207214027, revistime = 2015-12-07 21:40, gettitle = Module:Author3, shortVersion = v07 21:40 or v150227 end -- get, module = versioning.get_one_module_or_library(title, given_module) -- Get a module or a library, then form and record its descriptor. -- if get.i18n then table.insert(versioning.loaded_modules_and_libraries, get) end function versioning.add_one_i18n(t, module_name, module_tab) -- Add with others an i18n translations table and list all differences of translations. local t = t or "" -- change versioning.main_i18n and translate.main_i18n only once each and never repair them then they can become stable. versioning.main_i18n = versioning.main_i18n or {} -- if type(translate) == "table" then translate.main_i18n = versioning.main_i18n end -- Same pointers insure later same contents. -- local i18n, lang_N, text_N = {} ,0, 0 local translations_differences = {} function versioning_detect_transDiff(trans1, trans2) -- Collect all differences of translations if trans1.dtrans and trans2.dtrans and (trans1.dlang == trans2.dlang) and (trans1.dkey == trans2.dkey) and (trans1.dtrans ~= trans2.dtrans) then table.insert(translations_differences, { ["trans1"] = trans1, ["trans2"] = trans2 }) -- build a table with only languages codes end -- Only fast collect to treat later if needed. end if type(module_tab) == "table" and type(module_tab.i18n) == "table" then -- and type(module_tab.i18n) == "table" then i18n = module_tab.i18n or {} -- i18n lang_N, text_N = 0, 0 for lang, trans in pairs(i18n) do -- For all languages of the mixed module or library if versioning.main_i18n[lang] then -- the language already exists, add or replace imported fields lang_N = lang_N + 1 if type(trans) == "table" then -- if the language to add is really in a table for key, val in pairs(trans) do -- For all imported fields versioning_detect_transDiff( -- Collect all differences of translations { dlang = lang, dkey = key, dfile = "previous", dtrans = versioning.main_i18n[lang][key] }, { dlang = lang, dkey = key, dfile = module_name, dtrans = val} ) versioning.main_i18n[lang][key] = val -- add or replace a field and its translation text_N = text_N + 1 end end t = t .. viewer.form9user(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N) -- t = t .. translate.formTestCase(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N) else -- add the table and all is fields if it is not already in versioning.main_i18n if mw.language.isKnownLanguageTag(lang) then -- only for languages known in wikis lang_N = lang_N + 1 versioning.main_i18n[lang] = mw.clone(trans) text_N = text_N + #trans t = t .. viewer.form9user(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N) -- t = t .. translate.formTestCase(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N) end end end end -- t = t .. translate.track_counts("add_i18n:end", "versioning.i18n", trans, tables, versioning.i18n) local st, vr, fn, tb = luaTable.formSubCounts("versioning.main_i18n") t = t .. viewer.form9user(", addi18n:%1:<b>%2/%3</b> texts/langs, ", module_name, vr, tb) -- t = t .. translate.formTestCase(", addi18n:%1:<b>%2/%3</b> texts/langs, ", module_name, vr, tb) -- versionversion, lang:tot = ta:0 mix:Central1:441+3181=3181, return t, lang_N, text_N -- t, ln, an end -- function versioning.add_one_i18n(t, module_name, module_tab) function versioning.bind_one_library(name, library, options) -- Record a library in package.loaded -- RunOnce: -- RunOnce : Do not repeat this function to not disturb subsequent processes. -- library can be a table, a string or a function, not a nil. -- if package.loaded[name] then library = nil ; err = "cannot replace a previous library" end -- A library cannot replace a previous library. if library == string then return library end -- Install the new library, only a table. options = options or {} options.library = library or options.library options.name = name or options.name options.err = "err: " -- if (type(library) ~= "table") then return end -- if (type(options.library) ~= "table") then return end if (type(options.name) ~= "string") then return end local object = library local php -- Remove setup function -- if library then library.setupInterface = nil end function object.setupInterface(options) local php = nil -- Remove setup function if options.library then options.library.setupInterface = nil end -- Copy the PHP callbacks to a local variable, and remove the global php = mw_interface mw_interface = nil -- Do any other setup here -- Install into the mw global mw = mw or {} mw.ext = mw.ext or {} mw.ext[options.name] = options.library -- Indicate that we're loaded package.loaded[options.name] = options.library options.err = (options.err or "") .. "setup = mw.ext[options.name] = options.library, " end object = object.setupInterface(options) local NAME = options.NAME options.binded_in = versioning.binded_in(options.name, options.library) return options.library, options.err end -- return object, err = function versioning.bind_one_library(name, library, options) function versioning.binded_in(name, object) -- Is the object binded in _G space or in package.loaded = LD ? local binded_in = "xx" if _G[name] == object then binded_in = "_G" end if package.loaded[name] == object then binded_in = "LD" end return binded_in -- 20161202 18:25 See example https://fr.wikisource.org/wiki/Module:Phab.TestpackG : detect "in " "_G" or package.loaded end -- binded_in = function versioning.binded_in(name, object) function versioning.bind_central_libraries(librariesList, opt) -- Bind translatable libraries before bind modules and versions. -- Record centralisable libraries if they are not included in standard mw.Extension:Scribunto -- RunOnce : Do not repeat this function to not disturb subsequent processes. local t = "\n* <b>versioning.bind_central_libraries()</b> : " local librariesList = librariesList or versioning.librariesList for name, lib in pairs(librariesList) do local options = {} options.library = lib -- or options.library options.name = name -- or options.name local libra, err = versioning.bind_one_library(name, lib, options) libra = libra or lib or {} t = t .. "library.name = <b>" .. name .. "</b>, library.binded_in = <b>" .. options.binded_in .. "</b>, " .. options.err end local name, name_I18N, tt, lang_N, text_N local nm = "<br>Libraries after bind_one_library in bind_libraries() : " for name, library in pairs(package.loaded) do nm = nm .. name .. ", " end versioning.tracki18n_new_libraries123 = nm or "no library in package.loaded" -- Binding 1 - Bind first central libraries and their /I18N sub-modules. t = t .. "\n* effective versioning.bind_central_libraries() : " for title, obj in pairs(_G) do -- if object.hasi18n and object.isLibrary then if (type(obj) == "table") and (type(obj.i18n) == "table") then -- Get a module or a library, then form and record a descriptor of it. local get, module = versioning.get_one_module_or_library(title, obj) local loaded = versioning.loaded_modules_and_libraries --[ [ t = t .. "\n*" .. viewer.ta("get.title", get.title) -- .. viewer.ta("library", get.module) -- t = t .. viewer.ta("get.versionName", get.versionName) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("isLibrary", get.isLibrary) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("i18n", get.i18n) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) -- t = t .. viewer.ta("get.viewI18N", get.viewI18N) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) --] ] end end -- Same pointers insure later same contents. if (type(translate) == "table") and (type(versioning.main_i18n) == "table") then translate.main_i18n = versioning.main_i18n end -- versioning.bind_i18n_report = (versioning.bind_i18n_report or ".") .. (t or ".") translate.track_i18n_t = translate.track_i18n_t .. t -- versioning.bind_central_libraries_t = t return t end -- function versioning.bind_central_libraries(librariesList, opt) -- deprecated : versioning.sort_central_modules_report(t) -- Sorted list of central modules and libraries function versioning.bind_central_modules_report(t) -- Sorted list of central modules and libraries -- versioning_sort_central_modules_title = "versioning.sort_central_modules_report() Sorted list of central modules and libraries.", -- versioning_sort_central_modules_headers = "Title; Version; Date; Translations / Languages", local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>versioning.sort_central_modules_report()</b> -- Sorted list of central modules and libraries." -- local loaded_pack, loaded_txt, modu = versioning.get_loaded_modules() local loaded_sorted = {} -- table.sort(loaded_sorted, function (a, b) return ( a.pagename < b.pagename ) end ) local tabView = { -- Adapt all options for all uses, before all other adaptations. testGroup = versioning.loaded_modules_and_libraries, headers = "versioning_sort_central_modules_headers", headers_class = "wikitable alternative center sortable", -- form_elem_detail = "this + %2/%3 T/L, ", form_elem_detail = "versioning_sort_central_modules_counts", -- "this + %2/%3 T/L, " } function tabView.tableView_form_one_case(get) -- Generally to define: Convert a case from testGroup to rowGroup. local subI18N = "" if get.i18n then -- get.i18n local vers18 = get.versionName --; if not get.isI18N then vers18 = "" end if get.isModule then get.pagename = "Module:" .. get.versionName end -- Locate translations example in Module:Central/I18N if get.isLibrary then get.pagename = "Library:" .. get.versionName end -- Locate translations example in Module:Library/versioning/I18N -- local t ... = luaTable.formSubCounts(tabname, tablebase, text_form) -- get.counts = luaTable.formSubCounts(get.i18nRoot .. ".i18n", "this + %2/%3 T/L, ") -- versioning_sort_central_modules_counts get.counts = luaTable.formSubCounts(get.i18nRoot .. ".i18n", tabView.form_elem_detail) -- versioning_sort_central_modules_counts if get.has_I18N then get.counts = get.counts .. "<br>+ i18n in: <b>" .. get.viewI18N .. "</b>" end -- version_I18N -- luaTable.formSubCounts("versioning.main_i18n", versioning.main_i18n, ", (all = %2/%3 T/L)") if get.versionName and get.pagename then -- t2 = viewer.form9user("<br>* alias <b>%1</b> = <b>%2</b>, version = <b>%3</b>, date = <b>%4</b>", -- get.pagename, get.versionName, get.shortVersion, get.versionDate) end end return { (get.pagename or ""), (get.viewI18N or ""), (get.versionDate .. "<br>" .. get.shortVersion), get.counts } -- return { (get.pagename or ""), (get.versionName or ""), (get.versionDate .. "<br>" .. get.shortVersion), get.counts } end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function versioning.bind_central_modules_report(t) -- Sorted list of central modules and libraries -- local tt, vers_test = versioning.bind_sub_modules(p, vers_test) -- The main module can bind all its sub-modules versions, and their /I18N sub-modules. function versioning.bind_sub_modules(main_p, vers_test) -- Bind all modules and sub-modules versions, without their translations -- versioning.actual_modules = versioning.actual_modules or "actual_modules = <b>bind_sub_modules()</b>:" local recursiveLevel, recursiveLimit, recursiveLevel_err = 1, 1111, "" if versioning.main_i18n_complete then recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, modes.recursiveLimit) end -- local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, modes.recursiveLimit) local versioning_main_i18n_memo = versioning.main_i18n -- local modes_args_source_memo = modes.args_source -- local modes_args_config_memo = modes.args_config -- modes.args_source = new_source -- = nil -- modes.args_config = args_config -- = nil -- versioning.invoke_record_module_correct_T122752( ) -- Correct the bug T122752 : #invoke do not record the main module in package.loaded local t = "\n*<b>versioning.bind_sub_modules() start</b>, effective Search the main module: " -- Waiting the debug of T119978 Get the own module name and last record date-time from each module -- versioning.main_versions = nil -- versioning.main_module = nil local main_module = nil -- To get first local main_versions = nil local versions, version = nil local title = nil local gettitle = mw.getCurrentFrame():getTitle() -- get the mainmodule title local package_loaded_gettitle = package.loaded[gettitle] versioning.main_gettitle = gettitle -- t = t .. viewer.ta("gettitle", gettitle) main_p = main_p or versioning.debugT122752_main_module -- waiting debug of T122752 module found module.versions.sought -- Normal process if type(main_p) == "table" then -- A module can lauch itself or another as main module. main_module = main_p -- t = t .. viewer.ta("main_p", main_p) if type(main_p) == "table" and type(main_p.versions) == "table" then -- For main modules using versions management title = versioning.ModuleNS .. main_p.versions.versionName versioning.main_p_versions_txt = "main_p.versions : " -- .. viewer.ta("main_p.title", title) .. viewer.ta("main_p.versionNumber", main_p.versions.versionNumber) -- .. viewer.ta("main_p.sought", main_p.versions.sought) .. viewer.ta("main_p.known", main_p.versions.known) end -- bd : bind_sub_modules from main to sub, then compute all subI18N, then in reverse order addi18n from subI18N.i18n as .sub_i18n -- bd : versioning.init, bind_libraries_modules_translations, bind_central_libraries, bind_sub_modules, bind_i18n_translations, -- bd : get_one_module_or_library, bind_central_modules_report elseif type(package_loaded_gettitle) == "table" then -- If #invoke has already loaded the main module in package.loaded -- local main_i18n_memo = mw.clone(versioning.main_i18n) main_p = package_loaded_gettitle main_module = main_p -- t = t .. "\n* main module from gettitle : correct T122752 <b>" .. tostring(gettitle) .. "</b>. " if type(main_p) == "table" and type(main_p.versions) == "table" then -- For main modules using versions management versioning.gettitle_versions_txt = "getTitle.versions : " -- .. viewer.ta("getTitle.versionName", main_p.versions.versionName) .. viewer.ta("getTitle.versionNumber", main_p.versions.versionNumber) -- .. viewer.ta("getTitle.sought", main_p.versions.sought) .. viewer.ta("getTitle.known", main_p.versions.known) end else -- If the main module was not recorded in package.loaded, try to require() it. -- local module = versioning.pcallRequire(gettitle) -- require() must not fail and block the page. if module then-- Alert by a warning in edit mode: the bug is already fixed. local main_i18n_memo = versioning.main_i18n main_p = module main_module = main_p -- t = t .. "\n* main module from gettitle : repairs T122752 <b>" .. tostring(gettitle) .. "</b>. " else -- The main module called this module, but something else is in error. -- local main_i18n_memo = versioning.main_i18n main_p = p main_module = main_p -- t = t .. "\n* main module from gettitle : not found <b>" .. tostring(gettitle) .. "</b>. " end -- If not loaded, return only get.isTitled and get.title end -- After get the main module, get the versions for management. -- The main module can use or not the versions management. if type(main_p) == "table" and type(main_p.versions) == "table" then -- For main modules using versions management main_module = main_p versioning.main_module = main_module -- t = t .. viewer.ta("versioning.main_module", versioning.main_module) main_versions = main_p.versions -- t = t .. viewer.ta("versioning.main_versions", versioning.main_versions) end if not versioning.main_module then -- The main module is not found. return viewer.errorColor( viewer.form9user("versioning_main_module_missing_err") ) end versioning.main_i18n = versioning_main_i18n_memo -- Restore from versioning.bind_central_libraries() -- modes.args_source = modes_args_source_memo -- Restore from modes.argsConfigIinit() -- modes.args_config = modes_args_config_memo -- Restore from modes.argsConfigIinit() -- In normal cases if type(versioning) == "table" and type(versioning.main_gettitle) == "string" then main_versions.versionName = string.gsub(versioning.main_gettitle, versioning.ModuleNS, "") -- without Module: end -- if (type(vers_test) == "table") then -- In tests cases main_module.versions = vers_test -- In versions management test, vers_test replace the main versions main_versions = main_module.versions main_versions.used = ";" end -- t = t .. "<br>" .. viewer.ta("main_module", main_module) .. viewer.ta("main_versions", main_versions) -- t = t .. "<br>BEFORE sought, known, versionName, versionNumber, version, main_module : <br>" if type(main_module) == "table" and type(main_versions) == "table" then -- Verify main module and versions management ability. sought = main_versions.sought known = main_versions.known versionName = main_versions.versionName versionNumber = main_versions.versionNumber -- t = t .. viewer.ta("main_module", main_module) .. viewer.ta("main_versions", main_versions) -- t = t .. viewer.ta("sought", sought) .. viewer.ta("known", known) -- t = t .. viewer.ta("versionName", versionName) .. viewer.ta("versionNumber", versionNumber) end t = t .. "<br>AFTER sought, known, versionName, versionNumber, version, main_module : " versioning.bind_modules_start = t if type(main_versions.sought) == "string" and type(main_versions.known) == "string" then known = main_versions.known sought = main_versions.sought end t = t .. "\n*bind_sub_modules() starts: " local sought_t = string.gsub(main_versions.sought or sought or "", " ", ";") -- ";" .. .. ";" local sought_tab = mw.text.split(sought_t, " ", true) local sought_maxn = table.maxn(sought_tab) -- local known_tab = mw.text.split(main_versions.known or known or "", "*", true) local known_maxn = table.maxn(known_tab) -- local known_maxn = #known_tab local used = ";" local t = "" t = t .. "\n* list versioningsought.bind_sub_modules : " -- .. viewer.ta("main_versions.versionName", main_versions.versionName) -- .. viewer.ta("main_versions.", main_versions.sought) .. viewer.ta("sought_maxn", sought_maxn) -- .. "<br>" .. viewer.ta("main_versions.known", main_versions.known) .. viewer.ta("known_max", known_max) local alternatives, kind for i = known_maxn, 1, -1 do -- alternatives = known_tab[i] alternatives = known_tab[i] alternatives = ";" .. mw.text.trim(alternatives) .. ";" -- normalize versions between ";" -- alternatives = viewer.simpleList(alternatives) local altern_tab = mw.text.split(alternatives, ";", true) local elem, module, normal, alias, name_I18N normal = "" ; version = "" altern = tostring(altern) altern = mw.text.trim(altern) for v, altern in ipairs(altern_tab) do -- versioning.actual_modules = versioning.actual_modules .. ";" .. altern if v == 1 and string.find(";" .. sought .. ";", ";" .. altern .. ";", 1, true) then -- if v == 1 and viewer.is_in_sp(altern, sought, ";") then normal = altern kind = "normal" end if v > 1 and string.find(";" .. sought .. ";", ";" .. altern .. ";", 1, true) then -- if v > 1 and viewer.is_in_sp(altern, sought, ";") then version = altern kind = "version" end local name_mod, name_I18N, tt, lang_N, text_N, get_i18n, getI18N if vers_test then -- In versions management test if string.find(";" .. vers_test.loaded_list .. ";", ";" .. altern .. ";", 1, true) then -- if viewer.is_in_sp(altern, vers_test.loaded_list, ";") then used = (used or "- ") .. altern .. "; " end name_I18N = altern .. "/I18N" -- Get a module or a library, then form and record a descriptor of it. local get, module = versioning.get_one_module_or_library(name_I18N) -- versioning.actual_modules = versioning.actual_modules .. ";" .. get.title if (type(get.module) == "table") and (type(get.moduleName) == "string") then -- Verify main module and versions management ability. end -- bd : bind_sub_modules from main to sub, then compute all subI18N, then in reverse order addi18n from subI18N.i18n as .sub_i18n -- bd : versioning.init, bind_libraries_modules_translations, bind_central_libraries, bind_sub_modules, bind_i18n_translations, -- bd : get_one_module_or_library, bind_central_modules_report else -- In normal run -- addi18n from the module itself if (type(getI18N) == "table") and (type(getI18N.moduleName) == "string") then -- Verify main module and versions management ability. -- t = t .. "\n*" .. tostring(tb) .. viewer.ta("I18N", getI18N.moduleName) -- .. viewer.ta("name_I18N", name_I18N) -- versioning.actual_modules = versioning.actual_modules .. ";" .. getI18N.title end end if vers_test then -- In versions management test if viewer.is_in_sp(name_I18N, vers_test.loaded_list, ";") then used = (used or "- ") .. name_I18N .. "; " end else -- wait later versioning.bind_i18n_translations() to get I18N end end -- for v, altern in ipairs(altern_tab) do end -- for i = known_maxn, 1, -1 do -- alternatives = known_tab[i] local word, errs = "", "" if type(vers_test) == "table" then -- In tests run -- Versions management errors from overall look on modules local alloncesort = viewer.simpleList(vers_test.sought .. ";" .. vers_test.known .. ";" .. vers_test.used) local alloncetab = mw.text.split(alloncesort, ',') -- table of words for i, name in ipairs(alloncetab) do -- list all used names, only one each, in alphabetic order if viewer.is_in_sp(name, vers_test.sought, ";") and not viewer.is_in_sp(name, vers_test.known, ";") then errs = errs .. ";" .. events.add_err("versioning_missing_versions_err", name, vers_test.versionName ) -- new -- versioning_missing_versions_err = "The module <b>%1</b> misses in the main module <b>%2</b>.", end if viewer.is_in_sp(name, vers_test.used, ";") and not viewer.is_in_sp(name, vers_test.sought, ";") then vers_test.replaced = (vers_test.replaced or "") .. name .. ";" -- sought but not found errs = errs .. ";" .. events.add_err("versioning_replaced_versions_err", name, vers_test.versionName ) -- new -- versioning_replaced_versions_err = "The module <b>%1</b> replaces the missing module in the main module <b>%2</b>.", -- versioning_select_unknown_module_err = "Internal error: The missing Module:<b>%1</b> is replaced by the normal Module:<b>%2</b>.", -- versionsmanagement end if viewer.is_in_sp(name, vers_test.alloncesort, ";") and not viewer.is_in_sp(name, vers_test.known, ";") then vers_test.unknown = (vers_test.replaced or "") .. name .. ";" -- sought but not found errs = errs .. ";" .. events.add_err("versioning_unknownversions_err", name, vers_test.versionName ) -- new -- versioning_unknownversions_err = "The module <b>%1</b> is unknown in the main module <b>%2</b>.", end end -- for v, altern in ipairs(altern_tab) do end main_versions.used = used if not (type(vers_test) == "table") then -- In normal run versioning.main_module = main_module -- In normal cases and not in tests cases versioning.main_versions = mw.clone(main_versions) -- In normal cases and not in tests cases end -- t = t .. "\n* versioning.bind_sub_modules END : " -- .. viewer.ta("main_versions.used", main_versions.used) .. viewer.ta("#loaded_pack", #versioning.loaded_modules_and_libraries) versioning.bind_modules_start = t versioning.required_descriptors = loaded_pack versioning.bind_i18n_report = (versioning.bind_i18n_report or ".") .. (t or ".") return t, main_versions -- loaded_pack, versioning.track_i18n_vers end -- function versioning.bind_sub_modules(main_p, vers_test) -- Bind all modules and sub-modules versions, without their translations -- local tt, vers_test = versioning.bind_sub_modules(p, vers_test) -- The main module can bind all its sub-modules versions, and their /I18N sub-modules. function versioning.bind_i18n_translations(main_versions, loaded_pack) -- Bind all i18n translations from modules and their /I18N translations sub-modules local main_versions = main_versions or versioning.main_versions local t = "\n* <b>versioning.bind_i18n_translations()<b>" -- -- Todo: Bind i18n in reverse order of versioning.bind_sub_modules() -- bd : bind_sub_modules from main to sub, then compute all subI18N, then in reverse order addi18n from subI18N.i18n as .sub_i18n -- if (type(versioning.main_module) == "table") and (type(versioning.main_module.i18n) == "table") then -- Insert main i18n after any other i18n, then the main module could adapt sub_modules translations. -- table.insert(versioning.loaded_modules_and_libraries, versioning.main_module) end -- for i, get in pairs(versioning.loaded_modules_and_libraries) do if (type(get.title) == "string") and (type(get.i18n) == "table") then versioning.add_one_i18n("", get.title, get.i18n) -- Add with previews an i18n translations table t = t .. "\n*" .. viewer.ta("title", get.title) t = t .. viewer.ta("#i18n", #get.i18n) end -- Bind i18n sub-modules, for each its internal i18n then its /I18N sub-module. if (type(get.subI18N) == "string") and (type(get.module) == "table") then versioning.add_one_i18n("", get.subI18N, get.module) -- Add with previews an i18n translations table t = t .. viewer.ta("#i18n", #get.i18n) end end -- local flag_of_country = viewer.form9user("flag_of_country") -- "fails to debug on 20170424 Rical". (This work fine for many other cases.) bind main_module.i18n --[[ if get.isI18N then t = t .. "\n*" .. viewer.ta("get.title", get.title) -- .. viewer.ta("library", get.module) t = t .. viewer.ta("get.versionName", get.versionName) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("get.isLibrary", get.isLibrary) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("get.i18n", get.i18n) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("get.viewI18N", get.viewI18N) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) --]] return t end -- t = versioning.bind_i18n_translations(main_versions, loaded_pack) function versioning.bind_libraries_modules_translations(main_p, vers_test) -- Bind central libraries, modules, and their i18n translations local librariesList = versioning.librariesList -- Actual binding process -- Normalize recursiveLevel for any further process. local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, modes.recursiveLimit) versioning.main_i18n = versioning.main_i18n or {} -- bd : bind_sub_modules from main to sub, then compute all subI18N, then in reverse order addi18n from subI18N.i18n as .sub_i18n -- bd : versioning.init, bind_libraries_modules_translations, bind_central_libraries, bind_sub_modules, bind_i18n_translations, -- bd : get_one_module_or_library, bind_central_modules_report versioning.bind_central_libraries(librariesList, opt) -- Bind translatable libraries before bind modules and versions. if type(translate) == "table" then translate.main_i18n = versioning.main_i18n end -- Same pointers insure later same contents. versioning.bind_sub_modules(main_p, vers_test) -- -- Bind all modules and sub-modules versions, without their translations -- Bind all i18n translations from libraries, modules and their /I18N translations sub-modules versioning.bind_i18n_translations(main_p, package.loaded, opt) -- Bind all modules i18n translations. local t = "\n* <b>versioning.bind_libraries_modules_translations()</b>" for i, get in pairs(versioning.loaded_modules_and_libraries) do -- if (type(get.subI18N) == "string") and viewer.is_in(get.subI18N, "/I18N") then local get, module = versioning.get_one_module_or_library(get.subI18N) local NAME = get.NAME local object = get.module get.is_binded_in = "xx" -- if (type(package.loaded[NAME]) == object) then _G[NAME] = nil end if (type(_G[NAME]) == object) then options.is_binded_in = "_G" end if (type(package.loaded[NAME]) == object) then options.is_binded_in = "LD" end --[ [ if get.isI18N then t = t .. "\n*" .. viewer.ta("get.title", get.title) -- .. viewer.ta("library", get.module) t = t .. viewer.ta("get.versionName", get.versionName) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("get.isLibrary", get.isLibrary) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("get.i18n", get.i18n) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("get.viewI18N", get.viewI18N) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) t = t .. viewer.ta("get.is_binded_in", get.is_binded_in) -- .. viewer.ta("name", get.libraryName) -- .. viewer.ta("name_I18N", name_I18N) --] ] -- end end --[[ if get.isI18N then local NAME = options.NAME options.is_binded_in = "xx" if (type(package.loaded[NAME]) == object) then _G[NAME] = nil end if (type(_G[NAME]) == object) then options.is_binded_in = "_G" end if (type(package.loaded[NAME]) == object) then options.is_binded_in = "LD" end --]] -- bd : bind_sub_modules from main to sub, then compute all subI18N, then in reverse order addi18n from subI18N.i18n as .sub_i18n -- bd : versioning.init, bind_libraries_modules_translations, bind_central_libraries, bind_sub_modules, bind_i18n_translations, -- bd : get_one_module_or_library, bind_central_modules_report local main_versions if type(versioning.main_module) == "table" and type(versioning.main_versions) == "table" then main_versions = versioning.main_versions or { versionName = "versionName", versionNumber = "0.0", } versioning.report_main_short = main_versions.versionName .. " " .. main_versions.versionNumber versioning.report_main_discreet = viewer.discreetColor( versioning.report_main_short ) versioning.report_REVISIONTIMESTAMP = mw.getCurrentFrame():preprocess( "{{REVISIONTIMESTAMP}}" ) versioning.report_actual_versions = (versioning.report_main_discreet or "versioning.report_main_discreet") -- .. versioning.report_REVISIONTIMESTAMP .. " " else versioning.report_main_short = "versioning.report_main_short is missing." versioning.report_main_discreet = "versioning.report_main_discreet is missing." versioning.report_REVISIONTIMESTAMP = "versioning.report_REVISIONTIMESTAMP is missing." versioning.report_actual_versions = "versioning.report_actual_versions is missing." end -- bind_is_in if type(translate) == "table" then translate.main_i18n = versioning.main_i18n end -- Same pointers insure later same contents. -- initialize or change the wiki, the user and the page languages and their tables translate.init_wiki_user_page_lang(wiki_lang, user_lang, page_lang) return t, librariesList end -- t, librariesList = function versioning.bind_libraries_modules_translations(main_p, vers_test) function versioning.add_module_in_loaded_pack(tab, name, elem) -- Add an element to a table, with an index to permit later to sort the table in the insert order if not (type(tab) == "table") then tab = {} end if (type(tab) == "table") and (type(name) == "string") and (type(elem) == "table") then tab[name] = elem elem.elem_index_order = #tab -- order of insert end return tab end -- function versioning.add_module_in_loaded_pack(tab, name, elem) -- for loaded_descriptors and other function versioning.sort_table_in_insert_order(tab) -- Sort a table in the insert order of its elements, previously adapted if not (type(tab) == "table") then tab = {} end local tab_to_sort = mw.clone(tab) or {} table.sort(tab_to_sort, function (a, b) -- in recording order return ( a.elem_index_order < b.elem_index_order ) end ) return tab_to_sort end -- function versioning.sort_table_in_insert_order(tab) function versioning.tab_elem_report(tab, key) -- simple text report of versions elements local mode = mode or 1 local t = "" if (type(tab) == "table") and (type(key) == "number") then for i, elem in ipairs(tab) do t = t .. "\n* " .. viewer.ta("i", i) .. viewer.ta("title", elem.title) t = t .. viewer.ta("versionName", elem.versionName) .. viewer.ta("versionNumber", elem.versionNumber) t = t .. viewer.ta("versionDate", elem.versionDate) .. viewer.ta("i18n_varstabs", elem.i18n_varstabs) end end if (type(tab) == "table") and (type(key) == "string") then for k, elem in pairs(tab) do if not tonumber(key) then t = t .. "\n* " .. viewer.ta(key, k) t = t .. viewer.ta("versionName", elem.versionName) .. viewer.ta("versionNumber", elem.versionNumber) t = t .. viewer.ta("versionDate", elem.versionDate) .. viewer.ta("i18n_varstabs", elem.i18n_varstabs) end end end return t end -- function versioning.tab_elem_report(tab, key) function versioning.version_warning_normal_list(d) -- From alternatives forms version, title, alias, warning, normal local d = d.versions or versioning.versions or {} -- descriptor of submodule -- example of d.alternatives = "Central,CA,Central1,Central3" if type(d.alternates) == "string" then d.alternates = mw.text.trim(d.alternates) end if not d.alternates then d.alternates = "" ; return d end local altern_tab = mw.text.split(d.alternates, ";", true) local version, alias, normal for v, altern in ipairs(altern_tab) do altern = mw.text.trim(altern) if v == 1 and viewer.is_in(altern, d.selector) then normal = altern ; version = altern end if v == 2 and viewer.is_in(altern, d.selector) then normal = altern ; version = altern end if v > 2 and viewer.is_in(altern, d.selector) then version = altern end end if version then d.version = string.gsub(version, versioning.ModuleNS, "") -- version without Module: d.title = versioning.ModuleNS .. d.version d.normal = normal d.normal_I18N = versioning.ModuleNS .. normal .. "/I18N" d.normal_I18N = string.gsub(d.normal_I18N, "/I18N/I18N", "/I18N") d.version_I18N = versioning.ModuleNS .. version .. "/I18N" d.version_I18N = string.gsub(d.version_I18N, "/I18N/I18N", "/I18N") d.pagename = alias if d.normal and not viewer.is_in(d.normal, d.norm or " ") then d.norm = (d.norm or " ") .. " " .. d.normal .. " " end if d.version and not viewer.is_in(d.version, d.list or " ") then d.list = (d.list or " ") .. " " .. d.version .. " " end if d.normal_I18N and package.loaded[d.normal_I18N] and not viewer.is_in(d.normal_I18N, d.list or " ") then d.list = (d.list or " ") .. " " .. d.normal_I18N .. " " end if d.version_I18N and package.loaded[d.version_I18N] and not viewer.is_in(d.version_I18N, d.list or " ") then d.list = (d.list or " ") .. " " .. d.version_I18N .. " " end -- d.missing = d.missing .. " " .. d.version .. " " -- managed elsewhere -- d.excess = d.excess .. " " .. d.version .. " " -- managed elsewhere end return d end -- function versioning.version_warning_normal_list(d) -- Detect the task T122752 : #invoke seems do not record the module local debugT122752_task_state = "triage" -- default value, at Require() time local debugT122752_gettitle = mw.getCurrentFrame():getTitle() -- get the mainmodule title if type(package.loaded[debugT122752_gettitle]) == "table" -- get task state at Require() time then debugT122752_task_state = "OK" else debugT122752_task_state = "triage" end -- Detect T122752 : #invoke seems do not record the module function versioning.invoke_record_module_debug_T122752() -- Detect T122752 : #invoke seems do not record the module local gettitle = mw.getCurrentFrame():getTitle() -- get the mainmodule title if debugT122752_task_state then return end if type(package.loaded[gettitle]) == "table" then debugT122752_task_state = "OK" else debugT122752_task_state = "triage" end end function versioning.invoke_record_module_correct_T122752(t) -- Bypass the bug T122752 : #invoke do not record the main module in package.loaded -- When the parser build a wiki page, it do {{#invoke:MainModule | ... "}} -- Because the bug T122752 : #invoke do not record the main module in package.loaded -- but the MainModule is active and require("Module:Central") -- Then versioning.invoke_record_module_correct_T122752() verify versioning.debugT122752_status -- before versioning.bind_sub_modules() bind all modules and versions, and their translations local t = t or "" local gettitle = mw.getCurrentFrame():getTitle() -- get the mainmodule title versioning.main_gettitle = gettitle local module if type(package.loaded[gettitle]) == "table" then versioning.debugT122752_status = "Resolved" else versioning.debugT122752_status = "getmodule" -- "Open" module = versioning.pcallRequire(gettitle) -- require() must not fail and block the page if the module do not exists. if module then -- Alert? by a warning in edit mode: the bug is already fixed. versioning.debugT122752_main_module = module versioning.debugT122752_status = "module found" -- "Open" -- t = t .. viewer.form9user("versioning_try_waits_debug_T122752", tostring(gettitle) ) .. "#invoke T122752 replaced by pcallRequire." t = t .. "\n* invoke_record_module_correct_T122752: repairs the main <b>" .. tostring(gettitle) .. "</b>. See: [https://phabricator.wikimedia.org/T122752 T122752 #invoke seems do not record the module] " if type(package.loaded[gettitle]) == "table" then versioning.debugT122752_status = "get corrected Resolved" end else versioning.debugT122752_status = "module missing" -- "Open" -- Main error, there is no main module. end end versioning.debugT122752_status = versioning.debugT122752_status or "nil status" -- "Open" return t end -- function versioning.invoke_record_module_correct_T122752(t) -- Bypass the bug T122752 : #invoke do not record the main module in package.loaded function versioning.deprecatedFunction(old, new, kind) -- Deprecated function. Replace it in the module. local res = "" -- if type(translate.user_lang) == "string" then res = events.add_err("versioning_add_deprecated_err", old, new, versioning.main_versions.versionName) events.add_cat("modes_no_source_arguments_cat") -- end versioning.deprecatedFunctionGroup = versioning.deprecatedFunctionGroup or {} table.insert(versioning.deprecatedFunctionGroup, { old, new, versioning.main_versions.versionName, (kind or "actual"), } ) return res end function versioning.deprecatedFunction_test(t) -- Tests of deprecated function. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "" t = t .. "\n* Test <b>versioning.deprecatedFunction_tests</b> :" -- deprec -- versioning.deprecatedFunction("tools.option", "modes.option") local func, argmt, old, new = modes.option, "docview", "tools.option", "modes.option" local ifyes, used, available_options = func(argmt) t = t .. "\n\n* Test 1 : " .. viewer.ta("old", old) .. viewer.ta("new", new) .. viewer.ta("ifyes", ifyes) .. viewer.ta("available_options", available_options) -- -- versioning.deprecatedFunction("tools.luaTabStruc", "luaTable.structure") local func, argmt, old, new = luaTable.structure, {}, "tools.luaTabStruc", "luaTable.structure" local test = func(argmt) t = t .. "\n\n* Test 2 : " .. viewer.ta("old", old) .. viewer.ta("new", new) .. viewer.ta("test", test) versioning.deprecatedFunctionGroup = versioning.deprecatedFunctionGroup or {} -- table.insert(versioning.deprecatedFunctionGroup, { -- old, new, versioning.main_versions.versionName, "test") -- } ) local version = versioning.main_versions.versionName -- Save global configuration before eventual changes. local t = t or "\n* <b>Tests of main central modules:</b> :" local tabView = { testGroup = { -- versioning.deprecatedFunctionGroup { "versioning.bind_sub_modules", "versioning.bind_main_module", version, "test" }, -- { "tools.luaTabStruc", "luaTable.structure", version, "test" }, { "p.form_result", "modes.form_result", version, "test" }, { "tools.option", "modes.option", version, "test" }, { "tools.closeCatsErrs", "events.close", version, "test" }, { "tools.initCatsErrs", "events.memorize", version, "test" }, { "versioning.bind_sub_modules", "versioning.bind_main_module", version, "test" }, { "tools.luaTabStruc", "luaTable.structure", version, "test" }, { "versioning.versionsmanagement_test", "versioning.versions_management_test", version, "actual", versioning.versionsmanagement_test }, headers = "old; new; versionName; kind", } } function tabView.tableView_form_one_case(case) -- Generally to define: Convert a case from testGroup to rowGroup. --[[ Todo later: too complex. if type(case[5]) == "function" then return pcall(case[5], ...) --]] return case end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. local t = "\n* Test <b>versioning.deprecatedFunction()</b> :" -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function versioning.deprecatedFunction_test(t) function versioning.all_versions_text(all_versions) -- DEBUG all_versions = all_versions or versioning.all_versions if type(all_versions) == "string" then return all_versions end -- if type(all_versions) == "string" then all_versions = { all_versions } end if type(all_versions) == "table" then return table.concat(all_versions, " >> ") else return "" end end function versioning.sort_central_modules_report(t) -- Sorted list of central modules and libraries -- versioning_sort_central_modules_title = "versioning.sort_central_modules_report() Sorted list of central modules and libraries.", -- versioning_sort_central_modules_headers = "Title; Version; Date; Translations / Languages", local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "\n* <b>versioning.sort_central_modules_report()</b> -- Sorted list of central modules and libraries." local loaded_sorted = {} for key, elem in pairs(versioning.loaded_modules_and_libraries) do -- if elem.isModule then elem.pagename = "Module:" .. elem.versionName end -- Locate translations example in Module:Central/I18N -- if elem.isLibrary then elem.pagename = "Library:" .. elem.versionName end -- Locate translations example in Module:Library/versioning/I18N if elem.hasi18n and elem.isLibrary then table.insert(loaded_sorted, elem) end if elem.hasi18n and elem.isModule then table.insert(loaded_sorted, elem) end if versioning.loaded_modules_and_libraries[elem.subI18N] then elem.has_I18N = true end end -- loaded_modules_and_libraries local loaded_pack, loaded_txt, modu = versioning.loaded_modules_and_libraries -- loaded_sorted = versioning.loaded_modules_and_libraries versioning.loaded_modules_track = "\n* versioning.loaded_modules_track : " .. viewer.ta("#versioning.loaded_modules_and_libraries", #versioning.loaded_modules_and_libraries) -- t = t .. "\n* List versioning.actual_modules : " .. versioning.actual_modules t = t .. versioning.loaded_modules_track table.sort(versioning.loaded_modules_and_libraries, function (a, b) return ( a.pagename < b.pagename ) end ) local tabView = { -- Adapt all options for all uses, before all other adaptations. testGroup = versioning.loaded_modules_and_libraries, headers = "versioning_sort_central_modules_headers", headers_class = "wikitable alternative center sortable", -- form_elem_detail = "this + %2/%3 T/L, ", form_elem_detail = "versioning_sort_central_modules_counts", -- "this + %2/%3 T/L, " } function tabView.tableView_form_one_case(elem) -- Generally to define: Convert a case from testGroup to rowGroup. local subI18N = "" if elem.i18n then -- elem.i18n local vers18 = elem.versionName --; if not elem.isI18N then vers18 = "" end if elem.isModule then elem.pagename = "Module:" .. elem.versionName end -- Locate translations example in Module:Central/I18N if elem.isLibrary then elem.pagename = "Library:" .. elem.versionName end -- Locate translations example in Module:Library/versioning/I18N -- local t ... = luaTable.formSubCounts(tabname, tablebase, text_form) -- elem.counts = luaTable.formSubCounts(elem.i18nRoot .. ".i18n", "this + %2/%3 T/L, ") -- versioning_sort_central_modules_counts elem.counts = luaTable.formSubCounts(elem.i18nRoot .. ".i18n", tabView.form_elem_detail) -- versioning_sort_central_modules_counts if elem.has_I18N then elem.counts = elem.counts .. "<br>+ i18n in: <b>" .. elem.viewI18N .. "</b>" end -- version_I18N -- luaTable.formSubCounts("versioning.main_i18n", versioning.main_i18n, ", (all = %2/%3 T/L)") if elem.versionName and elem.pagename then -- t2 = viewer.form9user("<br>* alias <b>%1</b> = <b>%2</b>, version = <b>%3</b>, date = <b>%4</b>", -- elem.pagename, elem.versionName, elem.shortVersion, elem.versionDate) end end elem.is_binded_in = versioning.binded_in(elem.versionName, elem.module) return { (elem.pagename or ""), (elem.viewI18N or ""), ( elem.versionDate .. "<br>" .. elem.shortVersion .. " in:" .. elem.is_binded_in ), elem.counts } -- return { (elem.pagename or ""), (elem.versionName or ""), (elem.versionDate .. "<br>" .. elem.shortVersion), elem.counts } end local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function versioning.sort_central_modules_report(t) -- Sorted list of central modules and libraries function versioning.tasks_changes_report(t) -- The tests function uses mode and options to include edit or tests. local res = t or "" -- res = res .. "\n: Documentation of Module:Central: [[s:fr:Rical/Central modules|wikisource:Central modules]]." -- res = res .. "\n: Development of Module:Central: [[s:fr:Module:Central|wikisource:Module:Central]]." -- res = res .. "\n: Example of use: [[s:fr:Utilisateur:Rical/Victor_Hugo|wikisource:Rical/Victor_Hugo]]." -- res = res .. versioning.tasks_changes_report_short res = res .. "\n* List of blocking tasks: " .. versioning.tasks_changes_report_normal() return res -- versioning.tasks_changes_report_normal -- versioning_tasks_changes_report end -- function versioning.tasks_changes_report(t) function versioning.versioning_tasks_report(t, short) -- List states of known bugs or tasks. -- versioning.versioning_tasks_report() États des tâches connues local t = t or "\n* <b>versioning.versioning_tasks_report()</b> List states of known bugs or tasks, to support the tasks management from inside versions." versioning.debugT53660isEdited = mw.title.getCurrentTitle().isEdited or "Open" -- Detect the status of the task : T68051_status. versioning.debugT68051_status = mw.uri.new().userLanguage if versioning.debugT68051_status then versioning.debugT68051_status = "Resolved" else versioning.debugT68051_status = "args" end -- { 18, "Important", "T68051", 1, "Open", "Central modules need the user language to display errors and category names", "user language for errors", }, -- Detect the status of the task : T133498_status. local mwtitle = mw.title.getCurrentTitle() local url = tostring(mwtitle:canonicalUrl( )) -- versioning.debugT133498_status = mw.uri.canonicalUrl() -- mw.uri.canonicalUrl local title_object = mw.title.new(url) -- .itemid -- mw.uri.canonicalUrl if title_object then versioning.debugT133498_status = title_object.itemid end -- mw.uri.canonicalUrl if versioning.debugT133498_status then versioning.debugT133498_status = "Resolved" else versioning.debugT133498_status = "Open" end -- Any title with datas in wikibase give its item.id to any module. Probably across mw.title.new().itemid -- headers local tabView = { testGroup = { -- case.sort = case[1] ; case.importance = case[2] ; case.task = case[3] ; case.state = case[4] -- case.state = case[5] ; case.title = case[6] ; case.shortext = case[7] -- datas: sort, importance, taskNumber, detect, state, title, shortext. -- Importance: Important { 10, "Important", "20170130", "T20170130", 0, "ToCreate", "Begin to use central modules in 10 wikis", "Begin to use central", }, -- T20170130 : Not a one man task, continue until 10 helpers, 10 projects, 10 languages and 10 modules use central modules. { 11, "Important", "20170325", "T20170325", 0, "ToCreate", "Centralize and share central datas about central modules", "share central datas", }, -- T20170325 : Centralize datas as mediawiki versions installations in each lang-project, uses of central modules (helpers, projects, languages ...). { 12, "Important", "20170320", "T135845", 0, "Assigned", "Convert any module as central or centralisable", "Convert as central", }, { 14, "Important", "20170320", "T53660", 0, "Open", "Detect the edit state for modules which help users and helpers", "edit state", }, { 16, "Important", "20170320", "T4085", 0, "Assigned", "Add a {{USERLANGUAGE}}/{{USERLANG}} magic word", "USERLANGUAGE", }, { 18, "Important", "20170320", "T68051", 1, "Open", "Central modules need the user language to display errors and category names", "user language for errors", }, { 20, "Important", "20170320", "T142906", 1, "Stalled", "Data access in user language doesn't obey the uselang get parameter", "User language not OK", }, --[[ T142906 Data access in user language do not obey the uselang get parameter / Apparently We use the former as an optimization in Scribunto_LuaWikibaseLibrary::getLanguage and Scribunto_LuaWikibaseEntityLibrary::getLanguage to only split the parser cache when actually needed. --]] { 21, "Important", "20170320", "T85461", 0, "Gerrit", "Lua error: too many language codes requested", "too many language", }, -- T85461 https://meta.wikimedia.org/wiki/Module:Assemble_multilingual_message -- T85461 https://meta.wikimedia.org/w/index.php?title=Module:Assemble_multilingual_message&action=edit#mw-ce-l46 { 22, "Important", "20170309", "T159322", 0, "Open", "Central categories and alerts for central modules", "Central categories/alerts", }, -- T159322 : Does the community agree to implement central categories and alerts for central modules? -- T159322 : This enhances the efficiency of the detection and the correction of errors, in some ways: { 24, "Important", "20160522", "T85419", 0, "Open", "User groups should be exposed to Scribunto", "user groups", }, -- T85419: to adapt errors and warning for administrators or modules coders { 26, "Important", "20161026", "T142093", 0, "Open", "Decide how to do usage tracking for strings used to lookup entities (page titles, external ids, …)", "how to link entities/titles", }, { 28, "Important", "20170211", "T20170211", 1, "ToCreate", "In mw.language.fetchLanguageNames( 'fr' ) some languages names are not in French", "French languages names", }, { 30, "Important", "20170403", "T20161220", 0, "Assigned", "To test: Central modules need the page language to display errors categories and datas for helpers", "user language getContentLanguage()", }, -- T20161220 : ToDo: test: local getContentLanguage = mw.language.getContentLanguage().code -- default wiki_lang { 32, "Important", "20170320", "T147618", 0, "Open", "Localize one or more major WMF software products related to new editor retention to hu.wikipedia", "Localize new editor retention", }, { 34, "Important", "20170121", "T122752", 1, "Open", "#invoke do not record the main module in package.loaded", "invoke# main not loaded", }, -- T122752: 20161202 18:25 See example https://fr.wikisource.org/wiki/Module:Phab.TestpackG : detect "in " "_G" or package.loaded -- T122752: 20160102 22:46 See example https://fr.wikisource.org/wiki/Module:TestRequire -- T122752: To locate and to debug the bug T122752 in time, Rical lists here the versions of fr.wikisource.org/wiki/Module:ControlArgs1 -- T122752: Oldest research of "Replace the missing of record of the module by" : ModuleControlArgs 6 tools...lua 2016-01-16 -- T122752: (actu | diff) 2015-11-25T11:43:11 Rical (discussion | contributions | bloquer) . . (261 314 octets) (-3 519) . . (The versions management seems OK) (annuler) -- T122752: (actu | diff) 2015-11-28T09:55:37 Rical (discussion | contributions | bloquer) . . (267 472 octets) (+5 809) . . (find_main_module) -- T122752: (actu | diff) 2015-12-01T14:18:22 Rical (discussion | contributions | bloquer) . . (268 956 octets) (+1 614) . . (find_main_module OK ?) -- T122752: (actu | diff) 2016-01-18T02:09:45 Rical (discussion | contributions | bloquer) . . (319 599 octets) (+10 183) . . (translate library.i18n first) -- T122752: 2016-01-02 phabricator: T122752 Rical created this task. Sat, Jan 2, 2016-01-02 23:08 { 36, "Important", "20170323", "T85461", 0, "Open", "Lua error: too many language codes requested", "many language codes", }, -- -- Importance: Central { 40, "Central", "20170301", "T121470", 0, "Open", "Central Global Repository for Templates, Lua modules, and Gadgets", "central repository", }, { 42, "Central", "20170121", "T52329", 0, "Stalled", "We need a common repository for Scribunto modules and templates", "common repository", }, { 44, "Central", "20160523", "T41610", 0, "Open", "Scribunto should support global module invocations", "global invocations", }, { 46, "Central", "20170301", "T20170301", 0, "ToCreate", "Phabricator tasks states for easier versions management of modules", "Phab tasks states", }, -- datas to get for each query: Task number, title, state, priority, Authored By and date, Last event date, number of subscribers, Assigned. { 48, "Central", "20170225", "T20170225", 0, "ToCreate", "? Report Mediawiki changes for the versions management, and use {{subst:}}", "Mediawiki changes", }, -- T20170225: The gerrit team needs the date of a bug and the dates of mw install in each wiki to debug mw. -- T20170225: We could detect, record and report all date-time changes of mediawiki, for some weeks. -- T20170225: We could use {{subst:}} in 2 ways. See https://www.mediawiki.org/wiki/Manual:Substitution -- T20170225: duplicate of T121470: Central Global Repository for Templates, Lua modules, and Gadgets. { 50, "Central", "20170314", "T1238", 0, "Close", "Central Code Repository for code used on wikis (Templates, Lua modules, Gadgets)", "Code Repository", }, -- -- Importance: Other { 66, "Other", "20170526", "T104109", 0, "Close", "No syntax highlight for large JavaScript/CSS/Lua/API pages", "loadTemplateData", }, --[[ T104109: Have you the same bug? Where could this effect coming from? - My user:vector.css or common.css? But I have them only in fr.wikisource.org and not in vi.wikipedia.org - A step to prepare T121470 Central Global Repository? - A step to prepare T156048 syntax highlighting? - A change in my Module:Central itself, which forms many viewers, always inside <div>...</div> ? But I edit with the edit-panel first, up in the page, and the result of the module below, later. Also these "div" tags are, in the page, in other tags which protect them to interfere. - A mix of these origins? Small or large modules edit panels lost their syntax highlighting and line numbers. Tech News: 2017-15 : replacement of HTML_Tidy, Extension:ParserMigration, see https://meta.wikimedia.org/wiki/Tech/News/2017/15 T104109 --]] { 68, "Other", "20170407", "T20170407", 0, "ToCreate?", "When edit, the modification of Module:Central-s-fr do not display lines numbers", "Edit module misses lines numbers", }, { 70, "Other", "20170308", "T63958", 0, "Open", "Use existing $dateFormats to format dates on Wikidata", "Use $dateFormats on Wikidata", }, { 72, "Other", "20160520", "T85412", 0, "Open", "The formatPropertyValues needs an option to format data from date-time, angle or geographic coordinates", "format date-time", }, { 74, "Other", "20170228", "T156048", 0, "Open", "Add syntax highlighting to wiki diff of source code pages (like Gerrit)", "syntax highlighting", }, { 76, "Other", "20170313", "T107119", 0, "Open", "Provide a Lua method mw.loadTemplateData()", "loadTemplateData", }, { 78, "Other", "20170213", "T20170213", 0, "ToCreate", "Some languages have not French names in French language", "languages in stranger names", }, { 80, "Other", "20151215", "T20151215", 0, "ToCreate", "In some cases the box of the dropbox is not displayed", "dropbox not displayed", }, -- T20151215: .. "\n------ " -- This code interact with DropBox and debug the task T20151215 2016-11-13 17:57. -- T20151215: if there is "\n------ " before editDocBox and then the editDocBox "div" is only a bar of 1 em hight, and its content is after the "div". Rical 2016-10-24 08:15. -- T20151215: Original code from fr.wikisource : "{{Boîte déroulante/début|titre=" .. title .. "|alignT=" .. alignT .. "}}" .. content .. "{{Boîte déroulante/fin}}" { 82, "Other", "20160616", "T20160616", 0, "ToCreate", "? Add module and library types in scribunto ?", "module and library types?", }, -- T20160616: get.isLibrary = ( true ) -- true if the object is a library -- -- Importance: Obsolete: Do not create, these functions come from mw... library. { 90, "Obsolete", "20161022", "T20161022", 0, "ToCreate", "? Scribunto functions are out of package.loaded", "Lua functions out of package.loaded", }, -- T20161022: -- Found in Lua_reference_manual but not in Module:Central-s-fr : -- T20161022: -- 2016-10-22 15:45 : versioning.list_all_G_and_loaded() : Variables in _G global space without libraries and modules in packageloaded. , xpcall = function , tostring = function , _VERSION = Lua 5.1 , unpack = function , require = function , pairs = function , next = function , assert = function , ipairs = function , rawequal = function , getmetatable = function , rawset = function , pcall = function , type = function , selector = function , rawget = function , tonumber = function , error = function , setmetatable = function { 91, "Obsolete", "20170324", "T133498", 1, "Declined", "Detect and extend known title <-> entity links in a semi-automatic way", "semi-automatic wikidata itemid", }, { 92, "Obsolete", "20161128", "T151715", 0, "Invalid", 'string.gsub( s, "%%1", repl) fails as "invalid capture index"', 'string.gsub(s,"%%1",r) fails', }, { 93, "Obsolete", "20170110", "T154769", 0, "Invalid", 'When "Erreur Lua : attempt to call a string value", where?', "Error Lua call a string where?", }, -- T154769: Rical 2017-01-08 My main mistake was to write xpcall() where pcall() is right. -- T154769: Tests are there https://fr.wikisource.org/wiki/Module:Phab.T154769.Test -- T154769: versioning.antiCrash() preserve pages against residual errors which can crash pages. { 94, "Obsolete", "20170202", "T155898", 0, "Invalid", "Preview change from external local editors", "Change from local", }, -- T155898: OK, I will continue to search in JEdit plugins. Perhaps I will ask them an adapted solution. { 95, "Obsolete", "20160424", "T67507", 0, "Resolved", "It should be possible to get entity id from page title", "entity id from title", }, { 96, "Obsolete", "20160524", "T119978", 0, "Invalid", "Get name and record-time of all modules to better manage their versions", "own module name", }, { 98, "Obsolete", "20160813", "T75460", 0, "Resolved", "[Story] Make Lua functions default to the user's language on multilingual wikis", "multilingual wikis", }, { 99, "Obsolete", "20160524", "T119978", 0, "Invalid", "Get name and record-time of all modules to better manage their versions", "own module name", }, }, title_memo = "versioning_tasks_report_title", -- "versioning.versioning_tasks_report() States of known tasks", headers = "versioning_tasks_report_headers", -- "Importance; Task; State; Title; In short", } tabView.headers = "versioning_tasks_report_headers" -- tabView.headers = "Importance; Task; State; Title; In short" -- tabView.headers = "Importancia; Tarea; Estado; Título; En breve" -- tabView.headers = "Importance; Tâche; Etat; Titre; En bref" function tabView.tableView_form_one_case(case) -- Generally to define: Convert a case from testGroup to rowGroup. case.sort = case[1] ; case.importance = case[2] ; case.date = case[3] ; case.task = case[4] ; case.detect = case[5] case.state = case[6] ; case.title = case[7] ; case.shortext = case[8] case.task = "[[phab:" .. case.task .. "|" .. case.task .. "]]" local usual = "discreet" if viewer.is_in(case.state, "ToCreate, Declined, Invalid, ") then usual = "discreet" elseif viewer.is_in(case.state, "Open, Stalled, Assigned, Gerrit") then usual = "add" elseif viewer.is_in(case.state, "Resolved") then usual = "discreet" else usual = "discreet" end -- All states : ToCreate, Open, Stalled, Assigned, Resolved, Declined, Invalid, Gerrit case.title = viewer.usualColor(case.title, usual) if case.detect == 1 then case.title = case.title .. " - ( detected state )" end -- headers = "Importance; Task; State; Title; In short" local importance = case.importance .. viewer.discreetColor(" on " .. case.date) return { importance , case.task, case.state, case.title, case.shortext } end -- function viewer.errorColor( -- See viewer.usual_colors : -- { ["add"] = "blue", ["delete"] = "#C0C000" = yellow, ["discreet"] = "#B0B0B0" = light grey, ["error"] = "red", -- ["invoke"] = "#804020" = brown, ["normal"] = "black", ["warning"] = "#804020" = brown, ["wikidata"] = "green", } t = t .. "<br>Used colors: " .. viewer.ta("ToCreate, Stalled, Declined, Invalid", viewer.usualColor("task to create or activate", "discreet") ) .. viewer.ta("Resolved", viewer.usualColor("task already Resolved", "discreet") ) .. viewer.ta("Open, Stalled, Assigned, Gerrit", viewer.usualColor("task in way to Resolved", "add") ) .. viewer.ta("Other", viewer.usualColor("other tasks", "discreet") ) -- local tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function versioning.versioning_tasks_report(t, short) -- function versioning.init(frame, mode_name, args_known, options_for_modes, itemid) function versioning.init(frame, Central_version) -- Initializes translations, bind_libraries, bind_sub_modules, get arguments, modes, options. -- Imports arguments from wikidata, module and template with increasing priorities. local res, t = "", "" translate.track_i18n("versioning.init:frame") versioning.main_i18n_complete = false -- Mask any views to avoid failures until enough init. -- translate.Central_x_y = p.Central_x_y -- To adapt the version of Module:Central in any translated text. Central_version = Central_version or translate.Module_Central_version -- or p.Module_Central_version versioning.bind_libraries_modules_translations() -- Bind central libraries, modules, and their i18n translations translate.track_i18n("versioning.init:bind_modules_method") versioning.main_i18n_complete = true -- Unmask all views after enough init. res = res .. versioning.detect_mediawiki_changes() translate.track_i18n("versioning.init:detect_mediawiki_changes") return res end -- function versioning.init(frame, Central_version) function versioning.versionsmanagement_test(t) -- Deprecated alias function versioning.deprecatedFunction("versioning.versionsmanagement_test", "versioning.versions_management_test", t) return versioning.versions_management_test(t) end function versioning.versions_management_test(t) -- Test : List all loaded modules versioning_bind_modules_tests_title local memo = events.save_configs() -- Save global configuration before eventual changes. local t = (t or "") .. "\n* <b>versioning.versions_management_test</b> : The selector = <b> Box3, Group, Item1 </b> means: check these modules versions among those available." t = t .. "<br>" .. luaTable.formSubCounts("versioning.i18n") local loaded_tests = { -- loaded_tests -- Cases to look for the main module { key = "Box", versionName = "Box", versionDate = "2015-12-02 02:02", request = "normal modules", comment = 'normal module for Box, with alias like : <code>local Box = require("Box")</code>', i18n = { en = { a = "a" } }, sought = "Box", known = "Box", loaded_list = ";Box;", }, -- { key = "Box/I18N", versionName = "Box", versionDate = "2016-05-07 18:36", request = "normal with /I18N", comment = "I18N translations for Box", i18n = { en = { a = "a" } }, sought = "Box", known = "Box", loaded_list = ";Box;Box/I18N;", }, -- { key = "Box3", versionName = "Box2", versionDate = "2016-05-07 11:11", request = "normal replace known alternate", comment = "alternate version module for Box", i18n = { en = { a = "a" } }, sought = "Box2", known = "Box;Box2", loaded_list = ";Box;Box/I18N;Box2;Box2/I18N;", }, -- { key = "Box2/I18N", versionName = "Box2", versionDate = "2016-05-07 19:19", request = "missing actual module", comment = "I18N translations without basic module. Form an alert.", i18n = { en = { a = "a" } }, sought = "Box", known = "Box2;Box3", loaded_list = ";Box3;Box3/I18N;Box2;Box2/I18N;", }, -- Cases to look for sub-modules -- { key = "Group", versionName = "Box", I18N = "Group/I18N", request = "normal sub-module", comment = "normal module for Group", i18n = { en = { a = "a" } }, sought = "Group", known = "Group", loaded_list = ";Group;Group/I18N;", }, -- { key = "Group4", versionName = "Box", versionDate = "2015-12-11 11:11", request = "unknown sought version", comment = "Mask this to test missing sought version", i18n = { en = { a = "a" } }, sought = "Box;Group", known = "Box", loaded_list = ";Box;", }, -- { key = "Group/I18N", versionName = "Box", versionDate = "2016-05-07 22:2", request = "sub-module not exists", comment = "I18N translations for the normal module Group", i18n = { en = { a = "a" } }, sought = "Box;Group", known = "Box * Group", loaded_list = ";Box;", }, -- -- Cases to look for /I18N sub-modules { key = "Group2", versionName = "Box3", versionDate = "2015-12-22 22:2", versionDate = "2016-05-07 05:05", request = "normal sub-module with normal /18N", comment = "normal alternate sub-module Group for Group2", i18n = { en = { a = "a" } }, sought = "Box;Group2", known = "Box;Box2 * Group;Group2", loaded_list = ";Group;Group/I18N;Group2;Group2/I18N;Box;Box/I18N;Box2;Box2/I18N;", }, -- { key = "Group2", versionName = "Box3", versionDate = "2015-12-22 22:2", versionDate = "2016-05-07 05:05", request = "unknown module for /18N sub-module", comment = "normal alternate sub-module Group for Group2", i18n = { en = { a = "a" } }, sought = "Box;Group2", known = "Box;Box2 * Group;Group2", loaded_list = ";Group;Group/I18N;Group2;Group2/I18N;Box;Box/I18N;Box2;Box2/I18N;", }, -- { key = "Group2", versionName = "Box3", versionDate = "2015-12-22 22:2", versionDate = "2016-05-07 05:05", request = "missing module Box for /18N sub-module", comment = "normal alternate sub-module Group for Group2", i18n = { en = { a = "a" } }, sought = "Box;Group2", known = "Box;Box2 * Group;Group2", loaded_list = ";Group;Group/I18N;Group2;Group2/I18N;Box/I18N;Box2;Box2/I18N;", }, -- { key = "Jocker", versionName = "Jocker", versionDate = "2015-12-21 11:33", request = "not central module, without i18n", comment = "Any module can have no i18n table.", sought = "Box", known = "Box", loaded_list = ";Box;", }, -- i18n = { en = { a = "a" } }, -- { key = "Jocker", versionName = "Jocker", versionDate = "2015-12-21 11:33", request = "unknown and not sought actual module", comment = "Any module can be outside of the central system.", i18n = { en = { a = "a" } }, sought = "Jocker.2", known = "Jocker.2", loaded_list = ";Box;", }, } local function bind_modules_test1(t, vers_test) local tt, vers = vers_test -- versioning.bind_sub_modules(main_p, vers_test) -- Bind all modules and versions local x, vers_err = versioning.versions_management_report(vers) -- Detect versions management errors and warnings after bind_sub_modules vers.sought = viewer.simpleList(vers.sought) -- local vers_sought = viewer.simpleList(vers.used) local vers_sought = ";" .. string.gsub( (vers.sought or "-s-"), ";", ",<br>" ) .. ";" -- names in column local vers_used = viewer.simpleList(vers.used) vers_used = ";" ..string.gsub( (vers_used or "-u-"), ";", ",<br>" ) .. ";" -- names in column local vers_known = ";" .. string.gsub( (vers.known or ""), ";", "; " ) .. ";" -- add spaces local vers_loaded_list = ";" .. (vers.versionName or "versionName") .. ";" .. (vers.sought or "sought") .. ";" .. (vers.known or "known") .. ";" vers_loaded_list = vers.loaded_list or vers_loaded_list or "empty loaded list" vers_loaded_list = viewer.simpleList(vers_loaded_list) vers_loaded_list = ";" .. string.gsub(vers_loaded_list, ";", "; " ) .. ";" -- add spaces local vers_results = "<b>" .. (vers.request or "vers.request") .. "</b>" .. "<br>sought: " .. (vers.sought or "") .. " in the main module: <b>" .. vers.versionName .. "</b>" .. "<br>" .. (vers_err or "") .. "<br>known: " .. (vers_known or "") .. "<br>loaded list: " .. vers_loaded_list .. "<br>comment: " .. (vers.comment or "") t = (t or "") .. viewer.Tr() .. viewer.Td(vers_sought) .. viewer.Td(vers_used) .. viewer.Td(vers_results) return t -- viewer.Td(vers.used) .. end t = t .. "\n* <b>loaded_vers</b> : Table of all loaded modules, or simulation." t = t .. "\n* Simulate existing versions: " -- local loaded_versions = "Group;Group/I18N;Group2;Box;Box/I18N;Box2/I18N;Box3;Item;Item1/I18N;Jocker" -- example local loaded_versions = ";" local loaded_vers = {} local head = mw.text.split( viewer.form9user("versioning_bind_modules_test_headers") , ';') -- versioning_bind_modules_tests_title t = t .. viewer.Th() .. viewer.Tc(head[1]) .. viewer.Tc(head[2]) .. viewer.Tc(head[4]) t = bind_modules_test1( t, nil ) t = t .. viewer.Tr() .. viewer.Tc(head[1]) .. viewer.Tc(head[2]) .. viewer.Tc(head[5]) local i = 0 for i, tst in ipairs(loaded_tests) do -- build a simili loaded_vers, from loaded_tests, for only versions management local vers_test = mw.clone(tst) -- vers_test is an empty module, only for version management. vers_test.comment = tst.comment -- .. "<br>known : " .. tst.known -- vers_test.loaded_list = "Box,Box/I18N;Box2/I18N;Box3;Group;Group/I18N;Group2;Item;Item1/I18N;Jocker" local loaded_list = ";" .. vers_test.key .. ";" .. (vers_test.versionName or "versionName") .. ";" .. (vers_test.sought or "sought") .. ";" .. (vers_test.known or "known") .. ";" vers_test.loaded_list = tst.loaded_list or viewer.simpleList(vers_test.loaded_list) -- vers_test.i18n = { en = { txt = "txt" } } -- if viewer.is_in("/I18N", vers_test.key) then vers_test.isI18N = true end loaded_vers[i] = vers_test t = bind_modules_test1( t, vers_test) -- t = t .. "<b>" .. vers_test.key .. "</b>, " end t = t .. viewer.Tr() .. viewer.Tc(head[1]) .. viewer.Tc(head[2]) .. viewer.Tc(head[5]) t = t .. viewer.Te() local t2 = "" local head = mw.text.split( viewer.form9user("versioning_sort_central_modules_headers") , ';') t2 = t2 .. "\n* The table below simulates loaded modules for behind tests cases." t2 = t2 .. viewer.Th() .. viewer.Tc(head[1]) .. viewer.Tc(head[2]) .. viewer.Tc(head[3]) .. viewer.Tc(head[4]) .. viewer.Tc(head[5]) for key, elem in pairs(loaded_tests) do t2 = t2 .. viewer.Tr() .. viewer.Td(elem.key) .. viewer.Td(elem.versionName) .. viewer.Td(elem.versionDate) .. viewer.Td( type(elem.i18n) ) .. viewer.Td(elem.comment) end t2 = t2 .. viewer.Te() t2 = t2 .. "\n* " .. viewer.ta("Number of versions simulated:", #loaded_tests) t = t .. (t2 or " ") events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function versioning.versions_management_test(t) function versioning.antiCrash_wanted_error() -- Bug to test versioning.antiCrash() versioning.antiCrash_wanted_error_text = "antiCrash_bug_text_before_BUG" local x = wanted.error.runtime -- Produces a wanted.runtime.error because these sub-tables do not exist. -- local x = "wanted.error.runtime" -- Produces a normal string. versioning.antiCrash_wanted_error_text = "antiCrash_bug_text_after_OK" return versioning.antiCrash_wanted_error_text end -- function versioning.antiCrash_wanted_error() -- Bug to test versioning.antiCrash() function versioning.antiLoop(funcname, n, func, ...) -- Limit the n-th reentrant call of any function. if true then return end -- Enhancement: search the shortest loop? local memo = events.save_configs() -- Save global configuration before eventual changes. if type(funcname) ~= "string" then funcname = "funcname" end if type(n) ~= "number" then n = 3 end if type(func) ~= "function" then n = 0 end versioning.antiLoop_memo = versioning.antiLoop_memo or {} versioning.antiLoop_memo[funcname .. "_" .. n] = {funcname, n, func, ...} versioning.antiLoop_list_t = versioning.antiLoop_list_t or "" versioning.antiLoop_list_t = versioning.antiLoop_list_t -- versioning_antiLoop_function_err = "versioning.antiLoop() error in the <b>%3</b> <b>%1()</b>, loop n = <b>%2</b>, args = ", .. "\n* antiLoop: " .. viewer.form9user("versioning_antiLoop_function_err", tostring(funcname .. "_" .. n), n, viewer.value(func), ... ) .. translate.formTestCase(tostring(funcname .. "_" .. n), n, viewer.value(func), ... ) -- versioning.antiLoop_list_t = versioning.antiLoop_list_t .. "\n* antiLoop: " .. translate.formTestCase(tostring(funcname .. "_" .. n), n, viewer.value(func), ... ) events.add_cat("modes_no_source_arguments_cat") n = n - 1 events.restore_configs(memo) -- Restore global configurations after eventual changes. if n < 1 then return end return versioning.antiLoop(funcname, n, func, ...) -- Loop only in limited n times. end -- function versioning.antiLoop(funcname, n, func, ...) function versioning.antiLoop_list(t) -- List versioning.antiLoop(). local t = t or "" t = t .. "\n* List <b>versioning.antiLoop()</b> :" if (type(versioning.antiLoop_list_t) == "string") then t = t .. versioning.antiLoop_list_t end t = t .. "<br/>" return t end -- function versioning.antiLoop_list(t) -- {{#invoke:Phab.T154769.Test|antiCrash_frame}} -- Simplified code to test function versioning.antiCrash(options, content_or_func, ...) -- Form the display of a running error. local memo = events.save_configs() -- Save global configuration before eventual changes. local res, t = "", "" local ac_opt = {} if type(options) == "table" then -- Easy long term compatibility against variable arguments number. ac_opt = options -- Always use the same table to transmit details across pcall or xpcall. end if (ac_opt.selector == "nocontent") then -- "nocontent" always masks the internal content without try it. ac_opt.success = true -- because sought ac_opt.content = "" return (ac_opt.content or "ac_opt.content"), ac_opt end -- - - - - - ----------------- To debug : start with only pcall() then step by step, add other code ------------------- -- function pcall_protect(content_or_func, ac_opt) if (type(content_or_func) == "function") then -- replaces result = func( ... ) without blocking cases to avoid crash. ac_opt.try_success, ac_opt.try_content = pcall( content_or_func(luaTable.toList(ac_opt.args) ), "pcall_protect(content_or_func, ac_opt)" ) -- Try test case. end ac_opt.try_content = ac_opt.try_content or "ac_opt.try_content" return ac_opt.try_content -- , ac_opt end if ac_opt.errortype == "wanted_error" then -- replaces result = func( ... ) without blocking cases to avoid crash. ac_opt.try_success, ac_opt.try_content = pcall( versioning.antiCrash_wanted_error(...), "pcall_protect(content_or_func, ac_opt)" ) -- Try test case. -- res = res .. versioning.antiCrash(ac_opt, versioning.antiCrash_wanted_error() ) elseif (type(content_or_func) == "string") then -- replaces result = func( ... ) without blocking cases to avoid crash. ac_opt.try_content = content_or_func -- Minimal default ac_opt.try_success = true elseif (type(content_or_func) == "function") then -- replaces result = func( ... ) without blocking cases to avoid crash. ac_opt.try_success, ac_opt.try_content = pcall( content_or_func(...), "pcall_protect(content_or_func, ac_opt)" ) -- Try test case. -- debug.traceback( "beginning message", level ) -- Returns a string with a traceback of the call stack from level, else level=1. -- ac_opt.try_content = ", try_content = " .. ac_opt.try_content .. ", traceback = " .. debug.traceback() local TB = debug.traceback() local tb = string.gsub(TB, "\n", "") -- tb = string.gsub(tb, "<br>", "br") tb = string.gsub(tb, "stack traceback:", "") tb = string.gsub(tb, "%sModule:", "<br>Module:") tb = string.gsub(tb, "%smw.lua:", "<br>mw.lua:") -- enhanced traceback t = t .. TB if ac_opt.try_success then -- replaces result = func( ... ) without blocking cases to avoid crash. -- t = t .. viewer.ta("traceback", debug.traceback( "antiCrash success:" )) t = viewer.ta("try_success", ac_opt.try_success) t = t .. viewer.ta("try_content", ac_opt.try_content) t = t .. "<b>antiCrash success:" .. tb .. "</b>" else -- replaces result = func( ... ) without blocking cases to avoid crash. -- t = t .. viewer.ta("traceback", debug.traceback( "antiCrash ERROR:" )) t = viewer.ta("try_success", ac_opt.try_success) t = t .. viewer.ta("try_content", ac_opt.try_content) t = t .. "<b>antiCrash ERROR:" .. tb .. "</b>" ac_opt.try_content = ac_opt.try_content .. t end elseif (type(content_or_func) == "table") then -- replaces result = func( ... ) without blocking cases to avoid crash. ac_opt.try_content = ac_opt.try_content .. "-tbl-" .. viewer.value(content_or_func) -- ac_opt.try_content = "content table OK" ac_opt.try_success = true else ac_opt.try_content = "content_or_func_else OK" ac_opt.try_success = true end ac_opt.content = ac_opt.try_content ac_opt.content = ac_opt.title .. (ac_opt.content or "antiCrash.ac_opt.content") events.restore_configs(memo) -- Restore global configurations after eventual changes. return (ac_opt.content or "ac_opt.content"), ac_opt end -- function versioning.antiCrash(ac_opt, content_or_func, ...) -- Form the display of a running error. function versioning.antiCrash2(ac_opt, content_or_func, ...) -- Recursive.antiCrash test 2 return versioning.antiCrash(ac_opt, content_or_func, ...) end function versioning.antiCrash3(ac_opt, content_or_func, ...) -- Recursive.antiCrash test 3 return versioning.antiCrash2(ac_opt, content_or_func, ...) end -- {{#invoke:Phab.T154769.Test|antiCrash_frame}} function versioning.antiCrash_tests() -- Main test local res = "\n* Tests of versioning.antiCrash(ac_opt, content_or_func, ...) : " res = res .. "\n* This test is suspended to less delay central modules." if 1 then return res end -- {{#invoke:Phab.T154769.Test|antiCrash_frame}} --function versioning.antiCrash_tests() -- Main test -- local res = "\n* Central-s-fr.T154769.Tests of versioning.antiCrash(ac_opt, content_or_func, ...) : " local ac_opt = {} -- Parser errors without ModuleName:line: -- Erreur Lua : attempt to call a string value -- Erreur Lua : ...? -- local tst = "\n* <b>Crash test</b> input: " ac_opt.title = tst .. "a simple string : " local content_or_func = "simple test of string" res = res .. versioning.antiCrash(ac_opt, content_or_func) -- ac_opt.title = tst .. 'a function return a "string": ' function content_or_func() return "string from function" end -- T154769 Erreur Lua : attempt to call a string value res = res .. versioning.antiCrash(ac_opt, content_or_func) -- ac_opt.title = tst .. "a table = { x=1, y=2 } : " local content_or_func = { x=1, y=2 } res = res .. versioning.antiCrash(ac_opt, content_or_func) -- local content_or_func = "x = wanted.runtime.error fails" ac_opt.title = tst .. "wanted.runtime.error : " ac_opt.errortype = "wanted_error" res = res .. versioning.antiCrash(ac_opt, "wanted_error call" ) -- ac_opt.title = tst .. "Recursive antiCrash3() : " local content_or_func = "antiCrash3 test" -- Recursive.antiCrash test 3 res = res .. versioning.antiCrash3(ac_opt, versioning.antiCrash_wanted_error() ) return res end -- function versioning.antiCrash_tests(frame) -- Main test function versioning.antiCrashFormError(funcname, title, errortext, ...) -- Form the running error: text, event and category. if type(funcname) ~= "string" then funcname = "funcname" end if type(title) ~= "string" then title = "title" end if type(errortext) ~= "string" then errortext = "errortext" end local t = "" local args = translate.formTestCase("", ...) t = t .. viewer.ta("function", viewer.errorColor(funcname) .. "( " .. args .. " ), ") t = t .. viewer.ta("title", viewer.errorColor(title) ) t = t .. viewer.ta("error", viewer.errorColor(errortext) ) local cat = events.add_cat("modes_no_source_arguments_cat") if string.sub(cat, 1, 3) ~= "[[:" then cat = "[[:" .. string.sub(cat, 4) end -- To always display de link to the category, with or without catview. t = t .. "See: " .. cat -- link to internal_error_cat events.categories_lister("") -- activate categories at page level return t end -- function versioning.antiCrashFormError(funcname, title, errortext, ...) function versioning.antiCrash_details(ac_opt) -- Details about antiCrash local res = "\n* " .. viewer.ta("ac_opt.title", ac_opt.title) res = res .. "\n* " .. viewer.ta("ac_opt.title_error", ac_opt.title_error) res = res .. "\n* " .. viewer.ta("ac_opt.selector", ac_opt.selector) res = res .. "\n* " .. viewer.ta("ac_opt.try_success", ac_opt.try_success) res = res .. "\n* " .. viewer.ta("ac_opt.success", ac_opt.success) res = res .. "\n* " .. viewer.ta("ac_opt.try_error", ac_opt.try_error) res = res .. "\n* " .. viewer.ta("ac_opt.try_error_string", ac_opt.try_error_string) res = res .. "\n* " .. viewer.ta("ac_opt.try_error_string_color", ac_opt.try_error_string_color) res = res .. "\n* " .. viewer.ta("ac_opt.funcname", ac_opt.funcname) res = res .. "\n* " .. viewer.ta("ac_opt.try_form_error", ac_opt.try_form_error) res = res .. "\n* " .. viewer.ta("ac_opt.resultKind", ac_opt.resultKind) res = res .. "\n* " .. viewer.ta("ac_opt.try_error_color_ref", ac_opt.try_error_color_ref) res = res .. "\n* " .. viewer.ta("ac_opt.try_error_ref", ac_opt.try_error_ref) res = res .. "\n* " .. viewer.ta("ac_opt.content_error", ac_opt.content_error) res = res .. "\n* " .. viewer.ta("ac_opt.try_content", ac_opt.try_content) res = res .. "\n* " .. viewer.ta("ac_opt.content", ac_opt.content) -- res = res .. "\n* " .. viewer.ta("ac_opt.result", ac_opt.result) return res end -- function versioning.antiCrash(options, content_or_func, ...) -- Form the display of a running error. -- function versioning.antiLoop("luaTable.SubCounts", 11, luaTable.SubCounts, tablebase, tabname, opt, recursiveLevel) -- Limit the n-th reentrant call of any function. --[[ Another versioning means is : successive states of a page or a module. Here versions management means: To manage versions in a main_module, a user defines a list of soughtversions included in a list of knownversions. Example of arg: soughtversions = "Author3 MathRoman2 Central1" Example of arg: knownversions = " Author,Author3 * MathRoman,MathRoman2 * Central,Central1 " The user changes sought and known at module level or at Args level. And the "versions" library supports the module and the user. The main_module can display warnings like: versioning_all_versions_tests = "Versions warning: <b>%1</b>, normal: <b>%2</b>, listall: <b>%3</b>.", -- versionsmanagement versioning_select_unknown_module_err = "Internal error: The missing Module:<b>%1</b> is replaced by the normal Module:<b>%2</b>.", -- versionsmanagement versioning_I18N_module_no_base_err = "The <b>%1</b> translations module has no basic version.", -- versionsmanagement versioning_no_versions_module_err = "The module <b>%1</b> is not in the system versioning.", -- versionsmanagement --]] --[[ --] ] function tools.versionsmanagement_report(vers) -- Deprecated alias function versioning.deprecatedFunction("tools.versionsmanagement_report", "versioning.versions_management_report") return versioning.versions_management_report(vers) end --]] function versioning.versions_management_report(vers) -- Detect versions management errors and warnings after bind_sub_modules local memo = events.save_configs() -- Save global configuration before eventual changes. local errs, cats = "", "" if type(vers) ~= "table" then vers = versioning.main_versions end if type(vers) ~= "table" then vers = versioning.main_versions end --[[ Example in a module: p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module. versionName = "Author3", versionNumber = "3.03", versionDate = "2016-04-25 10:31", sought = " Author3, Central01 ", -- sought submodules versions known = " Author3 * Central;Central01 ", -- known submodules versions } --]] local sought_report = viewer.simpleList(vers.sought) local known_report = viewer.simpleList(vers.known) local loaded_report = viewer.simpleList(vers.loaded_list) local used_report = viewer.simpleList(vers.used) local alloncesort = viewer.simpleList(sought_report .. ";" .. known_report .. ";" .. used_report) -- .. ";" .. loaded_report) local missing_report = "" local replaced_report = "" local unknown_report = "" -- t = t .. "\n* <b>Versions management report</b>, second: " .. alloncesort -- local argm = modes.args_known local alloncetab = mw.text.split(alloncesort, ';') -- table of words for i, name in ipairs(alloncetab) do -- list all used names, only one each, in alphabetic order local name_I18N = string.find(name, "/I18N") if viewer.is_in_sp(name, sought_report, ";") and not viewer.is_in_sp(name, known_report, ";") and not name_I18N then missing_report = missing_report .. name .. ";" -- sought but not found errs = errs .. ";" .. events.add_err("versioning_missing_versions_err", name, vers.versionName ) .. ";" cats = cats .. events.add_cat("versioning_module_usage_error_cat") end if viewer.is_in_sp(name, used_report, ";") and not viewer.is_in_sp(name, sought_report, ";") and not name_I18N then replaced_report = replaced_report .. name .. ";" -- missing version replaced by normal errs = errs .. ";" .. events.add_err("versioning_replaced_versions_err", name, vers.versionName ) .. ";" cats = cats .. events.add_cat("versioning_module_usage_error_cat") end if viewer.is_in_sp(name, alloncesort, ";") and not viewer.is_in_sp(name, known_report, ";") and not name_I18N then unknown_report = unknown_report .. name .. ";" -- found but not known errs = errs .. ";" .. events.add_err("versioning_unknownversions_err", name, vers.versionName ) .. ";" cats = cats .. events.add_cat("versioning_module_usage_error_cat") end end local loaded_report = viewer.simpleList(loaded_report) local used_report = viewer.simpleList(used_report) local missing_report = viewer.simpleList(missing_report) local replaced_report = viewer.simpleList(replaced_report) local unknown_report = viewer.simpleList(unknown_report) local t = "\n* <b>Versions management_details</b>:" t = t .. "<br/>" .. viewer.ta("sought_report", sought_report) t = t .. "<br/>" .. viewer.ta("known_report", known_report) t = t .. "<br/>To understand:" t = t .. "<br/>" .. viewer.ta("loaded_report", loaded_report) t = t .. "<br/>" .. viewer.ta("used_report", used_report) t = t .. "<br/>" .. viewer.ta("missing_report", missing_report) t = t .. "<br/>" .. viewer.ta("replaced_report", replaced_report) t = t .. "<br/>" .. viewer.ta("unknown_report", unknown_report) events.restore_configs(memo) -- Restore global configurations after eventual changes. return t, errs end -- function versioning.versions_management_report(vers) -- res = res .. versioning.docDropBox(selector, "versioning_list_all_G_and_loaded_title", versioning.list_all_G_and_loaded) function versioning.list_all_G_and_loaded(t) -- List all objects in _G global space and in package.loaded local t = t or "\n* <b>versioning.list_all_G_and_loaded()</b> List all objects in _G global space and in package.loaded. " t = t .. translate.track_counts("list_all_G:begin", "versioning.i18n", trans, tables, versioning.i18n) t = t .. translate.track_counts("list_all_G:begin", "translate.i18n", trans, tables, translate.i18n) t = t .. translate.track_counts("list_all_G:begin", "versioning.main_i18n", trans, tables, versioning.main_i18n) t = t .. translate.track_counts("list_all_G:begin", "translate.main_i18n", trans, tables, translate.main_i18n) local memo = events.save_configs() -- Save global configuration before eventual changes. t = t .. viewer.usualColor("\n* <b>viewer.usualColor()</b> Available usual fonctional styles: ") -- Fonctional style for usual cases. function sort_and_list_objects(Objects) local sort_key, t = {}, "" for key, obj in pairs(Objects) do table.insert( sort_key, key ) end -- t = t .. viewer.ta("#sort_key before", #sort_key) .. ", " if #sort_key > 0 then table.sort(sort_key, function (a, b) return (a < b) end ) -- alphabetic sort of objects for i, key in pairs(sort_key) do local obj = Objects[key] if obj then usual = "discreet" end -- "central module or library" if type(obj) == "function" then usual = "error" end -- "function in _G global space" -- see: { 90, "Obsolete", "T20161022", 0, "ToCreate", "? Scribunto functions are out of package.loaded", "Lua functions out of package.loaded", }, if type(obj) == "string" then usual = "normal" end -- "value from mediawiki" if type(obj) == "table" then usual = "invoke" end -- "mediawiki library" if (type(obj) == "table") and (type(obj.i18n) == "table") then usual = "add" end -- "central module or library" t = t .. viewer.usualColor(key, usual) .. ", " end -- t = t .. viewer.ta("#sort_key after", #sort_key) .. ", " else -- t = t .. viewer.ta("#sort_key else", #sort_key) .. ", " end return t end t = t .. "\n\n* <b>versioning.list_all_G_and_loaded()</b>: Objects in <b>_G</b> global space: " t = t .. sort_and_list_objects(_G) t = t .. "\n\n* <b>versioning.list_all_G_and_loaded()</b>: Objects in <b>package.loaded</b>: " t = t .. sort_and_list_objects(package.loaded) events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function versioning.list_all_G_and_loaded(t) function viewer.wiki_modules_users_stat() -- Modules, users and stats in this wiki. local mwuri = mw.uri.new() res = "" res = res .. "\n*. <b>Modules</b>: " res = res .. viewer.ta("Main module", tostring(versioning.mainversion) ) res = res .. viewer.ta("Proto version", tostring(Central.versions.versionName ) ) res = res .. viewer.ta("Modules in this wiki", tostring(mw.site.stats.pagesInNamespace( 828 ) ) ) -- Users res = res .. "<br/>\n* <b>Users activities</b>: " res = res .. viewer.ta("activeUsers", tostring(mw.site.stats.activeUsers ) ) res = res .. viewer.ta("Administrators(sysop)", tostring(mw.site.stats.usersInGroup( "sysop" ) ) ) res = res .. viewer.ta("bots(bot)", tostring(mw.site.stats.usersInGroup( "bot" ) ) ) res = res .. viewer.ta("patrollers(patroller)", tostring(mw.site.stats.usersInGroup( "patroller" ) ) ) res = res .. viewer.ta("bureaucrats(bureaucrat)", tostring(mw.site.stats.usersInGroup( "bureaucrat" ) ) ) res = res .. "\n* [[Special:Statistics | Statistics on users and content]] " -- res = res .. viewer.ta("checkuser(checkuser)", tostring(mw.site.stats.usersInGroup( "checkuser" ) ) ) -- res = res .. viewer.ta("autoconfirmed(autoconfirmed)", tostring(mw.site.stats.usersInGroup( "autoconfirmed" ) ) ) -- res = res .. viewer.ta("Autopatrol users(autoreview)", tostring(mw.site.stats.usersInGroup( "autoreview" ) ) ) -- res = res .. viewer.ta("Account creators(accountcreator)", tostring(mw.site.stats.usersInGroup( "accountcreator" ) ) ) res = res .. " mw [[:mw:Special:ListGroupRights]] " -- https://www.mediawiki.org/wiki/Special:ListGroupRights -- Last revision res = res .. "<br/>\n* <b>Last revision</b>: " res = res .. viewer.ta("REVISIONTIMESTAMP", modes.frame:preprocess( "{{REVISIONTIMESTAMP}}" ) ) res = res .. viewer.ta("REVISIONUSER", modes.frame:preprocess( "{{REVISIONUSER}}" ) ) -- Languages res = res .. "<br/>\n* <b>Languages</b>: " res = res .. viewer.ta("PAGELANGUAGE", modes.frame:preprocess( "{{PAGELANGUAGE}}" ) ) -- res = res .. viewer.ta("PAGELANGUAGE", mw.getCurrentFrame():expandTemplate{ title = 'PAGELANGUAGE' } ) res = res .. viewer.ta("CONTENTLANGUAGE", modes.frame:preprocess( "{{CONTENTLANGUAGE}}" ) ) -- res = res .. "\n* <b>User language</b>: " res = res .. viewer.ta("USERLANG", modes.frame:preprocess( "{{USERLANG}}" ) ) res = res .. viewer.ta("UILANGCODE", modes.frame:preprocess( "{{UILANGCODE}}" ) ) res = res .. viewer.ta("USERLANG", modes.frame:preprocess( "{{USERLANG}}" ) ) res = res .. viewer.ta("USERLANGUAGE", modes.frame:preprocess( "{{USERLANGUAGE}}" ) ) res = res .. viewer.ta("USERIFCODE", modes.frame:preprocess( "{{USERIFCODE}}" ) ) -- res = res .. viewer.ta("USERLANG", mw.getCurrentFrame():expandTemplate{ title = 'USERLANG' } ) -- res = res .. "\n* <b>Scribunto</b>: " res = res .. ", [[ mw:Extension:Scribunto | Extension:Scribunto ]]" res = res .. viewer.ta("[http://tylerneylon.com/a/learn-lua/ Lua] [[ mw:Extension:Scribunto/Lua_reference_manual | manual ]], version: ", _VERSION ) -- res = res .. "\n* <b>Server mw.uri.new</b>: " res = res .. viewer.ta("protocol", mwuri.protocol ) res = res .. viewer.ta("user", mwuri.user ) res = res .. viewer.ta("password", mwuri.password ) res = res .. viewer.ta("host", mwuri.host ) res = res .. viewer.ta("port", mwuri.port ) res = res .. viewer.ta("path", mwuri.path ) res = res .. viewer.ta("query", mwuri.query ) res = res .. viewer.ta("fragment", mwuri.fragment ) res = res .. viewer.ta("userInfo", mwuri.userInfo ) res = res .. viewer.ta("hostPort", mwuri.hostPort ) res = res .. viewer.ta("authority", mwuri.authority ) res = res .. viewer.ta("queryString", mwuri.queryString ) res = res .. viewer.ta("relativePath", mwuri.relativePath ) -- res = res .. mwuri:parse( "uri:parse : user, ( userInfo ), host-Port = hostPort" ) return res end -- function viewer.wiki_modules_users_stat(t) function versioning.running_times(no_view, res, time1, time2, time3, time4) -- Form running times and references for Lua-coders. -- Last update example: -- Execution time and page: 2017-04-27 10:01:50 UTC , url = https://fr.wikisource.org/wiki/Module:Central-s-fr/Documentation -- Running times: , start in page = 171 mS , import + 0 mS , form result + 0 mS , tests + 522 mS , duration = 522 mS local res = "" -- res or "\n* versioning.running_times() Modules, users and stats in this wiki" local mwuri = mw.uri.new() local currentVersion = tostring(mw.site.currentVersion) if currentVersion ~= versioning.site_currentVersion_memo then currentVersion = viewer.errorColor(currentVersion) end res = res .. "\n* " .. viewer.ta("[[ Special:Version | Local MediaWiki version ]]", currentVersion ) res = res .. viewer.wiki_modules_users_stat() -- Modules, users and stats in this wiki. modes.time4 = os.clock() if no_view then return default_res end local time4 = time4 or modes.time4 local time3 = time3 or modes.time3 or time4 local time2 = time2 or modes.time2 or time3 local time1 = time1 or modes.time1 or time2 if time2 < time1 then time2 = time1 end if time3 < time2 then time3 = time2 end if time4 < time3 then time4 = time3 end local nowtime = 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 duration = time2d + time3d + time4d 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" duration = tostring(math.floor( duration * 1000 )) .. " mS" res = res .. "\n* <b>Execution time and page</b>: " .. nowtime .. " UTC" .. viewer.ta("url", url) -- prefixedText res = res .. "\n* <b>Running times</b>: " res = res .. viewer.ta("start in page", time1) .. viewer.ta("import", time2d, "+") res = res .. viewer.ta("form result", time3d, "+") .. viewer.ta("tests", time4d, "+") .. viewer.ta("duration", duration) --[[ Display example : Revision time: , module = 20161223063818 , page = 20161216171553 , user = Rical , REVISIONID = 6431229 Running times: , start in page = 680 mS , import + 0 mS , form result + 91 mS , tests + 58 mS , duration = 150 mS Execution and test_time: 2016-12-23 06:38:19 UTC , url = https://fr.wikisource.org/wiki/Module:Central-s-fr/Documentation --]] return res end -- function versioning.running_times(no_view, res, time1, time2, time3, time4) -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:viewer forms some viewers for tables(in lines and columns), dropboxes, recursive luatables... -- The name"luaTable" avoids ambiguities. To enhance rather than add it, we could write here : luaTable = table. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- viewer = {} -- already declared by Scribunto, else in _G space. -- Translations for viewer library viewer.i18n = {} viewer.i18n.en = { -- Main texts, errors and categories of tools viewer_test_no_values = "Test: without values", viewer_test_the_value_is_table = "Test: the value is a table", viewer_test_all_types_values = "Test: values of all types", viewer_DropBox_label_Unwrap = "Unwrap/Wrap", viewer_page_tests_title = "Testing and information related to this page:", viewer_page_tests_h2_title = "Tests of this page", viewer_module_tests_h2_title = "Tests of this module", viewer_internal_tests_h2_title = "Internal tests", viewer_dropdown_missing_title = "Missing title for this dropbox", -- Titles of tests viewer_module_tests_title = "Testing and information related to this module:", viewer_internal_tests_title = "Internal regression tests:", viewer_tableView_tests_headers = "Case;Value;Result", viewer_tableView_tests_title = "viewer.tableView() Test: Form a table with lines and columns.", viewer_tabView_form_elem_detail = "detail = %1 | %2 | %3 | %4 | %5.", viewer_tableView_tests_err = "Internal error : viewer.tableView() abnormal fail.", viewer_format_time_tests_title = "viewer.formatDate() Tests of coding and conversion of dates", viewer_parts_of_date_tests_title = "viewer.date_to_part() Tests of date to day, month, year or era", viewer_simpleList_tests_title = "viewer.simpleList() Test: Sort a list of words without repetition", } -- viewer.i18n.en viewer.i18n.es = { -- Textos principales, errores y categorías de instrumentos viewer_test_no_values = "Prueba: sin valores", viewer_test_the_value_is_table = "Prueba: el valor es una tabla", viewer_test_all_types_values = "Prueba: valores de todos los tipos", viewer_DropBox_label_Unwrap = "Desenvolver/Envolver", viewer_page_tests_title = "Pruebas y información relacionada con esta página:", viewer_page_tests_h2_title = "Pruebas de esta página", viewer_module_tests_h2_title = "Pruebas de esto página", viewer_internal_tests_h2_title = "Pruebas internas", viewer_dropdown_missing_title = "Falta el título para este dropbox", -- Titres des pruebas viewer_page_tests_title = "Pruebas y información relacionada con esta página:", viewer_module_tests_title = "Pruebas y información relacionada con esto módulo:", viewer_internal_tests_title = "Pruebas de no regresión internas:", viewer_tableView_tests_headers = "Caso; Valor; Resultado", viewer_tableView_tests_title = "viewer.tableView() Prueba: Formar una tabla con líneas y columnas.", viewer_tabView_form_elem_detail = "detalle = %1 | %2 | %3 | %4 | %5.", viewer_tableView_tests_err = "Error interno: viewer.tableView() error anormal.", viewer_format_time_tests_title = "viewer.formatDate() Pruebas de codificación y conversión fechas", viewer_parts_of_date_tests_title = "viewer.date_to_part() Pruebas de fecha a día, mes, año o época", viewer_simpleList_tests_title = "viewer.simpleList() Prueba: Ordenar una lista de palabras sin repetición", } -- viewer.i18n.es viewer.i18n.fr = { -- Principaux textes, erreurs et catégories des outils viewer_test_no_values = "Test: sans valeurs", viewer_test_the_value_is_table = "Test: la valeur est une table", viewer_test_all_types_values = "Test: valeurs de tous types", viewer_DropBox_label_Unwrap = "Dérouler/Enrouler", viewer_page_tests_title = "Tests et informations liées à cette page :", viewer_page_tests_h2_title = "Tests de cette page", viewer_module_tests_h2_title = "Tests de ce module", viewer_internal_tests_h2_title = "Tests internes", viewer_dropdown_missing_title = "Titre manquant pour cette boite déroulante", -- Titres des tests viewer_page_tests_title = "Tests et informations liées à cette page :", viewer_module_tests_title = "Tests et informations liées à ce module :", viewer_internal_tests_title = "Tests internes de non régression :", viewer_tableView_tests_headers = "Case;Value;Result", viewer_tableView_tests_title = "viewer.tableView() Test: former un tableau avec lignes et colonnes.", viewer_tabView_form_elem_detail = "détail = %1 | %2 | %3 | %4 | %5.", viewer_tableView_tests_err = "Erreur interne: viewer.tableView() échec anormal.", viewer_format_time_tests_title = "viewer.formatDate() Tests de codage et conversions de dates", viewer_parts_of_date_tests_title = "viewer.date_to_part() Tests de date vers jour, mois, année ou ère", viewer_simpleList_tests_title = "viewer.simpleList() Test: Trier une liste de mots sans répétition", } -- viewer.i18n.fr -- function versioning.antiLoop(funcname, n, func, ...) -- Limit the n-th reentrant call of any function. -- Try versioning.antiLoop() in functions recently changes, in case of errors: -- "Erreur Lua : stack overflow" or "Le temps alloué pour l’exécution des scripts a expiré." or "The time allowed for script execution has expired". -- $wgParserCacheExpireTime - Expiration time (in seconds) of cached parser information -- function versioning.antiLoop_list(t) -- List versioning.antiLoop(). -- See also string.format( formatstring, ... ) -- 2016-06-25 Rical -- Example printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec); -- 2016-06-25 Rical -- See also http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html -- 2016-06-25 Rical function viewer.is_in(word, text) -- The word is it in the text, even inside another word? local i = string.find(text or "", word or "", 1, true) return (i and true) end function viewer.is_in_sp(word, text, sep) -- The word is it in the text, beetwen spaces or separators, not inside another word? sep = sep or " " -- default separator is space. But could be * ; , or even any string. if type(word) ~= "string" then word = "" end if type(text) ~= "string" then text = "" end local i = string.find(sep .. text .. sep, sep .. word .. sep, 1, true) if i then i = true else i = false end return i end function viewer.isDef(x) -- x is defined or no. x est défini ou non return (type(x) == "string") and (x ~= "") and (x ~= " ") and (x ~= "nil") end function viewer.value(value) -- Form a string to discribe a value like: true, 123.456, "abcd", func(), table{} local typ, view = type(value), "-" if typ == "boolean" then if value == true then view = "true" else view = "false" end elseif typ == "function" then view = "func()" elseif typ == "number" then view = tostring(value) elseif typ == "string" then view = '"' .. value .. '"' elseif typ == "table" then view = "table{}" elseif typ == "nil" then view = "nil" end return view end -- function viewer.value(value) function viewer.ta(txt, val, sep) -- Form an argument and its value in a documentation. The text is "nil" if the value is nil. if val == nil then val = "nil" end if sep == nil then sep = "=" end return " , " .. tostring(txt) .. " " .. tostring(sep) .. " <b>" .. tostring(val) .. "</b> " end function viewer.tam(txt, val, sep) -- Form an argument and its value, or mask it if nil. if not val then return "" end return viewer.ta(txt, val, sep) end -- Build a table, with headers for columns. Example: -- ! style="text-align:left;"| Item -- {| class="wikitable" style="text-align: center; color: green;" -- {| border="1" style="border-crash:crash" -- {| class="wikitable sortable" border="1" mw-collapsible mw-crashd" -- |} end of table function viewer.Th(t) return '\n{| class="' .. tostring( t or 'wikitable alternative center' ) .. '" | ' end -- Table columns headers -- or " " -- A triable table start with : {| class="wikitable sortable" -- A column become fix and not triable with : ||class="unsortable"| -- A row become fix and not triable with : |- class="sortbottom" function viewer.Tc(t) return '\n! scope="col" | ' .. tostring( t or " " ) end -- Table repeated or different columns headers function viewer.Tr(t) return "\n|- " .. tostring( t or " " ) end -- Table -- row function viewer.Td(t) return "\n| " .. tostring( t or " ") end -- Table data -- or " " function viewer.Te(t) return "\n|}" end -- Table end -- Fonctional styles in central modules. viewer.usual_colors = { -- Available usual fonctional styles for central modules and those using them. ["add"] = "blue", -- Usual fonctional style for add in blue; blue/yellow are more accessible, see T156048. ["delete"] = "#C0C000",-- Usual fonctional style for delete in yellow; blue/yellow are more accessible, see T156048. ["discreet"]= "#B0B0B0",-- Usual fonctional style for discreet in light grey. ["error"] = "red", -- Usual fonctional style for error in red. ["invoke"] = "#804020",-- Usual fonctional style for invoke args in brown. ["normal"] = "black", -- Usual fonctional style for other standard in black. ["warning"] = "#804020",-- Usual fonctional style for warnings in brown. ["wikidata"]= "green", -- Usual fonctional style for wikidata in green. } function viewer.usualColor(t, usual) -- Fonctional style for available usual cases. if type(usual) ~= "string" then usual = "normal" end local t = tostring(t) -- template style: '<span style="color:black;" > usual </span>' -- template style local usual_in_style = '<span style="color:' .. viewer.usual_colors["normal"] .. ';" >' .. t .. '</span>' -- default style if viewer.usual_colors[usual] then -- Adapt the style of usual, if it exists. usual_in_style = '<span style="color:' .. viewer.usual_colors[ usual ] .. ';" >' .. t .. '</span>' -- actual style end -- Style for add in blue; blue/yellow are more accessible, see T156048. return usual_in_style end -- function viewer.usualColor(t, usual) function viewer.addColor(t) return viewer.usualColor(t, "add") end function viewer.deleteColor(t) return viewer.usualColor(t, "delete") end function viewer.discreetColor(t) return viewer.usualColor(t, "discreet") end function viewer.errorColor(t) return viewer.usualColor(t, "error") end function viewer.invokeColor(t) return viewer.usualColor(t, "invoke") end function viewer.normalColor(t) return viewer.usualColor(t, "normal") end function viewer.warningColor(t) return viewer.usualColor(t, "warning") end function viewer.wikidataColor(t) return viewer.usualColor(t, "wikidata") end function viewer.CSS_styles() -- Define viewers CSS_styles. -- viewer.errorColor() local CentralDocBox = '<div class="CentralDocBox" style=" width=90%; border: 1px solid #AAAAAA; margin:1em; background-color:#F1F1F1; padding:0.3em; ">' .. res .. '</div>' local CentralDropBox = '<div class="NavFrame CentralDropBox" style="clear:both; margin-bottom:'.. s.margin_bottom ..'; width:'.. s.width ..'; border-style:solid; -moz-border-radius:'.. s.border_radius ..'; border-color:'.. s.border_color ..'; background-color:'.. s.background_color ..'; " title="'.. s.label ..'" >' return end -- function viewer.CSS_styles() function viewer.smallCapsStyle(t) -- Display a text in small-caps style. return '<span style="font-variant: small-caps">' .. t .. '</span>' end function viewer.classDayTimeStyle(title, DATE) -- Display a date in class="(b|d)day" style. -- Todo: Tpt 20121005 19:48 : <span class="(b|d)day" title="DATE AU FORMAT YYYY">AFFICHAGE DE LA DATE</span> Tpt (d) 5 septembre 2012 à 19:48 (UTC) if type(title) ~= "string" then title = "title" end if type(DATE) ~= "string" then DATE = "DATE" end return '<span class="(b|d)day" title="' .. title .. '">' .. DATE .. '</span>' end -- Extract a part of date following a pre-defined format which starts with separator function viewer.date_split(date, format) -- local dd, mmmm, yyyy, era = viewer.date_split(a.birthdate, " dd mmmm yyyy") local dd, mmmm, yyyy, era local format_split = mw.text.split(format, "%s") local split = mw.text.split(date, "%s") for i, date_part in ipairs(split) do if format_split[i] == "dd" then dd = tonumber(date_part) end if format_split[i] == "mmmm" then mmmm = date_part end if format_split[i] == "yyyy" then yyyy = tonumber(date_part) end if format_split[i] == "era" then era = date_part end end return dd, mmmm, yyyy, era end -- function viewer.date_split(date, format) -- Extract a part of date following a pre-defined format which starts with separator function viewer.date_to_part(date, part) -- local t, err = viewer.date_to_part(a.birthyear, " dd mmmm yyyy", "yyyy") part = part or "yyyy" local dd, mmmm, yyyy, era local found = false -- local err = "modes_date_to_part_not_found_err" if not found then dd, mmmm, yyyy, era = viewer.date_split(date, "dd mmmm yyyy") if dd and mmmm and yyyy and not era then found = true end end if not found then dd, mmmm, yyyy, era = viewer.date_split(date, "mmmm dd yyyy") if dd and mmmm and yyyy and not era then found = true end end if not found then dd, mmmm, yyyy, era = viewer.date_split(date, "yyyy era") if not dd and not mmmm and yyyy then if era == "BCE" then yyyy = - yyyy end found = true end end if not found then dd, mmmm, yyyy, era = viewer.date_split(date, "mmmm yyyy") if not dd and mmmm and yyyy and not era then -- modes_date_months_names = "January, February, March, April, May, June, July, August, September, October, November, December", -- modes_date_months_names = "Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre", -- modes_date_months_names = "Janvier, Février, Mars, Avril, Mai, Juin, Juillet, Août, Septembre, Octobre, Novembre, Décembre", found = true end end if not found then dd, mmmm, yyyy, era = viewer.date_split(date, "yyyy") if not dd and not mmmm and yyyy and not era then found = true end end -- + cccc = roman number ? if found then if part == "yyyy" then return yyyy or "" end if part == "mmmm" then return mmmm or "" end if part == "dd" then return dd or "" end if part == "era" then return era or "" end end return "" -- tostring(dd)..tostring(mmmm)..tostring(yyyy)..tostring(era) -- A faire : Titus Livius (Q2039), format de dates : P569 = date of birth = 59 BCE, P570 = date of death = 17 -- Socrate (470-399 av. J.-C.). end -- function viewer.date_to_part(date, part) function mw.text.sortCommaList(list, sep1, sep2, sep3) -- Sort without repeat a list with separators like "Central01;versioning 2.4;tools;two words" versioning.deprecatedFunction("mw.text.sortCommaList", "viewer.simpleList") return viewer.simpleList(list, sep1, sep2, sep3, sep4) end function viewer.simpleList(list, sep1, sep2, sep3, sep4) -- Remove repeats in a string list with separators. Can also sort. -- sep1 is used in final list. sep1 to sep4 can be "sort" or "trim". -- wanted. local sort, trim = false, false if sep1 == "sort" then sep1 = "" ; sort = true end if sep2 == "sort" then sep2 = "" ; sort = true end if sep3 == "sort" then sep3 = "" ; sort = true end if sep4 == "sort" then sep4 = "" ; sort = true end if sep1 == "trim" then sep1 = "" ; trim = true end if sep2 == "trim" then sep2 = "" ; trim = true end if sep3 == "trim" then sep3 = "" ; trim = true end if sep4 == "trim" then sep4 = "" ; trim = true end if type(list) ~= "string" then list = "" end if type(sep1) ~= "string" then sep1 = "" end -- Default separators value if type(sep2) ~= "string" then sep2 = "" end if type(sep3) ~= "string" then sep3 = "" end if type(sep4) ~= "string" then sep4 = "" end -- Patterns: Dot (.) always matches all characters, including newlines. -- Patterns: Quantifiers (*, +, ?, and -) may only be applied to individual characters. if viewer.is_in(sep1, ".*+?-/") then sep1 = "%" .. sep1 end if viewer.is_in(sep2, ".*+?-/") then sep2 = "%" .. sep2 end if viewer.is_in(sep3, ".*+?-/") then sep3 = "%" .. sep3 end if viewer.is_in(sep4, ".*+?-/") then sep4 = "%" .. sep4 end local listtab = mw.text.split(list or "", sep1, true) -- names between commas local listtabOut = {} local listtabSingle = {} local list2 = "" local t = " * t = " for i, name in ipairs(listtab) do -- list all names, only one each, in alphabetic order -- t = t .. "-" .. i if trim then name = mw.text.trim(name) end -- do not keep spaces inside each name if not listtabSingle[name] then listtabSingle[name] = name list2 = list2 .. name .. sep1 end -- if (name ~= "") and not viewer.is_in_sp(name, list2, sep1) then list2 = list2 .. name .. sep1 end end if sort then table.sort(listtabSingle, function (a, b) return (a < b) end ) -- sort in alphabetic order end --[[ for i, name in ipairs(listtabSingle) do -- for all names -- if trim then name = mw.text.trim(name) end -- do not keep spaces inside each name -- table.insert(listtabOut, name) -- listtabSingle[name] = name -- list2 = list2 .. name .. sep1 end --]] t = t .. " * list2 = " .. list2 .. " * " local output = string.sub( list2, 1, (-string.len(sep1)-1) ) -- without last sep1 or ; return output -- .. t end -- function viewer.simpleList(list, sep1, sep2, sep3) function viewer.simpleList_test(t) -- Test of : Sort without repeat a list with separators like "Central01;versioning 2.4;tools;two words" local memo = events.save_configs() -- Save global configuration before eventual changes. local t = t or "" t = t .. "\n* Test <b>viewer.simpleList(list, sep1, sep2, sep3)</b>: " t = t .. '\n* Remove repeats in a string list with separators. Can also sort.' local function simpleList_test_1(t, input, sep1, sep2, sep3, sep4) local output = tostring( viewer.simpleList(input, sep1, sep2, sep3, sep4) ) -- input = viewer.value(input) -- ; viewer.value(input) ; -- t = t .. viewer.Tr() .. viewer.Td(viewer.value(input)) .. viewer.Td(sep1) .. viewer.Td(sep2) -- t = t .. viewer.Td(sep3) .. viewer.Td(sep4) .. viewer.Td(output) t = t .. viewer.Tr() .. viewer.Td(viewer.value(input)) .. viewer.Td(viewer.value(sep1)) .. viewer.Td(viewer.value(sep2)) t = t .. viewer.Td(viewer.value(sep3)) .. viewer.Td(viewer.value(sep4)) .. viewer.Td(viewer.value(output)) -- .. viewer.Td(viewer.value(input)) .. viewer.Td(viewer.value(input)) .. viewer.Td(sep1) .. viewer.Td(sep2) .. viewer.Td(sep3) .. viewer.Td(sep4) .. viewer.Td(output) return t end t = t .. viewer.Th() .. viewer.Tc("input") .. viewer.Tc("sep1") .. viewer.Tc("sep2") .. viewer.Tc("sep3") .. viewer.Tc("sep4") .. viewer.Tc("output") t = simpleList_test_1(t, "abc;def;abc", ";", "-", "|") t = simpleList_test_1(t, "xyz;def;abc", ";", "sort") t = simpleList_test_1(t, "abc-def=abc", "-", "=") t = simpleList_test_1(t, "abc - def = abc", "-", "=", "sort") t = simpleList_test_1(t, "abc - def = abc", "-", "=", "sort", "trim") t = simpleList_test_1(t, ";;", ";", ";", ",") t = simpleList_test_1(t, "abc/def;abc", ";", "/") t = simpleList_test_1(t, "abc;def/abc/def;abc;def;abc", ";", "/", "-") t = simpleList_test_1(t, "abc;def;abc", ";", ";", "") t = t .. viewer.Te() --[[ local t = t or "\n* Test <b>viewer.simpleList(list, sep1, sep2, sep3, sep4)</b>:<br> " t = t .. '\n* Remove repeats in a string list with separators. Can also sort.' local s = "x" s = "abc;def;abc" ; t = t .. "\n* " .. s .. " --> ; --> " .. viewer.simpleList(s, ";") s = "abc;def,abc;" ; t = t .. "\n* " .. s .. " --> , --> " .. viewer.simpleList(s, ",") s = ",ABC - XYZ , abc" ; t = t .. "\n* " .. s .. " --> ; --> " .. viewer.simpleList(s, ";") s = ";abc;def;def;abc;" ; t = t .. "\n* " .. s .. " --> ; --> " .. viewer.simpleList(s, ";") s = ";abc;def;def;:123;abc;" ; t = t .. "\n* " .. s .. " --> ; --> " .. viewer.simpleList(s, ";") s = ";abc;def;def;:123;abc;" ; t = t .. "\n* " .. s .. " --> ; : --> " .. viewer.simpleList(s, ";", ":") s = ";abc/def;def;/123///xyz" ; t = t .. "\n* " .. s .. " --> ; / --> " .. viewer.simpleList(s, ";", "/") s = ";abc/def;def;/123///xyz" ; t = t .. "\n* " .. s .. " --> ; : / --> " .. viewer.simpleList(s, ";", ":", "/") s = ";abc/def;def;/123///xyz" ; t = t .. "\n* " .. s .. " --> ; / : --> " .. viewer.simpleList(s, ";", "/", ":") t = t .. "\n* Special separators chars or cases:" s = ";Other;Middle;Begin" ; t = t .. "\n* " .. s .. " --> sort --> " .. viewer.simpleList(s, "sort") s = ";Other;Middle;Begin" ; t = t .. "\n* " .. s .. " --> ; sort --> " .. viewer.simpleList(s, ";", "sort") s = ";def;abc;def;abc" ; t = t .. "\n* " .. s .. " --> ; sort --> " .. viewer.simpleList(s, ";", "sort") s = ";abc,def;def,abc" ; t = t .. "\n* " .. s .. " --> sort ; , --> " .. viewer.simpleList(s, "sort", ";", ",") s = ";abc.def;def.abc" ; t = t .. "\n* " .. s .. " --> ; . --> " .. viewer.simpleList(s, ";", ".") s = ";abc.def;def.abc" ; t = t .. "\n* " .. s .. " --> ; . --> " .. viewer.simpleList(s, ";", ".") s = ";abc,def;def,abc" ; t = t .. "\n* " .. s .. " --> ; , --> " .. viewer.simpleList(s, ";", ",") s = ";abc-def;def-abc" ; t = t .. "\n* " .. s .. " --> ; - --> " .. viewer.simpleList(s, ";", "-") --]] events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- viewer.simpleList_test(t) -- mw.language:formatDate lang:formatDate( format, timestamp, local ) -- Formats a date according to the given format string. timestamp else current time. The value for local must be a boolean or nil; if true, the time is formatted in the wiki's local time rather else in UTC. -- The format string and supported values for timestamp are identical to those for the #time parser function from Extension:ParserFunctions. Note that backslashes may need to be doubled in the Lua string where they wouldn't in wikitext: -- {{#time:d F Y|1988-02-28|nl}} → 28 februari 1988 -- {{#time: U | now }} → 1424087375 -- {{#time: r|@1424087374}} → Mon, 16 Feb 2015 11:49:34 +0000 function viewer.day_to_UTC(jj, mm, aaaa) local t = "@" .. tostring( jj*86400 + mm*30*86400 + (aaaa-1970)*31556926 ) return t end function viewer.day_to_stamp(jj, mm, aaaa) jj = tonumber(jj) if not jj then jj = "2" else jj = string.sub("0000" .. tostring(jj), -2, -1 ) end mm = tonumber(mm) if not mm then mm = "2" else mm = string.sub("0000" .. tostring(mm), -2, -1 ) end aaaa = tonumber(aaaa) if not aaaa then aaaa = "2000" else aaaa = string.sub("0000" .. tostring(aaaa), -4, -1 ) end return aaaa .. "-" .. mm .. "-" .. jj end function viewer.formatDate(format, timestamp, lang, loc) if not viewer.language_obj then viewer.language_obj = mw.language.new( "fr" ) end if lang then viewer.language_obj = mw.language.new( lang ) end if viewer.language_obj then viewer.language_code = viewer.language_obj:getCode() end if type(loc) ~= "boolean" then loc = true end return tostring(viewer.language_obj:formatDate(format, timestamp, loc)) end -- function viewer.formatDate(format, timestamp, loc) function viewer.time_format_test_1(t, test, format, timestamp, lang, loc) if lang then viewer.language_obj = mw.language.new( lang ) end t = t .. viewer.Tr() .. viewer.Td(test or "-") .. viewer.Td(format or "-") .. viewer.Td(timestamp or "-") .. viewer.Td(tostring(lang)) .. viewer.Td( viewer.formatDate(format, timestamp, loc) ) return t end function viewer.format_time_tests(t) local memo = events.save_configs() -- Save global configuration before eventual changes. if not viewer.language_obj then viewer.language_obj = mw.language.new( "fr" ) end if viewer.language_obj then viewer.language_code = viewer.language_obj:getCode() end local t = t or "\n<b>time_format_test</b> :" t = t .. "\nCoding and conversion of dates by the parser function language_obj:formatDate(format, timestamp, loc)." t = t .. viewer.ta("viewer.language_code", viewer.language_code) t = t .. "<br>Verify some date formats: Vérifier quelques formats de dates :" t = t .. viewer.Th() .. viewer.Tc("Test dates from seconds") .. viewer.Tc("format") .. viewer.Tc("timestamp") .. viewer.Tc("lang") .. viewer.Tc("Formated date") t = viewer.time_format_test_1(t, " now", "U", "now") t = viewer.time_format_test_1(t, " now", "F j Y", "now") t = viewer.time_format_test_1(t, " seconds to full UTC ", "r", "@1421117374") t = viewer.time_format_test_1(t, " seconds to full UTC ", "r", "@1424087374") t = viewer.time_format_test_1(t, " 2015-02-16T11:49:34+00:00 ", "c", "@1424107003") t = viewer.time_format_test_1(t, " 14/7/1789 to english ", "F j Y", viewer.day_to_UTC(14, 7, 1789), "en") t = viewer.time_format_test_1(t, " seconds to french format ", "j F Y", "@1499997003") t = viewer.time_format_test_1(t, " french 14/7/1789 ", "j F Y", viewer.day_to_UTC(14, 7, 1789), "fr") t = viewer.time_format_test_1(t, " french 14/7/234 ", "j F Y", viewer.day_to_UTC(14, 7, 234), "fr") t = t .. viewer.Tr() .. viewer.Tc("Test from UTC") .. viewer.Tc("format") .. viewer.Tc("timestamp") .. viewer.Tc("lang") .. viewer.Tc("Formated date") t = viewer.time_format_test_1(t, " french date ", "j F Y", "1915-02-16T17:16:43+00:00", "fr") t = viewer.time_format_test_1(t, " french date ", "j F Y", "1515-02-22T17:16:43+00:00", "fr") t = t .. viewer.Tr() .. viewer.Tc("Test dates only") .. viewer.Tc("format") .. viewer.Tc("timestamp") .. viewer.Tc("lang") .. viewer.Tc("Formated date") t = viewer.time_format_test_1(t, " french 2015-02-16 ", "j F Y", "2015-02-16", "fr") t = viewer.time_format_test_1(t, " french 32-12-25 ", "j F Y", "32-12-25", "fr") t = viewer.time_format_test_1(t, " french 0032-12-25 ", "j F Y", "0032-12-25", "fr") t = viewer.time_format_test_1(t, " french 3/4/5 ", "j F Y", viewer.day_to_stamp(3, 4, 5), "fr") t = viewer.time_format_test_1(t, " french 24/11/31 ", "j F Y", viewer.day_to_stamp(24, 11, 31), "fr") t = viewer.time_format_test_1(t, " french 24/11/32 ", "j F Y", viewer.day_to_stamp(24, 11, 32) ) t = viewer.time_format_test_1(t, " french 24/12/32 ", "j F Y", viewer.day_to_stamp(24, 12, 32) ) t = viewer.time_format_test_1(t, " french 25/12/32 ", "j F Y", viewer.day_to_stamp(25, 12, 32) ) t = viewer.time_format_test_1(t, " french 25/12/32 roman year ", "j F xrY", viewer.day_to_stamp(25, 12, 32) ) t = t .. viewer.Tr() .. viewer.Tc("Test partial formats & missing datas") .. viewer.Tc("format") .. viewer.Tc("timestamp") .. viewer.Tc("lang") .. viewer.Tc("Formated date") t = viewer.time_format_test_1(t, " partial format 3/4/5 ", "j F Y", viewer.day_to_stamp(3, 4, 5) ) t = viewer.time_format_test_1(t, " partial format 3/4/5 ", "Y", viewer.day_to_stamp(3, 4, 5) ) t = viewer.time_format_test_1(t, " missing day -/4/5 ", "F Y", viewer.day_to_stamp(nil, 4, 5) ) t = viewer.time_format_test_1(t, " missing month 3/-/5 ", "j Y", viewer.day_to_stamp(3, nil, 5) ) t = viewer.time_format_test_1(t, " missing year 3/4/- ", "j F", viewer.day_to_stamp(3, 4, nil) ) t = viewer.time_format_test_1(t, " missing day -/4/5 ", "F Y", viewer.day_to_stamp(nil, 4, 5) ) t = viewer.time_format_test_1(t, " missing month 3/-/5 ", "j Y", viewer.day_to_stamp(3, nil, 5) ) t = viewer.time_format_test_1(t, " missing year 3/4/- ", "j F", viewer.day_to_stamp(3, 4, nil) ) t = t .. viewer.Te() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function viewer.format_time_tests(t) function viewer.parts_of_date_tests(t) local memo = events.save_configs() -- Save global configuration before eventual changes. local function date_to_part_test_1(t, nom, date, part) t = t .. viewer.Tr() .. viewer.Td(nom) .. viewer.Td(date) .. viewer.Td(part) .. viewer.Td(tostring(viewer.date_to_part(date, part))) return t end local t = t or "\n* <b>date_to_part</b> :" t = t .. "\n* Verify each value of part of date:" t = t .. viewer.Th() .. viewer.Tc("Example") .. viewer.Tc("date") .. viewer.Tc("part") .. viewer.Tc("value") t = date_to_part_test_1(t, "Socrate birth", "470 BCE", "era") t = date_to_part_test_1(t, "Tite-Live birth", "59 BCE", "yyyy") t = date_to_part_test_1(t, "Tite-Live death", "17", "yyyy") t = date_to_part_test_1(t, "empty", "", "yyyy") t = date_to_part_test_1(t, "Revolution", "14 July 1789", "mmmm") t = date_to_part_test_1(t, "Walk on Moon", "20 July 1969", " ") t = date_to_part_test_1(t, "English date", "July 20 1969", "yyyy") t = date_to_part_test_1(t, "English date", "July 20 1969", "mmmm") t = date_to_part_test_1(t, "Nelson Mandela birth", "July 1918", "yyyy") t = date_to_part_test_1(t, "Nelson Mandela death", "5 Decembre 2013", "dd") t = t .. viewer.Te() -- see https://fr.wikipedia.org/wiki/Discussion:ISO_8601#Av._J.C._:_contradiction_avec_l.27article_anglais -- see https://fr.wikipedia.org/w/index.php?title=ISO_8601&diff=next&oldid=12449725 -- see ISO 8601 time format like : 1977-04-22T01:00:00-05:00 (5 heures de décalage) = 1977-04-22T06:00:00Z local time -- os.date( format, time ) get datetime events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- function viewer.parts_of_date_tests(t) function viewer.tableView(tabView) -- Form a table with lines and columns. Using a tableView object. local memo = events.save_configs() -- Save global configuration before eventual changes. if type(tabView) ~= "table" then tabView = {} end -- tabView must be a table local tabView = mw.clone(tabView) tabView.t = (tabView.t or "") .. viewer.ta("tableView: ", "tabView.t:") local err = nil -- viewer.form9user("viewer_tableView_tests_title") local t = "" function tabView.tableView_form_one_case(case) -- Generally to define: Convert a case from testGroup to rowGroup. return case end tabView = viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- t = t .. tabView.t -- internal track for debug t = t .. tabView.form_whole_tableView() -- Form whole the viewer.tableView() events.restore_configs(memo) -- Restore global configurations after eventual changes. return t, err, tabView end -- function viewer.tableView(tabView) function viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. memo = events.save_configs() -- Save global configuration before eventual changes. if type(tabView) ~= "table" then tabView = {} end -- tabView must be a table tabView.headers = tabView.headers or "viewer_tableView_tests_headers" tabView.headers = viewer.form9user(tabView.headers) tabView.form_elem_detail = tabView.form_elem_detail or "viewer_tabView_form_elem_detail" -- "detail = %1 | %2 | %3 | %4 | %5." tabView.headers_class = tabView.headers_class or "wikitable alternative center" -- headers_class = "wikitable alternative center sortable", -- A triable table start with : {| class="wikitable sortable" -- A column become fix and not triable with : ||class="unsortable"| tabView.tableStyle = tabView.tableStyle or " " tabView.testGroup = tabView.testGroup or { { "abc", 123, "A1, B2, C3" }, { "equation", "y =", "a * x2 + b * x + c" }, { "Matrix:", { "2.1.0", "v4-6, ISO_8601, FC14 h6" } }, { "pi = ", 3.14, "circle / diameter" }, { "quadrature", "function end", "convert a square to a circle" }, } tabView.t = (tabView.t or "") .. viewer.ta("tableView.tabView.testGroup: ", #tabView.testGroup) -- track to debug tabView.rowGroup = tabView.rowGroup or {} function tableView_form_one_case(case) -- Default: Convert a case from testGroup to rowGroup. local tocase = case -- {} -- for i, val in pairs(case) do table.insert( tocase, val) end tabView.t = tabView.t .. viewer.ta("tableView_form_one_case#tocase: ", #tocase) -- track to debug return tocase end tabView.tableView_form_one_case = tabView.tableView_form_one_case or tableView_form_one_case function tabView.add_Row(case) -- Default: Add a row to rowGroup. tabView.t = tabView.t .. viewer.ta("add_Row-#case: ", #case) -- track to debug table.insert( tabView.rowGroup, case) end -- In other tableView objects this function could, from each case, select or duplicate some rows. function tabView.tableView_form_all_cases() -- Default: Convert all tests cases from testGroup to rowGroup. -- local memo = events.save_configs() -- Save global configuration before eventual changes. tabView.t = tabView.t .. viewer.ta("start#testGroup", #tabView.testGroup) -- track to debug tabView.t = tabView.t .. viewer.ta("start#rowGroup", #tabView.rowGroup) -- track to debug for i, case in ipairs(tabView.testGroup) do tabView.t = tabView.t .. viewer.ta("i", i) -- local tocase = {} if type(case) ~= "table" then case = { case } tabView.t = tabView.t .. viewer.ta("case={no_table}", i) end -- Cases must be tables of values. if type(tabView.tableView_form_one_case) == "function" then -- Convert all tests cases from testGroup to rowGroup. case = tabView.tableView_form_one_case(case) -- Form one case tabView.t = tabView.t .. viewer.ta("one.is_function", i) else case = case -- if tableView_form_one_case() is not defined, do not Form the case tabView.t = tabView.t .. viewer.ta("one.not_function", i) end -- if (type(case) == "table") and (type(tabView.add_Row) == "function") then -- Do not fail if case is nil or {}. -- tabView.add_Row(case) if (type(case) == "table") and (type(tabView.rowGroup) == "table") then -- Do not fail if case is nil or {}. table.insert( tabView.rowGroup, case) tabView.t = tabView.t .. viewer.ta("one.#case", #case) -- track to debug tabView.t = tabView.t .. viewer.ta("one.insert", i) -- track to debug end end tabView.t = tabView.t .. viewer.ta("end#testGroup", #tabView.testGroup) -- track to debug tabView.t = tabView.t .. viewer.ta("end#rowGroup", #tabView.rowGroup) -- track to debug -- t = (t or "") .. viewer.ta("support_central_modules: ", "end") -- events.restore_configs(memo) -- Restore global configurations after eventual changes. end function tabView.form_whole_tableView(headers_class) -- Form whole the viewer.tableView() -- local memo = events.save_configs() -- Save global configuration before eventual changes. local t = viewer.Th(headers_class or tabView.headers_class) local head = mw.text.split( viewer.form9user(tabView.headers), ";") for i, header in ipairs(head) do -- Form headers of the table. t = t .. viewer.Tc(header) end for row_i, columns_i in ipairs(tabView.rowGroup) do -- Form the content of each of rows. t = t .. viewer.Tr() for col, val in ipairs(columns_i) do t = t .. viewer.Td(val) -- each value in columns of row_i end end t = t .. viewer.Te() -- Do not events.restore_configs(memo) to not disturb adaptations events.restore_configs(memo) -- Restore global configurations after eventual changes. return t end -- Do not events.restore_configs(memo) to not disturb adaptations events.restore_configs(memo) -- Restore global configurations after eventual changes. return tabView end -- function viewer.tableView_adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. function viewer.tableView_test() -- Test viewer.tableView() return viewer.tableView() -- "viewer_tableView_tests_title" -- Form a table with lines and columns. end function viewer.docSection(selector, section, style) -- res = res .. viewer.docSection(selector, "viewer_page_tests_h2_title", "h2") -- example -- selector = "allwaysview" -- To allways display one view. local res = "" if type(section) ~= "string" then section = "missing section" end if type(style) ~= "string" then style = "h3" end if not ( (selector == true) or (selector == section) or (selector == "allwaysview") or (selector == "alltestsview") or (selector == "enforcerun") ) then return "" end if selector == "allwaysview" then local sec = viewer.form9user(section) -- debug not translate -- res = res .. viewer.form9user("<%1>" .. sec .. "</%1>", style) -- debug style ok res = res .. "<" .. style .. ">" .. sec .. "</" .. style .. ">" -- debug style ok end viewer.docSection_t = res return res end -- function viewer.docSection(selector, section, style) --[[ function tools.dropbox(title, content, boxstyle) -- Deprecated alias function versioning.deprecatedFunction("tools.dropbox", "viewer.DropBox") return viewer.DropBox(title, content, boxstyle) end --]] function viewer.DropBox(title, content, boxstyle) -- Form a drop box. Formar un cuadro desplegable. Former une boite déroulante. -- Easy Dropbox style from a list of named options. -- alignT, image, alignB, margin_bottom, width, border_radius, border_color, background_color) -- Original code from fr.wikisource : "{{Boîte déroulante/début|titre=" .. title .. "|alignT=" .. alignT .. "}}" .. content .. "{{Boîte déroulante/fin}}" if type(title) ~= "string" then title = "viewer_dropdown_missing_title" end title = viewer.form9user(title) local s = { -- options for style and other image = nil, 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 = "#AAAAAA", -- border-color height = "1.6em", -- height display = "block", -- not efficient, "block" to view, "none" to mask the list label = "▼ /▶ ", -- = "Unwrap/Wrap", -- ▼ = ▼ -- ▶ = ▶ https://fr.wikipedia.org/wiki/Table_des_caract%C3%A8res_Unicode/U25A0 -- label = label or viewer.form9user("viewer_DropBox_label_Unwrap"), -- = "Unwrap/Wrap", = "Unwrap/Wrap", } s.title = title -- s.content = content or "no s.content" s.content = tostring(content) if type(boxstyle) == "table" then for key, val in pairs(boxstyle) do if type(val) == "string" then s[key] = val end end end -- local txt = "{{Boîte déroulante/début|titre=" .. title .. "|alignT=" .. alignT .. "}}" .. content .. "{{Boîte déroulante/fin}}" -- image = image or "Nuvola_apps_bookcase_2.svg" -- image if type(s.image) == "string" then s.image = '' .. '<div class="NavPic" style=" background-color:' .. s.background_color .. '; " >' .. '[[File:' .. s.image .. '|22px]]' .. '</div>' -- else s.image = '' end -- local res = '<div>' -- try to debug task T20151215 -- local res = '</div><div> </div>' -- try to debug task T20151215 local res = '' .. "\n------ " -- This code interact with DropBox and debug the task T20151215 2016-11-13 17:57. -- Original code from wikisource : "{{Boîte déroulante/début|titre=" .. title .. "|alignT=" .. alignT .. "}}" .. content .. "{{Boîte déroulante/fin}}" .. '<div align="'.. s.alignB ..'" >' .. '<div class="NavFrame" style="clear:both; margin-bottom:'.. s.margin_bottom ..'; width:'.. s.width ..'; border-style:solid; -moz-border-radius:'.. s.border_radius ..'; border-color:'.. s.border_color ..'; background-color:'.. s.background_color ..'; " title="'.. s.label ..'" >' .. '<div class="NavHead" align="'.. s.alignT ..'" style=" height:'.. s.height ..'; background-color:'.. s.background_color ..'; color:'.. s.text_color ..'; " >' .. s.title .. '</div>' .. '<div class="NavContent" align="'.. s.alignB ..'" style="margin:'.. s.margin_all ..'; background-color:'.. s.background_color ..'; display=block; " >' .. s.image .. s.content .. '</div>' .. '</div>' .. '</div>' --[[ -- alternative dropbox for template optimisation. Misses title. local res = '' .. '<div class="templatesUsed">' -- \n------ .. '<div class="mw-templatesUsedExplanation mw-editfooter-toggler mw-icon-arrow-expanded" tabindex="0" role="button">' .. '<ul class="mw-editfooter-list mw-collapsible mw-crashd" style="display: none;"><p>' .. s.title .. '</p></ul>' .. '<li>' .. s.image .. s.content .. '</li>' .. '</div>' .. '</div>' --]] viewer.DropBox_t = res return res end -- function viewer.DropBox(title, content, boxstyle) --[==[ How to code a local note in html: * content with a note <sup>[[#binop-note|†]]</sup> <div id="binop-note" >content of the note</div> --]==] -- Rical 2017-02-07 from https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Metatables -- libraryUtil.makeCheckSelfFunction( libraryName, varName, selfObj, selfObjDesc ) function viewer.docDropBoxTitle() -- Support desk title of the docDropBox of the edit box. -- versioning_support_desk_title = "Support desk for %1 : %2 translations in %3 languages", -- en -- versioning_support_desk_table = "viewer.docDropBoxTitle", local tot_vars, tot_tabs, tot_func, vr_tb = luaTable.SubCounts(translate.main_i18n, "translate.main_i18n") local title = viewer.form9user("versioning_support_desk_title", versioning.report_main_discreet, vr_tb, tot_tabs) return title end -- function viewer.docDropBoxTitle() function viewer.docDropBox(selector, title, content_or_func, ...) -- Form a DropBox for a doc or a group of tests. -- Style options in boxstyle{}: alignT, image, alignB, margin_bottom, width, border_radius, border_color, background_color) -- selector = "allwaysview" -- To allways display one view. -- selector = "enforcerun" -- To debug one box with INTERNAL ERROR. local memo = events.save_configs() -- Save global configuration before eventual changes. local t = "" if not ( (selector == true) or (selector == title) or viewer.is_in_sp(selector, "allwaysview alltestsview enforcerun failinref nocontent") ) then return "" end local Default_title = "Default counts in %1: %2 translations e=in %3 languages" if (type(title) ~= "string") then title = Default_title end local key_title = title local informed_title = title local key_table = string.sub(key_title, 1, -7) .. "_table" -- in key_title replace "_title" with "_table" local subnames = viewer.form9user(key_table) -- "translate.main_i18n" -- example if subnames ~= key_table then -- If key_table exist, use it. t = t .."tag docDropBox : " t = t ..", key_title="..key_title t = t ..", key_table="..key_table t = t ..", use key_table: " local subnames_split = mw.text.split(subnames, ";") -- "translate.main_i18n;string" -- example local subnames = subnames_split[1] or subnames -- "translate.main_i18n" -- example local sub_type = subnames_split[2] or "string" -- "string" -- example t = t ..", sub_type="..sub_type local object_loaded, sub_names, count = luaTable.from_subnames(subnames, base_table, sub_type) -- Get the last sub-table from its sub-names. local tot_vars, tot_tabs, tot_func, vr_tb = 0, 0, 0, 0 -- if (type(object_loaded) == "string") then -- and (type(sub_type) == "string") The string is a subtable name. tot_vars, tot_tabs, tot_func, vr_tb = luaTable.SubCounts(object_loaded) -- counts of translations informed_title = viewer.form9user(key_title, subnames, vr_tb, tot_tabs) -- final title t = t ..",s"..","..tostring(vr_tb) -- elseif (type(object_loaded) == "function") then -- and (type(sub_type) == "function") The function computes counts of translations. informed_title = object_loaded() -- like viewer.docDropBoxTitle() -- Title of the title box of the edit box. t = t ..",f"..","..tostring(vr_tb) -- elseif (type(object_loaded) == "table") then -- and (type(sub_type) == "table") The table is a subtable to count. informed_title = informed_title t = t ..",t"..","..tostring(vr_tb) --Fonction d'aide : end end -- new code end local args = { ... } -- optional arguments local boxstyle = {} for i, tab in ipairs(args) do -- Get the style options for the box, modes.recursiveLoop = (modes.recursiveLoop or 0) + 1 if modes.recursiveLoop > 3 then return "" end if type(tab) == "table" and tab.boxstyle == "boxstyle" then boxstyle = mw.clone( args[i] ) args[i] = nil -- then mask this style for functions giving the content. end end local success, result = true, "" if type(title) ~= "string" then title = "viewer_dropdown_missing_title" end local ac_opt = {} -- for antiCrash ac_opt.selector = selector ac_opt.title = tostring(informed_title or title) -- ..","..tostring(vr_tb) -- .. viewer.ta("type", sub_type) .. viewer.ta("vr_tb", vr_tb) .. viewer.ta("key_title", key_title) .. viewer.ta("tot_tabs", tot_tabs) ac_opt.content = content_or_func ac_opt.success = true ac_opt.content_error = "" if type(content_or_func) == "function" then local memo = events.save_configs() -- Save global configuration before eventual changes. ac_opt.content, ac_opt.title_errors = content_or_func( ... ) events.restore_configs(memo) -- Restore global configurations after eventual changes. end ac_opt.title = ac_opt.title .. ( ac_opt.title_errors or "" ) ac_opt.resultKind = "ref" ac_opt.result = "" -- local contt, ac_opt = versioning.antiCrash(ac_opt, content_or_func, ...) -- Form the display of a running error. local res = viewer.DropBox(ac_opt.title, ac_opt.content, boxstyle) if not ac_opt.success then ac_opt.content_ref = "content_error<ref>" .. viewer.errorColor( ac_opt.content_error) .. "</ref>" ac_opt.content = ac_opt.content_ref end local list, count, level, split = luaTable.level_list(package.loaded) -- res = "* level_list = { " .. list .. " } ; " .. res -- translate.track_i18n(tostring(title) .. ":End") events.restore_configs(memo) -- Restore global configurations after eventual changes. return res -- t .. res end -- function viewer.docDropBox(selector, title, content, ...) function viewer.formResult(options_for_modes, mode) -- Forms the result using actual mode options -- viewer.formResult(p.options_for_modes, "edit") -- example -- local res = res .. versioning.init(frame, Central_version) -- res = res .. translate.track_language("viewer.formResul()") local res, options = "\n* viewer.formResult : ", "" if type(options_for_modes) ~= "table" then options_for_modes = modes.options_for_modes end local opt_t, elem, module, normal, alias, name_I18N -- collect all options options = tostring(modes.mode_options) .. tostring(modes.invoke_options) res = res .. viewer.ta("options_for_modes", options_for_modes) res = res .. viewer.ta("mode", mode) res = res .. viewer.ta("options", options) if (type(options_for_modes) == "table") then local options_tab = mw.text.split(options, " ", true) for i, opt in ipairs(options_tab) do -- run all options res = res .. viewer.ta("i", i) .. tostring(opt) if (type(opt) == "function") and (type(opt) == "function") then opt_t = opt res = res .. viewer.value(opt) .. tostring(opt_t) elseif (type(opt) == "string") and (opt ~= "") and (type(viewer[opt]) == "function") then if opt == "docGroup" then opt_t = viewer.docGroup("allwaysview") else opt_t = viewer[opt] end res = res .. viewer.value(opt) .. viewer.ta("viewer[opt]", type(viewer[opt])) .. tostring(opt_t) elseif (type(opt) == "string") and (opt ~= "") and (type(viewer[opt]) == "string") then opt_t = viewer[opt] res = res .. viewer.value(opt) .. viewer.ta("viewer[opt]", type(viewer[opt])) .. tostring(opt_t) elseif (type(opt) == "string") and (opt ~= "") then opt_t = opt res = res .. viewer.ta("i", i) .. viewer.value(opt) .. tostring(opt_t) end end end res = res .. "<br/><br/>" viewer.formResult_t = res return res end -- function viewer.formResult() function viewer.docPage(selector, itemid) -- Form some dropboxes of tests to document a page. local memo = events.init_configs() -- Save global configuration before eventual changes. local res = "" res = res .. viewer.docSection(selector, "viewer_page_tests_h2_title", "h2") -- on viewer.docDropBox( res = res .. viewer.docDropBox(selector, "modes_used_options_title", modes.used_options_list ) res = res .. viewer.docDropBox(selector, "modes_list_all_args_main_title", modes.list_all_args_main) -- to_debug_on 20170409 res = res .. "\n------ " -- This code interact with DropBox and debug the bug T20151215 2016-11-13 17:57. res = res .. viewer.docDropBox(selector, "translate_translationsCounts_title", translate.translationsCounts) res = res .. viewer.docDropBox(selector, "luaTable_table_args_source_title", luaTable.structure, modes.args_source, "modes.args_source") res = res .. viewer.docDropBox(selector, "modes_args_known_structure_title", modes.args_known_structure) -- to_debug_on 20170409 events.restore_configs(memo) -- Restore global configurations after eventual changes. return res end -- function viewer.docPage(selector, itemid) function viewer.docModule(selector, itemid) -- Form some dropboxes of tests to document a module. local memo = events.init_configs() -- Init a new events group local res = "" -- res = res .. viewer.form9user("begin_support_central_modules_title") .. " docModule " -- global _G versioning.list_all_G_and_loaded : Variables in _G global space = , br = Modulenn:Central-w-br/doc , br = Modulenn:Central-s-br/doc res = res .. viewer.docSection(selector, "viewer_module_tests_h2_title", "h2") res = res .. viewer.docDropBox(selector, "luaTable_table_args_unknown_title", luaTable.structure, modes.args_unknown, "modes.args_unknown", { boxstyle = "boxstyle", image = "Gtk-dialog-info.svg"} ) -- "[[Fichier:Gtk-dialog-info.svg|15px]]" res = res .. viewer.docDropBox(selector, "versioning_support_desk_title", versioning.form_support_desk_report ) -- versioning.support_desk_report -- versioning.form_support_desk_report() -- begin.follow_central_modules() Suivre le début de l'utilisation des modules centraux. res = res .. viewer.docDropBox(selector, "begin_support_central_modules_title", begin.support_begin_central_modules ) res = res .. viewer.docDropBox(selector, "begin_survey_sub_tasks_title", begin.survey_sub_tasks ) res = res .. viewer.docDropBox(selector, "modes_brief_options_mode_title", modes.options_from_mode_tests) res = res .. viewer.docDropBox(selector, "modes_all_categories_list_title", modes.all_categories_list) res = res .. viewer.docDropBox(selector, "modes_all_errors_list_title", modes.all_errors_list) events.restore_configs(memo) -- Restore global configurations after eventual changes. return res end -- function viewer.docModule(selector, itemid) function viewer.docInternal(selector, itemid) -- Form some dropboxes of tests to document internal functions. local memo = events.init_configs() -- Init a new events group local res = "" res = res .. viewer.docSection(selector, "viewer_internal_tests_h2_title", "h2") -- res = res .. viewer.docSection(selector, "Library:begin", "h3") res = res .. viewer.docDropBox(selector, "begin_support_central_modules_title", begin.support_begin_central_modules ) res = res .. viewer.docDropBox(selector, "begin_survey_sub_tasks_title", begin.survey_sub_tasks) res = res .. viewer.docDropBox(selector, "<b>begin.init_selected_wiki()</b> Test some wiki inits", begin.init_selected_wiki_test) res = res .. viewer.docDropBox(selector, "begin_links_to_central_modules_title", begin.links_to_central_modules) -- res = res .. viewer.docSection(selector, "Library:datas", "h3") -- res = res .. viewer.docDropBox(selector, "datas_wikidata_arbitrary_tests_title", datas.wikidata_arbitrary_tests ) -- { boxstyle = "boxstyle", image = "Gtk-dialog-info.svg"} ) res = res .. viewer.docDropBox(selector, "datas_wikidata_time_details_title", luaTable.structure, datas.wikidata_time_details) --, "datas.wikidata_time_details.claims." .. (datas.TimeName or "Pxxx") ) -- res = res .. viewer.docSection(selector, "Library:events", "h3") res = res .. viewer.docDropBox(selector, "events_all_kinds_tests_title", events.all_kinds_test) res = res .. viewer.docDropBox(selector, "events_categ_Test_title", events.categ_Test) -- to_debug_on 20170409 res = res .. viewer.docDropBox(selector, "events_selectLang_tests_title", events.selectLang_test) -- res = res .. viewer.docSection(selector, "Library:luaTable", "h3") res = res .. viewer.docDropBox(selector, "luaTable_from_subnames_test_title", luaTable.from_subnames_test ) res = res .. viewer.docDropBox(selector, "luaTable_roughView_tests_title", luaTable.roughView_test ) res = res .. viewer.docDropBox(selector, "luaTable_structure_nolimits_title", luaTable.structure, luaTable.tablim, "luaTable.tablim", {} ) res = res .. viewer.docDropBox(selector, "luaTable_structure_limits_title", luaTable.structure, luaTable.tablim, "luaTable.tablim", { boxstyle = "boxstyle", level_maxi = 2, max_n = 2, exclude1 = "hou" } ) -- , {width = "88%", text_color = "blue"} res = res .. viewer.docDropBox(selector, "luaTable_toList_tests_title", luaTable.toList_tests) res = res .. viewer.docDropBox(selector, "luaTable_toTable_tests_title", luaTable.toTable_test) -- In central modules, the Library:mathroman is a simple example of central modules support for any library. res = res .. viewer.docSection(selector, "Library:mathroman", "h3") res = res .. viewer.docDropBox(selector, "mathroman_roman2int_tests_title", mathroman.roman2int_tests) -- to_debug_on 20170409 res = res .. viewer.docDropBox(selector, "mathroman_int2roman_test_title", mathroman.int2roman_test) -- to_debug_on 20170409 --"enforcerun" "allwaysview" -- res = res .. viewer.docSection(selector, "Library:modes", "h3") res = res .. viewer.docDropBox(selector, "modes_options_from_args_tests_title", modes.options_from_args_tests) res = res .. viewer.docDropBox(selector, "modes_brief_options_mode_title", modes.options_from_mode_tests, { boxstyle = "boxstyle", width = "80%", text_color="green", alignT="left", alignB="center", margin_all="2em", background_color="yellow", border_color="red", height="2em", image="Gtk-dialog-info.svg"} ) res = res .. viewer.docDropBox(selector, "modes_options_from_mode_tests_title", modes.options_from_mode_tests, { boxstyle = "boxstyle", width = "80%", text_color="green", alignT="left", alignB="center", margin_all="3em", background_color="yellow", border_color="red", height="2em", image="Gtk-dialog-info.svg"} ) -- "[[Fichier:Gtk-dialog-info.svg|15px]]" res = res .. viewer.docDropBox(selector, "modes_recursiveNormal_tests_title", modes.recursiveNormal_tests ) -- arguments list res = res .. viewer.docDropBox(selector, "modes_all_categories_list_title", modes.all_categories_list) res = res .. viewer.docDropBox(selector, "modes_all_errors_list_title", modes.all_errors_list) -- arguments support res = res .. viewer.docDropBox(selector, "modes_multiple_selection_tests_title", modes.multiple_selection_tests) -- res = res .. viewer.docDropBox(selector, "modes_multiple_values_tests_title", modes.multiple_values_tests) res = res .. viewer.docDropBox(selector, "modes_similar_args_searchs_title", modes.similar_args_search_tests) -- to_debug_on 20170409 res = res .. viewer.docDropBox(selector, "modes_similar_levenshtein_tests_title", modes.similar_levenshtein_tests) res = res .. viewer.docDropBox(selector, "modes_spaces_names_page_title", modes.spacesNamesPageTest) -- "enforcerun" -- res = res .. viewer.docSection(selector, "Library:testsCases", "h3") res = res .. viewer.docDropBox(selector, "testsCases_group_Diffs_tests_title", testsCases.group_Diffs_tests ) -- Tests and report detailed differences, recursive. res = res .. viewer.docDropBox(selector, "testsCases_search_Diffs_tests_title", testsCases.search_Diffs_tests ) -- Tests and report detailed differences, recursive. res = res .. viewer.docDropBox(selector, "testsCases_tests_Cases_report_title", testsCases.tests_Cases_report ) -- Run a group of tests and returns one string. -- translations support res = res .. viewer.docSection(selector, "Library:translate", "h3") -- res = res .. translate.track_counts("Library:translate:begin", "versioning.i18n", trans, tables, versioning.i18n) -- res = res .. translate.track_counts("Library:translate:begin", "translate.i18n", trans, tables, translate.i18n) -- res = res .. translate.track_counts("Library:translate:begin", "versioning.main_i18n", trans, tables, versioning.main_i18n) -- res = res .. translate.track_counts("Library:translate:begin", "translate.main_i18n", trans, tables, translate.main_i18n) res = res .. viewer.docDropBox(selector, "translate_translationsCounts_title", translate.translationsCounts) -- to_debug_on 20170409 res = res .. viewer.docDropBox(selector, "translate_changing_translations_title", translate.changing_translations) --, i18n, t) res = res .. viewer.docDropBox(selector, "translate_missing_translations_title", translate.missing_translations) res = res .. viewer.docDropBox(selector, "translate_dummy_languages_title", translate.dummy_languages) -- res = res .. viewer.docDropBox(selector, "translate_mixed_translations_title", translate.i18n_lister) res = res .. viewer.docDropBox(selector, "translate_abnormal_char_in_text_title", translate.abnormal_char_in_text ) -- res = res .. viewer.docDropBox(selector, "translate_list_Mediawiki_languages_title", translate.list_Mediawiki_languages ) -- res = res .. translate.track_counts("Library:translate:end", "translate.i18n", trans, tables, translate.i18n) -- res = res .. translate.track_counts("Library:translate:end", "versioning.main_i18n", trans, tables, versioning.main_i18n) -- res = res .. translate.track_counts("Library:translate:end", "translate.main_i18n", trans, tables, translate.main_i18n) --"allwaysview" -- res = res .. viewer.docSection(selector, "Library:versioning", "h3") res = res .. viewer.docDropBox(selector, "versioning_versions_management_report", versioning.versions_management_report ) res = res .. viewer.docDropBox(selector, "versioning_list_all_G_and_loaded_title", versioning.list_all_G_and_loaded) -- res = res .. translate.track_counts("versioning_list_all_G:end", "translate.i18n", trans, tables, translate.i18n) -- res = res .. translate.track_counts("versioning_list_all_G:end", "translate.main_i18n", trans, tables, translate.main_i18n) res = res .. viewer.docDropBox(selector, "versioning_bind_modules_report_title", versioning.bind_central_modules_report ) res = res .. viewer.docDropBox(selector, "versioning_deprecatedFunction_tests_title", versioning.deprecatedFunction_test) -- res = res .. viewer.docDropBox(selector, "versioning_bind_modules_tests_title", versioning.bind_modules_test ) res = res .. viewer.docDropBox(selector, "versioning_sort_central_modules_title", versioning.sort_central_modules_report ) res = res .. viewer.docDropBox(selector, "versioning_tasks_report_title", versioning.versioning_tasks_report ) res = res .. viewer.docDropBox("nocontent", "versioning.antiCrash_tests() selector=nocontent", viewer.simpleList_test ) -- Test antiCrash() -- res = res .. versioning.antiCrash_tests() res = res .. viewer.docDropBox(selector, "versioning_antiCrash_tests_title", versioning.antiCrash_tests ) -- Tests antiCrash() res = res .. viewer.docDropBox(selector, "versioning_dev_running_times_title", versioning.running_times ) -- versioning.running_times() -- res = res .. viewer.docSection(selector, "Library:viewer", "h3") -- The Library:viewer forms some viewers for tables(in lines and columns), dropboxes, recursive luatables... res = res .. viewer.docDropBox(selector, "viewer_form9user_tests_title", viewer.form9user_test ) res = res .. viewer.docDropBox(selector, "viewer_form99user_tests_title", viewer.form99user_test ) res = res .. viewer.docDropBox(selector, "viewer_format_time_tests_title", viewer.format_time_tests) res = res .. viewer.docDropBox(selector, "viewer_parts_of_date_tests_title", viewer.parts_of_date_tests) res = res .. viewer.docDropBox(selector, "viewer_simpleList_tests_title", viewer.simpleList_test ) res = res .. viewer.docDropBox(selector, "viewer_table_tabOptions_title", viewer.table_test ) res = res .. viewer.docDropBox(selector, "viewer_tableView_tests_title", viewer.tableView_test ) events.restore_configs(memo) -- Restore global configurations after eventual changes. return res end -- function viewer.docInternal(selector, itemid) function viewer.testsview(t) -- Deprecated alias function versioning.deprecatedFunction("viewer.testsview", "viewer.docGroup") return viewer.docGroup(t) end function viewer.docGroup(selector, itemid) -- Form a documentation of one dropbox or all. local memo = events.init_configs(memo_tests) -- Init a new events group local res = "" res = res .. viewer.docPage(selector, itemid) res = res .. viewer.docModule(selector, itemid) res = res .. viewer.docInternal(selector, itemid) -- res = res .. versioning.antiLoop_list() -- List versioning.antiLoop(). viewer.docGroup_t = res events.restore_configs(memo) -- Restore global configurations after eventual changes. return res end -- function viewer.docGroup(selector, itemid) -- - - - ------------------ - - - - --------------------------------- -- Try part of Module:Central -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- At code level, try part tests show how to use libraries: -- * To convert a module as centralisable using functions(frame). -- * To form categories, errors and warnings, their collection and their activations. -- * To form dropboxes and tableform with translatable headers. -- * To display the structure of an internal luatable, to parameter this display and to get its counts of elements. -- -- At page level, try part tests show how to use libraries: -- * To get the wikitext resulting of a module in read or edit or tests or doc1 mode. -- * In edit mode, a docbox display received arguments, errors and categories. -- * In test mode, several dropboxes display many cases of tests that anybody can read and verify. -- * These tests verify libraries and tools. -- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - --------------------------------- -- 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. -- -- Errors are needed to test their detection. Do not correct them. -- Errores se necesitan para probar su detección. No corregirlos se. -- Les erreurs sont nécessaires pour tester leur détection. Ne pas les corriger. -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- Tables of translations of settings and warnings in the languages : en, es, fr. -- Mesas traducciones parámetros y mensajes en los idiomas : en, es, fr. -- Tables des traductions des paramètres et warnings dans les langues : en, es, fr. -- -- i18n translations tables to extend and update in calling modules -- - - - ------------------ - - - - --------------------------------- p.i18n = {} -- translations tables known in the module p.i18n.en = { -- Arguments linked to the main module lastname = 'name', lastname_descr = "Family name. Please specify to correct the sort key.", firstname = 'firstname', firstname_descr = "First name. Please specify to correct the sort key.", firstname2 = 'firstname', firstname2_descr = "First name. Please specify to correct the sort key.", initiale = 'initial', initiale_descr = "Initial to correct the category of authors.", title = 'title', title_descr = "Page title, automatic.", country = 'country', flag_of_country = 'Flag of England.svg', flag_of_country_descr = 'Flag of the country', occupation_cat = '%1', year_number_cat = "Year %1", birthyear = 'birthyear', -- birthyear P569 for test p_authors_birthyear_cat birthyear_descr = "Year of birth.", p_authors_birthyear_cat = "%1 births", -- en.wikisource 1802 births - 1885 deaths deathyear = 'deathyear', -- deathyear P570 for test p_authors_deathyear_cat deathyear_descr = "Year of death.", p_authors_deathyear_cat = "%1 deaths", -- en.wikisource 1802 births - 1885 deaths description = 'description', description_descr = "Author's description, to clarify whether the automatic description does not fit.", -- Arguments limited to multiple values region = 'region', -- argument with verified multiple values region_descr = 'Region to determine the ancient periods.', region_values = 'other;china;india;century', -- wiki_selectors rights = 'rights', rights_descr = "Necessary copyrights type: 70,50,mpf,ONU,non.", rights_values = '70;50;mpf;ONU;none', sex = 'sex', sex_descr = 'Genre of the author', sex_values = 'male;female', } -- p.i18n.en p.i18n.es = { -- Argumentos relacionados con el módulo principal occupation_cat = '%1', p_authors_deathyear_cat = "Autores-%1", year_number_cat = "Año %1", -- Nombres y descripciones de los argumentos lastname = 'nombre', lastname_descr = "Nombre. Por favor, especifique para corregir la clave de ordenación.", firstname = 'apellido', firstname_descr = "Primero. Proponer para corregir la autómata.", firstname2 = 'primero', firstname2_descr = "Primero. Proponer para corregir la autómata.", initiale = 'inicial', initiale_descr = "Inicial para corregir la categoría de los autores.", title = 'titulo', title_descr = "Título de la página, automático.", country = 'país', flag_of_country = 'Flag_of_Spain.svg', flag_of_country_descr = 'Bandera del país', birthyear = 'nacimiento', birthyear_descr = "Año de nacimiento.", p_authors_birthyear_cat = "N%1", -- es.wikisource N1802 - F1885 deathyear = 'muerte', deathyear_descr = "Año de la muerte.", p_authors_deathyear_cat = "F%1", -- es.wikisource N1802 - F1885 description = 'descripcion', description_descr = "Descripción del autor, para aclarar si la descripción automática no encaja.", -- Argumentos limitados a múltiples valores region = 'región', region_descr = 'Región para determinar los tiempos antiguos.', region_values = "otro;china;india;siglo", rights = 'derechos', rights_descr = "Tipo de derechos de autor necesario: 70,50,mpf,ONU,non.", rights_values = '70;50;mpf;ONU;no', sex = 'sex', sex_descr = 'Género del autor', sex_values = 'hombre;mujer', } -- p.i18n.es p.i18n.fr = { -- Arguments liés au module principal occupation_cat = '%1', p_authors_deathyear_cat = "Auteurs-%1", year_number_cat = "Année %1", -- Noms et descriptions des arguments lastname = 'nom', lastname_descr = "Nom. A préciser pour corriger la clé de tri.", firstname = 'prénom', firstname_descr = "Prénom. A préciser pour corriger la clé de tri.", firstname2 = 'prenom', firstname2_descr = "Prénom. A préciser pour corriger la clé de tri.", initiale = 'initiale', initiale_descr = "Initiale pour corriger les catégories d'ateurs.", title = 'titre', title_descr = "Titre de la page, automatique.", country = 'pays', flag_of_country = 'Flag_of_France.svg', flag_of_country_descr = 'Drapeau du pays', birthyear = 'anneeNaissance', birthyear_descr = "Année de naissance", p_authors_birthyear_cat = "Naissance en %1", -- fr.wikisource Naissance en 1802 Décès en 1885 deathyear = 'anneeDeces', deathyear_descr = "Année de décès", p_authors_deathyear_cat = "Décès en %1", -- fr.wikisource Naissance en 1802 Décès en 1885 description = 'description', description_descr = "Description de l'auteur, à préciser si la description automatique ne convient pas", -- Arguments limités à des valeurs multiples region = 'région', region_descr = 'Région pour déterminer les époques anciennes.', region_values = "autre;chine;inde;siècle", -- wiki_selectors rights = 'droits', rights_descr = "Type de droits d'auteur nécessaire parmi : 70,50,mpf,ONU,non.", rights_values = '70;50;mpf;ONU;non', sex = 'sexe', sex_descr = "Sexe de l'auteur", sex_values = 'homme;femme', } -- p.i18n.fr -- - - - ------------------ - - - - --------------------------------- -- p.i18n tables end -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- Arguments table, to change in calling modules -- - - - ------------------ - - - - --------------------------------- p.args_known = { -- Table of the definitions of all known arguments at module level. -- Arguments in order without names, with their keyword for use as other arguments. -- Arguments dans l'ordre, non nommés, avec leur keyword pour traitement comme les autres arguments. [1] = {need = 0, syn = 2, keyword = "mode"}, -- Special arguments to modify the fonctions and outputs of this module. -- Arguments speciaux pour modifier le fonctionnement et les sorties de ce module. mode = {typ = "config", need = 0, keyword = "mode"}, c = {typ = "config", need = 0, keyword = "c"}, options = {typ = "config", need = 0, keyword = "options"}, -- The userlang argument permits at an administrator in his own langage (errors, warnings, catégories, tests) to help a wiki in any language. -- El userlang argumento permisos en administrador en su propia langage (errores, advertencias, categorías, pruebas) para ayudar a un wiki en cualquier idioma. -- L'argument userlang permet à un administrateur dans son propre langage (erreurs, warnings, catégories, tests) d'aider un wiki dans ne importe quelle langue. -- userlang = {typ = "config", need = 0, -- keyword = "userlang"}, -- The wikilang argument permits to verify in one unique wiki that a module can well adapt itself to any wiki language. -- Los argumento wikilang permisos para verificar en una wiki único que un módulo puede así adaptarse a cualquier idioma de wiki. -- L'argument wikilang permet de vérifier dans un wiki unique qu'un module peut s'adapter à n'importe quelle langue de wiki. -- wikilang = {typ = "config", need = 0, -- keyword = "wikilang"}, -- allversions = {typ = "config", need = 0, -- keyword = "allversions"}, knownversions = {typ = "config", need = 0, keyword = "knownversions"}, -- selectversions = {typ = "config", need = 0, -- keyword = "selectversions"}, soughtversions = {typ = "config", need = 0, keyword = "soughtversions"}, debug = {typ = "opt", need = 0, keyword = "debug"}, category = {typ = "ctr", need = 0, keyword = "category"}, -- All arguments have a keyword identical to the registration name, except synonyms. -- Tous les arguments ont un keyword identique au nom d'enregistrement, sauf les synonymes. label = {typ = "dat", need = 0, keyword = "label" , prop = "label"}, country = {typ = "dat", need = 0, keyword = "country", prop = "P27", }, sitelink = {typ = "dat", need = 0, keyword = "sitelink" , prop = "sitelink"}, itemid = {typ = "dat", need = 2, keyword = "itemid" , prop = "itemid"}, itemid2 = {typ = "dat", need = 2, syn = 2, keyword = "itemid" , prop = "itemid"}, lastname = {typ = "dat", need = 0, keyword = "lastname"}, lastname2 = {typ = "dat", need = 0, syn = 2, keyword = "lastname"}, firstname = {typ = "dat", need = 0, keyword = "firstname"}, firstname2 = {typ = "dat", need = 0, syn = 2, keyword = "firstname"}, initiale = {typ = "dat", need = 2, keyword = "initiale"}, title = {typ = "dat", need = 2, keyword = "title"}, birthyear = {typ = "dat", need = 0, keyword = "birthyear", prop = "P569", format = "year"}, deathyear = {typ = "dat", need = 0, keyword = "deathyear", prop = "P570", format = "year"}, description = {typ = "dat", need = 0, keyword = "description", prop = "description"}, sex = {keyword = "sex", typ = "dat", need = 0, prop = "P21", arg_values = "sex_values", key_values = ";", }, -- wiki_selectors region = {keyword = "region", typ = "dat", need = 0, arg_values = "region_values", key_values = "other;china;india;century" }, -- wiki_selectors rights = {keyword = "rights", typ = "dat", need = 2, arg_values = "rights_values", key_values = "no;none;ONU;none;cn;50;us;70;mpf", -- wiki_selectors delay_values = "0;0;0;0;50;50;70;70;95", arg_uses = "none;none;none;none;cn;cn;us;us;mpf" }, -- wiki_selectors } -- p.args_known -- - - - ------------------ - - - - --------------------------------- -- Arguments sources examples -- -- Errors are needed to test their detection. Do not correct them. -- Errores se necesitan para probar su detección. No corregirlos se. -- Les erreurs sont nécessaires pour tester leur détection. Ne pas les corriger. -- - - - ------------------ - - - - --------------------------------- p.WikidataEN = { label = "John Smith", deathyear = "1789", country = "France" } p.ArgtestEN = { "mode One", "Rimbaud 2", name = "Rimbaud", firstname = "Arnaud", rights = "70", deathyear = "MDCCCJL", langue = "allemand,français,espagnol" } p.ArgtestES = { nombre = "Rimbaud", apellido = "Arthur", optionsES = " ", derechoss = "70", anoMuerte = "MDCCCJL"} p.ArgtestFR = { "mode Un", "Rimbaud 2", "Jonh", nom = "Smith", ["prénom"] = "Arnaud", anneeDeces = "1234", } function p.trc(fn_mode, t) local res = "" -- to put in comment to desactivate -- res = res .. "<br>* " .. t .. viewer.ta("fn_mode", fn_mode) .. viewer.ta("modes.mode_name", modes.mode_name) .. viewer.ta("modes.mode_options", modes.mode_options) .. viewer.ta("modes.invoke_options", modes.invoke_options) res = res .. viewer.ta("trc try", viewer.form9user("viewer_internal_tests_title")) .. viewer.ta("MR", viewer.form9user("err_J_before_end")) .. viewer.ta("AT", viewer.form9user("deathyear")) return res end function p.list_all_args_sub(t, args_known) -- modes_list_all_args_main_title = List of all arguments, for try local t = t or "<br>* <b>list_all_args_sub :</b> " -- t = t or "<br>* <b>List_all_args :</b> " if type(args_known) ~= "table" then args_known = modes.args_known end local descr, description = "", "" local args = mw.clone(args_known) local arglst = {} for key, elem in pairs(args) do elem.key = tostring(key) descr = key .. "_descr" -- key for description of an argument elem.description = translate.user_translations[descr] or "**missing translation**" elem.user_lang_key = translate.user_translations[elem.key] or elem.key or "**missing key**" elem.user_lang_keyword = translate.user_translations[elem.keyword] or elem.keyword or "**missing keyword**" elem.lev_arg_txt = "" local lst_lev = {} local lev_min = 99 for arg_lev, elem_lev in pairs(args) do elem_lev.levenshtein = modes.levenshtein( translate.wiki_translations[arg_lev], translate.wiki_translations[key] ) or 99 if elem_lev.levenshtein < lev_min then lev_min = elem_lev.levenshtein elem.levenshtein = elem_lev.levenshtein elem.lev_min = lev_min elem.arg_lev = arg_lev elem.lev_lang = translate.wiki_translations[arg_lev] or arg_lev end elem.arg_lev = arg_lev elem.lev_arg_txt = viewer.ta("lev", tostring(elem.lev_lang) .. ":" .. tostring(elem.lev_min) .. ":" .. elem.arg_lev ) -- events.add_err("modes_too_unnamed_arguments_err", key_N, val_src .. " LLL lev=" .. tostring(arglst[1].levenshtein) ) -- events.add_cat("versioning_module_usage_error_cat") end table.insert(arglst, elem) end -- insert in the arguments their own key table.sort(arglst, function (a, b) return (a.user_lang_key < b.user_lang_key) end ) local gr_syn, gr_need, gr_other = {}, {}, {} for i, elem in ipairs(arglst) do -- group arguments in some groups if elem.need == 1 or elem.need == 2 then table.insert(gr_need, elem) else table.insert(gr_other, elem) end end local needed = viewer.smallCapsStyle(viewer.form9user("modes_needed_to_verify")) local function list_group( group, needed ) needed = needed or "" local t = "" for key, elem in pairs(group) do if elem.syn then t = t .. "<br>* <b>" .. tostring(elem.user_lang_key) .. "</b> => <b>" .. elem.user_lang_keyword .. "</b> : " .. needed .. " " .. tostring(elem.description) .. elem.lev_arg_txt else t = t .. "<br>* <b>" .. tostring(elem.user_lang_key) .. "</b> : " .. needed .. " " .. tostring(elem.description) .. elem.lev_arg_txt end end return t end t = t .. "<br><br>* <b>" .. viewer.form9user("modes_list_needed_args") .. "</b> " .. list_group( gr_need, needed ) t = t .. "<br><br>* <b>" .. viewer.form9user("modes_list_all_other_args") .. "</b> " .. list_group( gr_other ) return t end -- function p.list_all_args_sub(t, args_known) -- modes_list_all_args_main_title for try function p.form_support_desk_report() return versioning.form_support_desk_report() end function versioning.form_support_desk_report() -- Form the detailed Versions report t = "\n* Discreet main version: " .. (versioning.report_main_discreet or " report_main_discreet missing ") t = t .. translate.main_i18n_languages_list() -- List available translations languages t = t .. "\n* Start versions from main module: " .. (versioning.bind_verif_modules_report_start or " bind_verif_modules_report_start missing ") t = t .. versioning.versions_management_report() t = t .. versioning.sort_central_modules_report() t = t .. versioning.running_times() return t, details end -- function versioning.versions_management_report(vers) -- Display the documentation in an infobox, similar to edit-boxs -- Affichage de documentation dans un cadre (box), semblable aux boites d'edition function p.formDocBox(args_final) -- modes.options = " docdata docmin docdef docmax docline docsrc docview : docafter docnotice docsrc" -- for documentation -- modes.options = " erron noerr nobox " -- without normal result -- modes.options = " debug tests en es fr " -- for debug or enforce language if type(args_final) ~= "table" then args_final = modes.args_final end -- optional arguments -- local err = modes.verify_args_tables(modes.args_known, modes.args_source) -- if err then return err end local res = "" -- on viewer.form9user( res = res .. viewer.errorColor("<center><b>" .. viewer.form9user("modes_delete_docbox_wng") .. "</b><br/></center>") res = res .. viewer.docDropBox("allwaysview", "versioning_support_desk_title", versioning.form_support_desk_report ) -- res = res .. viewer.DropBox(viewer.docDropBoxTitle(), versioning.form_support_desk_report() ) -- modes.catView = ":" -- modes.mode_options = " debug docview docdata docdef docline " -- modes.invoke_options = "" if modes.option("debug") then res = res .. "\n*" .. viewer.ta("modes.catView", modes.catView) .. viewer.ta("modes.invoke_options", modes.invoke_options) .. viewer.ta("modes.mode_options", modes.mode_options) end if modes.option("docdata") then res = res .. "\n*" .. modes.generDoc(" docdef docline ", datas.args_wikidata, "Wikidata") end if modes.option("docview") then res = res .. "\n*" .. modes.generDoc("", args_final, "Arguments") end if not modes.option("noerr") then res = res .. "\n*" .. events.errors_lister() end -- local t = "" -- Form events views local wng, err, cat = events.sort_typ() -- Sort events by type in wng, err, cat. for key, evt in pairs(wng) do evt.res, evt = events.form(evt) if evt.res then t = t .. "<br>* " .. tostring(evt.res) end end for key, evt in pairs(err) do evt.res, evt = events.form(evt) if evt.res then t = t .. "<br>* " .. tostring(evt.res) end end for key, evt in pairs(cat) do evt.res, evt = events.form(evt) if evt.res then t = t .. "<br>* " .. tostring(evt.res) end end -- local t = ""translate_main_i18n_languages_count = t = t .. translate.main_i18n_languages_list() -- List available translations languages -- res = res .. t local result = "\n------ " -- This code interact with DropBox and debug the bug T20151215 2016-11-13 17:57. result = result .. '<div class="CentralDocBox" style=" width=90%; border: 1px solid #AAAAAA; margin:1em; background-color:#F1F1F1; padding:0.3em; ">' .. res .. '</div>' result = result .. "\n* " .. events.categories_lister(":") return result end -- function p.formDocBox(args_final) function p.normal_box(args_final, title) local res = "" local warning_versions = versioning.report_main_short if type(args_final) ~= "table" then args_final = modes.args_final end if not title then title = args_final.title end if not title then title = "TITLE" end res = res .. "<center><b><big>" .. title .. "</big></b> " .. versioning.report_main_discreet .. " - " .. (versioning.site_currentVersion_view or "currentVersion") .. "<br></center>" -- flag_of_country = "[[File:Flag of France.svg|border|100px]]" -- from https://commons.wikimedia.org/wiki/File:Flag_of_France.svg local flag_of_country = viewer.form9user("flag_of_country") -- "fails to debug on 20170424 Rical". (This work fine for many other cases.) bind main_module.i18n local flag_of_country = p.i18n[translate.user_lang]["flag_of_country"] -- direct acces to bypass "fails to debug on 20170424 Rical" local flag_of_country_res = "[[File:" .. flag_of_country .. "|border|40px]]" -- flag_of_country_res .. " flag_svg=" .. flag_svg .. " 50px;40px " .. res = res .. flag_of_country_res local function arglingual(key) local t = "" if key and tools and translate.user_translations and translate.user_translations[key] then t = t .. viewer.tam(translate.user_translations[key], args_final[key] ) else t = ", " end return t end res = res .. arglingual("label") res = res .. arglingual("description") res = res .. arglingual("occupation") res = res .. arglingual("firstname") res = res .. arglingual("lastname") res = res .. arglingual("birthyear") res = res .. arglingual("deathyear") modes.nowyear = tonumber(os.date("%Y") ) -- now_date = os.date("%Y-%m-%d %H:%M:%S") -- local i2r = mathroman.int2roman(modes.nowyear) -- local r2i = mathroman.roman2int(i2r) -- local r2r = mathroman.int2roman(r2i) res = res .. viewer.ta("int2roman", i2r) .. viewer.ta("roman2int", r2i) .. viewer.ta("int2roman", r2r) res = res .. "<br>" .. translate.main_i18n_languages_list() -- List available translations languages res = '<div style="margin-right:5px; box-shadow:0.2em 0.3em 0.2em #B7B7B7; background-color:#F1F1DE; padding:0.3em; width=90%; overflow-x:hidden; ">' .. res .. '</div>' return res end -- function p.normal_box(args_final, title) function p.form_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 p.i18n and p.i18n.en then p.i18n.en.error_i18n_wanted_to_test_missing_translation = 'English error i18n wanted for tests missing translation' end if p.i18n and p.i18n.es then p.i18n.es.error_i18n_deseada_para_probar_traduccion_faltan = 'Espagnol error i18n deseada para probar traducción faltan' end if p.i18n and p.i18n.fr then p.i18n.fr.error_i18n_voulue_pour_test_de_traduction_manquante = 'Français erreur i18n voulue pour tests de traduction manquante' end -- if not args_source.userlang then args_source.userlang = "en" end -- if not args_source.wikilang then args_source.wikilang = "es" end if not args_source.modeinvoke then args_source.modeinvoke = "catview" end if not args_source.mode_invoke then args_source.mode_invoke = "catview" end if not args_source.invoke_options then args_source.invoke_options = "catview" end if not args_source.name then args_source.name = "Jack Smith" end if not args_source.nom then args_source.nom = "Victor Hugo" end if not args_source.region then args_source.region = "india" end if not args_source["région"] then args_source["région"] = "chine" end if not args_source.description then args_source.description = "Victor Hugo est très connu." end if not args_source.langue then args_source.langue = "français,japonais" end if not args_source.occupation then args_source.occupation = "Académiciens,Personnalités politiques" end modes.args_source = args_source return res end -- function p.form_tests_init(res, args_source) -- Interact parameters in international args_final function modes.interact_args_final(args_import) versioning.deprecatedFunction("modes.interact_args_final", "p.interact_args_final") return p.interact_args_final(args_import) end function p.interact_args_final(args_import) -- args_final = p.interact_args_final(args_import) local t = "" if type(args_import) ~= "table" then args_import = modes.args_import or {} end local args_final = mw.clone(args_import) -- do not disturb original args_import local a = args_import local i = {} -- interact -- local t = "\n* begin :" .. viewer.ta("initiale", a.initiale) .. viewer.ta("firstname", a.firstname) .. viewer.ta("lastname", a.lastname) .. viewer.ta("title", a.title) -- local tit = nil if not a.title then -- If title is undefined, enforce it. if a.lastname and a.firstname then tit = a.firstname .. " " .. a.lastname end i.title = a.label or tit or a.sitelink or a.lastname or modes.module_name end -- if not a.initiale then -- If initiale is undefined, enforce it. -- if absent, default initiale come from the last word of title local title = a.title or i.title if title then local tab = mw.text.split(title, '%s') -- table of words local max = table.maxn( tab ) i.initiale = tab[max] -- selector the last word i.initiale = string.sub( i.initiale, 1, 1 ) -- selector the first letter i.initiale = string.upper( i.initiale or "" ) end end -- -- if absent, synonym of basic arguments, syn = 2 if not a.firstname then i.firstname = (i.firstname2 or a.firstname2) end if not a.lastname then i.lastname = (i.lastname2 or a.lastname2) end if not a.firstname2 then i.firstname2 = (i.firstname or a.firstname) end if not a.lastname2 then i.lastname2 = (i.lastname or a.lastname) end -- if a.birth and not a.birthyear then local tt, err = viewer.date_to_part(a.birth, viewer.form9user("modes_date_to_part_format"), "yyyy") if tt then i.birthyear = tt else events.add_err(err, viewer.form9user("birthyear"), "yyyy") events.add_cat("modes_date_to_part_call_cat") end end -- memorize interactions in modes.args_final and show errors or warnings local n = 0 for key, val in pairs(i) do local args_kwn = modes.args_known[key] if args_kwn then args_final[key] = val -- = i[key] args_kwn.src = "inter" args_kwn.trk = args_kwn.trk.." i" n = n + 1 if (args_kwn.need == 2) and not a[key] then -- -- need=2 necessary from argument or module interaction events.add_wng("modes_auto_val_warning_wng", translate.user_translations[key], val) end else events.add_err("modes_unknown_auto_arg_err", translate.wiki_translations[key], val) end end if modes.args_known and modes.args_known.title then modes.args_known.title.trk = (modes.args_known.title.trk or "").."i="..n end modes.args_final = args_final return args_final, t end -- function p.interact_args_final(args_import) -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- Interfaces, alias and functions to templates -- Interfaces, alias y funciones para modelos -- Interfaces, alias et fonctions pour les modèles -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- p.options_for_modes = { -- module options_for_modes read = " noerr ", edit = " docdef docline docsrc docdata catview docview : ", doc = " nobox noerr nocat ", tests = " docdef docline docsrc docdata catview docview : tests ", } function modes.init_modes_translate_events(frame, Central_version, mode_name, args_known, options_for_modes, itemid) -- After versioning.init(), initialize modes and their options, known arguments, translations, and default item. local res = "" -- res = res .. versioning.detect_mediawiki_changes() modes.frame = frame -- translate.Central_x_y = p.Central_x_y -- To adapt the version of Module:Central in any translated text. translate.Module_Central_version = Central_version -- To adapt the version of Module:Central in any translated text. modes.args_known = args_known or modes.args_known -- res = res .. versioning.site_currentVersion_view -- clean and rewrite init for versioning, mode, options, translate, module modes.module_init(frame) -- Get modes.args_source with modes.args_config modes.init_options_for_modes(frame, options_for_modes, mode_name) -- Needed to init categories and errors res = res .. modes.trackOptions("modes.init_options_for_modes", "no_track") local mode_name, source_key, try_lang = modes.get_arg_mode(mode_name, source_key, try_lang, args_source) res = res .. modes.trackOptions("modes.get_arg_mode") -- modes.mode_name = mode_name or modes.mode_name or "read" translate.init_wiki_user_page_lang(modes.args_config.wikilang, modes.args_config.userlang) -- init user and the wiki languages from args local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, modes.recursiveLimit) events.init_configs() -- testcase, tabOptions, {}) -- Initialize global configurations and save them before eventual changes. return res end -- function modes.init_modes_translate_events(frame, Central_version, mode_name, args_known, options_for_modes, itemid) --[[ local p = {} p.v = {} -- Version descriptor for central modules updated by versioning.get_one_module_or_library() p.v.version = "p.v.version" -- The main module select this version, from its p.versions{}, to replace its main version. p.v.version = "[ [w:vi:Central-s-vi] ]" -- The main module select this version, from its p.versions{}, to replace its main version. p.v.version = "Central-s-fr" -- The main module select this version, from its p.versions{}, to replace its main version. p.v.main_version = "Central" -- Central modules share the main version from the central repositoty to any projects. -- Later, versioning.get_one_module_or_library() -- Get a module or a library, then form and record a descriptor of it. local Central = p p.Module_Central_version = "p.v.version" -- To adapt the version of Module:Central in any translated text. p.ModuleNS = mw.site.namespaces.Module.name .. ":" p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module. versionName = "Central-s-fr", versionNumber = "03 22:57", versionDate = "2017-04-03 22:57", sought = "Central-s-fr;Mathroman2;TestRequire", -- Sought module and submodules versions known = "Central-s-fr;Mathroman2;TestRequire;TestBug", -- Known module and submodules versions -- known = "Central-s-fr;p.v.version;ControlArgs1;Mathroman2;TestRequire;TestBug;Testpages", -- Known module and submodules versions -- loaded_list = ";Central;p.v.version;",-- Module:Central -- currentVersion = "", -- show if the mediawiki version has change ( for debug ) -- Central.fr.ws is in conflict with LUA syntax table.intable.subtable and results in overflow at runtime. -- Then Rical renames Central.fr.ws in Central-s-fr at 16 decembre 2016-12-16 18:03. } --]] function versioning.bind_all_i18n() -- Bind all i18n translations from all sub-modules in reverse order. local t = "\n* versioning.bind_all_i18n() " if 1 then return t end for i = #versioning.bind_main_and_sub_modules_order, 1, -1 do -- in reverse order sub_module_name = versioning.bind_main_and_sub_modules_order[i] -- local get = versioning.loaded_modules_and_libraries[sub_module_name] local get = versioning.bind_main_and_sub_modules_get[sub_module_name] -- Use the get descriptor of the sub_module. -- Add i18n translations from the sub-module itself: if (type(get.title) == "string") and (type(get.i18n) == "table") then versioning.add_one_i18n("", get.title, get.i18n) -- Add i18n translations with previews one's. t = t .. "\n*" .. viewer.ta("title", get.title) t = t .. viewer.ta("#i18n", #get.i18n) end -- Add i18n translations from an eventual /I18N sub-module: if (type(get.subI18N) == "string") then local get, module = versioning.get_one_module_or_library(get.subI18N) if (type(get.title) == "string") and (type(get.i18n) == "table") then versioning.add_one_i18n("", get.title, get.i18n) -- Add i18n translations with previews one's. t = t .. "\n*" .. viewer.ta("title", get.title) t = t .. viewer.ta("#i18n", #get.i18n) end end end return t end -- function versioning.bind_all_i18n() -- Bind all sub-modules of the main module. function versioning.bind_main_module_and_i18n() -- Bind the main module, all sub-modules and all their i18n. -- if 1 then return end -- The main module call this function to load needed sub-modules and translations. local res = "\n* versioning.bind_main_module_and_i18n() " local frame = mw.getCurrentFrame() local title = frame:getTitle() -- main module, example "Auteur" local get, main_module = versioning.get_one_module_or_library(title) -- Get the main module. -- Table to collect loaded sub-modules names in binding order and i18n translations in reverse order. versioning.mainversion = title versioning.bind_main_and_sub_modules_order = versioning.bind_main_and_sub_modules_order or {} table.insert(versioning.bind_main_and_sub_modules_order, title) -- Record first the main module name. versioning.bind_main_and_sub_modules_get = versioning.bind_main_and_sub_modules_get or {} versioning.bind_main_and_sub_modules_get[title] = get -- Record the get descriptor of the main module. -- -- After get the main module, get the versions for their management. -- The main module can use or not the versions management. versioning.main_module = main_module if type(main_module) == "table" and type(main_module.versions) == "table" then -- For main modules using versions management versioning.main_versions = main_module.versions end local main_versions = versioning.main_versions -- nil if the main module do not uses the versions management. -- if not versioning.main_module then -- The main module is not found. res = res .. viewer.errorColor( viewer.form9user("versioning_main_module_missing_err") ) end versioning.main_i18n = versioning.main_i18n or {} local main_versions = versioning.main_versions -- res = res .. versioning.bind_all_i18n() return res end -- function versioning.bind_main_module_and_i18n() -- Bind the main module, all sub-modules and all their i18n. function versioning.bind_all_sub_modules() -- Bind all sub-modules of the main module. if 1 then return end -- The main module call this function to load needed sub-modules and translations. local main_module = versioning.main_module local main_versions = versioning.main_versions -- nil if the main module do not uses the versions management. --[[ Example of main_versions main_module.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module. versionName = "Central-s-fr", versionNumber = "03 22:57", versionDate = "2017-04-03 22:57", sought = "Central-s-fr;Mathroman2;TestRequire", -- Sought module and submodules versions known = "Central-s-fr;Central-14 * Mathroman2;Mathroman34 * TestRequire;TestRequ * TestBug;TestBug4", -- Known module and submodules versions } --]] if type(main_module) == "table" and type(main_module.versions) == "table" then -- For main modules using versions management versioning.main_versions = main_module.versions end if type(main_module) == "table" and type(main_versions) == "table" then -- Verify main module and versions management ability. sought = main_versions.sought known = main_versions.known versionName = main_versions.versionName versionNumber = main_versions.versionNumber -- t = t .. viewer.ta("main_module", main_module) .. viewer.ta("main_versions", main_versions) -- t = t .. viewer.ta("sought", sought) .. viewer.ta("known", known) -- t = t .. viewer.ta("versionName", versionName) .. viewer.ta("versionNumber", versionNumber) end t = t .. "<br>AFTER sought, known, versionName, versionNumber, version, main_module : " versioning.bind_modules_start = t if type(main_versions.sought) == "string" and type(main_versions.known) == "string" then known = main_versions.known sought = main_versions.sought end t = t .. "\n*bind_sub_modules() starts: " local sought_t = string.gsub(main_versions.sought or sought or "", " ", ";") -- ";" .. .. ";" local sought_tab = mw.text.split(sought_t, " ", true) local sought_maxn = table.maxn(sought_tab) -- local known_tab = mw.text.split(main_versions.known or known or "", "*", true) local known_maxn = table.maxn(known_tab) -- local known_maxn = #known_tab local used = ";" local t = "" t = t .. "\n* list versioningsought.bind_sub_modules : " -- .. viewer.ta("main_versions.versionName", main_versions.versionName) -- .. viewer.ta("main_versions.", main_versions.sought) .. viewer.ta("sought_maxn", sought_maxn) -- .. "<br>" .. viewer.ta("main_versions.known", main_versions.known) .. viewer.ta("known_max", known_max) local alternatives, kind local alternatives, kind for i = known_maxn, 1, -1 do -- alternatives = known_tab[i] alternatives = known_tab[i] alternatives = ";" .. mw.text.trim(alternatives) .. ";" -- normalize versions between ";" -- alternatives = viewer.simpleList(alternatives) local altern_tab = mw.text.split(alternatives, ";", true) local elem, module, normal, alias, name_I18N normal = "" ; version = "" altern = tostring(altern) altern = mw.text.trim(altern) for v, altern in ipairs(altern_tab) do -- versioning.actual_modules = versioning.actual_modules .. ";" .. altern if v == 1 and string.find(";" .. sought .. ";", ";" .. altern .. ";", 1, true) then -- if v == 1 and viewer.is_in_sp(altern, sought, ";") then normal = altern kind = "normal" end if v > 1 and string.find(";" .. sought .. ";", ";" .. altern .. ";", 1, true) then -- if v > 1 and viewer.is_in_sp(altern, sought, ";") then version = altern kind = "version" end local name_mod, name_I18N, tt, lang_N, text_N, get_i18n, getI18N if vers_test then -- In versions management test if string.find(";" .. vers_test.loaded_list .. ";", ";" .. altern .. ";", 1, true) then -- if viewer.is_in_sp(altern, vers_test.loaded_list, ";") then used = (used or "- ") .. altern .. "; " end name_I18N = altern .. "/I18N" -- Get a module or a library, then form and record a descriptor of it. local get, module = versioning.get_one_module_or_library(name_I18N) -- versioning.actual_modules = versioning.actual_modules .. ";" .. get.title if (type(get.module) == "table") and (type(get.moduleName) == "string") then -- Verify main module and versions management ability. end -- bd : bind_sub_modules from main to sub, then compute all subI18N, then in reverse order addi18n from subI18N.i18n as .sub_i18n -- bd : versioning.init, bind_libraries_modules_translations, bind_central_libraries, bind_sub_modules, bind_i18n_translations, -- bd : get_one_module_or_library, bind_central_modules_report else -- In normal run -- addi18n from the module itself if (type(getI18N) == "table") and (type(getI18N.moduleName) == "string") then -- Verify main module and versions management ability. -- t = t .. "\n*" .. tostring(tb) .. viewer.ta("I18N", getI18N.moduleName) -- .. viewer.ta("name_I18N", name_I18N) -- versioning.actual_modules = versioning.actual_modules .. ";" .. getI18N.title end end if vers_test then -- In versions management test if viewer.is_in_sp(name_I18N, vers_test.loaded_list, ";") then used = (used or "- ") .. name_I18N .. "; " end else -- wait later versioning.bind_i18n_translations() to get I18N end end -- for v, altern in ipairs(altern_tab) do end -- for i = known_maxn, 1, -1 do -- alternatives = known_tab[i] local word, errs = "", "" if type(vers_test) == "table" then -- In tests run -- Versions management errors from overall look on modules local alloncesort = viewer.simpleList(vers_test.sought .. ";" .. vers_test.known .. ";" .. vers_test.used) local alloncetab = mw.text.split(alloncesort, ',') -- table of words for i, name in ipairs(alloncetab) do -- list all used names, only one each, in alphabetic order if viewer.is_in_sp(name, vers_test.sought, ";") and not viewer.is_in_sp(name, vers_test.known, ";") then errs = errs .. ";" .. events.add_err("versioning_missing_versions_err", name, vers_test.versionName ) -- new -- versioning_missing_versions_err = "The module <b>%1</b> misses in the main module <b>%2</b>.", end if viewer.is_in_sp(name, vers_test.used, ";") and not viewer.is_in_sp(name, vers_test.sought, ";") then vers_test.replaced = (vers_test.replaced or "") .. name .. ";" -- sought but not found errs = errs .. ";" .. events.add_err("versioning_replaced_versions_err", name, vers_test.versionName ) -- new -- versioning_replaced_versions_err = "The module <b>%1</b> replaces the missing module in the main module <b>%2</b>.", -- versioning_select_unknown_module_err = "Internal error: The missing Module:<b>%1</b> is replaced by the normal Module:<b>%2</b>.", -- versionsmanagement end if viewer.is_in_sp(name, vers_test.alloncesort, ";") and not viewer.is_in_sp(name, vers_test.known, ";") then vers_test.unknown = (vers_test.replaced or "") .. name .. ";" -- sought but not found errs = errs .. ";" .. events.add_err("versioning_unknownversions_err", name, vers_test.versionName ) -- new -- versioning_unknownversions_err = "The module <b>%1</b> is unknown in the main module <b>%2</b>.", end end -- for v, altern in ipairs(altern_tab) do end end -- function versioning.bind_all_sub_modules() function versioning.bind_sub_modules() if 1 then return end local res, t = "", "" translate.track_i18n("versioning.init:frame") versioning.main_i18n_complete = false -- Mask any views to avoid failures until enough init. -- translate.Central_x_y = p.Central_x_y -- To adapt the version of Module:Central in any translated text. Central_version = Central_version or translate.Module_Central_version -- or p.Module_Central_version versioning.bind_libraries_modules_translations() -- Bind central libraries, modules, and their i18n translations translate.track_i18n("versioning.init:bind_modules_method") versioning.main_i18n_complete = true -- Unmask all views after enough init. res = res .. versioning.detect_mediawiki_changes() translate.track_i18n("versioning.init:detect_mediawiki_changes") return res end -- versioning.bind_main_module_and_i18n() function Central.init(frame, Central_version, mode_name, args_known, options_for_modes, itemid) local res = "" modes.time1 = os.clock() translate.track_i18n("Central.init:frame") Central_version = Central_version or translate.Module_Central_version or p.Module_Central_version -- modes.args_known = args_known or modes.args_known options_for_modes = options_for_modes or modes.options_for_modes or p.options_for_modes -- begin.init_central_versions(wiki, central, main, known_wikis) -- Automatic adaptation of central versions in main and central modules. -- res = res .. versioning.bind_main_module_and_i18n() -- Bind the main module, all sub-modules and all their i18n translations. -- res = res .. versioning.init(frame, Central_version) translate.track_i18n("Central.init:versioning") -- versioning.actual_modules = "Central.init:" .. versioning.actual_modules -- res = res .. versioning.actual_modules -- local flag_of_country = viewer.form9user("flag_of_country") -- "fails to debug on 20170424 Rical". (This work fine for many other cases.) bind main_module.i18n res = res .. modes.init_modes_translate_events(frame, Central_version, mode_name, modes.args_known, options_for_modes, itemid) modes.change_itemid(itemid) -- Select a wikidata default item if needed. Default "Q41568" -- res = res .. translate.track_counts("Central.init", "versioning.i18n", trans, tables) -- res = res .. translate.track_counts_t viewer.docDropBox_title = viewer.docDropBoxTitle("versioning_support_desk_title", "versioning_support_desk_table") return res end -- function Central.init(frame, Central_version, mode_name, args_known, options_for_modes, itemid) _G["central"] = {} -- A central object to group central datas -- local t, central = versioning.host_to_CENTRALVERSION(host, central) function versioning.host_to_CENTRALVERSION(host, central) -- Get _CENTRALVERSION from the host of the project. -- Record centralisable libraries if they are not included in standard mw.Extension:Scribunto -- RunOnce : Do not repeat this function to not disturb subsequent processes. local mwuri, t = mw.uri.new(), "\n* mwuri: " for key, val in pairs(mwuri) do t = t .. viewer.ta(key, val) end t = t .. viewer.ta("_CENTRALTIME", _CENTRALTIME) t = t .. viewer.ta("host", mwuri.host) t = t .. viewer.ta("port", mwuri.port) t = t .. viewer.ta("path", mwuri.path) t = t .. viewer.ta("fragment", mwuri.fragment) t = t .. viewer.ta("hostPort", mwuri.hostPort) t = t .. viewer.ta("host", mwuri.host) local nowtime = os.date("%Y-%m-%d %H:%M:%S") local timestamp = os.date("%Y%m%d%H%M%S") versioning.central_CENTRALVERSION = split_version versioning.central_CENTRALSTAMP = timestamp versioning.central_CENTRALTIME = nowtime -- versioning.central_host = mwuri.host -- like fr.wikisource.org local split_host = mw.text.split(versioning.central_host, ".", true) versioning.central_shortlang = split_host[1] versioning.central_project = split_host[2] -- versioning.central_path = mwuri.path -- like /wiki/Module:Central-s-fr/Documentation like /wiki/Mô đun:Central-w-vi/tài liệu local split_version = mw.text.split(versioning.central_path, ":", true) local split_version = mw.text.split(split_version[2], "/", true) local split_version = split_version[1] versioning.central_CENTRALVERSION = split_version local project_to_short = { wiki = 'p', -- project to shortproject commons = 'cm', meta = 'meta', species = 'species', test2 = 'test2', wikibooks = 'b', wikimedia = 'wm', wikinews = 'n', wikiquote = 'q', wikisource = 's', wikiversity = 'v', wikivoyage = 'y', wiktionary = 't', } local split_version = mw.text.split(split_version, "-", true) versioning.central_CENTRALMAIN = split_version[1] versioning.central_shortproject = split_version[2] versioning.central_shortlang = split_version[3] local short_to_project = {} -- shortproject to project for key, val in pairs(project_to_short) do short_to_project[val] = key end -- -- local shortproject, shortlang = mwuri.port or mwuri.path or mwuri.fragment, mwuri.port or mwuri.hostPort versioning.central_CENTRALVERSIONTIME = versioning.central_CENTRALMAIN .. "-" .. versioning.central_shortproject .. "-" .. versioning.central_shortlang .. "-" .. versioning.central_CENTRALSTAMP t = t .. viewer.ta("_CENTRALVERSIONTIME", versioning.central_CENTRALVERSIONTIME) t = t .. "\n* central: " for key, val in pairs(central) do t = t .. viewer.ta(key, val) end return t, central end -- function versioning.host_to_CENTRALVERSION(host, central) -- local central = _G["central"] -- local t, central = versioning.host_to_CENTRALVERSION(host, central) -- local t, central = centralbinder(host, central) -- Bind central libraries and versions. function versioning.central_centralbinder(host, central) -- Bind central libraries and versions. -- Record centralisable libraries if they are not included in standard mw.Extension:Scribunto -- RunOnce : Do not repeat this function to not disturb subsequent processes. -- _G["central"] = central or {} -- A central object to group central datas local central = _G["central"] _G["centralbinder"] = versioning.central_centralbinder -- This binder -- local t, central = versioning.host_to_CENTRALVERSION(host, central) return t, central end -- function versioning.central_centralbinder(host, central) function Central.read(frame) -- The read mode generates the normal result for read only users. -- Helpers or admins can add options to include edit or tests or user language... local res = "" -- res = res .. versioning.central_centralbinder(host, central) -- Bind central libraries and versions. res = res .. Central.init(frame, p.Module_Central_version, "read", p.args_known, p.options_for_modes, "Q535") -- itemid -- versioning.actual_modules = "Central.read:" .. versioning.actual_modules -- res = res .. versioning.actual_modules -- res = res .. versioning.detect_mediawiki_changes() modes.args_import, t = modes.import_arguments() res = res .. modes.trackOptions("modes.import_arguments") modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between arguments -- res = res .. modes.short_config("Begin") res = res .. modes.form_result(modes.args_final) -- res = res .. versioning.running_times(false, "") -- res = res .. versioning.site_currentVersion_view -- in debug phase res = res .. versioning.detect_mediawiki_changes() -- local t, central = centralbinder(host, central) -- Bind central libraries and versions. -- res = res .. viewer.docGroup("allwaysview") -- res = res .. translate.track_i18n_t return res end -- function Central.read(frame) function Central.edit(frame) -- The edit mode verifies arguments, displays the edit panel with errors, warnings and categories. local res = "" res = res .. Central.init(frame, p.Module_Central_version, "edit", p.args_known, p.options_for_modes, "Q535") -- itemid -- res = res .. Central.init(frame, "edit", p.args_known, p.options_for_modes) -- , "Q535" -- res = res .. versioning.detect_mediawiki_changes() -- versioning.actual_modules = "Central.edit:" .. versioning.actual_modules -- res = res .. versioning.actual_modules modes.args_import, t = modes.import_arguments() res = res .. modes.trackOptions("edit import_arguments", "no_track") modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between argumensts -- res = res .. versioning.site_currentVersion_view translate.init_wiki_user_page_lang() -- local res_function = "<br/>\n" .. (versioning.main_versions.versionName or "MainModule_t") .. " " .. (versioning.main_versions.versionNumber or "0.0_t") .. ":" .. modes.mode_name .. ":" .. translate.wiki_lang .. " " -- res = res .. res_function .. " Begin:" .. "<br>" -- res = res .. modes.short_config("Begin") res = res .. modes.form_result(modes.args_final) -- res = res .. versioning.site_currentVersion_view res = res .. versioning.detect_mediawiki_changes() -- res = res .. translate.track_i18n_t return res end -- function Central.edit(frame) function p.doc1(frame) -- Deprecated alias function versioning.deprecatedFunction("p.doc1", "Central.doc") return Central.doc(frame) end function Central.doc(frame) -- Form a documentation or a test in a dropbox. local res = "" -- res = res .. Central.init(frame, p.Module_Central_version, "doc", p.args_known, p.options_for_modes, "Q535") -- itemid modes.args_import, t = modes.import_arguments() -- res = res .. modes.trackOptions("doc import_arguments", "no_track") modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between arguments -- res = res .. versioning.site_currentVersion_view res = res .. "\n*" .. viewer.ta("modes.mode_options", modes.mode_options) res = res .. viewer.ta("modes.invoke_options", modes.invoke_options) local dockey = modes.args_config.dockey or modes.args_source[1] local itemid = modes.args_config.itemid or modes.args_config.id or modes.args_source[2] modes.change_itemid(itemid) -- Select a wikidata default item if needed. Default "Q41568" modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between argumensts translate.init_wiki_user_page_lang() -- modes.time3 = os.clock() if dockey then res = res .. viewer.docGroup(dockey, itemid) end return res end -- function Central.doc(frame) function modes.short_config_old(where) local res = "" -- res = res .. "<br/>\n" .. (versioning.main_versions.versionName or "MainModule_t") .. " " .. (versioning.main_versions.versionNumber or "0.0_t") .. ":" .. modes.mode_name .. ":" .. translate.wiki_lang .. " " res = res .. "<br/>\n" .. (versioning.main_versions.versionName or "MainModule_t") res = res .. " " .. (versioning.main_versions.versionNumber or "0.0_t") .. ":" res = res .. modes.mode_name .. ":" .. translate.wiki_lang res = res .. ":" .. where .. ":" return res end -- function modes.short_config(where) function Central.tests(frame) local res = "" --[= =[ res = res .. Central.init(frame, p.Module_Central_version, "tests", p.args_known, p.options_for_modes, "Q535") -- itemid -- versioning.actual_modules = "Central.tests:" .. versioning.actual_modules -- res = res .. versioning.actual_modules -- res = res .. modes.short_config("Central.init.End") modes.args_import, t = modes.import_arguments() res = res .. modes.trackOptions("Central.tests import_arguments", "no_track") res = res .. "\n* getEntityIdForCurrentPage = " .. tostring( mw.wikibase.getEntityIdForCurrentPage() ) -- Returns the Item id as string, like "Q42" p.form_tests_init() --[ [ modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between arguments -- modes.mode_name = modes.args_final.mode or modes.args_import.mode or modes.args_config.mode or "tests" translate.init_wiki_user_page_lang() versioning.main_versions = versioning.main_versions or { versionName = "versionName", versionNumber = "0.0", } if not versioning.main_versions then versioning.main_versions = p.versions or versioning.versions end -- -- local res_function = "<br>* " .. versioning.main_versions.versionName .. ":" .. modes.mode_name .. ":" .. translate.wiki_lang .. " " -- If there is no MainModule, THIS version of Central is used alone -- res = res .. res_function .. " Begin:" .. "<br>" -- res = res .. modes.short_config("Begin") -- versioning.loaded_modules_and_libraries = versioning.loaded_modules_and_libraries or {} local loaded_pack, loaded_txt, modu = versioning.loaded_modules_and_libraries versioning.loaded_modules_track = "p.tests : " .. viewer.ta("#loaded_pack", #loaded_pack) res = res .. modes.form_result(modes.args_final) -- Generate wikitext, categories, and others --] ] -- res = res .. modes.short_config("End") -- res = res .. versioning.site_currentVersion_view -- frame:preprocess <pre>, <nowiki>, <gallery> and <ref>, will be replaced with "strip markers" res = res .. viewer.docSection("allwaysview", viewer.form9user("versioning_antiCrash_reference_label"), "h2") -- versioning_antiCrash_reference_label = "References", -- res = res .. frame:preprocess( "<br>== References ==<br><references><br>" ) -- res = res .. frame:preprocess( "<br>{{Références}}" ) -- antiCrash -- res = res .. "\n== references ==<br><references><br>" -- res = res .. versioning.antiCrash_tests() -- res = res .. versioning.detect_mediawiki_changes() -- res = res .. "\n* Enforce at end of tests: \n------ " -- res = res .. luaTable.from_subnames_test() -- Test: Get the last sub-table from a sub-table name. -- res = res .. viewer.docDropBox(selector, "luaTable_from_subnames_test_title", luaTable.from_subnames_test ) -- res = res .. begin.support_begin_central_modules() -- res = res .. viewer.docDropBox("allwaysview", "begin_support_central_modules_title", begin.support_begin_central_modules ) -- res = res .. versioning.sort_central_modules_report() -- Sorted list of central modules and libraries --]= =] -- res = res .. translate.track_i18n_t -- res = res .. versioning.bind_central_libraries_t -- res = res .. versioning.running_times(false, "") return res end -- function Central.tests(frame) translate.track_i18n_t = "translate.track_i18n : " function translate.track_i18n(where) translate.track_i18n_t = (translate.track_i18n_t or "") .. "\n* " .. tostring(where) .. viewer.ta("versioning.main_i18n", type(versioning.main_i18n) ) .. viewer.ta("translate.main_i18n", type(translate.main_i18n) ) .. viewer.ta("begin.i18n", type(begin.i18n) ) .. viewer.ta("datas.i18n", type(datas.i18n) ) return translate.track_i18n_t -- res = res .. translate.track_i18n(where) -- , select, -- dropbox -- res = res .. on viewer.docDropBox(selector, "mathroman_roman2int_tests_title", mathroman.roman2int_tests) -- Todo : Search "versioning.main_i18n =" "translate.main_i18n =" -- Todo : Search recursive loop -- Todo : Search recursive loop in addi18n -- Todo : limit the recursive level maxi to 3 : in versioning.i18n.en versioning=1 i18n=2 en=3 -- Todo : Search: count error fail ? by loop of count at the same level -- Todo : Search: limit and track the counts in function luaTable.formSubCounts() -- Todo : Search: each library is in package.loaded and in _G. Delete it in _G like datas = nil. end function versioning.detect_mediawiki_changes() local t = t or "\n* <b>versioning.record_mw_changes()</b> : Detect, record and report all date-time changes of mediawiki, in each wiki." -- T20170225 Rical: using 2 ways to use {{subst:}}, we could detect, record and report all date-time changes of mediawiki -- in each wiki to help the gerrit team to debug mw. -- See https://www.mediawiki.org/wiki/Manual:Substitution versioning.site_currentVersion = mw.site.currentVersion if mw.site.currentVersion == versioning.site_currentVersion_memo then versioning.site_currentVersion_view = viewer.discreetColor( versioning.site_currentVersion ) else versioning.site_currentVersion_view = viewer.errorColor( versioning.site_currentVersion ) end -- Spécial:Version mw.site.currentVersion t = t .. "\n* See also the [https://www.mediawiki.org/wiki/Manual:Substitution Mediawiki Manual:Substitution]." return "" -- t end -- function versioning.detect_mediawiki_changes() --[[ To get a list of Mediawiki changes: On the actual page insert (and mask) an old list in <section begin=description /> ... texte à transclure ... <section end=description /> insert also : {{#lst:{{{page| Modèle:{{{1}}}/documentation }}}|description}} a transclusion of this list with the actual mediawiki version. with these in 1 or 2 pages like for {{subst:CURRENTTIME}}. See https://fr.wikisource.org/wiki/Modèle:Descriptif/documentation See https://fr.wikipedia.org/wiki/Aide:Créer_un_modèle#subst:_imbriqué --]] -- Last Mediawiki-Wikisource update/upgrade versions: -- Seen and recorded at each preview to test fr.wikisource.org/wiki/Module:Central-s-fr -- French time UTC +1 ou +2 -- 20170221-23:50 : Mediawiki-Wikisource 1.29.0-wmf.12 (26fcd48) UTC-20170221-16:11.html -- 20170223-09:11 : Mediawiki-Wikisource 1.29.0-wmf.13 (c70f13a) UTC-20170222-20:22.html -- 20170225-00:09 : Mediawiki-Wikisource 1.29.0-wmf.13 (0276546) UTC-20170223-20:25.html -- 20170228-20:35 : Mediawiki-Wikisource 1.29.0-wmf.13 (c73a5e9) UTC-20170228-14:58.html -- 20170303-21:05 : Mediawiki-Wikisource 1.29.0-wmf.14 (ec6907e) UTC-20170228-19:03.html -- 20170308-12:41 : Mediawiki-Wikisource 1.29.0-wmf.14 (366a0c6) UTC-20170303-19:37.html -- 20170309-01:39 : Mediawiki-Wikisource 1.29.0-wmf.15 (01393e5) UTC-20170307-20:46.html -- 20170315-00:04 : Mediawiki-Wikisource 1.29.0-wmf.15 (c93a3a5) UTC-20170313-23:12.html -- 20170315-01:09 : Mediawiki-Wikisource 1.29.0-wmf.15 (38e4ae6) UTC-20170314-22:46.html -- 20170316-01:16 : Mediawiki-Wikisource 1.29.0-wmf.16 (bb89e34) UTC-20170314-22:50.html -- 20170322-13:08 : Mediawiki-Wikisource 1.29.0-wmf.16 (09eb188) UTC-20170321-15:56.html -- 20170323-20:14 : Mediawiki-Wikisource 1.29.0-wmf.17 (8b8262c) UTC-20170321-18:35.html -- 20170324-11:33 : Mediawiki-Wikisource 1.29.0-wmf.17 (f95d913) UTC-20170324-02:07.html -- 20170328-01:18 : Mediawiki-Wikisource 1.29.0-wmf.17 (50d3b0f) UTC-20170327-11:40.html -- 20170328-22:22 ? Mediawiki-Wikisource 1.29.0-wmf.17 (774e09e) UTC-20170328-01:03.html -- 20170331-09:02 ? Mediawiki-Wikisource 1.29.0-wmf.18 (cbdfa46) UTC-20170328-19:42.html -- 20170404-21:30 : Mediawiki-Wikisource 1.29.0-wmf.18 (9ab639f) UTC-20170403-15:20.html -- <td dir="ltr"><a class="external text" href="//www.mediawiki.org/wiki/MediaWiki_1.29/wmf.19">1.29.0-wmf.19</a> <a class="external text" href="https://phabricator.wikimedia.org/r/revision/mediawiki/core;e4784c6b8dd69b07a43335f607aa8d15ec61e693">(e4784c6)</a><br/>7 avril 2017 à 20:52</td> -- -- UTC-20170407-19:52 : fr.wikisource.org/wiki/Spécial:Version = 1.29/wmf.19 (e4784c6) UTC-20170407T20:52.html -- UTC-20170407-20:21 : reported in T155624 Special:Version not showing SHA info for Mediawiki version on fr.wikisource -- UTC-20170407-21:50 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.19 (e4784c6) UTC-20170407T20:52.html -- UTC-20170408-21:54 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.19 (6765327) UTC-20170411T19:37.html -- UTC-20170413-08:00 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.20 (f50afe2) UTC-20170413T01:15.html -- UTC-20170414-08:04 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.20 (345b2be) UTC-20170414T01:24.html -- UTC-20170424-11:48 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.20 (c37821a) UTC-20170420T21:04.html -- UTC-20170424-17:55 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.20 (780d62d) UTC-20170424T14:35.html -- UTC-20170426-17:50 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.20 (8954854) UTC-20170425T15:31.html -- UTC-20170426-19:45 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.21 (e826acd) UTC-20170425T15:31.html -- UTC-20170426-16:55 : fr.wikisource.org/wiki/Spécial:Version = 1.29.0-wmf.21 (e826acd) UTC-20170425T22:50.html versioning.site_currentVersion_memo = "1.29.0-wmf.21 (e826acd)" return p -- Usual pages for Translations -- Utilisateur:Rical/Victor Hugo -- Modulenn:Central-s-br/doc {{#invoke:Central-s-br|read}} br = Breton = Brezhoneg -- Modul:Central-s-de/Doku {{#invoke:Central-s-de|read}} de = German = Deutsch -- Module:Central-s-en/Documentation {{#invoke:Central-s-en|read}} en = English = English -- Module:Central-s-es/Documentación {{#invoke:Central-s-es|read}} es = Spanish = español -- Module:Central-s-fr/Documentation {{#invoke:Central-s-fr|read}} fr = French = Français -- Modul:Central-w-hu/doc {{#invoke:Central-w-hu|read}} hu = Hungarian = Magyar -- Module:Central-mw-en/doc {{#invoke:Central-mw-en|read}} en = English = English -- Mô đun:Central-w-vi/tài liệu {{#invoke:Central-w-vi|read}} vi = Vietnamese = Tiếng việt -- MediaWiki:Scribunto/Central modules reference manual