diff --git a/GricheldeChat.lua b/GricheldeChat.lua index cb6015c..f9bfa8f 100644 --- a/GricheldeChat.lua +++ b/GricheldeChat.lua @@ -206,6 +206,15 @@ function Grichelde:ReplaceCharacters(text, replName, replTable, consolidate, rep p, patRest = getNextCharUtf8(patRest) end ciPattern = ciPattern .. "]" + elseif (isUtf8MultiByte(p)) then + -- a set like [Ää] would match single bytes, so only group the differing last byte + local upperP, lowerP = toUpper(p), toLower(p) + local lead = sub(p, 1, -2) + if (upperP ~= lowerP) and (sub(upperP, 1, -2) == lead) and (sub(lowerP, 1, -2) == lead) then + ciPattern = ciPattern .. lead .. "[" .. sub(upperP, -1) .. sub(lowerP, -1) .. "]" + else + ciPattern = ciPattern .. p + end else ciPattern = ciPattern .. "[" .. convertToCaseInsensitivePatternGroup(p) .. "]" end @@ -428,8 +437,9 @@ function Grichelde:ReplaceCharacters(text, replName, replTable, consolidate, rep end -- update previous consolidate markers - local diff = lengthUtf8(replText) - lengthUtf8(match) - self:TracePrint("ReplaceCharacters : diff = %d - %d", lengthUtf8(replText), lengthUtf8(match)) + -- positions are byte offsets, so the difference must be counted in bytes as well + local diff = length(replText) - length(match) + self:TracePrint("ReplaceCharacters : diff = %d - %d", length(replText), length(match)) for key, posList in pairs(consolidate) do if (key ~= replName) then for i, pc in ipairs(posList) do diff --git a/GricheldeConstants.lua b/GricheldeConstants.lua index 99c2006..a127062 100644 --- a/GricheldeConstants.lua +++ b/GricheldeConstants.lua @@ -378,6 +378,24 @@ local function getUtf8Table(word) return tbl end +--- handles UTF-8 characters like äöü (except ß, ÿ, × and ÷) +local function toUpper(word) + return (Grichelde.F.gsub(_G.strupper(word), "\195([\160-\190])", function(c) + if (c ~= "\183") then + return "\195" .. Grichelde.F.bytes2Char(Grichelde.F.toByte(c) - 32) + end + end)) +end + +--- handles UTF-8 characters like äöü (except ß, ÿ, × and ÷) +local function toLower(word) + return (Grichelde.F.gsub(_G.strlower(word), "\195([\128-\158])", function(c) + if (c ~= "\151") then + return "\195" .. Grichelde.F.bytes2Char(Grichelde.F.toByte(c) + 32) + end + end)) +end + local function isLetter(word) local char = Grichelde.F.getNextCharUtf8(word) return (char ~= nil) and (Grichelde.F.toUpper(char) ~= Grichelde.F.toLower(char)) @@ -514,8 +532,8 @@ Grichelde.F = { gmatch = _G.string.gmatch, join = _G.strjoin, split = _G.strsplit, - toUpper = _G.strupper, - toLower = _G.strlower, + toUpper = toUpper, + toLower = toLower, getNextCharUtf8 = getNextCharUtf8, isUtf8MultiByte = isUtf8MultiByte, getUtf8Sequence = getUtf8Sequence, diff --git a/GricheldeTest.lua b/GricheldeTest.lua index c52aa8c..891f615 100644 --- a/GricheldeTest.lua +++ b/GricheldeTest.lua @@ -72,7 +72,7 @@ function Grichelde:RunTests() ["OSSO"] = "OCHO", ["ooSS"] = "ooCH", ["schmeissen"] = "chmeichen", - ["Schön"] = "Chön", + ["Schön"] = "Chön", } ) ok = ok + o @@ -819,8 +819,9 @@ function Grichelde:RunTests() { ["Hallä"] = "Hallae", ["Ätsch"] = "Aetsch", - ["Hällöluü"] = "Haelloelue", - ["ÜöÄ"] = "UeoeAe", + ["Hällöluü"] = "Haelloeluue", + ["ÜöÄ"] = "UeoeAE", + ["Ää"] = "Aeae", } ) ok = ok + o