Модуль:Локаль
| ||
---|---|---|
Тематические статьи | ||
Техническая справка | ||
Тэги MediaWiki: | ||
Общие правила | ||
Модуль для типографики и прочего.
аттическими
- Возвращает число, записанное аттическими цифрами
глаголицей
- Возвращает строку, переписанную из кириллицы в глаголицу
греческими
- Возвращает число, записанное греческими цифрами
еврейскими
- Возвращает число, записанное еврейскими цифрами
кириллицей
- Возвращает число, записанное кириллицей
прописью
- Возвращает число, записанное прописью
римскими
- Возвращает число, записанное римскими цифрами
-- Dependencies:
local keys = require 'Module:TableTools'.numKeys
local merge = require 'Module:Array'.table_merge
local u = mw.ustring
local gsub, char, sub, len, lower = u.gsub, u.char, u.sub, u.len, u.lower
local floor = math.floor
local clone = mw.clone
local lang = mw.language.getContentLanguage ()
-- Get alternative titles from Help page:
local function names (main)
local results = mw.smw.ask {
[1] = '[[Является представителем::Справка:Функция Lua]]'
.. '[[Название::' .. main .. ']]'
, [2] = '?Другое название'
, mainlabel = '-'
, link = 'none'
}
local ret = results and results [1] ['Другое название'] or {}
if type (ret) ~= 'table' then
ret = {ret}
end
ret [#ret + 1] = main
return ret
end -- local function names (main)
-- Export APIs:
local function exportAPIs (exported, implementation, settings)
for service, system in pairs (settings.systems) do
local APIs = type (service) == 'table' and service or {service}
-- {{#invoke:}}
for _, alias in ipairs (APIs) do
exported [alias] = function (frame)
return implementation (system, settings, frame.args)
end
end
-- require:
if system.lua then
exported [system.lua] = function (...)
return implementation (system, settings, {...})
end
end
end -- for service, system in pairs (settings.systems)
end -- local function exportAPIs (exported, implementation, settings)
-- Перевод арабских цифр в неарабские:
-- Numerals:
local numeralData = {
systems = {
-- Прописью:
[{'прописью'}] = {
[1] = ' один'
, [2] = ' два'
, [3] = ' три'
, [4] = ' четыре'
, [5] = ' пять'
, [6] = ' шесть'
, [7] = ' семь'
, [8] = ' восемь'
, [9] = ' девять'
, [11] = ' одиннадцать'
, [12] = ' двенадцать'
, [13] = ' тринадцать'
, [14] = ' четырнадцать'
, [15] = ' пятнадцать'
, [16] = ' шестнадцать'
, [17] = ' семнадцать'
, [18] = ' восемнадцать'
, [19] = ' девятнадцать'
, [10] = ' десять'
, [20] = ' двадцать'
, [30] = ' тридцать'
, [40] = ' сорок'
, [50] = ' пятьдесят'
, [60] = ' шестьдесят'
, [70] = ' семьдесят'
, [80] = ' восемьдесят'
, [90] = ' девяносто'
, [100] = ' сто'
, [200] = ' двести'
, [300] = ' триста'
, [400] = ' четыреста'
, [500] = ' пятьсот'
, [600] = ' шестьсот'
, [700] = ' семьсот'
, [800] = ' восемьсот'
, [900] = ' девятьсот'
-- Тысячи:
, [1000] = function (str, number)
local feminine = gsub (gsub (str, 'один$', 'одна'), 'два$', 'две')
return feminine .. ' ' .. lang:plural (number, {'тысяча', 'тысячи', 'тысяч'})
end
, [1000000] = function (str, number)
return str .. ' ' .. lang:plural (number, {'миллион', 'миллиона', 'миллионов'})
end
, [10000000000] = function (str, number)
return str .. ' ' .. lang:plural (number, {'миллиард', 'миллиарда', 'миллиардов'})
end
, wrap = function (str)
-- Удаление пробела слева:
return sub (str, 2)
end
} -- [{'прописью'}] = {...}
-- Римские цифры:
, [names 'римскими'] = {
lua = 'roman'
, [1] = 'I'
, [4] = 'IV'
, [5] = 'V'
, [9] = 'IX'
, [10] = 'X'
, [40] = 'XL'
, [50] = 'L'
, [90] = 'XC'
, [100] = 'C'
, [400] = 'CD'
, [500] = 'D'
, [900] = 'CM'
, [1000] = 'M'
, [5000] = 'ↁ'
, [10000] = 'ↂ'
, [50000] = 'ↇ'
, [100000] = 'ↈ'
-- Единственный случай, когда порог применения «цифры» отличается от её значения:
, [500000] = {digit = function (str)
return '<span style="text-decoration: overline">' .. str .. '</span>'
end, value = 1000}
, [1000000] = function (str)
return '<span style="padding-top: 1px; border-top: 1px solid; text-decoration: overline;">'
.. str
.. '</span>'
end
, unicode = {
[1] = 'Ⅰ'
, [2] = 'Ⅱ'
, [3] = 'Ⅲ'
, [4] = 'Ⅳ'
, [5] = 'Ⅴ'
, [6] = 'Ⅵ'
, [7] = 'Ⅶ'
, [8] = 'Ⅷ'
, [9] = 'Ⅸ'
, [10] = 'Ⅹ'
, [11] = 'Ⅺ'
, [12] = 'Ⅻ'
, [40] = 'ⅩⅬ'
, [50] = 'Ⅼ'
, [90] = 'ⅩⅭ'
, [100] = 'Ⅽ'
, [400] = 'ⅭⅮ'
, [500] = 'Ⅾ'
, [900] = 'ⅭⅯ'
, [1000] = 'Ⅿ'
-- , API = {'римскими-юникод', 'римские-юникод', 'roman-unicode'}
} -- ['unicode']
, ['unicode-small'] = {
[1] = 'ⅰ'
, [2] = 'ⅱ'
, [3] = 'ⅲ'
, [4] = 'ⅳ'
, [5] = 'ⅴ'
, [6] = 'ⅵ'
, [7] = 'ⅶ'
, [8] = 'ⅷ'
, [9] = 'ⅸ'
, [10] = 'ⅹ'
, [11] = 'ⅺ'
, [12] = 'ⅻ'
, [40] = 'ⅹⅼ'
, [50] = 'ⅼ'
, [90] = 'ⅹⅽ'
, [100] = 'ⅽ'
, [400] = 'ⅽⅾ'
, [500] = 'ⅾ'
, [900] = 'ⅽⅿ'
, [1000] = 'ⅿ'
--, API = {'римскими-юникод-малыми', 'римские-юникод-малые', 'roman-unicode-small'}
} -- ['unicode-small']
} -- [names 'римскими']
-- Старые греческие «цифры»:
, [names 'греческими'] = {
[1] = 'Α'
, [2] = 'Β'
, [3] = 'Γ'
, [4] = 'Δ'
, [5] = 'Ε'
, [6] = 'Ϛ'
, [7] = 'Ζ'
, [8] = 'Η'
, [9] = 'Θ'
, [10] = 'Ι'
, [20] = 'Κ'
, [30] = 'Λ'
, [40] = 'Μ'
, [50] = 'Ν'
, [60] = 'Ξ'
, [70] = 'Ο'
, [80] = 'Π'
, [90] = 'Ϙ'
, [100] = 'Ρ'
, [200] = 'Σ'
, [300] = 'Τ'
, [400] = 'Υ'
, [500] = 'Φ'
, [600] = 'Χ'
, [700] = 'Ψ'
, [800] = 'Ω'
, [900] = 'Ϡ'
-- Левая керая для тысяч:
, [1000] = function (str) return '͵' .. str end
, lang = 'el'
} -- [names 'греческими']
-- Аттические «цифры»:
-- alternative_names (main)
, [names 'аттическими'] = {
[1] = 'Ι'
, [5] = 'Π'
, [10] = 'Δ'
, [50] = char (0x10144)
, [100] = 'Η'
, [500] = char (0x10145)
, [1000] = 'Χ'
, [5000] = char (0x10146)
, [10000] = 'Μ'
, [50000] = char (0x10147)
, lang = 'el'
} -- [names 'аттическими']
-- Старые еврейские «цифры»:
, [names 'еврейскими'] = {
[1] = 'א'
, [2] = 'ב'
, [3] = 'ג'
, [4] = 'ד'
, [5] = 'ה'
, [6] = 'ו'
, [7] = 'ז'
, [8] = 'ח'
, [9] = 'ט'
, [10] = 'י'
-- Исключения для 15 и 16:
, [15] = 'טו'
, [16] = 'טז'
, [17] = 'יז'
, [18] = 'יח'
, [19] = 'יט'
, [20] = 'כ'
, [30] = 'ל'
, [40] = 'מ'
, [50] = 'נ'
, [60] = 'ס'
, [70] = 'ע'
, [80] = 'פ'
, [90] = 'צ'
, [100] = 'ק'
, [200] = 'ר'
, [300] = 'ש'
, [400] = 'ת'
, [1000] = function (str) return str .. '׳' end
, lang = 'he'
, wrap = function (str)
if len (str) > 1 then
-- Вставка гершаим перед последним символом, но не рядом с герешем:
if not (sub (str, -1) == '׳' or sub (str, -2, -2) == '׳') then
return sub (str, 1, -2) .. '״' .. sub (str, -1)
else
return str
end
else
-- Вставка гереша:
return str .. '׳'
end -- if mw.ustring.len (str) > 1
end -- wrap = function (str)
, rtl = true
} -- [names 'еврейскими']
-- Старые кириллические «цифры». Используется «малый счёт»:
, [names 'кириллицей'] = {
[1] = 'А'
, [2] = 'В'
, [3] = 'Г'
, [4] = 'Д'
, [5] = 'Є'
, [6] = 'Ѕ'
, [7] = 'З'
, [8] = 'И'
, [9] = 'Ѳ'
, [10] = 'І'
, [11] = 'АІ'
, [12] = 'ВІ'
, [13] = 'ГІ'
, [14] = 'ДІ'
, [15] = 'ЄІ'
, [16] = 'ЅІ'
, [17] = 'ЗІ'
, [18] = 'ИІ'
, [19] = 'ѲІ'
, [20] = 'К'
, [30] = 'Л'
, [40] = 'М'
, [50] = 'Н'
, [60] = 'Ѯ'
, [70] = 'Ѻ'
, [80] = 'П'
, [90] = 'Ч'
, [100] = 'Р'
, [200] = 'С'
, [300] = 'Т'
, [400] = 'У'
, [500] = 'Ф'
, [600] = 'Х'
, [700] = 'Ѱ'
, [800] = 'Ω'
, [900] = 'Ц'
-- Тысячи:
, [1000] = function (str) return gsub (str, '%a', '҂%0', n) end
-- Тьмы:
, [10000] = function (str) return gsub (str, '%a', '%0⃝', n) end
-- Легионы:
, [100000] = function (str) return gsub (str, '%a', '%0҈', n) end
-- Леодры:
, [1000000] = function (str) return gsub (str, '%a', '%0҉', n) end
-- Вороны:
, [10000000] = function (str) return gsub (str, '%a', '%0꙰', n) end
-- Колоды:
, [100000000] = function (str) return gsub (str, '%a', '%0꙱', n) end
, lang = 'cu'
} -- [names 'кириллицей']
}, -- systems
-- Ошибки:
noNumber = 'Передайте аргумент',
notAnumber = 'Передайте целое число',
notInteger = 'Дроби не поддерживаются',
notPositive = 'Неположительные числа не поддерживаются',
-- Аргументы:
argNumber = 1, -- число
argLower = 'строчными'
}
local function formatNumeralError (message, ...)
if select ('#', ...) > 0 then
message = string.format (message, ...)
end
return '<span class="error">' .. message .. '</span>'
end
-- Проверка правильности переданного параметра:
local function loadNumber (number, noNumber, notAnumber, notInteger, notPositive)
-- Нет аргумента:
if not number then
return false, formatNumeralError (noNumber)
end
-- Проверки:
local result = tonumber (number)
-- Это число:
if not result then
return false, formatNumeralError (notAnumber, number)
end
-- Это целое:
if math.floor (result) ~= result then
return false, formatNumeralError (notInteger, number)
end
-- Это натуральное:
if result <= 0 then
return false, formatNumeralError (notPositive, number)
end
return true, result
end -- local function loadNumber (number, noNumber, notAnumber, notInteger, notPositive)
-- Проверка правильности переданного параметра «строчными»:
local function loadLower (str)
return true, str and str ~= ''
end
--[[
НАЗНАЧЕНИЕ: Эта функция переводит натуральные числа арабскими цифрами в римские или другие.
ПАРАМЕТРЫ: number -- Натуральное число,
system -- система отображения, напр., «римскими»,
lower -- true, чтобы привести вывод к нижнему регистру.
ВЫВОД: Нет.
ВОЗВРАТ: 0, сообщение об ошибке - Ошибка из-за неверного аргумента
строка - число римскими цифрами
ПРИМЕЧАНИЕ: Все проверки аргумента уже проведены в loadNumber.
--]]
local function implement2nonarabic (number, conf)
local ret = ''
local residue = number
local thresholds = keys (conf)
-- table.sort () sort in place:
table.sort (thresholds, function (a, b) --[[descending]] return a > b end)
for _, threshold in ipairs (thresholds) do
local value, digit = threshold, conf [threshold]
if type (digit) == 'table' then
value, digit = digit.value, digit.digit
end
local converted = ''
if residue >= threshold then
-- if the digit is at all applicable (the number is great enough):
if type (digit) == 'string' then
-- простая «цифра»:
while residue >= value do
residue = residue - value
converted = converted .. digit
end
elseif type (digit) == 'function' then
-- более сложное оформление для больших чисел:
local quotient = floor (residue / value)
converted = digit (implement2nonarabic (quotient, conf), quotient)
residue = residue % value
end
ret = ret .. converted
end -- if residue >= threshold then
end -- for _, threshold in ipairs (thresholds) do
return ret
end -- local function implement2nonarabic (number, conf)
-- Загрузка конфигурации системы счисления:
local function loadConf (conf, options)
local loaded = clone (conf)
-- Overrides:
for _, override in ipairs (options) do
loaded = merge (loaded, loaded [override])
end
return loaded
end -- local function loadConf (conf, options)
-- Загрузка аргументов и вызов реализации:
local function toNonarabic (system, service, args)
local ok
-- Загрузка и проверка аргумента:
local number
ok, number = loadNumber (args [service.argNumber], service.noNumber, service.notAnumber, service.notInteger, service.notPositive)
if not ok then
-- Ошибка в аргументе:
return number
end
-- Загрузка и проверка показателя нижнего регистра:
local toLower = false
ok, toLower = loadLower (args [service.argLower])
if not ok then
-- Ошибка в аргументе «строчными»:
return toLower
end
-- Остальные аргументы — система счисления и дополнительные аргументы:
local options = clone (args)
options [service.argNumber] = nil
options [service.argLower] = nil
local conf = loadConf (system, options)
-- Действительное преобразование:
local ret = implement2nonarabic (number, conf)
-- Постпроцессинг, если требуется:
if conf.wrap and type (conf.wrap) == 'function' then
ret = conf.wrap (ret)
end
-- Строчными, если просят:
if toLower then ret = lower (ret) end
-- Обёртка в указатель на язык и указатель направления:
local dir = conf.rtl and ' dir="rtl"' or ''
local lang = conf.lang and ' lang="' .. conf.lang .. '"' or ''
if conf.rtl or conf.lang then
ret = '<span class="foreign-lang"' .. lang .. dir ..'>' .. ret .. '</span>'
end
return ret
end -- local function toNonarabic (system, service, args)
local function get_settings (system, subsystem)
for aliases, settings in pairs (numeralData.systems) do
if settings.lua == system then
-- Lua alias:
return merge (settings, settings [subsystem])
end
for _, alias in ipairs (aliases) do
-- Wiki alias:
if alias == system then
return merge (settings, settings [subsystem])
end
end
end
end -- local function get_settings (system, subsystem)
local function grammar (system, subsystem)
local values = get_settings (system, subsystem)
-- Values of the digits sorted in descending order:
local ordered = {}
for value, _ in pairs (values) do
if type (value) == 'number' then
ordered [#ordered + 1] = value
end
end
table.sort (ordered, function (a, b) return a > b end)
-- Collect digits into an ordered choice:
local lpeg = lpeg
local P, C, Cf = lpeg.P, lpeg.C, lpeg.Cf
local digits, tbl = P (false), {}
for _, value in ipairs (ordered) do
local digit = values [value]
if type (digit) == 'string' then
digits = digits + digit
tbl [digit] = value
end
end
return Cf ((digits / tbl) ^ 1, function (a, b) return a + b end)
end -- grammar (system, subsystem)
local m = {}
m.nonArabicGrammar = grammar
-- Export to Lua only:
function m.nonArabic (non_arabic, system, subsystem)
return grammar (system, subsystem): match (non_arabic)
end -- function m.nonArabic (non_arabic, system, subsystem)
-- Make all numeric systems available:
exportAPIs (m, toNonarabic, numeralData)
-- Перевод кириллицы в глаголицу:
local transliterationData = {
systems = {
-- Перевод кириллицы в глаголицу:
[names 'глаголицей'] = {
lua = 'glagolitic',
-- Capital:
['А'] = 'Ⰰ',
['Б'] = 'Ⰱ',
['В'] = 'Ⰲ',
['Г'] = 'Ⰳ',
['Д'] = 'Ⰴ',
['Е'] = 'Ⰵ',
['Ж'] = 'Ⰶ',
['Ѕ'] = 'Ⰷ',
['З'] = 'Ⰸ',
['І'] = 'Ⰹ',
['Ї'] = 'Ⰺ',
['И'] = 'Ⰻ',
['Й'] = 'Ⰻ',
['Ћ'] = 'Ⰼ',
['К'] = 'Ⰽ',
['Л'] = 'Ⰾ',
['М'] = 'Ⰿ',
['Н'] = 'Ⱀ',
['О'] = 'Ⱁ',
['П'] = 'Ⱂ',
['Р'] = 'Ⱃ',
['С'] = 'Ⱄ',
['Т'] = 'Ⱅ',
['Ѵ'] = 'Ⱛ',
['У'] = 'Ⱆ',
['Ꙋ'] = 'Ⱆ',
['Ѹ'] = 'Ⱆ',
['Ф'] = 'Ⱇ',
['Х'] = 'Ⱈ',
['Ѡ'] = 'Ⱉ',
['?'] = 'Ⱊ',
['Ц'] = 'Ⱌ',
['Ч'] = 'Ⱍ',
['Ш'] = 'Ⱎ',
['Щ'] = 'Ⱋ',
['Ъ'] = 'Ⱏ',
['Ы'] = 'ⰟⰊ',
['Ь'] = 'Ⱐ',
['ѣ'] = 'Ⱑ',
['Ё'] = 'Ⱖ',
['H'] = 'Ⱒ',
['Ю'] = 'Ⱓ',
['Ѧ'] = 'Ⱔ',
['Ѩ'] = 'Ⱗ',
['Ѫ'] = 'Ⱘ',
['Ѭ'] = 'Ⱙ',
['Ѳ'] = 'Ⱚ',
['Э'] = 'Ⰵ',
['Я'] = 'Ⱔ',
-- Lower:
['а'] = 'ⰰ',
['б'] = 'ⰱ',
['в'] = 'ⰲ',
['г'] = 'ⰳ',
['д'] = 'ⰴ',
['е'] = 'ⰵ',
['ж'] = 'ⰶ',
['ѕ'] = 'ⰷ',
['з'] = 'ⰸ',
['і'] = 'ⰹ',
['ї'] = 'ⰺ',
['и'] = 'ⰻ',
['й'] = 'ⰻ',
['ћ'] = 'ⰼ',
['к'] = 'ⰽ',
['л'] = 'ⰾ',
['м'] = 'ⰿ',
['н'] = 'ⱀ',
['о'] = 'ⱁ',
['п'] = 'ⱂ',
['р'] = 'ⱃ',
['с'] = 'ⱄ',
['т'] = 'ⱅ',
['ѵ'] = 'ⱛ',
['у'] = 'ⱆ',
['ꙋ'] = 'ⱆ',
['ѹ'] = 'ⱆ',
['ф'] = 'ⱇ',
['х'] = 'ⱈ',
['ѡ'] = 'ⱉ',
['?'] = 'ⱊ',
['ц'] = 'ⱌ',
['ч'] = 'ⱍ',
['ш'] = 'ⱎ',
['щ'] = 'ⱋ',
['ъ'] = 'ⱏ',
['ы'] = 'ⱏⰺ',
['ь'] = 'ⱐ',
['ѣ'] = 'ⱑ',
['ё'] = 'ⱖ',
['h'] = 'ⱒ',
['ю'] = 'ⱓ',
['ѧ'] = 'ⱔ',
['ѩ'] = 'ⱗ',
['ѫ'] = 'ⱘ',
['ѭ'] = 'ⱙ',
['ѳ'] = 'ⱚ',
['э'] = 'ⰵ',
['я'] = 'ⱔ'
} -- [names 'глаголицей']
} -- systems
-- Ошибки:
, noString = 'Передайте кириллическую строку'
} -- local transliterationData
local function implementTransliteration (from, corr)
local glagolitic, _ = gsub (from, '.', corr or {})
return glagolitic
end -- local function implementTransliteration (from, corr)
local function transliterate (alphabet, transliterations, args)
local str = table.concat (clone (args))
if not str or str == '' then
return formatNumeralError (transliterations.noString)
else
return implementTransliteration (str, alphabet)
end
end -- local function transliterate (alphabet, transliterations, args)
-- Make glagolitic available:
-- Make all transliteration systems available:
exportAPIs (m, transliterate, transliterationData)
return m