Jump to content

Module:Text: Difference between revisions

m
1 revision imported
en>Hike395
(update date)
 
m (1 revision imported)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
local yesNo = require("Module:Yesno")
local yesNo = require("Module:Yesno")
local Text = { serial = "2022-07-21",
local Text = { serial = "2024-09-21",
               suite  = "Text" }
               suite  = "Text" }
--[=[
--[=[
Text utilities
Text utilities
]=]
]=]
-- local globals
local PatternCJK        = false
local PatternCombined  = false
local PatternLatin      = false
local PatternTerminated = false
local QuoteLang        = false
local QuoteType        = false
local RangesLatin      = false
local SeekQuote        = false
local function initLatinData()
    if not RangesLatin then
        RangesLatin = { {    7,  687 },
                        { 7531, 7578 },
                        { 7680, 7935 },
                        { 8194, 8250 } }
    end
    if not PatternLatin then
        local range
        PatternLatin = "^["
        for i = 1, #RangesLatin do
            range = RangesLatin[ i ]
            PatternLatin = PatternLatin ..
                          mw.ustring.char( range[ 1 ], 45, range[ 2 ] )
        end    -- for i
        PatternLatin = PatternLatin .. "]*$"
    end
end
local function initQuoteData()
    -- Create quote definitions
    if not QuoteLang then
    QuoteLang =
            { af        = "bd",
                  ar        = "la",
                  be        = "labd",
                  bg        = "bd",
                  ca        = "la",
                  cs        = "bd",
                  da        = "bd",
                  de        = "bd",
                  dsb      = "bd",
                  et        = "bd",
                  el        = "lald",
                  en        = "ld",
                  es        = "la",
                  eu        = "la",
            --    fa        = "la",
                  fi        = "rd",
                  fr        = "laSPC",
                  ga        = "ld",
                  he        = "ldla",
                  hr        = "bd",
                  hsb      = "bd",
                  hu        = "bd",
                  hy        = "labd",
                  id        = "rd",
                  is        = "bd",
                  it        = "ld",
                  ja        = "x300C",
                  ka        = "bd",
                  ko        = "ld",
                  lt        = "bd",
                  lv        = "bd",
                  nl        = "ld",
                  nn        = "la",
                  no        = "la",
                  pl        = "bdla",
                  pt        = "lald",
                  ro        = "bdla",
                  ru        = "labd",
                  sk        = "bd",
                  sl        = "bd",
                  sq        = "la",
                  sr        = "bx",
                  sv        = "rd",
                  th        = "ld",
                  tr        = "ld",
                  uk        = "la",
                  zh        = "ld",
                  ["de-ch"] = "la",
                  ["en-gb"] = "lsld",
                  ["en-us"] = "ld",
                  ["fr-ch"] = "la",
                  ["it-ch"] = "la",
                  ["pt-br"] = "ldla",
                  ["zh-tw"] = "x300C",
                  ["zh-cn"] = "ld" }
    end
    if not QuoteType then
    QuoteType =
            { bd    = { { 8222, 8220 },  { 8218, 8217 } },
                  bdla  = { { 8222, 8220 },  {  171,  187 } },
                  bx    = { { 8222, 8221 },  { 8218, 8217 } },
                  la    = { {  171,  187 },  { 8249, 8250 } },
                  laSPC = { {  171,  187 },  { 8249, 8250 },  true },
                  labd  = { {  171,  187 },  { 8222, 8220 } },
                  lald  = { {  171,  187 },  { 8220, 8221 } },
                  ld    = { { 8220, 8221 },  { 8216, 8217 } },
                  ldla  = { { 8220, 8221 },  {  171,  187 } },
                  lsld  = { { 8216, 8217 },  { 8220, 8221 } },
                  rd    = { { 8221, 8221 },  { 8217, 8217 } },
                  x300C = { { 0x300C, 0x300D },
                            { 0x300E, 0x300F } } }
    end
end -- initQuoteData()


local function fiatQuote( apply, alien, advance )
local function fiatQuote( apply, alien, advance )
Line 127: Line 16:
     advance = tonumber(advance) or 0
     advance = tonumber(advance) or 0
     local suite
     local suite
     initQuoteData()
     local data = mw.loadData('Module:Text/data')
    local QuoteLang = data.QuoteLang
    local QuoteType = data.QuoteType
     local slang = alien:match( "^(%l+)-" )
     local slang = alien:match( "^(%l+)-" )
     suite = QuoteLang[alien] or slang and QuoteLang[slang] or QuoteLang["en"]
     suite = QuoteLang[alien] or slang and QuoteLang[slang] or QuoteLang["en"]
Line 230: Line 121:
     -- Returns: true, if CJK detected
     -- Returns: true, if CJK detected
     s = s and tostring(s) or ""
     s = s and tostring(s) or ""
     if not patternCJK then
     local patternCJK = mw.loadData('Module:Text/data').PatternCJK
        patternCJK = mw.ustring.char( 91,
                                    4352, 45,  4607,
                                  11904, 45,  42191,
                                  43072, 45,  43135,
                                  44032, 45,  55215,
                                  63744, 45,  64255,
                                  65072, 45,  65103,
                                  65381, 45,  65500,
                                      131072, 45, 196607,
                                      93 )
    end
     return mw.ustring.find( s, patternCJK ) ~= nil
     return mw.ustring.find( s, patternCJK ) ~= nil
end -- Text.containsCJK()
end -- Text.containsCJK()
Line 294: Line 174:
     -- Returns: true, if valid for latin only
     -- Returns: true, if valid for latin only
     s = s and tostring(s) or ""  --- ensure input is always string
     s = s and tostring(s) or ""  --- ensure input is always string
     initLatinData()
     local PatternLatin = mw.loadData('Module:Text/data').PatternLatin
     return mw.ustring.match(s, PatternLatin) ~= nil
     return mw.ustring.match(s, PatternLatin) ~= nil
end -- Text.isLatinRange()
end -- Text.isLatinRange()
Line 309: Line 189:
     return false
     return false
     end
     end
     if not SeekQuote then
     local SeekQuote = mw.loadData('Module:Text/data').SeekQuote
        SeekQuote = mw.ustring.char(   34,      -- "
                                      39,      -- '
                                      171,      -- laquo
                                      187,      -- raquo
                                    8216,      -- lsquo
                                    8217,      -- rsquo
                                    8218,      -- sbquo
                                    8220,      -- ldquo
                                    8221,      -- rdquo
                                    8222,      -- bdquo
                                    8249,      -- lsaquo
                                    8250,      -- rsaquo
                                    0x300C,    -- CJK
                                    0x300D,    -- CJK
                                    0x300E,    -- CJK
                                    0x300F )   -- CJK
    end
     return mw.ustring.find( SeekQuote, s, 1, true ) ~= nil
     return mw.ustring.find( SeekQuote, s, 1, true ) ~= nil
end -- Text.isQuote()
end -- Text.isQuote()
Line 398: Line 261:
     --                  or basic greek or cyrillic or symbols etc.
     --                  or basic greek or cyrillic or symbols etc.
     local cleanup, decomposed
     local cleanup, decomposed
     if not PatternCombined then
     local PatternCombined = mw.loadData('Module:Text/data').PatternCombined
        PatternCombined = mw.ustring.char( 91,
                                            0x0300, 45, 0x036F,
                                            0x1AB0, 45, 0x1AFF,
                                            0x1DC0, 45, 0x1DFF,
                                            0xFE20, 45, 0xFE2F,
                                          93 )
    end
     decomposed = mw.ustring.toNFD( adjust and tostring(adjust) or "" )
     decomposed = mw.ustring.toNFD( adjust and tostring(adjust) or "" )
     cleanup    = mw.ustring.gsub( decomposed, PatternCombined, "" )
     cleanup    = mw.ustring.gsub( decomposed, PatternCombined, "" )
Line 420: Line 276:
     -- Returns: true, if sentence terminated
     -- Returns: true, if sentence terminated
     local r
     local r
     if not PatternTerminated then
     local PatternTerminated = mw.loadData('Module:Text/data').PatternTerminated
        PatternTerminated = mw.ustring.char( 91,
                                            12290,
                                            65281,
                                            65294,
                                            65311 )
                            .. "!%.%?…][\"'%]‹›«»‘’“”]*$"
    end
     if mw.ustring.find( analyse, PatternTerminated ) then
     if mw.ustring.find( analyse, PatternTerminated ) then
         r = true
         r = true
Line 476: Line 325:
     -- Returns: string with non-latin parts enclosed in <span>
     -- Returns: string with non-latin parts enclosed in <span>
     local r
     local r
     initLatinData()
     local data = mw.loadData('Module:Text/data')
    local PatternLatin = data.PatternLatin
    local RangesLatin = data.RangesLatin
    local NumLatinRanges = data.NumLatinRanges
     if mw.ustring.match( adjust, PatternLatin ) then
     if mw.ustring.match( adjust, PatternLatin ) then
         -- latin only, horizontal dashes, quotes
         -- latin only, horizontal dashes, quotes
Line 490: Line 342:
                   -- isLatin
                   -- isLatin
                   local range
                   local range
                   for i = 1, #RangesLatin do
                  -- NumLatinRanges has to be precomputed because # does not work from loadData
                   for i = 1, NumLatinRanges do
                       range = RangesLatin[ i ]
                       range = RangesLatin[ i ]
                       if a >= range[ 1 ]  and  a <= range[ 2 ] then
                       if a >= range[ 1 ]  and  a <= range[ 2 ] then
Line 569: Line 422:
     local r
     local r
     if about == "quote" then
     if about == "quote" then
         initQuoteData()
         data = mw.loadData('Module:Text/data')
         r = { }
         r = { }
         r.QuoteLang = QuoteLang
         r.QuoteLang = data.QuoteLang
         r.QuoteType = QuoteType
         r.QuoteType = data.QuoteType
     end
     end
     return r
     return r
end -- Text.test()
end -- Text.test()


-- Non Unicode-aware version of mw.text.split and mw.text.gsplit
-- based on [[phab:diffusion/ELUA/browse/master/includes/Engines/LuaCommon/lualib/mw.text.lua]]
-- These run up to 60 times faster than the Unicode-aware versions
Text.split = function ( text, pattern, plain )
local ret = {}
for m in Text.gsplit( text, pattern, plain ) do
ret[#ret+1] = m
end
return ret
end


Text.gsplit = function ( text, pattern, plain )
local s, l = 1, string.len( text )
return function ()
if s then
local e, n = string.find( text, pattern, s, plain )
local ret
if not e then
ret = string.sub( text, s )
s = nil
elseif n < e then
-- Empty separator!
ret = string.sub( text, s, e )
if e < l then
s = e + 1
else
s = nil
end
else
ret = e > s and string.sub( text, s, e - 1 ) or ''
s = n + 1
end
return ret
end
end, nil, nil
end


-- Export
-- Export
Line 756: Line 644:
end
end


function p.split(frame)
local text = frame.args.text or frame.args[1] or ''
local pattern = frame.args.pattern or frame.args[2] or ''
local plain = yesNo(frame.args.plain or frame.args[3])
local index = tonumber(frame.args.index) or tonumber(frame.args[4]) or 1
local a = Text.split(text, pattern, plain)
if index < 0 then index = #a + index + 1 end
return a[index]
end




Line 761: Line 659:
     return Text.serial
     return Text.serial
end
end