diff --git a/CHANGELOG.md b/CHANGELOG.md index fa6384c..65d46a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Version 0.9.1-rc - 2020-08-01 [Release Candidate] +### Fixed +- emote detection mixed in other channels +- minimap button and dialog no longer resets active state after profile change +- default entries are no longer shown after example import +- better handling of capture groups and character sets + ## Version 0.9.0-rc - 2020-07-25 [Release Candidate] ### Added - enable/disable from slash command diff --git a/Grichelde.lua b/Grichelde.lua index c8a51ae..62bfe76 100644 --- a/Grichelde.lua +++ b/Grichelde.lua @@ -42,9 +42,9 @@ function Grichelde:OnEnable() self:RawHook("SendChatMessage", true) self.options, self.dialog = self:SetupOptions() - self:RefreshOptions("OnProfileChanged") - self.ldb, self.icon = self:MinimapButton() + + self:RefreshProfiles("OnEnable") self:SetupSlashCommands() -- tell the world we are listening diff --git a/Grichelde.toc b/Grichelde.toc index 5495054..12c4565 100644 --- a/Grichelde.toc +++ b/Grichelde.toc @@ -3,7 +3,7 @@ ## Title: Grichelde ## Notes: Replaces characters from the chat box ## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile -## Version: 0.9.0-rc +## Version: 0.9.1-rc ## Author: Teilzeit-Jedi ## eMail: tj@teilzeit-jedi.de diff --git a/GricheldeChat.lua b/GricheldeChat.lua index e06cbe2..3d4bcb9 100644 --- a/GricheldeChat.lua +++ b/GricheldeChat.lua @@ -2,9 +2,9 @@ local _G = _G local Grichelde = _G.Grichelde or {} -local IsAddOnLoaded, assert, nilOrEmpty, pairs, ipairs, spairs, tContains, tFilter, tInsert, tConcat, tSize, tIsEmpty, find, sub, gsub, gmatch, getNextCharUtf8, isUpper, isLower, toUpper, toLower, capitalize, trim, length, lengthUtf8 +local IsAddOnLoaded, assert, nilOrEmpty, pairs, ipairs, spairs, tContains, tFilter, tInsert, tConcat, tSize, tIsEmpty, find, sub, gsub, gmatch, getNextCharUtf8, isLetter, isUpper, isLower, toUpper, toLower, capitalize, trim, length, lengthUtf8 = Grichelde.F.IsAddOnLoaded, Grichelde.F.assert, Grichelde.F.nilOrEmpty, Grichelde.F.pairs, Grichelde.F.ipairs, Grichelde.F.spairs, Grichelde.F.tContains, Grichelde.F.tFilter, Grichelde.F.tInsert, Grichelde.F.tConcat, Grichelde.F.tSize, Grichelde.F.tIsEmpty, - Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.gmatch, Grichelde.F.getNextCharUtf8, Grichelde.F.isUpper, Grichelde.F.isLower, Grichelde.F.toUpper, Grichelde.F.toLower, Grichelde.F.capitalize, Grichelde.F.trim, Grichelde.F.length, Grichelde.F.lengthUtf8 + Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.gmatch, Grichelde.F.getNextCharUtf8, Grichelde.F.isLetter, Grichelde.F.isUpper, Grichelde.F.isLower, Grichelde.F.toUpper, Grichelde.F.toLower, Grichelde.F.capitalize, Grichelde.F.trim, Grichelde.F.length, Grichelde.F.lengthUtf8 --- Splits a long text in longest possible chunks of <= 255 length, split at last available space -- @param text string @@ -81,7 +81,20 @@ function Grichelde:ReplaceCharacters(text, replName, replTable, consolidate, rep ciPattern = ciPattern .. "[" p, patRest = getNextCharUtf8(patRest) while ((p ~= nil) and (p ~= "]")) do - ciPattern = ciPattern .. Grichelde.F.toUpper(p) .. Grichelde.F.toLower(p) + if (p == "%") then + -- ignore capture references + p, patRest = getNextCharUtf8(patRest) + if (p ~= nil) then + ciPattern = ciPattern .. "%" .. p + end + else + local upperP, lowerP = toUpper(p), toLower(p) + if (upperP ~= lowerP) then + ciPattern = ciPattern .. upperP .. lowerP + else + ciPattern = ciPattern .. p + end + end p, patRest = getNextCharUtf8(patRest) end ciPattern = ciPattern .. "]" @@ -313,6 +326,8 @@ function Grichelde:ReplaceCharacters(text, replName, replTable, consolidate, rep findText = result -- update values for next iteration pos1, pos2, cap1, cap2, cap3, cap4, cap5, cap6, cap7, cap8, cap9 = find(findText, searchText, pos) + self:TracePrint("ReplaceCharacters : pos1: %d, pos2: %d", pos1, pos2) + self:TracePrint("ReplaceCharacters : cap1: %s, cap2: %s, cap3: %s, cap4: %s, cap5: %s, cap6: %s, cap7: %s, cap8: %s, cap9: %s", cap1, cap2, cap3, cap4, cap5, cap6, cap7, cap8, cap9) end if (text ~= result) then @@ -442,11 +457,11 @@ function Grichelde:CheckForPreversableText(text, currentChar, previousChar, repl local pos1, pos2 = find(text, "^" .. pattern) if (pos1 == 1) and (pos2 ~= nil) then local emote = sub(text, pos1, pos2) - if (replaceEmotes) then - self:DebugPrint("CheckForPreversableText : Found emote \"%s\" but preserved it", emote) + if (not replaceEmotes) then + self:DebugPrint("CheckForPreversableText : Found emote \"%s\" at (%d, %d), but preserved it", emote, pos1, pos2) return pos2 else - self:DebugPrint("CheckForPreversableText : Found emote \"%s\" at (%d, %d)", emote, pos1, pos2) + self:DebugPrint("CheckForPreversableText : ignoring emote \"%s\" at (%d, %d)", emote, pos1, pos2) end end end diff --git a/GricheldeDatabase.lua b/GricheldeDatabase.lua index 9afc8b5..846b54b 100644 --- a/GricheldeDatabase.lua +++ b/GricheldeDatabase.lua @@ -2,8 +2,8 @@ local _G = _G local Grichelde = _G.Grichelde or {} -local pairs, tInsert, tClone, unpack, join, toString - = Grichelde.F.pairs, Grichelde.F.tInsert, Grichelde.F.tClone, Grichelde.F.unpack, Grichelde.F.join, Grichelde.F.toString +local pairs, tInsert, tClone, tWipe, unpack, join, toString + = Grichelde.F.pairs, Grichelde.F.tInsert, Grichelde.F.tClone, Grichelde.F.tWipe, Grichelde.F.unpack, Grichelde.F.join, Grichelde.F.toString function Grichelde.getDefaultConfig() return { @@ -24,7 +24,7 @@ function Grichelde.getDefaultConfig() }, replacements = { ["**"] = { - order = 9999, + order = 999, searchText = "", replaceText = "", exactCase = false, @@ -32,34 +32,52 @@ function Grichelde.getDefaultConfig() matchWhen = 2, stopOnMatch = false, }, - replacement_10 = { - order = 10, - searchText = "s", - replaceText = "ch", - }, - replacement_11 = { - order = 11, - searchText = "t", - replaceText = "ck", - }, - replacement_12 = { - order = 12, - searchText = "p", - replaceText = "b", - }, } } } end +function Grichelde.getDefaultSampleMappings() + return { + replacement_10 = { + order = 10, + searchText = "s", + replaceText = "ch", + exactCase = false, + consolidate = true, + matchWhen = 2, + stopOnMatch = false, + }, + replacement_11 = { + order = 11, + searchText = "t", + replaceText = "ck", + exactCase = false, + consolidate = true, + matchWhen = 2, + stopOnMatch = false, + }, + replacement_12 = { + order = 12, + searchText = "p", + replaceText = "b", + exactCase = false, + consolidate = true, + matchWhen = 2, + stopOnMatch = false, + } + } +end + function Grichelde:LoadDatabase() local db = LibStub("AceDB-3.0"):New(self.name .."DB", self.getDefaultConfig(), true) - db.RegisterCallback(self, "OnNewProfile", "RefreshOptions") - db.RegisterCallback(self, "OnProfileChanged", "RefreshOptions") - db.RegisterCallback(self, "OnProfileDeleted", "RefreshOptions") - db.RegisterCallback(self, "OnProfileCopied", "RefreshOptions") - db.RegisterCallback(self, "OnProfileReset", "RefreshOptions") + db.RegisterCallback(self, "OnNewProfile", "RefreshProfiles") + db.RegisterCallback(self, "OnProfileChanged", "RefreshProfiles") + db.RegisterCallback(self, "OnProfileDeleted", "RefreshProfiles") + db.RegisterCallback(self, "OnProfileCopied", "RefreshProfiles") + db.RegisterCallback(self, "OnProfileReset", "RefreshProfiles") + db.RegisterCallback(self, "OnProfileShutdown", "RefreshProfiles") return db end @@ -104,15 +122,15 @@ end --- Sorts a replacements table by order sub-field and rename. --- Do NOT reassign self.db.profile.replacements here or with its output as it will break defaults -function Grichelde:ReorderReplacements() - local replacements = self.db.profile.replacements or {} +function Grichelde:ReorderReplacements(replacements) + local repls = replacements or self.db.profile.replacements or {} self:TracePrint("ReorderReplacements : unsorted table") - self:TracePrint(replacements) + self:TracePrint(repls) local orderToName = {} local size = 0 - for replName, replTable in pairs(replacements) do + for replName, replTable in pairs(repls) do size = size + 1 tInsert(orderToName, replTable.order, replName) end @@ -125,31 +143,19 @@ function Grichelde:ReorderReplacements() while count < size do local replName = orderToName[index] - if (replName ~= nil) and (replacements[replName] ~= nil) then + if (replName ~= nil) and (repls[replName] ~= nil) then self:TracePrint("ReorderReplacements : replName: %s, replTable", replName) - self:TracePrint(replacements[replName]) + self:TracePrint(repls[replName]) local order = Grichelde.MAPPING_OFFSET + count - sorted["replacement_" .. order] = tClone(replacements[replName]) + sorted["replacement_" .. order] = tClone(repls[replName]) sorted["replacement_" .. order].order = order count = count + 1 end index = index + 1 - if ( index > 10000) then break end + if (index > 999) then break end end -- self:TracePrint("ReorderReplacements : sorted") -- self:TracePrint(sorted) - - -- do NOT set self.db.profile.replacements = {} it will break defaults - for replName, _ in pairs(replacements) do - replacements[replName] = nil - end - - -- copy over sorted replacements - for replName, replTable in pairs(sorted) do - replacements[replName] = replTable - end - - self:DebugPrint("ReorderReplacements : sorted table") - self:DebugPrint(self.db.profile.replacements) + return sorted end diff --git a/GricheldeMinimap.lua b/GricheldeMinimap.lua index 5af0ec0..51de63f 100644 --- a/GricheldeMinimap.lua +++ b/GricheldeMinimap.lua @@ -2,6 +2,10 @@ local _G = _G local Grichelde = _G.Grichelde or {} +local cPrefix, cGreen, cRed + = Grichelde.F.cPrefix, Grichelde.F.cGreen, Grichelde.F.cRed + + --- add Minimap button function Grichelde:MinimapButton() local function clickHandler(_, button) @@ -84,26 +88,42 @@ end function Grichelde:ToggleActivation() if (self.db.profile.enabled == true) then + if (self.dialog == nil) or (self.dialog.OpenFrames[self.name] == nil) then + self:PrefixedPrint(self.L.Profiles_Deactivated, cRed(self.db:GetCurrentProfile())) + end self:Deactivate() else + if (self.dialog == nil) or (self.dialog.OpenFrames[self.name] == nil) then + self:PrefixedPrint(self.L.Profiles_Activated, cGreen(self.db:GetCurrentProfile())) + end self:Activate() end end +function Grichelde:RefreshMinimap() + if (self.db.profile.enabled == true) then + self:Activate() + else + self:Deactivate() + end +end + function Grichelde:Activate() self.db.profile.enabled = true -- refresh option UI if open at the moment if (self.dialog ~= nil) and (self.dialog.OpenFrames[self.name] ~= nil) then - self.dialog:SelectGroup(self.name, "enabled") + self.dialog:SelectGroup(self.name) local namePlusVersion = self:Format(self.L.AddonNamePlusVersion, self.L.AddonName, self.version) local statusText = self:Format(self.L.AddonLoaded, namePlusVersion) self.dialog.OpenFrames[self.name]:SetStatusText(statusText) end - self.ldb.iconR = Grichelde.MINIMAP_ENABLED - self.ldb.iconG = Grichelde.MINIMAP_ENABLED - self.ldb.iconB = Grichelde.MINIMAP_ENABLED + if (self.ldb ~= nil) then + self.ldb.iconR = Grichelde.MINIMAP_ENABLED + self.ldb.iconG = Grichelde.MINIMAP_ENABLED + self.ldb.iconB = Grichelde.MINIMAP_ENABLED + end end function Grichelde:Deactivate() @@ -111,14 +131,16 @@ function Grichelde:Deactivate() -- refresh option UI if open at the moment if (self.dialog ~= nil) and (self.dialog.OpenFrames[self.name] ~= nil) then - self.dialog:SelectGroup(self.name, "enabled") + self.dialog:SelectGroup(self.name) local namePlusVersion = self:Format(self.L.AddonNamePlusVersion, self.L.AddonName, self.version) local statusText = self:Format(self.L.AddonUnloaded, namePlusVersion) self.dialog.OpenFrames[self.name]:SetStatusText(statusText) end - self.ldb.iconR = Grichelde.MINIMAP_DARKENDED - self.ldb.iconG = Grichelde.MINIMAP_DARKENDED - self.ldb.iconB = Grichelde.MINIMAP_DARKENDED + if (self.ldb ~= nil) then + self.ldb.iconR = Grichelde.MINIMAP_DARKENDED + self.ldb.iconG = Grichelde.MINIMAP_DARKENDED + self.ldb.iconB = Grichelde.MINIMAP_DARKENDED + end end diff --git a/GricheldeOptions.lua b/GricheldeOptions.lua index 09bf5ea..f16ad4f 100644 --- a/GricheldeOptions.lua +++ b/GricheldeOptions.lua @@ -406,24 +406,48 @@ function Grichelde:SetupOptions() return options, dialog end -function Grichelde:RefreshOptions(event, _, profileName) - self:DebugPrint("RefreshOptions : event:", event) +function Grichelde:RefreshProfiles(event, _, profileName) + local function replaceReplacements(replacements) + -- do NOT set self.db.profile.replacements = {} it will break defaults + tWipe(self.db.profile.replacements) + + -- copy over sorted replacements + for replName, replTable in pairs(replacements) do + self.db.profile.replacements[replName] = replTable + end + + self:DebugPrint("RefreshProfiles : reorderReplacements : sorted table") + self:DebugPrint(self.db.profile.replacements) + end + + local function addEmptyMappingWithoutRefresh() + self:DebugPrint("RefreshProfiles : addEmptyMappingWithoutRefresh") + self.db.profile.replacements.replacement_10.order = 10 + end + + self:DebugPrint("RefreshProfiles : event:", event) + --- AceDB will call OnProfileShutdown, OnProfileChanged and OnNewProfile in this order if (event == "OnNewProfile") then + addEmptyMappingWithoutRefresh() self:PrefixedPrint(self.L.Profiles_Created, cGreen(self.db:GetCurrentProfile())) elseif (event == "OnProfileChanged") then - self:PrefixedPrint(self.L.Profiles_Loaded, cGreen(self.db:GetCurrentProfile())) + self:DebugPrint(self.L.Profiles_Loaded, cGreen(self.db:GetCurrentProfile())) elseif (event == "OnProfileDeleted") then self:PrefixedPrint(self.L.Profiles_Deleted, cRed(profileName)) elseif (event == "OnProfileCopied") then - self:PrefixedPrint(self.L.Profiles_Copied, cOrange(profileName)) + self:DebugPrint(self.L.Profiles_Copied, cOrange(profileName)) elseif (event == "OnProfileReset") then + addEmptyMappingWithoutRefresh() self:PrefixedPrint(self.L.Profiles_Reset, cOrange(self.db:GetCurrentProfile())) else self:DebugPrint("Refreshing Profile %s on options change: %s", self.db:GetCurrentProfile(), event) end - self:ReorderReplacements() - self:RefreshReplacements(self.db.profile.replacements) + local repls = self:ReorderReplacements() + replaceReplacements(repls) + self:RefreshOptions(repls) + self:RefreshDialog() + self:RefreshMinimap() end function Grichelde:ToggleOptions() @@ -556,19 +580,17 @@ function Grichelde:ImportExample(num) self.db:SetProfile(profileName) assert(self.db:GetCurrentProfile() == profileName, "profile was not loaded") - local exampleProfile = self.db.profile - tWipe(exampleProfile.replacements) - + tWipe(self.db.profile.replacements) for replName, replTable in spairs(self.L.Options_Help_Examples[num].replacements) do self:TracePrint("ImportExample : replacement: %s", replName) self:TracePrint(replTable) if (replName ~= nil) and (replTable ~= nil) and (replTable.searchText ~= nil) then - exampleProfile.replacements[replName] = tClone(replTable) + self.db.profile.replacements[replName] = tClone(replTable) end end - self:RefreshReplacements(self.db.profile.replacements) + self:RefreshProfiles("ImportExample" .. num) else self:ErrorPrint(self.L.Profiles_AlreadyExistsError, profileName) end @@ -577,8 +599,8 @@ end --- Create UI options for the given replacement table (from DB). --- Usually called with with self.db.profile.replacements -- @param replacementsTable -function Grichelde:RefreshReplacements(replacementsTable) - self:TracePrint("RefreshReplacements : DB table:") +function Grichelde:RefreshOptions(replacementsTable) + self:TracePrint("RefreshOptions : DB table:") self:TracePrint(replacementsTable) -- remove all previous replacements from options (not DB), except header and buttons @@ -594,9 +616,11 @@ function Grichelde:RefreshReplacements(replacementsTable) replacements[replName] = self:CreateMapping(toNumber(replNumber)) end --- self:TracePrint("RefreshReplacements : UI options:") +-- self:TracePrint("RefreshOptions : UI options:") -- self:TracePrint(replacements) +end +function Grichelde:RefreshDialog() self.dialog:ConfigTableChanged(nil, self.name) end @@ -606,7 +630,7 @@ function Grichelde:AddEmptyMapping() self:DebugPrint("AddEmptyMapping : old DB entries:") self:DebugPrint(replacements) - local maxRepl = Grichelde.MAPPING_OFFSET + local maxRepl = Grichelde.MAPPING_OFFSET - 1 for replName, _ in pairs(replacements) do local num = match(replName, "^replacement_(%d+)") if (num ~= nil) and (maxRepl < toNumber(num)) then @@ -622,7 +646,7 @@ function Grichelde:AddEmptyMapping() self:DebugPrint("AddEmptyMapping : new DB entries:") self:DebugPrint(replacements) - self:RefreshOptions("AddEmptyMapping " .. newMapping) + self:RefreshProfiles("AddEmptyMapping " .. newMapping) self.dialog:SelectGroup(self.name, "replacements", newMapping) end @@ -651,7 +675,7 @@ function Grichelde:MoveUp(info) replacements[swapName].order = currentOrder replacements[currentName].order = currentOrder - 1 - self:RefreshOptions("MoveUp " .. currentName) + self:RefreshProfiles("MoveUp " .. currentName) self:DebugPrint("MoveUp : refresh focus on %s", swapName) self.dialog:SelectGroup(self.name, "replacements", swapName) @@ -694,7 +718,7 @@ function Grichelde:MoveDown(info) replacements[swapName].order = currentOrder replacements[currentName].order = currentOrder + 1 - self:RefreshOptions("MoveDown " .. currentName) + self:RefreshProfiles("MoveDown " .. currentName) self:DebugPrint("MoveDown : refresh focus on %s", swapName) self.dialog:SelectGroup(self.name, "replacements", swapName) @@ -774,7 +798,7 @@ function Grichelde:DeleteMapping(info) self:DebugPrint("delete option: %s", currentName) self.db.profile.replacements[currentName] = nil - self:RefreshOptions("DeleteMapping " .. currentName) + self:RefreshProfiles("DeleteMapping " .. currentName) local _, replNumber = self:SplitOnFirstMatch(currentName, "_") local newMapping = "replacement_" .. toNumber(replNumber - 1) @@ -788,5 +812,5 @@ function Grichelde:DeleteAllMappings() tWipe(self.db.profile.replacements) self:AddEmptyMapping() - self:RefreshOptions("DeleteAllMappings") + self:RefreshProfiles("DeleteAllMappings") end diff --git a/GricheldeTest.lua b/GricheldeTest.lua index f922b66..67c05c9 100644 --- a/GricheldeTest.lua +++ b/GricheldeTest.lua @@ -18,10 +18,10 @@ function Grichelde:TestMatch(text, pattern) end function Grichelde:RunTests() - local function test(name, replacements, testData) + local function test(name, replacements, testData, replaceEmotes) local i, ok, size = 0, 0, tSize(testData) for input, expected in pairs(testData) do - local actual = self:ReplaceText(input, replacements, false) + local actual = self:ReplaceText(input, replacements, replaceEmotes or false) i = i + 1 if (actual == expected) then ok = ok + 1 @@ -172,7 +172,7 @@ function Grichelde:RunTests() ["abcdz"] = "aefgz", ["abcd"] = "aefg", ["bcdz"] = "efgz", - -- replacement_10 + -- replacement_11 ["uio"] = "bnm", ["auioz"] = "auioz", ["auio"] = "auio", @@ -197,6 +197,19 @@ function Grichelde:RunTests() ["awerz"] = "asdfz", ["awer"] = "awer", ["werz"] = "werz", + + -- replacement_10 + ["bcd abcdz abcd bcdz"] = "efg aefgz aefg efgz", + -- replacement_11 + ["uio auioz auio uioz"] = "bnm auioz auio uioz", + -- replacement_12 + ["hij ahijz ahij hijz"] = "klm ahijz ahij klmz", + -- replacement_13 + ["nop anopz anop nopz"] = "qrs anopz aqrs nopz", + -- replacement_14 + ["tuv atuvz atuv tuvz"] = "wxy atuvz awxy wxyz", + -- replacement_15 + ["wer awerz awer werz"] = "wer asdfz awer werz", } ) ok = ok + o @@ -411,21 +424,31 @@ function Grichelde:RunTests() all = all + a o, a = test( - "Stottern", + "Stottern 1", { replacement_10 = { order = 10, - searchText = "^([^aeiouy]*)([aeiouy])", + searchText = "^([^aeiouy]-)([aeiouy])", replaceText = "%1%2-%1%2-%1%2", exactCase = false, consolidate = true, matchWhen = 4, stopOnMatch = false, }, + replacement_11 = { + order = 11, + searchText = "([^bwp%s]-)([bwp])", + replaceText = "%1%2-%1%2-%1%2", + exactCase = false, + consolidate = true, + matchWhen = 2, + stopOnMatch = false, + }, }, { ["Ich mag dich."] = "I-I-Ich mag dich.", ["Dich mag ich."] = "Di-Di-Dich mag ich.", + ["Bmm rrpss w"] = "B-B-Bmm rrp-rrp-rrpss w-w-w", } ) ok = ok + o @@ -695,7 +718,7 @@ function Grichelde:RunTests() replacement_13 = { order = 13, searchText = "youe", - replaceText = "tho", + replaceText = "thou", exactCase = false, consolidate = true, matchWhen = 3, @@ -709,6 +732,49 @@ function Grichelde:RunTests() ok = ok + o all = all + a + o, a = test( + "emote detection on", + { + replacement_10 = { + order = 10, + searchText = "r", + replaceText = "rr", + exactCase = false, + consolidate = false, + matchWhen = 2, + stopOnMatch = false, + }, + }, + { + ["Der Herr Richter *schaut Herrn Richter an*"] = "Derr Herrrr Rrichterr *schaut Herrn Richter an*", + ["*schaut Herrn Richter an*"] = "*schaut Herrn Richter an*", + } + ) + ok = ok + o + all = all + a + + o, a = test( + "emote detection ignored", + { + replacement_10 = { + order = 10, + searchText = "r", + replaceText = "rr", + exactCase = false, + consolidate = false, + matchWhen = 2, + stopOnMatch = false, + }, + }, + { + ["Der Herr Richter *schaut Herrn Richter an*"] = "Derr Herrrr Rrichterr *schaut Herrrrn Rrichterr an*", + ["*schaut Herrn Richter an*"] = "*schaut Herrrrn Rrichterr an*", + }, + true + ) + ok = ok + o + all = all + a + if (ok == all) then self:PrefixedPrint("All %d tests %s", all, cGreen("passed")) else diff --git a/GricheldeUpgrade.lua b/GricheldeUpgrade.lua index 8b918f4..43676ef 100644 --- a/GricheldeUpgrade.lua +++ b/GricheldeUpgrade.lua @@ -2,8 +2,8 @@ local _G = _G local Grichelde = _G.Grichelde or {} -local pairs, find, cGreen, cOrange, cRed, toNumber - = Grichelde.F.pairs, Grichelde.F.find, Grichelde.F.cGreen, Grichelde.F.cOrange, Grichelde.F.cRed, Grichelde.F.toNumber +local pairs, tSize, tClone, find, sub, cGreen, cOrange, cRed, toNumber + = Grichelde.F.pairs, Grichelde.F.tSize,Grichelde.F.tClone, Grichelde.F.find, Grichelde.F.sub, Grichelde.F.cGreen, Grichelde.F.cOrange, Grichelde.F.cRed, Grichelde.F.toNumber function Grichelde:Upgrade_To_v060() self:PrefixedPrint(self.L.Upgrade_ToVersion, cOrange("0.6.0")) @@ -90,67 +90,96 @@ function Grichelde:Upgrade_To_v090() end function Grichelde:UpgradeDatabase() - local dbVersion = self.db.global.version or "0.0.0" - self:DebugPrint("Database version:", dbVersion) + local function parseVersion(version) + local _, _, major, minor, patch, ext = find(version, "(%d+)%.(%d+)%.(%d+)(.*)") + local preBuild, build = ext, "" + if (sub(ext, 1, 1) == "-") then + local b = find(ext, "+", 2) + if (b ~= nil) then + preBuild = sub(ext, 1, b) + build = sub(ext, b + 1) + else + preBuild = sub(ext, 1, b) + end + end + return toNumber(major) or 0, toNumber(minor) or 0, toNumber(patch) or 0, preBuild, build + end + + local gMajor, gMinor, gPatch = parseVersion(self.version) + local dbVersion = self.db.global.version - local dbMajor, dbMinor, dbPatch = self:ParseVersion(dbVersion) - local gMajor, gMinor, gPatch = self:ParseVersion(self.version) + if (dbVersion == nil) then + self:DebugPrint("New installation detected, add sample mappings") + -- do NOT set self.db.profile.replacements = {} it will break defaults + local sampleRepl = self.getDefaultSampleMappings() + for replName, replTable in pairs(sampleRepl) do + self:TracePrint("UpgradeDatabase : copySampleMappings %s", replName) + self.db.profile.replacements[replName] = tClone(replTable) + end + + self.db.global.version = self:Format("%d.%d.%d", gMajor, gMinor, gPatch) + self:DebugPrint("Database version %s sucessfully created", self.db.global.version) + else + -- detect if upgrade is neccessary or downgrade was done + self:DebugPrint("Detected database version:", dbVersion) - local downGrade = false - if (dbMajor > gMajor) then - downGrade = true - elseif dbMajor == gMajor then - if (dbMinor > gMinor) then + local dbMajor, dbMinor, dbPatch = parseVersion(dbVersion) + local downGrade = false + if (dbMajor > gMajor) then downGrade = true - elseif dbMinor == gMinor then - if (dbPatch > gPatch) then + elseif dbMajor == gMajor then + if (dbMinor > gMinor) then downGrade = true + elseif dbMinor == gMinor then + if (dbPatch > gPatch) then + downGrade = true + end end end - end - if downGrade then - self:PrefixedPrint(cRed(self.L.Downgrade_Detected), self.L.AddonName) - else - local upgrade = 0 - local error = false + if downGrade then + self:PrefixedPrint(cRed(self.L.Downgrade_Detected), self.L.AddonName) + else + local upgrade = 0 + local error = false - if (dbMajor == 0) then - if (dbMinor < 6) then - upgrade = upgrade + 1 - dbMajor, dbMinor, dbPatch = self:Upgrade_To_v060(dbVersion) - end - if (dbMinor < 7) then - upgrade = upgrade + 1 - dbMajor, dbMinor, dbPatch = self:Upgrade_To_v070(dbVersion) - end - if (dbMinor == 7) then - if (dbPatch < 2) then + if (dbMajor == 0) then + if (dbMinor < 6) then upgrade = upgrade + 1 - dbMajor, dbMinor, dbPatch = self:Upgrade_To_v072(dbVersion) + dbMajor, dbMinor, dbPatch = self:Upgrade_To_v060(dbVersion) + end + if (dbMinor < 7) then + upgrade = upgrade + 1 + dbMajor, dbMinor, dbPatch = self:Upgrade_To_v070(dbVersion) + end + if (dbMinor == 7) then + if (dbPatch < 2) then + upgrade = upgrade + 1 + dbMajor, dbMinor, dbPatch = self:Upgrade_To_v072(dbVersion) + end + end + if (dbMinor < 8) then + upgrade = upgrade + 1 + dbMajor, dbMinor, dbPatch = self:Upgrade_To_v080(dbVersion) + end + if (dbMinor < 9) then + upgrade = upgrade + 1 + dbMajor, dbMinor, dbPatch = self:Upgrade_To_v090(dbVersion) end end - if (dbMinor < 8) then - upgrade = upgrade + 1 - dbMajor, dbMinor, dbPatch = self:Upgrade_To_v080(dbVersion) - end - if (dbMinor < 9) then - upgrade = upgrade + 1 - dbMajor, dbMinor, dbPatch = self:Upgrade_To_v090(dbVersion) - end - end - if (upgrade == 0) or (error == false) then - -- bump version number even if no update is required - self.db.global.version = self:Format("%d.%d.%d", gMajor, gMinor, gPatch) - end + if (upgrade == 0) or (error == false) then + -- bump version number even if no update is required + self.db.global.version = self:Format("%d.%d.%d", gMajor, gMinor, gPatch) + end - if (upgrade == 0) then - self:DebugPrint("Database up-to-date") - elseif (error == false) then - self:PrefixedPrint(cGreen(self.L.Upgrade_Successful)) - else - self:PrefixedPrint(cRed(self.L.Upgrade_Error)) + if (upgrade == 0) then + self:DebugPrint("Database was up-to-date") + elseif (error == false) then + self:PrefixedPrint(cGreen(self.L.Upgrade_Successful)) + else + self:PrefixedPrint(cRed(self.L.Upgrade_Error)) + end end end end \ No newline at end of file diff --git a/GricheldeUtils.lua b/GricheldeUtils.lua index 4c001fd..472a987 100644 --- a/GricheldeUtils.lua +++ b/GricheldeUtils.lua @@ -2,23 +2,8 @@ local _G = _G local Grichelde = _G.Grichelde or {} -local type, print, pairs, tSize, select, unpack, find, sub, gsub, cGray, cDarkgray, cRed, cPrefix, format, rep, toString, toNumber - = Grichelde.F.type, Grichelde.F.print, Grichelde.F.pairs, Grichelde.F.tSize, Grichelde.F.select, Grichelde.F.unpack, Grichelde.F.find, Grichelde.F.sub, Grichelde.F.gsub, Grichelde.F.cGray, Grichelde.F.cDarkgray, Grichelde.F.cRed, Grichelde.F.cPrefix, Grichelde.F.format, Grichelde.F.rep, Grichelde.F.toString, Grichelde.F.toNumber - -function Grichelde:ParseVersion(version) - local _, _, major, minor, patch, ext = find(version, "(%d+)%.(%d+)%.(%d+)(.*)") - local preBuild, build = ext, "" - if (sub(ext, 1, 1) == "-") then - local b = find(ext, "+", 2) - if (b ~= nil) then - preBuild = sub(ext, 1, b) - build = sub(ext, b + 1) - else - preBuild = sub(ext, 1, b) - end - end - return toNumber(major) or 0, toNumber(minor) or 0, toNumber(patch) or 0, preBuild, build -end +local type, print, pairs, tSize, select, unpack, find, cGray, cDarkgray, cRed, cPrefix, format, rep, toString + = Grichelde.F.type, Grichelde.F.print, Grichelde.F.pairs, Grichelde.F.tSize, Grichelde.F.select, Grichelde.F.unpack, Grichelde.F.find, Grichelde.F.cGray, Grichelde.F.cDarkgray, Grichelde.F.cRed, Grichelde.F.cPrefix, Grichelde.F.format, Grichelde.F.rep, Grichelde.F.toString -- show strings differently to distinguish them from numbers function Grichelde:plainValue(val) diff --git a/README.md b/README.md index 817217f..2e662bb 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,9 @@ Only slash commands, item links, textures, placeholders and ooc-markers are excl After entering a search or replacement text, you see a button "Okay" next to your input. This is **not** a validation message, but the save button for text. This is a restriction from the UI library and can be seen in other addons as well. -Please click on "Okay" to save the input permanently. +Please click on "Okay" to save the input permanently, otherwise it will not be stored.. + +![click "Okay" on text changes](https://media.forgecdn.net/attachments/305/887/text-okay.jpg "change confirmation") If it still does not work or gives you errors, please read the next question. diff --git a/localisation/deDE.lua b/localisation/deDE.lua index 28bed52..bbf71ea 100644 --- a/localisation/deDE.lua +++ b/localisation/deDE.lua @@ -37,6 +37,8 @@ L.Error_UnsupportedChannel = "Nicht unterst\195\188tzter Kanal" L.Profiles_Available = "Verf\195\188gbare Profile:" L.Profiles_Created = "Neues Profil %s angelegt." L.Profiles_Loaded = "Profil %s geladen." +L.Profiles_Activated = "Profil %s aktiviert." +L.Profiles_Deactivated = "Profil %s deaktiviert." L.Profiles_Refreshed = "Profil %s aktualisiert." L.Profiles_Deleted = "Profil %s gel\195\182scht." L.Profiles_Copied = "Einstellungen von Profil %s \195\188bernommen." @@ -549,7 +551,7 @@ L.Options_Help_Examples = { replacements = { replacement_10 = { order = 10, - searchText = "^([^aeiouy]*)([aeiouy])", + searchText = "^([^aeiouy]-)([aeiouy])", replaceText = "%1%2-%1%2-%1%2", exactCase = false, consolidate = true, diff --git a/localisation/enUS.lua b/localisation/enUS.lua index 8f96f9a..a899319 100644 --- a/localisation/enUS.lua +++ b/localisation/enUS.lua @@ -37,10 +37,12 @@ L.Error_UnsupportedChannel = "Unsupported channel" L.Profiles_Available = "Available profiles:" L.Profiles_Created = "New profile %s created." L.Profiles_Loaded = "Profile %s is loaded." -L.Profiles_Refreshed = "Profil %s refreshed." +L.Profiles_Activated = "Profile %s activated." +L.Profiles_Deactivated = "Profile %s deactivated." +L.Profiles_Refreshed = "Profile %s refreshed." L.Profiles_Deleted = "Profile %s deleted." L.Profiles_Copied = "Settings applied from profile %s." -L.Profiles_Reset = "Profil %s reset." +L.Profiles_Reset = "Profile %s reset." L.Profiles_Invalid = "Invalid profile %s!" L.Profiles_DeleteError = "The active profile cannot be deleted!" L.Profiles_AlreadyExistsError = "The profile %s already exists!" @@ -592,7 +594,7 @@ L.Options_Help_Examples = { replacements = { replacement_10 = { order = 10, - searchText = "^([^aeiouy]*)([aeiouy])", + searchText = "^([^aeiouy]-)([aeiouy])", replaceText = "%1%2-%1%2-%1%2", exactCase = false, consolidate = true, diff --git a/twitch/image-descriptions.txt b/twitch/image-descriptions.txt index 812cdb4..db612cd 100644 --- a/twitch/image-descriptions.txt +++ b/twitch/image-descriptions.txt @@ -19,13 +19,16 @@ Templates for various situations, now also with import possibility Help Built-in help texts +Confirm text changes +When you enter a search or replacement text, please confirm your input with the Okay button. Otherwise its not saved. + Beispielersetzung Eine Texteingabe wird im "Sagen"-Kanal ersetzt. Zeichenersetzung -Erzeuge bedingte Zuordnungen zwischen Such- und Ersetzungetext. +Erzeuge bedingte Zuordnungen zwischen Such- und Ersetzungstext. Kanälekonfiguration einzeln pro Kanal aktivierbar diff --git a/twitch/replacements2-de.jpg b/twitch/replacements2-de.jpg index 21bfd44..2cf30f8 100644 Binary files a/twitch/replacements2-de.jpg and b/twitch/replacements2-de.jpg differ diff --git a/twitch/replacements2-en.jpg b/twitch/replacements2-en.jpg index 60d1450..4c45318 100644 Binary files a/twitch/replacements2-en.jpg and b/twitch/replacements2-en.jpg differ diff --git a/twitch/text-okay.jpg b/twitch/text-okay.jpg new file mode 100644 index 0000000..a63a55c Binary files /dev/null and b/twitch/text-okay.jpg differ