Module:Central-s-fr
De Ekopedia
La documentation pour ce module peut être créée à Module:Central-s-fr/doc
-- Ce module ne semblant pas faire grand-chose d'utile pour le moment, -- à part catégoriser les pages qui l'utilisent dans des catégories inexistantes, -- je désactive le code de ce module, en retournant les fonctions minimums -- pour ne pas générer d'erreurs dans les pages l'utilisant. -- Pour plus d'info sur ce module, voir : -- * [[s:Module:Central-s-fr]] -- * [[s:MediaWiki:Scribunto/Central modules reference manual]] -- [[user:Zebulon84]], 14 avril 2018 return { read = function () return '' end; edit = function () return '' end; tests = function () return '' end; } --[=====[ local Central = {} -- The main central module install central libraries and bind the main and sub modules local p = Central p.versions = { -- Modules dependencies. Dependencias del módulo. Dépendances du module. versionName = "Central-s-fr", versionNumber = "180128.08.01", versionDate = "2018-01-28 08:01", -- UTC sought = "Central-s-fr;Central;Mathroman22;TestRequire", -- Sought module and submodules versions known = "Central-s-fr;Central;Central-14 * Mathroman22;Mathroman34 * TestRequire;TestRequ * TestBug;TestBug4", -- Known module and submodules versions } Central.Central_version = Central.versions.versionName p.ModuleNS = mw.site.namespaces.Module.name .. ":" -- translate Module: in other languages -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- Development guide line for i18n translations -- -- The Library:testsgrp initialises, runs and forms groups of tests for Mediawiki and users. -- -- 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:versn 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 string 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 central system permits to convert any module as central. -- The Lua part of the central modules support contains some libraries used by central modules. -- The Module:Central installs central libraries (waiting stable Scribunto central repository). -- An object has a function object.new() to form several objects -- A library is unic and come from Scribunto. -- Unique declarations of libraries and objects: -- To split ModuleCentral-s-fr delete activity. on 2018-01-10T09:35:00 activity = {} -- Library:activity from 20170611 Search story in Central modules.txt args = {} -- Object:args from 20180106 form known arguments to import, complete from datas and finalize boxview = {} -- Object:boxview from 20170723 in draft state datas = {} -- Library:datas from ? dropbox = {} -- Object:dropbox from 20170615 rename viewer.DropBox() in viewer.dropbox on 20170615 events = {} -- Object:events from ? "events" langs = {} -- Library:langs from i18n tables on 20130118, br-de-en-es-fr-vi from 20170217, lua_table = {} -- Library:lua_table from lua_table.level_list() from 20170808 mathroman = {} -- Library:mathroman from ? modes = {} -- Library:modes from arguments management on 20130125 in Module:Author, 20130312 in Module:ControlArgs centrobj = {} -- Object:centrobj from versn.centrobj on 20171211 in Module:Central tableview = {} -- Object:tableview from 20170208 tabView = {} -- Object:tabView from 20170208 testsgrp = {} -- Library:testsgrp from Initialises, runs and forms groups of tests for Mediawiki and users. tracker = {} -- Object:tracker from 20170628 versn = {} -- Library:versn from versioning on 20170316. From versions management in Module:Author3 on 20150225. viewer = {} -- Library:viewer from 20170209 versn.args = args -- Object:args from 20180106 todo versn.centrobj = centrobj -- Object:versn from 20170316 in draft state viewer.boxview = boxview -- Object:viewer from 20170723 ok on -- Records are in function versn.setup_central_libraries(bindable_libraries, opt) -- Install central bindable libraries in package.loaded Central.infos = { -- from 20171218 libname = "Central", typ = "Library", libdesc = "The main central module install central libraries and bind the main and sub modules.", versfirst = "130312.12:00", verslast = "171221.07:43", versions = { versionName = "Central-s-fr", versionNumber = "180106.0830", versionDate = "2018-01-06T08:30", -- UTC { libname = "Central", verstime = "2018-01-06T08:30:10", versid = "180106.0830", phabtask = "T135845", subtask = "S180106arg", change = "new: args.infos todo later", }, { libname = "Central", verstime = "2017-12-25T23:10:10", versid = "171225.2310", phabtask = "T135845", subtask = "S170901mMW", change = "MWversions_report()", }, { libname = "Central", verstime = "2013-03-12T12:00:00", versid = "130312.1200", phabtask = "T135845", subtask = "S000000new", change = "new: manage translations, arguments for central modules", }, }, -- infos.versions } -- infos -- see Central modules.txt : Short story of development -- * On [https://test2.wikipedia.org/w/index.php?title=Module:ControlArgs&oldid=48210 2013-03-12], -- the Module:ControlArgs groups complex translations and management of arguments to support other modules to become <b>centralisable</b>. activity.infos = { -- from 20171218 libname = "activity", typ = "Library", libdesc = "The Library:activity supports the management of Lua coders sub-tasks and inter-wikis central modules.", versfirst = "171218.1200", verslast = "171221.0743", versions = { { libname = "activity", verstime = "2017-12-25T00:01:02", versid = "171225.0001", phabtask = "T20170702", subtask = "S170804btu", change = "S171201xyz", }, { libname = "activity", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S171201xyz", change = "S171201xyz", }, { libname = "activity", verstime = "2017-12-12T00:00:00", versid = "171212.00", phabtask = "T000000", subtask = "S171201xyz", change = "S171201xyz", }, }, -- infos.versions } -- infos args.infos = { -- from 20180106 libname = "args", typ = "Object", libdesc = "The Object:args form known arguments to import, complete from datas and finalize.", versfirst = "180106.0815", verslast = "180106.0815", versions = { { libname = "args", verstime = "2018-01-06T08:30:10", versid = "180106.0830", phabtask = "T135845", subtask = "S180106arg", change = "new: args.infos todo later", }, }, -- infos.versions } -- infos centrobj.infos = { -- from 20171218 libname = "centrobj", typ = "Object", libdesc = "The Object:centrobj, in the Library:versn, begin to form libraries and their properties.", versions = { { libname = "centrobj", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "centrobj", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "centrobj", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos events.infos = { -- from 20171218 libname = "events", typ = "Library", libdesc = "The Library:events form events like erros, warnings and categories.", versfirst = "130312.1200", verslast = "171221.0743", versions = { { libname = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos langs.infos = { -- from 20171218 libname = "langs", typ = "Library", libdesc = "The Library:lua_table i18n translates: arguments names, sentencies, error messages, catégories...", versfirst = "130312.1200", verslast = "171221.0743", versions = { { libname = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos lua_table.infos = { -- from 20171218 libname = "lua_table", typ = "Library", libdesc = "The Library:lua_table enhances previous table library for counts and structure. It also converts to list or to rough_view.", versfirst = "130312.1200", verslast = "171221.0743", versions = { { libname = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos mathroman.infos = { -- from 20130312 libname = "mathroman", typ = "Library", libdesc = "The Library:mathroman converts roman to digital numbers and reverse. It also detects errors.", versfirst = "130312.1200", verslast = "171221.0743", versions = { { libname = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", }, { libname = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", }, { libname = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos modes.infos = { -- from 20171218 libname = "modes", typ = "Library", libdesc = "The Library:modes support modes and their options, like p.read(frame).", versfirst = "130312.1200", verslast = "171221.0743", versions = { { libname = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", }, { libname = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", }, { libname = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos tableview.infos = { -- from 20171218 libname = "tableview", typ = "Object", libdesc = "The Object:tableview and tabView, in the Library:viewer, forms tables in lines and columns.", versfirst = "130312.12:00", verslast = "171221.07:43", versions = { { libname = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos testsgrp.infos = { -- from 20171218 libname = "testsgrp", typ = "Library", libdesc = "The Library:testsgrp, initialises, runs and forms groups of tests for Mediawiki and users.", versions = { { libname = "testsgrp", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "testsgrp", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, { libname = "testsgrp", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos versn.infos = { -- from 20130312 libname = "versn", typ = "Library", libdesc = "The Library:versn installs central libraries, modules and translations. Also support versions management.", versfirst = "130312.1200", verslast = "171221.0743", versions = { { libname = "versn", verstime = "2017-12-14T20:13:27", versid = "171221.0743", phabtask = "T000000", subtask = "S000000abc", }, { libname = "versn", verstime = "2017-12-14T20:13:27", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", }, { libname = "versn", verstime = "2017-12-14T20:13:27", versid = "130312.1200", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos viewer.infos = { -- from 20130312 libname = "viewer", typ = "Library", libdesc = "The Library:viewer forms central objects views to easy form texts and search in them.", versfirst = "130312.1200", verslast = "171221.0743", versions = { { libname = "viewer", verstime = "2017-12-14T20:13:27", versid = "171221.0743", phabtask = "T000000", subtask = "S000000abc", }, { libname = "viewer", verstime = "2017-12-13T10:10:00", versid = "171213.1000", phabtask = "T000000", subtask = "S000000abc", }, { libname = "viewer", verstime = "2013-03-12T20:12:00", versid = "130312.1200", phabtask = "T000000", subtask = "S000000abc", }, }, -- infos.versions } -- infos modes.central_libraries = { -- New libraries to record in package.loaded[] { "activity", "The Library:activity supports the management of Lua coders sub-tasks and inter-wikis central modules.", }, { "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.", }, { "langs", "The Library:langs supports i18n translations.", }, { "lua_table", "The Library:lua_table enhances previous table library, to avoid ambiguities. To enhance, we could write here : lua_table = table.", }, { "mathroman", "The Library:mathroman convert roman numbers and detect errors. It is here as an example of very small central library.", }, { "modes", "The Library:modes support modes and their options, like p.read(frame).", }, { "testsgrp", "The Library:testsgrp, initialises, runs and forms groups of tests for Mediawiki and users.", }, { "viewer", "The Library:viewer form tableviews as objects inside the Library:viewer", }, { "versn", "The Library:versn installs all central libraries, modules and their i18n translations. It also support versions management.", }, -- Objects have a function object.new() to form several objects. { "args", "The Object:args form known arguments to import, complete from datas and finalize.", }, { "boxview", "The Object:boxview, in the Library:viewer, forms boxes, their styles and structures.", }, { "dropbox", "The Object:dropbox, in the Library:viewer, forms dropboxes and their styles.", }, { "centrobj", "The Object:centrobj, in the Library:versn, forms the basis of libraries and their properties.", }, { "tableview", "The Object:tableview, in the Library:viewer, forms some viewers for tables, in lines and columns.", }, { "tracker", "The Object:tracker, in the Library:activity, forms parametrables tracks to help to debug the code.", }, } Central.describ_version = "The main central module install central libraries and bind the main and sub modules." Central.libname = "Central" Central.previous_versions = { { libname = "Central", verstime = "2017-12-25T00:01:02", versid = "171225.0001", phabtask = "T20170702", subtask = "S170804btu", }, -- { libname = "Central", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "Central", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } activity.describ_version = "The Library:activity supports the management of Lua coders sub-tasks and inter-wikis central modules." activity.libname = "activity" activity.previous_versions = { { libname = "activity", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "activity", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "activity", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } args.infos = { -- from 20180106 libname = "args", typ = "Object", libdesc = "The Object:args form known arguments to import, complete from datas and finalize.", versfirst = "180106.0815", verslast = "180106.0815", versions = { { libname = "args", verstime = "2018-01-06T08:30:10", versid = "180106.0830", phabtask = "T135845", subtask = "S180106arg", change = "new: Object:args todo later", }, }, -- infos.versions } -- infos boxview.describ_version = "The Object:boxview, in the Library:viewer, forms boxes, their styles and structures." boxview.libname = "boxview" boxview.previous_versions = { { libname = "boxview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "boxview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "boxview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } datas.describ_version = "The Library:datas form some viewers for tables(in lines and columns), dropboxes, luatables..." datas.libname = "datas" datas.previous_versions = { { libname = "datas", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "datas", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "datas", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } dropbox.describ_version = "The Object:dropbox, in the Library:viewer, forms dropboxes and their styles." dropbox.libname = "dropbox" dropbox.previous_versions = { { libname = "dropbox", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "dropbox", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "dropbox", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } events.describ_version = "The Library:events form events like erros, warnings and categories." events.libname = "events" events.previous_versions = { { libname = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "events", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } langs.describ_version = "The Library:langs supports i18n translations." langs.libname = "langs" langs.previous_versions = { { libname = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "langs", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } lua_table.describ_version = "The Library:lua_table enhances previous table library, to avoid ambiguities. To enhance, we could write here : lua_table = table." lua_table.libname = "lua_table" lua_table.previous_versions = { { libname = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "lua_table", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } mathroman.describ_version = "The Library:mathroman convert roman numbers and detect errors. It is here as an example of very small central library." mathroman.libname = "mathroman" mathroman.previous_versions = { { libname = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "mathroman", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } modes.describ_version = "The Library:modes support modes and their options, like p.read(frame)." modes.libname = "modes" modes.previous_versions = { { libname = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "modes", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } centrobj.describ_version = "The Object:centrobj, in the Library:versn, forms the basis of libraries and their properties." centrobj.libname = "centrobj" centrobj.previous_versions = { { libname = "centrobj", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "centrobj", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "centrobj", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } tableview.describ_version = "The Object:tableview, in the Library:viewer, forms some viewers for tables, in lines and columns." tableview.libname = "tableview" tableview.previous_versions = { { libname = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "tableview", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } tabView.describ_version = "The Object:tabView, in the Library:tableview, forms cases of tests and reports." tabView.libname = "tabView" tabView.previous_versions = { { libname = "tabView", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "tabView", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "tabView", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } testsgrp.describ_version = "The Library:testsgrp, initialises, runs and forms groups of tests for Mediawiki and users." testsgrp.libname = "testsgrp" testsgrp.previous_versions = { { libname = "testsgrp", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "testsgrp", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "testsgrp", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } versn.describ_version = "The Library:versn installs all central libraries, modules and their i18n translations. It also support versions management." versn.libname = "versn" versn.previous_versions = { { libname = "versn", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "versn", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "versn", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } viewer.describ_version = "The Library:viewer forms views of many central objects to easy form texts and search in them." viewer.libname = "viewer" viewer.previous_versions = { { libname = "viewer", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "viewer", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, { libname = "viewer", verstime = "2017-12-14T20:13:27", versid = "171213.10", phabtask = "fr.wikisource", subtask = "fr.wikisource", }, } modes.central_libraries = { -- New libraries to record in package.loaded[] { "activity", "The Library:activity supports the management of Lua coders sub-tasks and inter-wikis central modules.", }, { "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.", }, { "langs", "The Library:langs supports i18n translations.", }, { "lua_table", "The Library:lua_table enhances previous table library, to avoid ambiguities. To enhance, we could write here : lua_table = table.", }, { "mathroman", "The Library:mathroman convert roman numbers and detect errors. It is here as an example of very small central library.", }, { "modes", "The Library:modes support modes and their options, like p.read(frame).", }, { "testsgrp", "The Library:testsgrp, initialises, runs and forms groups of tests for Mediawiki and users.", }, { "viewer", "The Library:viewer form tableviews as objects inside the Library:viewer", }, { "versn", "The Library:versn installs all central libraries, modules and their i18n translations. It also support versions management.", }, -- Objects have a function object.new() to form several objects. { "boxview", "The Object:boxview, in the Library:viewer, forms boxes, their styles and structures.", }, { "dropbox", "The Object:dropbox, in the Library:viewer, forms dropboxes and their styles.", }, { "centrobj", "The Object:centrobj, in the Library:versn, forms the basis of libraries and their properties.", }, { "tableview", "The Object:tableview, in the Library:viewer, forms some viewers for tables, in lines and columns.", }, { "tracker", "The Object:tracker, in the Library:activity, forms parametrables tracks to help to debug the code.", }, } -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Object:tracker implements parametrable track objects to debug the Lua code. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- activity = {} -- already declared by Scribunto, in _G space, then in package.loaded["begin"]. -- tracker = {} -- already declared by Scribunto, see centrobj.new() -- Record a library in package.loaded tracker.obj = { -- Options from: default, init and use steps. To mix in obj.* ["level"] = 1, -- level of detail of each track line ["name"] = "TRACK", -- name of the track ["where"] = "IN TRACK", -- name of the track ["limit"] = 2, -- Limit of track more or less details ["form"] = "\n* %1 in=<b>%2</b>", -- begin or each track line ["more"] = ", arg%1=<b>%2</b>", -- add to the previous text ["t"] = "", -- resulting text with all track lines ["groupname"] = "*.+!;-/", -- to display all grouped events with a same name ["add"] = function() return "" end, -- for tracker.initadd(opt) ["trk"] = function() return "" end, -- for tracker.initrack(opt) } function tracker.new(opt) -- Initialize a track -- from: ModuleCentral-s-fr 3e update subtasks ok.lua 20170918 -- The groupid option can select which track select and add in the groupname group. if (type(opt) ~= "table") then opt = {} end opt.level = opt.level or 1 -- level of detail of each track line opt.name = opt.name or "TRACK" -- name of the track opt.limit = opt.limit or 1 -- limit of detailed lines opt.form = opt.form or "\n* %1 in=<b>%2</b>" -- begin or each track line opt.more = opt.more or ", arg%1=<b>%2</b>" -- add to the previous text opt.t = opt.t or "" -- resulting text with all track lines opt.trackon = 1 -- track on or not (= 0) for one track object. opt.groupid = opt.groupid -- to select tracks in a group opt.groupname = opt.groupname -- to display all grouped events with a same name return opt end -- function tracker.new(opt) function tracker.add(opt, level, IN, ... ) -- Add, or not, a new track line to the list local t = "" -- function tracker:add(self, ...) -- table.func = function ( self, var-list ) block end if (type(opt) ~= "table") then return t end if opt.trackon == 0 then return t end if viewer.is_in_sp(opt.groupid, IN) then opt.grouptrack = opt.groupname or opt.groupid -- opt.grouptotrack = true -- viewer.MUT = tracker.init({ ["name"] = "MUT", limit = 2, groupid = "auto_val", ["groupname"] = "auto_val"}) -- Initialize a track -- MUT.add(MUT, 1, "modes.init_args_mode_options", { ["mode_name"] = mode_name, } ) -- MAMO, ARGS, AUTOVAL -- if (type(MUT) ~= "table") or (type(MUT.add) ~= "function") then MUT = tracker.init({ ["name"] = "NMC", ["limit"] = 2 }) end -- Initialize a track -- if (type(CNT) ~= "table") or (type(CNT.add) ~= "function") then CNT = tracker.init({ ["name"] = "NMC", ["limit"] = 2 }) end -- Initialize a track -- if (type(NMC) ~= "table") or (type(NMC.add) ~= "function") then NMC = tracker.init({ ["name"] = "NMC", ["limit"] = 2 }) end -- Initialize a track end if opt.grouptrack then t = t .. "<b>" .. opt.grouptrack .. ":</b> " end if (type(level) == "number") and (level > opt.limit) then return t end local vals, vals_t = { ... }, "" local vals_t = "\n* <b>" .. opt.name .. "</b>: " .. viewer.ta("in", IN) if (type(vals[1]) == "table") then vals = vals[1] end for k, var in pairs( vals ) do if var ~= nil then vals_t = vals_t .. viewer.ta(k, tostring(var) ) end end if where == opt.name then -- List the tracker options opt.values = viewer.ta("name", opt.name) -- .. viewer.ta("level", opt.level) .. viewer.ta("limit", opt.limit) -- .. viewer.ta("form", opt.form) .. viewer.ta("more", opt.more) .. viewer.ta("opt_N", lua_table.count_all(opt) ) .. viewer.ta("trackon", opt.trackon) -- .. viewer.ta("t", opt.t) return opt.t .. vals_t .. opt.values .. "<br>" end opt.t = opt.t .. vals_t -- add this track to the list of track lines t = t .. "<br>" return t -- report local track line end -- tracker.ARGS.t function tracker.initadd_old(opt) -- Initialize a track -- from: ModuleCentral-s-fr 3e update subtasks ok.lua 20170918 -- local obj = mw.clone(opt) local obj = mw.clone(tracker.obj) if (type(opt) ~= "table") then opt = {} end for key, val in pairs(opt) do if (type(key) == "string") and (val ~= nil) then obj[key] = val end end obj = tracker.new(obj) opt.add = tracker.add _G[obj.name] = obj return obj -- "methods, that is, functions that have an implicit extra parameter self." See http://www.lua.org/manual/5.1/manual.html#2.5.9 -- "c:f (params) body end is syntactic sugar for c.f = function (self, params) body end" See http://www.lua.org/manual/5.1/manual.html#2.5.9 -- opt:trk( limit, name, vals) -- run like opt:trk(self, limit, name, vals) end -- function tracker.initadd(opt) function tracker.initadd(opt) -- Initialize a track if (type(opt) ~= "table") then opt = {} end if (type(opt) == "table") and (type(opt.add) == "function") and (opt.name == _G[opt.name]) then -- _G[opt.name] = opt -- Reuse already initialized tracker for its continuity. -- return opt end opt = tracker.new(opt) opt.add = tracker.add _G[opt.name] = opt return opt end -- EXD = tracker.initadd({ ["name"] = "EXD", limit = 2, }) -- Initialize a track -- See: "Function as a method in a table" in Lua_reference_manual#Function_declaration_statements function tracker.initrack(opt) -- Initialize one new tracker and its track lines. if (type(opt) ~= "table") then opt = { ["name"] = "DEFAULTRACK", ["limit"] = 2 } end if (type(opt.name) ~= "string") then opt.name = "DEFAULTRACK" end if (type(opt.limit) ~= "number") then opt.limit = 2 end local optrk = mw.clone(opt) -- New initial tracker object function optrk:trk(self, limit, name, vals) -- see S171015trk return tracker.add(self, limit, name, vals) or "\n* optrk:trk. " end _G[optrk.name] = optrk return optrk -- "methods, that is, functions that have an implicit extra parameter self." See http://www.lua.org/manual/5.1/manual.html#2.5.9 -- "c:f (params) body end is syntactic sugar for c.f = function (self, params) body end" See http://www.lua.org/manual/5.1/manual.html#2.5.9 -- opt:trk( limit, name, vals) -- run like opt:trk(self, limit, name, vals) end -- EXD = tracker.initrack({ ["name"] = "EXD", limit = 2, }) -- Initialize a track -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:activity 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 --]==] -- activity = {} -- already declared by Scribunto, see centrobj.new() -- Record a library in package.loaded -- begin = {} -- already declared by Scribunto, see centrobj.new() -- Record a library in package.loaded -- Translations for begin library activity.i18n = {} activity.i18n.br = { -- br = Breton = Brezhoneg -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. -- _begin_ _begin_ 24 replace -- begin_ activity_ 102 replaces -- Modulenn:Central-s-br/doc {{#invoke:Central-s-br|read}} br = Breton = Brezhoneg activity_central_library_description = "La Library:activity soutient la gestion des tâches de phabricator, des sous-tâches inter Lua-codeurs et des modules centraux interwikis.", activity_display_central_libraries_title = "activity.describe_central_libraries() Description des bibliothèques centrales", activity_translate_string_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.", activity_Module_Central_central_version = "Modulenn:Central", activity_Library_translate_I18N = "Modulenn:Library/translate/I18N", activity_Central_modules_reference_manual = "Scribunto/Lua reference manual", activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Surveiller l'état actuel des sous-tâches", activity_monitor_MW_Versions_title = "<b>activity.monitor_MW_Versions()</b> Surveiller les versions de Mediawiki.", -- br activity_central_count_admins_active_users = "Ce site, br.wikisource.org, compte %1 administrateurs pour %2 utilisateurs actifs.", activity_support_central_modules_title = "<b>activity.support_begin_central_modules()</b> Soutenir les premières utilisations des Central modules.", activity_support_central_modules_headers = "Projet; Langue; Admins; Actifs; Début le; Utilisé depuis; Utilisateur", activity_phabricator_tasks_title = "activity.monitor_phabricator_tasks() États des tâches connexes dans Phabricator", activity_phabricator_tasks_headers = "Importance, modifiée le; Tâche; Etat; Titre", -- ; En bref activity_list_libraries_functions_title = "activity.list_libraries_functions(t) Lister les fonctions actuelles.", } -- activity.i18n.br activity.i18n.de = { -- de = German = Deutsche -- Modul:Central-s-de/Doku {{#invoke:Central-s-de|read}} de = German = Deutsch activity_central_library_description = "Das Library:activity Das Ding unterstützt das Management von phaborator-Aufgaben, von inter-Lua-Coder-Unteraufgaben und von interwikis-Zentralmodulen.", activity_display_central_libraries_title = "activity.describe_central_libraries() Zentrale Bibliotheksbeschreibungen", activity_Module_Central_central_version = "Modul:Central", activity_Library_translate_I18N = "Modul:Library/translate/I18N", activity_Central_modules_reference_manual = "Scribunto/Central modules reference manual", activity_support_central_modules_title = "<b>activity.support_begin_central_modules()</b> Unterstützen Sie die ersten Anwendungen von Central-Modulen.", activity_support_central_modules_headers = "Projekt; Sprache; Admins; Vermögenswerte; Anfang an; Gebraucht seit; Benutzer", activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Überwachen Sie den aktuellen Stand der subtasks", activity_monitor_MW_Versions_title = "<b>activity.monitor_MW_Versions()</b> Überwachen von Mediawiki-Versionen.", -- de activity_central_count_admins_active_users = "Für diese Seite, br.wikisource.org, Konto 1% Direktoren für %2 aktive Nutzer.", activity_phabricator_tasks_title = "activity.monitor_phabricator_tasks() Zuständige Aufgaben in Phabricator", activity_phabricator_tasks_headers = "Wichtigkeit; modifiziert die; Aufgabe; Status; Titel", activity_list_libraries_functions_title = "activity.list_libraries_functions(t) Listen Sie die aktuellen Funktionen auf.", } -- activity.i18n.de activity.i18n.en = { -- en = English = English -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. activity_central_library_description = "The Library:activity supports the management of phabricator tasks, of inter Lua coders sub-tasks, and of interwikis central modules.", activity_display_central_libraries_title = "activity.describe_central_libraries() Central libraries descriptions", activity_translate_string_guide = "To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", activity_Module_Central_central_version = "Module:Central", activity_Library_translate_I18N = "Module:Library/translate/I18N", activity_Central_modules_reference_manual = "Scribunto/Central modules reference manual", activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Monitor the current subtasks", activity_monitor_MW_Versions_title = "<b>activity.monitor_MW_Versions()</b> Monitor Mediawiki versions.", -- en activity_central_count_admins_active_users = "This site, br.wikisource.org, count %1 administrators for %2 active users.", activity_support_central_modules_title = "<b>activity.support_begin_central_modules()</b> Support the first uses of Central modules.", activity_support_central_modules_headers = "Project; Language; Admins; Assets; Module version; Link to doc; Start on; Used from; User", activity_phabricator_tasks_title = "activity.monitor_phabricator_tasks() States of related tasks in Phabricator", activity_phabricator_tasks_headers = "Importance; modified on; Task; Status; Title", activity_list_libraries_functions_title = "activity.list_libraries_functions(t) List actual functions.", } -- activity.i18n.en activity.i18n.es = { -- es = Spanish = español -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. -- Módulo:Central-s-es/Documentación {{#invoke:Central-s-es|read}} es = Spanish = español activity_central_library_description = "La Library:activity soporta la gestión de tareas de phabricator, de sub-tareas inter Lua coders, y de módulos interwikis centrales.", activity_display_central_libraries_title = "activity.describe_central_libraries() Descripciones de bibliotecas centrales", activity_translate_string_guide = "Para traducir, no traducir partes como estas: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G.", activity_Module_Central_central_version = "Módulo:Central", activity_Library_translate_I18N = "Módulo:Library/translate/I18N", activity_Central_modules_reference_manual = "Scribunto/Central modules reference manual", activity_support_central_modules_title = "activity.support_begin_central_modules() Apoye los primeros usos de los módulos centrales.", activity_support_central_modules_headers = "Proyecto; Lengua; Administradores; Activos; Comenzando encendido; Usado desde entonces; Usuarios", activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Monitorear las subtareas", activity_monitor_MW_Versions_title = "<b>activity.monitor_MW_Versions()</b> Monitorear las versiones de Mediawiki.", -- es activity_central_count_admins_active_users = "Este sitio, br.wikisource.org, cuenta %1 administradores para %2 usuarios activos.", activity_phabricator_tasks_title = "activity.monitor_phabricator_tasks() Tareas relacionadas con los estados en Phabricator", activity_phabricator_tasks_headers = "Importancia; modificado; Tarea; Estado; Título", activity_list_libraries_functions_title = "activity.list_libraries_functions(t) Listar funciones actuales.", } -- activity.i18n.es activity.i18n.fr = { -- fr = French = Français -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. activity_central_library_description = "La Library:activity soutient la gestion des tâches de phabricator, des sous-tâches inter Lua-codeurs et des modules centraux interwikis.", activity_display_central_libraries_title = "activity.describe_central_libraries() Description des bibliothèques centrales", activity_translate_string_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.", activity_Module_Central_central_version = "Module:Central", activity_Library_translate_I18N = "Module:Library/translate/I18N", activity_Central_modules_reference_manual = "Scribunto/Central modules reference manual", activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Surveiller les sous-tâches", activity_monitor_MW_Versions_title = "<b>activity.monitor_MW_Versions()</b> Surveiller les versions de Mediawiki.", -- fr activity_central_count_admins_active_users = "Ce site, fr.wikisource.org, compte %1 administrateurs pour %2 utilisateurs actifs.", activity_support_central_modules_title = "activity.support_begin_central_modules() Soutenir les premières utilisations des Central modules.", activity_support_central_modules_headers = "Projet; Langue; Admins; Actifs; Début le; Utilisé depuis; Utilisateur", activity_phabricator_tasks_title = "activity.monitor_phabricator_tasks() États des tâches connexes dans Phabricator", activity_phabricator_tasks_headers = "Importance, modifiée le; Tâche; Etat; Titre", activity_list_libraries_functions_title = "activity.list_libraries_functions(t) Lister les fonctions actuelles.", } -- activity.i18n.fr activity.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}} -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. activity_central_library_description = "A Library:activity a phabricator feladatok kezelését, az inter Lua-kódoló al-feladatok és az interwikis központi modulok kezelését.", activity_display_central_libraries_title = "activity.describe_central_libraries() Központi könyvtárak leírása", activity_translate_string_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.", activity_Module_Central_central_version = "Modul:Central", activity_Library_translate_I18N = "Modul:Library/translate/I18N", activity_Central_modules_reference_manual = "Scribunto/Central modules reference manual", activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Kíséri részfeladatok", activity_monitor_MW_Versions_title = "<b>activity.monitor_MW_Versions()</b> Monitor Mediawiki verziók.", -- hu activity_central_count_admins_active_users = "Ez az oldal, br.wikisource.org, fiók %1 rendszergazdák és %2 felhasználók aktív.", activity_support_central_modules_title = "activity.support_begin_central_modules() Támogassa a központi modulok első használatát.", activity_support_central_modules_headers = "Project Nyelv; Adminok; eszközök; Modul verzió; Link doc-re; Indulás; Használt; használó", activity_phabricator_tasks_title = "activity.monitor_phabricator_tasks() Államokkal kapcsolatos feladatok a Phabricator", activity_phabricator_tasks_headers = "Fontosság; módosította; a Feladat; Állapot; Cím", activity_list_libraries_functions_title = "activity.list_libraries_functions(t) Listázza az aktuális funkciókat.", } -- activity.i18n.hu activity.i18n.vi = { -- vi = Vietnamese = Tiếng việt -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. activity_central_library_description = "Điều này Library:activity hỗ trợ việc quản lý các công việc của nhà phân tích, các nhiệm vụ phụ liên Lua coders, và các mô-đun trung tâm liên thông.", activity_display_central_libraries_title = "activity.describe_central_libraries() Mô tả thư viện trung ương", activity_translate_string_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.", activity_Module_Central_central_version = "Mô đun:Central", activity_Library_translate_I18N = "Mô đun:Library/translate/I18N", activity_Central_modules_reference_manual = "Scribunto/Central modules reference manual", activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Xem việc phụ", activity_monitor_MW_Versions_title = "<b>activity.monitor_MW_Versions()</b> Giám sát các phiên bản Mediawiki.", -- vi activity_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.", activity_support_central_modules_title = "activity.support_begin_central_modules() Hỗ trợ sử dụng đầu tiên của mô-đun Trung tâm.", activity_support_central_modules_headers = "dự án; ngôn ngữ; Quản trị viên; tài sản; Bắt đầu từ; Được sử dụng từ; người sử dụng", activity_phabricator_tasks_title = "activity.monitor_phabricator_tasks() Các nhiệm vụ liên quan đến Nhà nước trong Phabricator", activity_phabricator_tasks_headers = "Tầm quan trọng; sửa đổi; nhiệm vụ; tình trạng; tiêu đề", activity_list_libraries_functions_title = "activity.list_libraries_functions(t) Liệt kê các chức năng hiện tại.", } -- activity.i18n.vi function activity.describe_central_libraries(t) -- Central libraries descriptions, activity_display_central_libraries_title local memo = viewer.zzz_save_configs("activity.describe_central_libraries") -- Save global configuration before eventual changes. local t = t or "\n* <b>activity.describe_central_libraries()</b> Monitor central libraries descriptions." -- t or local tabView = { testGroup = modes.central_libraries, -- List of subtasks to monitor. title_memo = "activity_display_central_libraries_title", -- "activity.describe_central_libraries() Monitor central libraries descriptions", -- headers = "activity_monitor_central_libraries_headers", -- " Name; Description of the library ", headers = " Name; Description of the library ", headers_class = "wikitable alternative center sortable", rowGroup = {}, -- track_on == "details", } t = t .. tableview.new(tabView) -- Form a table view with lines and columns. return t end activity.wikis_names = { -- see mw:Extension:WikimediaIncubator ["b"] = 'wikibooks', ["cm"] = 'commons', ["meta"] = 'meta', ["mw"] = 'mediawiki', ["n"] = 'wikinews', ["p"] = 'wiki', ["q"] = 'wikiquote', ["s"] = 'wikisource', ["species"] = 'species', ["t"] = 'wiktionary', ["test"] = 'test', ["test2"] = 'test2', ["v"] = 'wikiversity', ["w"] = 'wikipedia', ["wm"] = 'wikimedia', ["y"] = 'wikivoyage', } -- activity.wikis_names -- see https://fr.wikisource.org/wiki/Spécial:Interwiki -- see https://www.mediawiki.org/wiki/Special:Interwiki -- see https://fr.wikisource.org/wiki/Sp%C3%A9cial:Matrice_des_sites activity.kiwis_names = { ["commons"] = 'cm', ["mediawiki"] = 'mw', ["meta"] = 'meta', ["species"] = 'species', ["test"] = 'test', ["test2"] = 'test2', ["wiki"] = 'p', ["wikibooks"] = 'b', ["wikimedia"] = 'wm', ["wikinews"] = 'n', ["wikipedia"] = 'w', ["wikiquote"] = 'q', ["wikisource"] = 's', ["wikiversity"] = 'v', ["wikivoyage"] = 'y', ["wiktionary"] = 't', } activity.wikis_to_begin = { -- br.wikisource.org/wiki/Modulenn:Central-s-br/doc {{#invoke:Central-s-br|read}} fr = Breton = Breton = Breitz { s = 1, doc_full = "br.wikisource.org/wiki/Modulenn:Central-s-br/doc", enforce_main_version = "br.wikisource.org", beginon = "20171105", usedfrom = "20171130 ?", user = "VIGNERON", -- 1 template = "Modèle", admins = "16", assets = "236", -- 16 administrators for 236 assets }, -- de.wikisource.org/wiki/Modul:Central-s-de/Doku {{#invoke:Central-s-de|read}} de = German = Deutsch { s = 2, doc_full = "de.wikisource.org/wiki/Modul:Central-s-de/Doku", enforce_main_version = "de.wikisource.org", beginon = "20171105 ?", usedfrom = "20171130 ?", user = "?", -- 2 template = "Modèle", admins = "16 ?", assets = "236 ?", -- 16 administrators for 236 assets }, -- en.wikipedia.org/wiki/Module:Central-w-en/Documentation {{#invoke:Central-w-en|read}} en = English = English { s = 3, doc_full = "en.wikipedia.org/wiki/Module:Central-w-en/Documentation", enforce_main_version = "en.wikipedia.org", beginon = "20171115 ?", usedfrom = "20171104 ?", user = "?", -- 3 template = "Modèle", admins = "16 ?", assets = "236 ?", -- 16 administrators for 236 assets }, -- es.wikipedia.org/wiki/Módulo:Central-w-es/Documentación {{#invoke:Central-w-es|read}} es = Spanish = español { s = 4, doc_full = "es.wikipedia.org/wiki/Módulo:Central-w-es/Documentación", enforce_main_version = "es.wikisource.org", beginon = "20171115 ?", usedfrom = "20171104 ?", user = "?", -- 4 template = "Modèle", admins = "16 ?", assets = "236 ?", -- 16 administrators for 236 assets }, -- fr.wikipedia.org/wiki/Module:Central-w-fr/Documentation {{#invoke:Central-w-fr|read}} fr = French = Français { s = 5, doc_full = "fr.wikisource.org/wiki/Module:Central-w-fr/Documentation", enforce_main_version = "fr.wikipedia.org", beginon = "20171112", usedfrom = "20171112 ?", user = "Ickx6", -- 5-- Lua-coder: Zebulon84, Ickx6. Od1n=coder.JS template = "Modèle", admins = "16", assets = "294", -- 16 administrators for 236 assets }, -- fr.wikisource.org/wiki/Module:Central-s-fr/Documentation {{#invoke:Central-s-fr|read}} fr = French = Français { s = 6, doc_full = "fr.wikisource.org/wiki/Module:Central-s-fr/Documentation", enforce_main_version = "fr.wikisource.org", beginon = "20170215", usedfrom = "20171104 ?", user = "Rical", -- 6 template = "Modèle", admins = "16", assets = "294", -- 16 administrators for 236 assets }, -- hu.wikipedia.org/wiki/Modul:Central-w-hu/doc {{#invoke:Central-w-hu|read}} hu = Hungarian = Magyar { s = 7, doc_full = "hu.wikipedia.org/wiki/Modul:Central-w-hu/doc", enforce_main_version = "hu.wikipedia.org", beginon = "20171105 ?", usedfrom = "20171130 ?", user = "?", -- 7 template = "Modul", admins = "23", assets = "1513", -- 23 administrators for 1513 assets }, -- https://www.mediawiki.org/wiki/Module:Central-mw-en {{#invoke:Central-mw-en|read}} en = English = English { s = 8, doc_full = "www.mediawiki.org/wiki/Module:Central-mw-en/doc", enforce_main_version = "www.mediawiki.org", beginon = "20171127", usedfrom = "20171105", user = "Rical", -- 8 template = "Template", admins = "184", assets = "1215", -- 184 administrators for 1215 assets on 20170427 }, -- vi.wikipedia.org/wiki/Mô đun:Central-w-vi/tài liệu {{#invoke:Central-w-vi|read}} vi = Vietnamese = Tiếng Việt { s = 9, doc_full = "vi.wikipedia.org/wiki/Mô_đun:Central-w-vi/tài_liệu", enforce_main_version = "vi.wikipedia.org", beginon = "20171112 ?", usedfrom = "20171130 ?", user = "Lê Thy ?", -- 9 template = "Modèle", admins = "23", assets = "1513", -- 23 administrators for 1513 assets }, } -- end activity.wikis_to_begin activity.proto_version = "Central-s-fr" activity.local_version = "Central-s-fr" -- default function activity.central_module_descriptor(wiki, selector) -- Begin to adapt the main central module version to a wiki. local mwuri = mw.uri.new() local hostPort = mwuri.hostPort local actual_wiki = false if type(selector ~= "string") then selector = hostPort end -- Adapt to actual wiki as default -- wiki.doc_full = wiki.version_full .. "/" .. wiki.doc -- fr.wikisource.org/wiki/Module:Central-s-fr/Documentation if not CMD then CMD = tracker.initadd({ ["name"] = "CMD", ["limit"] = 2 }) end -- Initialize a track wiki.actual_wiki = actual_wiki -- Is this wiki selected? if (type(wiki.doc_full) == "string") then -- fr.wikisource.org/wiki/Module:Central-s-fr/Documentation local points = string.gsub(wiki.doc_full, "/", ".") -- fr.wikisource.org.wiki.Module:Central-s-fr.Documentation local points = string.gsub(points, ":", ".") -- fr.wikisource.org.wiki.Module.Central-s-fr.Documentation local s = mw.text.split(points, '.', true)-- { "fr", "wikisource", "org", "wiki", "Module", "Central-s-fr", "Documentation" } wiki.url_ref = "https://fr.wikisource.org/wiki/Module:Central-s-fr/Documentation" wiki.protocol = "https://" -- https:// wiki.lang_project_org = s[1] .. "." .. s[2] .. "." .. s[3] if (type(wiki.enforce_main_version) == "string") then wiki.lang_project_org = wiki.enforce_main_version end wiki.doc_full = string.gsub(wiki.doc_full, wiki.lang_project_org, wiki.enforce_main_version) -- fr.wikisource.org.wiki.Module.Central-s-fr.Documentation local points = string.gsub(wiki.doc_full, "/", ".") -- fr.wikisource.org.wiki.Module:Central-s-fr.Documentation local points = string.gsub(points, ":", ".") -- fr.wikisource.org.wiki.Module.Central-s-fr.Documentation local s = mw.text.split(points, '.', true)-- s= { "fr", "wikisource", "org", "wiki", "Module", "Central-s-fr", "Documentation" } wiki.lang = s[1] -- fr wiki.project = s[2] -- wikisource if wiki.project =="mediawiki" then wiki.lang = "en" end wiki.proj = activity.kiwis_names[wiki.project] or "proj" -- s in brief for wikisource wiki.org = s[3] -- org wiki.lang_project_org = wiki.lang .. "." .. wiki.project .. "." .. wiki.org -- fr.wikisource.org if wiki.lang_project_org == hostPort then actual_wiki = true ; wiki.actual_wiki = actual_wiki end if wiki.actual_wiki then wiki.admins = tostring(mw.site.stats.usersInGroup("sysop")) wiki.assets = tostring(mw.site.stats.activeUsers) wiki.found = true -- This wiki is selected CMD.add(CMD, 1, "descriptor admins assets hostPort", { ["admins"] = wiki.admins, ["assets"] = wiki.assets, ["actual_wiki"] = wiki.actual_wiki, ["lang_project_org"] = wiki.lang_project_org, } ) else wiki.admins = wiki.admins wiki.assets = wiki.assets wiki.actual_wiki = wiki.actual_wiki -- This wiki is selected CMD.add(CMD, 1, "descriptor admins assets else", { ["admins"] = wiki.admins, ["assets"] = wiki.assets, ["actual_wiki"] = wiki.actual_wiki, ["lang_project_org"] = wiki.lang_project_org, } ) end CMD.add(CMD, 1, "descriptor wikis_to_begin", { ["i"] = i, ["s"] = s, ["wiki.lang"] = wiki.lang, ["wiki.lang_project_org"] = wiki.lang_project_org, } ) wiki.wiki = s[4] -- wiki wiki.transmodule = s[5] -- Module wiki.version = "Central-" .. wiki.proj .. "-" .. wiki.lang -- Central-s-fr wiki.modulename = wiki.version -- s[6] -- Module wiki.version_full = wiki.lang_project_org .. "/" .. wiki.wiki .. "/" .. wiki.transmodule .. ":" .. wiki.version wiki.version_url = wiki.protocol .. wiki.lang_project_org .. "/" .. wiki.wiki .. "/" .. wiki.transmodule .. ":" .. wiki.version wiki.version_link = "[" .. wiki.version_url .. " " .. wiki.version .. "]" -- To link to the central version wiki.doc = s[7] -- Documentation wiki.doc_full = wiki.version_full .. "/" .. wiki.doc -- fr.wikisource.org/wiki/Module:Central-s-fr/Documentation wiki.doc_url = wiki.protocol .. wiki.doc_full -- https://fr.wikisource.org/wiki/Module:Central-s-fr/Documentation wiki.doc_link = "[" .. wiki.doc_url .. " " .. wiki.doc .. "]" -- To link to the documentation of the central version CMD.add(CMD, 1, "activity.descriptor links", { ["wiki.lang_project_org"] = wiki.lang_project_org, ["wiki.version"] = wiki.version, ["version_link"] = wiki.version_link, ["doc_link"] = wiki.doc_link, } ) end -- CMD.t = "\n* <b>:activity.central_module_descriptor()</b> END." return wiki end -- function activity.central_module_descriptor(wiki, selector) function activity.init_central_versions(wikis_to_begin, selector, proto_version) -- Adaptation of central modules versions in begin phase. -- 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. -- See: $wmincProjectDatabases in https://www.mediawiki.org/wiki/Extension:WikimediaIncubator langs.Central_version = Central.Central_version -- To adapt the version of Module:Central in any translated text. -- enforce_main_version = "Central-s-br", if (type(wikis_to_begin) ~= "table") then wikis_to_begin = activity.wikis_to_begin end return "\n* activity.init_central_versions()" .. viewer.ta("local_version", activity.local_version) .. viewer.ta("proto_version", activity.proto_version) end -- function activity.init_central_versions(wikis_to_begin, local_wiki, proto_version) function activity.count_used_central_wikis(wikis_to_begin) -- Count using of central modules in wikis, in begin phase. local wikis_to_begin = wikis_to_begin if (type(wikis_to_begin) ~= "table") then wikis_to_begin = activity.wikis_to_begin 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(wikis_to_begin) 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 = lua_table.level_count(tabs.project) counts.modulename = lua_table.level_count(tabs.modulename) counts.lang = lua_table.level_count(tabs.lang) counts.user = lua_table.level_count(tabs.user) return counts end -- function activity.count_used_central_wikis(wikis_to_begin) function activity.list_actual_libraries(t) -- List actual libraries for documentation. subtask S171128laf "now", local t = t or "\n* activity.list_actual_libraries(t) List actual libraries for documentation." local i_libraries = {} local central_libraries = {} for name, library in pairs(package.loaded) do -- search all libraries if (type(library) == "table") and (type(library["i18n"]) == "table") then -- select central libraries name = string.gsub(name, versn.ModuleNS, "") -- delete Module: table.insert(i_libraries, { ["name"] = name, ["library"] = library} ) end end table.sort(i_libraries, function (a, b) return (a["name"] < b["name"]) end ) -- Sort libraries table.sort(i_libraries, function (a, b) return ( (a["libname"] or "libname") < (b["libname"] or "libname") ) end ) -- Sort libraries activity.i_libraries = i_libraries for i, lib in pairs(i_libraries) do t = t .. "\n* <b>Library:" .. tostring(lib["libname"]) .. "</b>, " end return t end -- function activity.list_actual_libraries(t) -- activity_list_libraries_functions_title = "activity.list_libraries_functions(t) List actual functions.", function activity.list_libraries_functions(t) -- List actual functions for documentations. subtask S171128laf "now", local t = t or "\n* activity.list_libraries_functions(t) List actual functions for documentations." local i_libraries_functions = {} local libname_libraries = versn.sorted_bind_libraries or {} t = t .. viewer.ta("\n* Count of central libraries", #libname_libraries) for i, lib in pairs(libname_libraries) do -- search all libraries t = t .. "\n* <b>Library:" .. tostring(lib["libname"]) .. "</b>, " i_libraries_functions = {} for name, func in pairs(lib) do -- search all libraries if (type(func) == "function") then -- select central libraries name = string.gsub(name, versn.ModuleNS, "") -- delete Module: table.insert(i_libraries_functions, { ["name"] = name} ) end end table.sort(i_libraries_functions, function (a, b) return (a["name"] < b["name"]) end ) -- Sort libraries for i, obj in pairs(i_libraries_functions) do -- search all libraries t = t .. tostring(obj.name) .. ", " end end return t end -- function activity.list_libraries_functions(t) activity.monitor_subtasks_list = { -- List of subtasks to monitor. -- Automatic shift of below "todo" subtasks. { "20180108", "20180109", "todo", "Rical", "S180108blg", "For each wikidata search the better lang in userlang, userlang2, pagelang, contentlang", }, { "20180106", "20180108", "todo", "Rical", "S180106arg", "new Object:args form known arguments to import, complete from datas and finalize", }, { "20171019", "20171022", "todo", "Rical", "S171019ime", "include Lua modules in extensions like Wikibase/client/includes/DataAccess/Scribunto/mw.wikibase.lua, see phabtask T41610.", }, { "20171015", "20171018", "todo", "Rical", "S171015trk", "add a method tracker:trk(self, ...) from tracker.add(opt, ...). see Lua_reference_manual#Function_declaration_statements", }, -- { "20171001", "20171002", "todo", "Rical", "S170801cvG", "put MW versions and Central versions in _G and CentralData", }, { "20171001", "20171002", "todo", "Rical", "S170801tcG", "put testsgrp versions in _G and CentralData", }, { "20171001", "20171002", "todo", "Rical", "S170801cCD", "Create Special:PageData/CentralData (change from MW only)", }, { "20171001", "20171002", "todo", "Rical", "S170801cCD", "Create MediaWiki:Scribunto/CentralData (change from admin only)", }, { "20171001", "20171002", "todo", "Rical", "S170801cCD", "Create Central/PageData/CentralData (change from any user)", }, { "20170915", "20170917", "todo", "Rical", "S170915ajb", "phabtask extend testsgrp.subdiffs() to lua_table.trees.all_jobs", }, { "20170910", "20170914", "todo", "Rical", "S170910UPD", "Use: PageData for Mediawiki_Versions, monitor_subtasks_list, activity.wikis_to_begin ...", }, { "20170910", "20170914", "todo", "Rical", "S170910wpw", "Use: wikidata = { property = 'P84',... syntax like {{Wikidata}} for wikidata", }, -- see 4.2 Paramètre "wikidata" https://fr.wikipedia.org/wiki/Aide:Infobox_en_Lua#Param.C3.A8tre_.22wikidata.22 { "20170910", "20170914", "todo", "Rical", "S170910bob", "Create a button object for boxes, like dropbox with: n, states, shapes, keywords, colors", }, { "20170910", "20170914", "todo", "Rical", "S170910ssb", "Restructure for a soft structure in viewer.boxview.form()", }, { "20170906", "20170909", "todo", "Rical", "S170906tbe", "restructure for a Table of Box Elements in viewer.boxview.form()", }, { "20170828", "20170905", "todo", "Rical", "S170828dut", "delete unused tracker in _G : ARGS, IAMO, MAMO, testsgrp", }, { "20170828", "20170905", "todo", "Rical", "S170820vtg", "try graphics in viewer.try_graph() -- see Macron", }, { "20170828", "20170905", "todo", "Rical", "S170723obv", "make object viewer.boxview.form(cssView)", }, { "20170816", "20170823", "todo", "Rical", "S170809ffs", "viewer.form_functionalCSS() Form functional structures", }, { "20170816", "20170823", "todo", "Rical", "S170901adl", "automatize langs.dummy_languages() using isSupportedLanguage(xx)", }, { "20170816", "20170823", "todo", "Rical", "S170901sas", "debug modes.similar_args_search() Test des mots proches similaires", }, { "20170816", "20170823", "todo", "Rical", "S170901mMW", "use Special:PageData CentralData T163923+T168726 in activity.monitor_MW_Versions()", }, { "20170816", "20170823", "todo", "Rical", "S170729eli", "easy https://en.wikisource.org/wiki/Template:Lorem_ipsum", }, { "20170816", "20170823", "todo", "Rical", "S170728acr", "debug versn.antiCrash() + tests", }, { "20170816", "20170823", "todo", "Rical", "S170801uPD", "automatize PageData change in datas.update_PageData(t) for activity.monitor_MW_Versions()", }, { "20170811", "20170815", "todo", "Rical", "S170716tac", "langs.abnormal_char_in_text() fails", }, { "20170811", "20170815", "todo", "Rical", "S170705dbf", "Debug all functions tests in dropboxes", }, { "20170811", "20170815", "todo", "Rical", "S170615css", "use Conventional css parameters cssview in edit, content, dropbox, infobox, tableview ... ", }, { "20170811", "20170815", "todo", "Rical", "S170720diw", "Enhance datas.get_item() from 20170403 ModuleCentral 6a clean display.lua", }, { "20170811", "20170815", "todo", "Rical", "S170718FLI", "Propose Firstname, Lastname and Initial in wikidata", }, -- S170718FLI : in https://www.wikidata.org/wiki/Wikidata:Property_proposal/Person#Noms().", }, -- S170718FLI : T53657 is Close : Firstname and Lastname properties -- S170718FLI : T53657 to re Open : Firstname and Lastname properties. Follow Aklapper comment on Jul 19 2013, 12:51 -- Begin Later { "20170810", "20170811", "todo", "Rical", "S170617rpd", "debug modes.recursiveNormal() test", }, { "20170810", "20170811", "todo", "Rical", "S170630alr", "debug antiLoop() modules libraries runTestsCases limit counts init time tables", }, { "20170810", "20170811", "todo", "Rical", "S170614tva", "Use tableview.new() for all tables, search .Te()", }, -- { "20170810", "20170811", "todo", "Rical", "S170813lll", "debug lua_table.level_list(mw) for all uses", }, -- { "20170808", "20170810", "todo", "Rical", "S170707icc", "Begin: begin to integrate central changes from other coders", }, { "20170808", "20170810", "todo", "Rical", "S170707icc", "Begin: update important Phabricator tasks to activate their availability", }, -- Inform after 'Create Begin' { "20170805", "20170807", "todo", "Rical", "S170702cJP", "Lua coders Utilisateur:JackPotte [[:fr:Utilisateur:JackPotte|JackPotte fr de es en]]", }, { "20170805", "20170807", "todo", "Rical", "S170702flc", "Begin: Search 10 Lua coders in 10 projects, small or big, first ask", }, { "20170805", "20170807", "todo", "Rical", "S170702wvm", "Begin: announce Meet coders throught Wikis video meeting France SWEL-fr https://meet.jit.si/swel-fr", }, { "20170805", "20170807", "todo", "Rical", "S170702atr", "Ask translations in meta [https://meta.wikimedia.org/wiki/Translation_requests Translation_requests]", }, { "20170805", "20170807", "todo", "Rical", "S170604iTN", "inform [https://meta.wikimedia.org/wiki/Tech/News#contribute Tech News] about central modules begin phase", }, -- S170604iTN : Tech/News#contribute : central, begin to use, efficiency, ask lua coders ? { "20170805", "20170807", "todo", "Rical", "S170702ALC", "Ask Lua coders: Oliv0, Akeron, Tpt, Od1n, Ayack, Kertraon, Julien1978, Thibaut120094, Daehan", }, { "20170805", "20170807", "todo", "Rical", "S170620dcm", "Begin: create a dedicated page for discussions in fr.wikipedia/Discussion:Central modules", }, { "20170805", "20170807", "todo", "Rical", "S170620dcm", "Begin: create announce and description with links in fr.wikipedia/Central modules", }, -- Debug to support Create Begin's group { "20170801", "20170804", "todo", "Rical", "S170702atr", "Begin: before ask translate, group all translations in Module:Central/I18N", }, { "20170801", "20170804", "todo", "Rical", "S170707ukt", "Begin: update known translations in ModuleCentral-s-fr-I18N 20170510.lua", }, { "20170801", "20170804", "todo", "Rical", "S170804btu", "Create phab task T20170702 'Begin to use central modules S170804btu' ", }, { "20170801", "20170804", "todo", "Rical", "S170611bit", "For 'Begin' Update all phabtask in activity.monitor_phabricator_tasks()", }, { "20170801", "20170804", "todo", "Rical", "S170705ust", "For 'Begin' Update all important tasks to support central modules", }, { "20170730", "20170731", "todo", "Rical", "S170705crm", "For 'Begin' Update Central modules reference manual", }, -- Automatic shift of behind "todo" subtasks. -- -- Now, in change. { 196, "Central", "20180111", "T20180111", 0, "Assigned", "Made a generic object module to support others. need phabtask T135845", }, { "20180111", "20180111", "now", "Rical", "S180111pfs", "For , Made a generic object module to support others. need phabtask T135845", }, { "20171224", "20171225", "now", "Rical", "S171224mka", "Report of main known args in modes.args_known_report(t)", }, { "20171218", "20171221", "now", "Rical", "S171218laf", "List actual functions for documentations in activity.list_libraries_functions()", }, { "20171210", "20171212", "now", "Rical", "S171210arg", "Check all arguments: known_args/unknow_args missing/levenstein upercase/lowercase description args_known", }, -- p.args_known = { -- Table of the definitions of all known arguments at module level. -- initial = {typ = "dat", need = 2, keyword = "initial"}, { "20171209", "20171209", "now", "Rical", "S171209ust", "ModuleCentral update subtasks list", }, { "20171130", "20171209", "now", "Rical", "S171130esr", "check equilibrium save/restore of configs in viewer.zzz_save_configs_in_functions_report()", }, -- -- Already done { "20171205", "20171208", "done", "Rical", "S171205dtt", "Debug translations in langs.trans9vars()", }, { "20171128", "20171129", "done", "Rical", "S171128laf", "For doc list_libraries_functions().", }, { "20171127", "20171128", "done", "Rical", "S171127dip", "debug init_content_page_user_lang().", }, { "20171126", "20171127", "done", "Rical", "S171126ecl", "list available all_errors_list() and all_categories_list()", }, { "20171120", "20171125", "done", "Rical", "S171120", "missing and changing infos in langs.missing_translations().", }, { "20171111", "20171111", "done", "Rical", "S170918ust", "ModuleCentral update subtasks list", }, { "20171110", "20171111", "done", "Rical", "S170620csc", "make versn.centrobj() for easier descriptions of libraries and modules.", }, { "20171104", "20171105", "done", "Rical", "S170620csc", "For 'Begin' count Lua-coders, langs, projects in function lua_table.level_list().", }, { "20171102", "20171102", "done", "Rical", "S170918ust", "ModuleCentral size 20171102=1413 k, 20170803=1340 k, 20170501=1226 k, 20170204=1016 k, 1.5 k/j", }, { "20171026", "20171103", "done", "Rical", "S171026mdl", "For 'Begin' record central_module_descriptor() in ModuleCentral-s-fr 5d activity.central_module_descriptor OK", }, { "20171024", "20171025", "done", "Rical", "S170706s10", "For 'Begin' link to 7 wikis/langages in function activity.central_module_descriptor()", }, { "20171024", "20171024", "done", "Rical", "S170918ust", "ModuleCentral update subtasks list", }, { "20171001", "20171024", "done", "Rical", "S170918dtr", "debug testsgrp.resultdiffs() in ModuleCentral-s-fr 5d resultdiffs near ok", }, { "20170925", "20170928", "done", "Rical", "S170918uPD", "debug update_PageData() in ModuleCentral-s-fr 4c update_PageData ok 20170928-1639.pdf", }, { "20170918", "20170918", "done", "Rical", "S170918ust", "ModuleCentral update subtasks list", }, { "20170902", "20170918", "done", "Rical", "S170902cnt", "Begin: improve stability of testsgrp in testsgrp.getTestProvider()", }, { "20170906", "20170907", "done", "Rical", "S170907dcm", "For 'Begin' Update doc MediaWiki:Scribunto/Central modules", }, { "20170903", "20170904", "done", "Rical", "S170903dif", "For testsgrp and stability, testsgrp.subdiffs() Report differences between 2 tables", }, { "20170801", "20170902", "done", "Rical", "S170801rtc", "Begin: improve stability of testsgrp in testsgrp.recursive_tests()", }, { "20170901", "20170902", "done", "Rical", "S170902crm", "For 'Begin' Update doc MediaWiki:Scribunto/Central modules reference manual", }, { "20170822", "20170822", "done", "Rical", "S170706tcG", "first test of PageData in datas.update_PageData() Share DATAS between modules?", }, { "20170821", "20170821", "done", "Rical", "S170821sty", "Short story of Central modules from modes on 20130125 to boxview on 20170723", }, { "20170819", "20170820", "done", "Rical", "S170820crm", "For 'Begin' Update doc MediaWiki:Scribunto/Central modules reference manual", }, { "20170806", "20170808", "done", "Rical", "S170806ass", "Automatic shift of todo subtasks in activity.monitor_central_subtasks(t)", }, { "20170801", "20170807", "done", "Rical", "S170820crm", "For 'Begin' Update doc MediaWiki:Scribunto/Central modules reference manual", }, { "20170802", "20170804", "done", "Rical", "S170802mct", "Library langs : debug missing and changing_translations().", }, { "20170801", "20170801", "done", "Rical", "S170711ust", "ModuleCentral update subtasks list", }, { "20170729", "20170729", "done", "STOP", STOP = "STOP", }, -- Limit the display of this table { "20170723", "20170724", "done", "Rical", "S170723vbv", "make an easy box builder viewer.boxview.form(txt, css)", }, { "20170723", "20170723", "done", "Rical", "S170711ust", "ModuleCentral update subtasks list", }, { "20170720", "20170720", "done", "Rical", "S170720t_G", "for months, var 't' to debug in versn.list_all_G_and_loaded() after line 4303", }, { "20170718", "20170719", "done", "Rical", "S170703amo", "debug modes.import_arguments() in modes.import_args_mode_options()", }, { "20170717", "20170717", "done", "Rical", "S170717iwi", "update and activate datas.get_item()", }, { "20170703", "20170705", "done", "Rical", "S170703ust", "ModuleCentral update subtasks list", }, { "20170703", "20170704", "done", "Rical", "S170703wtA", "Module:Central-s-fr 5c viewer.tracker.ARGS ok", }, { "20170629", "20170703", "done", "Rical", "S170629alc", "debug add and list categories.", }, { "20170629", "20170702", "done", "Rical", "S170701cpu", "debug langs.init_languages() import from modes.args_source.", }, { "20170701", "20170701", "done", "Rical", "S170701ial", "debug langs.init_languages() activate languages.", }, { "20170629", "20170629", "done", "Rical", "S170629mct", "debug events.categ_Test() Test: Creation of categories in some languages.", }, { "20170625", "20170629", "done", "Rical", "S170625ust", "ModuleCentral update subtasks", }, { "20170626", "20170628", "done", "Rical", "S170626rev", "Rebuild events.add_new()", }, { "20170628", "20170628", "done", "Rical", "S170626trk", "viewer.tracker = tracker -- Object for parametrable tracks.", }, { "20170626", "20170626", "done", "Rical", "S170606rmn", "roman2int_tests+int2roman error form9usernil in function events.add_err()", }, { "20170618", "20170625", "done", "Rical", "S170606cmr", "versn.bind_central_modules_report error Discreet main version:?", }, { "20170618", "20170625", "done", "Rical", "S170625ste", "lua_table.tabfromsubnames() last sub-table from its sub-names.", }, { "20170618", "20170625", "done", "Rical", "S170618ltc", "langs.translationsCounts(t) limit counts", }, { "20170625", "20170625", "done", "Rical", "S170625bx1", "simpler options from modes in form_result() box1 ok", }, { "20170617", "20170617", "done", "Rical", "S170618slk", "sort langs keys search .i18n.es", }, } -- activity.monitor_subtasks_list = { -- List of subtasks to monitor. -- See tasks in activity.monitor_phabricator_tasks() and sub-tasks in activity.monitor_central_subtasks(t) function activity.monitor_central_subtasks(t) -- Monitor the current state of subtasks. Automatic shifts todo tasks some days after now. local t = t or "\n* <b>activity.monitor_central_subtasks()</b> Monitor the current state of subtasks. Automaticaly shifts tasks to do later." local memo = viewer.zzz_save_configs("activity.monitor_central_subtasks") -- Save global configuration before eventual changes. local t = t or "" local tabView = { testGroup = activity.monitor_subtasks_list, -- List of subtasks to monitor. title_memo = "activity_monitor_subtasks_title", -- "activity.monitor_central_subtasks(t) Monitor the current state of subtasks to correct", headers = " start; end; state; user; sub id; bug description; delay ", headers_class = "wikitable alternative center sortable", -- track_on = true, ccc = {}, -- To communicate and compute between cases rowGroup = {}, } local function tabView_rough_shifter(tabView) -- Monitor and shift tasks. tabView.ccc.now = os.date("%Y%m%d") tabView.ccc.now_days = activity.rough_date_days(tabView.ccc.now) local stop_min_days, delay_min = 999999, 999999, 999999 tabView.ccc.shift_days = 999999 tabView.ccc.stop_min = "99999999" for i, bug in pairs(tabView.testGroup) do -- First: Compute how to shift subtasks. bug.track = "" local now = tabView.ccc.now tabView.ccc.now_days = activity.rough_date_days(tabView.ccc.now) bug.start = bug[1] bug.stop = bug[2] bug.plan = bug[3] local y2 = tonumber(string.sub(bug.stop,1,4)) local m2 = tonumber(string.sub(bug.stop,5,6)) local d2 = tonumber(string.sub(bug.stop,7,8)) local date_days, y2, m2, d2, years, months, days = activity.rough_date_days(bug.stop) -- Rough date days of a time stamp, from 0000-01-01. bug.start_days = activity.rough_date_days(bug.start) bug.stop_days = activity.rough_date_days(bug.stop) bug.delay = bug.stop_days - bug.start_days if (type(bug.start) == "string") and (type(bug.stop) == "string") and (bug.plan == "todo") then if bug.stop < tabView.ccc.stop_min then tabView.ccc.stop_min = bug.stop tabView.ccc.stop_min_days = activity.rough_date_days(tabView.ccc.stop_min) if tabView.ccc.stop_min_days < tabView.ccc.now_days then tabView.ccc.stop_min_days = tabView.ccc.now_days end tabView.ccc.shift_days = (tabView.ccc.stop_min_days + 2) - bug.stop_days end bug.track = bug.track.."<br/>"..viewer.ta("now", now)..viewer.ta("y2", y2)..viewer.ta("m2", m2)..viewer.ta("d2", d2) bug.track = bug.track.."<br/>"..viewer.ta("stop", bug.stop)..viewer.ta("delay", bug.delay)..viewer.ta("date_days", date_days) end end for i, bug in pairs(tabView.testGroup) do -- After: really shift subtasks. bug.start = bug[1] bug.stop = bug[2] bug.plan = bug[3] bug.start = bug.start --.. "+3 " .. bug.start if bug.plan == "todo" then -- Only for todo tasks bug.start_days = activity.rough_date_days(bug.start) bug.start = activity.rough_days_timestamp(bug.start_days + tabView.ccc.shift_days) -- Rough time stamp from date days, like "20170806". bug.stop_days = activity.rough_date_days(bug.stop) bug.stop = activity.rough_days_timestamp(bug.stop_days + tabView.ccc.shift_days) -- Rough time stamp from date days, like "20170806". end end end -- function tabView_rough_shifter(tabView) -- Shift todo tasks. function tabView.form_one_case(bug, tabView) -- Convert a case from testGroup to rowGroup. bug.start = bug.start or bug[1] or "---" bug.stop = bug.stop or bug[2] or "---" bug.plan = bug.plan or bug[3] or "---" if bug.plan == "todo" then -- Display one row whole in bold. bug[6] = bug[6] -- .. bug.track end if bug.plan == "now" then -- Display one row whole in bold. bug.start = "<b>" .. bug.start .. "</b>" bug.stop = "<b>" .. bug.stop .. "</b>" bug.plan = "<b>" .. bug.plan .. "</b>" bug[4] = "<b>" .. bug[4] .. "</b>" bug[5] = "<b>" .. bug[5] .. "</b>" bug[6] = "<b>" .. bug[6] .. "</b>" bug.delay = "<b>" .. bug.delay .. "</b>" end return { bug.start, bug.stop, bug.plan, bug[4], bug[5], bug[6], bug.delay, } end tabView_rough_shifter(tabView) -- Monitor and shift tasks. t = t .. tableview.new(tabView) -- Form a table view with lines and columns. t = t .. "\n* Counts of selected and sorted sub-tasks: " local list, count_done, level, split = lua_table.level_list(tabView.rowGroup, "string", "done", 3) -- subtasks S170813lll local list, count_now, level, split = lua_table.level_list(tabView.rowGroup, "string", "now", 3) -- function lua_table.level_list( local list, count_later, level, split = lua_table.level_list(tabView.rowGroup, "string", "todo", 3) -- subtasks S170813lll tabView.t = tabView.t or "-" t = t .. viewer.ta("subtasks main count_done", count_done) .. viewer.ta("count_now", count_now) .. viewer.ta("count_later", count_later) viewer.zzz_restore_configs(memo, "activity.monitor_central_subtasks") -- Restore global configurations after eventual changes. return t end -- t = function activity.monitor_central_subtasks(t) activity.phabricator_tasks_Group = { -- 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] -- Typical tasks redaction: Description: Steps to reproduce: Expected outcome: Actual outcome: -- datas: sort, importance, taskNumber, detect, state, title, shortext. -- -- Importance: Important { 98, "Important", "20180123", "T185557", 0, "Open", "Create the easy function mw.wikibase.property('P21', 'Q8023', 'en')", }, --[[ new phabtask 20180123 : (property, QITEM, language) Description This function gets the sought property from any available item and language. The QITEM can be the Title or the Label of the page. The property can be defined in it's own name, in English (or in the local content language, if non ambiguous). The language can be a sequence. Properties include Label, Title, description, sitelink ```code local prop1 = mw.wikibase.property('P21') -- Simplest use local prop2 = mw.wikibase.property('lastname') -- Named property local prop3 = mw.wikibase.property('Label', 'Q', { 'user', 'page', 'content', 'en', 'de', 'es', } ) -- Default values local prop4 = mw.wikibase.property('description', 'Nelson Mandela', { 'user', 'fr', } ) -- other case ```code --]] { 100, "Important", "20180102", "T20180102", 0, "ToCreate", "Add mw.wikibase.getTitle() to easy get the title", }, -- new phabtask 20180102 : add mw.wikibase.getTitle(), identic to mw.getCurrentFrame():getTitle() to easy get the title of the article. { 102, "Important", "20170807", "T20170807", 0, "ToCreate", "Run tests cases in modules for Mediawiki tests cases", }, -- 20170807 : name : Run tests cases in modules for Mediawiki tests cases. -- 20170807 : Before the module can provide(n), it must build its own table and count of tests cases -- 20170807 : There are 2 ways : 1/ testsgrp.testslist() returns a table of all tests to run with all needed args. -- 20170807 : There are 2 ways : 2/ testsgrp.nexttest() returns the first test to run, and later others. -- 20170807 : See function testsgrp.getTestProvider(tabView) -- Form whole the result for users and Mediawiki tests cases. S170801rtc { 104, "Important", "20170725", "T53657", 0, "Re Open", "Propose Firstname, Lastname and Initial in wikidata", "share central datas", }, -- T53657 : Description : Automatize it is not possible. + for an easy use in Scribunto modules. -- T53657 : is Close : from Jul 19 2013, 12:51. See S170718FLI -- T53657 : to re Open : Firstname, Lastname and Initial properties. Follow Aklapper comment on Jul 19 2013, 12:51. See S170718FLI { 106, "Important", "20170703", "T20170703", 0, "ToCreate", "Standardize content, page and user langages availability", "Standardize languages", }, -- T20170703 : Rename T68051 : "Central modules need the user language to display errors and category names" -- T20170703 : Standardize content, page and user langages availability -- T20170703 : Content, page and user langages are not available nor defined in the same ways for scribunto modules. -- T20170703 : That complicate modules which use them. Similar ways could enhance efficiency and reduce the development tasks. { 108, "Important", "20170702", "T20170702", 0, "ToCreate", "Begin to use central modules in 10 wikis S170804btu", "Begin use central", }, --[[ "S170702btu", "Enhance phab task T20170702 'Begin to use central modules' as my birthday present after 4.5 years of coding. ", }, Task description structure : est un . Il peut remplacer, en apportant , une qualité, architecture générale. contient les bibliothèques, en utilisant. The goal of this task is to transmit the know-how from the initial developer at some others. This task is not for one man, it is a shared task. This task continue until 10 Lua coders, 10 helpers, 10 projects, 10 languages and 10 modules use central modules or libraries. When this task is open, the initial developer inserts changes from others Lua coders in the Module:Central. --]] { 110, "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 ...). { 112, "Important", "20170907", "T20170907", 0, "ToCreate", "Do central modules need a console mode ?", "console mode ?", }, -- T20170325 : Centralize datas as mediawiki versions installations in each lang-project, uses of central modules (helpers, projects, languages ...). { 114, "Important", "20170522", "T135845", 0, "Assigned", "Convert any module as central or centralisable", "Convert as central", }, { 116, "Important", "20170320", "T53660", 0, "Open", "Detect the edit state for modules which help users and helpers", "edit state", }, { 118, "Important", "20170320", "T4085", 0, "Assigned", "Add a {{USERLANGUAGE}}/{{USERLANG}} magic word", "USERLANGUAGE", }, -- T173207: Implement Lua alternative to {{int:Lang}}. { 120, "Important", "20170716", "T163923", 0, "Open", "Create Special:PageData as a canonical entry point for machine readable page data.", "Special:PageData done", }, -- T163923: Permit at modules to change PageData (for stat, modules versions, mw versions...). { 122, "Important", "20170716", "T149532", 0, "Assigned", "Why Multi-Content-Revisions? Use cases and requirements.", "Special:PageData done", }, { 124, "Important", "20170625", "T168726", 0, "Open", "Create syntax documentation page for Special:PageData.", "Special:PageData doc", }, { 126, "Important", "20170522", "T68051", 1, "Open", "Central modules need the user language to display errors and category names", "user language for errors", }, { 128, "Important", "20170522", "T132308", 0, "Open", "Deal with incomplete and non standard dates, year only, season...", "Deal non standard dates", }, { 130, "Important", "20170219", "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. --]] { 132, "Important", "20170525", "T85461", 0, "Open", "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 { 134, "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: { 136, "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 { 138, "Important", "20161026", "T142093", 0, "Open", "Decide how to do usage tracking for strings_c used to lookup entities (page titles, external ids, …)", "how to link entities/titles", }, { 140, "Important", "20170211", "T20170211", 1, "ToCreate", "In mw.language.fetchLanguageNames( 'fr' ) some languages names are not in French", "French languages names", }, { 142, "Important", "20170403", "T20161220", 0, "ToCreate", "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 content_lang { 144, "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", }, { 146, "Important", "20170816", "T176362", 0, "ToCreate", "Implement getTestProvider in Scribunto to enhance central modules stability", }, -- T176362 : phabtask : Implement getTestProvider in Scribunto to enhance central modules stability -- T176362 : phabtask : proposed functions in Mediawiki: -- T176362 : phabtask : mw.getTestProvider(mw_tests, nmaxi) -- To initialise, to limit all tests in time and to limit cases to nmaxi. -- T176362 : phabtask : mw.ClassNameCase(case, n), used inside mw.getTestProvider() to run each test case of number 1 to nmaxi. -- T176362 : phabtask : The case object contains fields: count, OK="OK"..., n, name, type, args{}, expect{}, NameTest{}, func(), provide(), run() -- T176362 : phabtask : Functions used in central modules: testsgrp.getTestProvider(), .init(), .gettestsgroups(), .getcases(), .subdiffs(), .normalcase(case), viewer.form9en() -- T176362 : phabtask : In the testsgrp library, tests cases are in recursive groups of groups of cases. Groups levels: main module, sub modules or libraries, functions and their tests cases. { 148, "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 { 150, "Important", "20170623", "T163923", 0, "Closed", "Create Special:PageData as a canonical entry point for machine readable page data", }, { 152, "Important", "20170625", "T168726", 0, "Open", "Create syntax documentation page for Special:PageData", }, { 154, "Important", "20170323", "T85461", 0, "Open", "Lua error: too many language codes requested", "many language codes", }, { 156, "Important", "20170521", "T63958", 0, "Assigned", "Use existing $dateFormats to format dates on Wikidata", "$dateFormats on Wikidata", }, -- -- -- Importance: Central { 196, "Central", "20180111", "T20180111", 0, "Assigned", "Made a generic object module to support others", "Made object module", }, -- Linked or needed tasks: -- { 114, "Important", "20170522", "T135845", 0, "Assigned", "Convert any module as central or centralisable", "Convert as central", }, -- { 108, "Important", "20170702", "T20170702", 0, "ToCreate", "Begin to use central modules in 10 wikis S170804btu", "Begin use central", }, -- { 120, "Important", "20170716", "T163923", 0, "Open", "Create Special:PageData as a canonical entry point for machine readable page data.", "Special:PageData done", }, -- { 152, "Important", "20170625", "T168726", 0, "Open", "Create syntax documentation page for Special:PageData", }, -- -- T20180111: What is a central object module? In 2017: -- * It was a parametric informatic object. -- * Able to use human translations of parametric sentences. -- * Able to include actual reports and tests in documentations. -- * Able to use 3 languages, of the user, the page an the content. -- * Able to drow dropboxes and tables(colons of lines) with non CCS dedicated styles. -- * Able to require some sought submodules in lists of some prefered versions. -- * Able to get datas from the wikibase. -- * Able to enhance the stability of itself and others, using many tests cases. -- * Able to T135845 "Convert any module as central or centralisable". -- * Able to report the states of Phabricator tasks. -- -- Later it could be: -- * Able to support CCS styles. -- * Able to drow boxes. -- * Able to get datas from the mediawiki wikibase. -- * Able to exchange Special:PageData whith others modules. -- Some of these abilities are partial or manual waiting the availability of these datas for modules. -- -- { 198, "Central", "20180103", "T20180103", 0, "ToCreate", "Add a language argument like mw.wikibase.getDescriptionWithLang(item, lang) for translations in Central modules", }, -- new phabtask 20180103 : add the "language" as second input argument to translate the description in any languages for Central modules. { 200, "Central", "20171106", "T20171106", 0, "Open", "Lua-coders could better report bugs with Mediawiki version for each wiki", "wikis Mediawiki_version", }, { 202, "Central", "20170710", "T121470", 0, "Open", "Central Global Repository for Templates, Lua modules, and Gadgets", "central repository", }, { 204, "Central", "20170707", "T52329", 0, "Stalled", "We need a common repository for Scribunto modules and templates", "common repository", }, { 206, "Central", "20170522", "T41610", 0, "Open", "Scribunto should support global module invocations", "global invocations", }, -- T41610: subscriber: kaldari 2017-05-20, 16:03 -- T41610: You can include Lua modules in extensions and then register them with Scribunto as global modules. -- T41610: Wikibase, for example, includes 2 Lua modules: -- T41610: Wikibase/client/includes/DataAccess/Scribunto/mw.wikibase.entity.lua -- T41610: Wikibase/client/includes/DataAccess/Scribunto/mw.wikibase.lua { 208, "Central", "20170301", "T20170301", 0, "ToCreate", "Phabricator tasks states for easier versions management of modules", "Phabricator tasks states", }, -- datas to get for each query: Task number, title, state, priority, Authored By and date, Last event date, number of subscribers, Assigned. { 210, "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. { 212, "Central", "20170314", "T1238", 0, "Close", "Central Code Repository for code used on wikis (Templates, Lua modules, Gadgets)", "Code Repository", }, { 214, "Important", "20170521", "T67687", 0, "Resolved", "mw.loadData can be used to pass data between #invoke's by reading frame arguments", }, -- -- Importance: Other { 302, "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 --]] { 304, "Other", "20170427", "T104109", 0, "Close", "No syntax highlight for large JavaScript/CSS/Lua/API pages", "highlight for large Lua", }, { 306, "Other", "20170427", "T162877", 0, "Close", "CodeEditor default changed if you have never used the toggle", "CodeEditor default if never", }, { 367, "Other", "20170427", "T161875", 0, "Close", "CodeEditor is always enabled when starting an edit on a page containing code", "CodeEditor enabled on code", }, -- T161875: Actual: It is enabled, though mw.user.options.get('usecodeeditor') correctly gives 0. { 308, "Other", "20170407", "T20170407", 0, "ToCreate?", "When edit, the modification of Module:Central-s-fr do not display lines numbers", "Edit module misses lines numbers", }, { 310, "Other", "20160918", "T63958", 0, "Open", "Use existing $dateFormats to format dates on Wikidata", "Use $dateFormats on Wikidata", }, { 312, "Other", "20160520", "T85412", 0, "Open", "The formatPropertyValues needs an option to format data from date-time, angle or geographic coordinates", "format date-time", }, { 314, "Other", "20170517", "T156048", 0, "Open", "Add syntax highlighting to wiki diff of source code pages (like Gerrit)", "syntax highlighting", }, { 316, "Other", "20170313", "T107119", 0, "Open", "Provide a Lua method mw.loadTemplateData()", "loadTemplateData", }, { 318, "Other", "20170524", "T166202", 0, "Open", "Strings defined as long comments give a Lua modules syntax error", "Strings as comments error", }, -- -- Other, ToCreate or not { 320, "Other", "20170213", "T20170213", 0, "ToCreate", "Some languages have not French names in French language", "languages in stranger names", }, { 322, "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 .. "|ta1=" .. ta1 .. "}}" .. content .. "{{Boîte déroulante/fin}}" { 324, "Other", "20170429", "T156048", 0, "Open", "Add syntax highlighting to wiki diff of source code pages (like Gerrit)", "highlighting diffs", }, { 326, "Other", "20160616", "T20160616", 0, "ToCreate", "? Add module and library types in scribunto ?", "module and library types?", }, -- T20160616: get.is_library = ( true ) -- true if the object is a library { 328, "Other", "20171007", "T155624", 0, "Open", "Special:Version not showing SHA info for Mediawiki version on fr.wikisource", "Mediawiki version?", }, -- UTC-20170407-20:21 : reported in T155624 Special:Version not showing SHA info for Mediawiki version on fr.wikisource -- -- Importance: Obsolete: Do not create, these functions come from mw... libraries. { 428, "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 : versn.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 { 430, "Obsolete", "20170324", "T133498", 1, "Declined", "Detect and extend known title <-> entity links in a semi-automatic way", "semi-automatic wikidata QITEM", }, { 432, "Obsolete", "20161128", "T151715", 0, "Invalid", 'string.gsub( s, "%%1", repl) fails as "invalid capture index"', 'string.gsub(s,"%%1",r) fails', }, { 434, "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: versn.antiCrash() preserve pages against residual errors which can crash pages. { 436, "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. { 438, "Obsolete", "20160424", "T67507", 0, "Resolved", "It should be possible to get entity id from page title", "entity id from title", }, { 440, "Obsolete", "20160524", "T119978", 0, "Invalid", "Get name and record-time of all modules to better manage their versions", "own module name", }, { 442, "Obsolete", "20160813", "T75460", 0, "Resolved", "[Story] Make Lua functions default to the user's language on multilingual wikis", "multilingual wikis", }, { 444, "Obsolete", "20160524", "T119978", 0, "Invalid", "Get name and record-time of all modules to better manage their versions", "own module name", }, } -- activity.phabricator_tasks_Group = {...} function activity.monitor_phabricator_tasks(t, short) -- Monitor states of known phabricator tasks. S170606act local memo = viewer.zzz_save_configs("activity.monitor_phabricator_tasks") -- Save global configuration before eventual changes. local t = t or "\n* <b>activity.monitor_phabricator_tasks()</b> Monitor states of known phabricator tasks, to support the tasks management from inside central modules." versn.debugT53660isEdited = mw.title.getCurrentTitle().isEdited or "Open" -- Detect the status of the task : T68051_status. versn.debugT68051_status = mw.uri.new().userLanguage if versn.debugT68051_status then versn.debugT68051_status = "Resolved" else versn.debugT68051_status = "args" end -- { 18, "Important", "20170505", "T68051", 1, "Open", "Central modules need the user language to display errors and category names" }, -- Detect the status of the task : T133498_status. local mwtitle = mw.title.getCurrentTitle() local url = tostring(mwtitle:canonicalUrl( )) -- versn.debugT133498_status = mw.uri.canonicalUrl() -- mw.uri.canonicalUrl local title_object = mw.title.new(url) -- .QITEM -- mw.uri.canonicalUrl if title_object then versn.debugT133498_status = title_object.QITEM end -- mw.uri.canonicalUrl if versn.debugT133498_status then versn.debugT133498_status = "Resolved" else versn.debugT133498_status = "Open" end -- Any title with datas in wikibase give its item.id to any module. Probably across mw.title.new().QITEM -- headers local tabView = { testGroup = activity.phabricator_tasks_Group, title_memo = "activity_phabricator_tasks_title", -- "activity.monitor_phabricator_tasks() Monitor states of known phabricator tasks", headers = "activity_phabricator_tasks_headers", -- "Importance, changed on; Task; State; Title", -- ; In short -- track_on = true, } -- tabView.headers = "activity_phabricator_tasks_headers" -- tabView.headers = "Sort ;Importance ;Change date; Task id ;State ;Title ;In short" -- tabView.headers = "Tri ;Importancia ;Change date; Tarea id ;Estado ;Título ;En breve" -- tabView.headers = "Tri ;Importance ;Change date; Tâche id ;Etat ;Titre ;En bref" function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. case.sort = case[1] ; case.importance = case[2] ; case.datechange = case[3] ; case.taskid = case[4] case.state = case[5] ; case.title = case[6] ; case.shortext = case[7] 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, Assigned, Gerrit") then usual = "normal" elseif viewer.is_in(case.state, "Resolved") then usual = "invoke" 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 { case.sort, case.importance, case.datechange, case.taskid, case.state, case.title, } -- case.shortext } end -- function tabView.form_one_case(case) -- 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, Declined, Invalid", viewer.usualColor("task to create or activate", "discreet") ) .. viewer.ta("Open, Assigned, Gerrit", viewer.usualColor("task in way to Resolved", "normal") ) .. viewer.ta("Resolved", viewer.usualColor("task already Resolved", "invoke") ) .. viewer.ta("Other", viewer.usualColor("other tasks or track objects", "discreet") ) t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "activity.monitor_phabricator_tasks") -- Restore global configurations after eventual changes. return t end -- function activity.monitor_phabricator_tasks(t, short) --[===[ 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 activity.init_selected_wiki(wikis_to_begin, selector) -- Select the rigth wiki descriptor to init it. local wiki = activity.central_module_descriptor(wikis_to_begin, selector) -- Adapt this main central module version to a know wiki, in begin phase. --[[ 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.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 "-", activity.proto_version or "-", wiki.central_proj_lang or "-") p.versions.known = string.gsub(p.versions.known or "-", activity.proto_version or "-", wiki.central_proj_lang) or "-" end return wiki end -- function activity.init_selected_wiki(wikis_to_begin, host_name) function activity.support_begin_central_modules(t) -- Support the first uses of Central modules. local memo = viewer.zzz_save_configs("activity.support_begin_central_modules") -- Save global configuration before eventual changes. local t = t or "\n* <b>activity.support_begin_central_modules()</b> Support the first uses of Central modules." local tabView = { title_memo = "activity_support_central_modules_title", testGroup = activity.wikis_to_begin, rowGroup = {}, headers_class = "wikitable alternative center sortable", headers = "activity_support_central_modules_headers", -- track_on = true, } if not CMD then CMD = tracker.initadd({ ["name"] = "CMD", ["limit"] = 2 }) end -- Initialize a track CMD.add(CMD, 1, "support_begin_central_modules begin", { ["#activity.wikis_to_begin"] = lua_table.level_count(activity.wikis_to_begin), ["#activity.wikis_names"] = lua_table.level_count(activity.wikis_names), ["#activity.kiwis_names"] = lua_table.level_count(activity.kiwis_names), } ) function tabView.form_one_case(wiki) -- Convert a case from testGroup to rowGroup. local mwuri = mw.uri.new() local hostPort = mwuri.hostPort local selector = mwuri.hostPort CMD.add(CMD, 1, "form_one_case 575", { ["wiki.s"] = wiki.s, ["selector"] = selector, ["#wiki"] = lua_table.level_count(wiki), } ) -- wiki.found = false -- Is this wiki selected? wiki = activity.central_module_descriptor(wiki) -- Begin to adapt the main central module version to a wiki. wiki = wiki2 or wiki -- headers = = "%1 Projects; %2 Languages; Admins; Assets; %3 Modules versions; doc; Start on; Used from; %4 Users", wiki.project = wiki.project or "wiki.project" ; wiki.lang = wiki.lang or "wiki.lang" ; wiki.admins = wiki.admins or "wiki.admins" wiki.assets = wiki.assets or "wiki.assets" ; wiki.version = wiki.version or "wiki.version" ; wiki.doc_link = wiki.doc_link or "wiki.doc_link" local whatest = viewer.form9en("%1:%2:%3:%4", viewer.value(wiki.s), viewer.value(wiki.lang_project_org), viewer.value(selector) ) if wiki.lang_project_org == hostPort then -- if (wiki.found == true) then -- If this wiki is selected, hightlight it. -- viewer.styles_colors = "add delete discreet error invoke normal warning wikidata" -- viewer.styles_formats = "big bold small up" wiki.project = viewer.styles(wiki.project, "add ") -- hightlight actual wiki. wiki.lang = viewer.styles(wiki.lang, "add bold") -- hightlight actual wiki. wiki.admins = viewer.styles(wiki.admins, "add bold") -- hightlight actual wiki. wiki.assets = viewer.styles(wiki.assets, "add bold") -- hightlight actual wiki. wiki.version_link = viewer.styles(wiki.version_link, "add bold") -- hightlight actual wiki. wiki.doc_link = viewer.styles(wiki.doc_link, "add bold") -- hightlight actual wiki. wiki.beginon = viewer.styles(wiki.beginon, "add bold") -- hightlight actual wiki. wiki.usedfrom = viewer.styles(wiki.usedfrom, "add bold") -- hightlight actual wiki. wiki.user = viewer.styles(wiki.user, "add bold") -- hightlight actual wiki. end return { wiki.project, wiki.lang, wiki.admins, wiki.assets, wiki.version_link, wiki.doc_link, wiki.beginon, wiki.usedfrom, wiki.user } end -- See wiki.version = local langs, versions, users = {}, {}, {} for i, wiki in pairs(activity.wikis_to_begin) do if (type(wiki.lang) == "string") then table.insert(langs, wiki.lang) end if (type(wiki.user) == "string") then table.insert(users, wiki.user) end if (type(wiki.version) == "string") then table.insert(versions, wiki.version) end end t = t .. "\n* Count begin langs: " .. viewer.rough_view( lua_table.count_values(langs) ) .. lua_table.level_list(langs) t = t .. "\n* Count begin users: " .. viewer.rough_view( lua_table.count_values(users) ) .. lua_table.level_list(users) t = t .. "\n* Count begin versions: " .. viewer.rough_view( lua_table.count_values(versions) ) .. lua_table.level_list(versions) local form = tableview.new(tabView) -- Form a table view with lines and columns. CMD.add(CMD, 1, "support_begin_central_modules end", { ["#tabView.testGroup"] = #tabView.testGroup, ["#tabView.rowGroup"] = #tabView.rowGroup, } ) t = t .. viewer.ta("#testGroup", #tabView.testGroup) .. viewer.ta("#rowGroup", #tabView.rowGroup) t = t .. form local counts = activity.count_used_central_wikis(wikis_to_begin) counts.project = lua_table.level_count(wikis_to_begin) counts.version = lua_table.level_count(wikis_to_begin) counts.lang = lua_table.level_count(wikis_to_begin) counts.user = lua_table.level_count(wikis_to_begin) t = t .. viewer.ta("counts.project", counts.project) .. viewer.ta("counts.version", counts.version) .. viewer.ta("counts.lang", counts.lang) .. viewer.ta("counts.user", counts.user) -- t = t .. "\n* Tracks of <b>:activity.support_begin_central_modules(t)</b>" -- t = t .. CMD.t viewer.zzz_restore_configs(memo, "activity.support_begin_central_modules") -- Restore global configurations after eventual changes. return t end -- t = t .. activity.support_begin_central_modules(t) -- Survey the current state of sub tasks to debug. len function activity.rough_delay_timestamps(stamp1, stamp2) -- Rough delay between two time stamps, like 31. 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 function activity.rough_date_days(stamp1) -- Rough date days of a time stamp, like 736447. local date_days, years, months, days = 0, 0, 0, 0 if (type(stamp1) ~= "string") then return delay end local y1 = tonumber(string.sub(stamp1,1,4)) or 2001 local m1 = tonumber(string.sub(stamp1,5,6)) or 1 local d1 = tonumber(string.sub(stamp1,7,8)) or 1 years = y1 * 365 months = m1 * 30 days = d1 date_days = years + months + days return date_days, y1, m1, d1, years, months, days end function activity.rough_days_timestamp(date_days) -- Rough time stamp from date days, like "20170806". local timestamp = "no timestamp" if (type(date_days) ~= "number") then return timestamp end local year = math.floor(date_days / 365) local day = date_days - (year * 365) local month = math.floor(day / 30) local day = day - (month * 30) local yyyy = string.sub( ("0000" .. tostring(year) ), -4, -1) local mm = string.sub( ("0000" .. tostring(month) ), -2, -1) local dd = string.sub( ("0000" .. tostring(day) ), -2, -1) timestamp = yyyy .. mm .. dd return timestamp end -- See tasks in activity.monitor_phabricator_tasks() and sub-tasks in activity.monitor_central_subtasks(t) -- { "20170529", "20170530", "done", "Rical", "S170530mwv", "versn.Mediawiki_Versions in Module:MediawikiVersions for activity.monitor_MW_Versions()", }, function activity.monitor_MW_Versions(t) -- Monitor Mediawiki versions. S170606act -- activity_monitor_subtasks_title = "activity.monitor_MW_Versions(t) Monitor the current state of subtasks", local memo = viewer.zzz_save_configs("activity.monitor_MW_Versions") -- Save global configuration before eventual changes. local t = t or "\n* <b>activity.monitor_MW_Versions()</b> Monitor Mediawiki versions." -- t = t .. activity.Mediawiki_Versions_code(versn.Mediawiki_Versions, ">") -- First on begin, Last on end -- t = t .. activity.Mediawiki_Versions_code(versn.Mediawiki_Versions, "<") -- First on end, Last on begin table.sort(versn.Mediawiki_Versions, function (a, b) return (a["verstime"] > b["verstime"]) end ) local tabView = { testGroup = versn.Mediawiki_Versions, title_memo = "activity_monitor_MW_Versions_title", -- "<b>activity.monitor_MW_Versions()</b> Monitor Mediawiki versions.", headers = " verstime; versid; site; seen_time ", -- local case = { version.MW, version.versid, version.site, version.seen_time, } headers_class = "wikitable alternative center sortable", rowGroup = {}, -- track_on = true, } -- MediaWiki 1.30.0-wmf.4 (3248a17) 22:41, 7 June 2017 -- 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 -- versn.Mediawiki_version_memo = tabView.testGroup[1].versid -- "1.30.0-wmf.2 (b40805f)" -- =max( verstime ) if (type(tabView.testGroup) == "table") then -- table.sort(tabView.testGroup, function (a, b) return ( ( a[4] or "0" ) > ( b[4] or "0" ) ) end ) -- alphabetic sort of verstime -- table.sort(tabView.testGroup, function (a, b) return (a[1] or "5") < (b[1] or "5") ) end -- alphabetic sort of verstime end -- table.sort(tabView.testGroup, function (a, b) return (a["verstime"] < b["verstime"]) end ) -- alphabetic sort of translated arguments function tabView.form_one_case(version, all_cases) -- Convert a case from testGroup to rowGroup. local example = { site = "www.mediawiki", verstime = "2017-10-03T19:45:39", versid = "1.31.0-wmf.2 (25e1684)", seen_time = "2017-10-03T20:44:00-00:00", task = "T155624", title = "Seb35: 2017-10-07T12:12 could Rical observe?", } if version.task then version.versid = version.versid .. "<br/>" .. "[[phab:" .. version.task .. "|" .. version.task .. "]]" end if version.title then version.seen_time = version.seen_time .. "<br/>" .. version.title end return { version.site, version.verstime, version.versid, version.seen_time, } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. t = t .. "\n* Counts of monitor_MW_Versions: " t = t .. viewer.ta("#testGroup", #tabView.testGroup) .. viewer.ta("#rowGroup", #tabView.rowGroup) local list, count_done, level, split = lua_table.level_list(tabView.rowGroup, "string", "mediawiki", 3) local list, count_now, level, split = lua_table.level_list(tabView.rowGroup, "string", "wikisource", 3) -- function lua_table.level_list( local list, count_later, level, split = lua_table.level_list(tabView.rowGroup, "string", "2017-08", 1) -- subtasks S170813lll t = t .. viewer.ta("MW_Versions mediawiki count_done", count_done) .. viewer.ta("MW_Versions wikisource count_now", count_now) .. viewer.ta("MW_Versions 2017-08 count_later", count_later) -- Counts of selected and sorted sub-tasks: , #testGroup = 52 , #rowGroup = 0 -- { "20170529", "20170530", "done", "Rical", "S170530mwv", "versn.Mediawiki_Versions in Module:MediawikiVersions for activity.monitor_MW_Versions()", }, viewer.zzz_restore_configs(memo, "activity.monitor_MW_Versions") -- Restore global configurations after eventual changes. return t end -- t = activity.monitor_MW_Versions(t) -- See tasks in activity.monitor_phabricator_tasks() and sub-tasks in activity.monitor_central_subtasks(t) -- { "20170610", "20170610", "todo", "Rical", "S170", "Monitor Mediawiki versions from versn.Mediawiki_Versions{} in activity.monitor_MW_Versions()", }, function activity.Mediawiki_Versions_code(Mediawiki_Versions, sort) -- Re_form the Lua code of versn.Mediawiki_Versions{}. -- activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Monitor the current state of subtasks", local Mediawiki_Versions = Mediawiki_Versions or versn.Mediawiki_Versions if (type(Mediawiki_Versions) ~= "table") then Mediawiki_Versions = {} end local Mediawiki_Versions_example = { -- Example only { site = "fr.wikisource", verstime = "2017-05-11T00:48:00", versid = "1.29.0-wmf.21 (d6c07d1)", seen_time = "2017-05-11T00:48:00-00:00", task = "T165000", title = "The version date of MW 1.29.0-wmf.21 (d6c07d1) is in the future !", report = "Rical: Schedule in https://www.mediawiki.org/wiki/MediaWiki_1.29/Roadmap", }, } -- alphabetic sort vesions on verstime local sort = sort if (type(sort) ~= "string") then sort = activity.Mediawiki_Versions_sort end -- if not ( (sort == ">") or (sort == "<") ) then sort = ">" end if sort == ">" then table.sort(Mediawiki_Versions, function (a, b) return (a["verstime"] > b["verstime"]) end ) end -- First on begin, Last on end if sort == "<" then table.sort(Mediawiki_Versions, function (a, b) return (a["verstime"] < b["verstime"]) end ) end -- First on end, Last on begin local code = '\n* activity.Mediawiki_Versions_sort = "' .. sort .. '"' code = code .. "\n* versn.Mediawiki_Versions = {" for i, version in ipairs(Mediawiki_Versions) do -- 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 code = code .. '<br/> { site = "' .. version.site code = code .. '", verstime = "' .. version.verstime code = code .. '", versid = "' .. version.versid code = code .. '", seen_time = "' .. version.seen_time if (type(version.task) == "string") then code = code .. '", task = "' .. version.task end if (type(version.title) == "string") then code = code .. '", title = "' .. version.title end if (type(version.report) == "string") then code = code .. '", report = "' .. version.report end code = code .. '", },' -- end of line end -- versn.Mediawiki_version_memo = "1.31.0-wmf.3 (c5edfc3)" -- in fr.wikisource -- { site = "fr.wikisource", verstime = "2017-10-11T19:17:18", versid = "1.31.0-wmf.3 (c5edfc3)", seen_time = "2017-10-12T18:52:00", }, code = code .. "<br/>}<br/>" return code end -- t = t .. activity.Mediawiki_Versions_code(Mediawiki_Versions, sort) -- See tasks in activity.monitor_phabricator_tasks() and sub-tasks in activity.monitor_central_subtasks(t) -- { "20170610", "20170610", "todo", "Rical", "S170", "Monitor Mediawiki versions from versn.Mediawiki_Versions{} in activity.monitor_MW_Versions()", }, function activity.extract_MW_Versions() -- Extract Mediawiki versions from the page. -- activity_monitor_subtasks_title = "activity.monitor_central_subtasks(t) Monitor the current state of subtasks", local memo = viewer.zzz_save_configs("activity.extract_MW_Versions") -- Save global configuration before eventual changes. local t = t or "\n* <b>activity.extract_MW_Versions()</b> Monitor the current state of subtasks." -- local frame_title = frame:getTitle() -- Returns the title associated with the frame as a string. For the frame created by {{#invoke:}}, this is the title of the module invoked. local actual_title = mw.title.getCurrentTitle() -- Returns the title object for the current page. local actual_content = actual_title:getContent() -- Returns the (unparsed) content of the page, or nil if there is no page. The page will be recorded as a transclusion. local i = string.find(actual_content, "Central Normal mode example") if i then t = t .. "\n* " .. string.sub(actual_content, i, i + 222) end -- local t = t or "\n* <b>activity.extract_MW_Versions()</b> Monitor the current state of subtasks." -- mw.site.stats.pagesInCategory( category, which ) --This function is expensive -- versn.Mediawiki_version_memo = tabView.testGroup[1].versid -- "1.30.0-wmf.2 (b40805f)" -- =max( verstime ) viewer.zzz_restore_configs(memo, "activity.extract_MW_Versions") -- Restore global configurations after eventual changes. return t end -- t = activity.extract_MW_Versions() -- Extract Mediawiki versions from the page. -- cut_libraries -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- The Library:datas imports 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, see centrobj.new() -- Record a library in package.loaded -- Translations for datas library datas.i18n = {} datas.i18n.br = { -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. -- Wikidata datas_wikidata_header = "Données : ", datas_known_Datas_header = "Données connues : ", datas_sougth_Datas_header = "Données souhaitées : ", datas_needed_Datas_header = "Données nécessaires : ", 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.get_item() Test de Wikidata accès arbitraire", datas_wikidata_arbitrary_access_text = "Wikidata pour un titre : ", datas_wikidata_time_details_title = "datas.wikidata_time_details{} Wikidata propriétés de temps pour plus de détails", datas_update_Special_PageData_title = "datas.update_PageData() Partager des DATA entre modules en Special:PageData", datas_update_Special_PageData_header = "site; temps de version; identificateur de version; heure de vue", -- 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.br datas.i18n.de = { datas_wikidata_header = "Daten: ", datas_known_Datas_header = "bekannte Daten: ", datas_sougth_Datas_header = "gewünschte Daten: ", datas_needed_Datas_header = "Daten benötigt: ", } -- datas.i18n.de datas.i18n.en = { -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. datas_wikidata_header = "Datas: ", datas_known_Datas_header = "Known datas: ", datas_sougth_Datas_header = "Sougth datas: ", datas_needed_Datas_header = "Needed datas: ", 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.get_item() Test of Wikidata arbitrary access", datas_wikidata_arbitrary_access_text = "Wikidata for Title: ", datas_wikidata_time_details_title = "datas.wikidata_time_details{} Wikidata time properties for more details", datas_update_Special_PageData_title = "datas.update_PageData() Share DATAS between modules in Special:PageData", datas_update_Special_PageData_header = "site; version time; version identifier; seen hour", -- 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 = { -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. -- Wikidata datas_wikidata_header = "Datos: ", datas_known_Datas_header = "Datos conocidas: ", datas_sougth_Datas_header = "Datos deseados: ", datas_needed_Datas_header = "Datos necesarios: ", 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.get_item() Prueba de Wikidata acceso arbitrario", datas_wikidata_arbitrary_access_text = "Wikidata por título: ", datas_wikidata_time_details_title = "datas.wikidata_time_details{} Wikidata propiedades de tiempo para más detalles", datas_update_Special_PageData_title = "datas.update_PageData() Compartir DATOS entre módulos en Special:PageData", datas_update_Special_PageData_header = "sitio; tiempo de versión; identificador de versión; tiempo visto", -- 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 = { -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. -- Wikidata datas_wikidata_header = "Données : ", datas_known_Datas_header = "Données connues : ", datas_sougth_Datas_header = "Données souhaitées : ", datas_needed_Datas_header = "Données nécessaires : ", 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.get_item() Test de Wikidata accès arbitraire", datas_wikidata_arbitrary_access_text = "Wikidata pour un titre : ", datas_wikidata_time_details_title = "datas.wikidata_time_details{} Wikidata propriétés de temps pour plus de détails", datas_update_Special_PageData_title = "datas.update_PageData() Partager des DATA entre modules en Special:PageData", datas_update_Special_PageData_header = "site; temps de version; identificateur de version; heure de vue", -- 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 datas.i18n.hu = { -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. datas_wikidata_header = "Adat: ", datas_known_Datas_header = "Ismert adatok: ", datas_sougth_Datas_header = "Kívánt adatokat: ", datas_needed_Datas_header = "Szükséges adatok: ", datas_update_Special_PageData_title = "datas.update_PageData() Megosztja a DATA-t a speciális modulok között: Special:PageData", datas_update_Special_PageData_header = "webhely; verzióidő; verzióazonosító; látott órát", } -- datas.i18n.hu datas.i18n.vi = { -- To translate, referral languages are English and French. -- To translate, do not translate parts like these: <b>%1</b> ; <b>%1 = %2</b> (%3) ; <code>Q535</code> ; <br/> ; \n* ; _G. datas_wikidata_header = "Dữ liệu: ", datas_known_Datas_header = "Dữ liệu nổi tiếng: ", datas_sougth_Datas_header = "Dữ liệu mong muốn: ", datas_needed_Datas_header = "Dữ liệu cần thiết : ", datas_update_Special_PageData_title = "datas.update_PageData() Chia sẻ DATA giữa các mô-đun trong Special:PageData", datas_update_Special_PageData_header = "địa điểm; thời gian phiên bản; định danh phiên bản; thấy giờ", } -- datas.i18n.vi function datas.getDateFromTimeStatement(statement, field) local struct = { year = nil, century = nil, text = nil, precision = 0 } ------------------------------------------------------------------------------- -- local entity = mw.wikibase.getEntity() -- local snak = entity['claims']['P342'][1]['qualifiers']['P342'][1] -- mw.wikibase.renderSnak( snak ) -- Returns the given Snak value formatted as wikitext escaped plain text. ------------------------------------------------------------------------------- local snak = statement.mainsnak if snak.snaktype == 'novalue' then return struct end if snak.snaktype == 'somevalue' then struct.text = '??' return struct end struct = parseWbTime(snak.datavalue.value) local prefix = '' if struct.precision == 8 then prefix = 'vers ' end --Extract circa if statement.qualifiers ~= nil and statement.qualifiers.P1480 ~= nil then for _,qualifier in pairs(statement.qualifiers.P1480) do if qualifier.datavalue.value.id == 'Q5727902' then prefix = 'circa ' struct.precision = 8 --TODO: hacky end end end --Use before and after if precision <= century if statement.qualifiers ~= nil and struct.precision <= 7 then if statement.qualifiers.P1319 ~= nil then for _,qualifier in pairs(statement.qualifiers.P1319) do struct = parseWbTime(qualifier.datavalue.value) prefix = 'après ' struct.precision = 8 --TODO: hacky end elseif statement.qualifiers.P1326 ~= nil then for _,qualifier in pairs(statement.qualifiers.P1326) do struct = parseWbTime(qualifier.datavalue.value) prefix = 'avant ' struct.precision = 8 --TODO: hacky end elseif statement.qualifiers.P1317 ~= nil then for _,qualifier in pairs(statement.qualifiers.P1317) do struct = parseWbTime(qualifier.datavalue.value) prefix = 'floruit ' struct.precision = 8 --TODO: hacky end end end --Create text if struct.precision >= 9 then struct.text = prefix .. getTextForYear(struct.year) elseif struct.precision == 8 then struct.text = prefix .. getTextForYear(struct.year) elseif struct.precision == 7 then struct.text = prefix .. getTextForCentury(struct.century, true) else struct.text = errorMessage('La date de ' .. field .. ' a une précision trop faible sur Wikidata') end return struct end datas.track_val = datas.track_val or "" function datas.tv(line, prop, what, val) -- track a property in datas.get_item datas.track_val = datas.track_val or "" -- birthyear=P569 if prop == "P569" then local line = "L" .. tostring(line) local prop = tostring(prop) local what = tostring(what) local val = tostring(val) datas.track_val = datas.track_val .. viewer.ta(line .. "-" .. prop .. ":" .. what, val) end return datas.track_val end -- datas.track_val = datas.tv(line, prop, what, val) function datas.get_QITEM(QITEM) -- Get datas.QITEM for the page. local QITEM = QITEM datas.QITEM = QITEM or datas.QITEM or mw.wikibase.getEntityIdForCurrentPage() or "Q8023" -- without any arg return QITEM, QITEM end function datas.get_uri(prop, better, lang) -- Get props.uri for the page. local mwuri, uri = mw.uri.new(), "-" -- Server mw.uri.new for path like = /wiki/Utilisateur:Rical/Nelson_Mandela local sub_parts = mw.text.split(mwuri.path, '/') ; for k, part in pairs(sub_parts) do uri = part end -- last text after / uri = string.gsub(uri, "_", " ") ; return uri end function datas.get_image(prop, better, lang) -- Get sought image for the page. local prop = prop or "P18" -- Get sought image for the page, or some others for galeries. -- if prop == 'Q16222597' then prop = "P18" end -- QITEM -> image if (prop == "image") then prop = "P18" end -- local image = image or "Victor Hugo.jpg" local image = image or datas.props.image or datas.props.P18 or "Victor Hugo.jpg" or datas.get_uri() .. ".jpg" return "Victor Hugo.jpg" -- image or prop end function datas.get_prop(prop, better, lang) -- Get datas.props[prop] for the page. local prop = prop or 'P735' -- lastname = 'P735' local better = better or 1 -- for [1]['qualifiers'] local statements, qualifiers, snak, val, naissanceWikidata local loc_langs = { -- known langs ["content_lang"] = langs.content_lang or "fr", ["page_lang"] = langs.user_lang or "es", ["user_lang"] = langs.user_lang or "en", } local lang = lang or langs.content_lang or "en" -- datas.item = mw.wikibase.getEntity() -- datas.item = mw.wikibase.getEntity(datas.QITEM) -- add_err()+add_cat() Only in a dedicated namespace and if datas exist local t = "\n* datas.get_prop(args_known, QITEM):" -- local snak = datas.item['claims'][prop][1]['qualifiers'] local get_snak = function(prop, better, lang) return datas.item['claims'][prop][better]['qualifiers'] end local success, snak = pcall( get_snak, prop, better, lang ) -- pcall or xpcall can run any function without blocking page. if type(snak) == "table" then -- snak = datas.item['claims'][prop][1]['qualifiers'] snak = datas.item['claims'][prop][1]['qualifiers'][prop][1] val = mw.wikibase.formatValue( snak ) -- Returns the given Snak value formatted as rich wikitext. return val, t else t = t .. "\n* get_prop() " .. viewer.ta("prop", prop) .. viewer.ta("better", better) .. viewer.ta("lang", lang) return tostring(prop), t end return (val or "get_prop() "), t end -- val, t = datas.get_prop(prop, better, lang) -- Get datas.props[prop] for the page. function datas.get_item(args_known, QITEM) -- Get datas from mwwikibase for the page. local args_known = args_known or p.args_known or {} -- optional value from p.args_known = {...} local t = "\n* <b>datas.get_mng(args_known, QITEM)</b>: Get datas from mwwikibase for the page." local Title, Label, prop, lang, description, val, val_label, adr, proplabel local QITEM = QITEM or mw.wikibase.getEntityIdForCurrentPage() or "Q868" -- without any arg Aristote (Q868) datas.QITEM = QITEM datas.item = mw.wikibase.getEntity(datas.QITEM or "Q868") -- Aristote (Q868) local props = {} -- to collect propperties local loc = {} -- local values for key, pp in pairs(args_known) do -- Pour tous les paramètres connus if (type(pp.prop) == "string") then if pp.prop == "label" then val = datas.item:getLabel() -- Returns a string, like "Berlin" with 'de' elseif pp.prop == "sitelink" then val = datas.item:getSitelink() elseif pp.prop == "QITEM" then val = mw.wikibase.getEntityIdForCurrentPage() -- Returns the Item id as string, like "Q42" elseif pp.prop == "label" then val = mw.wikibase.entity:getLabelWithLang() -- Returns a string, like "Berlin" with 'de' elseif pp.prop == "description"then val = mw.wikibase.description(datas.QITEM) -- ric : Description of the QITEM page -- elseif pp.prop == "claims" then val = mw.wikibase.renderSnak(loc.wd_entity['claims']) -- Snaks formatted as wiki text. -- elseif pp.prop == "properties" then val = datas.item:getProperties() -- List of properties for the page. -- elseif pp.prop then val = datas.get_Prop(prop) -- Get any other property. -- elseif pp.prop then val = datas.get_Tpt(prop) -- Get any other property. else val = tostring(val) if pp.format == "year" then val = mw.ustring.sub( val, -4, -1 ) end props[pp.prop] = tostring(val) --[[ -- RANK_TRUTH, RANK_PREFERRED, RANK_NORMAL, RANK_DEPRECATED, -- Return all claims with id P123 (as the table passed contains all possible claim ranks) datas.item:formatPropertyValues( 'P123', mw.wikibase.entity.claimRanks ) -- Return the normal ranked claims with the property id P5 datas.item:formatPropertyValues( 'P5', { mw.wikibase.entity.claimRanks.RANK_NORMAL } ) loc.formatPropertyValues = datas.item:formatPropertyValues( pp.prop ) -- "P" .. pp.prop -- Returns a table like: { value = "Formatted claim value", label = "Label of the Property" } if loc.wd_claimRanks then loc.formatPropertyValues = datas.item:formatPropertyValues( pp, { "claimRanks" } ) end if loc.wd_RANK_TRUTH then loc.formatPropertyValues = datas.item:formatPropertyValues( pp, { "RANK_TRUTH" } ) end if loc.wd_RANK_TRUTH then loc.formatPropertyValues = datas.item:formatPropertyValues( pp, { "RANK_PREFERRED" } ) end val = loc.formatPropertyValues.value -- proplabel = loc.formatPropertyValues.label --]] end -- if pp.prop == "label" then val = datas.item:getLabel() ) -- Returns a string, like "Berlin" with 'de' end end props.countall = tostring( lua_table.level_count(props) ) datas.props = props return props end -- local props = datas.get_item(args_known, QITEM) -- Get datas from mwwikibase for the page. function datas.prot(prop) -- form a string to show a prop value datas.props = datas.props or {} local prop = prop if type(prop) ~= "string"then prop = "prop" end local t = prop if type(prop) == "string" and not string.find(prop, "%s", 1, true) then t = datas.props[prop] or prop end return t end function datas.get_item_report(t) -- datas.get_item() Tests of the import of wikidatas from the wikibase ** local t = t or "\n* <b>datas.get_item_report(t)</b>: Report datas from mw.wikibase for the page." local props = datas.get_item(args_known, QITEM) -- Get datas from mwwikibase for the page. for key, val in pairs(props) do -- from list all fond datas t = t .. "\n* in(get_item_report): " .. viewer.ta(tostring(key), tostring(val) ) end return t end -- local t = datas.get_item_report(t) function datas.one_arbitrary_access(QITEM) -- Form a short description from QITEM -- also used in datas_Datas_header local t = "" local QITEM = datas.prot("QITEM") -- or "Q868" -- Aristote local Title = datas.prot("Title") -- if not datas.item then datas.item = mw.wikibase.getEntity() end local datas_structured_data_txt = viewer.form9user("datas_wikidata_header") local datas_structured_data_txt = viewer.form9user("datas_wikidata_arbitrary_access_text") -- "Wikidata for Title: " t = t .. '[[d:' .. QITEM .. '|' .. datas_structured_data_txt .. ']]' t = t .. ' * ' .. Title or "Title" datas.prot("QITEM") return t end function datas.PageData_to_table(datext) -- Convert a PageData in JSON to a table. return tab end -- local tab = datas.PageData_to_table(datext) function datas.table_to_PageData(tab) -- Convert a table to JSON for PageData. return datext end -- local datext = datas.table_to_PageData(tab) -- { "20170816", "20170823", "todo", "Rical", "S170801uPD", "automatize PageData change in datas.update_PageData(t) for activity.monitor_MW_Versions()", }, function datas.update_PageData(t, datext) -- Try to share INFOS between a group of modules in Module:Main/INFOS local memo = viewer.zzz_save_configs("datas.update_PageData") -- Save global configuration before eventual changes. local t = t or "\n* datas.update_PageData() Share DATAS between modules in Special:PageData for modules." -- PageData from 20170822 -- activity_update_shared_INFOS = "datas.update_PageData() Share DATAS between modules in Special:PageData for modules", --[[ Guideline: Central INFOS are in Module:Central/INFOS, a Data module. A main module shares INFOS between a group of modules in . At each run, Central module bind INFOS from internal central, internal main, INFOS central, INFOS main. At each run, this function can update INFOS and change Module:Central/INFOS or Module:Main/INFOS. On 2017-06-14 Rical, INFOS contains versn.Mediawiki_Versions. -- Special:PageData https://fr.wikisource.org/wiki/Wikisource:Newsletter_technique#Tech_News:_2017-25 Special:PageData sera un point d’entrée pour des données d’une page lisibles par la machine. [125] 20170620 08:55 Rical Special:PageData will be an entry point for machine-readable page data. phabtask T163923 Create Special:PageData as a canonical entry point for machine readable page data. --]] local tab = datas.PageData_to_table(datext) local datext = datas.table_to_PageData(tab) --[[ PageData Guideline: How to do: Structure_for_PageData = { -- Several modules can access this Special:PageData without disturbing eachother. -- Example of structure to share versn.Mediawiki_Versions actualMWbefore = "MWVERSIONSbeginMWVERSIONSend", -- false balise ready to replace by string.gsub(s,"%%1",r) ) actualMWstart = "MWVERSIONSbegin", actualMWstop = "MWVERSIONSend", preview222 = { -- old versions to automatic delete later previewMWstop = "MWVERSIONSbegin222", -- The number protect against bad access error, waiting a delete preview_content = viewer.rough_view(Mediawiki_Versions), previewMWstop = "MWVERSIONSend222", preview111 = { -- old versions to automatic delete previewMWstop = "MWVERSIONSbegin111", preview_content = viewer.rough_view(Mediawiki_Versions), previewMWstop = "MWVERSIONSend111", } } } --]] --[==[ Help:Tabular Data example Data:Sandbox/Name/Example.tab for PageData https://www.mediawiki.org/wiki/Help:Tabular_Data https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Extension_libraries_.28mw.ext.29 -- For now, page content can only be edited in the raw JSON format. Eventually, we hope there will be a spreadsheet-like editor to simplify data editing. --]==] local Help_Tabular_DataExample = [=[{ "license": "CC0-1.0", "description": { "en": "Some good fruits for you", "es": "Algunas buenas frutas para ti" }, "sources": "http://example.com and [[Data]] page", "schema": { "fields": [ { "name": "id", "type": "string", "title": { "en": "Fruit ID", "fr": "ID de fruit" }}, { "name": "count", "type": "number", "title": { "en": "Count" }}, { "name": "liked", "type": "boolean", "title": { "en": "Do I like it?" }}, { "name": "description", "type": "localized", "title": { "en": "Fruit name", "fr": "Nom du fruit" }} ] }, "data": [ [ "peaches", 100, true, { "en": "Magnificent but a bit artificial sweet peaches", "es": "esto puede estar en español", "fr": "this could be in french" } ], ] }]=] local lua_content = mw.text.jsonDecode(Help_Tabular_DataExample) local json_content = mw.text.jsonEncode(lua_content) local table_to_code = { -- see activity.wikis_names ["b"] = 'wikibooks', ["cm"] = 'commons', ["meta"] = 'meta', ["mw"] = 'mediawiki', ["n"] = 'wikinews', ["p"] = 'wiki', ["q"] = 'wikiquote', ["s"] = 'wikisource', ["species"] = 'species', ["t"] = 'wiktionary', ["test"] = 'test', ["test2"] = 'test2', ["v"] = 'wikiversity', ["w"] = 'wikipedia', ["wm"] = 'wikimedia', ["y"] = 'wikivoyage', } -- activity.wikis_names local table_json = mw.text.jsonEncode(table_to_code) local table_lua = mw.text.jsonDecode(table_json) local final_table = {} for key, val in pairs(table_lua) do final_table[key] = val end local tabView = { testGroup = final_table, -- Use default cases. title_memo = "datas_update_Special_PageData_title", -- "events.all_kinds_test() Test: all kinds of events (err, wng, cat)", headers = "key;val", rowGroup = {}, } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. return { case.key, case.val } end -- t = t .. viewer.ta("form #rowGroup *2", #tabView.rowGroup) -- debug170602 t = t .. tableview.new(tabView) -- Form a table view with lines and columns. t = t .. viewer.ta("#testGroup", #tabView.testGroup) t = t .. viewer.ta("#rowGroup", #tabView.rowGroup) viewer.zzz_restore_configs(memo, "datas.update_PageData") -- Restore global configurations after eventual changes. return t end -- function datas.update_PageData(t) function datas.loadData(t, datext) -- Pass data between #invoke's local T67687 = "phabtask : mw.loadData can be used to pass data between #invoke's by reading frame arguments" if false then -- Create the following as Module:LoadData: local p = {} function p.main(frame) return mw.loadData('Module:LoadData/data')[1] end return p end if false then -- Create the following as Module:LoadData/data: return { mw.getCurrentFrame().args[1] } end if false then -- Create the following as Module:LoadData/doc: -- {{#invoke:LoadData|main|some data to share}} -- {{#invoke:LoadData|main}} -- {{#invoke:LoadData|main}} end end -- function datas.loadData(t, datext) -- Pass data between #invoke's -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:events support events of types erros, warnings and categories. -- viewer.zzz_save_configs("events.save_configs" base, tabView, group ) -- Init a new events group -- events.add_err(key, ... ) -- Add an error in the actual table of events. -- events.add_cat_group(groupCat, groupList) -- Add some categories in the actual table of events. -- events.form(evt) -- Format events types -- events.categ_Test(t) -- test categories -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- events = {} -- already declared by Scribunto, see centrobj.new() -- Record a library in package.loadedS -- 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_all_kinds_tests_headers = "typ;key;idargs;result", events_close_without_memo_err = "viewer.zzz_restore_configs(memo, where) without <b>memo</b> in module <b>%1</b>.", events_antiCrash_protect_err = "The antiCrash() function protects this page against a complete crash due to an internal error: %1.", } -- 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_all_kinds_tests_headers = "typ;key;idargs;result", events_add_cat_deprecated = "Función obsoleto en módulo principal.", events_close_without_memo_err = "viewer.zzz_restore_configs(memo, where) sin <b>memo</b> en el módulo <b>%1</b>.", events_antiCrash_protect_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_all_kinds_tests_headers = "typ;key;idargs;result", events_add_cat_deprecated = "Fonction obsolète dans le module principal.", events_close_without_memo_err = "viewer.zzz_restore_configs(memo, where) sans <b>memo</b> dans le module <b>%1</b>.", events_antiCrash_protect_err = "La fonction antiCrash() protège cette page contre un effondrement complet dû à une erreur interne : %1.", } -- events.i18n.fr events.testGroup = {} events.rowGroup = {} events.tabView = {} events.tabView.testGroup = {} events.tabView.rowGroup = {} function events.add_err(key, ... ) -- Add an error in the actual table of events. return events.add_record("err", key, ...) -- Add a error, warning or category in the lists. S170626rev end function events.add_wng(key, ... ) -- Add a warning in the actual table of events. return events.add_record("wng", key, ...) -- Add a error, warning or category in the lists. S170626rev end function events.add_cat(key, ... ) -- Add a category in the actual table of events. return events.add_record("cat", key, ...) -- Add a error, warning or category in the lists. S170626rev end function events.form_cat(evt, txt, lnk, c, space) local space = space or (mw.site.namespaces.Category.name .. ":") local c = c or evt.ccc or ":" return " [[" .. c .. space .. (evt.content_wkt or lnk) .. "|" .. (evt.user_wkt or txt) .. "]] " end events.list_all_events = {} -- Table to collect all events types "err", "wng" and "cat". function events.new(typ, key, ...) -- Initialize and finalize a new event. local evt = {} -- default event if type(typ) == "table" then evt = typ -- Use a predefined event else -- To finalize an existing event. evt.typ = typ evt.key = key end -- Finalize all events 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 evt.key or "name" -- Translation key, simple or extended by name evt.vals = evt.vals or { ... } -- table of arguments values evt.catview = evt.catview or ":" -- Default value for eventual use evt.res, evt = events.form( evt ) -- Form the resulting wikitext, can be re-form later return evt end -- function events.new(typ, key, ...) function events.add_new(evt) -- Add a error, warning or category in the lists. S170626rev -- Select only new events if type(evt) ~= "table" then evt = {} end local new_evt = langs.formTestCase( tostring(evt.key), lua_table.toList( evt.vals ) ) for i, event in pairs(events.list_all_events) do local old_evt = langs.formTestCase( tostring(event.key), lua_table.toList( event.vals ) ) if new_evt == old_evt then new_evt = nil ; break end -- Add only new events. Reject already seen events. end -- events.add_wng("modes_auto_val_warning_wng", langs.user_translations[key], val) -- form_result if new_evt then table.insert(events.list_all_events, evt) end return evt end -- function events.add_new(typ, ref, ...) function events.add_record(typ, key, ... ) -- Add a new error, warning or category in a list. -- Guide line: all events are in a single table, including categories, without duplication. -- Guide line: without duplication: events differ if the type, the key or any value of any argument differs. -- Guide line: We can view or categorize categories. local intern_or_use = langs.main_i18n["en"][key] if viewer.is_in("_i_cat", key) or viewer.is_in("_u_cat", key) then -- In a i18n table if viewer.is_in("_i_cat", key) then key = "versn_internal_error_i_cat" -- dedicated internal error cat elseif viewer.is_in("_u_cat", key) then key = "versn_usage_error_u_cat" -- dedicated usage error cat elseif tostring(intern_or_use) < "intern_or_use" then key = "versn_internal_error_i_cat" -- Choose internal or use error end -- display form9user and link to internal usage or usage category end if intern_or_use < "intern_or_use" then key = "versn_internal_error_i_cat" -- Choose internal or use error key = "langs_selectLang_test_cat" -- langs_selectLang_test_cat = "Module with internal error" else key = "versn_module_usage_error_cat" -- versn_module_usage_error_cat = "Module avec erreur d'utilisation" end local evt = events.new(typ, key, ...) -- Initialize and finalize a new event. local evt = events.add_new(evt) -- Add a error, warning or category in the lists. S170626rev local res, evt = events.form(evt, c) -- Format an event as an error, warning or category. return res, evt end -- local res, evt = events.add_record(typ, key, ... ) function events.form(evt, c) -- Format an event as an error, warning or category. local evt = mw.clone(evt) -- do not disturb input event if type(evt) ~= "table" then evt = {} 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), lua_table.toList( evt.vals ) ) ) -- Each type of event forms its own type of wikitext -- evt.content_wkt = viewer.trans9vars(langs.content_translations, evt.key, lua_table.toList( evt.vals ) ) -- evt.page_wkt = viewer.trans9vars(langs.page_translations, evt.key, lua_table.toList( evt.vals ) ) -- evt.user_wkt = viewer.trans9vars(langs.user_translations, evt.key, lua_table.toList( evt.vals ) ) evt.content_wkt = viewer.form9content(evt.key, lua_table.toList( evt.vals ) ) evt.page_wkt = viewer.form9page(evt.key, lua_table.toList( evt.vals ) ) evt.user_wkt = viewer.form9user(evt.key, lua_table.toList( evt.vals ) ) evt.res = "" 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 evt.ccc = c or evt.catview or events.catview or ":" evt.content_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 .. content_catspace .. ":" .. evt.content_wkt .. "|" .. evt.user_wkt .. "]] " -- evt.res = events.form_cat(evt.user_wkt, evt.content_wkt, c, content_catspace) evt.res = " [[" .. evt.ccc .. evt.content_catspace .. evt.content_wkt .. "|" .. evt.user_wkt .. "]] " -- evt.res = events.form_cat(evt) end viewer.trc = viewer.trc or "? form " .. langs.formTestCase(".form evt.key=%1, evt.res=%2, ", evt.key, evt.res ) return evt.res, evt end -- function events.form(evt, c) events.all_kinds_test_testGroup = { { "abc", "langs_form9user_all_types_values", { "pi = ", "circle / diameter", 3.14, }, }, { "equation", "langs_form9user_all_types_values", { 11, 7, 3.14, }, }, { "Matrix:", "langs_form9user_all_types_values", { "2.1.0", "v4-6, ISO_8601, FC14 h6", }, }, { "pi = ", "langs_form9user_all_types_values", { "circle / diameter", 3.14, }, }, { "quadrature", "langs_form9user_all_types_values", { function() end, "convert a square to a circle", }, }, } -- langs_form9user_all_types_values = "Test: string=%1 number=%2 nil=%3 function=%4 table=%5.", function events.all_kinds_test(t) -- Test: all kinds of events (err, wng, cat) local memo = viewer.zzz_save_configs("events.all_kinds_test") -- Save global configuration before eventual changes. events.all_kinds_trck = "\n* events.all_kinds_trck: " local t = t or "" t = t .. "\n* events.all_kinds_test(t) -- Test: all kinds of events (err, wng, cat): " t = t .. events.all_kinds_trck local tabView = { testGroup = events.all_kinds_test_testGroup, -- Use default cases. title_memo = "events_all_kinds_tests_title", -- "events.all_kinds_test() Test: all kinds of events (err, wng, cat)", headers = "events_all_kinds_tests_headers", -- "typ;key;idargs;result", rowGroup = {}, } function tabView.form_one_case(evt) -- Convert a case from testGroup to rowGroup. local res, evt = events.add_record(tostring(evt.typ), tostring(evt.key), lua_table.toList(evt.vals) ) res = (res or "add_in_list.res: ") events.all_kinds_trck = events.all_kinds_trck .. (evt.trk or "") -- return { tostring(evt.typ), tostring(evt.key), tostring(evt.idargs), tostring(evt.res) } return { evt.typ or "t", evt.key or "k", evt.idargs or "i", res or "r" } end -- t = t .. viewer.ta("form #rowGroup *2", #tabView.rowGroup) -- debug170602 t = t .. tableview.new(tabView) -- Form a table view with lines and columns. t = t .. viewer.ta("end #testGroup *2", #tabView.testGroup) -- function tableview.new( nil bug170602 t = t .. viewer.ta("end #rowGroup *2", #tabView.rowGroup) -- function tableview.new( nil bug170602 t = t .. events.all_kinds_trck viewer.zzz_restore_configs(memo, "events.all_kinds_test") -- Restore global configurations after eventual changes. return t end -- function events.all_kinds_test(t) function events.add_cat_group(groupCat, groupList) -- Add some categories in the actual table of events. Separated by ";". -- 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 = "" 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.add_cat_group(groupCat, groupList) 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.selector( tabView, evt ) if type(evt) ~= "table" then evt = { -- options for tableview.new() -- 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(tabView) == "table") and (type(tabView.typ) == "string") and (tabView.typ == evt.typ) then table.insert( tabView.testGroup, { evt.typ, evt.key, evt.name, evt.wkt } ) elseif (type(tabView) == "table") and (type(tabView.typ) == "string") and (tabView.typ == "v") then table.insert( tabView.testGroup, { evt.typ, evt.key, evt.name, evt.wkt } ) else tabView = {} table.insert( tabView.testGroup, { evt.typ, evt.key, evt.name, evt.wkt } ) end end -- function events.selector( tabView, evt ) function events.categ_Test(t) -- test of categories local memo = viewer.zzz_save_configs("events.categ_Test") -- Save global configuration before eventual changes. langs.init_languages() -- restore previous langages local t = t or "\n* These categ_Test test the function <b>add_cat</b> : " .. viewer.ta("user_lang", langs.user_lang) .. viewer.ta("content_lang", langs.content_lang) local tabView = { testGroup = { -- events.testGroup -- { typ = "cat", ["funcname"] = "add_cat", user_lang = nil, content_lang = nil, key = "datas_no_args_wikidata_err", }, { typ = "cat", ["funcname"] = "add_cat", user_lang = nil, content_lang = nil, key = "versn_module_usage_error_cat", }, { typ = "cat", ["funcname"] = "add_cat", user_lang = "en", content_lang = nil, key = "modes_no_source_arguments_cat", }, -- { typ = "cat", ["funcname"] = "add_cat", user_lang = "es", content_lang = nil, key = "modes_no_source_arguments_err", }, -- { typ = "cat", ["funcname"] = "add_cat", user_lang = "en", content_lang = "es", key = "datas_no_args_wikidata_err", }, { typ = "cat", ["funcname"] = "add_cat", user_lang = "fr", content_lang = "en", key = "modes_no_source_arguments_cat", }, { typ = "cat", ["funcname"] = "add_cat", user_lang = "es", content_lang = "en", key = "versn_module_usage_error_cat", }, { typ = "cat", ["funcname"] = "add_cat", user_lang = "en", content_lang = "x-y-z", key = "versn_err_module_miss_i18n_cat", }, { typ = "cat", ["funcname"] = "add_cat", user_lang = "en", content_lang = "fr", key = "modes_no_source_arguments_cat", }, }, headers = "events_test_categ_Test_headers", -- headers = "Test type; user language; wiki language; Categories", } function tabView.form_one_case(test) -- For each case: ac_opt = testOptions.testGroup[i] local content_lang_memo = langs.content_lang local page_lang_memo = langs.page_lang local user_lang_memo = langs.user_lang langs.init_languages(test.content_lang, test.page_lang, test.user_lang) if test.funcname == "add_cat" then -- test.catext = events.add_cat(test.key, test.key,":") --, lua_table.toList(test.vals) ) -- debug : function events.form( local keyuser = viewer.form9user(test.key) local keycontent = viewer.form9content(test.key) test.catext = events.form_cat({}, keyuser, keycontent, ":") local content_lang_memo = langs.content_lang local page_lang_memo = langs.page_lang local user_lang_memo = langs.user_lang return { (test.funcname or "-"), (test.user_lang or "-"), (test.content_lang or "-"), (test.catext or "-") } elseif test.funcname == "add_cat_group" then test.catext = events.add_cat_group(test.key) --, lua_table.toList(test.vals) ) local content_lang_memo = langs.content_lang local page_lang_memo = langs.page_lang local user_lang_memo = langs.user_lang return { (test.funcname), (test.user_lang), (test.content_lang), (test.catext) } end langs.init_languages(content_lang_memo, page_lang_memo, user_lang_memo) end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "events.categ_Test") -- Restore global configurations after eventual changes. return t end -- function events.categ_Test(t) function events.all_kinds_test_test(t) -- Test: all kinds of events (err, wng, cat) local memo = viewer.zzz_save_configs("events.categ_Test") -- Save global configuration before eventual changes. local t = t or "\n* <b>events.all_kinds_test()</b> Test: all kinds of events (err, wng, cat)" local tabView = { testGroup = nil, -- Use default cases. title_memo = "events_all_kinds_tests_title", -- "events.all_kinds_test() Test: all kinds of events (err, wng, cat)", headers = "events_all_kinds_tests_headers", -- "typ;key;idargs;result", } function tabView.form_one_case(evt) -- Convert a case from testGroup to rowGroup. return { evt.typ, evt.key, evt.idargs, evt.res } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "events.all_kinds_test_test") -- Restore global configurations after eventual changes. return t --, errors -- langs_missing_translations_title end -- function events.all_kinds_test_test(t) 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 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("versn_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) function events.categories_lister(c) -- Categorize categories, or view categories if c=":". local res = "" modes.options_to_catView() -- c can replace catView to enforce the documentation or the categorisation c = c or modes.catView or "" for k, evt in pairs(events.list_all_events) do -- res = res .. k .. evt.res -- if (c == ":") and (evt.type == "cat") then res = res .. k .. evt.res end -- to view categories -- if (c == "") and (evt.type == "cat") then res = res .. k .. evt.res end -- to categorize -- if (evt.type == "cat") then local keyuser = viewer.form9user(evt.key) local keycontent = viewer.form9content(evt.key) -- res = res .. ", k=" .. k -- res = res .. evt.key .. ", " -- c = ":" -- res = res .. events.form_cat({}, keyuser, keycontent, c) res = res .. events.form_cat({}, keyuser, keycontent, ":") res = res .. events.form_cat({}, keyuser, keycontent, "") -- end end return res -- "cats+" .. res end -- function events.categories_lister(c) -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:langs supports i18n translations. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- langs = {} -- already declared by Scribunto, see centrobj.new() -- Record a library in package.loaded -- Translations for translate library langs.i18n = {} langs.i18n.en = { language = 'language', langs_translationsCounts_title = "langs.translationsCounts() Counts of translations in tables", langs_form9user_tests_title = "viewer.form9user() Test: Replace %1 to %9 by tostring( argN ) from arguments", langs_form9user_all_types_values = "Test: string=%1 number=%2 nil=%3 function=%4 table=%5.", langs_form99user_tests_title = "in viewer.form99user() Test: Replace %01 to %99 by tostring( argN ) from arguments", langs_form99user_all_types_values = "in viewer.form99user() Values of all types: %1, %2, %3, %4, %5.", langs_form99user_no_tranlation = "in viewer.form99user() Lack of translation.", langs_form99user_a_value_is_table = "in viewer.form99user() A value is a table.", langs_translations_key_missing = "Internal error: Translations key missing or abnormal in viewer.trans9vars()", langs_lang_not_exist_err = "Error: The language <b>%1</b> is not available.", langs_abnormal_char_in_text_title = "langs.abnormal_char_in_text() Test: Detect abnormal characters in an unilingual text.", langs_abnormal_char_in_alphabet = "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 ,;.:!?", langs_list_Mediawiki_languages_title= "langs.list_Mediawiki_languages() List all Mediawiki languages.", -- Main string, errors and categories of tools langs_first_doc_languages = "Documentation of first languages", langs_content_page_user_lang_msg = "Languages: content: %1, page: %2, user: %3.", langs_without_translation_err = "Known argument, but not translated: <b>%1</b>.", langs_without_translation_N_err = "There are %1 arguments untranslated.", langs_main_i18n_languages_count = "This module can translate into <b>%2</b> languages <b>%1</b> texts: ", langs_table_can_translate_counts = "The table <b>%1</b> can translate <b>%2</b> sentences into <b>%3</b> languages.", langs_mw_language_fetchLanguageName = "<b>%1</b>(%2=%3), ", langs_counts_translations_headers = "*; Table name; Texts; Tables; Comment", langs_i18n_list_all_string = "This list show all the string, but cannot replace the original declarations.", langs_languages_nbr_and_list = "\n* There are %1 tables of translations in these languages : %2 <br>", -- Miscellaneous warnings and errors langs_string_translated_in_langs = "There are %1 string translated in %2 languages.", langs_no_wiki_translations_err = "Error: Module without translated arguments table.", langs_list_in_translated_lang = "%1 translations in language %2 : %3 : %4", langs_transdiff_wanted_error_err = "Wanted error for minimal test of langs.missing_translations().", langs_missing_translations_title = "langs.missing_translations() Missing translations in i18n tables.", langs_missing_translations_headers = "Language; i18n Key; Previous translation; Changing translation; Module", langs_changing_translations_title = "langs.changing_translations() Changing (or missing) translations in i18n tables.", langs_changing_translations_headers = "Language; i18n Key; Previous translation; New translation; Module", langs_changing_translations_help = "See also %1 to ask for help to langs.", langs_mixed_translations_title = "langs.i18n_lister() Combined i18n translations tables:", langs_dummy_languages_title = "langs.dummy_languages() Languages Definitions:", langs_Module_Central_version = "Central-w-en", langs_selectLang_tests_title = "langs.selectLang() Tests: Select a language for tests or other", langs_selectLang_test_headers = "Wiki language; User language; Sought language; Selected language; Example", langs_selectLang_test_example = "Language: wiki = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.", langs_selectLang_test_err = "Internal error : langs.selectLang(lang) has no tests table.", langs_selectLang_test_cat = "Module with internal error", } -- langs.i18n.en langs.i18n.es = { -- ¿Quién es? language = 'lenguaje', langs_translationsCounts_title = "langs.translationsCounts() Condes des traducciones en tablas", langs_form9user_tests_title = "viewer.form9user() Prueba: Reemplazar %1 a %9 por tostring( argN ) a partir de argumentos", langs_form9user_all_types_values = "Prueba: string=%1 number=%2 nil=%3 function=%4 table=%5.", langs_form99user_tests_title = "en viewer.form99user() Prueba: Reemplazar %01 a %29 por tostring( argN ) a partir de argumentos", langs_form99user_all_types_values = "en viewer.form99user() Valores de todos los tipos: %1, %2, %3, %4, %5.", langs_form99user_no_tranlation = "en viewer.form99user() Falta de traducción.", langs_form99user_a_value_is_table = "en viewer.form99user() Un valor es una tabla.", langs_translations_key_missing = "Error interno: Traducciones clave que falta o anormal en viewer.trans9vars()", langs_lang_not_exist_err = "Error: El lenguaje <b>%1</b> no está disponible.", langs_abnormal_char_in_text_title = "langs.abnormal_char_in_text() Prueba: Detectar caracteres anormales en un texto monolingüe.", langs_abnormal_char_in_alphabet = "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?", langs_list_Mediawiki_languages_title= "langs.list_Mediawiki_languages() Lista de todos los idiomas de Mediawiki.", -- Textos principales, errores y categorías de instrumentos langs_first_doc_languages = "Documentación de las primeras idiomas", langs_content_page_user_lang_msg = "Idiomas: usuario: %1, wiki: %2.", langs_without_translation_err = "Argumento conocido, pero no traducido: <b>%1</b>.", langs_without_translation_N_err = "Hay 1% argumentos no traducidos.", -- Diversos mensajes y errores langs_main_i18n_languages_count = "Este módulo puede traducir en <b>%2</b> idiomas <b>%1</b> textos: ", langs_table_can_translate_counts = "Tabla <b>%1</b> puede traducir <b>%2</b> frases en <b>%3</b> idiomas.", langs_mw_language_fetchLanguageName = "<b>%1</b>(%2=%3), ", langs_counts_translations_headers = "*; Nombre de la tabla; Textos; Mesas; Comentario", langs_languages_nbr_and_list = "\n* Hay %1 mesas de traducciones en estas idiomas: %2 <br>", langs_string_translated_in_langs = "Hay 1% textos traducidos en 2% idiomas.", langs_no_wiki_translations_err = "Error: Módulo sin argumentos traducidos tabla.", langs_i18n_list_all_string = "Esta lista muestra todos los textos, pero no puede sustituir a las declaraciones originales.", langs_list_in_translated_lang = "%1 traducciones en idioma %2 : %3 : %4", langs_missing_translations_title = "langs.missing_translations() Traducciones que falta de las tablas i18n.", langs_missing_translations_headers = "Idioma; Clave i18n; Traducción anterior; Cambiando traducción; Módulo", langs_changing_translations_title = "langs.changing_translations() Traducciones que cambian (o falta de) en las tablas i18n.", langs_changing_translations_headers = "Idioma; Clave i18n; Traducción anterior; Nueva traducción; Módulo", langs_changing_translations_help = "Consulte también %1 para solicitar ayuda para traducir.", langs_mixed_translations_title = "Tablas traducciones i18n combinadas:", langs_dummy_languages_title = "langs.dummy_languages() Definiciones de idiomas:", langs_Module_Central_version = "Central-w-es", langs_selectLang_tests_title = "langs.selectLang() Tests: Select a language for tests or other", langs_selectLang_test_headers = "Wiki language; User language; Sought language; Selected language; Example", langs_selectLang_test_example = "Language: wiki = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.", langs_selectLang_test_err = "Internal error : langs.selectLang(lang) has no tests table.", langs_selectLang_test_cat = "Module with internal error", } -- langs.i18n.es langs.i18n.fr = { language = 'langue', langs_translationsCounts_title = "langs.translationsCounts() Comptages des traductions en tables", langs_form9user_tests_title = "viewer.form9user() Test: Remplacer %1 à %9 par tostring( argN ) à partir des arguments", langs_form9user_all_types_values = "Test: string=%1 number=%2 nil=%3 function=%4 table=%5.", langs_form99user_tests_title = "viewer.form99user() Test: Remplacer %01 à %29 par tostring( argN ) à partir des arguments", langs_form99user_all_types_values = "en viewer.form99user() Valeurs de tous types : %1, %2, %3, %4, %5.", langs_translations_key_missing = "Erreur interne: Clé de traduction manquante ou anormale dans viewer.trans9vars()", langs_form99user_no_tranlation = "en viewer.form99user() Manque de traduction.", langs_form99user_a_value_is_table = "en viewer.form99user() Une valeur est une table.", langs_lang_not_exist_err = "Erreur : La langue <b>%1</b> n'est pas disponible.", langs_abnormal_char_in_text_title = "langs.abnormal_char_in_text() Test: Détecter les caractères anormaux dans un texte unilingue.", langs_abnormal_char_in_alphabet = "abcdefghabklmnopqrstuvwxyz ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 àéèêëiouüœ ÀÉÈÊËIOUÜŒ ,;.:!?", langs_list_Mediawiki_languages_title= "langs.list_Mediawiki_languages() Liste de toutes les langues de Mediawiki.", -- Principaux textes, erreurs et catégories des outils langs_first_doc_languages = "Documentation des premières langues", langs_content_page_user_lang_msg = "Langues : utilisateur : %1, wiki : %2.", langs_without_translation_err = "Argument connu, mais non traduit : <b>%1</b>.", langs_without_translation_N_err = "Il y a %1 arguments non traduits.", langs_main_i18n_languages_count = "Ce module peut traduire en <b>%2</b> langues <b>%1</b> textes : ", langs_table_can_translate_counts = "La table <b>%1</b> peut traduire <b>%2</b> phrases en <b>%3</b> langues.", langs_mw_language_fetchLanguageName = "<b>%1</b>(%2=%3), ", langs_counts_translations_headers = "*; Nom de la table; Textes; Tables; Commentaire", langs_i18n_list_all_string = "Cette liste montre tous les textes, mais ne peut remplacer les déclarations originales.", langs_languages_nbr_and_list = "\n* Il y a %1 tables de traductions dans ces langues : %2 <br>", langs_string_translated_in_langs = "Il y a %1 textes traduits en %2 langues.", langs_no_wiki_translations_err = "Erreur interne : Module sans table d'arguments traduits.", langs_list_in_translated_lang = "%1 traductions en langage %2 : %3 : %4", langs_changing_translations_title = "langs.changing_translations() Changements de traduction dans les tables i18n", langs_changing_translations_headers = "Module; Langue; Clé i18n; Traduction précédente; Traduction changeante", langs_missing_translations_title = "langs.missing_translations() Liste les traductions manquantes dans les tables i18n", langs_missing_translations_headers = "Module; Langue; Clé i18n; Traduction précédente; Langues manquantes", langs_changing_translations_help = "Voir aussi %1 pour demander de l'aide pour traduire.", langs_mixed_translations_title = "Tables de traductions i18n combinées :", langs_dummy_languages_title = "langs.dummy_languages() Définitions de langues :", langs_Module_Central_version = "Central-w-fr", langs_selectLang_tests_title = "langs.selectLang() Tests: Select a language for tests or other", langs_selectLang_test_headers = "Wiki language; User language; Sought language; Selected language; Example", langs_selectLang_test_example = "Language: wiki = <b>%1</b>, user = <b>%2</b>, selected = <b>%3</b>.", langs_selectLang_test_err = "Internal error : langs.selectLang(lang) has no tests table.", langs_selectLang_test_cat = "Module avec erreur interne", } -- langs.i18n.fr langs.i18n.br = { langs_counts_translations_headers = "*; Nom de la table; Textes; Tables; Commentaire", langs_table_can_translate_counts = "La table <b>%1</b> peut traduire <b>%2</b> phrases en <b>%3</b> langues.", langs_mw_language_fetchLanguageName = "<b>%1</b>(%2=%3), ", langs_changing_translations_title = "langs.changing_translations() Changements de traduction dans les tables i18n", langs_changing_translations_headers = "Module; Langue; Clé i18n; Traduction précédente; Traduction changeante", langs_missing_translations_title = "langs.missing_translations() Liste les traductions manquantes dans les tables i18n", langs_missing_translations_headers = "Module; Langue; Clé i18n; Traduction précédente; Langues manquantes", } -- langs.i18n.br langs.i18n.de = { langs_counts_translations_headers = "*; Tabellenname; Texte; Tische; Kommentar", langs_table_can_translate_counts = "<b>%1</b>-Tabelle kann <b>%2</b> Sätze übersetzen in <b>%3</b> Sprachen.", langs_mw_language_fetchLanguageName = "<b>%1</b>(%2=%3), ", langs_changing_translations_title = "langs.changing_translations () Übersetzungen ändern sich in i18n Tabellen", langs_changing_translations_headers = "Modul; Sprache; i18n Schlüssel; Frühere Übersetzung; Übersetzung ändern", langs_missing_translations_title = "langs.missing_translations () Liste fehlender Übersetzungen in i18n-Tabellen", langs_missing_translations_headers = "Modul; Sprache; i18n Schlüssel; Frühere Übersetzung; Fehlende Sprachen", } -- langs.i18n.de langs.i18n.hu = { langs_counts_translations_headers = "*; Táblázat neve; Szövegek; Asztalok; Megjegyzés", langs_table_can_translate_counts = "<b>%1</b> tábla lefordítani <b>%2</b> mondat <b>%3</b> nyelven.", langs_mw_language_fetchLanguageName = "<b>%1</b>(%2=%3), ", langs_changing_translations_title = "langs.changing_translations() Fordítások az i18n táblákban megváltoztatva", langs_changing_translations_headers = "Modul; Nyelv; i18n Kulcs; Korábbi fordítás; A fordítás megváltoztatása", langs_missing_translations_title = "langs.missing_translations() A hiányzó fordítások listája az i18n táblákban", langs_missing_translations_headers = "Modul; Nyelv; i18n Kulcs; Korábbi fordítás; Hiányzó nyelvek", langs_missing_translations_headers_test = "Modul; Nyelv, test...", } -- langs.i18n.hu langs.i18n.vi = { langs_counts_translations_headers = "*; Tên bảng; Văn bản; Những cái bàn; Bình luận", langs_table_can_translate_counts = "Bảng <b>%1</b> có thể dịch thành <b>%2</b> câu <b>%3</b> ngôn ngữ.", langs_mw_language_fetchLanguageName = "<b>%1</b>(%2=%3), ", langs_changing_translations_title = "langs.changing_translations() Các bản dịch trong i18n tables", langs_changing_translations_headers = "Mô đun; Ngôn ngữ;, Khóa i18n; Bản dịch trước; Thay đổi bản dịch", langs_missing_translations_title = "langs.missing_translations() Danh sách các bản dịch bị mất trong các bảng i18n", langs_missing_translations_headers = "Mô đun, Ngôn ngữ, Khóa i18n, Bản dịch trước, Thiếu ngôn ngữ", langs_missing_translations_title_test = "langs.missing_translations() test...", } -- langs.i18n.vi langs.MetaSupportedLanguages = { "ja", "es", "ru", "de", "nl", "tr", "fr", "pt", "ko", "en", "it", "oc", "pl", "fa", "ar", "vi", "arz", "hi", "sv", "diq", "pt-br", "zh", "th", "bg", "hu", "uk", "en-gb", "sh", "id", "bn", "az", "fi", "be", "he", "eo", "el", "sd", "kn", "ro", "yue", "sr", "mk", "ta", "pa", "hy", "lb", "tt", "si", "yi", "ne", "cs", "sk", "ms", "eu", "mr", "sa", "tl", "eml", -- https://meta.wikimedia.org/wiki/Special:SupportedLanguages on 20170629 Rical } -- 58 languages in total. function langs.i18n_sub_counts(subnames_in, key_form, lang) -- Count i18n in the last sub-table from its sub-names. -- local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(subnames_in, key_form, lang) local subnames_in, key_form, lang = subnames_in, key_form, lang if (type(subnames_in) ~= "string") then subnames_in = "" end local t, strings_c, tables_c, strs_on_tabs, subnames = "", 0, 0, 0, "" local sub_names = mw.text.split(subnames_in, '%.') -- table of words local in_i18n, i18n_i, subnames_, sub_tab, all_strings, strs_on_tabs, separ local i18n_counts, i18n_strings_c, i18n_tables_c local lang_counts, lang_strings_c, lang_tables_c = {} if (type(sub_names) == "table") then subnames_ = "" separ = "" in_i18n = nil i18n_i = 0 for i, sub_name in ipairs(sub_names) do subnames_ = subnames_ .. separ .. sub_name separ = "." subnames = subnames_ -- string.sub(subnames_, 2, -1) -- like modes.i16n.fr if viewer.is_in("i18n", sub_name) then -- In a i18n table i18n_i = i sub_tab = lua_table.tabfromsubnames(subnames) -- Get the last sub-table from its sub-names. i18n_counts = lua_table.count_types(sub_tab) i18n_strings_c = i18n_counts.string or "0" i18n_tables_c = i18n_counts.table or 0 tables_c = i18n_tables_c all_strings = 0 for key, val in pairs(sub_tab) do if (type(val) == "table") then all_strings = all_strings + lua_table.count_all(val) end end strs_on_tabs = math.floor( (all_strings + 0.49) / math.min(tables_c, 1) ) strings_c = strs_on_tabs elseif i > i18n_i then -- In a language sub-table sub_tab = lua_table.tabfromsubnames(subnames) -- Get the last sub-table from its sub-names. lang_counts = lua_table.count_types(sub_tab) lang_strings_c = lang_counts.string lang_tables_c = lang_counts.table strings_c = lang_strings_c tables_c = 1 end end end -- This module can translate... = langs_main_i18n_languages_count local strings_c = strings_c or 0 -- or lang_counts.strings_c local tables_c = tables_c or 0 -- or i18n_tables_c.tables_c local strs_on_tabs = strs_on_tabs or 0 -- Form resulting text if (type(lang) ~= "string") then lang = "user" elseif lang == "c" then lang = "content" elseif lang == "p" then lang = "page" elseif lang == "u" then lang = "user" end if (type(key_form) ~= "string") then key_form = "langs_table_can_translate_counts" end local t = viewer.form9user(key_form, subnames, strings_c, tables_c) if lang == "page" then t = viewer.form9page(key_form, subnames, strings_c, tables_c) end if lang == "content" then t = viewer.form9content(key_form, subnames, strings_c, tables_c) end return t, strings_c, tables_c, strs_on_tabs, subnames -- local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(subnames_in, key_form, lang) end -- function langs.i18n_sub_counts(subnames_in, key_form, lang) function langs.translationsCounts(t) -- Counts of contents of some tables, from their names. -- S170618ltc local memo = viewer.zzz_save_configs("langs.translationsCounts") -- Save global configuration before eventual changes. local t = t or '\n* langs.translationsCounts("activity.i18n") Counts of contents of some tables, from their names: ' local selector = "br;es;vi;modes;begin;translate;" -- Select a reduces table view. local object_loaded, counts, pre_counts, tables_c, sub_string_count local tabname, subnames, tt, lang local trans_Group, trans_counts = {}, {} local libname_total = 0 local select_track = "-" -- nil local trans_counts = {} for libname, library in pairs(package.loaded) do if (type(library.i18n) == "table") then -- Select all libraries with i18n tables. tabname = libname .. ".i18n" table.insert(trans_Group, { tabname } ) -- Build a table with translations counts. end end table.sort(trans_counts, function (row_x, row_y) return ( row_x[1] < row_x[1] ) end ) -- Sort based on [1]=tabname -- table.insert(trans_Group, { "langs.main_i18n" } ) -- Build a table with translations counts. local test_tables = "langs.main_i18n;begin.i18n.de;begin.i18n.hu;begin.i18n.vi;modes.i18n.fr" -- Select a reduces table view. local test_tables_tab = mw.text.split(test_tables, ';') -- table of words for i, subnames_in in ipairs(test_tables_tab) do -- list all used names, only one each, in alphabetic order table.insert(trans_Group, { ["subnames_in"] = subnames_in, ["i"] = i } ) -- Build a table with translations counts. end local tabView = { -- testGroup = trans_Group, testGroup = { -- { i = 1, subnames_in = "activity.i18n.hu", }, { i = 2, subnames_in = "versn.i18n.hu", }, { i = 3, subnames_in = "versn.i18n.en", }, { i = 4, subnames_in = "langs.main_i18n.en", }, { i = 5, subnames_in = "langs.main_i18n.hu", }, { i = 6, subnames_in = "langs.main_i18n.vi", }, { i = 7, subnames_in = "langs.main_i18n", }, }, title_memo = "langs_translationsCounts_title", -- "langs.translationsCounts() Counts of translations in tables", headers = "langs_counts_translations_headers", -- "*; Table name; Texts; Tables; Comment",en headers_class = "wikitable alternative center sortable", rowselect = selector, rowGroup = {}, -- tests or tabView.testGroup or } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local subnames_in = case.subnames_in or "subnames_in" local i = case.i or 33 local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(subnames_in, "langs_table_can_translate_counts", "user") local comment = viewer.form9user("langs_table_can_translate_counts", subnames, strings_c, tables_c) -- strs_on_tabs = strs_on_tabs, maxstringcount = max_string_count, missingtrans = missing_trans, } return { i, subnames, strings_c, tables_c, t, } -- .. comment .. trk end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "langs.translationsCounts") -- Restore global configurations after eventual changes. return t end -- t = function langs.translationsCounts(t) function langs.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 = langs.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, langs.user_lang), translate_one_key(translate_i18n, key, langs.content_lang), translate_one_key(translate_i18n, key, langs.page_lang) end -- local user, wiki, page = langs.key(key, lang) -- Examples of uses end -- function langs.key(key, lang) function langs.main_i18n_languages_list() -- List available translations and languages local main_i18n = langs.main_i18n or {} local xxx, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts("langs.main_i18n", "langs_main_i18n_languages_count", "user") 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 the languages codes in stable alphabetic order return ( a < b ) end ) local t = viewer.form9user("langs_main_i18n_languages_count", strs_on_tabs, tables_c) for i, lang in pairs(tab_to_sort) do -- Name and count translations in each language local langi18n = "langs.main_i18n." .. lang local xxx, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(langi18n, "langs_main_i18n_languages_count", "user") t = t .. "<b>" .. strings_c .. "</b>-" local nativename = mw.language.fetchLanguageName(lang) local englishname = mw.language.fetchLanguageName(lang, "en") local englishname = mw.language.fetchLanguageName(lang, "en") t = t .. viewer.form9user("langs_mw_language_fetchLanguageName", nativename, lang, englishname) -- "<b>%1</b>(%2=%3), " if i > 12 then t = t .. "<b> ...</b>" ; break end end -- see langs.selectLang return t end -- function langs.main_i18n_languages_list() function langs.formTestCase(ref, ...) -- Form reference_key;v1;v2;v3;... for tests. 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 langs.Central_version = "Central-s-fr" -- To adapt the version of Module:Central in any translated text. function langs.init_languages(content_lang, page_lang, user_lang) -- Initialize or change the content, the page and the user languages and their translations tables. -- Guide line: decreasing priority, for each of these 3 languages, is : -- this function args else args_source else default value. -- See also https://meta.wikimedia.org/wiki/Translate_extension and [[Special:PageLanguage]] 2016-12-19 langs.main_i18n = langs.main_i18n or versn.main_i18n -- content_lang, page_lang, user_lang = "en", "vi", nil local t = "langs.init_languages() Lua code track." local lg = {} local args_source = args_source or modes.args_source local modesCont, modesPage, modesUser = nil, nil, nil if modes.args_source then -- and modes.args_source.userlang Does module arguments ask a content_lang? local modes_args = modes.args_final or modes.args_source -- work after full init or before modesCont = modes_args.contentlang modesPage = modes_args.pagelang modesUser = modes_args.userlang else return t .. " modes.args_source is missing when init this central module." end -- -- define CONTENT LANGUAGE modes.frame = mw.getCurrentFrame() -- lg.content_lang = modes.frame:preprocess("{{CONTENTLANGUAGE}}") -- Returns the default content language. lg.content_lang = mw.getContentLanguage().code -- Returns the default content language. if (type(content_lang) == "string") and (not langs.main_i18n[lg.content_lang]) then content_lang = nil end -- Are content_lang translations available? lg.content_prior = content_lang or args_source.contentlang or modesCont or lg.content_lang or "en" -- Priorize content_lang definitions. -- -- define PAGE LANGUAGE lg.page_lang = modes.frame:preprocess("{{PAGELANGUAGE}}") -- Returns the default page language. if (type(page_lang) == "string") and (not langs.main_i18n[lg.page_lang]) then page_lang = nil end -- Are page_lang translations available? lg.page_prior = page_lang or args_source.pagelang or modesPage or lg.page_lang or "en" -- Priorize page_lang definitions. -- -- define USER LANGUAGE lg.user_lang = modes.frame:preprocess( "{{int:Lang}}" ) -- lg.user_lang = modes.frame:preprocess("{{USERLANGUAGE}}") or "{{USERLANGUAGE}}" -- None ways run on 20170630 Rical, wait for task T68051. if (type(user_lang) == "string") and (not langs.main_i18n[user_lang]) then user_lang = nil end -- Are user_lang translations available? -- lg.user_prior = user_lang or modesUser or lg.user_lang or "en" -- Priorize page_lang definitions. -- lg.user_prior = lg.user_prior or lg.content_prior or lg.page_prior or "en" -- insure user_lang, waiting task T68051. lg.user_prior = user_lang or args_source.userlang or lg.user_lang or modesUser or lg.content_prior or lg.page_prior or "en" -- insure user_lang, waiting task T68051. -- -- Activate these languages for any uses. langs.content_lang = lg.content_prior langs.content_translations = langs.main_i18n[langs.content_lang] langs.page_lang = lg.page_prior langs.page_translations = langs.main_i18n[langs.page_lang] langs.user_lang = lg.user_prior langs.user_translations = langs.main_i18n[langs.user_lang] -- t = t .. "\n* langs.init_languages(content_lang, page_lang, user_lang): " .. viewer.ta("lg.content_lang", lg.content_lang) .. viewer.ta("lg.page_lang", lg.page_lang) .. viewer.ta("lg.user_lang", lg.user_lang) return t end -- function langs.init_languages(content_lang, page_lang, user_lang) function langs.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 content_lang tests en es fr or any available in i18n. if lang == "tests" then lang = "tests" elseif langs.main_i18n and langs.main_i18n[lang] then lang = lang -- available in i18n elseif lang == "user_lang" then lang = langs.user_lang elseif lang == "content_lang" then lang = langs.content_lang else lang = langs.user_lang end -- default is user language return lang end -- function langs.selectLang( lang ) function langs.selectLang_test(t) -- Tests: Select a language for tests or other purpose. local memo = viewer.zzz_save_configs("langs.selectLang_test") -- Save global configuration before eventual changes. local t = t or "\n* Test <b>langs.selectLang()</b> :" -- langs_selectLang_tests_title local tabView = { testGroup = { -- events.testGroup { content_lang = "en", user_lang = "fr", sought = "content_lang", }, { content_lang = "en", user_lang = "es", sought = "user_lang", }, { content_lang = "en", user_lang = nil , sought = "content_lang", }, { content_lang = nil , user_lang = "es", sought = "user_lang", }, { content_lang = "fr", user_lang = "es", sought = "tests", }, }, headers = "langs_selectLang_test_headers" -- headers = "Wiki language; User language; Sought language; Selected language; Example", } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local selected = langs.selectLang( lang ) local example = viewer.form9user("langs_selectLang_test_example") if selected == "tests" then example = langs.formTestCase("selectLang", case.content_lang, case.user_lang, case.sought) end return { tostring(case.content_lang), tostring(case.user_lang), tostring(case.sought), tostring(selected), tostring(example), } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "langs.selectLang_test") -- Restore global configurations after eventual changes. return t end -- langs.selectLang_test(t) --[[ T135845 Convert any module as central or centralisable : From the question "how to name the central space and its shortcut?" we can ask 3 questions: * The shortcut cannot be "c" for commons, it could be "ct" for central or "gb" for global. * Where to find a list of shortcut ? like for languages: mw.language.new .getFallbackLanguages .fetchLanguageNames * The central space is it a project ? local lang = mw.language.new( langs.user_lang or "en" ) local LangCode = lang:getFallbackLanguages() local lang_code_name = mw.language.fetchLanguageNames() -- inLanguage, 'mwfile' ) mw.site.interwikiMap mw.site.interwikiMap( "local" "!local").prefix prefix - the interwiki prefix. Returns a table holding data about available interwiki prefixes. If filter is the string "local", then only data for local interwiki prefixes is returned. If filter is the string "!local", then only data for non-local prefixes is returned. If no filter is specified, data for all prefixes is returned. A "local" prefix in this context is one that is for the same project. For example, on the English Wikipedia, other-language Wikipedias are considered local, while Wiktionary and such are not. Keys in the table returned by this function are interwiki prefixes, and the values are subtables with the following properties: --]] function langs.list_Mediawiki_languages(t, lang) -- List all Mediawiki languages. local memo = viewer.zzz_save_configs("langs.list_Mediawiki_languages") -- Save global configuration before eventual changes. if type(t) ~= "string" then t = "\n* <b>langs.list_Mediawiki_languages()</b> List all known Mediawiki languages:" end local interwikiMap = mw.site.interwikiMap("local") --[[content_or_func -- mw.site.interwikiMap() to not permit to find the projet from its shortcut and reverse. Where to find that? , "now", t = t .. "\n* mw.site.interwikiMap: " .. viewer.ta( "interwikiMap", interwikiMap ) .. viewer.ta( "#interwikiMap", #interwikiMap ) t = t .. '\n* local interwikiMap["wikisource"]: ' .. viewer.rough_view(interwikiMap["wikisource"]) t = t .. '\n* local interwikiMap["s"]: ' .. viewer.rough_view(interwikiMap["s"]) t = t .. '\n* local interwikiMap["wikisource"]: ' .. lua_table.structure(interwikiMap["wikisource"]) t = t .. '\n* local interwikiMap["s"]: ' .. lua_table.structure(interwikiMap["s"]) t = t .. "\n* <b>end interwikiMap</b>" --]] local lang = mw.language.new( langs.user_lang or "en" ) local LangCode = lang:getFallbackLanguages() local lang_code_name = mw.language.fetchLanguageNames() -- inLanguage, 'mwfile' ) local toSort, t2 = {}, "" local t = (t or "") .. "\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", langs.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 = langs.abnormal_char_in_text(lang[2], langs.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 .. viewer.ta( lang[1], lang_2 ) -- .. "\n* " end t = t .. "\n* List of <b>known</b> languages of MediaWiki: <br/>" .. t2 viewer.zzz_restore_configs(memo, "langs.list_Mediawiki_languages") -- Restore global configurations after eventual changes. return t end -- function langs.list_Mediawiki_languages(t, lang) function langs.abnormal_char_in_text(t) -- Test: Detect abnormal characters in an unilingual text. if type(t) ~= "string" then return false end -- langs_abnormal_char_in_text_title local ok, normal = true, viewer.form9user("langs_abnormal_char_in_alphabet") -- local ok, normal = true, "ABCDEFGHABKLMNOPQRSTUVWXYZ 013456789 abcdefghabklmnopqrstuvwxyz àéèêë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 langs.abnormal_char_in_text(t) function langs.changing_translations(t) -- List all changing translations local memo = viewer.zzz_save_configs("langs.changing_translations") -- Save global configuration before eventual changes. local t = t or "\n* <b>langs.changing_translations()</b>: List all changing translations:" -- if 1 then return t end local i18n = langs.main_i18n or versn.main_i18n langs.translations_differences = langs.translations_differences or {} local nerr, errors, trans, err = 0, "*", "", "" local nbr, nbr_in_lang, list = 0, 0, "" local nbr_in_lang_limit = 4 local prev_i18n, next_i18n, prev_table, next_table, max, nkeys = {}, {}, {}, {}, 0, 0 local strnew, lang, prev_lang, refer_lang, cats = "strnew", "", "", "", "", "" -- change means a different text in the main module relative to the text inside each central library, based on the same keyi18n. local changingGroup, libraries = {}, {} for title, obj in pairs(package.loaded) do -- For libraries only local get = versn.bind_main_and_sub_modules_get[title] if get and get.is_library and (type(get.i18n) == "table") then prev_lang = refer_lang prev_i18n = get.i18n next_i18n = i18n table.insert(libraries, get.module) end -- for refer_lang, next_table in pairs(i18n) do -- For all languages and texts to translate -- for refer_lang, next_table in pairs(i18n) do -- For all languages and texts to translate -- end -- end end local lib_langs_keys = {} -- To mix libraries their langs and keys and vals for title, onelibrary in pairs(libraries) do -- For all libraries only for onelang, lang_table in pairs(onelibrary.i18n) do -- For all languages in each library lib_langs_keys[onelang] = lib_langs_keys[onelang] or {} for key, val in pairs(lang_table) do -- For all keys in each language lib_langs_keys[onelang][key] = val end end end for refer_lang, next_table in pairs(libraries) do -- For all languages and texts to translate list = list .. refer_lang .. ", " nbr = nbr + 1 if type(next_table) == "table" then -- For each pair of languages to compare nkeys = 0 nbr_in_lang = 0 local all_txts = {} if type(next_table) == "table" then -- For each language to compare for keyi18n, stri18n in pairs(next_table) do -- List all texts translated in at least one language all_txts[keyi18n] = stri18n end for keyi18n, stri18n in pairs(all_txts) do -- Look at all translations in one language, but check them only from 1 to nbr_in_lang_limit. nbr_in_lang = nbr_in_lang + 1 nkeys = nkeys + 1 if (type(keyi18n) == "string") then -- only translations, not positional arguments keyi18n, stri18n = tostring(keyi18n), tostring(stri18n) local cut = string.find(tostring(keyi18n) .. "_", "_") local modul = string.sub(keyi18n, 1, cut - 1) if (nbr_in_lang == nbr_in_lang_limit) then -- for the last changing -- local strnew = i18n[refer_lang][keyi18n] or "strnew" if i18n[refer_lang] then strnew = i18n[refer_lang][keyi18n] or "strnew" end table.insert( changingGroup, { ["lang"] = refer_lang, ["keyi18n"] = keyi18n, ["stri18n"] = stri18n, ["strnew"] = strnew, ["counts"] = viewer.errorColor("changing limit = " .. nbr_in_lang_limit), ["modul"] = modul} ) -- nerr = nerr + 1 elseif (nbr_in_lang < nbr_in_lang_limit) then -- for changing before the last -- headers = "Language; i18n Key; Previous translation; New translation; Module", if i18n[refer_lang] then strnew = i18n[refer_lang][keyi18n] or "strnew" end table.insert( changingGroup, { ["lang"] = refer_lang, ["keyi18n"] = keyi18n, ["stri18n"] = stri18n, ["strnew"] = strnew, ["counts"] = "changing: " .. nkeys .. " / " .. nerr, ["modul"] = modul} ) nerr = nerr + 1 end end end end if nkeys > max then max = nkeys end end prev_lang = refer_lang prev_table = next_table end if nerr > 0 then err = events.add_err("versn_module_miss_i18n_count_err", nerr, max) t = t .. "<br>" .. err .. " " errors = errors .. err cats = cats .. events.add_cat("versn_err_module_miss_i18n_cat") else errors = errors .. " no errors " -- err = events.add_wng("versn_module_miss_i18n_none_err") end local tabView = { -- options for tableview.new(tabView) -- Form a table view with lines and columns. testGroup = changingGroup, langs_changing_translations_title = "langs.changing_translations() Changing (or missing) translations in i18n tables.", langs_changing_translations_headers = "Language; i18n Key; Previous translation; New translation; Module", title_memo = "langs_changing_translations_title", headers = "Language; Key; Translation; N errs / N keys, Module", headers = "langs_changing_translations_headers", -- CHANGING headers = "Language; Key; Previous translation; New translation; Module", headers = "Language; i18n Key; Previous translation; New translation; counts; Module", kind = "projects", -- mediawiki or projects typ = "err", rowGroup = {}, -- tests or tabView.testGroup or } -- tabView.headers = viewer.form9user("translate_changing_translations_headers") function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. return { case.lang, case.keyi18n, case.stri18n, case.strnew, case.counts, case.modul, }-- "Language; Key; Previous translation; New translation; Module" end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. errors = errors or " no errors " if errors ~= "" then errors = viewer.errorColor(errors) end t = t .. viewer.ta("#tabView.rowGroup", #tabView.rowGroup) -- Form a table with lines and columns. viewer.zzz_restore_configs(memo, "langs.changing_translations") -- Close a cats and errors table. For one test or main module. return t --, errors -- translate_missing_translations_title end -- function langs.changing_translations(t) function langs.missing_translations_init(t) -- Initialize the list of known translations, and their counts. local t = t or "" langs.known_translations = langs.known_translations or {} local i18n = langs.main_i18n or versn.main_i18n langs.known_langs = i18n langs.known_texts = {} langs.known_langs_maxi = 0 langs.known_texts_maxi = 0 for refer_lang, next_table in pairs(i18n) do -- For all languages and texts to translate if (type(other_trans) == "table") then langs.known_langs[refer_lang] = refer_lang t = t .. "\n* for refer_lang : " .. viewer.ta("refer_lang", refer_lang) .. viewer.ta("#next_table", lua_table.level_count(next_table) ) -- if (refer_lang == "fr") then -- and (lua_table.level_count(next_table) < 5 ) then for name, txt in pairs(next_table) do -- mix translations for 1 language in 1 library -- table.insert( langs.known_texts, { name = txt } ) langs.known_texts[name] = txt -- t = t .. viewer.ta("name", name) .. viewer.ta("#txts", #txts) end -- end -- Maximum number of languages t = t .. " end for : " .. viewer.ta("#langs.known_texts", lua_table.level_count(langs.known_texts) ) end end t = t .. "\n* i18n end: " .. viewer.ta("#langs.known_langs", lua_table.level_count(langs.known_langs) ) .. viewer.ta("#langs.known_texts", lua_table.level_count(langs.known_texts) ) if (langs.known_langs_maxi < #i18n) then langs.known_langs_maxi = #i18n end -- Maximum number of languages return t end function langs.missing_translations(t) -- List all missing translations local memo = viewer.zzz_save_configs("langs.missing_translations") -- Save global configuration before eventual changes. local t = t or "\n* <b>langs.missing_translations()</b>: List all missing translations: " local i18n = langs.main_i18n or versn.main_i18n local errors = "*" local changingGroup = {} local missingGroup = {} langs.translations_differences = langs.translations_differences or {} local nerr, trans, err = 0, "", "" local nbr, nbr_in_lang, list = 0, 1, "" local nbr_in_lang_limit = 4 local prev_table, next_table, max, nkeys = {}, {}, 0, 0 local lang, prev_lang, refer_lang, cats = "", "", "", "" local i18n = langs.main_i18n or versn.main_i18n local refer_stri18n, other_stri18n = "-" local count_known_texts = lua_table.level_count(langs.known_texts) local count_changingGroup = lua_table.level_count(changingGroup) local count_missingGroup t = t .. langs.missing_translations_init(t) -- Initialize the list of known translations, and their counts. t = t .. "\n* Insure next_table is OK: " nkeys = 0 local err_in_refer_lang, err_in_other_lang, err_in_refer_lang_limit = 0, 0, 5 for refer_lang, refer_trans in pairs(langs.known_langs) do -- for all languages if not ( (refer_lang == "en") or (refer_lang == "es") or (refer_lang == "fr") ) then -- small langs for tests debug t = t .. ", L=" .. refer_lang ..": n=".. lua_table.level_count(refer_trans) refer_trans = i18n[refer_lang] for other_lang, other_trans in pairs(langs.known_langs) do -- Look at all translations in one language, but check them only from 1 to nbr_in_lang_limit. if not ( (other_lang == "en") or (other_lang == "es") or (other_lang == "fr") ) then -- small langs for tests debug t = t .. ", O=" .. other_lang ..": n=".. lua_table.level_count(other_trans) if (type(other_trans) == "table") then -- if the translations in the alternate language is ok t = t .. ", nlt=" .. refer_lang for keyi18n, stri18n in pairs(refer_trans) do -- Look at all translations local cut = string.find(tostring(keyi18n) .. "_", "_") local modul = string.sub(keyi18n, 1, cut - 1) refer_stri18n = i18n[refer_lang][keyi18n] other_stri18n = i18n[other_lang][keyi18n] count_known_texts = lua_table.level_count(langs.known_texts) count_changingGroup = lua_table.level_count(changingGroup) -- if (err_in_refer_lang < err_in_refer_lang_limit) and not other_stri18n then -- if missing if (not other_stri18n) and (err_in_refer_lang < err_in_refer_lang_limit) then -- if missing err_in_refer_lang = err_in_refer_lang + 1 count_missingGroup = lua_table.level_count(missingGroup) + 1 local missing_case = { ["refer_lang"] = refer_lang, ["other_lang"] = other_lang, ["keyi18n"] = keyi18n, ["refer_stri18n"] = refer_stri18n, ["counts"] = viewer.form9user("counts missing=%1 / changing=%2 (err n=%3)", count_missingGroup, count_changingGroup, count_known_texts, err_in_refer_lang), ["modul"] = modul, } table.insert( missingGroup, missing_case ) t = t .. viewer.form9user( "\n* missing err: refer_lang=%1, other_lang=%2, missing=%3 / changing=%4, keyi18n=%5", refer_lang, other_lang, count_missingGroup, count_changingGroup, keyi18n) -- elseif (err_in_other_lang < err_in_refer_lang_limit) and (other_stri18n ~= refer_stri18n) then -- if changing elseif (other_stri18n ~= refer_stri18n) and (err_in_other_lang < err_in_refer_lang_limit) then -- if changing err_in_other_lang = err_in_other_lang + 1 count_changingGroup = lua_table.level_count(changingGroup) + 1 local counts = viewer.form9user("refer_lang=%1, other_lang=%2, counts changing=%1 / missing=%2, texts=%3", refer_lang, other_lang, count_changingGroup, count_missingGroup, count_known_texts, err_in_other_lang) local changing_case = { ["refer_lang"] = refer_lang, ["other_lang"] = other_lang, ["keyi18n"] = keyi18n, ["refer_stri18n"] = refer_stri18n, ["other_stri18n"] = other_stri18n, ["counts"] = counts, ["modul"] = modul, } -- case.keyi18n, case.other_stri18n, case.refer_stri18n, (case.counts or "counts"), } table.insert( changingGroup, changing_case ) t = t .. viewer.form9user( "\n* changing err: refer_lang=%1, other_lang=%2, changing=%3 / missing=%4, keyi18n=%5", refer_lang, other_lang, count_changingGroup, count_missingGroup, keyi18n) end end end end -- small langs for tests debug end end -- small langs for tests debug end local tabView = { -- options for tableview.new(tabView) -- Form a table view with lines and columns. testGroup = missingGroup, langs_missing_translations_title = "langs.missing_translations() Missing translations in i18n tables.", langs_missing_translations_headers = "Language; i18n Key; Previous translation; New translation; Module", title_memo = "langs_missing_translations_title", headers = "langs_missing_translations_headers", -- MISSING "Language; i18n Key; Previous translation; New translation; Module", headers = "Languages; missing Key; Previous translation; New translation; Module", kind = "projects", -- mediawiki or projects typ = "err", rowGroup = {}, -- tests or tabView.testGroup or } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. --[[table.insert( missingGroup, { ["lang"] = refer_lang, ["keyi18n"] = keyi18n, ["refer_stri18n"] = refer_stri18n, ["modul"] = modul, ["counts"] = viewer.form9user("counts missing=%1 / changing=%2 (err n=%3)", count_missingGroup, count_changingGroup, count_known_texts, err_in_refer_lang), } ) --]] return { (case.modul or "modul") .." : ".. (case.refer_lang or "lang") .."/".. (case.other_lang or "lang"), case.keyi18n, case.refer_stri18n, case.other_stri18n, (case.counts or "counts"), } -- headers = "Language; missing Key; Previous translation; New translation; Counts Module", end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. tabView.testGroup = changingGroup tabView.rowGroup = {} tabView.headers = "Language; changing Key; Previous translation; New translation; Counts Module" function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. --[[table.insert( changingGroup, { ["lang"] = refer_lang, ["keyi18n"] = keyi18n, ["stri18n"] = stri18n, ["modul"] = modul, ["counts"] = viewer.form9user("lang=%1, other_lang=%2, counts changing=%1 / missing=%2, texts=%3", count_changingGroup, count_missingGroup, count_known_texts, err_in_other_lang), } ) --]] local modul_refer_other = (case.modul or "modul") .." : ".. (case.refer_lang or "refer_lang") .."/".. (case.other_lang or "other_lang") return { modul_refer_other, case.keyi18n, case.other_stri18n, case.refer_stri18n, (case.counts or "counts"), } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "langs.missing_translations") -- Restore global configurations after eventual changes. return t --, errors -- langs_missing_translations_title end -- function langs.missing_translations(t) function langs.i18n_lister(t, i18n_tables) if type(i18n_tables) ~= "table" then i18n_tables = langs.main_i18n end local t = t or "\n* <b>i18n_lister</b> :" t = t .. viewer.errorColor("\n* <b>This list show all the string, but cannot replace the original declarations.</b> ") t = t .. viewer.errorColor("\n* <b>" .. viewer.form9user("langs_i18n_list_all_string") .. " </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 langs.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 langs.dummy_languages() -- Test dummy languages S170614tva -- 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'... langs.MetaSupportedLanguages = { "ja", "es", "ru", "de", "nl", "tr", "fr", "pt", "ko", "en", "it", "oc", "pl", "fa", "ar", "vi", "arz", "hi", "sv", "diq", "pt-br", "zh", "th", "bg", "hu", "uk", "en-gb", "sh", "id", "bn", "az", "fi", "be", "he", "eo", "el", "sd", "kn", "ro", "yue", "sr", "mk", "ta", "pa", "hy", "lb", "tt", "si", "yi", "ne", "cs", "sk", "ms", "eu", "mr", "sa", "tl", "eml", -- https://meta.wikimedia.org/wiki/Special:SupportedLanguages on 20170629 Rical } -- 58 languages in total. 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* langs.dummy_languages() : ' .. viewer.ta("isTag", "isKnownLanguageTag(xx)") .. viewer.ta("isLang", "isSupportedLanguage(xx)") .. viewer.ta("isBuilt", "isValidBuiltInCode(xx)") local tabView = { testGroup = { { "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 }, title_memo = "langs_dummy_languages_title", -- "lua_table.toList() Return a list from a Lua table.", headers = "langs_dummy_languages_headers", -- headers = " lang; isTag; isLang; isBuilt; langname; native ", -- rowGroup = {}, } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local lang, modname = case[1], case[2] 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 langs.selectLang local native = mw.language.fetchLanguageName(lang) local space_name = tostring(mw.site.namespaces.Module.name) return { lang, isTag, isLang, isBuilt, langname, native, } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. return t end -- function langs.dummy_languages() -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:lua_table enhances the support of previous table library from Lua. -- "lua_table" avoids ambiguities with other kind of tables. -- To enhance, we could write here : lua_table = table. -- see Extension:Scribunto/Lua reference manual : class nameTest extends Scribunto_LuaEngineTestBase -- - - - ------------------ - - - - --------------------------------- -- - - - ------------------ - - - - --------------------------------- -- lua_table = {} -- already declared by Scribunto, see centrobj.new() -- Record a library in package.loaded -- Translations for lua_table library lua_table.i18n = {} lua_table.i18n.en = { luaTable_recursive_luaTable_title = "Mediawiki recursive lua_table", luaTable_rough_view_tests_title = "viewer.rough_view() 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 = "lua_table.structure() List a table, test without limits:", luaTable_structure_limits_title = "lua_table.structure() List a table, test with limits:", luaTable_toList_tests_title = "lua_table.toList() Return a list from a Lua table.", luaTable_toList_tests_headers = "Tested case; Input table, rough_view; Output list", luaTable_toTable_tests_title = "lua_table.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_fromsubnames_base_err = "Internal error: in langs.sub_i18n_counts(), base unavailable for the subnames table %1.", luaTable_fromsubnames_subtable_err = "Internal error: in langs.sub_i18n_counts(), <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 lua_table.formSubCounts() The search for this sub-table <b>%1</b> found only this one <b>%2</b>.", luaTable_fromsubnames_tests_headers = "Sub name; Base table; Table count; Input viewer.rough_view", luaTable_table_dont_exists_err = "The table <b>%1</b> does not exist.", luaTable_table_args_source_title = "lua_table.structure() Table of received arguments, args_source:", luaTable_tables_differences_title = "testsgrp.resultdiffs() report differences between 2 tables.", } -- lua_table.i18n.en lua_table.i18n.es = { luaTable_recursive_luaTable_title = "Mediawiki lua_table recursiva", luaTable_rough_view_tests_title = "viewer.rough_view() 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 = "lua_table.structure() Enumerar una tabla, prueba sin límites:", luaTable_structure_limits_title = "lua_table.structure() Enumerar una tabla, prueba con límites:", luaTable_toList_tests_title = "lua_table.toList() Devolver una lista de una tabla Lua.", luaTable_toList_tests_headers = "Probados casos; Tabla a listar, ver prima; lista de salida", 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_fromsubnames_base_err = "Error interno: en langs.sub_i18n_counts(), base no disponible para la tabla subnames %1.", luaTable_fromsubnames_subtable_err = "Error interno: en langs.sub_i18n_counts(), %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 lua_table.formSubCounts() La búsqueda de este subtabla <b>%1</b> encontró que <b>%2</b>.", luaTable_fromsubnames_tests_headers = "Sub nombre; Mesa base; Tamaño de la mesa; viewer.rough_view de entrada", luaTable_table_dont_exists_err = "La tabla <b>%1</b> no existe.", luaTable_table_args_source_title = "lua_table.structure() Tabla de argumentos recibido, args_source:", luaTable_tables_differences_title = "testsgrp.resultdiffs() reportar diferencias entre 2 tablas.", } -- lua_table.i18n.es lua_table.i18n.fr = { luaTable_recursive_luaTable_title = "Mediawiki lua_table récursive", luaTable_rough_view_tests_title = "viewer.rough_view() 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 = "lua_table.structure() Lister une table, test sans limites :", luaTable_structure_limits_title = "lua_table.structure() Lister une table, test avec limites :", luaTable_toList_tests_title = "lua_table.toList() Retourne une liste à partir d'une table Lua.", luaTable_toList_tests_headers = "Cas testé; Table à lister, vue brute; Liste de sortie", luaTable_toTable_tests_title = "lua_table.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_fromsubnames_base_err = "Erreur interne: dans langs.sub_i18n_counts(), base indisponible pour la table subnames %1.", luaTable_fromsubnames_subtable_err = "Erreur interne: dans langs.sub_i18n_counts(), %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 lua_table.formSubCounts() La recherche de cette sous-table <b>%1</b> n'a trouvé que celle-ci <b>%2</b>.", luaTable_fromsubnames_tests_headers = "Sous-nom; Table de base; Taille de la table; Entrée viewer.rough_view", luaTable_table_dont_exists_err = "La table <b>%1</b> n'existe pas.", luaTable_table_args_source_title = "lua_table.structure() Table des arguments reçus, args_source :", luaTable_tables_differences_title = "testsgrp.resultdiffs() signaler les différences entre 2 tables.", } -- lua_table.i18n.fr function lua_table.tabfromsubnames(sub_names, base_table) -- Get the last sub-table from its sub-names. -- S170625ste sub_tab is bad, but it run if (type(base_table) ~= "table")then base_table = package.loaded end local sub_names = mw.text.split(sub_names, '%.') -- table of words local sub_tab = base_table for i, sub_name in ipairs(sub_names) do if (type(sub_tab) == "table") and (type(sub_tab[sub_name]) == "table") then sub_tab = sub_tab[sub_name] else sub_tab = nil end end return sub_tab end function lua_table.objfromsubnames(sub_names, base_table) -- Get the last sub-object from its sub-names. if (type(base_table) ~= "table")then base_table = package.loaded end local sub_names = mw.text.split(sub_names, '%.') -- table of words local sub_tab, sub_obj = base_table, nil for i, sub_name in ipairs(sub_names) do sub_obj = sub_tab[sub_name] if (type(sub_obj) == "table") then sub_tab = sub_obj else break end end return sub_obj end function lua_table.named_sub_counts(subnames_in, base_table) -- Count all objects of all types in all levels, in the sub-tables from their sub-names. local t = "\n* lua_table.named_sub_counts() Count all objects of all types in all levels" if (type(subnames_in) ~= "string") then subnames_in = "." end local base_table = base_table -- Do not disturb other processes through an external pointer. if (type(base_table) ~= "table") then base_table = package.loaded end -- luaTable_fromsubnames_base_err = "Internal error: in langs.sub_i18n_counts(), base unavailable for the subnames table %1.", local subnames, k = "", "" local count, pre_count, errs = 0, 0, ", errs: " local subnames_tab = mw.text.split(subnames_in, '.', true) local subnames_1 = subnames_tab[1] -- Default base_table for libraries and modules. -- if (type(base_table) ~= "table") then base_table = _G end -- Default base_table for not loaded libraries. if (type(base_table) ~= "table") and (type(subnames_1) == "string") and (type(_G[subnames_1]) == "table") then base_table = _G end -- if (type(base_table) ~= "table") then base_table = _G end local sub_table, object_loaded = base_table, sub_table local obj_typ, count, pre_count = "string", 0, 0 local counts, all_counts = {}, {} local pre_counts = nil local functions_c, numbers_c, strings_c, tables_c, last_count, all_strings, sub_tables_count = 0, 0, 0, 0, 0, 0, 0, 0 local isi18n, endi18n, to_break = false, false local max_string_count, max_tables_count, missing_trans = 0, 0, 0, 0 local loop = 1 for i, partname in pairs(subnames_tab) do loop = loop + 1 subnames = subnames .. "." .. partname object_loaded = sub_table[partname] obj_typ = type(object_loaded) all_strings = 0 functions_c, numbers_c, strings_c, tables_c, sub_tables_count = 0, 0, 0, 0, 0 endi18n = string.sub(subnames, -4, -1) -- Is this an i18n table? isi18n = (endi18n == "i18n") -- Is this an i18n table? if (type(object_loaded) == "table") then -- Count languages tables. if isi18n then -- Count languages tables. for key, val in pairs(object_loaded) do if (type(val) == "table") then tables_c = tables_c + 1 end loop = loop + 1 if loop > 99 then break end end sub_tables_count = 0 for key, val in pairs(object_loaded) do if (type(val) == "table") then sub_tables_count = sub_tables_count + 1 all_strings = all_strings + lua_table.count_all(val) end end else -- Count translations in this table. for key, val in pairs(object_loaded) do if (type(val) == "string") then strings_c = strings_c + 1 if strings_c > max_string_count then max_string_count = strings_c end elseif (type(val) == "number") then numbers_c = numbers_c + 1 elseif (type(val) == "function") then functions_c = functions_c + 1 end loop = loop + 1 if loop > 99 then break end end end -- local strs_on_tabs = all_strings / tables_c, ["subnames"] = subnames, obj = object_loaded, typ = obj_typ, local strs_on_tabs = math.floor( (all_strings + 0.49) / math.min(sub_tables_count, 1) ) -- 1/1 = 1.4/1 = 1 3/3 = 3.4/3 = 1.13 = 1 10/2 = 10.5/2 = 5.25 = 5 -- local c = counts counts = { ["i"] = i, ["partname"] = partname, ["subnames"] = subnames, ["object_loaded"] = object_loaded, ["obj_typ"] = obj_typ, ["isi18n"] = isi18n, ["endi18n"] = endi18n, ["tables_c"] = tables_c, ["strings_c"] = strings_c, ["numbers_c"] = numbers_c, ["functions_c"] = functions_c, ["booleans_c"] = booleans_c, ["all_strings"] = all_strings, ["max_string_count"] = max_string_count, ["pre_counts"] = pre_counts, ["all_counts"] = all_counts, -- details: ["strs_on_tabs"] = strs_on_tabs, ["missing_trans"] = missing_trans, -- special langs, remove here ["sub_tables_count"] = sub_tables_count, -- special langs, remove here, obsolete, replaced by pre_counts ["to_break"] = to_break, ["loop"] = loop, -- internal, anticrash and tests only } table.insert(all_counts, counts) -- Build a table with translations counts. if (type(pre_counts) == "table") and (type(counts) == "table") then counts.pre_counts = pre_counts pre_counts.post_counts = counts end pre_counts = counts counts.tt = viewer.form9user( "\n* counts: %1, %2, %3, %4, %5, %6.", counts.i, counts.partname, counts.endi18n, counts.strings_c, counts.tables_c, counts.all_strings) if loop > 99 then break end end t = (t or "t") .. (counts.tt or "counts.tt") --[[ modes.options_from_args_tests() Test des options de modes t = t .. "<br>" .. lua_table.formSubCounts("modes.i18n") counts.t counts: 1, modes, odes, 10, 0, 0. counts: 1, modes, odes, 10, 0, 0. --]] end local strs_on_tabs = math.floor( (strings_c + 0.49999) / math.min(tables_c, 1) ) counts.t = (t or "t") return strings_c, tables_c, strs_on_tabs, subnames, counts, all_counts, counts.t -- local strings_c, tables_c, strs_on_tabs, subnames, counts, all_counts, t = lua_table.named_sub_counts(subnames_in, base_table) end -- function lua_table.named_sub_counts(subnames_in, base_table) function lua_table.formSubCounts(subnames_in, tablebase, text_form) -- Form text of translations counts of a i18n table. local memo = viewer.zzz_save_configs("lua_table.formSubCounts") -- Save global configuration before eventual changes. if (type(text_form) ~= "string") then text_form = "langs_table_can_translate_counts" end local strings_c, tables_c, strs_on_tabs, subnames, counts, all_counts, t = lua_table.named_sub_counts(subnames_in, base_table) viewer.zzz_restore_configs(memo, "lua_table.formSubCounts") -- Restore global configurations after eventual changes. return t, strings_c, tables_c, strs_on_tabs, subnames, counts, all_counts -- local t, strings_c, tables_c, strs_on_tabs, subnames, counts, all_counts = lua_table.formSubCounts(tabname, tablebase, text_form) end function lua_table.count_all(tab) -- Count all objects in the table. local count = 0 for key, elem in pairs(tab or {}) do count = count + 1 end return count end function lua_table.count_types(tab) -- Count in the table, for each type, the number of objects of the this type. local types_counts = {} -- S170620csc for key, obj in pairs(tab or {}) do types_counts[type(obj)] = (types_counts[type(obj)] or 0) + 1 end return types_counts end function lua_table.count_values(tab) -- Count in the table, for each value, the number of objects of the this value. local values_counts = {} for key, obj in pairs(tab or {}) do values_counts[obj] = (values_counts[obj] or 0) + 1 end return values_counts end function lua_table.counts(obj, opt) -- Counts in object types -- local subtask = { "20170615", "20170616", "todo", "Rical", "S170616cow", "lua_table.counts(obj, opt) -- Counts in object types", } local t = t or "\n* <b>lua_table.counts()</b>: Counts in object types, where, what, how, sort." -- to_debug_on_20170503 tabView.t = tabView.t or "-" -- t = t .. viewer.ta("#testGroup", #tabView.testGroup) .. viewer.ta("#rowGroup", #tabView.rowGroup) t = t .. viewer.ta("count_done", count_done) .. viewer.ta("count_now", count_now) .. viewer.ta("count_later", count_later) local counts_fields = { -- define counts : caracterize available counts where_to_count = { "string table numbers function", }, -- Detect object type to count. Convert from function. where_to_count = { "tostring totable tonumbers", }, -- Convert asked totable() or tostring() or tonumber() which_part = { "coli coln colname rowi rown rowname", }, -- in which object part to count : column i, named row what_to_count = { "column_i column_n row_i row_n word_i word_n group_i group_n", }, -- count in the column_i. count column_n = the number of columns how_to_count = { "group_i group_n", }, -- group_i = number of objects in which_part how_to_sort = { "nosort 0to9 9to0 atoz ztoa", }, -- sort or no, in alpha or digital, increasing decreasing or none example_1 = { opt = "tostring ztoa", }, -- Count words in a string. Sort in reverse order. example_3 = { opt = "totable column_n", }, -- Convert to table or insure that. Count the number of columns. example_2 = { opt = "totable colname group_n 9to0", }, -- Convert to table. Count in column colname. Count in each group_n of values. Sort decreasing. } return count, t -- count can be a number, a list, a simple table, an array table of counts end -- count, t = lua_table.counts(obj, opt) -- Counts in object types function lua_table.toList(tab, ...) -- Return a list from any Lua table. -- 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 = lua_table.count_all(tab) local function tabN_to_list1(tab, n, ...) local max_tab = lua_table.count_all(tab) local listab = {...} local max_list = lua_table.count_all(listab) local tab_last = tab[n] -- last element, even a table to not delete below local tab_last_string = type(tab_last) -- tostring(tab_last) if (type(tab_last) ~= "nil") and (n <= max_tab) then if (type(tab) == "table") then return tab_last, tabN_to_list1(tab, n + 1, ...) else tab_last = tostring(tab_last) end else return end end return tabN_to_list1(tab, 1, ...) end -- function lua_table.toList(tab, ...) function lua_table.toList_tests(t) -- Return a list from a LUA table. local memo = viewer.zzz_save_configs("lua_table.toList_tests") -- Save global configuration before eventual changes. local t = t or "\n* <b>events.all_kinds_test()</b> Test: all kinds of events (err, wng, cat)" local tabView = { testGroup = { { "Simple table", { 123, "abc", key = "txt" }, }, { "All types transmited", { "name", 111, true, false, { 789, "xyz"}, function()end }, }, { "10 values in the table", { "a", "b", "c", "d", "e", "f", "g", "h", "i9", "j10" }, }, { "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" }, }, }, title_memo = "luaTable_toList_tests_title", -- "lua_table.toList() Return a list from a Lua table.", headers = "luaTable_toList_tests_headers", -- "Tested case; Input table, rough_view; Output list", } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local descript = case[1] local tabview = viewer.rough_view( case[2] ) local tab_list = { lua_table.toList( case[2] ) } local t1 = "" for i, elem in ipairs(tab_list) do t1 = t1 .. viewer.ta( "[" .. i .. "]", tostring(elem) ) end return { descript, tabview, t1, } end local t = tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "lua_table.toList_tests") -- Restore global configurations after eventual changes. return t --, errors -- langs_missing_translations_title end -- function lua_table.toList_tests(t) function lua_table.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 if plain then plain = true else plain = false end 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 -- not table.insert(tab2, name) end return tab2 end function lua_table.toTable_test(t) -- Test: convert a string to a table of words local memo = viewer.zzz_save_configs("lua_table.toTable_test") -- Save global configuration before eventual changes. local stringList = "" local t = t or "\n* lua_table.toTable_test(t) -- Test: convert a string to a table of words" local tabView = { testGroup = { { stringList = "docview nocatview : tests docline", pattern = nil, }, { stringList = "docview nocatview : tests docline", pattern = " ", plain = nil, }, { stringList = "docview,nocatview, : ,tests docline", pattern = ",", plain = true, }, { stringList = "docview docline : tests", pattern = " ", plain = true, }, { stringList = "docview; nocatview; : tests; docline", pattern = ";", plain = false, }, { stringList = "abc ; ; def.;ghi;,jkl", pattern = ";", }, }, headers = "langs_selectLang_test_headers", -- "stringList; pattern; plain; result" headers = "stringList; pattern; plain; result", } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local tab = lua_table.toTable(case.stringList, case.pattern, case.plain) local t1 = "" -- "lua_table.toTable : " .. viewer.ta( "#tab ", #tab ) for key, elem in pairs(tab) do t1 = t1 .. viewer.ta("[" .. viewer.value(key) .. "]", elem) end return { case.stringList, case.pattern, case.plain, t1, } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "lua_table.toTable_test") -- Restore global configurations after eventual changes. return t end -- function lua_table.toTable_test(t) -- local tot_vars, tot_tabs, tot_func, vr_tb = lua_table.SubCounts(tablebase, tabname, opt, recursiveLevel) function lua_table.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 -- lua_table.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 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 = lua_table.SubCounts(var, tabname, opt) opt.recursiveLevel = opt.recursiveLevel + 111 vr, tb, fn, vrtb = lua_table.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 -- string number in all languages else -- How many translations in each language? Approximative if not equal. vr_tb = tot_vars / tot_tabs -- string number in one language, like + 33.49 vr_tb = math.floor( vr_tb ) -- digital string 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 string 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 = lua_table.SubCounts(tablebase, tabname, opt, recursiveLevel) function lua_table.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 count end for k,v in pairs(tab) do count = count + 1 end return count end -- c = lua_table.level_count(tab) function lua_table.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 lua_table.level_get(tab, typ) function lua_table.level_list(tab, typ, select, field) -- Collect and count selected or all keys, in the first level of the table -- subtasks S170813lll -- typ = "key;val;keys;vals;sort;boolean;function;number;string;table;" -- Get only the first level of the table. Select only keys containing select. Select the field as key if defined. -- Collects and counts the selected keys, or all, in recording order -- Count the key of the typ type -- for T20170130 Begin to use local list, count, level, split, ok = "", 0, {}, {}, false local sort, keyval = typ, "" -- if sort == "sort" then typ = "string" end -- Select values by their type. 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 (typ == "key") then -- Count and list keys from select and field. sort, keyval = false, key if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. elseif (typ == "val") then -- Count and list values... sort, keyval = false, val if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. elseif (typ == "keys") then -- Count and sort keys... sort, keyval = true, key if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. elseif (typ == "vals") then -- Count and sort values... sort, keyval = true, val if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. elseif (typ == "sort") then -- Sort all values... sort, keyval = true, tab[field or 1] if viewer.is_in( tostring(keyval), tostring(select) ) then ok = true end -- Select a value if the val is in select. else -- lua_table.count_values() --[[ local list, count_done, level, split = lua_table.level_list(mw, "keys") -- , "string", "done", 3) -- S170621csc t = t .. "\n* list mw.* " .. list -- Library:lua_table function lua_table.level_list( t = t .. "\n* level_list mw " .. tostring(lua_table.level_list(mw, "keys") ) t = t .. "\n* count_all mw " .. tostring(lua_table.count_all(mw, "keys") ) t = t .. "\n* count_types mw " .. viewer.rough_view(lua_table.count_types(mw, "keys") ) t = t .. "\n* count_values mw " .. viewer.rough_view(lua_table.count_values(mw, "keys") ) t = t .. "\n* rough_view mw " .. viewer.rough_view(mw, {recursiveLimit = 1,}) -- function viewer.rough_view(table, option) opt.recursiveLimit --]] local typ2 = type(typ) -- To select a type or the type of a variable. if (typ2 == "boolean") or (typ == "boolean") then -- Count only these types. if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. elseif (typ2 == "function") or (typ == "function") then if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. elseif (typ2 == "number") or (typ == "number") then if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. elseif (typ2 == "string") or (typ == "string") then if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. elseif (typ2 == "table") or (typ == "table") then if viewer.is_in(keyval, select) then ok = true end -- Select a value if the val is in select. end end if ok then table.insert(split, keyval) -- Collect the selected keys, or all, in recording order count = count + 1 -- Count the key of the typ type list = list .. tostring(keyval) .. ", " -- List values end end if (sort == "sort") or (sort == true) then table.sort( split ) end -- in alphabetic order -- , function (a, b) end list = table.concat(split, ", ") return list, count, level, split end -- local list, count, level, split = lua_table.level_list(tab, typ, select, field) lua_table.level_list_tests( -- lua_table.count_values( -- title_memo = "luaTables_count_all_types_values_title", -- "lua_table.count_values() Count all objects or types or values in the table.", function lua_table.count_tests(t) -- Count all objects or types or values in the table local memo = viewer.zzz_save_configs("lua_table.count_tests") -- Save global configuration before eventual changes. local t = t or "\n* <b>lua_table.count_values()</b> Tests: Count all objects or types or values." local test_table = { "name", 111, "other", function() return 2 end, true, false, { 789, "xyz"}, function() return 1 end } local tabView = { testGroup = { { "count_all", { "name", 111, "other", function() end, true, false, { 33 }, function() end }, }, { "count_types", { "name", 111, "other", function() end, true, false, { 33 }, function() end }, }, { "count_values", { "name", 111, "other", function() end, true, false, { 33 }, function() end }, }, { "count_all", { a = "abc", 11, z = "xyz", t = true, false, n = nil, min = 11, 33, nil, 33, max = 55, "abc", }, }, { "count_types", { a = "abc", 11, z = "xyz", t = true, false, n = nil, min = 11, 33, nil, 33, max = 55, "abc", }, }, { "count_values", { "abc", 11, "xyz", true, false, nil, 11, 33, nil, 33, 55, "abc", }, }, { "level_list", { "abc", 11, "xyz", true, false, nil, 11, 33, nil, 33, 55, "abc", }, "key", "3", }, { "level_list", { "abc", 11, "xyz", true, false, nil, 11, 33, nil, 33, 55, "abc", }, "val", "3", }, { "level_list", { "abc", 11, "xyz", true, false, nil, 11, 33, nil, 33, 55, "abc", }, "keys", "3", }, { "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "vals", "bc", }, { "level_list", { "name", 111, "other", function() end, true, false, { 33 }, function() end }, "sort", }, -- local list, count, level, split = lua_table.level_list(tab, typ, select, field) -- typ = "key;val;keys;vals;sort;boolean;function;number;string;table;" { "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "boolean", "bc", }, { "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "function", "bc", }, { "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "number", "bc", }, { "level_list", { "abc", "bcd", "xyz", "bcbc", nil, 11, 33, nil, 33, 55, "abc", }, "string", "bc", }, { "level_list", { "abc", { "bcbc", nil }, "bcd", "xyz", { "tab1", "tab2" }, "abc", }, "table", "bc", }, { "level_list", "abcdefg", "table", "bc", }, { "level_list", 12345, "table", "bc", }, }, title_memo = "luaTables_count_all_types_values_title", -- "lua_table.count_values() Count all objects or types or values in the table.", headers = "luaTables_count_all_types_values_headers", -- "Tested case; Input table, rough_view; Output list", headers = "Tested table; Function to count; Kind of count; Resulting counts", } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup RIC05900470 local func_name = case[1] local test_table = case[2] local count_kind = case[3] if (type(test_table) ~= "table") then test_table = { test_table } end -- if (type(func_name) ~= "string") then test_table = { test_table } end local values_counts = lua_table[func_name](test_table) -- Select the function to test if (type(values_counts) ~= "table") then values_counts = { values_counts } end local tests_view = "" for key, val in pairs(test_table) do val = tostring(val) tests_view = tests_view .. viewer.ta(key, val) end local counts_view = "" for key, val in pairs(values_counts) do val = tostring(val) counts_view = counts_view .. viewer.ta(key, val) end return { tests_view, func_name, count_kind, counts_view } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "lua_table.count_tests") -- Restore global configurations after eventual changes. return t end -- function lua_table.count_tests(t) -- opt = { drop_opt.drop_opt = "drop_opt", level_maxi = 3, max_n = 2, exclude1 = "hou" } ) -- example of use , {width = "88%", tc1 = "blue"} function lua_table.normal_options(opt, recursiveLevel, recursiveLimit) -- Normalize lua_table options. if type(opt) ~= "table" then opt = {} end if type(opt.level_maxi) ~= "number" then opt.level_maxi = 111 end if type(opt.max_n) ~= "number" then opt.max_n = 9999 end opt.max_n = opt.max_n or 9999 opt.recursiveLevel = recursiveLevel or opt.recursiveLevel or 1 opt.recursiveLimit = recursiveLimit or opt.recursiveLevel or 111 opt.exclude1 = opt.exclude1 or "" opt.exclude2 = opt.exclude2 or "" opt.exclude3 = opt.exclude3 or "" opt.countonly = opt.countonly and true return opt end function viewer.rough_view(table) -- Form a string to describe a value like: true, 123.456, "abcd", func(), 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(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 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 = viewer.rough_view(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 -- t = viewer.rough_view(table) -- Form a string to describe a value like: true, 123.456, "abcd", func(), table{} function lua_table.rough_view(table) -- Form a string to describe a value like: true, 123.456, "abcd", func(), table{} versn.deprecatedFunction("lua_table.rough_view", "viewer.rough_view") return viewer.rough_view(table) end function viewer.rough_view_test(t) -- Form a rough LUA code of the table structure. local memo = viewer.zzz_save_configs("viewer.rough_view_test") -- Save global configuration before eventual changes. local t = t or "viewer.rough_view_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 .. viewer.rough_view(test_table) viewer.zzz_restore_configs(memo, "viewer.rough_view_test") -- Restore global configurations after eventual changes. return t end -- function viewer.rough_view_test(t) function lua_table.sort_onkey(tab, key) -- Sort a table with any types of keys. -- local tab = tab or {} -- keep table errors to permit to debug local key = key or "keyword" return table.sort(tab, function (a, b) if (type(a[key]) == type(b[key])) then return ( a[key] < b[key] ) -- any translated arguments of same types else return ( tostring(a[key]) < tostring(b[key]) ) end -- alphabetic sort of translated arguments end ) end function lua_table.sort_types(tab, key, decrease) -- Sort a table, with any types of fields, even of differents types as strings. if (type(tab) ~= "table") then return tab end if (type(key) ~= "string") then key = "keyword" end if decrease == ">" then -- sort in decreasing order table.sort(tab, function (a, b) if ( type(a[key]) == type(b[key]) ) then return ( a[key] > b[key] ) -- Sort same types else return (tostring(a[key]) > tostring(b[key]) ) end -- Sort differents types as strings end ) else -- sort in increasing order table.sort(tab, function (a, b) if ( type(a[key]) == type(b[key]) ) then return ( a[key] < b[key] ) -- Sort same types else return (tostring(a[key]) < tostring(b[key]) ) end -- Sort differents types as strings end ) end end -- function lua_table.sort_types(tab, key, decrease) function lua_table.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 = lua_table.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 lua_table.structure_recursive(tbl, uppername, name, recursiveLevel, opt) -- countonly, level_maxi, max_n, exclude1, exclude2, exclude3) -- - - - ------------------ - - - - --------------------------------- -- 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 -- opt = { drop_opt.drop_opt = "drop_opt", level_maxi = 3, max_n = 2, exclude1 = "hou" } ) -- , {width = "88%", tc1 = "blue"} function lua_table.structure(table, tablename, opt) -- luaTable_structure_limits_title = "List a table, test with limits:", local memo = viewer.zzz_save_configs("lua_table.structure") -- Save global configuration before eventual changes. 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 langs.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 = lua_table.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) viewer.zzz_restore_configs(memo, "lua_table.structure") -- Restore global configurations after eventual changes. return res, tot_vars, tot_func, tot_tabs end -- function lua_table.structure(table, tablename, opt) -- Auto test of limits of the table list. -- Auto test des limites de liste de table. lua_table.tablim = { "one", "two", max1 = "MAX1", max2 = "MAX2", max3 = "MAX3"} lua_table.tablim.life = { animal = "dog", vegetal = { big = "tree", small = "flower"} } lua_table.tablim.life.animals = { "turtle"} lua_table.tablim.comfort = { "tv", mobile = "car"} lua_table.tablim.house = { "kitcheen", "bedroom"} lua_table.tablim.house.garden = { flower = "rose", nature = "river"} -- opt = { drop_opt.drop_opt = "drop_opt", level_maxi = 3, max_n = 2, exclude1 = "hou" } ) -- , {width = "88%", tc1 = "blue"} -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- 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, see centrobj.new() -- Record a library in package.loaded 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_int2roman_tests_headers = "Digital number; Roman value; Correct; Error(s)", 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_int2roman_tests_headers = "Número decimal, Valor romana; Correcto; Error(es),", 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_int2roman_tests_headers = "Nombre décimal; Valeur romaine; Correct; Erreur(s)", 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. -- 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 -- S170606rmn 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)', ["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 -- S170606rmn local roman, 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"] = "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 -- S170606rmn local memo = viewer.zzz_save_configs("mathroman.roman2int_tests") -- Save global configuration before eventual changes. local t = t or "\n* " .. viewer.form9user("mathroman_roman2int_tests_title") -- t = t .. "<br>" .. lua_table.formSubCounts("mathroman.i18n") local tabView = { tests_title = "mathroman_roman2int_tests_title", -- "mathroman.roman2int() Test roman to digital numbers" testGroup = { { 123, }, { 2.78, }, { "-X", }, { "", }, { "0", }, { "MCXI", },{ "XIJ", }, { "XJI", }, { "XIA", }, { "VLD", }, { "IXC", }, { "MMMMCMXCIX", }, { "MMMMM", }, { "MMMMMYJXC", }, { {x}, }, { function()end, }, }, headers = "mathroman_roman2int_tests_headers", -- "Roman number; Digital value; Correct; Error(s)" rowGroup = {}, } tabView.t = (tabView.t or "") .. viewer.ta("roman2int_tests: ", "start") tabView.t = tabView.t .. viewer.ta("#testGroup: ", lua_table.level_count(tabView.testGroup) ) function tabView.form_one_case(case) -- 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. return { word, valX, wordX, errs .. " " .. errsX, } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "mathroman.roman2int_tests") -- Restore global configurations after eventual changes. return t end -- function mathroman.roman2int_tests(t) function mathroman.int2roman_test(t) -- Unitary tests of mathroman.int2roman local memo = viewer.zzz_save_configs("mathroman.int2roman_test") -- Save global configuration before eventual changes. local t = t or "\n* " .. viewer.form9user("mathroman_int2roman_tests_title") -- t = t .. "<br>" .. lua_table.formSubCounts("mathroman.i18n") local tabView = { tests_title = "mathroman_int2roman_test_title", -- "mathroman.int2roman() Test digital numbers to roman numbers" testGroup = { { -10, }, { 3.14, }, { "not-a-number", }, { "", }, { 0, }, { 12, }, { 17, }, { "18", }, { "19", }, { 111, }, { 444, }, { 555, }, { "777", }, { "1111", },{ "4999", }, { "5000", }, }, headers = "mathroman_int2roman_tests_headers", -- "Digital number; Roman value; Correct; Error(s)" rowGroup = {}, } tabView.t = (tabView.t or "") .. viewer.ta("int2roman_tests: ", "start") tabView.t = tabView.t .. viewer.ta("#testGroup: ", lua_table.level_count(tabView.testGroup) ) function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local val = case[1] -- DEBUG : mathroman.roman2int() can fail without blocking page. local wordX, errs = mathroman.int2roman(val, " ") -- DEBUG : mathroman.int2roman() can fail without blocking page. local valX, errsX = mathroman.roman2int(wordX) -- DEBUG : mathroman.roman2int() can fail without blocking page. return { val, wordX, valX, errs .. " " .. errsX, } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "mathroman.int2roman_test") -- Restore global configurations after eventual changes. return t end -- function mathroman.int2roman_test(t) -- 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"] = "mathroman.int2roman", group = mathroman.TestsCasesGroup, }, -- { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "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"] = "mathroman.int2roman", ["args"] = { 1 }, ["expect"] = { "I" }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 3 }, ["expect"] = { "III" }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 6 }, ["expect"] = { "VIII" }, }, -- { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "IV", }, ["expect"] = { 4 }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "V", }, ["expect"] = { 5 }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "III", }, ["expect"] = { 6 }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "VI", }, ["expect"] = { 6 }, }, --]] { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "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"] = "mathroman.int2roman", ["args"] = { 12, }, ["expect"] = { "XII" }, }, --[[ { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 17, }, ["expect"] = { "II" }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 3, }, ["expect"] = { "III" }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 4, }, ["expect"] = { "IX" }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 5, }, ["expect"] = { "V" }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 6, }, ["expect"] = { "VI" }, }, -- { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "I" }, ["expect"] = { 1 }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "II" }, ["expect"] = { 2 }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "III", }, ["expect"] = { 6 }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "VI", }, ["expect"] = { 123 }, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "V", }, ["expect"] = { 1 }, }, --]] { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "VIA", }, ["expect"] = { 6, "character AAA in 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"] = "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"] = "mathroman.int2roman", ["args"] = { 12 }, ["expect"] = { "XII" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 17 }, ["expect"] = { "XVII" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 18 }, ["expect"] = { "XVIII" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 111 }, ["expect"] = { "CXI" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 444 }, ["expect"] = { "CDXLIV" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 555 }, ["expect"] = { "DLV" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 777 }, ["expect"] = { "DCCLXXVII" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 1111 }, ["expect"] = { "MCXI" } }, --]] { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 4999 }, ["expect"] = { "MMMMCMXCIX" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 5000 }, ["expect"] = { "0", "value > 4999" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { -10 }, ["expect"] = { "X", "null value" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 0 }, ["expect"] = { "0", "null value" } }, --[[ { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { 3.14 }, ["expect"] = { "3.3.3" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { "not-a-number" }, ["expect"] = { "xxx" } }, --]] } 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"] = "mathroman.roman2int", ["args"] = { "-X" }, ["expect"] = { 10, "mathroman_char_X_in_N_err---1-" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "0" }, ["expect"] = { 0, "null value" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XIA" }, ["expect"] = { 11, "character A in 3" } }, --[ { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "" }, ["expect"] = { 0 } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XIJ" }, ["expect"] = { 12 } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XJI" }, ["expect"] = { 12, "X Y Z" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "XJI" }, ["expect"] = { 12, "mathroman_char_increase_err" } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "VLD" }, ["expect"] = { 445 } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "IXC" }, ["expect"] = { 89 } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MMMMCMXCIX" }, ["expect"] = { 4999 } }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MMMMM" }, ["expect"] = { 5000, "mathroman_J_before_end_err-XJI" } }, --]] { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "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"] = "mathroman.roman2int", ["args"] = { "XXIJ" }, ["expect"] = { 22 } }, -- { ["errorsKey"] = 2, ["modulename"] = "mathroman", funcname = 'recurse', group = mathroman.testsRecursive, }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 } }, -- { ["errorsKey"] = 2, ["modulename"] = "mathroman", funcname = 'recurse', group = mathroman.testsRecursive, }, } local func_example = { ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["errorsKey"] = 2, } local group_example = { ["name"] = "mathroman.roman2int.5", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", } mathroman.testsGroups = { -- Autotest cases to validate the mathroman library at mediawiki level. -- Each test_case defines a name, a function, an input, an output. { ["name"] = "mathroman", ["modulename"] = "mathroman", ["funcname"] = "runGroups", ["groupname"] = "mathroman.Tests_cases", }, -- { ["name"] = "mathroman", ["modulename"] = "mathroman", ["funcname"] = "runGroups", ["groupname"] = "mathroman.int2romanTests", }, -- { ["name"] = "mathroman", ["modulename"] = "mathroman", ["funcname"] = "runGroups", ["groupname"] = "mathroman.roman2intTests", }, -- -- modulename = "mathroman", ["funcname"] = "runGroups", ["groupname"] = "mathroman.testsRecursive", }, } -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- 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 supports 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, see centrobj.new() -- Record a library in package.loaded -- Translations for modes library modes.catView = "" -- = ":" to document a category rather than truly categorize it modes.i18n = {} -- 12 modes.i18n. modes.i18n.en = { -- 182 <tab>mode_... -- From here, TRANSLATE ONLY descriptions with a key like label_descr -- To translate, always keep -- 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.", -- Languages contentlang = "contentlang", contentlang_descr = "Language of the wiki.", pagelang = "pagelang", pagelang_descr = "Language of the page.", userlang = "userlang", userlang_descr = "Language of the page reader.", -- QITEM = 'QITEM', uri = 'uri', QITEM_descr = "Identifiant de donnée Wikidata, comme <code>Q535</code> pour Victor Hugo.", itemid = 'itemid', itemid_descr = "Identifiant de donnée Wikidata, comme <code>Q535</code> pour Victor Hugo.", itemid2 = 'id', itemid2_descr = "Identifiant de donnée Wikidata, comme <code>Q535</code> pour 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.", -- From here, DO NOT TRANSLATE function names ending with () like modes.used_options_list() -- Titles of tests modes_used_options_list_title = "modes.used_options_list() Options uses and short test", modes_options_uses_tests_title = "modes.options_from_mode_tests() Options uses and short test", modes_list_all_args_main_title = "modes.list_all_args_main() List of all accepted arguments", 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 string, 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_auto_val_warning_wng = "Verify the automatic arguments.", -- modes_assist_user_param_err = "User support for checking the settings:", 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_arguments_cat = "Module without known arguments table.", modes_no_known_arguments_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_args_unknown_report_title = "viewer.simpleList_test() Report unknown arguments", 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 string 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_args_known_report_title = "modes.args_known_report(t) Report of main known args.", modes_args_known_report_headers = "key;bind;typ;need;keyword;prop;format", } -- 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.", -- Languages contentlang = "contentlang", contentlang_descr = "Idioma del wiki.", pagelang = "pagelang", pagelang_descr = "Idioma de la página.", userlang = "userlang", userlang_descr = "Idioma del lector de la página.", -- QITEM = 'QITEM', uri = 'uri', QITEM_descr = "Nombre de los datos Wikidata, como <code>Q535</code> para Victor Hugo.", itemid = 'QITEM', 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.", -- -- Textos principales, errores y categorías de instrumentos modes_form_ok_categ_tests = "Test category generation OK", modes_form_ok_categ_tests = "Prueba generación categoría en OK", modes_form_ok_categ_tests = "Test de génération de catégorie OK", -- -- Titres des pruebas modes_used_options_list_title = "modes.used_options_list() Opciones de uso y prueba corta:", modes_options_uses_tests_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 argumentos automáticos.", -- modes_assist_user_param_err = "Apoyo al usuario para comprobar la configuración:", 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_arguments_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_args_unknown_report_title = "viewer.simpleList_test() Informar argumentos desconocidos", 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_args_known_report_title = "modes.args_known_report(t) Informe de los principales argumentos conocidos.", modes_args_known_report_headers = "clave; enlace; tipo; es necesario; palabra clave; datos; formato", } -- 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.", -- Languages contentlang = "contentlang", contentlang_descr = "Langue du wiki.", pagelang = "pagelang", pagelang_descr = "Langue de la page.", userlang = "userlang", userlang_descr = "Language du lecteur de la page.", -- QITEM = 'QITEM', uri = 'uri', 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', -- 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_list_title = "modes.used_options_list() Utilisation des options et petits tests:", modes_options_uses_tests_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 automatiques.", -- modes_assist_user_param_err = "Support aux utilisateurs pour vérifier les paramètres :", 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_arguments_cat = "Module sans table d'arguments connus.", modes_no_known_arguments_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_args_unknown_report_title = "viewer.simpleList_test() Signaler les arguments inconnus", 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_args_known_report_title = "modes.args_known_report(t) Rapport des principaux arguments connus.", modes_args_known_report_headers = "clé; lien; type; nécessaire; mot-clé; donnée; format", } -- modes.i18n.fr modes.i18n.br = { modes_args_known_report_title = "modes.args_known_report(t) Rapport des principaux arguments connus.", modes_args_known_report_headers = "clé; lien; type; nécessaire; mot-clé; donnée; format", } -- modes.i18n.br modes.i18n.de = { modes_args_known_report_title = "modes.args_known_report(t) Bericht der wichtigsten bekannten Argumente.", modes_args_known_report_headers = "Schlüssel; Link; Art; erforderlich; Stichwort; Daten; Format", } -- modes.i18n.de modes.i18n.hu = { modes_args_known_report_title = "modes.args_known_report(t) A legfontosabb ismert érvekről szóló jelentés.", modes_args_known_report_headers = "kulcs; kapcsolatot; fajtája; szükséges; kulcsszó; adatok formátum", } -- modes.i18n.hu modes.i18n.vi = { modes_args_known_report_title = "modes.args_known_report(t) Báo cáo của các đối số được biết đến chính.", modes_args_known_report_headers = "chính; liên kết; loại; cần thiết; từ khóa; dữ liệu; định dạng", } -- modes.i18n.vi -- - - - ------------------ - - - - --------------------------------- -- 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 = " box1 ", edit = " box1 docdef docline docsrc docdata catview docview : ", doc = " nobox1 noerr nocatview ", tests = " box1 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 nobox1 nocatview " -- do not form normal result -- modes.options = " debug tests en es fr " -- enforce a language for debug -- Option nocatview means "Do not categorize and do not show categories." } -- Manage Library:modes options. Administrar opciones. Gérer les options. modes.template_options = "" -- Normal options from the template, like {{Bananas|options=docmax docdef}}. modes.mode_options = "" -- Internal options from the mode. modes.available_options = "" -- table to collect all available options, at any time. modes.used_options = {} -- table to collect really or tested options then list them at end of tests. mathroman.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. [1] = {need = 0, syn = 2, keyword = "mode"}, -- Special arguments to modify the fonctions and outputs of this 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. contentlang = {typ = "config", need = 1, keyword = "contentlang"}, pagelang = {typ = "config", need = 2, keyword = "pagelang"}, userlang = {typ = "config", need = 0, keyword = "userlang"}, birthyear = {typ = "dat", need = 0, keyword = "birthyear", prop = "P569", format = "year"}, } function modes.bind_args_known_props(args_known, args_new) -- Bind known args and their properties for central libraries. Later for modules. -- for function versn.init() or function Central.init() or any upper centrobj local args_known = args_known or modes.args_known or p.args_known if (type(args_known) ~= "table") then return {} end -- modes.args_known = mathroman.args_known_one_lib(modes.args_known, versn.central_libraries_sort) local args_known_one = {} if (type(args_new) ~= "table") then return args_known end for key, props in pairs(args_new) do -- import and mix known args and properties if (type(props) == "table") then args_known_one[key] = props or args_known[key] props.key = key end -- Add properties for a new argument end return args_known_one end -- local args_known_props = modes.bind_args_known_props(args_known, args_new) function modes.args_known_one_lib(args_known, args_new) -- Bind known args and their properties for central libraries. Later for modules. -- for function versn.init() or function Central.init() or any upper centrobj local args_known = args_known or p.args_known or modes.args_known -- local central_libraries_sort = central_libraries_sort or versn.central_libraries_sort if (type(args_known) ~= "table") then return {} end local args_known_props = {} for key, one_lib in pairs(args_new) do -- import and mix known args and properties if (type(one_lib) == "table") then -- args_new = central_library.args_known bind_args = modes.bind_args_known_props(args_known, args_new) args_known_props = modes.bind_args_known_props(modes.args_known, args_new) end end -- modes.args_known_props = args_known_props -- do not break modes.args_known return args_known_props end -- function modes.args_known_one_lib(args_known, args_new) function modes.bind_args_known_one_lib_report(t) -- Report the binding of one library known args. local memo = viewer.zzz_save_configs("modes.bind_args_known_one_lib_report") -- Save global configuration before eventual changes. local t = t or "\n* mathroman.args_known_one_lib(t) Report the binding of one library known args." -- mathroman.args_known_one_lib(args_known, obji18n_list) local args_known_props = modes.args_known_one_lib(modes.args_known, mathroman.args_known) t = t .. "\n* " .. viewer.ta("#args_known_props", #args_known_props) if (type(args_known) ~= "table") then return args_known end -- modes.args_known = args_known local tabView = { testGroup = args_known, rowGroup = {}, form_one_case = function(case) -- Convert a case from testGroup to rowGroup. return { viewer.value(case.key), case.bind, case.typ, case.need, case.keyword, case.prop, case.format, } end, title_memo = "modes_bind_args_known_report_title", title_memo = "modes.bind_args_known_one_lib_report(t) Report the binding of one library known args. **", headers = "modes_bind_args_known_report_headers", headers = "key;bind;typ;need;keyword;prop;format", } t = t .. "<br/>" .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "modes.bind_args_known_one_lib_report") -- Restore global configurations after eventual changes. return t end -- function modes.bind_args_known_one_lib_report(t) function lua_table.sort_onkey(tab, key) -- Sort a table with any types of keys. -- local tab = tab or {} -- keep table errors to permit to debug local key = key or "keyword" return table.sort(tab, function (a, b) if (type(a[key]) == type(b[key])) then return ( a[key] < b[key] ) -- any translated arguments of same types else return ( tostring(a[key]) < tostring(b[key]) ) end -- alphabetic sort of translated arguments end ) end function modes.args_known_report(t, args_known) -- Report of main known args. local memo = viewer.zzz_save_configs("modes.args_known_report") -- Save global configuration before eventual changes. local t = t or "\n* modes.args_known_report(t) Report of main known args." local args_final = args_final or versn.main_module.args_final or modes.args_final or p.args_final -- modes.args_final = { -- p.args_final = { local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = { } if (type(args_final) ~= "table") then return t .. "\n* Error: none main finals args." end local key_props = 0 t = t .. "\n* " .. DAT.t local args_props = {} for key, props in pairs(args_known) do -- props = args_known[key] or {} local props = props or {} props[key] = key props.keyword = key props.val = datas.props[key] or "-" table.insert(args_props, props) -- if props.prop then table.insert(args_props, props) end end table.sort(args_props, function (a, b) return (a.keyword < b.keyword) end ) -- alphabetic sort of translated arguments lua_table.sort_types(args_props, "keyword", "<" ) -- alphabetic sort of translated arguments t = t .. "\n* " .. viewer.ta("#modes.args_known", lua_table.level_count(args_props) ) local tabView = { testGroup = args_props, -- tabView.testGroup or rowGroup = {}, form_one_case = function(case) -- Convert a case from testGroup to rowGroup. tabView.form_one_case or return { case.key, case.val, case.typ, case.need, case.keyword, case.syn, case.prop, case.format, } end, -- ["birthyear"] = {typ = "dat", need = 0, keyword = "birthyear", prop = "P569", format = "year"}, title_memo = "modes.args_known_report(t) Report of main known args. **", title_memo = "modes_args_final_report_title", headers = "modes_args_final_report_headers", headers = "key;val;typ;need;keyword;syn;prop;format", } t = t .. "<br/>" .. tableview.new(tabView) -- Form a table view with lines and columns. --] ] viewer.zzz_restore_configs(memo, "modes.args_known_report") -- Restore global configurations after eventual changes. return t end -- function modes.args_known_report(t, args_final) function versn.bind_central_objects(t) -- Bind all central objects. --[[ GUIDELINE to bind all central objects: Objects to bind: libraries, then from inner sub-modules to the main module, following the tree of sought sub-modules. For each object, bind modes, arguments and i18n translations. Until which level: keep the properties of each argument which are coherent between themselves. --]] local t = t or "\n* versn.bind_central_objects(t) Bind all central objects." versn.bind_libraries(t) versn.bind_sub_modules(t) versn.bind_main_module(t) return t end -- function versn.bind_central_objects(t) function versn.bind_one_central_objects(t) -- Bind all central objects. --[[ GUIDELINE to bind all central objects: For each object, bind modes, arguments and i18n translations. Until which level: keep the properties of each argument which are coherent between themselves. --]] local t = t or "\n* versn.bind_central_objects(t) Bind all central objects." versn.bind_one_library(t) versn.bind_one_sub_module(t) versn.bind_main_module(t) return t end -- function versn.bind_central_objects(t) function modes.trackOptions(where, select_track) if modes.select_track then return "" end -- if modes.select_track then modes.select_track = select_track end -- if select_track then mask all next modes.trackOptions(). local t = viewer.form9user("\n* trackOptions where=%1, mode_options=%2, template_options=%3", where, modes.mode_options, modes.template_options) modes.report_trackOptions = (modes.report_trackOptions or"") .. t return "" -- t or "" end function modes.init_options(template_options) -- modes.template_options = modes.init_options(args.options) -- modes.template_options = modes.init_options("fr params docview docmin docmax docdef docnotice docafter docline docsrc") if (type(template_options) == "string") then modes.template_options = template_options end if (type(modes.template_options) ~= "string") then modes.template_options = "" end -- 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 nobox1 nocatview " -- 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(versn.i18n) do if modes.option(lang) then langs.init_languages(langs.content_lang, xx, yy, lang) -- langs.content_lang, langs.user_lang end end return modes.template_options end -- function modes.init_options(template_options) 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" modes.mode_name = mode_name or modes.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.template_options or "") .. " " local available_options = (modes.template_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 = 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 = viewer.zzz_save_configs("modes.options_from_mode_tests") -- Save global configuration before eventual changes. local t = tostring(t) local t = t or "options_from_mode_test:" for md, opt in pairs(modes.options_for_modes) do t = t .. "<br>- " .. viewer.ta(md, opt) end -- S170614tva 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() viewer.zzz_restore_configs(memo, "modes.options_from_mode_tests") -- Restore global configurations after eventual changes. return t end -- function modes.options_from_mode_tests(t) function modes.used_options_list(t, used_options) local t = t or "List of modes:" used_options = used_options or modes.used_options -- modes.mode_name = modes.mode_name modes.mode_name = mode_name or modes.mode_name or "read" 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 .. "\n* " .. viewer.form9user("langs_content_page_user_lang_msg", langs.user_lang, langs.content_lang) -- ( or viewer.form9user("langs_content_page_user_lang_msg", langs.user_lang, langs.content_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.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.options_from_args_tests(t) local memo = viewer.zzz_save_configs("modes.options_from_args_tests") -- Save global configuration before eventual changes. local mode_options_memo = modes.mode_options -- save local template_options_memo = modes.template_options -- save local used_options_memo = mw.clone(modes.used_options) -- save modes.used_options = {} -- for test local t = tostring(t) t = t or "options_from_args_tests:" t = t .. "<br>" .. lua_table.formSubCounts("modes.i18n") -- S170614tva t = t .. viewer.Th() .. viewer.Tc("mode_options") .. viewer.Tc("template_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, template_options, opt, key, verif) modes.available_options = "" modes.mode_options = mode_options or "" modes.template_options = template_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( template_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("nobox1 nocatview", "en docview", nil, "nobox1", "true") t = t .. options_from_args("nobox1 nocatview", "en docview", nil, "nocatview", "true") t = t .. options_from_args("nobox1 nocatview", "en docview", nil, "en", "true") t = t .. options_from_args("nobox1 nocatview", "en docview", nil, "docview", "true") t = t .. options_from_args("nobox1 nocatview", ": docview", nil, ":", "true") t = t .. options_from_args("nobox1 nocatview", "en docview", "docline fr", "docline", "false") t = t .. options_from_args("nobox1 nocatview", "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("nobox1 nocatview", nil, "docline fr", "docline", "false") t = t .. options_from_args("nobox1 nocatview", "en docview", "docline fr", nil, "true") t = t .. options_from_args("nobox1 nocatview", "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.template_options = template_options_memo -- restore modes.used_options = used_options_memo -- restore viewer.zzz_restore_configs(memo, "modes.options_from_args_tests") -- Restore global configurations after eventual changes. return t end -- function modes.options_from_args_tests(t) --[[ 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_template = {} -- Template arguments, at {{Template| ... }} level modes.args_source = {} -- Source arguments = args_template modes.args_unknown = {} -- Unknown arguments modes.args_mixed = {} -- Mixed 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 langs.content_translations = {} -- Wiki translations langs.user_translations = {} -- User translations versn.loaded_pack = {} -- loaded packages of modules and libraries versn.loaded_vers = {} -- loaded versions of modules and libraries --]] function modes.change_itemid(id_in) -- Select a wikidata default item if needed. -- modes.args_source.itemid = id -- always inforce modes.change_itemid() -- modes.args_source.QITEM = id -- always inforce modes.change_itemid() local id = "" if id_in then -- Local function parameter have priority. id = id_in else -- Else use the template arguments or inforce QITEM here. id = modes.args_source.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() modes.main_title = mwtitle.text -- Server mw.uri.new local nsX = mw.title.getCurrentTitle():inNamespaces("10", "11", "828", "829") local nsX = mwtitle:inNamespaces("10", "11", "828", "829") local ns = tostring(mw.site.namespaces.id) if viewer.is_in_sp(ns, "10;11;828;829", ";") then -- Change QITEM only where title cannot be in wikidata. id = id or modes.main_title or modes.args_source.title or modes.args_source.QITEM or modes.args_source.label or modes.args_source.itemid modes.args_source.title = id modes.args_source.QITEM = id end 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 DEBUG : S170606aks 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) -- S170720t_G: On 20170720, versn.list_all_G_and_loaded() shows a variable "t" in _G space, for months. -- S170720t_G: This debug needs much time because there are many "t" variables. On 20170720, Rical stop the search from line 1 to line 4303. 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 if (type(word1) ~= "string") or (type(word2) ~= "string") 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 if (type(search) ~= "string") then search = "" end local diffmaxi = modes.similar_args_diffmaxi( string.len(search) ) local len1, len2, lev, tlev, diff local t = "" -- 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 = viewer.zzz_save_configs("modes.similar_levenshtein_tests") -- 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 viewer.zzz_restore_configs(memo, "modes.similar_levenshtein_tests") -- 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(langs.content_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 if (type(search) ~= "string") then search = "" end 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 local 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 = viewer.zzz_save_configs("modes.similar_args_search_tests") -- 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 local 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 = langs.content_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"}) viewer.zzz_restore_configs(memo, "modes.similar_args_search_tests") -- 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. -- local ... = modes.multiple_values(test.argm, test.argvalue, test.args_final) 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 = langs.content_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 tabView = {} tabView.headers = viewer.form9user("argm; all values; value; keyword; keyval; argval; rank") tabView.testGroup = group_test tabView.rowGroup = {} if type(group_test) == "table" then for i, test in ipairs(group_test) do local keyword, keyval, argval, rank, arg_values = modes.multiple_values(test.argm, test.argvalue, test.args_final) table.insert( tabView.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 .. tableview.new(tabView) -- Form a table with lines and columns. -- t = t .. viewer.tableView{ -- Form a table with lines and columns. -- headers = viewer.form9user("argm; all values; value; keyword; keyval; argval; rank"), -- testGroup = group_test, -- } 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 = viewer.zzz_save_configs("modes.multiple_selection_tests") -- 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") -- S170614tva local function multiple_selection_test1(t, opt, selector, to_select) local selected_txt, selected_tab, txt = modes.multiple_selection(opt, selector, to_select) local 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() viewer.zzz_restore_configs(memo, "modes.multiple_selection_tests") -- 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 _known = modes.args_known end -- if type(_source) ~= "table" then _source = modes.args_source end if type(modes.args_known) ~= "table" then events.add_err("modes_no_known_arguments_err") events.add_cat("modes_no_known_arguments_cat") return viewer.errorColor(" Internal error : no source or no known arguments ! ") 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.mix_args(mix, mode_name, args_template) -- Mix arguments from options_for_modes, args_template S170710mix local mix = mix or {} modes.mix = mix -- Get basic values modes.frame = mw.getCurrentFrame() modes.args_template = modes.frame:getParent().args -- mix -- mix.args_template = args_template or mix.args_template or modes.args_template or {} mix.all_args = {} local function mix_args(args) if (type(args) ~= "table") then args = {} end for key, argmnt in pairs(args) do mix.all_args[key] = argmnt end end -- actual steps to mix -- begin with least priority mix_args(modes.args_template) mix_args(mix.args_template) mix_args(mix.args_import) mix_args(args_template) -- end with most priority MAMO.add(MAMO, 1, "mix.all_args", mix.all_args ) mix.args = mix.all_args return mix end -- local mix = modes.mix_args(mix, mode_name, args_template) function modes.mix_modes(mix, mode_name, args_template) -- Mix some modes from several origins S170710mix mix = mix or {} mix.args_template = args_template or modes.args_template or mix.args_template if (type(mix.args_template) ~= "table") then default = "read" end -- Mix modes values mix.mode_name = mix.args_template.mode or mix.args_template[1] or mode_name or "read" modes.args_template = mix.args_template modes.mode_name = mix.mode_name MAMO.add(MAMO, 1, "modes.mode_name", { ["mode_template"] = modes.args_template.mode, ["modes.mode_name"] = modes.mode_name } ) return mix end -- local mix = modes.mix_modes(mix, mode_name, args_template) function modes.mix_options(mix, old_group, new_group) -- Mix 2 groups of options from diverse origins S170710mix mix = mix or {} if (type(old_group) ~= "string") then old_group = "" end if (type(new_group) ~= "string") then new_group = "" end local old_group_tab = mw.text.split(old_group, " ", true) local new_group_tab = mw.text.split(new_group, " ", true) local all_group_tab = mw.clone(old_group_tab) -- do not disturb old_group_tab for i, option in ipairs(new_group_tab) do table.insert(all_group_tab, option) end -- add new with old options local no_options_tab, active_options_tab = {}, {} for i, option in ipairs(all_group_tab) do -- form 2 groups of no_options and active_options local no_t, opt_t = string.sub( option, 1, 2), (string.sub( option, 3) or "") -- no prefix and option without no if ( no_t == "no" ) then no_options_tab[option] = opt_t -- form a group of no_options, perhaps to delete an active option else active_options_tab[option] = option -- form a group of active_options, perhaps to delete end end local keep_group_tab = mw.clone(all_group_tab) -- Reject no_options to keep active_options for i, option in pairs(active_options_tab) do if ( no_options_tab[option] ) then active_options_tab[option] = nil -- form a group of active_options, perhaps to delete end end mix.active_options = table.concat(active_options_tab, " ") mix.no_options = table.concat(no_options_tab, " ") return mix end -- active_options = modes.mix_options(old_group, new_group) -- S170710mix -- { "20170710", "20170711", "now", "Rical", "S170710mix", "Optimize modes.import_args_mode_options() in modes.init_args_mode_options()", }, -- modes.init_args_mode_options(mix, mode_name, args_template) -- Import and mix args mode and options from template and invoke -- S170710mix function modes.init_args_mode_options(mix, mode_name, args_template) -- Import and mix args mode and options from template and invoke -- S170710mix -- Guideline: Any combination of options can define a mixture of options to modify options. -- This function allows any module to modify this process. -- The default process gives the priority to options from arguments. -- Each option can be deleted by the nooption option. Then options begining by "no" are forbiden. -- Mix modes values MAMO = tracker.initadd({ ["name"] = "MAMO", limit = 2, }) -- Initialize a track MAMO.add(MAMO, 1, "modes.init_args_mode_options", { ["mode_name"] = mode_name, } ) -- MAMO.t -- Init basic values local mix = mix or {} modes.mix = mix mix.mode_name = mode_name or mix.mode_name or modes.mode_name -- Steps to mix -- Once run mix_args and mix_modes, in case a mode option would change the mode. mix = modes.mix_args(mix, mode_name, args_template) -- Mix arguments from options_for_modes, args_template MAMO.add(MAMO, 1, "mix_args1", mix.args ) -- MAMO.t mix = modes.mix_modes(mix, mode_name, args_template) -- Mix some modes from several origins S170710mix MAMO.add(MAMO, 1, "mix_modes1", mix.args ) -- MAMO.t -- { "20170710", "20170711", "now", "Rical", "S170710mix", "Optimize modes.import_args_mode_options() in modes.init_args_mode_options()", }, modes.options = modes.options_for_modes[modes.mode_name] -- options from mode -- -- Once repeat mix_args and mix_modes, in case the mode changes through them. mix = modes.mix_args(mix, mode_name, args_template) -- Mix arguments from options_for_modes, args_template MAMO.add(MAMO, 1, "mix_args2", mix.args ) -- MAMO.t mix = modes.mix_modes(mix, mode_name, args_template) -- Mix some modes from several origins S170710mix -- { "20170710", "20170711", "now", "Rical", "S170710mix", "Optimize modes.import_args_mode_options() in modes.init_args_mode_options()", }, MAMO.add(MAMO, 1, "mix_modes2", mix.args ) -- MAMO.t modes.options = modes.options_for_modes[modes.mode_name] -- options from mode -- MAMO.add(MAMO, 1, "modes.options_for_modes", { ["mode.options"] = modes.options } ) mix = modes.mix_options(mix, modes.options, modes.args_template.options ) -- Mix options from template MAMO.add(MAMO, 1, "modes.mix_options args_template", mix.options ) -- MAMO.t modes.options = mix.options -- MAMO.add(MAMO, 1, "itemid to QITEM", { ["itemid"] = modes.args_template.itemid, ["QITEM"] = modes.args_template.QITEM, }) -- form_result MAMO.t -- activate init_args_mode_options modes.list_invoke = mix.list_invoke or modes.list_invoke modes.list_template = mix.list_template or modes.list_template modes.args_template = mix.args_template or modes.args_template modes.mode_template = mix.mode_template or modes.mode_template or modes.args_template.mode modes.active_options = mix.active_options or modes.active_options modes.no_options = mix.no_options or modes.no_options or table.concat(no_options_tab, " ") modes.options_template = mix.options_template or modes.options_template or modes.args_template.options modes.mode_name = mix.mode_name or modes.mode_name modes.options_for_modes = mix.options_for_modes or modes.options_for_modes modes.options = mix.options or modes.options MAMO.add(MAMO, 1, "mix.no_options", mix.no_options ) -- MAMO.t MAMO.add(MAMO, 1, "mix.active_options", mix.active_options ) -- MAMO.t MAMO.add(MAMO, 1, "mix.options", mix.options ) -- MAMO.t MAMO.add(MAMO, 1, "modes.options" , modes.options ) -- res = res .. MAMO.t return mix end -- modes.args_mixed = function modes.init_args_mode_options(mix, mode_name, args_template) function modes.args_mixer(args_template) -- S170703amo -- Guideline: Any combination of templates can define a mixture of arguments to modify arguments. -- This function allows any module to modify this process. -- The default process gives the priority to templates arguments. local t = "\n* <b>modes.args_mixer()</b> Import and mix arguments from templates and invoke." local args_template = args_template or modes.args_template or {} IAMO.add(IAMO, 1, "args_mixer", args_template ) -- IAMO.t t = t .. "\n* " .. viewer.ta("\n* args_template", args_template) if (type(args_template) == "table") then for arg_key, argment in pairs(args_template) do args_template[arg_key] = argment -- sought args from templates args_template.QITEM = args_template.QITEM or args_template.itemid -- temporary debug the test page t = t .. viewer.ta(arg_key, argment) IAMO.add(IAMO, 1, ",IAMO: ", { [arg_key] = argment } ) -- IAMO.t if arg_key == "itemid" then t = t .. viewer.ta("QITEM", argment) end -- temporary debug the test page end end args_template.QITEM = args_template.QITEM or args_template.itemid -- temporary debug the test page viewer.TITL = tracker.initadd({ ["name"] = "TITL", limit = 2, }) -- Initialize a track TITL.add(TITL, 1, "args_mixer", args_template ) -- TITL.t -- Activate the sought args modes.args_mixed = args_template t = t .. viewer.ta("modes.args_mixed count", lua_table.count_all(modes.args_mixed) ) IAMO.add(IAMO, 1, "args_mixer end", { ["#args_mixed"] = lua_table.count_all(modes.args_mixed) } ) -- IAMO.t return modes.args_mixed end -- local t = modes.args_mixer(args_template) function modes.modes_mixer(args_template) -- S170703amo local t = "" args_template = args_template or modes.args_template -- IAMO.add(IAMO, 1, "modes_mixer", args_template ) -- IAMO.t t = t .. viewer.ta("modes.args_template[1]", modes.args_template[1]) .. viewer.ta("modes.args_template.mode", modes.args_template.mode) -- Activate the sought mode modes.mode_name = modes.args_template.mode or modes.args_template[1] -- modes.args_sources.mode_name = modes.mode_name modes.args_mixed.mode_name = modes.mode_name t = t .. viewer.ta("sought mode_name", modes.mode_name) IAMO.add(IAMO, 1, "modes_mixer end", { mode = modes.mode_name } ) -- IAMO.t -- modes.mode_name return t, modes.mode_name end -- local t = modes.modes_mixer(args_template) function modes.options_mixer(args_template) -- S170703amo -- Guideline: Any combination of options can define a mixture of options to modify options. -- This function allows any module to modify this process. -- The default process gives the priority to options from arguments. -- Each option can be deleted by the nooption option. Then options cannot begin by "no" chars. -- -- First, import args, then mix modes and options. local t = "\n* <b>modes.options_mixer()</b> Import and mix options from template." -- modes.options = " docdata docmin docdef docmax docline docview docafter docnotice docsrc: " -- for documentation modes.options_template = modes.args_template.options or " catview nobox1 doclist docdata nodocline" modes.options_all = modes.options_template .. " " .. modes.options_invoke t = t .. viewer.ta("\n* options_template", modes.options_template ) t = t .. viewer.ta("\n* options_invoke", modes.options_invoke ) modes.options_tab = mw.text.split(modes.options_all, " ", true) local opt_pretab, opt_tab, noopt_tab, opt_list = {}, {}, {}, " " for i, option in pairs(modes.options_tab) do -- Build the subgroup table from the groupname string -- opt_tab[option] = option local no_t, opt_t = string.sub( option, 1, 2), string.sub( option, 3) if ( no_t == "no" ) then noopt_tab[option] = opt_t -- no_option to delete an active option else opt_pretab[option] = option end -- active option end local lst = "" ; for key, val in pairs(modes.options_tab) do lst = lst .. viewer.ta(key, val ) end t = t .. viewer.ta("\n* #modes.options_tab", lua_table.count_all( modes.options_tab ) ) .. viewer.ta("options_tab", lst ) IAMO.add(IAMO, 1, "#modes.options_tab" .. lua_table.count_all(modes.options_tab), modes.options_tab ) -- IAMO.t -- t = t .. viewer.ta("\n* #modes.options_tab", lua_table.count_all( modes.options_tab ) ) .. viewer.ta("options_tab", viewer.rough_view( modes.options_tab ) ) -- local lst = "" ; for key, val in pairs(opt_pretab) do lst = lst .. viewer.ta(key, val ) end t = t .. viewer.ta("\n* #opt_pretab", lua_table.count_all( opt_pretab ) ) .. viewer.ta("opt_pretab", lst ) IAMO.add(IAMO, 1, "#opt_pretab = " .. lua_table.count_all(opt_pretab), opt_pretab ) -- IAMO.t -- t = t .. viewer.ta("\n* #opt_pretab", lua_table.count_all( opt_pretab ) ) .. viewer.ta("opt_pretab", viewer.rough_view( opt_pretab ) ) -- local lst = "" ; for key, val in pairs(noopt_tab) do lst = lst .. viewer.ta(key, val ) end t = t .. viewer.ta("\n* #noopt_tab", lua_table.count_all( noopt_tab ) ) .. viewer.ta("noopt_tab", lst ) IAMO.add(IAMO, 1, "#noopt_tab = " .. lua_table.count_all(noopt_tab), noopt_tab ) -- IAMO.t -- t = t .. viewer.ta("\n* #noopt_tab", lua_table.count_all( noopt_tab ) ) .. viewer.ta("noopt_tab", viewer.rough_view( noopt_tab ) ) -- opt_tab = mw.clone(opt_pretab) -- unknown arguments to detect are source arguments without known arguments. for option, opt_t in pairs(noopt_tab) do -- Build the subgroup table from the groupname string opt_tab[opt_t] = nil -- no_option delete an active option end -- active options are in opt_tab local lst = "" ; for key, val in pairs(opt_tab) do lst = lst .. viewer.ta(key, val ) end t = t .. viewer.ta("\n* #opt_tab = " .. lua_table.count_all( opt_tab ) ) .. viewer.ta("opt_tab whitout no", lst ) -- t = t .. viewer.ta("\n* #opt_tab", lua_table.count_all( opt_tab ) ) .. viewer.ta("opt_tab whitout no", viewer.rough_view( opt_tab ) ) -- Activate the sought options local template_options = " " for key, val in pairs(noopt_tab) do template_options = template_options .. " " .. val end -- Build the subgroup table from the groupname string -- active options are in opt_tab modes.template_options = template_options IAMO.add(IAMO, 1, "actual template_options", modes.template_options ) -- IAMO.t -- modes.template_options = modes.options_all -- options from template args ? -- Activate the sought options -- if (type(args_template.options) == "string") then modes.template_options = args_template.options end t = t .. viewer.ta("modes.template_options", modes.template_options) return t, modes.template_options end -- local t = modes.options_mixer(args_template) -- { "20170703", "20170705", "now", "Rical", "S170703amo", "debug viewer.simpleList_test() in modes.import_args_mode_options()", }, function modes.import_args_mode_options(args_template) -- Import and mix args mode and options from template and invoke -- S170703amo -- Guideline: Any combination of options can define a mixture of options to modify options. -- This function allows any module to modify this process. -- The default process gives the priority to options from arguments. -- Each option can be deleted by the nooption option. Then options begining by "no" are forbiden. -- local fenv = getfenv() -- Not activated in fr.wikisource.org by allowEnvFuncs in the engine configuration. if (type(modes.options_for_modes) ~= "table") then modes.options_for_modes = {} end if (type(modes.args_template) ~= "table") then modes.args_template = {} end if (type(args_template) == "table") then args_template = modes.args_template end -- Import args mode options if not viewer.IAMO then viewer.IAMO = tracker.initadd({ ["name"] = "IAMO", limit = 2, }) end -- Initialize a track IAMO.add(IAMO, 1, "import_args_mode_options, <b>options_for_modes</b> :", modes.options_for_modes ) -- IAMO.t local t = "t= * * * " modes.frame = mw.getCurrentFrame() -- frame or modes.frame or modes.args_template = modes.frame:getParent().args args_template = modes.args_template modes.mode_name = args_template.mode or args_template[1] or "read" modes.args_mixed = modes.args_mixer(args_template) modes.modes_mixer(args_template) modes.options_mixer(args_template) TITL.add(TITL, 1, "import_args_mode_options", { item = args_template.itemid, QITEM = args_template.QITEM, }) -- TITL.t return modes.args_mixed end -- local t = modes.import_args_mode_options(args_template) function modes.import_arguments(args_known, args_source, content_translations, args_wikidata) -- Import all arguments from template, or invoke, or wikidata -- modes.args_import = modes.import_args_mode_options(args_source) -- Import and mix args mode and options from template and invoke -- S170703amo -- modes.init_args_mode_options(mix, mode_name, args_template) -- Import and mix args mode and options from template and invoke -- S170710mix local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = { } modes.args_known = args_known local args_wikidata = args_wikidata or modes.args_wikidata or p.args_wikidata or {} -- optional value from p.args_known = { } modes.args_wikidata = args_wikidata local args_import = args_import or modes.args_import or {} -- optional value from p.args_known = { } modes.args_import = args_import -- if type(args_wikidata) ~= "table" then args_wikidata = datas.args_wikidata end -- 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 content_translations = content_translations or langs.content_translations -- Mix args_source in args_import, with priority for present args_source. for key, argm in pairs(modes.args_template) do modes.args_import[key] = argm end -- local err = nil local cats = "" modes.nowyear = tonumber(os.date("%Y") ) -- now_date = os.date("%Y-%m-%d %H:%M:%S") ARGS.add(viewer.ARGS, 1, "import_arguments", { ["argsknown"] = args_known, ["argssource"] = args_source, ["argswikidata"] = args_wikidata, ["nowyear"] = modes.nowyear, } ) -- ARGS.t -- 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 -- initialize all arguments to "not found" before import them from p.args_known = {...} for key_known, argm in pairs(args_known) do if type(argm) == "table" then argm.found = 0 end -- else args_known[key_known] = nil end -- also clean args_known{} table with only arguments descriptors end ARGS.add(viewer.ARGS, 1, "args_known", { Nargs_known = #args_known, } ) -- ARGS.t -- 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 -- Get datas from mw.wikibase for the page and Mix datas in modes.args_import. datas.props = datas.get_item(args_known, QITEM) -- Get datas from mw.wikibase for the page. -- 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 if type(argm) == "table" then 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] ARGS.add(viewer.ARGS, 1, "args_known for", { key = key_known, Nargm = #argm, syn = argm.syn, } ) -- ARGS.t 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.."=" -- Import a wikidata argument. Importer un argument wikidata if type(datas.props) == "table" and datas.props[key_known] then argm["val"] = datas.props[key_known] argval = datas.props[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 arg_found = true modes.import_arguments_track = modes.import_arguments_track .. "=<b>" .. tostring(argval) .. "</b> " end if false and args_wikidata[key_known] then -- replaced by datas.props on 2018-01-28 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 = langs.content_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 args_source[arglingual] and not modes.args_source[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 = content_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("versn_module_miss_i18n_trad_err", key_known) -- Generate a category to list all modules with missing translation cats = cats .. events.add_cat( "versn_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 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("versn_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("versn_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("versn_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 = content_translations[key_known] if arglingual then events.add_err("modes_need_arg_value_err", arglingual) cats = cats .. events.add_cat("versn_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. function tableview.new( 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("versn_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("versn_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") modes.args_import.nowyear = modes.nowyear modes.args_import = args_import return modes.args_import end -- modes.args_import = modes.import_arguments(args_known, args_source, content_translations, args_wikidata) function modes.args_unknown_report(t) -- Report unknown arguments. local t = t or "\n* modes.args_unknown_report(t) Report main unknown arguments." local tabView = { testGroup = modes.args_unknown, -- Use default cases. rowGroup = {}, form_one_case = function(case) -- Convert a case from testGroup to rowGroup. return { case.i, case.where, case.save, } end, title_memo = "modes_args_unknown_report_title", headers = "modes_args_unknown_report_headers", headers = "i;where;save", } t = t .. "<br/>" .. tableview.new(tabView) -- Form a table view with lines and columns. return t end -- t = t .. modes.args_unknown_report(t) -- Report unknown arguments. -- res = res .. dropbox.new(selector, "modes_args_unknown_report_title", modes.args_unknown_report) -- - - - ------------------ - - - - --------------------------------- -- Argts : Generate documentation. Generar documentación. Générer la documentation. -- - - - ------------------ - - - - --------------------------------- 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 nobox1 nocatview " -- without normal result -- modes.options = " debug tests en es fr " -- for debug or enforce language -- Option nocatview 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(langs.user_translations[key]) -- multilingual name of the arg in the template arglingual = viewer.form9user(arglingual) -- 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 t = t .. viewer.tam( viewer.form9user(key), parm) end -- list if found and selected 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_source 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 -- Mix invoked modified arguments from prioritary template arguments. -- Argument 1 from template become the mode in #invoke. Other i arguments must be shifted. local invoked = frame.args -- arguments from #invoke module local args_tab = mw.clone(invoked) -- less priority than template for key, val in pairs(args_tab) do -- invoked 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 local args_tab = mw.clone(templat) -- template have the priority and can itself #invoke arguments 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 -- args from: modes.module_init() -- Get modes.args_source with modes.args_source -- modes.args_source = modes.argsConfigIinit(modes.args_source) -- Extract and put apart args_source from args_source -- Default values of main module version. if versn.main_versions then versn.main_versions.versionName = versn.main_versions.versionName or "Central0" versn.main_versions.versionNumber = versn.main_versions.versionNumber or "0.00" versn.main_versions.versionDate = versn.main_versions.versionDate or "2013-03-24" end return -- modes.args_source end -- function modes.module_init(frame) function modes.replace_args_known(args_known) modes.args_known = args_known or p.args_known or modes.args_known end 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 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) -- Select the actual mode from some sources local mode_key = "mode" local args_source = args_source or modes.args_source 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 return mode_name, source_key, lang, args_source end -- function modes.get_arg_mode(mode_name, source_key, lang, args_source) function modes.all_categories_list(t) -- List all eventual categories of this wiki local memo = viewer.zzz_save_configs("modes.all_categories_list") -- Save global configuration before eventual changes. local t = "\n* " .. (t or viewer.form9user("modes_all_categories_list_title") ) -- for key, txt in pairs(langs.user_translations or langs.content_translations or langs.page_translations) do for key, txt in pairs(langs.main_i18n[langs.user_lang]) do if viewer.is_in("cat_", key) or viewer.is_in("_cat", key) then txt = viewer.form9user(key, "**", "**", "**", "**", "**", "**") t = t .. "<br>" .. viewer.ta(key, txt) end end viewer.zzz_restore_configs(memo, "modes.all_categories_list") -- Restore global configurations after eventual changes. return t end -- function modes.all_categories_list(t) function modes.all_errors_list(t) -- List detectable errors of this module local t = "\n* " .. (t or viewer.form9user("modes_all_errors_list_title") ) -- for key, txt in pairs(langs.user_translations or langs.content_translations or langs.page_translations) do for key, txt in pairs(langs.main_i18n[langs.user_lang] or modes.modes_args.userlang) do if viewer.is_in("err_", key) or viewer.is_in("_err", key) then txt = viewer.form9user(key, "**", "**", "**", "**", "**", "**") 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) -- List of all accepted arguments local memo = viewer.zzz_save_configs("modes.options_from_mode_tests") -- Save global configuration before eventual changes. local t = "\n* " .. (t or viewer.form9user("modes_list_all_args_main_title") ) -- local t = t or "\n* <b>list_all_args_main :</b> " if type(args_known) ~= "table" then args_known = modes.args_known or versn.main_module.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 = langs.user_translations[descr] or "**missing translation**" elem.user_lang_key = langs.user_translations[elem.key] or "**missing key**" elem.user_lang_keyword = langs.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 ) viewer.zzz_restore_configs(memo, "modes.list_all_args_main") -- Restore global configurations after eventual changes. 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 = recursiveLevel_err or"" -- 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) + 1 if recursiveLimit < 1 then recursiveLimit = modes.recursiveLimit end -- default recursiveLevel if type(recursiveLevel) ~= "number" then recursiveLevel = 1 end recursiveLevel = math.floor( recursiveLevel ) + 1 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 = viewer.zzz_save_configs("modes.recursiveNormal_tests") -- Save global configuration before eventual changes. -- recursiveLevel, recursiveLimit, recursiveLevel_err == modes.recursiveNormal(recursiveLevel, recursiveLimit) 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, "versn_module_miss_i18n_txt_err") t = t .. recursiveNormal_test1(11112, 5, "versn_module_miss_i18n_count_err") t = t .. recursiveNormal_test1(23456, 5, "modes_recursiveLevel_err") viewer.zzz_restore_configs(memo, "modes.recursiveNormal_tests") -- 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.init_modes_translate_events(frame, Central_version, mode_name, args_known, options_for_modes, QITEM) -- After versn.init(), initialize modes and their options, known arguments, translations, and default item. local res = "" modes.frame = frame langs.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 .. versn.site_currentVersion_view -- clean and rewrite init for versioning, mode, options, translate, module modes.module_init(frame) -- Get modes.args_source with modes.args_source modes.mode_name = mode_name or modes.mode_name or "read" -- modes.args_known = modes.args_known_one_lib(args_known, centrobj.i18n_libraries_list) -- Bind all known args and properties from any libraries. Later for modules. -- mathroman.args_known_one_lib(args_known) -- Bind means import and mix known args and their properties. 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", "select_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" langs.init_languages(modes.args_source.contentlang, modes.args_source.pagelang, modes.args_source.userlang, "modes.init") local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, modes.recursiveLimit) return res end -- function modes.init_modes_translate_events(frame, Central_version, mode_name, args_known, options_for_modes, QITEM) function modes.warning_short() -- local warning_versions = modes.warning_short() -- in Module:Author3 -- versn.deprecatedFunction("modes.interact_args_final", "p.interact_args_final") -- versn.report_main_short = main_versions.versionName .. " " .. main_versions.versionNumber local warning_versions = versn.report_main_short return warning_versions end -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:testsgrp initialises, runs and forms groups of tests for Mediawiki and users. -- It supports modules coders and users to: -- * Increase the stability of central modules. -- * Form some views for users -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- testsgrp = {} mw.testsgrp = testsgrp -- From 20170729 -- Translations for testsgrp library testsgrp.i18n = {} testsgrp.i18n.en = { testsgrp_recursive_tests_title = "testsgrp.recursive_tests(t) Tests cases for users and Mediawiki", testsgrp_getTestProvider_title = "viewer.simpleList_test() Tests: Implement getTestProvider in central modules", testsgrp_getTestProvider_tests_title = "viewer.simpleList_test() Tests: Implement getTestProvider in central modules", testsgrp_subdiffs_abnormal_error = "Internal error: abnormal subDiffs process", testsgrp_subdiffs_boolean_error = "subDiffs boolean error", testsgrp_subdiffs_function_error = "subDiffs function error", testsgrp_subdiffs_nil_error = "subDiffs nil error", testsgrp_subdiffs_number_error = "subDiffs number error", testsgrp_subdiffs_string_error = "subDiffs string error", testsgrp_subdiffs_table_error = "subDiffs table error", testsgrp_subdiffs_tables_error = "subDiffs tables error", testsgrp_subdiffs_type_error = "subDiffs type error", testsgrp_subdiffs_types_error = "subDiffs types error", testsgrp_recursiveLevel_error = "subDiffs recursion level exceeded error", testsgrp_search_Diffs_tests_title = "testsCases.search_Diffs_tests() Search detailed differences in testsCases", testsgrp_search_Diffs_tests_headers = "Expected value; Actual value; Test indentifier; Results + Errors : expected-actual-details", testsgrp_testsgrp_report_title = "testsCases.testsgrp_report() Mediawiki recursive testsCases", testsgrp_group_Diffs_tests_title = "testsCases.group_Diffs_tests() Tests: Report detailed differences, where, recursively", testsgrp_group_Diffs_test_headers = "Expected value; Actual value; Test indentifier; Results + Errors : expected-actual-details", } -- testsgrp.i18n.en testsgrp.i18n.es = { testsgrp_recursive_tests_title = "testsgrp.recursive_tests(t) Prueba casos para usuarios y Mediawiki", testsgrp_getTestProvider_tests_title = "viewer.simpleList_test() Pruebas: Implementar getTestProvider en módulos centrales", testsgrp_subdiffs_abnormal_error = "Error interno: subDiffs proceso anormal", testsgrp_subdiffs_boolean_error = "subDiffs booleano error", testsgrp_subdiffs_function_error = "subDiffs función error", testsgrp_subdiffs_nil_error = "subDiffs nulo error", testsgrp_subdiffs_number_error = "subDiffs numero error", testsgrp_subdiffs_string_error = "subDiffs texto error", testsgrp_subdiffs_table_error = "subDiffs tabla error", testsgrp_subdiffs_tables_error = "subDiffs tablas error", testsgrp_subdiffs_type_error = "subDiffs typo error", testsgrp_subdiffs_types_error = "subDiffs typos error", testsgrp_recursiveLevel_error = "subDiffs nivel de recursividad superó error", testsgrp_search_Diffs_tests_title = "testsCases.search_Diffs_tests() Buscar diferencias detalladas en testsCases", testsgrp_search_Diffs_tests_headers = "Valor prevista; Valor activa; Identificador del prueba; Resultados + Errores : prevista-activa-detalles", testsgrp_testsgrp_report_title = "testsCases.testsgrp_report() Mediawiki testsCases recursivos", testsgrp_group_Diffs_tests_title = "testsCases.group_Diffs_tests() Pruebas: Reporte detallado de las diferencias, ¿dónde? recursivamente", testsgrp_group_Diffs_test_headers = "Valor prevista; Valor activa; Identificador del prueba; Resultados + Errores : prevista-activa-detalles", } -- testsgrp.i18n.es testsgrp.i18n.fr = { testsgrp_recursive_tests_title = "testsgrp.recursive_tests(t) Tests cases for users and Mediawiki", testsgrp_getTestProvider_tests_title = "viewer.simpleList_test() Tests: Implement getTestProvider in central modules", testsgrp_subdiffs_abnormal_error = "Erreur interne : processus subDiffs anormal", testsgrp_subdiffs_boolean_error = "subDiffs erreur de booléen", testsgrp_subdiffs_function_error = "subDiffs erreur de fonction", testsgrp_subdiffs_nil_error = "subDiffs erreur de nul", testsgrp_subdiffs_number_error = "subDiffs erreur de nombre", testsgrp_subdiffs_string_error = "subDiffs erreur de texte", testsgrp_subdiffs_table_error = "subDiffs erreur de table", testsgrp_subdiffs_tables_error = "subDiffs erreur de tables", testsgrp_subdiffs_type_error = "subDiffs erreur de type", testsgrp_subdiffs_types_error = "subDiffs erreur de types", testsgrp_recursiveLevel_error = "subDiffs erreur de niveau de récursivité dépassé", testsgrp_search_Diffs_tests_title = "testsCases.search_Diffs_tests() Chercher les différences détaillées dans les testsCases", testsgrp_search_Diffs_tests_headers = "Valeur attendue; Valeur active; Identifiant du test; Résultats + Erreurs : attendue-active-détails", testsgrp_testsgrp_report_title = "testsCases.testsgrp_report() Mediawiki testsCases recursifs", testsgrp_group_Diffs_tests_title = "testsCases.group_Diffs_tests() Tests: Rapport detaillé des différences, où, recursivement", testsgrp_group_Diffs_test_headers = "Valeur attendue; Valeur active; Identifiant du test; Résultats + Erreurs : attendue-active-détails", } -- testsgrp.i18n.fr testsgrp.default_testGroup = { -- events.testGroup { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 } }, -- case { ["name.roman2intTests.1"] = "mathroman", ["modulename"] = "mathroman", ["groupname"] = "mathroman.roman2intTests", }, -- group { ["name"] = "testsgrp.autotests.1", ["modulename"] = "testsgrp", ["groupname"] = "testsgrp.autotests_group", }, -- group } -- testsgrp.default_testGroup mathroman.roman2intNMC = { -- Tests cases for testsgrp.resultdiffs("mathroman.testsRecur", "mathroman.roman2intNMC", case, opt, 1) only -- each test_case defines a name, a function, an input, an output. See also viewer.strTestCase. 6 cases { ["args"] = { "-X" }, ["expect"] = { 10, "mathroman_char_X_in_N_err" }, -- change one key [" ] ," ["errorsKey"] = 2, ["modulenameNMC"] = "mathroman", ["funcname"] = "mathroman.roman2int", }, { ["args"] = { "0" }, ["expect"] = { 0, "mathroman_NMC" }, -- change one string value, and change a value in the args table ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2intNMC", }, { ["args"] = { "XIA" }, ["expect"] = { 11, "character A in 3" }, -- missing key/val in level 1 and sub table ["errorsKey"] = 2, ["funcname"] = "mathroman.roman2int", }, { ["args"] = { "MCXI" }, ["expect"] = { 1111 }, -- missing case ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int",}, } 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, ["args"] = { "IV" }, ["expect"] = { 4 }, ["funcname"] = "mathroman.roman2int", ["modulename"] = "mathroman", }, { ["errorsKey"] = 2, ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["funcname"] = "mathroman.roman2int", ["modulename"] = "mathroman", }, -- case } mathroman.testsRecur = { -- Autotest cases to validate the mathroman library at mediawiki level. { ["name"] = "mathroman", ["modulename"] = "mathroman", ["groupname"] = "mathroman.roman2intTests", }, -- group { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { "31" }, ["expect"] = { "XXX1" } }, { ["name"] = "mathroman", ["modulename"] = "mathroman", ["groupname"] = "mathroman.main_tests_groups", }, -- group } local func_example = { ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["errorsKey"] = 2, } local group_example = { ["name"] = "mathroman.roman2int.5", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", } testsgrp.main_tests_groups = { -- Autotest cases to validate the mathroman library at mediawiki level. { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.roman2int", ["args"] = { "VIA", }, ["expect"] = { 6, "character A in 3" }, }, { ["name"] = "mathroman", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", }, { ["errorsKey"] = 2, ["modulename"] = "mathroman", ["funcname"] = "mathroman.int2roman", ["args"] = { "19" }, ["expect"] = { "XII" } }, { ["name"] = "testsgrp", ["modulename"] = "testsgrp", ["groupname"] = "testsgrp.autotests_group", }, } testsgrp.autotests_group = { -- events.testGroup { ["errorsKey"] = 2, ["modulename"] = "testsgrp", ["funcname"] = "testsgrp.autotests", -- 1 ["args"] = { "1111", ["guide"] = "t1: small result = expect", }, ["expect"] = { "MCXI" }, ["result"] = { "MCXI" }, }, { ["errorsKey"] = 2, ["modulename"] = "testsgrp", ["funcname"] = "testsgrp.autotests", -- 2 ["args"] = { "abc2", 222, ["guide"] = "t2: = -s; 2 = -s", }, ["expect"] = { "xyz2", "xyz2-e", }, -- 2 = -e ["result"] = { "xyz2", "xyz2-s", }, }, { ["errorsKey"] = 2, ["modulename"] = "testsgrp", ["funcname"] = "testsgrp.autotests", -- 3 ["args"] = { "abc3", 333, ["guide"] = "t3: ident levels > no error", }, ["expect"] = { "xyz3", ["subgrp3"] = { ["one3"] = 33, ["endgrp33"] = "good", }, }, ["result"] = { "xyz3", ["subgrp3"] = { ["one3"] = 33, ["endgrp33"] = "good", }, }, }, { ["errorsKey"] = 2, ["modulename"] = "testsgrp", ["funcname"] = "testsgrp.autotests", -- 4 ["args"] = { "abc4", 444, ["guide"] = "t4: val: good ~= BAD in val of level 2", }, ["expect"] = { "xyz4", ["subgrp"] = { ["one"] = 44, ["endgrp"] = "good4", }, }, ["result"] = { "xyz4", ["subgrp"] = { ["one"] = 44, ["badgrp"] = "BAD4", }, }, }, { ["errorsKey"] = 2, ["modulename"] = "testsgrp", ["funcname"] = "testsgrp.autotests", -- 5 ["args"] = { "abc5", 555, ["guide"] = "t5: val diffs and key diffs in level 1 and 2", }, ["expect"] = { "xyz5", ["subgrp"] = { ["one"] = 55, ["endgrp"] = "good5", }, }, ["result"] = { "UVWX5", ["subgrp"] = { ["two"] = 51, ["badgrp"] = "BAD5", }, }, }, { ["errorsKey"] = 2, ["modulename"] = "testsgrp", ["funcname"] = "testsgrp.autotests", -- 6 ["args"] = { "abc6", 666, ["guide"] = "t6: 1 val diff in level 3", }, ["expect"] = { "xyz6", ["sub2"] = { ["one6"] = 111, { ["end6"] = "valRef6", }, }, }, ["result"] = { "xyz6", ["sub2"] = { ["one6"] = 666, { ["end6"] = "valDif6", }, }, }, }, { ["errorsKey"] = 2, ["modulename"] = "testsgrp", ["funcname"] = "testsgrp.autotests", -- 7 ["args"] = { "equal7", 777, ["guide"] = "t7: all levels result = expect", }, ["expect"] = { "xyz7", ["sub2"] = { ["one6"] = { ["diff7"] = "val 7", }, }, }, ["result"] = { "xyz7", ["sub2"] = { ["one6"] = { ["diff7"] = "val 777", }, }, }, }, } -- testsgrp.autotests_group = {} function testsgrp.autotests(case, opt) -- Form tests cases to run for Mediawiki and users. if (type(case.result) ~= "table") and (type(case.expect) == "table") then case.result = case.result or case.expect or {} -- default end EXD.add(EXD, 1, "autotests", { ["#args"] = lua_table.level_count(case.args), ["#expect"] = lua_table.level_count(case.expect), ["#result"] = lua_table.level_count(case.result), } ) return case end testsgrp.main_groupname = "mathroman.testsGroups" -- Autotest cases to validate the mathroman library at mediawiki level. testsgrp.main_groupname = "testsgrp.main_tests_groups" -- Main group of tests cases for auto-test testsgrp itself. function testsgrp.Organisation(case) -- See mw:Extension:Scribunto/Lua reference manual#Test cases if nil then -- Do not disturb other process, in case of bad use. local case = case or {} local ClassNameTests = { ["count"] = nmaxi, ["name"] = caseid, ["count"] = nmaxi, } -- ClassNameTests.lua as if it were the page "Module:ClassNameTests" case.count = case.nmaxi -- count: Integer, number of tests case.name = case.name -- string identifier of the test case case.provide = testsgrp.provide_func( n ) -- Function that returns three values: n, the test name, a string case.run = testsgrp.provide_run( n ) -- run( n ): Function that runs test n and returns one string. case.result_string = case.run( n ) -- run( n ): Function that runs test n and returns one string. local n, the_test_name, a_string = case.provide(n, case) local testsgrp = require 'Module:TestFramework' -- local testsgrp = require 'Module:TestFramework' testsgrp.getTestProvider( { "Tests go here" } ) -- return testsgrp.getTestProvider( { -- Tests go here } ) case = { ["name"] = "name of the test", ["func"] = "function to execute", ["args"] = "Optional table of arguments to pass to the function", ["expect"] = "Results to expect", ["type"] = 'Optional "type" of the test, default is "Normal"', ["types"] = "Included types are", ["Normal"] = "expect is a table of return values, or a string if the test should raise an erro", ["Iterator"] = "expect is a table of tables of return values", ["ToString"] = 'Like "Normal", except each return value is passed through tostring()', } -- Each test is itself a table, with the following properties: end return nil end -- function testsgrp.Organisation(case) testsgrp.allpublics = { ["readers"] = "readers", ["helpers"] = "helpers", ["coders"] = "coders", } -- Available status of errors testsgrp.alldescriptions = {} -- Descriptions of errors function testsgrp.errors_init(allstatus) -- Check and standardize errors objects. Form a table view of errors definitions. -- res = res .. dropbox.new(selector, "testsgrp_getTestProvider_tests_title", viewer.simpleList_test ) local memo = viewer.zzz_save_configs("testsgrp.errors_init") -- Save global configuration before eventual changes. if ( type(testsgrp.allstatus) ~= "table" ) then testsgrp.allstatus = {} end if ( type(allstatus) ~= "table" ) then allstatus = testsgrp.allstatus end testsgrp.allpublics = {} testsgrp.alldescriptions = {} local allpublics, alldescriptions = testsgrp.allpublics, testsgrp.alldescriptions for key, an_error in pairs(allstatus) do -- Synthesis and descriptions of all status -- testsgrp.allstatus[an_error.name] = an_error.status testsgrp.allpublics["public"] = an_error.public testsgrp.alldescriptions[an_error.name] = an_error.descript end if (type(EXD) ~= "table") or (type(tracker.initadd) ~= "function") then EXD = tracker.initadd({ ["name"] = "EXD", ["limit"] = 2 }) end -- Initialize a track EXD.add(EXD, 1, "errors_init begin 6354", { ["#errors"] = lua_table.level_count(EXD.errors), } ) -- testsgrp.alldescriptions[key] = an_error.descript -- Descriptions of errors -- testsgrp.allstatus = errors -- direct update from init() local t = "\n* testsgrp.errors_init(errors) -- Check and standardize errors objects" local tabView = { tests_title = "testsgrp.errors_init(errors) -- Check and standardize errors objects", -- "mathroman.int2roman() Test digital numbers to roman numbers" testGroup = testsgrp.allstatus, headers = "Error name; Status; Public; Description", -- "Digital number; Roman value; Correct; Error(s)" rowGroup = {}, } tabView.t = (tabView.t or "") .. viewer.ta("int2roman_tests: ", "start") tabView.t = tabView.t .. viewer.ta("#testGroup: ", lua_table.level_count(tabView.testGroup) ) function tabView.form_one_case(an_error) -- Convert a case from testGroup to rowGroup. return { an_error.name, an_error.status, an_error.public, an_error.descript, } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "testsgrp.errors_init") -- Restore global configurations after eventual changes. return t, errors end -- local t, errors = testsgrp.errors_init(testsgrp.allstatus) function testsgrp.ClassNameTests(case) -- expecting it to return an object with the following properties: count, name, case.provide. case.count = case.nmaxi or 1 -- count: Integer, number of tests case.n = case.n or 1 -- count: Integer, number of tests case.name = (case.funcname or "case.funcname") .. "." .. case.n -- string identifier of the test case case.provide = testsgrp.provide_func(case.n, case) -- Function that returns three values: n, the test name, a string return case end -- local case = testsgrp.ClassNameTests(case) function testsgrp.getTestProvider(mw_tests, nmaxi) -- Form tests cases to run for Mediawiki and users. -- function testsgrp.getTestProvider(), .init(), .gettestsgroups(), .getcases(), .resultdiffs(), .form(), .recursive_tests(), viewer.form9en(), -- This will load the file _getTestProvider.lua as if it were the page "Module:_getTestProvider", -- expecting it to return an object with the following properties: -- count: Integer, number of tests -- provide( n ): Function that returns three values: n, the name of test n, and a string that is the expected output for test n. -- run( n ): Function that runs test n and returns one string. -- Guideline: -- Before to run tests cases mw.testsgrp.getTestProvider() must first -- * Get all tests cases, in a composite and recursive exploration of available modules and libraries. -- * And build, from that exploration, a single level table of all tests cases. -- * And return this table to Mediawiki to really run these tests cases. -- To run these tasks the main module replace this function by its own. -- That happens each time a Lua-coder try or record a change of a module. -- Tests cases: -- testsgrp.getTestProvider(mw_tests, 0) return the table of tests cases, for Mediawiki only, which check the coherence of all returned tests cases. -- Any other uses are available for the calling module or library. -- Structures of tests: -- return testsgrp.getTestProvider( { Tests go here } ) -- getTestModules(): returns a group of controls -- getTestProvider return one control: count = number of tests; provide(n) returns n, name of n, expected string; run( n ) returns one string. -- One test case contains: name, func, args, expect, type -- One type is: Normal = {table}, Iterator like pairs(), ToString = tostring() -- { 33, "Important", "20170816", "T176362", 0, "Open", "Implement getTestProvider in Scribunto to enhance central modules stability", }, -- T176362 : phabtask : Implement getTestProvider in Scribunto to enhance central modules stability -- T176362 : phabtask : The case object contains fields: count, OK="OK", n, name, type, args{}, expect{}, NameTest{}, func(), provide(), run() -- T176362 : phabtask : Functions used in central modules: testsgrp.getTestProvider(), .init(), .gettestsgroups(), .getcases(), .subdiffs(), .normalcase(case), viewer.form9en() -- T176362 : phabtask : proposed functions in Mediawiki: -- T176362 : phabtask : mw.getTestProvider(mw_tests, nmaxi) -- To initialise and limit all tests in time. n is the number of all tests -- T176362 : phabtask : mw.ClassNameCase(case, n), used inside mw.getTestProvider() to run each test case of number 1 to nmaxi. -- T176362 : phabtask : In the testsgrp library, tests cases are in recursive groups of groups of cases. local memo = viewer.zzz_save_configs("testsgrp.getTestProvider") -- Save global configuration before eventual changes. mw_tests = mw_tests or {} local nn = nmaxi or 0 if (type(CNT) ~= "table") or (type(CNT.add) ~= "function") then CNT = tracker.initadd({ ["name"] = "NMC", ["limit"] = 2 }) end -- Initialize a track CNT.add(CNT, 1, "getTestProvider begin", { ["CNT"] = tostring(CNT), ["#CNT"] = lua_table.level_count(CNT), ["#mw_tests"] = #mw_tests, ["nmaxi"] = tostring(nmaxi), } ) local t = "\n* testsgrp.getTestProvider() -- Run testcases for Mediawiki and users." local last_case = {} local mw_cases = {} local nmaxi = #mw_tests for k, case in pairs(mw_tests) do -- For all cases to run local func_example = { ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["errorsKey"] = 2, } local group_example = { ["name"] = "mathroman.roman2int.5", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", } local test_example = { ["errorsKey"] = 2, ["modulename"] = "testsgrp", ["funcname"] = "testsgrp.autotests", -- 2 ["args"] = { "abc2", 123, ["guide"] = "2 = -s; 2 = -s", }, ["expect"] = { "xyz2", "xyz2-e", }, -- 2 = -e ["simul"] = { "xyz2", "xyz2-s", }, } -- 2 = -s if ( type(case) == "table" ) and ( type(case.funcname) == "string" ) and ( type(case.args) == "table" ) then -- count: Integer, number of tests -- provide( n ): Function that returns three values: n, the name of test n, and a string that is the expected output for test n. -- run( n ): Function that runs test n and returns one string. -- Normal: expect{} is a table of return values, or a string if the test should raise an error. func is simply called. -- Each test is itself a table, with the following properties: -- name: The name of the test. -- func: The function to execute. -- args: Optional table of arguments to pass to the function. -- expect: Results to expect. -- type: Optional "type" of the test, default is "Normal". -- Active params of the case: case.name = case.name -- string identifier of the test case case.func = lua_table.tabfromsubnames(case.funcname) -- tested function for this case case.args = case.args -- table of input arguments for the function case.expect = case.expect -- table of the expected result of the function case.type = case.type or "Normal" -- Optional "type" of the test, default is "Normal". -- Default id of the case: case.nmaxi = nmaxi -- count integer is the number of cases case.n = k -- or nn or case.n -- number of cases case.OK = case.OK or "OK" -- Optional "type" of the test, default is "Normal". case.provide = testsgrp.provide_func(case.n, case) -- returns n, its test name, and "OK" or "error string". -- This will load the file getTestProvider.lua as if it were the page "Module:getTestProvider", expecting it to return an object with the following properties: local n, name, ok = case.provide(case.n, case.name, case.OK) -- returns n, its test name, and "OK" or "error string". CNT.add(CNT, 1, "CNTest:provide", { ["n"] = n, ["name"] = name, ["ok"] = ok, } ) case.run = testsgrp.run_func(n, case.func) -- runs the test n. Returns n and one string: "OK" or "error string". case = testsgrp.ClassNameTests(case) -- expecting it to return an object with the following properties: count, name, case.provide. case.NameTest = { case.count, case.name , case.provide} -- return object { count, name, provide(n) } CNT.add(CNT, 1, "case.NameTest", { ["k"] = k, ["name"] = tostring(case.NameTest.name), ["case.NameTest.count"] = case.NameTest.count, ["#NameTest"] = #case.NameTest, ["provide"] = tostring(case.NameTest.provide), } ) table.insert(mw_cases, case) last_case = case else -- error: mw_tests must be fine t = t .. CNT.add(CNT, 1, "CNTest:NO RUN", { ["k"] = k, ["funcname"] = tostring(case.funcname), } ) end end if ( type(mw_tests) == "table" ) and ( type(nn) == "number" ) and ( nn > 0 ) then -- Use mw_tests for Mediawiki, and form adhoc functions. -- testsgrp has already kept mw_tests in all tests_groups. CNT.add(CNT, 1, "CNTest:mw_tests last_case", { ["caseid"] = last_case.name, ["funcname"] = tostring(last_case.funcname), ["nn"] = nn, } ) else -- Use mw_tests for users, and form results tables views. CNT.add(CNT, 1, "CNTest:users_tests last_case", { ["caseid"] = last_case.name, ["funcname"] = tostring(last_case.funcname), ["nn"] = nn, } ) end if last_case and ( #mw_tests ~= #mw_cases ) then last_case.expect = "Cases count error: ".. #mw_tests .. " = #mw_tests ~= #mw_cases = ".. #mw_cases CNT.add(CNT, 1, "CNTest:count error", { ["caseid"] = last_case.name, ["funcname"] = tostring(last_case.funcname), ["#mw_tests"] = #mw_tests, ["#mw_cases"] = #mw_cases, } ) end -- Check the count of cases CNT.add(CNT, 1, "getTestProvider end", { ["#mw_tests"] = #mw_tests, ["#mw_cases"] = #mw_cases, } ) -- if ( type(n) == "number" ) and ( n <= #mw_cases ) and ( type(mw_cases[n]) == "table" ) then mw_cases = mw_cases[n] end -- For tests uses return only the sougth test case -- t = t .. CNT.t viewer.zzz_restore_configs(memo, "testsgrp.getTestProvider") -- Restore global configurations after eventual changes. return mw_cases, t end -- local mw_cases, t = testsgrp.getTestProvider(mw_tests, n) function testsgrp.normalcase(case, expect_tab_name, result_tab_name, diff) -- Normalize case options. local case = case local allstatus = testsgrp.allstatus if (type(case) ~= "table") then case = {} end -- Initialize a track if (type(CNT) ~= "table") or (type(CNT.add) ~= "function") then CNT = tracker.initadd({ ["name"] = "CNT", ["limit"] = 2 }) end -- Initialize a track -- testsgrp.status_memo = "OK,code,differ,equal,excess,miss,tabcount,taberr,types" -- testsgrp.allstatus status values local tt, errors = testsgrp.errors_init(testsgrp.allstatus) -- local allstatus, allpublics, alldescriptions = testsgrp.allstatus, testsgrp.allpublics, testsgrp.alldescriptions case.status = case.status or testsgrp.allstatus.OK.status case.level = case.level or 1 if case.level == 1 then case.expect_base = case.expect or {} end if case.level == 1 then case.result_base = case.result or {} end case.levelsup = case.levelsup or 1 if case.level > case.levelsup then case.levelsup = case.level else case.levelsup = 1 end case.levelLimit = case.levelLimit or 3 case.all_diffs = case.all_diffs or {} case.diff = diff or case.diff or false case.expect_tab_name = expect_tab_name or case.expect_tab_name case.result_tab_name = result_tab_name or case.result_tab_name case.ref_key = case.ref_key or "" if type(case.expect_tab_name) ~= "string" then case.expect_tab_name = "mathroman.testsRecur" end -- to debug when begin if type(case.result_tab_name) ~= "string" then case.result_tab_name = "mathroman.roman2intTests" end -- to debug when begin ; roman2intNMC case.get_expect_tab = function(expect_tab_name) return lua_table.tabfromsubnames(case.expect_tab_name, case.expect_base) end -- expect table case.get_result_tab = function(result_tab_name) return lua_table.tabfromsubnames(case.result_tab_name, case.result_base) end -- result table -- local ref_tab = case.get_expect_tab(case.expect_tab_name) -- expect table. Do not get it in case. to not duplicate it when mw.clone(case) local ref_tab = case.get_expect_tab(case.expect_tab_name) -- expect table. Do not get it in case. To not duplicate it when mw.clone(case) local alt_tab = case.get_expect_tab(case.result_tab_name) -- result table. Do not get it in case. To not duplicate it when mw.clone(case) local ref_tab = lua_table.tabfromsubnames(case.expect_tab_name, case.expect_base) -- expect table. Do not get in case to avoid duplicate in clone nor loop. local alt_tab = lua_table.tabfromsubnames(case.result_tab_name, case.result_base) -- result table. Do not get in case to avoid duplicate in clone nor loop. mw.clone(case) -- case.get_result_tab = function(result_tab_name) return lua_table.tabfromsubnames(case.expect_base) end -- expect table case.missing_jobs = " missbranch misslevel missarg diffs " -- example of jobs for missing parts case.diffs_jobs = " missbranch misslevel missarg newbranch newlevel newarg diffs " -- default jobs for diffs case.all_jobs = " missbranch misslevel missarg newbranch newlevel newarg diffs altbranchs altlevel altarg " -- "now" case.jobs = case.jobs or case.all_jobs -- example of jobs for missing parts case.sub_key = case.sub_key or "" case.errors = case.errors or "" case.all_errors = case.all_errors or {} case.all_diffs = case.all_diffs or {} case.result = case.result or {} return case end -- local case = testsgrp.normalcase(case, expect_tab_name, result_tab_name, diff) -- Normalize case options. testsgrp.defaultform = "status=%1: result=%2 <b>≠</b> expect=%3" -- for: status, result_val, expect_val -- Unicode Character 'NOT EQUAL TO' (U+2260) : ≠ function testsgrp.add_error(case, form, status, result_val, expect_val, ...) -- Form one error, default: "status=%1: result=%2 <b>≠</b> expect=%3" -- testsgrp.add_error(case, "result_type = %1 <b>≠</b> %2", sub_key, allstatus.taberr, result_type, expect_type) -- Form errors for helpers local sub_key, expect, result, errortxt, diff_type local expect_key, expect_val, expect_type, result_key, result_val, result_type local result_val = result_val or case.result_val local expect_val = expect_val or case.expect_val local status = status or case.status or "code" local form = form or case.form or testsgrp.defaultform -- for: status, result_val, expect_val local sub_key = sub_key or case.sub_key or "" case.transform = viewer.form9en(case.form) -- to test only the tranlations if (type(case.form) == "string") and (case.transform ~= case.form) then case.form = case.transform end -- if form has translations, use it -- testsgrp.status_memo = "OK,code,differ,equal,excess,miss,tabcount,taberr,types" -- testsgrp.allstatus status values if (type(form) == "string") and viewer.is_in_sp(form, testsgrp.status_memo, ",") then form = testsgrp.defaultform end if (type(status) ~= "string") then case.status = testsgrp.allstatus.code.status ; status = case.status end local vals = { ... } -- vals = { status, result_val, expect_val, ... } case.transform = viewer.form9en(form, status, result_val, expect_val, ...) -- Show one diff between result and expect. Always in english for testsgrp. table.insert( case.all_errors, case.transform ) local errortxt = sub_key .. case.transform -- Show one diff between alt and ref. Always in english for testsgrp. return errortxt end -- local errortxt = testsgrp.add_error(case, form, status, result_val, expect_val, ...) -- Form one error testsgrp.allstatus = { ["OK"] = { ["name"] = "OK", ["status"] = "OK", ["public"] = "readers", ["descript"] = "Normal default state of error status.", }, ["code"] = { ["name"] = "code", ["status"] = "code", ["public"] = "readers", ["descript"] = "Abnormal coding error.", }, ["differ"] = { ["name"] = "differ",["status"] = "differ", ["public"] = "helpers", ["descript"] = "The result differs from the expected value.", }, ["equal"] = { ["name"] = "equal", ["status"] = "equal", ["public"] = "helpers", ["descript"] = "Equal values when compared.", }, ["excess"] = { ["name"] = "excess",["status"] = "excess", ["public"] = "coders", ["descript"] = "The value is not expected in the result.", }, ["miss"] = { ["name"] = "miss", ["status"] = "miss", ["public"] = "coders", ["descript"] = "The value miss in the result.", }, ["tabcount"]= { ["name"] = "tabcount",["status"] = "tabcount",["public"] = "coders",["descript"] = "Result and expect (sub)tables have different sizes.", }, ["taberr"] = { ["name"] = "taberr",["status"] = "taberr", ["public"] = "coders", ["descript"] = "The value miss in the result.", }, ["types"] = { ["name"] = "types",["status"] = "types",["public"] = "coders",["descript"] = "Result and expect are of different types.", }, } -- testsgrp errors uses and documentations testsgrp.status_memo = "OK,code,differ,equal,excess,miss,tabcount,taberr,types" -- testsgrp.allstatus status values function testsgrp.resultdiffs(case) -- Form errors in case.result{} where it differs from case.expect{}. local sub_key, expect, result, errortxt, diff_type, level, status, allstatus local expect_key, expect_val, expect_type, result_key, result_val, result_type local allstatus = testsgrp.allstatus case.subexpect = case.subexpect or case.expect or {} case.subresult = case.subresult or case.result or {} case.expect_base = case.expect or {} -- Only exactly in expect{} and result{} case.result_base = case.result or {} -- Only exactly in expect{} and result{} case.expect_key = case.key or 1 -- variable to check in case.expect case.result_key = case.key or 1 -- variable to check in case.result case.expect_val = case.expect[case.expect_key] case.result_val = case.result[case.result_key] case.level = case.level or 0 case.levelsup = case.levelsup or 0 if case.level > case.levelsup then case.levelsup = case.level else case.levelsup = 1 end case.levelmaxi = case.levelmaxi or 3 case.error_n = case.error_n or 0 case.errorsmaxi = case.errorsmaxi or 4 case.sub_key = (case.sub_key or case.name or "") .. "[" .. case.level .. "]" sub_key = case.sub_key if case.error_n > case.errorsmaxi then return case end case.transform = viewer.form9en(case.form) if (type(case.form) == "string") and case.transform ~= case.form then case.form = case.transform end -- if form translate, use it -- for key, val in pairs(case.subresult) do if not case.subexpect[key] then -- Detect a result key absent in expect testsgrp.add_error(case, "excess", "excess", key, "nil") -- Form one error, default: "status=%1: result=%2 <b>≠</b> expect=%3" EXD.add(EXD, 1, "resultdiffs types 6674", { ["case.name"] = case.name, ["sub_key"] = case.sub_key, ["case.status"] = case.status, ["key"] = key, ["val"] = tostring(val), } ) end end if (result_type ~= expect_type) then -- Detect diffs on types. testsgrp.add_error(case, "types", "types", case.result_val, case.expect_val) -- Form one error, default: "status=%1: result=%2 <b>≠</b> expect=%3" EXD.add(EXD, 1, "resultdiffs types 6674", { ["case.name"] = case.name, ["sub_key"] = case.sub_key, ["case.status"] = case.status, ["error_n"] = case.error_n, } ) --]] elseif (case.result_val ~= case.expect_val) then -- if diff on counts of values testsgrp.add_error(case, "differ", "differ", result_val, expect_val) end -- testsgrp.status_memo = "OK,code,differ,equal,excess,miss,tabcount,taberr,types" -- testsgrp.allstatus status values if (type(case.subresult) == "table") and (type(case.subexpect) == "table") then -- Loop in sub-tables to a sub level. EXD.add(EXD, 1, "sub.resultdiffs if level 6686", { ["sub_key"] = case.sub_key, ["level"] = (case.level or "0"), ["#case.subresult"] = #case.subresult, ["#case.subexpect"] = #case.subexpect, } ) local count_subresult, count_subexpect = lua_table.level_count(case.subresult), lua_table.level_count(case.subexpect) if (count_subresult ~= count_subexpect) then -- if diff level_count testsgrp.add_error(case, "tabcount", count_subresult, count_subexpect) EXD.add(EXD, 1, "resultdiffs types 6667", { ["case.name"] = case.name, ["sub_key"] = case.sub_key, ["count_subresult"] = count_subresult, ["count_subexpect"] = count_subexpect, } ) --]] end if (case.subresult ~= case.subexpect) then -- pointers always differ Loop in tables levels to an upper level. -- testsgrp.add_error(case, "differ", "differ", case.subresult, case.subexpect) end -- ["guide"] = "t4: val: good ~= BAD in val of level 2" if case.level <= case.levelmaxi then case.level = case.level + 1 EXD.add(EXD, 1, "before sub.resultdiffs 6689", { ["sub_key"] = case.sub_key, ["level"] = (case.level or "0"), ["#case.subresult"] = #case.subresult, ["#case.subexpect"] = #case.subexpect, ["error_n"] = case.error_n, ["transform"] = case.transform, } ) case = testsgrp.resultdiffs(case) EXD.add(EXD, 1, "after sub.resultdiffs 6691", { ["sub_key"] = case.sub_key, ["level"] = case.level, ["levelsup"] = case.levelsup, ["error_n"] = case.error_n, ["transform"] = case.transform, } ) -- case.transform = viewer.form9en(form, status, result_val, expect_val, ...) -- Show one diff between result and expect. Always in english for testsgrp. end end if ( #case.all_errors == 0 ) then case.errors = allstatus.OK.status -- There is no error. else -- List error(s) case.errors = "List error(s): " for k, errortxt in pairs(case.all_errors) do -- Get all differences in excess (line 6236) case.errors = case.errors .. tostring(errortxt) .. ", " end end EXD.add(EXD, 1, "resultdiffs end 6702", { ["sub_key"] = case.sub_key, ["case.levelsup"] = case.levelsup, ["case.expect[1]"] = case.expect[1], ["guide"] = case.args.guide, ["case.errors"] = case.errors, ["error_n"] = case.error_n, } ) return case end -- local case = function testsgrp.resultdiffs(case) function testsgrp.run_func(n, case) -- for case.run(n) = testsgrp.run_func(n) local run = function(n) return tostring(n) end -- Function that runs test n and returns one string. return run end function testsgrp.provide_func(n, case) -- for case.provide(n) = testsgrp.provide_func(n) -- provide( n ): Function that returns three values: n, the name of test n, and a string that is the expected output for test n. -- case.result = case.func(case.args) if (type(testsgrp.result_cases) ~= "table") then testsgrp.result_cases = {} end -- local case = testsgrp.result_cases[n] local provide = function(n, case) -- testsgrp.kept_groups = result_cases -- testsgrp.result_cases = result_cases if (type(case) ~= "table") then case = testsgrp.result_cases[n] end if (type(case) ~= "table") then case = { args = { case }, expect = { }, res = { }, } end local case = testsgrp.normalcase(case, expect_tab_name, result_tab_name, diff) -- Normalize case options. local ref_tab = case.ref_tab or case.expect -- expect table local alt_tab = case.alt_tab or case.result -- result table case.expect = case.ref_tab or case.expect or {} -- expect table case.result = alt_tab or case.result or {} -- result table if (type(case.result) == "table") and (type(case.result.jobs) == "string") then CNT.add(CNT, 1, "provide_func 6793", { ["RES.ERROR"] = "RES.ERROR", ["#case.result"] = #case.result, ["jobs"] = case.result.jobs, } ) end case.n = n if (type(case.funcname) == "string") then -- Get the function to test case.func = lua_table.objfromsubnames(case.funcname) -- Get the last sub-object from its sub-names. if (type(case.func) == "function") then -- Get new diffs case = testsgrp.resultdiffs(case) -- Compare expected and actual results of one test case. else case.err = "Internal error: abnormal function to compute case.result" case.errors = case.err case.result = { "missing function", case.errors } if (type(case.result) == "table") and (type(case.result.jobs) == "string") then CNT.add(CNT, 1, "subdiffs 6805", { ["RES.ERROR"] = "RES.ERROR", ["#case.result"] = #case.result, ["jobs"] = case.result.jobs, } ) end end end if (type(case.errorsKey) ~= "number") then case.errorsKey = 2 end -- Use new diffs case.res1 = case.result[1] or "res1pv" -- default result value case.err2 = case.result[case.errorsKey] or case.errors or case.err local errorsOK = case.errors or case.err2 if errorsOK == "" then errorsOK = nil end errorsOK = errorsOK or case.OK return n, case.name, errorsOK -- Function that returns three values: n, name of test n, and a string as expected output of test n. end return provide end -- function testsgrp.provide_func(n, case) function testsgrp.gettestsgroups(groupname, modulename, kept_groups, recursiveLevel) -- Get groups of tests cases for MW and users. -- function testsgrp.getTestProvider(), .init(), .gettestsgroups(), .getcases(), .resultdiffs(), .form(), .recursive_tests(), viewer.form9en(), -- Guideline: to convert a tree of groups, even in case of loops in any leve: -- Inside each level of the tree of groups, search only sub groups and add only news groups. local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, (testsgrp.gettestsgroups_recursiveLimit or 11) ) local level = recursiveLevel local groupname = groupname local t = "<br>gettestsgroups: " if (type(groupname) ~= "string") then groupname = testsgrp.main_groupname end -- initial default main group if (type(recursiveLevel) ~= "number") then recursiveLevel = 3 end -- initial default main group local main_groups, search_groups, kept_groups = {}, {}, kept_groups or {} local ante_name, post_name local tests_groups = {} -- Get cases in tests_groups main_groups = lua_table.tabfromsubnames(groupname) -- for the main or any new group of groups local modulename = modulename if (type(modulename) ~= "string") then modulename = main_groups.modulename end -- initial module to test CNT.add(CNT, 1, "gettestsgroups start", { ["groupname"] = groupname, ["modulename"] = modulename, ["#main_groups"] = #main_groups, ["level"] = level, } ) local func_example = { ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["errorsKey"] = 2, } local group_example = { ["name"] = "mathroman.roman2int.5", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", } CNT.add(CNT, 1, "gettestsgroups recursive", { ["i"] = i, ["level"] = level, ["groupname"] = groupname, ["#kept_groups"] = lua_table.level_count(kept_groups), } ) function get_tests_groups(groupname, kept_groups, recursiveLevel) local groupname = groupname local modulename = modulename local recursiveLevel, recursiveLimit, recursiveLevel_err = modes.recursiveNormal(recursiveLevel, (testsgrp.gettestsgroups_recursiveLimit or 11) ) local level = recursiveLevel if (type(groupname) ~= "string") then groupname = testsgrp.main_groupname end local main_groups = lua_table.tabfromsubnames(groupname) -- for the main or any new group of groups local search_groups = main_groups or {} local kept_groups = kept_groups or {} CNT.add(CNT, 1, "get_tests_groups:begin", { ["groupname"] = groupname, ["#kept_groups"] = lua_table.level_count(kept_groups), } ) for key, group in pairs(search_groups) do -- For all sub groups in one level if ( type(group) == "table" ) then local group_example = { ["name"] = "mathroman.roman2int.5", ["groupname"] = "mathroman.testsRecur", ["modulename"] = "mathroman", } groupname = group.groupname modulename = group.modulename if ( type(group) == "table" ) and ( type(groupname) == "string" ) and ( type(kept_groups[groupname]) ~= "table" ) then -- antiLoop: if the case is new in the tree of cases groups. kept_groups[groupname] = group -- The groupname as key avoid abnormal loops, like table.insert( kept_groups, group ) group["level"] = level CNT.add(CNT, 1, "get_tests_groups:INSERT", { ["groupname"] = groupname, ["#kept_groups"] = lua_table.level_count(kept_groups), } ) if ( recursiveLevel < recursiveLimit ) then kept_groups = get_tests_groups(groupname, kept_groups, recursiveLevel + 1) end else CNT.add(CNT, 1, "get_tests_groups:no insert", { ["groupname"] = group.groupname, ["funcname"] = group.funcname, ["#kept_groups"] = lua_table.level_count(kept_groups), } ) end search_groups = mw.clone(kept_groups) else -- type(group) ~= "table" to debug : versn.bindable_libraries CNT.add(CNT, 1, "get_tests_groups:no group", { ["key"] = tostring(key), ["type(group)"] = type(group), ["tostring(group)"] = tostring(group), } ) end end CNT.add(CNT, 1, "get_tests_groups:end", { ["recursiveLevel"] = recursiveLevel, ["groupname"] = groupname, ["#kept_groups"] = lua_table.level_count(kept_groups), } ) return kept_groups end -- function get_tests_groups() local kept_groups = get_tests_groups(groupname, kept_groups, recursiveLevel) local func_example = { ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["errorsKey"] = 2, } local group_example = { ["name"] = "mathroman.roman2int.5", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", } local cases_groups, case = {}, {} for key, keptgroup in pairs(kept_groups) do case = lua_table.tabfromsubnames(keptgroup.groupname or "mathroman.int2roman") -- Get the last sub-table from its sub-names. table.insert(cases_groups, case) -- Re-form a normal group of groups, from all sub-groups. end tests_groups = cases_groups table.sort(tests_groups, function (a, b) return ( tostring(a.groupname) ) < ( tostring(b.groupname) ) end ) local result_cases = {} for i, group in pairs(tests_groups) do -- For all known tests_groups CNT.add(CNT, 1, "gettestsgroups group", { ["i"] = i, ["groupname"] = group.groupname, ["name"] = group.name, ["#group"] = #group, } ) for k, case in pairs(group) do -- For all cases in each group local func_example = { ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["errorsKey"] = 2, } local group_example = { ["name"] = "mathroman.roman2int.5", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", } if ( type(case.funcname) == "string" ) then -- Select only tests cases using functions table.insert( result_cases, case ) CNT.add(CNT, 1, "gettestsgroups:INSERT", { ["funcname"] = case.funcname, ["#args"] = #case.args, } ) end end end kept_groups = result_cases testsgrp.kept_groups = result_cases CNT.add(CNT, 1, "gettestsgroups end", { ["modulename"] = modulename, ["group_name"] = group_name, ["post_name"] = post_name, ["#kept_groups"] = lua_table.level_count(kept_groups), ["#tests_groups"] = lua_table.level_count(tests_groups), } ) return kept_groups, t end -- local kept_groups = testsgrp.gettestsgroups(groupname, modulename, kept_groups, recursiveLevel) function testsgrp.getcases(kept_groups) -- Get a group of tests cases for MW and users. -- function testsgrp.getTestProvider(), .init(), .gettestsgroups(), .getcases(), .resultdiffs(), .form(), .recursive_tests(), viewer.form9en(), -- testsgrp.gettestsgroups_recursiveLimit = 11 CNT.add(CNT, 1, "getcases()", { ["#kept_groups"] = #kept_groups, } ) local t = "testsgrp.getcases(tabView) Form the result of tests for MW and users." if (type(kept_groups) ~= "table") then kept_groups = {} end local result_cases = {} local n, more = 0, 0 for k, case in pairs(kept_groups) do -- For all cases in each group -- testsRecur CNT.add(CNT, 1, "for case in kept_groups", { ["case"] = viewer.rough_view(case), } ) case.func = lua_table.tabfromsubnames(case.funcname or "mathroman.int2roman") -- Get the last sub-table from its sub-names. CNT.add(CNT, 1, "k, case", { ["k"] = k, ["funcname"] = case.funcname or "funcname?", ["func"] = tostring(case.func), ["#args"] = lua_table.level_count(case.args), } ) if ( type(case) == "table" ) then -- Select only tests cases using functions n = n + 1 case.n = n case.name = case.funcname .. "." .. n CNT.add(CNT, 1, "for case", { ["k"] = k, ["funcname"] = case.funcname or "func?", ["modulename"] = case.modulename or "module", ["#args"] = lua_table.level_count(case.args), } ) end local func_example = { ["funcname"] = "mathroman.roman2int", ["args"] = { "MCXI" }, ["expect"] = { 1111 }, ["errorsKey"] = 2, } local group_example = { ["name"] = "mathroman.roman2int.5", ["modulename"] = "mathroman", ["groupname"] = "mathroman.testsRecur", } if ( type(case) == "table" ) and ( type(case.funcname) == "string" ) then -- Select only tests cases using functions more = more + 1 table.insert( result_cases, case ) CNT.add(CNT, 1, "CASES:INSERT", { ["funcname"] = case.funcname, ["#args"] = lua_table.level_count(case.args), } ) end end -- testsgrp.kept_groups = result_cases testsgrp.result_cases = result_cases CNT.add(CNT, 1, "getcases all", { ["#kept_groups"] = lua_table.level_count(kept_groups), ["#result_cases"] = lua_table.level_count(result_cases), } ) return result_cases end -- local result_cases = testsgrp.getcases(kept_groups) function testsgrp.run_one_case(case) -- Run one case for users and Mediawiki tests cases. -- function testsgrp.getTestProvider(), .init(), .gettestsgroups(), .getcases(), .resultdiffs(), .form(), .recursive_tests(), viewer.form9en(), local case = testsgrp.normalcase(case) -- Normalize case options. CNT.add(CNT, 1, "run_one_case begin 6878", { ["case_id"] = case.name, ["args[1]"] = case.args[1], ["#case.result"] = #case.result, ["case.result"] = viewer.rough_view(case.result), ["jobs"] = case.result.jobs, } ) if type(case.args) ~= "table" then case.args = { case.args } end -- CNT.add(CNT, 1, "run_one_case begin", { ["caseid"] = case.name, ["#case.args"] = #case.args, ["funcname"] = tostring(case.funcname), } ) if type(case.funcname) == "string" then case.run = lua_table.objfromsubnames(case.funcname, base_table) -- Get the last sub-object from its sub-names. end -- function lua_table.tabfromsubnames( if type(case.run) == "function" then -- 555 666 777 case.result = { case.run( case.args ) } -- Run the test case and record its results. see case.run = case = testsgrp.resultdiffs(case) -- Form errors in case.result{} where it differs from case.expect{}. case.errors = case.errors CNT.add(CNT, 1, "run_one_case after resultdiffs 6889", { ["case.key"] = case.key, ["case.error_n"] = case.error_n, ["errors"] = case.errors, } ) else case.result = { [1] = "no case.run function", [2] = "no case.run function", } -- Run the test case and record its results. case.run = CNT.add(CNT, 1, "run_one_case no function 6891", { ["case.result[1]"] = case.result[1], ["case.result[2]"] = case.result[2], } ) end CNT.add(CNT, 1, "CASES:INSERT 6893", { ["funcname"] = case.funcname, ["#args"] = lua_table.level_count(case.args), } ) if (type(case.result) ~= "table") then -- Get diffs case.result = case.result or {} case.err = viewer.ta("case.result", case.result) case.all_diffs = case.all_diffs or {} table.insert( case.all_diffs, { ["sub_key"] = sub_key, ["status"] = status, ["err"] = case.err, } ) CNT.add(CNT, 1, "CASES:INSERT 6899", { ["funcname"] = case.funcname, ["#args"] = lua_table.level_count(case.args), } ) end case.res1 = case.result[1] or "res1roc" -- DEBUG : mathroman.int2roman() can fail without blocking page. case.err2 = case.result[case.errorsKey] or "err2" -- DEBUG : mathroman.int2roman() can fail without blocking page.e2 -- Use new diffs case.res1 = case.result[1] or "res1" -- DEBUG : mathroman.int2roman() can fail without blocking page. case.err2 = case.result[case.errorsKey] or "err2" -- DEBUG : mathroman.int2roman() can fail without blocking page.e2 -- if (type(CNT) ~= "table") or (type(CNT.add) ~= "function") then CNT = tracker.initadd({ ["name"] = "CNT", ["limit"] = 2 }) end -- Initialize a track CNT.add(CNT, 1, "run_one_case end 6907", { ["case_id"] = case.name, ["args[1]"] = case.args[1], ["args[2]"] = case.args[2], ["#case.result"] = #case.result, ["case.result"] = viewer.rough_view(case.result), ["case.errors"] = case.errors, } ) return case -- for function tabView.form_one_case(case) end -- case = testsgrp.run_one_case(case) -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:versn installs other libraries, supports versions, then binds modules, libraries and i18n translations. -- This library supports 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_c -- * 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. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- versn = {} -- The Library:versn installs other libraries, bind modules and libraries, bind i18n translations, manage versions. -- versn = {} -- The Library:versn must stay in _G global space, to not change in init phase. -- versn = {} -- already declared by Scribunto, see centrobj.new() -- Record a library in package.loaded -- Translations for versioning library versn.i18n = {} versn.i18n.br = { versn_support_desk_title = "Informations de soutien: version %1, %2 traductions en %3 langues", versn_support_desk_table = "viewer.docDropBoxTitle", } -- versn.i18n.br versn.i18n.de = { versn_support_desk_title = "Support Informationen: Version %1, %2 Sprachen %3 Übersetzungen", versn_support_desk_table = "viewer.docDropBoxTitle", } -- versn.i18n.de versn.i18n.en = { -- Main string, errors and categories of tools versn_dev_running_times_title = "versn.running_times() Running times and references for Lua coders.", versn_luatables_counts = "%1 variables, %3 sub-tables, %2 functions", versn_table_dont_exists = "The table <b>%1</b> does not exist.", versn_table_listlimit_levelmaxi = "Level limit recursiveLimit = <b>%1</b> ", versn_table_listlimit_max_n = "Length limit max_n = <b>%1</b> ", versn_antiCrash_tests_title = "versn.antiCrash() Test: in case of running error, do not crash the page.", versn_antiCrash_reference_label = "References", versn_antiLoop_function_err = "versn.antiLoop() error in the <b>%3</b> <b>%1()</b>, loop n = <b>%2</>, args = ", versn_module_usage_error_cat = "Module with usage error", versn_module_with_error_cat = "Module with error", versn_module_with_error_err = "Module with error", versn_with_internal_error_cat = "Module with internal error", -- Versions management versn_versions_no_select_altern_err = "Versions error: no selection in the alternative <b>%1</b> of the module <b>%2</b>.", versn_versions_too_select_altern_err= "Versions error: <b>%1</b> selections in the alternative <b>%2</b> of the module <b>%3</b>.", versn_versions_select_not_used_err = "Versions error: <b>%1</b> selector is not in alternative <b>%2</b> of the module <b>%3</b>.", versn_versions_missing_module_err = "Versions error: missing module for the version <b>%1</b> of the module <b>%2</b>.", versn_main_module_missing_err = "The main module is not found.", versn_select_unknown_module_err = "Internal error: The missing Module:<b>%1</b> is replaced by the normal Module:<b>%2</b>.", versn_I18N_module_no_base_err = "The <b>%1</b> translations module has no basic version.", versn_no_versions_module_err = "The module <b>%1</b> is not in the system of versions.", versn_all_versions_tests = "Versions warning: <b>%1</b>, normal: <b>%2</b>, listall: <b>%3</b>.", versn_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>.", versn_missing_versions_err = "The module <b>%1</b> misses in the main module <b>%2</b>.", versn_replaced_versions_err = "The module <b>%1</b> replaces the missing sub-module in the main module <b>%2</b>.", versn_unknownversions_err = "The module <b>%1</b> is unknown in the main module <b>%2</b>.", versn_module_miss_i18n_txt_err = "Internal Error: The text <b>%1</b> lack of translation in <b>%2</b> language, and/or others.", versn_module_miss_i18n_count_err = "Internal Error: There are <b>%1</b> missings in <b>%2</b> translations.", versn_module_miss_i18n_none_err = "OK, none missing translations.", versn_module_miss_i18n_trad_err = "Internal Error: Module missing i18n translation for the argument <b>i18n.%1.%2</b>.", -- versn_err_module_miss_i18n_cat = "Module missing i18n translation", versn_err_module_miss_i18n_cat = "Module with internal error", versn_module_miss_i18n_mini_err = "Error: I18n table has only <b>1%</b> translations.", versn_module_error_err = "Module with error.", -- Titles of tests versn_list_all_G_and_loaded_title = "versn.list_all_G_and_loaded() Objects in _G global space", versn_support_desk_title = "Support information: version% 1,% 2 translations in %3 languages", versn_support_desk_table = "viewer.docDropBoxTitle", versn_bind_central_modules_title = "versn.bind_central_modules_report() Versions of central libraries and modules", versn_versions_management_report = "versn.versions_management_report() Versions management report", -- versn_bind_modules_tests_title = "versn.bind_modules_test() Test for management of modules versions", versn_verif_bind_modules_report = "Binding of modules and versions control", versn_bind_modules_test_headers = "Sought versions; Used versions; Known versions; ACTUAL: Errors in the active module; SIMULATION: Errors in the active module", versn_tasks_changes_report = "versn.tasks_changes_report() Documentations, tasks and changes", versn_sort_central_modules_title = "versn.sort_central_modules_report() Sorted list of central modules and libraries.", versn_sort_central_modules_headers = "Title; Version; Date; Translations / Languages", versn_sort_central_modules_counts = "this: + %2/%3 T/L, ", versn_versions_management_title = "versn.versions_management_test() Tests of versions management.", versn_versions_management_headers = "sought; versions; process; comments", versn_try_waits_debug_T122752 = "#invoke has not loaded <b>%1</b>, but the debug of T122752 has loaded it.", versn_add_deprecated_err = "Deprecated function <b>%1(...)</b>. Replace it by <b>%2(...)</b> in the module <b>%3</b>.", versn_deprecatedFunction_tests_title= "versn.deprecatedFunction() Test: Deprecated function. Replace it in the module.", } -- versn.i18n.en versn.i18n.es = { -- Textos principales, errores y categorías de instrumentos versn_dev_running_times_title = "versn.running_times() Tiempos de ejecución y referencias para los codificadores Lua.", versn_luatables_counts = "%1 variables, %3 subtablas, %2 funciones", versn_table_dont_exists = "La tabla <b>%1</b> no existe.", versn_table_listlimit_levelmaxi = "Límite de nivel recursiveLimit = <b>%1</b>", versn_table_listlimit_max_n = "Límite de longitud max_n = <b>%1</b>", versn_antiCrash_tests_title = "versn.antiCrash() Prueba: en caso de error de ejecución, no sobrescribir la página.", versn_antiCrash_reference_label = "Referencias", versn_antiLoop_function_err = "versn.antiLoop() Error en el <b>%3</b> <b>%1()</b>, bucle n = <b>%2</>, args = ", versn_module_usage_error_cat = "Módulo con error del uso", versn_module_with_error_cat = "Módulo con error", versn_module_with_error_err = "Módulo con error", versn_with_internal_error_cat = "Módulo con interno error", -- Gestión de versiones versn_versions_no_select_altern_err = "Error de versiones: no hay selección en alternativa <b>%1</b> del módulo <b>%2</b>.", versn_versions_too_select_altern_err= "Error de versiones: <b>%1</b> selecciones en la alternativa <b>%2</b> del módulo <b>%3</b>.", versn_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>.", versn_versions_missing_module_err = "Error de versiones: módulo ausente para la versión <b>%1</b> del módulo <b>%2</b>.", versn_main_module_missing_err = "El módulo principal no es encontrado.", versn_select_unknown_module_err = "Internal error: El Modulo:<b>%1</b> faltante se reemplaza por lo normal Module:<b>%2</b>.", versn_I18N_module_no_base_err = "El módulo de traducciones <b>%1</b> no tiene ninguna versión básica.", versn_no_versions_module_err = "El <b>%1</b> módulo no está en el sistema de versiones.", versn_all_versions_tests = "Versiones aviso: <b>%1</b>, normal: <b>%2</b>, lista: <b>%3</b>.", versn_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>.", versn_missing_versions_err = "El módulo <b>%1</b> no disponible en el módulo principal <b>%2</b>.", versn_replaced_versions_err = "El módulo <b>%1</b> reemplaza el sub-módulo ausente en el módulo principal <b>%2</b>.", versn_unknownversions_err = "El módulo <b>%1</b> es desconocido en el módulo principal <b>%2</b>.", versn_module_miss_i18n_txt_err = "Error Interno: El texto <b>%1</b> falta de traducción en <b>%2</b> lengua, y / o otras.", versn_module_miss_i18n_count_err = "Error interno: Hay <b>%1</b> que falta en <b>%2</b> traducciones.", versn_module_miss_i18n_none_err = "OK, ninguno traducciones que faltan.", versn_module_miss_i18n_trad_err = "Error interno: translation faltan en Módulo i18n para el argumento <b>i18n.%1.%2</b>.", -- versn_err_module_miss_i18n_cat = "Módulo traducción i18n que falta", versn_err_module_miss_i18n_cat = "Módulo con error interno", versn_module_miss_i18n_mini_err = "Error: la tabla i18n tiene solamente <b>1%</b> traducciones.", -- Titres des pruebas versn_list_all_G_and_loaded_title = "versn.list_all_G_and_loaded() Objects en el espacio global _G", versn_support_desk_title = "Información de soporte: versión %1, %2 traducciones en %3 idiomas", versn_support_desk_table = "viewer.docDropBoxTitle", versn_bind_central_modules_title = "versn.bind_central_modules_report() Versiones de bibliotecas y módulos centrales", versn_versions_management_report = "versn.versions_management_report() Informe de gestión de versiones", -- versn_bind_modules_tests_title = "versn.bind_modules_test() Test for management of modules versions", versn_verif_bind_modules_report = "Binding of modules and versions control", versn_bind_modules_test_headers = "Sought versions; Used versions; Known versions; ACTUAL: Errors in the active module; SIMULATION: Errors in the active module", versn_tasks_changes_report = "versn.tasks_changes_report() Documentación, parches y modificaciones", versn_sort_central_modules_title = "versn.sort_central_modules_report() Lista ordenada de módulos y bibliotecas centrales.", versn_sort_central_modules_headers = "Título; Versión; Fecha; Traducciones / Idiomas", versn_sort_central_modules_counts = "esta + %2/%3 T/I, ", versn_versions_management_title = "versn.versions_management_test() Pruebas de gestión de versiones.", versn_versions_management_headers = "sought; versions; process; comments", versn_try_waits_debug_T122752 = "#invoke no ha cargado <b>%1</b>, pero la depuración de T122752 ha lo cargó.", versn_add_deprecated_err = "Función obsoleta <b>%1(...)</b>. Sustitúyala por <b>%2(...)</b> en el módulo <b>%3</b>.", versn_deprecatedFunction_tests_title= "versn.deprecatedFunction() Prueba: Función obsoleta. Sustitúyala en el módulo.", } -- versn.i18n.es versn.i18n.fr = { -- Principaux textes, erreurs et catégories des outils versn_dev_running_times_title = "versn.running_times() Temps d'exécution et références pour les Lua-codeurs.", versn_luatables_counts = "%1 variables, %3 sous-tables, %2 fonctions", versn_table_dont_exists = "La table <b>%1</b> n'existe pas.", versn_table_listlimit_levelmaxi = "Limite de niveau recursiveLimit = <b>%1</b> ", versn_table_listlimit_max_n = "Limite de longueur max_n = <b>%1</b> ", versn_antiCrash_tests_title = "versn.antiCrash() Test: en cas d'erreur en cours d'exécution, ne pas écraser la page.", versn_antiCrash_reference_label = "Références", versn_antiLoop_function_err = "versn.antiLoop() Erreur dans la <b>%3</b> <b>%1()</b>, boucle n = <b>%2</>, args = ", versn_module_usage_error_cat = "Module avec erreur d'utilisation", versn_module_with_error_cat = "Module avec erreur", versn_module_with_error_err = "Module avec erreur", versn_with_internal_error_cat = "Module avec erreur interne", -- Gestion des versions versn_versions_no_select_altern_err = "Erreur de versions : pas de sélection dans l'alternative <b>%1</b> du module <b>%2</b>.", versn_versions_too_select_altern_err= "Erreur de versions : <b>%1</b> sélections dans l'alternative <b>%2</b> du module <b>%3</b>.", versn_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>.", versn_versions_missing_module_err = "Erreur de versions : module absent pour la version <b>%1</b> du module <b>%2</b>.", versn_main_module_missing_err = "Le module principal est introuvable.", versn_select_unknown_module_err = "Internal error: Le Module:<b>%1</b> manquant est remplacé par le module normal Module:<b>%2</b>.", versn_I18N_module_no_base_err = "Le module de traductions <b>%1</b> n'a pas de version de base.", versn_no_versions_module_err = "Le module <b>%1</b> n'est pas dans le système des versions.", versn_all_versions_tests = "Versions avertissements : <b>%1</b>, normaux : <b>%2</b>, liste : <b>%3</b>.", versn_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>.", versn_missing_versions_err = "Le module <b>%1</b> manque dans le module principal <b>%2</b>.", versn_replaced_versions_err = "Le module <b>%1</b> remplace le sous-module absent dans le module principal <b>%2</b>.", versn_unknownversions_err = "Le module <b>%1</b> est inconnu dans le module principal <b>%2</b>.", versn_module_miss_i18n_txt_err = "Erreur interne : Le texte <b>%1</b> manque de traduction en langue <b>%2</b>, et/ou d'autres.", versn_module_miss_i18n_count_err = "Erreur interne : Il y a <b>%1</b> manques parmi <b>%2</b> traductions.", versn_module_miss_i18n_none_err = "OK, aucune traduction manquante.", versn_module_miss_i18n_trad_err = "Erreur interne : manque de traduction pour l'argument <b>i18n.%1.%2</b>.", -- versn_err_module_miss_i18n_cat = "Module manquant de traduction i18n", versn_err_module_miss_i18n_cat = "Module avec erreur interne", versn_module_miss_i18n_mini_err = "Erreur interne : La table i18n n'a que <b>%1</b> traductions.", versn_module_error_err = "Module avec erreur", -- Titres des tests versn_list_all_G_and_loaded_title = "versn.list_all_G_and_loaded() Objects dans l'espace global _G", versn_support_desk_title = "Informations de soutien: version %1, %2 traductions en %3 langues", versn_support_desk_table = "viewer.docDropBoxTitle", versn_bind_central_modules_title = "versn.bind_central_modules_report() Versions des bibliothèques et modules centraux", versn_versions_management_report = "versn.versions_management_report() Rapport de gestion des versions", -- versn_bind_modules_tests_title = "versn.bind_modules_test() Test de la gestion des versions des modules", versn_verif_bind_modules_report = "Liaison des modules et contrôle des versions", versn_bind_modules_test_headers = "Versions demandées; Versions utilisées; Versions connues; ACTUEL : Erreurs dans le module actif; SIMULATION : Erreurs dans le module actif", versn_tasks_changes_report = "versn.tasks_changes_report() Documentations, tâches et modifications", versn_sort_central_modules_title = "versn.sort_central_modules_report() Liste triée des modules et bibliothèques centraux.", versn_sort_central_modules_headers = "Titre; Version; Date; Traductions / Langues", versn_sort_central_modules_counts = "ceci: + %2/%3 T/L, ", versn_versions_management_title = "versn.versions_management_test() Tests du management de versions.", versn_versions_management_headers = "sought; versions; process; comments", versn_try_waits_debug_T122752 = "#invoke n'a pas chargé <b>%1</b>, mais le débogage de T122752 l'a chargé.", versn_add_deprecated_err = "Fonction obsolète <b>%1(...)</b>. Remplacez-la par <b>%2(...)</b> dans le module <b>%3</b>.", versn_deprecatedFunction_tests_title= "versn.deprecatedFunction() Test: Fonction obsolète. Remplacez-la dans le module.", } -- versn.i18n.fr versn.i18n.hu = { versn_support_desk_title = "Támogatási információk: Version %1, %2 fordítás en %3 nyelv", versn_support_desk_table = "viewer.docDropBoxTitle", } -- versn.i18n.hu versn.i18n.vi = { versn_support_desk_title = "Thông tin hỗ trợ: Phiên bản %1, %2 dịch en %3 ngôn ngữ khác", versn_support_desk_table = "viewer.docDropBoxTitle", } -- versn.i18n.vi versn.ModuleNS = mw.site.namespaces.Module.name .. ":" function versn.trackAllVersions(where, txt) versn.report_trackAllVersions = (versn.report_trackAllVersions or "function report_trackAllVersions ") .. viewer.ta(where, txt) return versn.report_trackAllVersions -- search .all_versions end function versn.pcallRequire(version) -- require() must not fail and block the page. if type(version) == "string" then version = string.gsub( version, versn.ModuleNS, "" ) -- normalize for always one "Module:" local bug = "Erreur Lua dans Module:Central-s-fr à la ligne 5778 : attempt to call field 'gsub' (a nil value)." version = versn.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 versn.centrobj(objt, title) -- Get checked values and types of central objects local o = {} local i18n = langs.main_i18n or versn.main_i18n if (type(loaded) == "table") or (type(loaded) == "function") then module = loaded end -- The module is well loaded in package.loaded o.val = objt o.title = title -- like Module:Author, or the versioning library o.ModuleNS = mw.site.namespaces.Module.name .. ":" if type(o.title) ~= "string" then local frame = mw.getCurrentFrame() o.title = frame:getTitle() -- get the main module name end o.is_nil = (o.type == "nil") o.type = type(o.val) o.is_function = (type(o.val) == "function") if o.is_function then o.func = o.val ; return o else o.func = nil end -- o.function = o.is_number = (type(o.val) == "number") if o.is_number then o.number = o.val ; return o else o.number = nil end -- o.number = o.is_string = (type(o.val) == "string") if o.is_string then o.table = o.val ; return o else o.table = nil end -- o.string = o.is_table = (type(o.val) == "table") if o.is_table then o.table = o.val else o.table = nil end -- o.table = -- Module or Library o.is_module = o.is_table and (1 == string.find(o.title, versn.ModuleNS, 1, true) ) -- true if the object is a library if o.is_module then o.module = o.val else o.module = nil end -- o.module = o.is_loaded = (i and o.val) and ( o.val == package.loaded[o.title] ) o.is_G = (1 and o.val) and ( o.val == _G[o.title] ) o.is_library = o.is_table and not (string.find(o.title, versn.ModuleNS, 1, true) ) -- true if the object is a library if o.is_library then o.library = o.val else o.library = nil end o.hasi18n = o.is_table and (type(o.val.i18n) == "table") -- i18n langs if o.hasi18n then o.i18n = o.val.i18n else o.i18n = nil end -- o.i18n = if o.is_library and o.hasi18n then o.is_central_library = true end -- o.i18n = o.isI18N = true and string.find(o.title, "/I18N") -- true if the title contains /I18N like Module:Author/I18N return o end -- function versn.centrobj(objt, title) function versn.get_one_module_or_library(title, given_module) -- Get a module or a library, then form and record its descriptor. -- local get, module = versn.get_one_module_or_library("Module:Central") -- basic example of use -- local get = versn.centrobj(given_module, title) local get, module, required, loaded = {} if type(title) ~= "string" then get.title = "abnormal title : " .. tostring(title) get.is_nil = 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 = versn.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.is_nil = not module -- like true or false get.is_loaded = true and package.loaded[title] -- true if the module is in package.loaded get.is_function = (type(module) == "function") -- true if the module is a function get.is_table = (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.is_library = (type(module)=="table") and not (type(module)=="function") and not (string.find(title, versn.ModuleNS, 1, true) ) 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 "", versn.ModuleNS, "") -- without Module: like versioning or Author get.versionTitle = versn.ModuleNS .. get.versionName -- normalize title like Module:Author get.is_module = string.find(get.title, versn.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.is_library then -- get.revistamp = "20010101000000" -- default libraries timestamp at 2000-01-01T00:00:00Z, see ISO 8601 time format get.revistamp = get.nowstamp get.TitleI18N = versn.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.is_module 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 = versn.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 "", versn.ModuleNS, "") -- full version name with perhaps /I18N -- get.simplename = string.gsub(get.title or "", versn.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.is_function = true -- ISfunction get.is_module = false get.is_library = false get.functionName = get.simplename -- like tostring get.pagename = "function:" .. get.simplename -- like function:tostring elseif string.find(get.title, versn.ModuleNS) then -- If the module title begin with "Module:" get.is_function = false get.is_module = true -- ISmodule get.is_library = 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 = versn.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.is_function = false get.is_module = false get.is_library = true -- ISlibrary get.libraryName = get.title -- standard library name like versioning get.versionName = get.libraryName -- like versioning get.pagename = versn.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 if not get.revistamp then get.revistamp = os.date("%Y%m%d %H%M%S") end 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 -- time4 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 "", versn.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 versn.loaded_modules_and_libraries = versn.loaded_modules_and_libraries or {} if get.i18n then table.insert(versn.loaded_modules_and_libraries, get) end -- versn.bind_main_and_sub_modules_get = versn.bind_main_and_sub_modules_get or {} versn.bind_main_and_sub_modules_get[get.title] = get return get, module -- Execution time and page: 2017-06-27 16:30:05 UTC , url = https://fr.wikisource.org/wiki/Module:Central-s-fr/Documentation -- Running times: , start in page = 141 mS , import + 0 mS , form result + 0 mS , tests + 603 mS , duration = 603 mS end -- get, module = versn.get_one_module_or_library(title, given_module) function versn.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 versn.main_i18n and langs.main_i18n only once each and never repair them then they can become stable. langs.main_i18n = langs.main_i18n or {} versn.main_i18n = langs.main_i18n local main_i18n = langs.main_i18n local i18n, lang_N, text_N = {} ,0, 0 local translations_differences = {} function versn.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 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 versn.detect_transDiff( -- Collect all differences of translations { dlang = lang, dkey = key, dfile = "previous", dtrans = main_i18n[lang][key] }, { dlang = lang, dkey = key, dfile = module_name, dtrans = val} ) 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 .. langs.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 langs.main_i18n if mw.language.isKnownLanguageTag(lang) then -- only for languages known in wikis lang_N = lang_N + 1 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 .. langs.formTestCase(", lang:<b>%1:%2:%3</b> ", lang, lang_N, text_N) end end end end t = t .. viewer.ta("lang_N", lang_N) .. viewer.ta("lang_N", text_N) return t, lang_N, text_N end -- function versn.add_one_i18n(t, module_name, module_tab) function centrobj.binded_in(object, name) -- 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 centrobj.binded_in(object, name) function centrobj.new(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. -- Install the new library, only a table. options = options or {} options.err = "" options.library = options.library or library if (type(options.library) ~= "table") then options.err = "library~=table" return library end options.name = options.name or name if (type(options.name) ~= "string") then return library end if (type(options.name) ~= "string") then options.err = "name~=string" return library end local object = library local php = nil function object.setupInterface(options) -- 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 = "" end object = object.setupInterface(options) centrobj.i18n_libraries_list = centrobj.i18n_libraries_list or {} -- Build a list of central libraries centrobj.i18n_libraries_list[options.name] = object -- options.binded_in = centrobj.binded_in(options.name, options.library) options.binded_in = centrobj.binded_in(object, options.name) -- if package.loaded[options.name] == options.library then _G[options.name] = nil end -- _G[options.name] = nil -- Locked by object.setupInterface -- return object, options.err return package.loaded[options.name], options.err -- return options.library, options.err end -- return object, err = function centrobj.new(name, library, options) function versn.setup_central_libraries(bindable_libraries, opt) -- Install central bindable libraries in package.loaded -- 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 bindable_libraries = bindable_libraries or versn.bindable_libraries versn.central_libraries_sort = versn.central_libraries_sort or {} local sorted_bind_libraries = versn.central_libraries_sort -- Record central libraries from _G space to package.loaded, using setup. activity = centrobj.new("activity", activity) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, activity) -- Record all libraries args = centrobj.new("args", args) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, args) -- Record all libraries boxview = centrobj.new("boxview", boxview) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, boxview) -- Record all libraries centrobj = centrobj.new("centrobj", centrobj) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, centrobj) -- Record all libraries datas = centrobj.new("datas", datas) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, datas) -- Record all libraries dropbox = centrobj.new("dropbox", dropbox) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, dropbox) -- Record all libraries events = centrobj.new("events", events) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, events) -- Record all libraries langs = centrobj.new("langs", langs) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, langs) -- Record all libraries lua_table = centrobj.new("lua_table", lua_table) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, lua_table) -- Record all libraries mathroman = centrobj.new("mathroman", mathroman) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, mathroman) -- Record all libraries modes = centrobj.new("modes", modes) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, modes) -- Record all libraries tableview = centrobj.new("tableview", tableview) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, tableview) -- Record all libraries testsgrp = centrobj.new("testsgrp", testsgrp) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, testsgrp) -- Record all libraries tracker = centrobj.new("tracker", tracker) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, tracker) -- Record all libraries versn = centrobj.new("versn", versn) -- Lock in _G and package.loaded table.insert(sorted_bind_libraries, versn) -- Record all libraries viewer = centrobj.new("viewer", viewer) -- Lock in _G and package.loaded local libname_libraries = {} for libname, obj in pairs(sorted_bind_libraries) do -- Record the get descriptor with others libname = obj.libname or libname if (type(obj) == "table") and (type(obj.i18n) == "table") and (type(libname) == "string") then table.insert(libname_libraries, obj) end end table.sort(libname_libraries, function (a, b) return ( a["libname"] < b["libname"] ) end ) versn.sorted_bind_libraries = libname_libraries versn.sorted_bind_libraries_t = viewer.ta("\n* #versn.sorted_bind_libraries", #versn.sorted_bind_libraries) local title, description = "", "" local object, library, get = {}, {}, {}, {}, {} for i, object in ipairs(libname_libraries) do -- Record the get descriptor with others -- object = package.loaded[name] if (type(object) == "table") and (type(object.i18n) == "table") then library = object title = library["libname"] get = versn.get_one_module_or_library(title, library) -- Get a module or a library, then form and record its descriptor. library.description = library["describ_version"] -- library.description = description end end end -- function versn.setup_central_libraries(bindable_libraries, opt) function versn.bind_central_modules_report(t) -- Sorted list of central modules and libraries -- versn_sort_central_modules_title = "versn.sort_central_modules_report() Sorted list of central modules and libraries.", local memo = viewer.zzz_save_configs("versn.bind_central_modules_report") -- Save global configuration before eventual changes. local t = t or "\n* <b>versn.bind_central_modules_report()</b> -- Sorted list of central modules and libraries." local loaded_sorted = {} local args_known_props = modes.args_known_one_lib(modes.args_known, mathroman.args_known) local tabView = { -- Define a table view testGroup = args_known_props, rowGroup = {}, -- form_elem_detail = "this + %2/%3 T/L, ", form_elem_detail = "versn_sort_central_modules_counts", -- "this + %2/%3 T/L, " title_memo = "modes_bind_args_known_report_title", title_memo = "modes.bind_args_known_one_lib_report(t) Report the binding of one library known args. **", headers = "modes_bind_args_known_report_headers", headers = "key;bind;typ;need;keyword;prop;format", } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local subI18N = "" local versionDate = versn.main_versions.versionDate or "2017-12-16" case.date_vers = versionDate .. "<br>" .. string.gsub(versionDate, "-", "") return { case.key, case.bind, case.typ, case.need, case.keyword, case.prop, case.format } -- .. tostring(get.counts) end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "versn.bind_central_modules_report") -- Restore global configurations after eventual changes. return t end -- t = versn.bind_central_modules_report(t) -- local tt, vers_test = versn.bind_sub_modules(p, vers_test) -- The main module can bind all its sub-modules versions, and their /I18N sub-modules. function versn.bind_reverse_i18n_translations(main_versions, loaded_pack) -- Bind all i18n translations from libraries, modules, sub-modules and their /I18N translations sub-modules. -- Bind all translations in the exact reverse order of sub-modules binding. Then upper modules can adapt translations. local main_versions = main_versions or versn.main_versions local t = "\n* <b>versn.bind_reverse_i18n_translations()<b>" -- Todo: Bind i18n in reverse order of versn.bind_sub_modules() if (type(versn.main_module) == "table") and (type(versn.main_module.i18n) == "table") then -- Insert main i18n after any other i18n, then the main module could adapt sub_modules translations. -- table.insert(versn.loaded_modules_and_libraries, versn.main_module) end for i, get in pairs(versn.loaded_modules_and_libraries) do if (type(get.title) == "string") and (type(get.module) == "table") then versn.add_one_i18n("", get.title, get.module) -- 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 versn.add_one_i18n("", get.subI18N, get.module) -- Add with previews an i18n translations table t = t .. viewer.ta("#i18n", #get.i18n) end end return t end -- t = versn.bind_reverse_i18n_translations(main_versions, loaded_pack) function versn.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 versn.tab_elem_report(tab, key) function versn.version_warning_normal_list(d) -- From alternatives forms version, title, alias, warning, normal local d = d.versions or versn.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, versn.ModuleNS, "") -- version without Module: d.title = versn.ModuleNS .. d.version d.normal = normal d.normal_I18N = versn.ModuleNS .. normal .. "/I18N" d.normal_I18N = string.gsub(d.normal_I18N, "/I18N/I18N", "/I18N") d.version_I18N = versn.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 versn.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 versn.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 versn.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 versn.invoke_record_module_correct_T122752() verify versn.debugT122752_status -- before versn.bind_sub_modules() bind all modules and versions, and their translations local t = t or "" local gettitle = mw.getCurrentFrame():getTitle() -- get the mainmodule title versn.main_gettitle = gettitle local module if type(package.loaded[gettitle]) == "table" then versn.debugT122752_status = "Resolved" else versn.debugT122752_status = "getmodule" -- "Open" module = versn.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. versn.debugT122752_main_module = module versn.debugT122752_status = "module found" -- "Open" -- t = t .. viewer.form9user("versn_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 versn.debugT122752_status = "get corrected Resolved" end else versn.debugT122752_status = "module missing" -- "Open" -- Main error, there is no main module. end end versn.debugT122752_status = versn.debugT122752_status or "nil status" -- "Open" return t end -- function versn.invoke_record_module_correct_T122752(t) -- Bypass the bug T122752 : #invoke do not record the main module in package.loaded versn.deprecatedFunctionGroup = versn.deprecatedFunctionGroup or {} function versn.deprecatedFunction(old, new, kind, use, main_version) -- Deprecated function. Replace it in the module. local res = "" if type(langs.user_lang) == "string" then res = events.add_err("versn_add_deprecated_err", old, new, Central.versions.versionName) events.add_cat("modes_no_source_arguments_cat") end versn.deprecatedFunctionGroup = versn.deprecatedFunctionGroup or {} versn.deprecatedFunctionGroup[old] = { ["old"] = old, ["new"] = new, ["kind"] = (kind or "kind"), ["use"] = "run", ["central_version"] = Central.versions.versionName, } return res end versn.deprecatedFunction("old", "versn.deprecatedFunction", "kind", "code", Central.versions.versionName) -- Deprecated function. Replace it in the module. function versn.all_versions_text(all_versions) -- DEBUG all_versions = all_versions or versn.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 versn.sort_central_modules_report(t) -- Sorted list of central modules and libraries -- versn_sort_central_modules_title = "versn.sort_central_modules_report() Sorted list of central modules and libraries.", -- versn_sort_central_modules_headers = "Title; Version; Date; Translations / Languages", local memo = viewer.zzz_save_configs("versn.sort_central_modules_report") -- Save global configuration before eventual changes. local t = t or "\n* <b>versn.sort_central_modules_report()</b> -- Sorted list of central modules and libraries." local loaded_sorted = {} for key, elem in pairs(versn.loaded_modules_and_libraries) do -- if elem.is_module then elem.pagename = "Module:" .. elem.versionName end -- Locate translations example in Module:Central/I18N -- if elem.is_library then elem.pagename = "Library:" .. elem.versionName end -- Locate translations example in Module:Library/versioning/I18N if elem.hasi18n and elem.is_library then table.insert(loaded_sorted, elem) end if elem.hasi18n and elem.is_module then table.insert(loaded_sorted, elem) end if versn.loaded_modules_and_libraries[elem.subI18N] then elem.has_I18N = true end end -- loaded_modules_and_libraries local loaded_pack, loaded_txt, modu = versn.loaded_modules_and_libraries -- loaded_sorted = versn.loaded_modules_and_libraries versn.loaded_modules_track = "\n* versn.loaded_modules_track : " .. viewer.ta("#versn.loaded_modules_and_libraries", #versn.loaded_modules_and_libraries) -- t = t .. "\n* List versn.actual_modules : " .. versn.actual_modules t = t .. versn.loaded_modules_track table.sort(versn.loaded_modules_and_libraries, function (a, b) return ( a.pagename < b.pagename ) end ) local tabView = { -- Define a table view testGroup = loaded_sorted, -- versn.loaded_modules_and_libraries, title_memo = "versn_sort_central_modules_title", -- "versn.sort_central_modules_report() Sorted list of central modules and libraries.", headers = "versn_sort_central_modules_headers", -- "Title; Version; Date; Translations / Languages", form_elem_detail = "versn_sort_central_modules_counts", -- "this + %2/%3 T/L, " } function tabView.form_one_case(get) -- Convert a case from testGroup to rowGroup. local subI18N = "" get.counts = get.counts or "get.counts" if get.i18n then -- get.i18n local vers18 = get.versionName --; if not get.isI18N then vers18 = "" end if get.is_module then get.pagename = "Module:" .. get.versionName end -- Locate translations example in Module:Central/I18N if get.is_library then get.pagename = "Library:" .. get.versionName end -- Locate translations example in Module:Library/versioning/I18N local tabname = get.i18nRoot .. ".i18n" -- local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts("langs.main_i18n", "langs_main_i18n_languages_count", "user") local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts(tabname, "versn_sort_central_modules_counts", "user") -- get.counts = viewer.form9user("versn_sort_central_modules_counts", strings_c, tables_c) .. t get.counts = viewer.form9user("this: + %1/%2 T/L, ", strings_c, tables_c) -- get.counts = get.counts .. viewer.form9user("versn_sort_central_modules_counts", strings_c, tables_c) if get.has_I18N then get.counts = get.counts .. "<br>+ i18n in: <b>" .. get.viewI18N .. "</b>" end -- version_I18N if get.versionName and get.pagename then end return { get.viewI18N, (get.versionDate .. "<br>" .. get.shortVersion), get.counts } -- get.pagename, end end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "versn.sort_central_modules_report") -- Restore global configurations after eventual changes. return t end -- function versn.sort_central_modules_report(t) function versn.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 .. versn.tasks_changes_report_short res = res .. "\n* List of blocking tasks: " .. versn.tasks_changes_report_normal() return res -- versn.tasks_changes_report_normal -- versn_tasks_changes_report end -- function versn.tasks_changes_report(t) function versn.bind_all_i18n() -- Bind all i18n translations from all sub-modules in reverse order. -- Translate all translations in the exact reverse order, using the memorised binding order. Then upper modules can adapt translations. local t = "\n* versn.bind_all_i18n() " -- if 1 then return t end for i = #versn.central_libraries_sort, 1, -1 do -- in reverse order sub_module_name = versn.central_libraries_sort[i] -- local get = versn.loaded_modules_and_libraries[sub_module_name] local get = versn.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 versn.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 = versn.get_one_module_or_library(get.subI18N) if (type(get.title) == "string") and (type(get.i18n) == "table") then versn.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 -- t = versn.bind_all_i18n() -- Bind all sub-modules of the main module. function versn.bind_the_main_module() -- 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* versn.bind_the_main_module() " local frame = mw.getCurrentFrame() local title = frame:getTitle() -- main module, example "Auteur" local get, main_module = versn.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. versn.mainversion = title versn.central_libraries_sort = versn.central_libraries_sort or {} table.insert(versn.central_libraries_sort, title) -- Record first the main module name. versn.bind_main_and_sub_modules_get = versn.bind_main_and_sub_modules_get or {} versn.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. versn.main_module = main_module if type(main_module) == "table" and type(main_module.versions) == "table" then -- For main modules using versions management versn.main_versions = main_module.versions end local main_versions = versn.main_versions -- nil if the main module do not uses the versions management. -- if not versn.main_module then -- The main module is not found. res = res .. viewer.errorColor( viewer.form9user("versn_main_module_missing_err") ) end langs.main_i18n = langs.main_i18n or {} versn.main_i18n = langs.main_i18n return res end -- function versn.bind_the_main_module() -- Bind the main module, all sub-modules and all their i18n. function versn.bind_all_sub_modules_test() -- Test : Bind all sub-modules of the main module. versn.bind_all_sub_modules_track = "TEST" local memo = viewer.zzz_save_configs("versn.bind_central_modules_report") -- Save global configuration before eventual changes. local sub_modules = versn.sub_modules local iftest = true local t = "\n* versn.bind_all_sub_modules() TEST Bind all sub-modules of the main module." -- t = t .. "\n* bind_all_sub_modules_test <b>sub_modules</b> :" .. viewer.rough_view(sub_modules) t = t .. "\n* bind_all_sub_modules_test <b>sub_modules.sub_tries</b> :" .. viewer.rough_view(sub_modules.sub_tries) local tabView = { testGroup = sub_modules.sub_tries, title_memo = "versn.bind_all_sub_modules() Bind all sub-modules of the main module", headers = " insub; sub; sought; known; errors ", headers_class = "wikitable alternative center sortable", -- track_on = true, } -- tabView.testGroup = sub_modules.sub_tries tabView.headers = " insub; sub; sought; sub_modules.sub_tries known; errors " function tabView.form_one_case(case, all_cases) -- Convert a case from testGroup to rowGroup. return { case.insub, case.sub, case.sought, case.known, case.errors or "", } end local tt, sub_tries = versn.bind_all_sub_modules(sub_modules, iftest) -- Bind all sub-modules of the main module. -- t = t .. "\n* bind_all_sub_modules_test <b>sub_modules.sub_tries</b> :" .. viewer.rough_view(sub_modules.sub_tries) -- t = t .. tt tabView.testGroup = sub_modules.sub_tries tabView.headers = " insub; sub; sought; sub_modules.sub_tries known; errors " t = t .. tableview.new(tabView) -- Form a table view with lines and columns. -- t = t .. "\n* bind_all_sub_modules_test <b>sub_modules.sub_used</b> :" .. viewer.rough_view(sub_modules.sub_used) -- t = t .. tt tabView.testGroup = sub_modules.sub_used tabView.headers = " insub; sub; sought; sub_modules.sub_used known; errors " t = t .. tableview.new(tabView) -- Form a table view with lines and columns. -- viewer.zzz_restore_configs(memo, "versn.bind_all_sub_modules_test") -- Restore global configurations after eventual changes. return t end -- t = versn.bind_all_sub_modules_test() versn.bind_all_sub_modules_track = "SOURCE" versn.sub_modules = {} versn.sub_modules.sub_tries = { -- TEST: Bind all sub-modules of the main module. -- Normal cases: all known = "Box1, Box3 * Group;Group2;Group4 * Item;Item5;Item7" Main = { versionName = "Main", sought = "Box1;Group2;Item5", known = "Box1;Box3 * Group;Group2;Group4 * Item5;Item7", }, Box1 = { versionName = "Box1", sought = "Group2;Item5", known = "Group;Group2;Group4 * Item5;Item7", }, Box3 = { versionName = "Box3", sought = "Group2;Item", known = "Group2;Group4 * Item;Item5", }, Group2 = { versionName = "Group2", sought = "Item", known = "Item;Item5,Item7", }, Group4 = { versionName = "Group4", sought = "Item5", known = "Item;Item5,Item7", }, -- Errors cases: Box1_ms = { versionName = "Box1", sought = "Group2", known = "Group;Group2;Group4 * Item5;Item7", }, -- missing sought Box3_es = { versionName = "Box3", sought = "Group2;ItemERR", known = "Group2;Group4 * Item;Item5", }, -- erroneous sought Group2_mk = { versionName = "Group2", sought = "Item", known = "Item5,Item7", }, -- missing known Group4_ek = { versionName = "Group4", sought = "Item5", known = "Item;ItemERR,Item7", }, -- erroneous known Box3_ks = { versionName = "Box3", sought = "Group2;ItemERR", known = "Group2;Group4 * Item;Item5", }, -- known repairs erroneous sought } -- versn.bind_the_main_module() -- Bind the main module, all sub-modules and all their i18n. function versn.bind_all_sub_modules(sub_modules, iftest) -- Bind all sub-modules of the main module. local t = "\n* versn.bind_all_sub_modules() Bind all sub-modules of the main module." t = t .. "\n* versn.bind_all_sub_modules_track : " .. versn.bind_all_sub_modules_track -- Method: Record in a stack the sought sub-modules for the main_module. -- For each try of sub-module, add it in stack. That extend the stack along the procces. -- For each error, when found, add it the errors stack. At the end prioritize them and display only the most significant. -- To report that display sought known and used sub-modules like in the stack, in colors to show typical errors. -- To test these process, try normal and erroneous cases. -- These process are like a small expert system. -- The main module call this function to load needed sub-modules and translations. -- Later run versn.bind_reverse_i18n_translations() -- Bind all i18n translations in reverse order, from modules and their /I18N sub-modules local sub_modules = sub_modules local iftest = iftest or false local actual_init, sub_modules_stack local main_module, main_versions, ModuleNS local sub_tries, i_tries, sub_used, i_used local sought, known = "", "" -- Select and activate the right scenario, actual or for test. if iftest then -- TEST: Bind all sub-modules of the main module. versn.bind_all_sub_modules_track = "TEST" sub_modules.ModuleNS = "Module:" if (type(sub_modules) ~= "table") and (type(versn.sub_modules) == "table") then sub_modules = versn.sub_modules end sub_modules = mw.clone(sub_modules) sub_tries = sub_modules.sub_tries or {} sub_modules.sub_used = {} i_tries = sub_modules.i_tries or {} sub_modules.i_used = {} main_versions = sub_tries.Main -- from main test, with versions.versionName = "Main" as example else -- ACTUAL: Bind all sub-modules of the main module. versn.bind_all_sub_modules_track = "ACTUAL" main_module = versn.main_module main_versions = versn.main_versions sub_modules = {} sub_modules.ModuleNS = mw.site.namespaces.Module.name .. ":" sub_modules.sub_tries = {} sub_modules.sub_used = {} sub_modules.i_tries = {} sub_modules.i_used = {} sub_tries = sub_modules.sub_tries or {} sub_tries.Main = main_module.versions -- from main actual, with versions.versionName = "Central-s-fr" as example if (type(main_module.versions) == "table") then -- Start the version management binding for the main module. -- ACTUAL: Bind all sub-modules of the main module. -- sub_tries.Main = main_module.versions -- with versions.versionName = "Central-s-fr" as example end if (type(main_module.versions) ~= "table") then -- Start the version management binding for the main module. -- ACTUAL: Bind all sub-modules of the main module. main_versions = sub_tries.Main end if (type(main_module.versions) == "table") then -- Start the version management binding for the main module. -- ACTUAL: Bind all sub-modules of the main module. sub_tries.Main = main_module.versions -- with versions.versionName = "Central-s-fr" as example end end -- Get initial sought and known sub_modules -- local known = sub_modules.sub_tries["Main"].versions.known -- local versionName = sub_modules.sub_tries["Main"].versions.versionName -- local versionNumber = sub_modules.sub_tries["Main"].versions.versionNumber local function viewer_sub_to_i_sub(sub) -- Form a sequence table from a keyed table. local tosub = {} for key, elem in pairs(sub) do elem[insub] = key table.insert(tosub, elem) end return tosub end -- viewer_sub_to_i_sub(sub) t = t .. "\n* bind_sub_modules() start: " local sought_t = string.gsub(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 = ";" t = t .. "\n* list versioning sought.bind_sub_modules : " .. viewer.ta("main_versions.versionName", main_versions.versionName) .. viewer.ta("main_versions.sought", main_versions.sought) .. viewer.ta("sought_maxn", sought_maxn) .. "<br>" .. viewer.ta("main_versions.known", main_versions.known) .. viewer.ta("known_maxn", known_maxn) local sub_tries = {} -- Duplicate sub_tries to not disturb original sub_modules.sub_tries for key, elem in pairs(sub_modules.sub_tries) do -- alternatives = known_tab[i] local try = mw.clone(elem) -- Duplicate sub_tries to not disturb original sub_modules.sub_tries sub_tries[key] = try end local normal, altern, alternatives, kind, altern_tab local elem, module, normal, alias, name_I18N, version for i, try in pairs(sub_tries) do -- alternatives = known_tab[i] local sought_t = string.gsub(try.sought or "", " ", ";") -- ";" .. .. ";" local known_tab = mw.text.split(try.known or "", "*", true) local known_maxn = table.maxn(known_tab) -- local known_maxn = #known_tab -- local used = ";" try.errors = "" alternatives = try.known alternatives = ";" .. mw.text.trim(alternatives) .. ";" -- normalize versions between ";" -- alternatives = viewer.simpleList(alternatives) local altern_tab = mw.text.split(alternatives, "*", true) -- see _Example -- See altern alternate alternatives main_report_Example to_debug_on_20170529 Rical for i, alternate in ipairs(altern_tab) do local sought_tab = mw.text.split(sought_t, ";", true) local sought_maxn = table.maxn(sought_tab) normal = "" ; version = "" for v, altern in ipairs(sought_tab) do -- versn.actual_modules = versn.actual_modules .. ";" .. altern -- sub_modules.tried = {} -- Record all tried sub-modules of the main module. -- sub_modules.sub_used = {} -- Record all used sub-modules of the main module. -- sub_modules.errors = {} -- Record all errors/warnings in sub-modules of the main module. altern = tostring(altern) altern = mw.text.trim(altern) if v == 1 then normal = altern kind = "normal" end local try = { insub = normal, versionName = altern, ["sought"] = sought, ["known"] = known, } try.errors = "" local insert_try = false if v == 1 and string.find(";" .. sought .. ";", ";" .. altern .. ";", 1, true) then -- sub_modules.sub_used = {} -- Bind all sub-modules used in the main module. end if v == 1 and viewer.is_in_sp(altern, sought, ";") then -- normal = altern -- kind = "normal" end if v > 1 then -- and viewer.is_in_sp(altern, sought, ";") version = altern kind = "version" end if not viewer.is_in_sp(altern, sought, ";") then try.errors = try.errors .. "; altern_is_not_in_sought" end if viewer.is_in_sp("WantedError", known, ";") then -- { insub = "Box2", versionName = "Group4", sought = "Item4;Item", known = "Item2;WantedError;Item3", }, try.errors = (try.errors or "") .. "altern_is_WantedError" try.known = "Item2;Item3" -- PREVENT A RECURSIVE LOOP IN STACK end if try.versionName == "Box3" then try.versionName = "Box345" -- PREVENT A RECURSIVE LOOP IN STACK try.errors = try.errors .. "; altern_is_Box3" end if try.insub == "Group2" then try.errors = try.errors .. "; altern_is_WantedError" end if viewer.is_in_sp(altern, known, ";") then -- Try another sub_module local new_try = nil if iftest then -- In test of versions management if (type(sub_tries[altern]) == "table") then new_try = sub_tries[altern] end else -- In normal run of versions management -- Get a module or a library, then form and record a descriptor of it. local get, module = versn.get_one_module_or_library( sub_modules.ModuleNS .. altern ) if (type(get.module) == "table") and (type(get.moduleName) == "string") then -- Verify main module and versions management ability. new_try = { insub = altern, versionName = get.moduleName, ["sought"] = get.module.versions.sought, ["known"] = get.module.versions.known, errors = "" } insert_try = true end end if new_try and #sub_tries < 111 then -- Limit the number of sub_modules to 111 sub_modules.sub_tries[altern] = new_try sub_modules.i_tries = viewer_sub_to_i_sub(sub_modules.sub_tries) -- Form a sequence table from a keyed table. sub_modules.sub_used[altern] = new_try sub_modules.i_used = viewer_sub_to_i_sub(sub_modules.sub_tries) -- Form a sequence table from a keyed table. sought = sought .. ";" .. new_try.sought -- this sub_modules extend sought for inner sub_modules known = known .. " * " .. new_try.known -- this sub_modules extend known for inner sub_modules else try.errors = try.errors .. "; Limit the number of sub_modules to 111" end end end end end -- for i = known_maxn, 1, -1 do -- alternatives = known_tab[i] -- local tabView = { testGroup = sub_modules.sub_tries, title_memo = "versn.bind_all_sub_modules() Bind all sub-modules of the main module", headers = " insub; sub; sought; known; errors ", headers_class = "wikitable alternative center sortable", -- track_on = true, } -- t = t .. "\n* <b>sub_modules.i_tries</b> :" .. viewer.rough_view(sub_modules.i_tries) tabView.testGroup = sub_modules.i_tries tabView.headers = " insub; sub; sought; sub_modules.i_tries known; errors " t = t .. tableview.new(tabView) -- Form a table view with lines and columns. -- t = t .. "\n* <b>sub_modules.i_used</b> :" .. viewer.rough_view(sub_modules.i_used) tabView.testGroup = sub_modules.i_used tabView.headers = " insub; sub; sought; sub_modules.i_used known; errors " t = t .. tableview.new(tabView) -- Form a table view with lines and columns. if iftest then versn.bind_all_sub_modules_test_report = t -- TEST: Bind all sub-modules of the main module. else versn.bind_all_sub_modules_actual_report = t end -- TEST: Bind all sub-modules of the main module. return t, sub_modules.sub_used -- t, sub_modules = versn.bind_all_sub_modules(sub_modules, iftest) end -- function versn.bind_all_sub_modules(sub_modules, iftest) --[[ 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 } --]] versn.bindable_libraries = { -- New libraries to record in package.loaded[] ["activity"] = "The <b>activity</b> library supports Lua coders sub-tasks for central modules in international interactions.", ["boxview"] = "The <b>boxview</b> library easy forms boxes based on css options", ["datas"] = "The <b>datas</b> library forms some viewers for tables(in lines and columns), dropboxes, luatables...", ["dropbox"] = "The <b>dropbox</b> library forms dropboxes as objects, inside the viewer library", ["events"] = "The <b>events</b> library forms events like errors, warnings and categories.", ["langs"] = "The <b>langs</b> library supports i18n translations.", ["lua_table"] = "The <b>lua_table</b> library enhances the previous table library, to avoid ambiguities. To enhance, we could write here : lua_table = table.", ["modes"] = "The <b>modes</b> library supports modes and their options, like p.read(frame).", ["tableview"] = "The <b>tableview</b> library forms tableviews as objects, inside the viewer library", ["tracker"] = "The <b>tracker</b> library implements parametrable track objects to debug the Lua code, inside the activity library.", ["versn"] = "The <b>versn</b> library installs all central libraries, bind modules, libraries and i18n translations. Also support versions management.", ["viewer"] = "The <b>viewer</b> library forms some viewers for tables(in lines and columns), dropboxes, luatables...", ["mathroman"] = "The <b>mathroman</b> library converts roman numbers and detect errors. It is here as an example of very small central library.", } -- function versn.init(frame, mode_name, args_known, options_for_modes, QITEM) function versn.init(frame, Central_version, mode_name, args_known, options_for_modes, QITEM) -- Initializes translations, bind_libraries, bind_sub_modules, get arguments, modes, options. -- Imports arguments from wikidata, module and template with increasing priorities. local res, t = "", "" res = res .. versn.bind_the_main_module() -- Bind the main module, all sub-modules and all their i18n. langs.main_i18n_complete = false -- Mask any views to avoid failures until enough init. Central_version = Central_version or langs.Central_version -- or Central.Central_version versn.setup_central_libraries(versn.bindable_libraries) -- Actual installation of central bindable libraries in package.loaded res = res .. "\n* versn.bind_all_sub_modules()" -- Bind all sub-modules of the main module. res = res .. versn.bind_all_sub_modules() -- Bind all sub-modules of the main module. -- modes.init_options(template_options) res = res .. modes.init_modes_translate_events(frame, Central_version, mode_name, args_known, options_for_modes, QITEM) if type(translate) == "table" then langs.main_i18n = langs.main_i18n or versn.main_i18n or {} end -- Same pointers insure later same contents. -- Bind all i18n translations from libraries, modules and their /I18N translations sub-modules versn.bind_reverse_i18n_translations(main_versions, loaded_pack) -- Bind all i18n translations from modules and their /I18N translations sub-modules -- versn.bind_all_i18n() -- Bind all i18n translations from all sub-modules in reverse order. ARGS = tracker.initadd({ ["name"] = "ARGS", limit = 2, }) -- Initialize a track ARGS.add(ARGS, 1, "versn.init before import_arguments") -- ARGS.t modes.args_import = modes.init_args_mode_options(mix, mode_name, modes.args_template) -- Import and mix args mode and options from template and invoke -- S170710mix local import = modes.args_import or {} modes.args_import.title = title or modes.args_import.QITEM or modes.args_import.itemid -- or "Q535" -- if not IAMO then IAMO = tracker.initadd({ ["name"] = "IAMO", limit = 2, }) end -- Initialize a track IAMO.add(IAMO, 1, "normal_box", { modes.args_import.title, modes.args_import.QITEM, modes.args_import.itemid, "TITLE", } ) -- IAMO.t ARGS.add(ARGS, 1, "after import_arguments", { importab = import, qitem = import.QITEM, opt = import.options, uslang = import.user_lang, } ) -- ARGS.t langs.init_languages(content_lang, page_lang, user_lang, "versn.init") langs.main_i18n_complete = true -- Unmask all views after enough init. res = res .. versn.detect_mediawiki_changes() return res end -- res = res .. versn.init(frame, Central_version) function versn.versions_management_test(t) -- Test : List all loaded modules local memo = viewer.zzz_save_configs("versn.versions_management_test") -- Save global configuration before eventual changes. local t = (t or "") .. "\n* <b>versn.versions_management_test</b> : Test : List all loaded modules." t = t .. "\n* The selector = <b> Box3, Group, Item1 </b> means: check these modules versions among those available." -- t = t .. "<br>" .. lua_table.formSubCounts("versn.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;", }, } t = t .. "\n* <b>loaded_vers</b> : Table of all loaded modules, or simulation." -- t = t .. "\n* Simulate existing versions: " local tabView = { testGroup = loaded_tests, -- headers = "versn_sort_central_modules_headers", -- "Title; Version; Date; Translations / Languages", -- title_memo = "versn_sort_central_modules_title", -- "versn.sort_central_modules_report() Sorted list of central modules and libraries.", title_memo = "versn_versions_management_title", -- "versn.versions_management_test() List all loaded modules." headers = "versn_versions_management_headers", -- "sought; versions; process; comments", -- versn_versions_management_headers = "sought; versions; process; comments", headers_class = "wikitable alternative center sortable", -- track_on = true, } function tabView.form_one_case(vers_test) -- Convert a case from testGroup to rowGroup. -- local function bind_modules_test1(t, vers_test) local vers = vers_test -- versn.bind_sub_modules(main_p, vers_test) -- Bind all modules and versions local x, vers_err = versn.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.sub_used) local vers_sought = ";" .. string.gsub( (vers.sought or "-s-"), ";", ",<br>" ) .. ";" -- names in column local vers_used = viewer.simpleList(vers.sub_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 "") local case = { vers_sought, vers_used, vers_results, vers.comment } -- local case = { elem.key, elem.versionName, elem.versionDate, type(elem.i18n), elem.comment } return case end t = t .. "\n* " .. viewer.ta("Number of versions simulated:", #loaded_tests) t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "versn.versions_management_test") -- Restore global configurations after eventual changes. return t end -- function versn.versions_management_test(t) function versn.antiCrash_wanted_error() -- Bug to test versn.antiCrash() versn.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. versn.antiCrash_wanted_error_text = "antiCrash_bug_text_after_OK" return versn.antiCrash_wanted_error_text end -- function versn.antiCrash_wanted_error() -- Bug to test versn.antiCrash() function versn.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 = viewer.zzz_save_configs("versn.antiLoop") -- 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 versn.antiLoop_memo = versn.antiLoop_memo or {} versn.antiLoop_memo[funcname .. "_" .. n] = {funcname, n, func, ...} versn.antiLoop_list_t = versn.antiLoop_list_t or "" versn.antiLoop_list_t = versn.antiLoop_list_t -- versn_antiLoop_function_err = "versn.antiLoop() error in the <b>%3</b> <b>%1()</b>, loop n = <b>%2</>, args = ", .. "\n* antiLoop: " .. viewer.form9user("versn_antiLoop_function_err", tostring(funcname .. "_" .. n), n, viewer.value(func), ... ) .. langs.formTestCase(tostring(funcname .. "_" .. n), n, viewer.value(func), ... ) -- versn.antiLoop_list_t = versn.antiLoop_list_t .. "\n* antiLoop: " .. langs.formTestCase(tostring(funcname .. "_" .. n), n, viewer.value(func), ... ) events.add_cat("modes_no_source_arguments_cat") n = n - 1 viewer.zzz_restore_configs(memo, "versn.antiLoop") -- Restore global configurations after eventual changes. if n < 1 then return end return versn.antiLoop(funcname, n, func, ...) -- Loop only in limited n times. end -- function versn.antiLoop(funcname, n, func, ...) function versn.antiLoop_list(t) -- List versn.antiLoop(). local t = t or "" t = t .. "\n* List <b>versn.antiLoop()</b> :" if (type(versn.antiLoop_list_t) == "string") then t = t .. versn.antiLoop_list_t end t = t .. "<br/>" return t end -- function versn.antiLoop_list(t) -- {{#invoke:Phab.T154769.Test|antiCrash_frame}} -- Simplified code to test function versn.antiCrash(options, content_or_func, ...) -- Form the display of a running error. local memo = viewer.zzz_save_configs("versn.bind_central_modules_report") -- 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(lua_table.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( versn.antiCrash_wanted_error(...), "pcall_protect(content_or_func, ac_opt)" ) -- Try test case. -- res = res .. versn.antiCrash(ac_opt, versn.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. 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") viewer.zzz_restore_configs(memo, "versn.antiCrash") -- Restore global configurations after eventual changes. return (ac_opt.content or "ac_opt.content"), ac_opt end -- function versn.antiCrash(ac_opt, content_or_func, ...) -- Form the display of a running error. function versn.antiCrash2(ac_opt, content_or_func, ...) -- Recursive.antiCrash test 2 return versn.antiCrash(ac_opt, content_or_func, ...) end function versn.antiCrash3(ac_opt, content_or_func, ...) -- Recursive.antiCrash test 3 return versn.antiCrash2(ac_opt, content_or_func, ...) end -- {{#invoke:Phab.T154769.Test|antiCrash_frame}} function versn.antiCrash_tests() -- Main test local res = "\n* Tests of versn.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 versn.antiCrash_tests() -- Main test -- local res = "\n* Central-s-fr.T154769.Tests of versn.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 crash_tst = "\n* <b>Crash test</b> input: " ac_opt.title = crash_tst .. "a simple string : " local content_or_func = "simple test of string" res = res .. versn.antiCrash(ac_opt, content_or_func) -- ac_opt.title = crash_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 .. versn.antiCrash(ac_opt, content_or_func) -- ac_opt.title = crash_tst .. "a table = { x=1, y=2 } : " local content_or_func = { x=1, y=2 } res = res .. versn.antiCrash(ac_opt, content_or_func) -- local content_or_func = "x = wanted.runtime.error fails" ac_opt.title = crash_tst .. "wanted.runtime.error : " ac_opt.errortype = "wanted_error" res = res .. versn.antiCrash(ac_opt, "wanted_error call" ) -- ac_opt.title = crash_tst .. "Recursive antiCrash3() : " local content_or_func = "antiCrash3 test" -- Recursive.antiCrash test 3 res = res .. versn.antiCrash3(ac_opt, versn.antiCrash_wanted_error() ) return res end -- function versn.antiCrash_tests(frame) -- Main test function versn.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 = langs.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 versn.antiCrashFormError(funcname, title, errortext, ...) function versn.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 --[[ DOCUMENTATION ( 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 soughtversions = "Author3 MathRoman2 Central1" Example of 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: versn_select_unknown_module_err = "Internal error: The missing Module:<b>%1</b> is replaced by the normal Module:<b>%2</b>.", versn_I18N_module_no_base_err = "The <b>%1</b> translations module has no basic version.", versn_no_versions_module_err = "The module <b>%1</b> is not in the system of versions.", versn_all_versions_tests = "Versions warning: <b>%1</b>, normal: <b>%2</b>, listall: <b>%3</b>.", --]] function versn.versions_management_report(versions) -- Detect versions management errors and warnings after bind_sub_modules -- Todo : Use colors to easier look at errors on sough/known in versions_management_report() local memo = viewer.zzz_save_configs("versn.bind_central_modules_report") -- Save global configuration before eventual changes. local t = "\n* <b>versn.versions_management_report()</b>: Versions management details: " local versions, errs, cats = versions, "", "" t = t .. "\n* To debug later to_debug_on_20170531 Rical " -- See altern alternate alternatives main_report_Example to_debug_on_20170529 Rical if 1 then return t end if type(versions) ~= "table" then versions = versn.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 sought = "Central-s-fr;Mathroman2;TestRequire", -- Sought module and submodules versions } --]] local sought_report = viewer.simpleList(versions.sought) local known_report = viewer.simpleList(versions.known) local loaded_report = viewer.simpleList(versions.loaded_list) local used_report = viewer.simpleList(versions.sub_used) local all_once_sort = 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 all_once_tab = mw.text.split(all_once_sort, ';') -- table of words for i, name in ipairs(all_once_tab) do -- list all used names, only one each, in alphabetic order local name_I18N = string.find(name, "/I18N") -- List erroneous versions which are sought but not found: 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 .. ";" errs = errs .. ";" .. events.add_err("versn_missing_versions_err", name, versions.versionName ) .. ";" -- versn.versions_management_report(): Versions management details: -- Example of erroneous versions: (not used here) local main_report_Example = "Central-proj-fr.wikisource.org" -- red error display to_debug_on_20170529 Rical local sought_report_Example = "Central-s-fr;Mathroman2;TestRequire" -- red error display to_debug_on_20170529 Rical local known_report_Example = "Central-s-fr;Central-14 * Mathroman2;Mathroman34 * TestRequire;TestRequ * TestBug;TestBug4" cats = cats .. events.add_cat("versn_module_usage_error_cat") -- "Module with usage error" -- See altern alternate alternatives main_report_Example to_debug_on_20170529 Rical end -- List warning versions which are missing and replaced by normal: 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 .. ";" errs = errs .. ";" .. events.add_err("versn_replaced_versions_err", name, versions.versionName ) .. ";" cats = cats .. events.add_cat("versn_module_usage_error_cat") end if viewer.is_in_sp(name, all_once_sort, ";") 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("versn_unknownversions_err", name, versions.versionName ) .. ";" cats = cats .. events.add_cat("versn_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) 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) viewer.zzz_restore_configs(memo, "versn.versions_management_report") -- Restore global configurations after eventual changes. return t, errs end -- function versn.versions_management_report(versions) -- res = res .. viewer.docDropBox(selector, "versn_list_all_G_and_loaded_title", versn.list_all_G_and_loaded) function versn.list_all_G_and_loaded(t) -- List all objects in _G global space and in package.loaded local memo = viewer.zzz_save_configs("versn.list_all_G_and_loaded") -- Save global configuration before eventual changes. -- debug done S170820t_G local t, tt, hh = "", "", "" -- t or "\n* <b>versn.list_all_G_and_loaded()</b> List all objects in _G global space and in package.loaded. " local function sort_and_list_objects(Objects) local t, hh, sort_key = "", "", {} for key, obj in pairs(Objects) do table.insert( sort_key, { key, obj } ) end if #sort_key > 0 then table.sort(sort_key, function (a, b) return (a[1] < b[1]) end ) -- alphabetic sort of objects keys for i, elem in pairs(sort_key) do local title = elem[1] -- Objects[key] local obj = elem[2] -- Objects[key] -- viewer.styles_colors = "add delete discreet error invoke normal warning wikidata" -- viewer.styles_formats = "big bold small up" local o = versn.centrobj(obj, title) -- Get checked values and types of central objects if o.is_table and (type(obj.add) == "function") then t = t .. viewer.styles(title, "discreet") -- function tracker.initadd() styles elseif o.is_string then t = t .. viewer.styles(title, "normal") -- "value from mediawiki" elseif o.is_function then t = t .. viewer.styles(title, "error") -- "mediawiki library" elseif o.hasi18n then t = t .. viewer.styles(title, "add bold") -- "central module or library" elseif o.is_table then t = t .. viewer.styles(title, "add") -- "mediawiki library" else t = t .. "<b>[ " .. tostring(title) .. " ]</b> " end -- others t = t .. ", " end end hh = hh .. "\n* Styles for objects types: " ..viewer.styles("central library", "add bold")..", " hh = hh .. viewer.styles("library", "add")..", " ..viewer.styles("function", "error")..", " ..viewer.styles("track", "discreet")..", " hh = hh .. "<b>[ others ]</b>, " .. viewer.ta("objects number", #sort_key) return hh, t end hh, tx = sort_and_list_objects(_G) t = t .. "\n* Objects in <b>_G</b> global space: " .. hh .. "<br>" .. tx hh, tx = sort_and_list_objects(package.loaded) t = t .. "\n* Objects in <b>package.loaded</b>: " .. hh .. "<br>" .. tx viewer.zzz_restore_configs(memo, "versn.list_all_G_and_loaded") -- Restore global configurations after eventual changes. return t end -- function versn.list_all_G_and_loaded(t) function versn.delay_time(t1, t2, diff) -- Compute the delay from t1 to t2, or adjust t2 at t1 + diff. local t1, t2, diff = tostring(t1), tostring(t2), tostring(diff) local t = t or "\n* <b>versn.delay_time()</b> Compute the delay from t1 to t2, or adjust t2 at t1 + diff." -- Adjust year+- month+- day+- h+- min+- s+- until OK. return t1, t2, diff, t -- local t1, t2, diff, t = versn.delay_time(t1, t2, diff) end -- function versn.delay_time(t1, t2, diff) function versn.is_O_8601_time_format_like(time_in, form) -- Compute the delay from t1 to t2, or adjust t2 at t1 + diff. -- 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 local nowtime = os.date("%Y-%m-%d %H:%M:%S") -- in ISO 8601 time format like : 1977-04-22T01:00:00 local nowtable = os.date("*t") or {} -- in ISO 8601 time format like : 1977-04-22T01:00:00 local nowclock_rest = os.clock(nowtable) or {} -- seconds from time 00:00 if nowtable.day then local nowclock = {} -- seconds from time 00:00 nowclock.second = math.floor(nowclock_rest / 60) ; nowclock_rest = nowclock_rest - (nowclock.second * 60) ; nowclock.minute = math.floor(nowclock_rest / 60) ; nowclock_rest = nowclock_rest - (nowclock.minute * 60) ; nowclock.hour = math.floor(nowclock_rest / 24) ; nowclock_rest = nowclock_rest - (nowclock.hour * 24) ; nowtable.hour = nowclock.hour ; nowtable.minute = nowclock.minute ; nowtable.second = nowclock.second ; -- if nowclock.minute < 10 then nowclock.minute = "0" .. nowclock.minute end -- if nowclock.hour < 10 then nowclock.hour = "0" .. nowclock.hour end if nowtable.day < 10 then nowtable.day = "0" .. nowtable.day end if nowtable.month < 10 then nowtable.month = "0" .. nowtable.month end if nowtable.year < 10 then nowtable.year = "0" .. nowtable.year end if nowtable.year < 100 then nowtable.year = "0" .. nowtable.year end if nowtable.year < 1000 then nowtable.year = "0" .. nowtable.year end nowtime = nowtable.year .."-"..nowtable.month .."-"..nowtable.day .."-"..nowtable.hour .."-"..nowtable.minute .."-"..nowtable.second end -- http://www.lua.org/manual/5.1/manual.html#pdf-os.date -- If format starts with '!', then the date is formatted in Coordinated Universal Time. After this optional character, if format is the string "*t", then date returns a table with the following fields: year (four digits), month (1--12), day (1--31), hour (0--23), min (0--59), sec (0--61), wday (weekday, Sunday is 1), yday (day of the year), and isdst (daylight saving flag, a boolean). local form = form or "1789-12-31T23:59:55-11:44" if (type(time_in) ~= "string") then time_in = nowtime end if not time_in then time_in = nowtime end local startime = "2017-05-14 00:00:00" local form = string.gsub(form, "44", string.sub(startime, 15, 16) ) -- shift_minute, 00 for UTC local form = string.gsub(form, "11", string.sub(startime, 15, 16) ) -- shift_hour, 00 for UTC local form = string.gsub(form, "55", string.sub(startime, 15, 16) ) -- second local form = string.gsub(form, "59", string.sub(startime, 15, 16) ) -- minute local form = string.gsub(form, "23", string.sub(startime, 12, 13) ) -- hour local form = string.gsub(form, "31", string.sub(startime, 9, 10) ) -- day local form = string.gsub(form, "12", string.sub(startime, 6, 7) ) -- month local time_out = string.gsub(form, "1789", string.sub(startime, 1, 4) ) -- year return time_out, nowtime -- local time_out, nowtime = versn.is_O_8601_time_format_like(time, form) end -- function versn.is_O_8601_time_format_like(time, form) function versn.wiki_modules_users_stat() -- Modules, users and stats in this wiki. local mwuri = mw.uri.new() local res = "" res = res .. "\n*. <b>Modules</b>: " res = res .. viewer.ta("Main module", tostring(versn.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 -- Wivivi : Where vikipedia is read in which language ? https://stats.wikimedia.org/wikimedia/animations/pageviews/wivivi.html res = res .. "\n* [https://stats.wikimedia.org/wikimedia/animations/pageviews/wivivi.html <b>Wivivi</b>: In which language do you read Wikipedia?] " -- 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' } ) https://gerrit.wikimedia.org/r/#/c/189324/ res = res .. viewer.ta("CONTENTLANGUAGE", modes.frame:preprocess( "{{CONTENTLANGUAGE}}" ) ) -- res = res .. "\n* <b>User language</b>: " -- T173207: Implement Lua alternative to {{int:Lang}}. res = res .. viewer.ta("⧼Lang⧽", "⧼Lang⧽" ) res = res .. viewer.ta("⧼es⧽", "⧼es⧽" ) -- https://fr.wikisource.org/w/index.php?title=MediaWiki:Lang/en&action=edit -- To support {{int:Lang}} for central modules. Equivalent to calling mw.getCurrentFrame():preprocess("{{int:Lang}}") in Lua. res = res .. viewer.ta("{{int:Lang}}", modes.frame:preprocess( "{{int:Lang}}" ) ) 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("T161875 usecodeeditor", mw.user.options.get('usecodeeditor') ) res = res .. mw.user.options.get( 'usebetatoolbar' ) -- can be used to check if a user is using the wikiEditor res = res .. mw.user.options.get( 'gender' ) -- // Get several preferences res = res .. mw.user.options.get( 'usebetatoolbar' ) -- can be used to check if a user is using the wikiEditor res = res .. mw.user.options.get( 'language' ) -- !== 'de' ) { mw.loader.load( 'mediawiki.notify' ) -- Extension talk:TocTree res = res .. mw.user.options.get( 'showtoolbar' ) res = res .. mw.user.options.get( 'compact-language-links' ) res = res .. mw.user.options.get( 'toc-expand' ) -- User:Lavaner/common.js : using( 'user.options', function () { if ( mw.user.options.get( 'usebetatoolbar' ) && mw.user.options.get( 'showtoolbar' ) ) -- 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 ]], [http://www.lua.org/manual/5.1/manual.html 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("main_title", modes.main_title ) res = res .. viewer.ta("label", mwuri.label ) -- local label = modes.args_final.label or modes.main_title or modes.args_final.QITEM or modes.args_final.itemid res = res .. viewer.ta("text", mwuri.text ) 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 versn.wiki_modules_users_stat(t) function versn.Mediawiki_version() -- Form Mediawiki_version, in error color if it changes. local currentVersion = tostring(mw.site.currentVersion) local vers, time, color, discreet, currentview = "0.0", "00:00:00", "color", "discreet", "currentview" for k, vrs in pairs( versn.Mediawiki_Versions ) do if vrs.verstime > time then time = vrs.verstime vers = vrs.versid end end color = viewer.errorColor(currentVersion) discreet = viewer.discreetColor(currentVersion) -- if currentVersion ~= versn.Mediawiki_version_memo then currentVersion = viewer.errorColor(currentVersion) end currentview = currentVersion if currentVersion ~= versn.Mediawiki_version_memo then currentview = color end currentview = viewer.ta("[[ Special:Version | Local MediaWiki version ]]", currentview .. " time=" .. time) versn.Mediawiki_version_memo = vers versn.Mediawiki_version_time = time versn.Mediawiki_version_color = color versn.Mediawiki_version_discreet = discreet versn.Mediawiki_version_currentview = currentview return currentview end -- function versn.Mediawiki_version() -- Discreet main version function versn.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* versn.running_times() Modules, users and stats in this wiki" local mwuri = mw.uri.new() res = res .. "\n* " .. versn.Mediawiki_version() -- Modules, users and stats in this wiki. res = res .. "\n* " .. versn.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 on 2017-05-14 : , Local MediaWiki version = 1.30.0-wmf.1 (3fe82bc) . Modules: , Main module = Module:Central-s-fr , Proto version = Central-proj-fr.wikisource.org , Modules in this wiki = 84 Users activities: , activeUsers = 215 , Administrators(sysop) = 15 , bots(bot) = 24 , patrollers(patroller) = 44 , bureaucrats(bureaucrat) = 1 Statistics on users and content mw mw:Special:ListGroupRights Last revision: , REVISIONTIMESTAMP = 20170403210950 , REVISIONUSER = Rical Languages: , PAGELANGUAGE = fr , CONTENTLANGUAGE = fr User language: , USERLANG = Modèle:USERLANG , UILANGCODE = ⧼LangX⧽ , USERLANG = Modèle:USERLANG , USERLANGUAGE = Modèle:USERLANGUAGE , USERIFCODE = Modèle:USERIFCODE Scribunto: , Extension:Scribunto , Lua manual , version : = Lua 5.1 Server mw.uri.new: , protocol = nil , user = nil , password = nil , host = fr.wikisource.org , port = nil , path = /wiki/Module:Central-s-fr/Documentation , query = nil , fragment = nil , userInfo = nil , hostPort = fr.wikisource.org , authority = fr.wikisource.org , queryString = nil , relativePath = /wiki/Module:Central-s-fr/Documentation Execution time and page: 2017-05-14 19:42:52 UTC , url = https://fr.wikisource.org/wiki/Module:Central-s-fr/Documentation Running times: , start in page = 88 mS , import + 0 mS , form result + 0 mS , tests + 143 mS , duration = 143 mS --]] return res end -- function versn.running_times(no_view, res, time1, time2, time3, time4) -- cut_libraries -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- The Library:viewer forms some viewers for tables(in lines and columns), dropboxes, recursive luatables... -- The name"lua_table" avoids ambiguities. To enhance rather than add it, we could write here : lua_table = table. -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- - - - ------------------ - - - - ------------------ - - - - ----------------------------- -- viewer = {} -- already declared by Scribunto, see centrobj.new() -- Record a library in package.loaded -- Translations for viewer library viewer.i18n = {} viewer.i18n.en = { -- Main string, 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_default_headers = "A; B; C; D; E", viewer_tableView_tests_title = "tableview.new() 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 : tableview.new() 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_default_headers = "A; B; C; D; E", viewer_tableView_tests_title = "tableview.new() 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: tableview.new() 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_default_headers = "A; B; C; D; E", viewer_tableView_tests_title = "tableview.new() 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: tableview.new() é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 versn.antiLoop(funcname, n, func, ...) -- Limit the n-th reentrant call of any function. -- Try versn.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 versn.antiLoop_list(t) -- List versn.antiLoop(). function viewer.is_in(word, text) -- The word is it in the text, even inside another word? local bug = "Erreur Lua dans Module:Central-s-fr à la ligne 7444 : attempt to call field 'find' (a nil value)." 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) -- Form a string to discribe a value like: true, 123.456, "abcd", func(), table{}. local typ, view = type(value), "-" -- options: ' nonil noquote ' 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 if viewer.is_in('noquote', form) then view = value else view = '"' .. value .. '"' end elseif typ == "table" then view = "table{}" elseif typ == "nil" then view = "nil" if viewer.is_in('nonil', form) then view = "" end end return view end -- function viewer.value(value, form) 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 -- 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. ["mask"] = "white", -- Usual fonctional style for mask standard in white. ["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. } viewer.usual_colors_memo = "add delete discreet error invoke mask normal warning wikidata" 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) viewer.styles_colors = "add delete discreet error invoke normal warning wikidata" viewer.styles_formats = "big bold small up" function viewer.styles(t, styles) -- Fonctional styles for usual cases. local t = tostring(t) local styles_split = mw.text.split(styles, "%s") for i, style in ipairs(styles_split) do if viewer.is_in_sp(style, viewer.styles_colors) then t = viewer.usualColor(t, style) end if viewer.is_in_sp(style, viewer.styles_formats) then if style == "big" then t = "<big>" .. t .. "</big>" end if style == "bold" then t = "<b>" .. t .. "</b>" end if style == "small" then t = "<small>" .. t .. "</small>" end if style == "up" then t = "<up>" .. t .. "</up>" end end end return t end -- function viewer.styles(t, opt) 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 -- Form also functional styles for boxes -- viewer.form_functionalCSS(CSSstructure, opt) -- Form the CSS structure based upon viewer.central_functionalCSS 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) dropbox.css_options = { -- Conventional CSS parameters : See -- https://en.wikisource.org/wiki/Template:DropBox#Parameters cssview = false, -- cssview : display values of options bg1 = "#FFFFFF", -- bg1 : the background-color for the heading fs1 = "100%", -- font-size: 100%; fw1 = "left", -- fw1 : the font-weight for the heading ta1 = "left", -- ta1 : the text-align for the heading tc1 = "black", -- tc1 : the text-color for the heading -- bg2 = "#FFFFFF", -- bg2 : the background-color for the body fs2 = "100%", -- font-size: 100%; fw2 = "left", -- fw2 : the font-weight for the body ta2 = "left", -- ta2 : the text-align for the body tc2 = "black", -- tc2 : the text-color for the body -- -- <div id="NavFrame10" class="NavFrame" style="clear:both; margin-bottom:1em; width:99%; border-style:solid; border-radius:0px 0px 0px 0px; border-color:#AAAAAA; background-color:#FFFFFF;" title="▼ /▶ "> border_color = "#AAAAAA", -- border-color : the text-color for the heading and the body border_radius = "0px 0px 0px 0px", -- border-radius: "15px 50px 30px 5px" : add rounded corners to an element. display = "inline", -- display: inline : results with free line break. block : results without line break. float = "none", -- float : should the box be floated? (left, right, or none) headType = "h4", -- headType : allows you to set the box header to (say) "h4", which means it will be included in the table of contents. This is provided as an explicit parameter because if you just surround the title with header tags, e.g. <h4>Box 1.1</h4> height = "1.6em", -- height hidden = "true", -- hidden : set this to any string (e.g. hidden=true) to have the box hidden by default margin_all = "0px", -- all margin margin_bottom = "1em", -- margin-bottom style = "0px 0px 0px 0px", -- style : HTML/CSS affectionados only: any other css style arguments for the whole box width = "99%", -- width : the width of the box, e.g. 33% image = "Flag_of_France.svg", 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" translations } function viewer.boxview.form(txt, css) -- Make an easy box builder based on css options -- S170723vbv -- 20170807 restructure this for a table of box elements s[n]bg, s[n]fs, s[n]tc. S170906tbe -- 20170807 restructure this in a hierarchic structure of objects able to build a box, a table, a circular or a spiral graph. -- 20170807 restructure example : table4 = tab.cols[2].style -- style of the column 2 of the table4. -- 20170807 restructure example : box7 = box.row[3].cols[1].spir[11].curv[2].style S170910ssb -- style of the curve 2 of 11th petal of the flower in the column 1 of the row 3 of the box7. S170910ssb local t = "" -- see ta1 local txt = tostring(txt) -- local css = mw.clone(css) if type(css) ~= "table" then css = {} end -- css is a table of options local actual_options = mw.clone(dropbox.css_options) -- protect Conventional css parameters : -- See -- https://en.wikisource.org/wiki/Template:DropBox#Parameters local drop_opt = drop_options or {} -- protect Conventional css parameters : See -- https://en.wikisource.org/wiki/Template:DropBox#Parameters if (type(drop_opt) == "table") then for key, val in pairs(drop_opt) do actual_options[key] = val end end if (type(drop_opt) == "table") then for key, val in pairs(drop_opt) do actual_options[key] = val txt = string.gsub(txt, "<"..key..">", val) end end return t, css end function viewer.boxview_test(t) -- Tests: Make an easy box builder -- S170723vbv local t = "\n* viewer.boxview_test(): Tests: Make an easy box builder " -- if 1 then return t end local css = dropbox.css_options -- bg1 = "#FFFFFF", -- bg1 : the background-color for the heading -- fs1 = "100%", -- font-size: 100%; -- fw1 = "left", -- fw1 : the font-weight for the heading -- ta1 = "left", -- ta1 : the text-align for the heading -- tc1 = "black", -- tc1 : the text-color for the heading -- local css = mw.clone(css) local titl = mw.clone(css) ; titl.ta1 = "center" ; titl.headType = "h2" local descr = mw.clone(css) ; descr.ta2 = "left" local imgcss = mw.clone(css) ; imgcss.border_radius = "3px 3px 3px 3px" ; imgcss.margin_all = "5px" local link1 = mw.clone(css) ; link1.ta1 = "left" ; link1.ta1 = "left" ; link1.ta1 = "left" local linkdatas = mw.clone(css) ; linkdatas.ta1 = "left" ; linkdatas.ta1 = "left" ; linkdatas.ta1 = "left" local links = mw.clone(css) ; links.ta1 = "" ; links.ta1 = "" ; links.ta1 = "" local boxcss = mw.clone(css) ; links.ta1 = "" ; links.ta1 = "" ; links.ta1 = "" if type(css2) ~= "table" then css2 = {} end -- css is a table of options local t = t .. "\n* viewer.boxview_test(): " local txt = "\n* viewer.boxview_test(): headType=<b><headType></>, ta1=<b><ta1></>, ta2=<b><ta2></>, imgcss=<b><imgcss></> " -- if 1 then return t .. txt end local txt = viewer.boxview.form(txt, titl) local txt = viewer.boxview.form(txt, descr) local txt = viewer.boxview.form(txt, link1) local txt = viewer.boxview.form(txt, imgcss) if 1 then return t .. txt end local box_link2 = viewer.boxview.form(txt, link2) local box_link3 = viewer.boxview.form(txt, link3) local box_link4 = viewer.boxview.form(txt, link4) local box_links = viewer.boxview.form(box_link1 .. box_link2 .. box_link3 .. box_link4, links) local box_img = viewer.boxview.form("Flag_of_France.svg", imgcss) local box_content = box_links .. box_title .. box_img local box_test = viewer.boxview.form(box_content, boxcss) return t .. txt end -- function viewer.boxview_test(txt, css) function mw.text.sortCommaList(list, sep1, sep2, sep3) -- Sort without repeat a list with separators like "Central01;versn 2.4;tools;two words" versn.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 t = t or "" 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 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) -- Tests of deprecated function. local memo = viewer.zzz_save_configs("versn.bind_central_modules_report") -- Save global configuration before eventual changes. local t = t or "" t = t .. "\n* Test <b>versn.deprecatedFunction_tests</b> :" -- versn.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) -- -- versn.deprecatedFunction("tools.luaTabStruc", "lua_table.structure") local func, argmt, old, new = lua_table.structure, {}, "tools.luaTabStruc", "lua_table.structure" local test = func(argmt) t = t .. "\n\n* Test 2 : " .. viewer.ta("old", old) .. viewer.ta("new", new) .. viewer.ta("test", test) versn.deprecatedFunctionGroup = versn.deprecatedFunctionGroup or {} -- table.insert(versn.deprecatedFunctionGroup, { -- old, new, versn.main_versions.versionName, "test") -- } ) local version = versn.main_versions.versionName -- Save global configuration before eventual changes. local t = t or "\n* <b>Tests of main central modules:</b> :" local tabView = { testGroup = { -- versn.deprecatedFunctionGroup { "versn.bind_sub_modules", "versn.bind_main_module", version, "test" }, -- { "tools.luaTabStruc", "lua_table.structure", version, "test" }, { "p.form_result", "viewer.main_view", version, "test" }, { "tools.option", "modes.option", version, "test" }, { "tools.closeCatsErrs", "events.close", version, "test" }, { "tools.initCatsErrs", "events.memorize", version, "test" }, { "versn.bind_sub_modules", "versn.bind_main_module", version, "test" }, { "tools.luaTabStruc", "lua_table.structure", version, "test" }, headers = "old; new; versionName; kind", } } function tabView.form_one_case(case) -- 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 t = "\n* Test <b>versn.deprecatedFunction()</b> :" t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "viewer.simpleList_test") -- Restore global configurations after eventual changes. return t end -- function viewer.simpleList_test(t) --]] function viewer.simpleList_test(t) -- Form whole the result for users and Mediawiki tests cases. S170801rtc -- function testsgrp.getTestProvider(), .init(), .gettestsgroups(), .getcases(), .resultdiffs(), .form(), .recursive_tests(), viewer.form9en(), local memo = viewer.zzz_save_configs("viewer.simpleList_test") -- Save global configuration before eventual changes. t = t or "\n* viewer.simpleList_test(t) Form whole the result for users and Mediawiki tests cases." local t, tt = t or "\n* viewer.simpleList_test(t) Tests: Form whole the result for users and Mediawiki tests cases.", "-" -- if 1 then return t end local tt, errors = testsgrp.errors_init(testsgrp.allstatus) t = t .. "\n* ".. (tt or "*tt*") testsgrp.gettestsgroups_recursiveLimit = 11 -- To protect against unsought loops in recursive testsGroups. testsgrp.main_groupname = "mathroman.testsGroups" testsgrp.main_groupname = "testsgrp.main_tests_groups" if (type(EXD) ~= "table") or (type(EXD.add) ~= "function") then EXD = tracker.initadd({ ["name"] = "EXD", ["limit"] = 2 }) end -- Initialize a track EXD = tracker.initadd({ ["name"] = "EXD", ["limit"] = 2 }) -- Initialize a track EXD.add(EXD, 1, "viewer.simpleList_test main_groupname 6387", { ["main_groupname"] = testsgrp.main_groupname, ["recursiveLimit"] = testsgrp.gettestsgroups_recursiveLimit, } ) local kept_groups, tt = testsgrp.gettestsgroups(testsgrp.main_groupname) -- Get groups of tests cases for MW and users. testsgrp.kept_groups = kept_groups -- t = t .. "\n* ".. viewer.rough_view(kept_groups) t = t .. "\n* ".. (tt or "-tt-") local result_cases = {} local result_cases = testsgrp.getcases(kept_groups) -- Run testcases for Mediawiki. testsgrp.result_cases = result_cases -- local n = 5 local mw_cases, tt = testsgrp.getTestProvider(result_cases, n) -- T176362 : phabtask : Enhance Mediawiki informations on versions for a better support -- T176362 : phabtask : Implement getTestProvider in Scribunto to enhance central modules stability if (type(EXD) ~= "table") or (type(EXD.add) ~= "function") then EXD = tracker.initrack({ ["name"] = "EXD", ["limit"] = 2 }) end -- Initialize a track t = t .. "\n* :testsgrp.autotests_group" local tabView = { testGroup = testsgrp.autotests_group, -- testsgrp.autotests_group = { -- events.testGroup tests_title = "testsgrp_getTestProvider_tests_title", -- Implement getTestProvider in central modules headers = "testsgrp_testcase_tests_headers", -- "Digital number; Roman value; Correct; Error(s)" headers = "case.name; args{}; expect{}; result{}; errors in result{} from expect{}", -- OK or error/s keys = "name;args;expect;result;errors", rowGroup = {}, ccc = {}, } t = t .. EXD.add(EXD, 1, "viewer.simpleList_test(tabView) 6410", { ["#tabView.testGroup"] = lua_table.level_count(tabView.testGroup), ["#result_cases"] = lua_table.level_count(tabView.testGroup), } ) -- Form a table view with lines and columns.s function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. t = t .. EXD.add(EXD, 1, "form_one_case before run_one_case 6413", { ["case.name"] = case.name, ["#case.result"] = tostring(#case.result), } ) case = testsgrp.run_one_case(case) -- Run one case for users and Mediawiki tests cases.getTestProvider_tests t = t .. EXD.add(EXD, 1, "form_one_case after run_one_case 6415", { ["case_id"] = case.name, ["args[1]"] = case.args[1], ["#case.result"] = #case.result, ["case.result"] = viewer.rough_view(case.result), ["case.errors"] = tostring(case.errors), } ) if (type(case.result) == "table") and (type(case.result.diffs_jobs) == "string") then t = t .. EXD.add(EXD, 1, "getTestProvider_tests form_one_case 6417", { ["RES.ERROR"] = "RES.ERROR", ["case.result.jobs"] = case.result.jobs, } ) elseif (type(case.result) == "table") then t = t .. EXD.add(EXD, 1, "getTestProvider_tests form_one_case 6419", { ["RES.normal"] = "RES.normal", ["#case.result"] = #case.result, ["jobs"] = "nil", } ) else -- testsgrp.autotests t = t .. EXD.add(EXD, 1, "getTestProvider_tests form_one_case 6421", { ["RES.ERROR"] = "RES.ERROR", ["case.result"] = "nil", } ) end -- EXD = testsgrp.resultdiffs(EXD) -- Compare expected and actual results of one test case. function testsgrp.run_one_case( if (type(case.result) == "table") and (type(case.result.jobs) == "string") then EXD.add(EXD, 1, "getTestProvider_tests form_one_case 6516", { ["RES.ERROR"] = "RES.ERROR", ["#case.result"] = #case.result, ["jobs"] = case.result.jobs, } ) end case.res1 = case.result[1] or "res1" -- DEBUG : mathroman.int2roman() can fail without blocking page. case.err2 = case.result[case.errorsKey] or "err2" -- DEBUG : mathroman.int2roman() can fail without blocking page. case.errors = case.errors or status.OK case.errors = viewer.ta("case.res1", case.res1) .. viewer.ta("case.err2", case.err2) .. viewer.ta("case.errors", case.errors) -- headers = "case.name; args{}; expect{}; result{}; errors in result{} from expect{}", -- OK or error/s return { case.name, viewer.rough_view(case.args), viewer.rough_view(case.expect), viewer.rough_view(case.result), case.errors } end -- errors in result t = t .. EXD.add(EXD, 1, "tableview.new EXD BEFORE 6525", { ["#kept_groups"] = lua_table.level_count(kept_groups), ["#rowGroup"] = #tabView.rowGroup, } ) t = t .. tableview.new(tabView) -- Form a table view with lines and columns. t = t .. "\n* :testsgrp.autotests_group end" t = t .. EXD.add(EXD, 1, "tableview.new EXD AFTER 6527", { ["#kept_groups"] = lua_table.level_count(kept_groups), ["#rowGroup"] = #tabView.rowGroup, } ) -- Counts of selected and sorted sub-tasks: , #testGroup = 43 , #rowGroup = 0 -- function obj.add(EXD, 1, "tableview.new EXD AFTER 6527", { ["#kept_groups"] = lua_table.level_count(kept_groups), ["#rowGroup"] = #tabView.rowGroup, } ) t = t .. "\n* EXD.t = " .. EXD.t t = t .. "\n* :viewer.simpleList_test(txt) end" -- EXD: , in = errors_init begin 6531 , #allstatus = 7 , #errors = 7 , #allpublics = 1 , #alldescriptions = 7 viewer.zzz_restore_configs(memo, "viewer.simpleList_test") -- Restore global configurations after eventual changes. return t end -- t = t .. viewer.simpleList_test(t) function viewer.simpleList_test(t) -- Test of : Sort without repeat a list with separators like "Central01;versn 2.4;tools;two words" local memo = viewer.zzz_save_configs("viewer.simpleList_test") -- 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.' -- S170614tva 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() viewer.zzz_restore_configs(memo, "viewer.simpleList_test") -- 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 local 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 = viewer.zzz_save_configs("viewer.format_time_tests") -- 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 :" -- S170614tva 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() viewer.zzz_restore_configs(memo, "viewer.format_time_tests") -- Restore global configurations after eventual changes. return t end -- function viewer.format_time_tests(t) function viewer.parts_of_date_tests(t) local memo = viewer.zzz_save_configs("viewer.parts_of_date_tests") -- Save global configuration before eventual changes. local function date_to_part_test_1(t, nom, date, part) local 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:" -- S170614tva 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 viewer.zzz_restore_configs(memo, "viewer.parts_of_date_tests") -- Restore global configurations after eventual changes. return t end -- function viewer.parts_of_date_tests(t) function viewer.trans9vars(translations, ref, ...) -- Replace %1 to %9 by tostring( argN ) from arguments, without any ambiguity in any string. local t, S9, repl, val, charN = "", "", "", "", "" -- ref = ref .. "" -- Give a runtime error to debug at coding time if type(ref) ~= "string" then ref = "a;b;c;d;e;f;g" end if type(translations) ~= "table" then t = langs.formTestCase( tostring(ref), ...) -- t = "trans9notrans:" .. t return t end if type(translations[ref]) == "string" then ref = translations[ref] end local args = {...} t = ref if #args > 0 then local n = 1 for n = 9, 1, -1 do S9 = tostring(n) charN = string.find(t, "%".. S9, 1, true) if charN then -- If reference has %0 to %9 repl = tostring( args[n] or "" ) t = string.sub(t, 1, charN - 1) .. repl .. string.sub(t, charN + string.len( "%".. S9 ) ) end end end t = string.gsub(t, p.versions.versionName, langs.Central_version or Central.Central_version or "versionName") return t end -- function viewer.trans9vars(translations, key, ...) function viewer.form9en(ref, ...) -- Replace %1 to %9 by arguments. Always in english for testsgrp. if not langs.main_i18n_complete then return "" end -- Avoid to fail in init phase. local t, n = "", 0 if type(ref) ~= "string" then t = langs.formTestCase("form9en", ...) elseif type(langs.main_i18n.en[ref] == "string") then t = viewer.trans9vars(langs.main_i18n.en, ref, ...) else t = langs.formTestCase(ref, ...) end -- Default text to help to locate a bug return t end -- function viewer.form9en(ref, ...) function viewer.form9content(ref, ...) -- replace %1 to %9 by v1 to v9 in the content translation of ref, else in ref if not langs.main_i18n_complete then return "" end -- Mask or Unmask all views to avoid failures. local form, n = "", 0 if type(ref) ~= "string" then form = langs.formTestCase("form9content", ...) end if (type(langs.content_translations) == "table") then -- Only after versn.bind_reverse_i18n_translations() if langs.content_translations[ref] then -- Normal case form = form .. viewer.trans9vars(langs.content_translations, ref, ...) elseif langs.main_i18n.en[ref] then -- try english translation in case another lang mises of translation form = form .. viewer.trans9vars(langs.main_i18n.en, ref, ...) else form = form .. langs.formTestCase(ref, ...) end else form = form .. langs.formTestCase(ref, ...) end return form end -- function viewer.form9content(ref, ...) function viewer.form9page(ref, ...) -- Replace %1 to %9 by tostring( argN ) from arguments, without any ambiguity in any string. if not langs.main_i18n_complete then return "" end -- Mask or Unmask all views to avoid failures. local form, n = "", 0 if type(ref) ~= "string" then form = langs.formTestCase("form9page", ...) end local form, n = "", 0 if not langs.main_i18n_complete then return "" end -- Mask or Unmask all views to avoid failures. if (type(langs.page_translations) == "table") then -- Only after versn.bind_reverse_i18n_translations() if langs.page_translations[ref] then -- Normal case form = form .. viewer.trans9vars(langs.page_translations, ref, ...) elseif langs.main_i18n.en[ref] then -- try english translation in case another lang mises of translation form = form .. viewer.trans9vars(langs.main_i18n.en, ref, ...) else form = form .. langs.formTestCase(ref, ...) end else form = form .. langs.formTestCase(ref, ...) end return form end -- function viewer.form9page(ref, ...) function viewer.form9user(ref, ...) -- Replace %1 to %9 by arguments, without any ambiguity in any string. if not langs.main_i18n_complete then return "" end -- Avoid to fail in init phase. local t, n = "", 0 if type(ref) ~= "string" then return langs.formTestCase("form9user", ...) end if (type(langs.user_translations) == "table") then -- Normal translation if langs.user_translations[ref] then ref = langs.user_translations[ref] end -- Normal ref to translate t = viewer.trans9vars(langs.user_translations, ref, ...) elseif langs.main_i18n.en[ref] then -- If a lang mises of translations, try English. if langs.main_i18n.en[ref] then ref = langs.main_i18n.en[ref] end -- Normal ref to translate t = viewer.trans9vars(langs.main_i18n.en, ref, ...) else t = langs.formTestCase(ref, ...) end -- Default text to help to locate a bug return t end -- function viewer.form9user(ref, ...) function viewer.form9user_test(t) -- Tests of viewer.form9user_test(). local memo = viewer.zzz_save_configs("viewer.form9user_test") -- Save global configuration before eventual changes. local t = t or "\n* <b>viewer.form9user_test(t, ref, ...)</b>:" local tabView = { testGroup = { { "translate_form9user_no_translation", }, { "viewer_test_no_values", }, { "translate_form9user_a_value_is_table", {}, }, { "langs_form9user_all_types_values", "abc", 4, nil, function(x) end, { 55, "xyz" }, }, { "replace: abc%1efg%2ijk", "<b>D</b>", "<b>H</b>", }, { "repeat: a=%1 b=%2 c=%1 d=%2", "<b>1</b>", "<b>2</b>", }, { "altern: 1%13%25", "<b>2</b>", "<b>4</b>", }, { "list: %0<%1<%2<%3<%4<%5<%6<%7<%8<%9", "00", "11", "22", "33", "44", "55", "66", "77", "88", "99", }, { "mix: %1, %5, %2, %4, %3, ", "A", "B", "C", "D", "E", }, { "missing args: yes=%1 no=%5 no=%9 yes=%2", "args[1]", "args[2]", }, { "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", }, }, title_memo = "activity_monitor_MW_Versions_title", headers = " input string and args; viewer.form9user_test ", -- headers_class = "wikitable alternative center sortable", rowGroup = {}, } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local ref = case[1] local form9user, t9 = viewer.form9user( lua_table.toList(case) ) return { ref, form9user, } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "viewer.form9user_test") -- Restore global configurations after eventual changes. return t end -- function viewer.form9user_test(t) 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 langs.formTestCase(ref, ...) end if type(ref) ~= "string" then ref = "langs_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.form99content(ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string. local form = viewer.trans99vars(langs.content_translations, ref, ...) return form end function viewer.form99page(ref, ...) -- Replace %01 to %99 by tostring( argN ) from arguments, without any ambiguity in any string. local form = viewer.trans99vars(langs.page_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(langs.user_translations, ref, ...) return form end function viewer.form99user_test(t) -- Tests of viewer.form9user_test(). local memo = viewer.zzz_save_configs("viewer.form99user_test") -- Save global configuration before eventual changes. local t = t or "\n* <b>viewer.form9user_test(t, ref, ...)</b>:" local tabView = { testGroup = { { "langs_form99user_no_tranlation", }, { "viewer_test_no_values", }, { "langs_form99user_a_value_is_table", {}, }, { "langs_form99user_all_types_values", "abc", 4, nil, function(x) end, { 55, "xyz" }, }, { "replace: abc%01fg%02jk", "<b>DE</b>", "<b>HI</b>", }, { "repeat: a=%01 b=%02 c=%01 d=%02", "<b>01</b>", "<b>02</b>", }, { "altern: 01%0145%0289", "<b>23</b>", "<b>67</b>", }, { "list: %00<%01<%02<%03<%04<%05<%06<%07<%08<%09", "00", "11", "22", "33", "44", "55", "66", "77", "88", "99", }, { "mix: %01, %05, %02, %04, %03, ", "A", "B", "C", "D", "E", }, { "missing args: yes=%01 no=%05 no=%09 yes=%02", "args[1]", "args[2]", }, { "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", }, }, title_memo = "langs_form99user_tests_title", -- "in viewer.form99user() Test: Replace %01 to &%;29 by tostring( argN ) from arguments", headers = " input string and args; viewer.form9user_test ", -- headers_class = "wikitable alternative center sortable", rowGroup = {}, -- track_on = true, } function tabView.form_one_case(case) -- Convert a case from testGroup to rowGroup. local ref = case[1] local form99user, t99 = viewer.form99user( lua_table.toList(case) ) return { ref, form99user, } end t = t .. tableview.new(tabView) -- Form a table view with lines and columns. viewer.zzz_restore_configs(memo, "viewer.form99user_test") -- Restore global configurations after eventual changes. return t end -- function viewer.form99user_test(t) function viewer.form_main_version(main_versions) if (type(main_versions) ~= "table") then main_versions = versn.main_versions end if (type(main_versions) ~= "table") then main_versions = { versionName = "versionName", versionNumber = "0.0", } end local t = "" if type(main_versions) == "table" then t = main_versions.versionName .. " " .. main_versions.versionNumber .. ", " end return t end function viewer.discreet_main_version(main_versions) return viewer.discreetColor( viewer.form_main_version(main_versions) ) end function viewer.docSection(selector, section, style) -- Begin of section in viewer.docPage(), viewer.docModule()... local res = "" --[[ 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", 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 .. "<" .. style .. ">" .. sec .. "</" .. style .. ">" -- debug style ok end --]] local sec = viewer.form9user(section) -- debug not translate res = res .. "<" .. style .. ">" .. sec .. "</" .. style .. ">" -- debug style ok viewer.docSection_t = res return res end -- function viewer.docSection(selector, section, style) function dropbox.form(title, content, drop_options) -- Easy Dropbox style from a list of named options. local memo = viewer.zzz_save_configs("dropbox.form") -- Save global configuration before eventual changes. if type(title) == "function" then title = title() -- function dropbox.new_title() elseif type(title) ~= "string" then title = "viewer_dropdown_missing_title" end title = viewer.form9user(title) local drop_opt = drop_options or {} drop_opt = { -- Conventional css parameters : from -- https://en.wikisource.org/wiki/Template:DropBox#Parameters image = nil, cssview = drop_opt.cssview, -- cssview : display values of options fw1 = drop_opt.fw1 or "left", -- fw1 : the font-weight for the heading fw2 = drop_opt.fw2 or "left", -- fw2 : the font-weight for the body fs1 = drop_opt.fs1 or "100%", -- font-size: 100%; fs2 = drop_opt.fs2 or "100%", -- font-size: 100%; bg1 = drop_opt.bg1 or "#FFFFFF", -- bg1 : the background-color for the heading bg2 = drop_opt.bg2 or "#FFFFFF", -- bg2 : the background-color for the body ta1 = drop_opt.ta1 or "left", -- ta1 : the text-align for the heading ta2 = drop_opt.ta2 or "left", -- ta2 : the text-align for the body float = drop_opt.float or "none", -- float : should the box be floated? (left, right, or none) width = drop_opt.width or "99%", -- width : the width of the box, e.g. 33% border_radius = drop_opt.border_radius or "0px 0px 0px 0px", -- border-radius: "15px 50px 30px 5px" : add rounded corners to an element. style = drop_opt.style or "0px 0px 0px 0px", -- style : HTML/CSS affectionados only: any other css style arguments for the whole box -- <div id="NavFrame10" class="NavFrame" style="clear:both; margin-bottom:1em; width:99%; border-style:solid; border-radius:0px 0px 0px 0px; border-color:#AAAAAA; background-color:#FFFFFF;" title="▼ /▶ "> hidden = drop_opt.hidden or "true", -- hidden : set this to any string (e.g. hidden=true) to have the box hidden by default headType = drop_opt.headType or "h4", -- headType : allows you to set the box header to (say) "h4", which means it will be included in the table of contents. This is provided as an explicit parameter because if you just surround the title with header tags, e.g. <h4>Box 1.1</h4> tc1 = drop_opt.tc1 or "black", -- tc1 : the text-color for the heading tc2 = drop_opt.tc2 or "black", -- tc2 : the text-color for the body border_color = drop_opt.border_color or "#AAAAAA", -- border-color : the text-color for the heading and the body -- display = drop_opt.display or "block", -- display: block : results without line break. display = drop_opt.display or "inline", -- display: inline : results with free line break. margin_all = drop_opt.margin_all or "0px", -- margin margin_bottom = drop_opt.margin_bottom or "1em", -- margin-bottom -- height = drop_opt.height or "1.6em", -- height label = drop_opt.label or "▼ /▶ ", -- = "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" translations } drop_opt.title = drop_opt.title or title drop_opt.content = drop_opt.content or content or "There is no text to view." if type(drop_opt.image) == "string" then drop_opt.image = '' .. '<div class="NavPic" style=" background-color:' .. drop_opt.bg1 .. '; " >' .. '[[File:' .. drop_opt.image .. '|22px]]' .. '</div>' -- else drop_opt.image = '' end local d = drop_opt local t = '' t = t .. "\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 .. "|ta1=" .. ta1 .. "}}" .. content .. "{{Boîte déroulante/fin}}" t = t .. '<div align="'.. d.ta2 ..'" >' t = t .. '<div class="NavFrame" style="clear:both; margin-bottom:'.. d.margin_bottom ..'; width:'.. d.width t = t ..'; border-style:solid; border-radius:'.. d.border_radius ..'; border-color:'.. d.border_color t = t ..'; background-color:'.. d.bg1 ..'; " title="'.. d.label ..'" >' t = t .. '<div class="NavHead" align="'.. d.ta1 ..'" style=" height:'.. d.height ..'; background-color:'.. d.bg1 ..'; color:'.. d.tc1 ..'; " >' t = t .. d.title t = t .. '</div>' t = t .. '<div class="NavContent" align="'.. d.ta2 ..'" style="margin:'.. d.margin_all ..'; background-color:'.. d.bg1 ..'; display=block; " >' t = t .. d.image t = t .. d.content t = t .. '</div>' t = t .. '</div>' t = t .. '</div>' if drop_opt.cssview then t = t .. '\n* List values of <b>CSS if cssview</b>: ' for key, elem in pairs(drop_opt) do if (key ~= "content") and (key ~= "title") then t = t .. viewer.ta(key, elem) end end end dropbox.DropBox_t = t viewer.zzz_restore_configs(memo, "dropbox.form") -- Restore global configurations after eventual changes. return t end -- function dropbox.form(title, content, drop_opt) function dropbox.new_title() -- Support desk title of the docDropBox of the edit box. local t, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts("langs.main_i18n", "langs_main_i18n_languages_count", "user") local report_main_discreet = viewer.discreetColor( viewer.form_main_version(main_versions) ) local title = viewer.form9user("versn_support_desk_title", report_main_discreet, strs_on_tabs, tables_c) -- "Support desk for %1 : %2 translations in %3 languages" return title end -- function dropbox.new_title() function dropbox.new(selector, title, content_or_func, ...) -- Form a DropBox for a doc or a group of tests. Take apart drop_opt options. -- Style options in drop_opt{}: ta1, image, ta2, margin_bottom, width, border_radius, border_color, bg1) -- selector = "allwaysview" -- To allways display one view. -- selector = "enforcerun" -- To debug one box with INTERNAL ERROR. -- Form a drop box could by a part of a process, do not save the global configuration. local memo = viewer.zzz_save_configs("dropbox.new") -- Save global configuration before eventual changes. local t = "" local content_or_func = content_or_func if type(content_or_func) ~= "function" then content_or_func = tostring(content_or_func) end if selector == "never" then return "" end if not ( (selector == true) or (selector == title) or viewer.is_in_sp(selector, "allwaysview alltestsview enforcerun failinref nocontent") ) then return "" end if (type(title) ~= "string") then title = "Default_title" end local args = { ... } -- optional arguments for the content_or_func function local drop_opt = nil -- drop_opt to change the look of the dropbox for i, args_tab in ipairs(args) do -- Get the drop_opt options for the dropbox. -- ii = i modes.recursiveLoop = (modes.recursiveLoop or 0) + 1 if modes.recursiveLoop > 33 then return "" end -- The last argument can be a drop_opt to change the look of the dropbox -- if (type(args_tab) == "table") then -- if (type(args_tab) == "table") and (args_tab["drop_opt"] == "drop_opt") then if (i == #args) and (type(args_tab) == "table") and (args_tab["drop_opt"] == "drop_opt") then drop_opt = mw.clone( args_tab ) end end local ac_opt = drop_opt or {} -- for antiCrash local success, result = true, "" if type(title) ~= "string" then title = "viewer_dropdown_missing_title" end ac_opt.selector = selector ac_opt.title = title -- ..","..tostring(vr_tb) -- .. viewer.ta("type", sub_type) .. viewer.ta("vr_tb", vr_tb) .. viewer.ta("tot_tabs", tot_tabs) ac_opt.args = args ac_opt.content = content_or_func ac_opt.success = true ac_opt.content_error = "" if type(content_or_func) == "function" then -- Form a drop box could by a part of a process, do not save the global configuration. local memo2 = viewer.zzz_save_configs("dropbox.new function") -- Save global configuration before eventual changes. ac_opt.content, ac_opt.title_errors = content_or_func( ... ) viewer.zzz_restore_configs(memo2, "dropbox.new function") -- 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 = versn.antiCrash(ac_opt, content_or_func, ...) -- Form the display of a running error. -- { "20170615", "20170616", "now", "Rical", "S170612dbx", "Convert viewer.DropBox() in viewer.dropbox = dropbox = {} for dropbox.form(tit, cf, opt)", }, -- local res = dropbox.form(ac_opt.title, ac_opt.content, drop_opt) 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 = lua_table.level_list(package.loaded) -- subtasks S170813lll -- res = "* level_list = { " .. list .. " } ; " .. res -- Form a drop box could by a part of a process, do not save the global configuration. viewer.zzz_restore_configs(memo, "dropbox.new") -- Restore global configurations after eventual changes. -- res = t .. res return res end -- function dropbox.new(selector, title, content, ...) -- Build a table, with headers for columns. Example:f -- ! 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 viewer.default_testGroup = { { "abc", 123, "A1, B2, C3" }, { "equation", "y =", (11 * 7 + 3 * 12 + 1) }, { "Matrix:", { "2.1.0", "v4-6, ISO_8601, FC14 h6" } }, { "pi = ", "circle / diameter", 3.14, }, { "quadrature", function() end, "convert a square to a circle" }, } function tableview.form_one_case(case, tabView) -- Default: Convert a case from testGroup to rowGroup. local tocase = case -- {} return case end -- function tableview.form_one_case(case) function tableview.add_Row(case, tabView) -- Default: Add a row to rowGroup. if (type(case) == "table") and (type(tabView) == "table") and (type(tabView.rowGroup) == "table") then -- tabView must be a table tabView.t = tabView.t .. viewer.ta("add_Row-#rowGroup: ", #tabView.rowGroup) -- track to debug tabView.t = tabView.t .. viewer.ta("add_Row-#case: ", #case) -- track to debug table.insert( tabView.rowGroup, case) elseif (type(case) == "table") and (type(tabView) == "table") then -- tabView.rowGroup = {} table.insert( tabView.rowGroup, case) tabView.t = (tabView.t or "") .. viewer.ta("add_Row-#rowGroup: ", #tabView.rowGroup) -- track to debug tabView.t = tabView.t .. viewer.ta("add_Row-#case: ", #case) -- track to debug end end -- function tableview.add_Row(tabView) function tableview.form_all_cases(tabView) -- Default: Convert all tests cases from testGroup to rowGroup. local memo = viewer.zzz_save_configs("tableview.form_all_cases") -- Save global configuration before eventual changes. local tabView = tabView if (type(tabView) ~= "table") then tabView = {} end -- tabView must be a table if type(tabView.testGroup) ~= "table" then -- tabView.testGroup must be a table tabView.testGroup = {} end tabView.rowGroup = tabView.rowGroup or {} tabView.track = tabView.track or {} -- Begin tracking of errors and caracteristics of a tabView case. local trk = tabView.track if (type(tabView) ~= "table") then trk.tabView = tabView end -- err tabView is table ? trk.min_in = 999999 ; trk.max_in = 0 trk.min_out = 999999 ; trk.max_out = 0 tabView.t = tabView.t or "" trk.Start_test = tabView.testGroup -- err tabView.testGroup is table ? trk.Start_test_N = #tabView.testGroup -- size tabView.testGroup trk.Start_row = tabView.rowGroup -- err tabView.testGroup is table ? trk.Start_row_N = #tabView.rowGroup -- size tabView.testGroup tabView.t = tabView.t .. viewer.ta("start#testGroup", #tabView.testGroup) -- track to debug if type(tabView.rowGroup) ~= "table" then tabView.rowGroup = {} end 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) if case.STOP == "STOP" then break end trk.i = i trk.case_in = case -- for table error ? if type(case) ~= "table" then case = { case } end -- Cases must be tables of values. trk.min_in = 99 ; trk.max_in = 0 trk.min_out = 99 ; trk.max_out = 0 if #case < trk.min_in then trk.min_in = #case end if #case > trk.max_in then trk.max_in = #case end if type(tableview.form_one_case) == "function" then -- Convert all tests cases from testGroup to rowGroup. case = tabView.form_one_case(case, tabView) -- Form one case else case = case -- if tableView_form_one_case() is not defined, do not Form the case end -- Keep all cells: Insert a masked text in all table cells, to not lost following cells. if (type(case) == "table") and (type(tabView.rowGroup) == "table") then -- Do not fail if case is nil or {}. local headers_split = mw.text.split(tabView.headers, ';', true) -- fr wikisource org for i, header in ipairs(headers_split) do header = mw.text.trim(header) case[i] = case[i] or viewer.usualColor("-", "mask") -- "mask", "discreet", "error" end end -- trk.case_out = type(case) if type(case) ~= "table" then -- check case_out case = { case } end if #case < trk.min_out then trk.min_out = #case end if #case > trk.max_out then trk.min_out = #case end tabView.add_Row(case, tabView) -- Default: Add a row to rowGroup. trk.End_test = tabView.testGroup -- err tabView.testGroup is table ? trk.End_test_N = #tabView.testGroup -- err tabView.testGroup is table ? trk.End_row = tabView.rowGroup -- err tabView.testGroup is table ? trk.End_row_N = #tabView.rowGroup -- err tabView.testGroup is table ? tabView.t = tabView.t .. "\n* Start: " tabView.t = tabView.t .. viewer.form9user("tb=<b>%1</b>, tbN=<b>%2</b>, min=<b>%3</b>, max=<b>%4</b>. ", tostring(trk.Start_test), trk.Start_test_N, trk.min_in, trk.max_in) -- track to debug tabView.t = tabView.t .. viewer.form9user("i=<b>%1</b>, case_in=<b>%2</b>, case_out=<b>%3</b>, ", tostring(trk.i), type(trk.case_in), type(trk.case_out) ) trk.Start_test = tabView.testGroup -- err tabView.testGroup is table ? trk.Start_test_N = #tabView.testGroup -- size tabView.testGroup trk.Start_row = tabView.rowGroup -- err tabView.testGroup is table ? trk.Start_row_N = #tabView.rowGroup -- err tabView.testGroup is table ? tabView.t = tabView.t .. " ** End: " tabView.t = tabView.t .. viewer.form9user("tb=<b>%1</b>, tbN=<b>%2</b>, min=<b>%3</b>, max=<b>%4</b>. ", tostring(trk.End_test), trk.End_test_N, trk.min_out, trk.max_out) -- track to debug tabView.track = trk end viewer.zzz_restore_configs(memo, "tableview.form_all_cases") -- Restore global configurations after eventual changes. end -- function tableview.form_all_cases(tabView) function tableview.adapt_options(tabView) -- Adapt all options for all uses. local memo = viewer.zzz_save_configs("tableview.adapt_options") -- Save global configuration before eventual changes. if type(tabView) ~= "table" then tabView = {} end -- tabView must be a table tabView.t = (tabView.t or "") tabView.headers = tabView.headers or "viewer_tableView_default_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 " " -- Style of the whole table view. tabView.testGroup = tabView.testGroup or viewer.default_testGroup tabView.t = (tabView.t or "") .. viewer.ta("tableView.tabView.testGroup size: ", #tabView.testGroup) -- track to debug tabView.form_one_case = tabView.form_one_case or tableview.form_one_case tabView.form_all_cases = tabView.form_all_cases or tableview.form_all_cases tabView.add_Row = tabView.add_Row or tableview.add_Row tabView.ccc = tabView.ccc or tableview.ccc or {} -- To communicate and compute between cases tabView.rowGroup = tabView.rowGroup or {} -- Only tabView can change rowGroup to avoid effect from a tableview on the next tabView.track_on = tabView.track_on or false tabView.t = tabView.t .. viewer.ta("#tabView.rowGroup", #tabView.rowGroup) -- track to debug viewer.zzz_restore_configs(memo, "tableview.adapt_options") -- Restore global configurations after eventual changes. return tabView end -- function tableview.adapt_options(tabView) function tableview.form_whole_view(tabView) -- Form whole the tableview.new() local memo = viewer.zzz_save_configs("tableview.form_all_cases") -- Save global configuration before eventual changes. local t, err = "", "" if (#tabView.testGroup == 0) then err = err .. viewer.ta("#tabView.testGroup", #tabView.testGroup) end local t = viewer.Th(tabView.headers_class or "") if (type(tabView.headers) ~= "string") then tabView.headers = "tabView; headers; missing" err = err .. tabView.headers end 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 or "") end tableview.form_all_cases(tabView) -- Default: Convert all tests cases from testGroup to rowGroup. if (type(tabView.rowGroup) ~= "table") then tabView.rowGroup = {} end if (#tabView.rowGroup == 0) then err = err .. "whole:" err = err .. viewer.ta("#tabView.testGroup", #tabView.testGroup) err = err .. viewer.ta("#tabView.rowGroup", #tabView.rowGroup) 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 or "") -- each value in columns of row_i end end t = t .. viewer.Te() if (err ~= "") and (tabView.track_on) then t = t .. "tableView_form_whole_view: " .. err end viewer.zzz_restore_configs(memo, "tableview.form_whole_view") return t end -- function tableview.form_whole_view(tabView) -- S170610csc function tableview.new(tabView) -- Form a table with lines and columns. S170610tvf local memo = viewer.zzz_save_configs("tableview.form_whole_view") -- Save global configuration before eventual changes. if type(tabView) ~= "table" then tabView = {} end -- tabView must be a table tabView.t = (tabView.t or "") .. viewer.ta("tableView: ", "start") local t = "" local err = nil -- viewer.form9user("viewer_tableView_tests_title") tabView = tableview.adapt_options(tabView) -- Adapt all options for all uses, before all other adaptations. if tabView.track_on then t = t .. viewer.ta("#testGroup", #tabView.testGroup) .. viewer.ta("#rowGroup", #tabView.rowGroup) end t = t .. tableview.form_whole_view(tabView) -- Form whole the tableview.new() if tabView.track_on then t = t .. viewer.ta("#testGroup", #tabView.testGroup) .. viewer.ta("#rowGroup", #tabView.rowGroup) end if tabView.track_on then t = t .. tabView.t end -- Counts of selected and sorted sub-tasks: , #testGroup = 43 , #rowGroup = 0 viewer.zzz_restore_configs(memo, "tableview.form_whole_view") -- Restore global configurations after eventual changes. return t, err, tabView end -- t, err, tabView = function tableview.new(tabView) function viewer.tableView_test() -- Test tableview.new() return tableview.new() -- Form a table with lines and columns. end function viewer.docPage(selector) -- Form some dropboxes of tests to document a page. local res = "" -- res = res .. viewer.docSection(selector, "Tests of this page", "h2") res = res .. viewer.docSection(selector, "viewer_page_tests_h2_title", "h2") -- res = res .. dropbox.new(selector, "datas.get_item() Tests of the import of wikidatas from the wikibase snaks **", datas.get_datas_report) res = res .. dropbox.new(selector, "modes_args_known_report_title", modes.args_known_report) res = res .. dropbox.new(selector, "modes_used_options_list_title", modes.used_options_list ) res = res .. dropbox.new("user_translations", "modes_list_all_args_main_title", modes.list_all_args_main) -- res = res .. "\n------ " -- This code interact with DropBox and debug the bug T20151215 2016-11-13 17:57. -- res = res .. dropbox.new(selector, "langs_translationsCounts_title", langs.translationsCounts) -- S170618ltc res = res .. dropbox.new(selector, "luaTable_table_args_source_title", lua_table.structure, modes.args_source, "modes.args_source") res = res .. dropbox.new(selector, "modes_args_known_structure_title", modes.args_known_structure) return res end -- function viewer.docPage(selector) function viewer.docModule(selector) -- Form some dropboxes of tests to document a module. local res = "" -- res = res .. viewer.docSection(selector, "viewer_module_tests_h2_title", "h2") res = res .. viewer.docSection(selector, "Tests of this module", "h2") res = res .. dropbox.new(selector, "modes_args_unknown_report_title", modes.args_unknown_report) res = res .. dropbox.new(selector, "versn_support_desk_title", versn.form_support_desk_report) res = res .. dropbox.new(selector, "modes_options_uses_tests_title", modes.options_from_mode_tests) res = res .. dropbox.new("user_translations", "modes_all_categories_list_title", modes.all_categories_list) res = res .. dropbox.new("user_translations", "modes_all_errors_list_title", modes.all_errors_list) return res end -- function viewer.docModule(selector) function viewer.docInternal(selector) -- Form some dropboxes of tests to document internal functions. local res = "" -- res = res .. viewer.docSection(selector, "viewer_internal_tests_h2_title", "h2") res = res .. viewer.docSection(selector, "Internal tests", "h2") -- res = res .. viewer.docSection(selector, "Library:activity", "h3") res = res .. dropbox.new(selector, "activity_support_central_modules_title", activity.support_begin_central_modules) -- doc link res = res .. dropbox.new(selector, "activity_phabricator_tasks_title", activity.monitor_phabricator_tasks) -- S170606act res = res .. dropbox.new(selector, "activity_monitor_subtasks_title", activity.monitor_central_subtasks) res = res .. dropbox.new(selector, "activity_display_central_libraries_title", activity.describe_central_libraries) res = res .. dropbox.new(selector, "activity_monitor_MW_Versions_title", activity.monitor_MW_Versions) res = res .. dropbox.new(selector, "activity_list_libraries_functions_title", activity.list_libraries_functions) -- res = res .. viewer.docSection(selector, "Library:datas", "h3") res = res .. dropbox.new(selector, "datas.get_item() Tests of the import of wikidatas from the wikibase snaks **", datas.get_datas_report) res = res .. dropbox.new(selector, "datas_wikidata_arbitrary_tests_title") -- { drop_opt.drop_opt = "drop_opt", image = "Gtk-dialog-info.svg"} ) res = res .. dropbox.new(selector, "datas_wikidata_time_details_title", lua_table.structure, datas.wikidata_time_details) res = res .. dropbox.new(selector, "datas_update_Special_PageData_title", datas.update_PageData) -- res = res .. viewer.docSection(selector, "Library:events", "h3") -- function events.all_kinds_test(t) -- Test: all kinds of events (err, wng, cat) -- res = res .. dropbox.new(selector, "events_all_kinds_tests_title", events.all_kinds_test) -- 5 empty rows res = res .. dropbox.new(selector, "events_categ_Test_title", events.categ_Test) -- Discreet main version ? -- res = res .. dropbox.new(selector, "langs_selectLang_tests_title", langs.selectLang_test) -- lang %1 %2 %3 -- res = res .. viewer.docSection(selector, "Library:langs", "h3") res = res .. dropbox.new(selector, "langs_translationsCounts_title", langs.translationsCounts) -- S170618ltc res = res .. dropbox.new(selector, "langs_changing_translations_title", langs.changing_translations) -- no tabview res = res .. dropbox.new(selector, "langs_missing_translations_title", langs.missing_translations) -- string.find nil res = res .. dropbox.new(selector, "langs_dummy_languages_title", langs.dummy_languages) -- res = res .. dropbox.new(selector, "langs_mixed_translations_title", langs.i18n_lister) res = res .. dropbox.new(selector, "langs_abnormal_char_in_text_title", langs.abnormal_char_in_text ) -- false res = res .. dropbox.new(selector, "langs_list_Mediawiki_languages_title", langs.list_Mediawiki_languages ) -- OK, show in table ? -- res = res .. viewer.docSection(selector, "Library:lua_table", "h3") -- local list, count, level, split = lua_table.level_list(tab, typ, select, field) lua_table.level_list_tests( -- subtasks S170813lll -- res = res .. dropbox.new(selector, "luaTables_count_all_types_values_title", lua_table.count_tests ) -- lua_table.level_list() res = res .. dropbox.new(selector, "luaTables_count_all_types_values_title", lua_table.count_tests ) -- lua_table.count_tests() -- title_memo = "luaTables_count_all_types_values_title", -- "lua_table.count_values() Count all objects or types or values in the table.", -- function lua_table.count_tests(t) -- Count all objects or types or values in the table -- res = res .. dropbox.new(selector, "luaTable_fromsubnames_test_title", lua_table.fromsubnames_test ) -- nil res = res .. dropbox.new(selector, "luaTable_rough_view_tests_title", viewer.rough_view_test ) res = res .. dropbox.new(selector, "luaTable_structure_nolimits_title", lua_table.structure, lua_table.tablim, "lua_table.tablim") res = res .. dropbox.new(selector, "luaTable_structure_limits_title", lua_table.structure, lua_table.tablim, "lua_table.tablim", { ["drop_opt"] = "drop_opt", ["level_maxi"] = 3, ["max_n"] = 2, ["exclude1"] = "hou" } ) -- opt = { drop_opt.drop_opt = "drop_opt", level_maxi = 3, max_n = 2, exclude1 = "hou" } res = res .. dropbox.new(selector, "luaTable_toList_tests_title", lua_table.toList_tests, { ["drop_opt"] = "drop_opt", arggg = "drop_opt" } ) -- if (i == #args) and (type(tab) == "table") and (tab.drop_opt == "drop_opt") then res = res .. dropbox.new(selector, "luaTable_toTable_tests_title", lua_table.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 .. dropbox.new(selector, "mathroman_roman2int_tests_title", mathroman.roman2int_tests) -- Discreet main version res = res .. dropbox.new(selector, "mathroman_int2roman_test_title", mathroman.int2roman_test) -- Discreet main version --"enforcerun" "allwaysview" -- res = res .. viewer.docSection(selector, "Library:modes", "h3") res = res .. dropbox.new(selector, "modes_args_known_report_title", modes.args_known_report) res = res .. dropbox.new(selector, "modes.bind_args_known_one_lib_report(t) Report the binding of one library known args. **", modes.bind_args_known_one_lib_report) -- res = res .. dropbox.new(selector, "modes_used_options_list_title", modes.used_options_list ) res = res .. dropbox.new(selector, "modes_options_from_args_tests_title", modes.options_from_args_tests, { ["drop_opt"] = "drop_opt", width = "60%", tc1="#987654", ta1="right", ta2="center", margin_all="1em", -- S170615css bg1="#FFEEDD", border_color="#338866", height="2em" } ) -- Discreet main version res = res .. dropbox.new(selector, "modes_options_uses_tests_title", modes.options_from_mode_tests, { ["drop_opt"] = "drop_opt", width = "70%", tc1="#345678", ta1="center", ta2="center", margin_all="3em", -- S170615css bg1="#DDEEFF", border_color="green", border_radius="5px 5px 5px 5px", image="Button-synchro-on.png" } ) -- "[[Fichier:Gtk-dialog-info.svg|15px]]" res = res .. dropbox.new(selector, "modes_options_uses_tests_title", modes.options_from_mode_tests, { ["drop_opt"] = "drop_opt", width = "80%", tc1="green", ta1="left", ta2="center", margin_all="2em", -- S170615css bg1="yellow", border_color="red", border_radius="10px 10px 10px 10px", image="Sanscrit dha.svg", } ) -- , cssview=true res = res .. dropbox.new(selector, "modes_recursiveNormal_tests_title", modes.recursiveNormal_tests ) -- only errors -- arguments list -- res = res .. dropbox.new(selector, "modes_all_categories_list_title", modes.all_categories_list) -- n = 0 -- res = res .. dropbox.new(selector, "modes_all_errors_list_title", modes.all_errors_list) -- todo -- arguments support res = res .. dropbox.new(selector, "modes_multiple_selection_tests_title", modes.multiple_selection_tests) res = res .. dropbox.new("never", "modes_multiple_values_tests_title", modes.multiple_values_tests) res = res .. dropbox.new(selector, "modes_similar_args_searchs_title", modes.similar_args_search_tests) -- no source or no known arguments res = res .. dropbox.new(selector, "modes_similar_levenshtein_tests_title", modes.similar_levenshtein_tests) res = res .. dropbox.new(selector, "modes_spaces_names_page_title", modes.spacesNamesPageTest) -- "enforcerun" res = res .. viewer.docSection(selector, "Library:testsgrp", "h3") -- S170801rtc todo -- res = res .. dropbox.new(selector, "testsgrp_recursive_tests_title", testsgrp.recursive_tests (t) res = res .. dropbox.new(selector, "testsgrp_getTestProvider_title", viewer.simpleList_test ) -- res = res .. viewer.docSection(selector, "Library:versn", "h3") -- title_memo = "versn_versions_management_title", -- "versn.versions_management_test() List all loaded modules." res = res .. dropbox.new(selector, "versn_versions_management_title", versn.versions_management_test ) -- OK, to optimize res = res .. dropbox.new(selector, "versn.bind_all_sub_modules() ACTUAL Bind all sub-modules of the main module **", versn.bind_all_sub_modules_actual_report ) -- to_debug_on_20170507 -- -- versn.bind_all_sub_modules_test(versn.sub_modules, true) -- At test time: TEST: Bind all sub-modules of the main module. -- "versn.bind_all_sub_modules() ACTUAL Bind all sub-modules of the main module", versn.bind_all_sub_modules_actual_report ) -- to_debug_on_20170507 -- if iftest then versn.bind_all_sub_modules_test_report = t -- TEST: Bind all sub-modules of the main module. res = res .. dropbox.new(selector, "versn.bind_all_sub_modules() TEST Bind all sub-modules of the main module **", versn.bind_all_sub_modules_test_report ) -- to_debug_on_20170507 -- res = res .. dropbox.new(selector, "versn_versions_management_report", versn.versions_management_report ) -- to_debug_on_20170507 res = res .. dropbox.new(selector, "versn_list_all_G_and_loaded_title", versn.list_all_G_and_loaded) res = res .. dropbox.new(selector, "versn_bind_central_modules_title", versn.bind_central_modules_report ) -- S170606cmr res = res .. dropbox.new(selector, "versn_deprecatedFunction_tests_title", viewer.simpleList_test) -- res = res .. dropbox.new(selector, "versn_bind_modules_tests_title", versn.bind_modules_test ) res = res .. dropbox.new(selector, "versn_sort_central_modules_title", versn.sort_central_modules_report ) -- S170606cmr res = res .. dropbox.new("never", "versn_antiCrash_tests_title", versn.antiCrash_tests ) -- Tests antiCrash() -- to_debug_on_20170507 res = res .. dropbox.new(selector, "versn_dev_running_times_title", versn.running_times ) -- versn.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 .. dropbox.new(selector, "langs_form9user_tests_title", viewer.form9user_test ) res = res .. dropbox.new(selector, "langs_form99user_tests_title", viewer.form99user_test ) res = res .. dropbox.new(selector, "viewer_format_time_tests_title", viewer.format_time_tests) res = res .. dropbox.new(selector, "viewer_parts_of_date_tests_title", viewer.parts_of_date_tests) res = res .. dropbox.new(selector, "viewer_simpleList_tests_title", viewer.simpleList_test ) res = res .. dropbox.new(selector, "viewer.boxview.form() Tests: Make an easy box builder **", viewer.boxview_test) -- S170723vbv res = res .. dropbox.new("never", "viewer_table_tabOptions_title", viewer.table_test ) res = res .. dropbox.new(selector, "viewer_tableView_tests_title", viewer.tableView_test ) -- to_debug_on_20170507 -- viewer.zzz_restore_configs(memo, "viewer.docInternal") -- Restore global configurations after eventual changes. res = res .. dropbox.new(selector, "viewer.zzz_save_configs_in_functions_report(t) Report known couples of save and restore global configurations **", viewer.zzz_save_configs_report) return res end -- function viewer.docInternal(selector) viewer.time_line = [=[ <timeline># All measures are in pixels ImageSize = width:800 height:100 PlotArea = left:57 right:12 bottom:20 top:0 AlignBars = justify DateFormat = dd/mm/yyyy Period = from:01/01/2004 till:01/03/2017 TimeAxis = orientation:horizontal Colors = id:darkgray value:gray(0.5) id:lightgray value:gray(0.9) ScaleMajor = unit:year gridcolor:darkgray increment:1 start:01/01/2004 ScaleMinor = unit:month gridcolor:lightgray increment:3 start:01/01/2004 BarData = Bar:pro text:"Profession" Bar:bnk Bar:pol text:"Politique" Bar:par text:"(parti)" Define $left1 = align:left shift:(-45, -3) Define $left2 = align:left shift:(-75, -3) Define $left3 = align:left shift:(-30, -3) Define $left4 = align:left shift:(-85, -3) PlotData= width:16 fontsize:s bar:pro color:yellow $left1 from:01/04/2004 till:01/09/2008 text:"[[Inspection générale des finances (France)|Inspecteur des finances]]" color:pink $left4 from:02/09/2008 till:15/05/2012 text:"En disponibilité de la fonction publique" color:pink from:10/06/2014 till:30/08/2016 bar:bnk color:yellow $left1 from:02/09/2008 till:01/05/2012 text:"[[Banquier d'affaires]]" bar:pol color:kelleygreen $left1 from:15/05/2012 till:10/06/2014 text:"[[Cabinet du président de la République française|Adjoint à l'Élysée]]" color:kelleygreen $left1 from:28/08/2014 till:30/08/2016 text:"[[Ministère de l'Économie et des Finances (France)|Ministre de l'Économie]]" bar:par color:coral $left3 from:01/01/2006 till:31/12/2008 text:"[[Parti socialiste (France)|Parti socialiste]]" color:lightgray $left3 from:06/04/2016 till:28/02/2017 text:"[[En marche !]]" </timeline> ]=] -- See T166202 Strings defined as long comments give a Lua modules syntax error function viewer.try_graph() -- see Macron from https://fr.wikipedia.org/w/index.php?title=Mod%C3%A8le:Frise_chronologique_Emmanuel_Macron&action=edit -- unusable : frame:expandTemplate{ title = 'template', args = { 'arg1', 'arg2', name = 'arg3' } } -- use : frame:preprocess( string ) or object = frame:newParserValue( text ) -- use : frame:newTemplateParserValue{ title = title, args = table } local t = "\n* viewer.try_graph()" t = t .. "<b>Carrière et parcours politique d'Emmanuel Macron</b>" t = t .. viewer.time_line -- <noinclude> </noinclude> return t end -- function viewer.try_graph() viewer.central_functionalCSS = { -- S170617CSS : Use MW CSS see edit_class, content_class, CSSstructure edit_class = "editOptions", edit_form = "mw-editform-legacy", box_class = "infobox_v2", box_form = "infobox_v2", content_class = "content", content_form = "content", page_class = "page_class", page_form = "page_form", user_class = "user_class", user_form = "user_form", toc_class = "toc", toc_form = "toc_form", -- result_form = viewer.form9user(result_form, toc_form, toc_class, edit_form, content_form, page_form, user_form, xx, xx, xx) -- %1 %1 %1 %1 %1 %1 %1 %1 CSSstructure = '<div class="editOptions">%1</div><div class="editOptions">%1</div><div class="editOptions">%1</div><div class="editOptions">%1</div>', -- .. '<div class="editOptions">...</div>' .. '<div class="editOptions">...</div>' .. '<div class="editOptions">...</div>', viewer_sentence_example_page_text = "Cette phrase montre un exemple de texte de page. ", -- br viewer_sentence_example_page_text = "Dieser Satz zeigt eine Beispieltextseite. ", -- de viewer_sentence_example_page_text = "This sentence shows an example of page text. ", -- en viewer_sentence_example_page_text = "Esta frase muestra una página de muestra de texto. ", -- es viewer_sentence_example_page_text = "Cette phrase montre un exemple de texte de page. ", -- fr viewer_sentence_example_page_text = "Ez a mondat egy minta oldal szöveg.", -- hu viewer_sentence_example_page_text = "Câu này cho thấy một trang mẫu của văn bản. ", -- vi } -- The TemplateStyles extension introduces a <templatestyles> tag to specify that a stylesheet should be loaded from a wiki page. Placing this in a template allows the template to have custom styles without having to place them in MediaWiki:Common.css. function viewer.form_functionalCSS(CSSstructure, opt) -- Form the CSS structure based upon viewer.central_functionalCSS local t, page_text = "", viewer.form9page("viewer_sentence_example_page_text") page_text = page_text .. page_text .. page_text .. page_text .. page_text .. page_text .. page_text local CSSstructure = CSSstructure or viewer.central_functionalCSS.CSSstructure local opt = opt or {} if type(CSSstructure) ~= "table" then CSSstructure = viewer.central_functionalCSS.CSSstructure end -- local result_form, box_form, edit_form, content_form, page_form, user_form, flag, image, background_image box_form = opt.box_form or CSSstructure.box_form or "" content_form = opt.content_form or CSSstructure.content_form or "" edit_form = opt.edit_form or CSSstructure.edit_form or "" page_form = opt.page_form or CSSstructure.page_form or "" toc_form = opt.toc_form or CSSstructure.toc_form or "" user_form = opt.user_form or CSSstructure.user_form or "" result_form = opt.result_form or CSSstructure.result_form or "" flag = opt.flag or CSSstructure.flag or "" if flag then -- image to insert flag = mw.text.trim( tostring(flag) ) flag = '[[File:' .. flag .. '|frameless|170x170px||class=photo]]' else flag = " " end if image then -- image to insert image = mw.text.trim( tostring(image) ) image = '[[File:' .. image .. '|frameless|170x170px||class=photo]]' else image = " " end local xx = "" -- result_form = viewer.form9user(result_form, toc_form, toc_class, edit_form, content_form, page_form, user_form, xx, xx, xx) -- %1 %1 %1 %1 %1 %1 %1 %1 -- edit_class = "editOptions", -- edit_form = "mw-editform-legacy", content_form = viewer.form9user('<div class="%1">%2</div>', CSSstructure.content_class, CSSstructure.content_form or "content_form") edit_form = viewer.form9user('<div class="%1">%2</div>', CSSstructure.edit_class, CSSstructure.edit_form or "edit_form") page_form = viewer.form9user('<div class="%1">%2</div>', CSSstructure.page_class, CSSstructure.page_form or "page_form") toc_form = viewer.form9user('<div class="%1">%2</div>', CSSstructure.toc_class, CSSstructure.toc_form or "toc_form") user_form = viewer.form9user('<div class="%1">%2</div>', CSSstructure.user_class, CSSstructure.user_form or "user_form") flag_form = viewer.form9user('<div class="%1">%2</div>', CSSstructure.flag_class, CSSstructure.flag_form or "flag_form") -- CSSstructure = '<div class="editOptions">%1</div><div class="editOptions">%2</div><div class="editOptions">%3</div><div class="editOptions">%4</div>' -- CSSstructure = CSSstructure .. '<div class="editOptions">%2</div><div class="editOptions">%6</div><div class="editOptions">%7</div><div class="editOptions">%4</div>' result_form = CSSstructure result_form = viewer.form9user("%1%2%3%4%5%6%7", edit_form, content_form, page_form, user_form, toc_form, flag_form, xx, xx) -- CSSstructure = '<div class="editOptions">...</div>', -- .. '<div class="editOptions">...</div>' .. '<div class="editOptions">...</div>' .. '<div class="editOptions">...</div>', t = t .. result_form return t end -- function viewer.form_functionalCSS(CSSstructure, opt) function viewer.form_result(args_final, main_module) -- Form all results of this module, and of others. return viewer.main_view(args_final, main_module) end -- function viewer.form_functionalCSS(CSSstructure, opt) function viewer.main_view(args_final, main_module) -- Form all results of this module, and of others. local res = "" local memo = viewer.zzz_init_configs("viewer.main_view") -- Initialize global configurations and save them before eventual changes. main_module = main_module or versn.main_module if type(args_final) ~= "table" then args_final = modes.args_final end -- optional arguments res = res .. viewer.ta("modes.mode_name", modes.mode_name) .. viewer.ta("modes.options", modes.options) events.gener_categories(args_final) -- Form all categories without activate them -- local label = modes.args_final.label or modes.main_title or datas.props.Label or modes.args_final.itemid local label = modes.args_final.label or modes.main_title or datas.prot("title") or modes.args_final.itemid -- local label = modes.args_final.label or modes.main_title or modes.args_final.QITEM or modes.args_final.itemid if modes.option("docview") or modes.option(":") or modes.option("tests") or (modes.args_final.mode == "edit") then -- res = res .. dropbox.new("allwaysview", "versn_support_desk_title", versn.form_support_desk_report ) res = res .. p.formDocBox(modes.args_final) end if modes.option("box1") then res = res .. p.box1(datas.props) end if modes.option("box1") or modes.option("catview") then res = res .. " catview = " .. events.categories_lister(":") end -- Display categories events.categories_lister("") -- really link to categories modes.time3 = os.clock() if modes.option("tests") then -- or (modes.args_final.mode == "tests") Central.tst = false -- To form documentations of only some tests and reports. Central.tst = "tst" -- To form all tests and reports. res = res .. viewer.docGroup("allwaysview") -- res = res .. viewer.docPage("allwaysview", QITEM) -- res = res .. viewer.docModule("allwaysview", QITEM) -- res = res .. viewer.docInternal("allwaysview", QITEM) res = res .. versn.running_times(false, "") end viewer.zzz_restore_configs(memo, "viewer.main_view") -- Restore global configurations after eventual changes. return res end -- res = res .. viewer.main_view(args_final, main_module) -- Form all the result of this module function p.form_result(args_final, main_module) return viewer.main_view(args_final, main_module) end -- function viewer.main_view(args_final, main_module) function viewer.zzz_init_configs(base, tabView, group) -- Initialize global configurations and save them before eventual changes. if type(base) ~= "table" then base = {} end if type(group) ~= "table" then group = nil end if type(tabView) ~= "table" then tabView = events.tabView or {} end base.events = events -- A new events process/object come from the events process/object in this module. base.events.tabView = tabView or base.events.tabView or events.tabView base.events.catview = tabView.catview or base.events.catview or modes.catView base.events.default_group = tabView.default_group or base.events.group_all_types_test base.events.dropboxStyle = tabView.dropboxStyle or base.events.dropboxStyle base.events.testGroup = group or tabView.testGroup or base.events.testGroup or events.testGroup or {} base.events.headers = tabView.headers or base.events.headers base.events.kind = tabView.kind or base.events.kind base.events.tableViewStyle = tabView.tableViewStyle or base.events.dropboxStyle base.events.testsFunction = tabView.testsFunction or base.events.testsFunction base.events.typ = tabView.typ or base.events.typ base.events.content_lang = tabView.content_lang or base.events.content_lang base.events.page_lang = tabView.page_lang or base.events.page_lang base.events.user_lang = tabView.user_lang or base.events.user_lang base.events.recursiveLevel = tabView.recursiveLevel or base.events.recursiveLevel base.events.recursiveLimit = tabView.recursiveLimit or base.events.recursiveLimit or 11111 base.events.testGroup = events.testGroup or base.events.testGroup or {} langs.init_languages(base.events.content_lang, base.events.page_lang, base.events.user_lang) return memo, base.events end -- function viewer.zzz_init_configs(base, tabView, group) function viewer.zzz_save_configs(where) -- Save global configuration before eventual changes. -- local where = where .. "" -- TO DEBUG MISSING WHERE if type(where) ~= "string" then where = "where" end -- to not disturb normal string and detect missing where viewer.zzz_save_configs_runs = viewer.zzz_save_configs_runs or {} viewer.zzz_save_configs_runs[where] = { ["where"] = where, ["save"] = "save", } local memo = {} memo.memo_categories_list = events.categories_list memo.memo_tabView = events.tabView memo.memo_testGroup = events.testGroup memo.memo_content_lang = langs.content_lang memo.memo_content_translations = langs.content_translations memo.memo_langs_main_i18n = langs.main_i18n memo.memo_page_lang = langs.page_lang memo.memo_page_translations = langs.page_translations memo.memo_user_lang = langs.user_lang memo.memo_user_translations = langs.user_translations memo.memo_args_known = modes.args_known memo.memo_args_template = modes.args_template memo.memo_modes_catView = modes.catView memo.memo_mode_name = modes.mode_name memo.memo_mode_options = modes.mode_options memo.memo_options_for_modes = modes.options_for_modes memo.memo_recursiveLimit = modes.recursiveLimit memo.memo_report_trackOptions = modes.report_trackOptions memo.memo_template_options = modes.template_options memo.memo_used_options = modes.used_options memo.memo_versn_actual_modules = versn.actual_modules memo.memo_versn_main_i18n = versn.main_i18n return memo end -- function viewer.zzz_save_configs() function viewer.zzz_restore_configs(memo, where) -- Restore global configurations after eventual changes. -- local where = where .. "" -- TO DEBUG MISSING WHERE if type(memo) ~= "table" then events.add_err("events_close_without_memo_err", versn.main_versions.versionName) -- Add an error in the actual table of events. return end if type(where) ~= "string" then where = "where" end -- to not disturb normal string and detect missing where viewer.zzz_restore_configs_runs = viewer.zzz_restore_configs_runs or {} viewer.zzz_restore_configs_runs[where] = { ["where"] = where, ["restore"] = "restore", } local memo = memo events.categories_list = memo.memo_categories_list events.tabView = memo.memo_tabView events.testGroup = memo.memo_testGroup langs.content_lang = memo.memo_content_lang langs.content_translations = memo.memo_content_translations langs.main_i18n = memo.memo_langs_main_i18n langs.page_lang = memo.memo_page_lang langs.page_translations = memo.memo_page_translations langs.user_lang = memo.memo_user_lang langs.user_translations = memo.memo_user_translations langs.init_languages(langs.content_lang, langs.page_lang, langs.user_lang) modes.args_known = memo.memo_args_known modes.args_template = memo.memo_args_template modes.catView = memo.memo_modes_catView modes.mode_name = memo.memo_mode_name modes.mode_options = memo.memo_mode_options modes.options_for_modes = memo.memo_options_for_modes modes.recursiveLimit = memo.memo_recursiveLimit modes.report_trackOptions = memo.memo_report_trackOptions modes.template_options = memo.memo_template_options modes.used_options = memo.memo_used_options versn.actual_modules = memo.memo_versn_actual_modules versn.main_i18n = memo.memo_versn_main_i18n return end -- function viewer.zzz_restore_configs(memo, where) function viewer.zzz_save_configs_check(save_configs_runs, restore_configs_runs) -- AFTER ALL RUNS, report saved global configurations. viewer.zzz_save_configs_runs = save_configs_runs or viewer.zzz_save_configs_runs or {} viewer.zzz_restore_configs_runs = restore_configs_runs or viewer.zzz_restore_configs_runs or {} viewer.zzz_mix_configs_runs, i = {}, 0 for where, one_run in pairs(viewer.zzz_save_configs_runs) do end for where, one_run in pairs(viewer.zzz_restore_configs_runs) do if type(viewer.zzz_save_configs_runs[where]) == "table" then -- normal run, saved and restored one_run["save"] = "save" one_run["restore"] = "restore" viewer.zzz_mix_configs_runs[where] = one_run elseif viewer.zzz_restore_configs_runs[where] and not viewer.zzz_mix_configs_runs[where] then viewer.zzz_mix_configs_runs[where] = one_run one_run["restore"] = "restore" end end viewer.zzz_save_restore_runs = {} for i, one_run in pairs(viewer.zzz_mix_configs_runs) do if one_run["save"] and one_run["restore"] then one_run["err"] = nil -- normal run, saved and restored elseif one_run["save"] then one_run["err"] = "error: restored missing" elseif one_run["restore"] then one_run["err"] = "error: saved missing" end if viewer.zzz_save_configs_runs[where] then one_run["save"] = "save" end if viewer.zzz_restore_configs_runs[where] then one_run["restore"] = "restore" end if (not one_run["save"]) or (not one_run["save"]) then one_run["err"] = "error" end table.insert(viewer.zzz_save_restore_runs, one_run) end --] ] table.sort(viewer.zzz_save_restore_runs, function (a, b) return ( a.where < b.where ) end ) -- Sort based on where for i, one_run in pairs(viewer.zzz_save_restore_runs) do one_run["i"] = i end return viewer.zzz_save_restore_runs end -- function viewer.zzz_save_configs_check(save_configs_runs, restore_configs_runs) -- After all runs, report saved global configurations. function viewer.zzz_save_configs_in_functions_report(t) -- Report known couples of save and restore global configurations. local t = t or "\n* viewer.zzz_save_configs_in_functions_report(t) Report known couples of save and restore global configurations." viewer.zzz_save_configs_check(save_configs_runs, restore_configs_runs) -- Report known couples of save and restore global configurations. -- t = t .. viewer.ta("#viewer.zzz_save_configs_runs", lua_table.level_count(viewer.zzz_save_configs_runs) ) t = t .. viewer.ta("#viewer.zzz_save_restore_runs", lua_table.level_count(viewer.zzz_save_restore_runs) ) t = t .. viewer.ta("#viewer.zzz_restore_configs_runs", lua_table.level_count(viewer.zzz_restore_configs_runs) ) t = t .. viewer.ta("#viewer.zzz_mix_configs_runs", lua_table.level_count(viewer.zzz_mix_configs_runs) ) if type(viewer.zzz_save_restore_runs) ~= "table" then return t end -- abnormal run local tabView = { testGroup = viewer.zzz_save_restore_runs, -- Use default cases. rowGroup = {}, form_one_case = function(one_run) -- Convert a case from testGroup to rowGroup. return { one_run.i, one_run.where, one_run.save, one_run.restore, one_run.err, } end, title_memo = "events_save_configs_report_title", headers = "viewer_zzz_save_configs_report_headers", headers = "i;where;save;restore;errors", } t = t .. "<br/>" .. tableview.new(tabView) -- Form a table view with lines and columns. return t end -- t = t .. viewer.zzz_save_configs_in_functions_report(t) -- cut_libraries -- - - - ------------------ - - - - --------------------------------- -- 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 to import, do not translate. c = 'c', mode = 'mode', options = 'options', itemid = 'itemid', QITEM = 'QITEM', uri = 'uri', -- -- Translate all the following arguments: -- 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.", initial = 'initial', initial_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 = { -- Importar estos argumentos. No traducir. c = 'c', mode = 'mode', options = 'options', itemid = 'itemid', QITEM = 'QITEM', uri = 'uri', -- -- Traducir todos los los argumentos siguientes: -- 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.", initial = 'inicial', initial_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 à importer. Ne pas traduire. c = 'c', mode = 'mode', options = 'options', itemid = 'itemid', QITEM = 'QITEM', uri = 'uri', -- -- Traduire tous les arguments suivants : -- 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.", initial = 'initiale', initial_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] = { ["typ"] = "config", ["need"] = 0, ["keyword"] = "mode", ["syn"] = 2}, -- 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 n'importe quelle langue. ["contentlang"] = { ["typ"] = "config", ["need"] = 0, ["keyword"] = "contentlang"}, ["contentlang"] = { ["typ"] = "config", ["need"] = 0, ["keyword"] = "contentlang"}, ["pagelang"] = { ["typ"] = "config", ["need"] = 0, ["keyword"] = "pagelang"}, ["userlang"] = { ["typ"] = "config", ["need"] = 0, ["keyword"] = "userlang"}, ["knownversions"] = { ["typ"] = "config", ["need"] = 0, ["keyword"] = "knownversions"}, ["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. ["uri"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "uri", ["prop"] = "uri", }, ["country"] = { ["typ"] = "dat", ["need"] = 0, ["keyword"] = "country", ["prop"] = "P27", }, ["birthyear"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "birthyear", ["prop"] = "P569", ["format"] = "year", }, ["deathyear"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "deathyear", ["prop"] = "P570", ["format"] = "year", }, ["lastname"] = { ["typ"] = "dat", ["need"] = 0, ["keyword"] = "lastname", ["prop"] = "P734", }, ["lastname2"] = { ["typ"] = "dat", ["need"] = 0, ["keyword"] = "lastname", ["prop"] = "P734", ["syn"] = 2, }, ["firstname"] = { ["typ"] = "dat", ["need"] = 0, ["keyword"] = "firstname", ["prop"] = "P735", }, ["firstname2"] = { ["typ"] = "dat", ["need"] = 0, ["keyword"] = "firstname", ["prop"] = "P735", ["syn"] = 2, }, ["initial"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "initial", ["prop"] = "P735", }, ["title"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "title", ["prop"] = "P735", }, ["personlang"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "personlang", ["prop"] = "P1412", }, ["QITEM"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "QITEM", ["prop"] = "Q16222597", }, ["itemid"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "QITEM", ["prop"] = "Q16222597", ["syn"] = 2, }, ["label"] = { ["typ"] = "dat", ["need"] = 0, ["keyword"] = "label" , ["prop"] = "label", }, ["sitelink"] = { ["typ"] = "dat", ["need"] = 0, ["keyword"] = "sitelink", ["prop"] = "sitelink", }, ["description"] = { ["typ"] = "dat", ["need"] = 2, ["keyword"] = "description",["prop"] = "description", }, ["sex"] = {["keyword"] = "sex", ["typ"] = "dat", ["need"] = 0, ["prop"] = "P21", ["arg_values"] = "sex_values", ["key_values"] = "male;femelle", }, -- 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 = 29 on 2018-01-15 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 = langs.user_translations[descr] or "**missing translation**" elem.user_lang_key = langs.user_translations[elem.key] or elem.key or "**missing key**" elem.user_lang_keyword = langs.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( langs.content_translations[arg_lev], langs.content_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 = langs.content_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("versn_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(t) return versn.form_support_desk_report() end function versn.form_support_desk_report(t) -- Form the detailed Versions report local memo = viewer.zzz_save_configs("versn.form_support_desk_report") -- Save global configuration before eventual changes. local report_main_discreet = versn.report_main_discreet or " report_main_discreet missing " local t = t or "" t = t .. "\n* Discreet main version: " .. viewer.discreet_main_version() -- .. form_support_desk_report t = t .. "\n* Mediawiki_version: " .. versn.Mediawiki_version() -- Form Mediawiki_version, in error color if it changes. local xxx, strings_c, tables_c, strs_on_tabs, subnames = langs.i18n_sub_counts("langs.main_i18n", "langs_main_i18n_languages_count", "user") t = t .. "\n*" .. viewer.form9user("versn_support_desk_title", report_main_discreet, strs_on_tabs, tables_c) t = t .. "\n*" .. langs.main_i18n_languages_list() -- List available translations languages t = t .. "\n* Start versions from main module: " .. (versn.bind_verif_modules_report_start or " bind_verif_modules_report_start missing ") t = t .. versn.versions_management_report() t = t .. versn.sort_central_modules_report() t = t .. versn.running_times() viewer.zzz_restore_configs(memo, "versn.form_support_desk_report") -- Restore global configurations after eventual changes. return t, details end -- 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) -- read = " box1 ", -- edit = " box1 docdef docline docsrc docdata catview docview : ", -- doc = " nobox1 noerr nocatview ", -- tests = " box1 docdef docline docsrc docdata catview docview : tests ", local res = "" if type(args_final) ~= "table" then args_final = modes.args_final end -- optional arguments langs.init_languages(modes.args_source.contentlang, modes.args_source.pagelang, modes.args_source.userlang) res = res .. "<center><small>" .. viewer.discreet_main_version() .. viewer.ta("contentlang", langs.content_lang) .. viewer.ta("pagelang", langs.page_lang) .. viewer.ta("userlang", langs.user_lang) res = res .. " - [https://fr.wikisource.org/wiki/MediaWiki:Scribunto/Central_modules_reference_manual User manual]" res = res .. " - [[phab:T135845|T135845 Convert task]]" .. "</small></center>" res = res .. viewer.errorColor("<center><b>" .. viewer.form9user("modes_delete_docbox_wng") .. "</b><br/></center>") res = res .. dropbox.form(dropbox.new_title(), versn.form_support_desk_report() ) if modes.option("debug") then res = res .. "\n*" .. viewer.ta("modes.catView", modes.catView) .. viewer.ta("modes.template_options", modes.template_options) .. viewer.ta("modes.mode_options", modes.mode_options) end local datas_link = datas.one_arbitrary_access(datas.props.QITEM) -- or "Q535") if modes.option("docdata") then res = res .. "\n*" .. modes.generDoc(" docdef docline ", datas.args_wikidata, datas_link) end res = res .. ", " .. viewer.form9user(" (%1 properties)", (datas.propss_count_all or "") ) -- datas_structured_data_txt 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 t = t .. langs.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.box1(props, title) -- Draw the main box one. local res = "(p.box1)" local props = props or datas.props or {} -- optional value from p.args_known = { } local warning_versions = versn.report_main_short local title = title or datas.props.uri or "Aristote" -- "Aristote (Q868)" -- local title_1 = datas.one_arbitrary_access(datas.props.QITEM) -- Aristote (Q868) local birthyear_deathyear = " ( " .. datas.prot("birthyear") .. " - " .. datas.prot("deathyear") .. " ) " -- function datas.prot( local flag = "[[File:" .. viewer.form9user("flag_of_country") .. "|border|50px]]" local image = "[[File:" .. viewer.form9user( (props.image or props.P18 or "Victor Hugo.jpg") ) .. "|border|50px]]" if props.image then image = image .. "-image " elseif props.P18 then image = image .. "-P18 " else image = image .. "-else " end props.uri = datas.get_uri() -- Get props.uri for the page. -- props.sitelink = datas.get_uri() -- Get props.uri for the page. props.sitelink = mw.wikibase.sitelink(datas.QITEM) res = res .. "<center><b><big> flag=" .. flag .. " " .. (props.title or "title") .. " - birth=" .. birthyear_deathyear .. " - description=" .. (props.description or "props.description") .. "</big></b></center>" res = res .. "<br/><center>content: uri=" .. (props.uri or "uri") .. " sitelink=" .. (props.sitelink or "sitelink") .. " title=" .. (props.title or "title") .. "</center>" res = res .. "<br/><center>content:<b>" .. langs.content_lang .. "</b>, page:<b>" .. langs.page_lang .. "</b>, user:<b>" .. langs.user_lang .. " - " .. (image or "image") .. "</b></center>" res = res .. "<br>" .. langs.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.box1(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 = modes.args_source or {} 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.contentlang then args_source.contentlang = "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.template_options then args_source.template_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) function p.interact_args_final(args_import, args_known) -- args_final = p.interact_args_final(args_import) -- p.args_known = { -- Table of the definitions of all known arguments at module level. -- local args_known = modes.args_known[key] local t = "" local args_known = args_known or modes.args_known or p.args_known or {} -- optional value from p.args_known = { } 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 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 modes.main_title or a.QITEM or a.itemid or a.title or tit end -- if a.dockey then a.dockey = mw.text.trim(a.dockey) end -- -- local label = modes.args_final.label or modes.main_title or modes.args_final.QITEM or modes.args_final.itemid if not a.QITEM then -- The Title can come from several arguments to insure it. i.QITEM = a.label or modes.main_title or a.QITEM or a.itemid or a.title i.QITEM = mw.text.trim(i.QITEM or "QITEM") else a.QITEM = mw.text.trim(a.QITEM or "QITEM") 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 not a.initial then -- If initial is undefined, enforce it. if a.lastname then i.initial = string.sub( a.lastname, 1, 1 ) -- selector the first letter i.initial = string.upper( i.initial or "*" ) end 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 langs.init_languages() local n = 0 for key, val in pairs(i) do local argskwn = args_known[key] if type(argskwn) == "table" then args_final[key] = val -- = i[key] args_final.src = "inter" n = n + 1 if (args_final.need == 2) and not a[key] then -- -- need = 2 necessary from argument or module interaction events.add_wng("modes_auto_val_warning_wng", langs.user_translations[key], val) -- form_result end else events.add_err("modes_unknown_auto_arg_err", langs.content_translations[key], val) end end modes.args_final = args_final return args_final, t end -- args_final = 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 = " box1 catview ", edit = " box1 docdef docline docsrc docdata catview docview : ", doc = " nobox1 noerr nocatview ", tests = " box1 catview docdef docline docsrc docdata docview : tests docGroup ", } function tracker.init_trakers() -- Initialize some trakers. To run in Central.init() ARGS = tracker.initadd({ ["name"] = "ARGS", ["limit"] = 2 }) -- Initialize a track CNT = tracker.initadd({ ["name"] = "CNT", ["limit"] = 2 }) -- Initialize a track DAT = tracker.initadd({ ["name"] = "DAT", ["limit"] = 2 }) -- Initialize a track EXD = tracker.initadd({ ["name"] = "EXD", ["limit"] = 2, }) -- Initialize a track IAMO = tracker.initadd({ ["name"] = "IAMO", ["limit"] = 2 }) -- Initialize a track MAMO = tracker.initadd({ ["name"] = "MAMO", ["limit"] = 2 }) -- Initialize a track return "\n* ARGS.t=" .. tostring(ARGS.t) .. ", CNT.t=" .. tostring(CNT.t) .. ", EXD.t=" .. tostring(EXD.t) .. ", IAMO.t=" .. tostring(IAMO.t) .. ", MAMO.t=" .. tostring(MAMO.t) end function Central.init(frame, Central_version, mode_name, args_known, options_for_modes) local res = "" tracker.init_trakers() -- Initialize some trakers. To run in Central.init() modes.time1 = os.clock() Central_version = Central_version or langs.Central_version or Central.Central_version options_for_modes = options_for_modes or modes.options_for_modes or p.options_for_modes res = res .. versn.init(frame, Central_version) -- if 1 then return res end res = res .. modes.init_modes_translate_events(frame, Central_version, mode_name, modes.args_known, options_for_modes, QITEM or itemid) datas.props = datas.get_item() -- Get datas from modes.args_final and add wikibase datas for the page. modes.init_args_mode_options(mix, mode_name, modes.args_template) -- Import and mix args mode and options from template and invoke -- S170710mix modes.args_import = modes.import_arguments(args_known, args_source, content_translations, args_wikidata) -- function modes.import_arguments() modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between arguments langs.init_languages() res = res .. (datas.props_trk or "") return res end -- function Central.init(frame, Central_version, mode_name, args_known, options_for_modes, QITEM) 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 = "" local t = Central.init(frame, Central.Central_version, "read", p.args_known, p.options_for_modes) -- res = res .. t res = res .. modes.trackOptions("modes.import_arguments") modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between arguments res = res .. p.form_result(modes.args_final) res = res .. "\n* " .. datas.track_val 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 .. "Library:langs" local t = Central.init(frame, Central.Central_version, "edit", p.args_known, p.options_for_modes) -- res = res .. t res = res .. modes.trackOptions("edit import_arguments", "select_track") modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between argumensts res = res .. p.form_result(modes.args_final) return res end -- function Central.edit(frame) -- {{Central | doc | dockey = versn_sort_central_modules_title | QITEM = Q535 }} function Central.doc(frame) -- Form a documentation or a test in a dropbox. local res = "" local t = Central.init(frame, Central.Central_version, "doc", p.args_known, p.options_for_modes) -- res = res .. t modes.change_itemid() -- default = "Q41568" modes.args_final = p.interact_args_final(modes.args_import) -- Interactions between argumensts --[ [ local dockey = modes.args_final.dockey or modes.args_final[2] dockey = mw.text.trim(dockey) -- clean spaces in each name local QITEM = modes.args_final.QITEM or modes.args_final.id or modes.args_final[3] QITEM = mw.text.trim(QITEM) -- clean spaces in each name --] ] return res end -- function Central.doc(frame) function Central.tests(frame) local res = "" -- if 1 then return res end res = res .. tracker.init_trakers() -- Initialize some trakers. To run in Central.init() local t = Central.init(frame, Central.Central_version, "tests", p.args_known, p.options_for_modes) -- res = res .. t -- if 1 then return res end -- modes.args_import, t = modes.import_arguments() res = res .. "\n* Library:testsgrp" res = res .. modes.trackOptions("Central.tests import_arguments", "select_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 langs.init_languages(a, b, c, d, "Central.tests") versn.main_versions = versn.main_versions or { versionName = "versionName", versionNumber = "0.0", } if not versn.main_versions then versn.main_versions = p.versions or versn.versions end -- res = res .. p.form_result(modes.args_final) -- Generate wikitext, categories, and others -- res = res .. viewer.try_graph() return res end -- function Central.tests(frame) function versn.detect_mediawiki_changes() -- Could record Mediawiki_Versions in Special:PageData T163923 -- { 16, "Important", "20170625", "T163923", 0, "Assigned", "Create Special:PageData as a canonical entry point for machine readable page data.", "Special:PageData done", }, -- { 17, "Important", "20170625", "T168726", 0, "Open", "Create syntax documentation page for Special:PageData.", "Special:PageData doc", }, local t = t or "\n* <b>versn.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 versn.site_currentVersion = mw.site.currentVersion versn.Mediawiki_version_memo = vers if mw.site.currentVersion == versn.Mediawiki_version_memo then versn.site_currentVersion_view = viewer.discreetColor(versn.site_currentVersion) else versn.site_currentVersion_view = viewer.errorColor(versn.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 versn.detect_mediawiki_changes() -- 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 or +2 -- See ISO 8601 time format like : 1977-04-22T01:00:00-05:00 (5 shift hours) = 1977-04-22T06:00:00Z local time versn.Mediawiki_Versions_sort = ">" versn.Mediawiki_Versions = { { site = "fr.wikisource", verstime = "2016-06-19", versid = "2016-06-19", seen_time = "2016-06-19", task = "T155624", report = "Rical: 2016-06-19 Older record in fr.wikisource. Rical added a comment.Jan 21 2017, 08:40", }, { site = "fr.wikisource", verstime = "2017-01-17T21:39", versid = "1.29.0-wmf.8 (a60b7fe)", seen_time = "2017-01-19T23:36", task = "T155624", report = "Rical: 20170119-23:36 : Mediawiki-Wikisource 1.29.0-wmf.8 (a60b7fe)UTC-20170117-21:39.html", }, { site = "fr.wikisource", verstime = "2017-01-06T14:47", versid = "1.29.0-wmf.7 (ca362d6)", seen_time = "2017-01-08T19:38", task = "T155624", report = "Rical: 20170108-19:38 : Mediawiki-Wikisource 1.29.0-wmf.7 (ca362d6)UTC-20170106-14:47.html", }, { site = "fr.wikisource", verstime = "2017-01-05T15:11", versid = "1.29.0-wmf.7 (8f47c69)", seen_time = "2017-01-05T21:33", task = "T155624", report = "Rical: 20170105-21:33 : Mediawiki-Wikisource 1.29.0-wmf.7 (8f47c69)UTC-20170105-15:11.html", }, { site = "fr.wikisource", verstime = "2017-04-03T15:20:00", versid = "1.29.0-wmf.18 (rMW9ab639f85dc6)", seen_time = "2017-04-03T15:20:00-00:00", task = "T155624", report = "Rical: (rMW9ab639f85dc6)", }, { site = "fr.wikisource", verstime = "2017-04-07T20:52:00", versid = "1.29/wmf.19 (e4784c6)", seen_time = "2017-04-08T20:21:00-00:00", task = "T155624", title = "Rical: 2017-04-07-20:52 MediaWiki_1.29/wmf.19>1.29.0-wmf.19", }, { site = "fr.wikisource", verstime = "2017-04-20T21:04:00", versid = "1.29.0-wmf.20 (c37821a)", seen_time = "2017-04-24T11:48:00", }, { site = "fr.wikisource", verstime = "2017-04-24T14:35:00", versid = "1.29.0-wmf.20 (780d62d)", seen_time = "2017-04-24T17:55:00", }, { site = "fr.wikisource", verstime = "2017-04-25T15:31:00", versid = "1.29.0-wmf.20 (8954854)", seen_time = "2017-04-26T17:50:00", }, { site = "fr.wikisource", verstime = "2017-04-25T15:31:00", versid = "1.29.0-wmf.21 (e826acd)", seen_time = "2017-04-26T19:45:00", }, { site = "fr.wikisource", verstime = "2017-04-27T13:25:00", versid = "1.29.0-wmf.21 (e826acd)", seen_time = "2017-04-27T13:25:00-00:00", task = "T163974", title = "Last Mediawiki 1.29.0-wmf.21 or .20 seems disturb Dropboxes", }, { site = "fr.wikisource", verstime = "2017-05-02T18:57:00", versid = "1.29.0-wmf.21 (29800e6)", seen_time = "2017-05-04T06:20:00", }, { site = "fr.wikisource", verstime = "2017-05-09T15:20:00", versid = "1.29.0-wmf.21 (5b4c209)", seen_time = "2017-05-10T10:20:00", }, { site = "fr.wikisource", verstime = "2017-05-10T15:10:00", versid = "1.29.0-wmf.21 (760ddf9)", seen_time = "2017-05-10T20:50:00", }, { site = "fr.wikisource", verstime = "2017-05-11T00:48:00", versid = "1.29.0-wmf.21 (d6c07d1)", seen_time = "2017-05-11T00:48:00-00:00", task = "T165000", title = "The version date of MW 1.29.0-wmf.21 (d6c07d1) is in the future !", report = "Rical: Schedule in https://www.mediawiki.org/wiki/MediaWiki_1.29/Roadmap", }, { site = "fr.wikisource", verstime = "2017-05-11T01:12:00", versid = "1.30.0-wmf.1 (ce662cc)", seen_time = "2017-05-11T14:06:00", }, { site = "fr.wikisource", verstime = "2017-05-11T01:16:00", versid = "1.29.0-wmf.21 (d6c07d1)", seen_time = "2017-05-11T00:48:00", }, { site = "fr.wikisource", verstime = "2017-05-12T19:33:00", versid = "1.30.0-wmf.1 (3fe82bc)", seen_time = "2017-05-11T08:58:00", }, { site = "fr.wikisource", verstime = "2017-05-19T10:58:00", versid = "1.30.0-wmf.1 (245f166)", seen_time = "2017-05-23T19:45:00", }, { site = "fr.wikisource", verstime = "2017-05-24T20:36:00", versid = "1.30.0-wmf.2 (30b848c)", seen_time = "2017-05-24T20:39:00", }, { site = "www.mediawiki", verstime = "2017-05-26T01:51:00", versid = "1.30.0-wmf.2 (b40805f)", seen_time = "2017-05-26T01:51:00", }, { site = "fr.wikisource", verstime = "2017-05-26T01:51:00", versid = "1.30.0-wmf.2 (b40805f)", seen_time = "2017-05-26T01:51:00", }, { site = "fr.wikisource", verstime = "2017-06-07T22:41:00", versid = "1.30.0-wmf.4 (3248a17)", seen_time = "2017-06-09T23:00:00", }, { site = "fr.wikisource", verstime = "2017-06-13T01:59:00", versid = "1.30.0-wmf.4 (5e92916)", seen_time = "2017-06-13T12:30:00", }, { site = "fr.wikisource", verstime = "2017-06-13T14:50:00", versid = "1.30.0-wmf.4 (fd6445e)", seen_time = "2017-06-13T19:00:00", }, { site = "fr.wikisource", verstime = "2017-06-13T19:07:00", versid = "1.30.0-wmf.5 (fe87ea7)", seen_time = "2017-06-13T20:42:00", }, { site = "www.mediawiki", verstime = "2017-06-13T19:07:00", versid = "1.30.0-wmf.5 (fe87ea7)", seen_time = "2017-06-13T21:37:00", }, { site = "fr.wikisource", verstime = "2017-06-15T16:34:00", versid = "1.30.0-wmf.5 (2802709)", seen_time = "2017-06-16T06:30:00", }, { site = "fr.wikisource", verstime = "2017-06-20T21:29:00", versid = "1.30.0-wmf.6 (569a97e)", seen_time = "2017-06-21T20:45:00", }, { site = "fr.wikisource", verstime = "2017-06-22T20:25:00", versid = "1.30.0-wmf.6 (85da774)", seen_time = "2017-06-22T20:52:00", }, { site = "fr.wikisource", verstime = "2017-06-26T15:35:00", versid = "1.30.0-wmf.6 (720c1b3)", seen_time = "2017-06-27T05:20:00", }, { site = "www.mediawiki", verstime = "2017-06-27T22:09:00", versid = "1.30.0-wmf.7 (3608819)", seen_time = "2017-06-27T05:08:00", }, { site = "fr.wikisource", verstime = "2017-06-27T22:09:00", versid = "1.30.0-wmf.7 (3608819)", seen_time = "2017-06-28T21:40:00", }, { site = "fr.wikisource", verstime = "2017-06-29T20:08:00", versid = "1.30.0-wmf.7 (32a2645)", seen_time = "2017-06-29T23:09:00", }, { site = "fr.wikisource", verstime = "2017-07-05T23:24:00", versid = "1.30.0-wmf.7 (9ae1d1b)", seen_time = "2017-07-06T05:50:00", }, { site = "fr.wikisource", verstime = "2017-07-06T20:45:00", versid = "1.30.0-wmf.7 (231b5ef)", seen_time = "2017-07-06T20:50:00", }, { site = "fr.wikisource", verstime = "2017-07-10T12:16:00", versid = "1.30.0-wmf.7 (acb0b4a)", seen_time = "2017-07-10T18:25:00", }, { site = "fr.wikisource", verstime = "2017-07-11T15:31:00", versid = "1.30.0-wmf.7 (13f08e9)", seen_time = "2017-07-11T21:42:00", }, { site = "www.mediawiki", verstime = "2017-07-11T19:43:00", versid = "1.30.0-wmf.9 (455051d)", seen_time = "2017-07-12T06:42:00", }, { site = "fr.wikisource", verstime = "2017-07-12T21:04:00", versid = "1.30.0-wmf.9 (136e975)", seen_time = "2017-07-13T22:00:00", }, { site = "fr.wikisource", verstime = "2017-07-17T23:48:00", versid = "1.30.0-wmf.9 (63a0e7c)", seen_time = "2017-07-18T11:08:00", }, { site = "www.mediawiki", verstime = "2017-07-18T18:04:00", versid = "1.30.0-wmf.9 (455051d)", seen_time = "2017-07-18T19:30:00", }, { site = "www.mediawiki", verstime = "2017-07-18T18:04:00", versid = "1.30.0-wmf.10 (cf8ce2d)", seen_time = "2017-07-19T18:50:00", }, { site = "fr.wikisource", verstime = "2017-07-18T19:54:00", versid = "1.30.0-wmf.9 (65000c0)", seen_time = "2017-07-18T19:30:00", }, { site = "www.mediawiki", verstime = "2017-07-19T20:59:00", versid = "1.30.0-wmf.10 (3646c26)", seen_time = "2017-07-19T20:55:00", }, { site = "fr.wikisource", verstime = "2017-07-19T20:59:00", versid = "1.30.0-wmf.9 (4a34db9)", seen_time = "2017-07-19T20:55:00", }, { site = "fr.wikisource", verstime = "2017-07-19T20:59:00", versid = "1.30.0-wmf.10 (3646c26)", seen_time = "2017-07-19T21:30:00", }, { site = "fr.wikisource", verstime = "2017-07-24T20:16:00", versid = "1.30.0-wmf.10 (0e25717)", seen_time = "2017-07-25T21:45:00", }, { site = "fr.wikisource", verstime = "2017-07-26T20:37:00", versid = "1.30.0-wmf.11 (273b050)", seen_time = "2017-07-27T18:20:00", }, { site = "fr.wikisource", verstime = "2017-07-27T20:41:00", versid = "1.30.0-wmf.11 (83a9694)", seen_time = "2017-07-28T07:25:00", }, { site = "fr.wikisource", verstime = "2017-07-31T20:05:00", versid = "1.30.0-wmf.11 (2d7e373)", seen_time = "2017-07-31T18:35:00", }, { site = "www.mediawiki", verstime = "2017-08-03T01:13:54", versid = "1.30.0-wmf.12 (a937cda)", seen_time = "2017-08-03T05:47:00", }, { site = "fr.wikisource", verstime = "2017-08-03T01:13:54", versid = "1.30.0-wmf.12 (a937cda)", seen_time = "2017-08-03T20:20:00", }, { site = "fr.wikisource", verstime = "2017-08-07T20:56:00", versid = "1.30.0-wmf.12 (59819d3)", seen_time = "2017-08-09T11:45:00", }, { site = "fr.wikisource", verstime = "2017-08-08T19:13:23", versid = "1.30.0-wmf.13 (6d6a077)", seen_time = "2017-08-09T11:45:00", }, { site = "fr.wikisource", verstime = "2017-08-11T22:02:23", versid = "1.30.0-wmf.13 (bc30e62)", seen_time = "2017-08-12T23:18:00", }, { site = "fr.wikisource", verstime = "2017-08-12T21:44:00", versid = "1.30.0-wmf.13 (103d94a)", seen_time = "2017-08-16T09:50:00", }, { site = "fr.wikisource", verstime = "2017-08-15T20:23:46", versid = "1.30.0-wmf.14 (984ec26)", seen_time = "2017-08-16T09:50:00", }, { site = "fr.wikisource", verstime = "2017-08-17T20:56:47", versid = "1.30.0-wmf.14 (36b8ed6)", seen_time = "2017-08-18T05:12:00", }, { site = "fr.wikisource", verstime = "2017-08-18T02:39:14", versid = "1.30.0-wmf.14 (e993fed)", seen_time = "2017-08-24T12:21:00", }, { site = "fr.wikisource", verstime = "2017-08-23T21:27:44", versid = "1.30.0-wmf.15 (9323f8b)", seen_time = "2017-08-18T04:17:00", }, { site = "fr.wikisource", verstime = "2017-08-29T01:35:00", versid = "1.30.0-wmf.15 (4a27f2b)", seen_time = "2017-08-29T15:27:00", }, { site = "fr.wikisource", verstime = "2017-08-29T19:19:02", versid = "1.30.0-wmf.16 (e052d64)", seen_time = "2017-08-29T15:27:00", }, { site = "fr.wikisource", verstime = "2017-08-31T20:42:38", versid = "1.30.0-wmf.16 (a3a950e)", seen_time = "2017-09-01T05:10:00", }, { site = "fr.wikisource", verstime = "2017-09-05T18:08:00", versid = "1.30.0-wmf.16 (1f95e6a)", seen_time = "2017-09-06T09:30:00", }, { site = "fr.wikisource", verstime = "2017-09-05T19:12:08", versid = "1.30.0-wmf.17 (579f1bb)", seen_time = "2017-09-06T09:30:00", }, { site = "fr.wikisource", verstime = "2017-09-07T23:23:14", versid = "1.30.0-wmf.17 (259e37a)", seen_time = "2017-09-08T06:12:00", }, { site = "fr.wikisource", verstime = "2017-09-11T16:12:03", versid = "1.30.0-wmf.17 (a31f1c1)", seen_time = "2017-09-12T05:16:00", }, { site = "fr.wikisource", verstime = "2017-09-12T15:11:52", versid = "1.30.0-wmf.17 (9b0276a)", seen_time = "2017-09-12T20:44:00", }, { site = "www.mediawiki", verstime = "2017-09-12T21:14:48", versid = "1.30.0-wmf.18 (a77f850)", seen_time = "2017-09-13T14:35:00", }, { site = "fr.wikisource", verstime = "2017-09-12T21:14:48", versid = "1.30.0-wmf.18 (a77f850)", seen_time = "2017-09-13T20:19:00", }, { site = "fr.wikisource", verstime = "2017-09-19T17:24:00", versid = "1.30.0-wmf.18 (638e398)", seen_time = "2017-09-20T05:29:00", }, { site = "www.mediawiki", verstime = "2017-09-19T18:30:54", versid = "1.30.0-wmf.19 (c3a0f25)", seen_time = "2017-09-20T05:29:00", }, { site = "fr.wikisource", verstime = "2017-09-20T20:31:07", versid = "1.30.0-wmf.19 (37a8875)", seen_time = "2017-09-21T14:08:00", }, { site = "fr.wikisource", verstime = "2017-09-22T01:21:06", versid = "1.30.0-wmf.19 (8ed47bf)", seen_time = "2017-09-23T05:10:00", }, { site = "fr.wikisource", verstime = "2017-09-25T18:21:02", versid = "1.30.0-wmf.19 (6e753d3)", seen_time = "2017-09-26T05:12:00", }, { site = "fr.wikisource", verstime = "2017-09-27T11:54:00", versid = "1.30.0-wmf.19 (737ee4f)", seen_time = "2017-09-27T15:15:00", }, { site = "fr.wikisource", verstime = "2017-09-27T16:20:10", versid = "1.31.0-wmf.1 (f5d33a5)", seen_time = "2017-09-27T15:15:00", }, { site = "fr.wikisource", verstime = "2017-09-28T06:53:46", versid = "1.31.0-wmf.1 (963972f)", seen_time = "2017-09-28T11:59:00", }, { site = "fr.wikisource", verstime = "2017-10-03T01:33:23", versid = "1.31.0-wmf.1 (a1225fa)", seen_time = "2017-10-03T07:59:00", }, { site = "fr.wikisource", verstime = "2017-10-03T15:36:00", versid = "1.31.0-wmf.1 (1b01e53)", seen_time = "2017-10-03T20:44:00", }, { site = "www.mediawiki", verstime = "2017-10-03T19:45:39", versid = "1.31.0-wmf.2 (25e1684)", seen_time = "2017-10-03T20:44:00-00:00", task = "T155624", title = "Seb35: 2017-10-07T12:12 could Rical observe?", }, { site = "fr.wikisource", verstime = "2017-10-11T19:17:18", versid = "1.31.0-wmf.3 (c5edfc3)", seen_time = "2017-10-12T18:52:00", }, { site = "fr.wikisource", verstime = "2017-10-16T20:44:31", versid = "1.31.0-wmf.3 (d3bfa8c)", seen_time = "2017-10-17T13:12:00", }, { site = "fr.wikisource", verstime = "2017-10-17T15:13:26", versid = "1.31.0-wmf.3 (c3925df)", seen_time = "2017-10-17T18:10:00", }, { site = "www.mediawiki", verstime = "2017-10-17T19:07:27", versid = "1.31.0-wmf.4 (477691b)", seen_time = "2017-10-17T20:05:00", }, { site = "fr.wikisource", verstime = "2017-10-17T19:07:27", versid = "1.31.0-wmf.4 (477691b)", seen_time = "2017-10-19T06:54:00", }, { site = "fr.wikisource", verstime = "2017-10-20T18:02:49", versid = "1.31.0-wmf.4 (d7b75f4)", seen_time = "2017-10-24T04:53:00", }, { site = "fr.wikisource", verstime = "2017-10-24T18:23:04", versid = "1.31.0-wmf.5 (ce688d5)", seen_time = "2017-10-25T23:03:00", }, { site = "fr.wikisource", verstime = "2017-10-31T00:15:00", versid = "1.31.0-wmf.5 (3a95690)", seen_time = "2017-10-31T21:48:00", }, { site = "www.mediawiki", verstime = "2017-10-31T16:48:30", versid = "1.31.0-wmf.6 (b5d8aad)", seen_time = "2017-10-31T21:48:00", }, { site = "fr.wikisource", verstime = "2017-11-01T20:19:47", versid = "1.31.0-wmf.6 (d59aefd)", seen_time = "2017-11-01T20:56:00", }, { site = "fr.wikisource", verstime = "2017-11-06T14:53:13", versid = "1.31.0-wmf.6 (3867d21)", seen_time = "2017-11-06T21:11:00", }, { site = "www.mediawiki", verstime = "2017-11-07T19:09:21", versid = "1.31.0-wmf.7 (03448d8)", seen_time = "2017-11-08T06:49:00", }, { site = "fr.wikisource", verstime = "2017-11-07T19:09:21", versid = "1.31.0-wmf.7 (03448d8)", seen_time = "2017-11-09T07:04:00", }, { site = "fr.wikisource", verstime = "2017-11-14T14:58:16", versid = "1.31.0-wmf.7 (5c543d7)", seen_time = "2017-11-14T17:45:00", }, { site = "www.mediawiki", verstime = "2017-11-14T18:48:33", versid = "1.31.0-wmf.8 (33df702)", seen_time = "2017-11-15T08:21:10", }, { site = "fr.wikisource", verstime = "2017-11-16T17:51:59", versid = "1.31.0-wmf.8 (30a4750)", seen_time = "2017-11-16T18:20:00", }, { site = "fr.wikisource", verstime = "2017-12-07T23:25:30", versid = "1.31.0-wmf.11 (4342977)", seen_time = "2017-12-09T05:51:00", }, { site = "fr.wikisource", verstime = "2017-12-11T20:12:30", versid = "1.31.0-wmf.11 (6d47031)", seen_time = "2017-12-12T20:07:00", }, { site = "www.mediawiki", verstime = "2017-12-12T17:30:22", versid = "1.31.0-wmf.12 (ee842bb)", seen_time = "2017-12-13T07:11:00", }, { site = "fr.wikisource", verstime = "2017-12-12T17:30:22", versid = "1.31.0-wmf.12 (ee842bb)", seen_time = "2017-12-14T06:25:00", }, { site = "fr.wikisource", verstime = "2017-12-14T20:13:27", versid = "1.31.0-wmf.12 (5056cef)", seen_time = "2017-12-14T22:17:00", }, { site = "fr.wikisource", verstime = "2017-12-15T23:35:09", versid = "1.31.0-wmf.12 (2bbe2d4)", seen_time = "2017-12-18T19:34:00", }, { site = "fr.wikisource", verstime = "2018-01-02T18:49:06", versid = "1.31.0-wmf.15 (8e46998)", seen_time = "2018-01-04T14:20:00", }, { site = "fr.wikisource", verstime = "2018-01-04T21:47:05", versid = "1.31.0-wmf.15 (601cf9d)", seen_time = "2018-01-07T18:30:00", }, { site = "fr.wikipedia", verstime = "2018-01-07T20:46:36", versid = "1.31.0-wmf.15 (0953700)", seen_time = "2018-01-09T20:57:00", }, { site = "fr.wikisource", verstime = "2018-01-07T20:46:36", versid = "1.31.0-wmf.15 (0953700)", seen_time = "2018-01-12T07:43:00", }, { site = "fr.wikisource", verstime = "2017-12-15T23:35:09", versid = "1.31.0-wmf.16 (a31d45c)", seen_time = "2018-01-12T07:43:00", task = "T155624", title = "In wikisource/Spécial:Version:wmf.15 (0953700) but Central module mw = 1.31.0-wmf.16 (a31d45c) seen by Rical.", }, { site = "www.mediawiki", verstime = "2018-01-11T20:29:30", versid = "1.31.0-wmf.16 (ab6bf1f)", seen_time = "2018-01-13T06:11:00", }, { site = "fr.wikisource", verstime = "2018-01-16T18:33:22", versid = "1.31.0-wmf.16 (d3c472e)", seen_time = "2018-01-17T06:59:00", }, { site = "www.mediawiki", verstime = "2018-01-16T21:16:44", versid = "1.31.0-wmf.17 (d543eb9)", seen_time = "2018-01-17T06:59:00", }, { site = "fr.wikisource", verstime = "2018-01-18T01:23:03", versid = "1.31.0-wmf.17 (d8c8c31)", seen_time = "2018-01-19T08:16:00", }, } versn.Mediawiki_version_memo = "1.31.0-wmf.17 (d8c8c31)" -- in fr.wikisource versn.Mediawiki_Versions_sort = "<" -- First on end, Last on begin versn.Mediawiki_Versions_sort = ">" -- First on begin, Last on end -- on 20180105.1530 fr.wikipedia.org = 10.0.23-MariaDB-log ; www.mediawiki.org = 10.0.31-MariaDB ; fr.wikisource.org = 10.0.32-MariaDB ; function viewer.docGroup(selector) -- Form all documentations of tests and reports. -- snaks tst local res = "" Central.tst = false -- To form documentations of only some tests and reports. Central.tst = true -- To form all tests and reports. -- snaks tst if Central.tst then -- Select which tests to form. res = res .. viewer.docSection(selector, "Tests of this page", "h2") res = res .. dropbox.new(selector, "datas.get_item() Tests of the import of wikidatas from the wikibase snaks **", datas.get_datas_report) -- local t = t or "\n* modes.args_known_report(t) Report of main known args." res = res .. dropbox.new(selector, "modes_args_known_report_title", modes.args_known_report) -- res = res .. viewer.docSection(selector, "viewer_page_tests_h2_title", "h2") else res = res .. viewer.docPage(selector) res = res .. viewer.docModule(selector) res = res .. viewer.docInternal(selector) end return res end -- function viewer.docGroup(selector) item: return p -- Utilisateur:Rical/MediawikiVersion -- Module to test, last change : 2018-01-12 à 20:58:47 -- Module:MediawikiVersion/Documentation -- Module to test, last change : 2018-01-12 à 20:58:47 -- Module:MediawikiVersion -- Module to test, last change : 2018-01-12 à 20:58:47 -- Usual pages for Translations (for easier select the test page when edit this module in other wikis) -- 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 -- 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 -- Utilisateur:Rical/Auteur:Victor Hugo (Q535) -- content Module:Author3 -- Utilisateur:Rical/Auteur:Nelson Mandela (Q8023)-- content Module:Central-s-fr/Documentation -- Module:Central-s-fr/Documentation {{#invoke:Central-s-fr|read}} fr = French = Français proto -- Galilée (Q307), Victor Hugo (Q535), Aristote (Q868), Albert Einstein (Q937), Mohandas Karamchand Gandhi (Q1001), Christophe Colomb (Q7322), -- Nelson Mandela (Q8023), Rudyard Kipling (Q34743), Martin Fleischmann (Q899264), Emmanuel Macron (Q3052772) -- After the last tests pages on 2018-01-25 -- Auteur3:Aristote -- ws.Module:Auteur3 (Q868) -- ModuleTpt/Victor Hugo -- ws.Module:Tpt (Q535) -- Auteur3:Nelson Mandela -- ws.Module:Auteur3 (Q8023) -- Module:Central-s-fr/Galilée -- ws.Module:Central (Q307) -- Module:Tests/Victor Hugo -- ws.Module:Tests (Q535) -- Module:Central-s-fr/Documentation -- wp.Module:Central (doc) -- Module:Tests/Aristote -- wp.ws.Module:Tests (Q868) -- Utilisateur:Rical/Rudyard Kipling -- wp.Module:Central (Q34743) -- Utilisateur:Rical/Nelson Mandela -- wp.Module:Tests (Q8023) -- After the last tests page on 2018-01-27 -- Utilisateur:Rical/Nelson Mandela -- ws.Module:Central-s-fr (Q8023) -- ]=====]