Version 0.9.1-rc

- 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
master 0.9.1
Lothar Buchholz 4 years ago
parent bafb116bb9
commit 45099a9a3b

@ -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/), 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). 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] ## Version 0.9.0-rc - 2020-07-25 [Release Candidate]
### Added ### Added
- enable/disable from slash command - enable/disable from slash command

@ -42,9 +42,9 @@ function Grichelde:OnEnable()
self:RawHook("SendChatMessage", true) self:RawHook("SendChatMessage", true)
self.options, self.dialog = self:SetupOptions() self.options, self.dialog = self:SetupOptions()
self:RefreshOptions("OnProfileChanged")
self.ldb, self.icon = self:MinimapButton() self.ldb, self.icon = self:MinimapButton()
self:RefreshProfiles("OnEnable")
self:SetupSlashCommands() self:SetupSlashCommands()
-- tell the world we are listening -- tell the world we are listening

@ -3,7 +3,7 @@
## Title: Grichelde ## Title: Grichelde
## Notes: Replaces characters from the chat box ## Notes: Replaces characters from the chat box
## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile ## Notes-de: Ersetzt eingegebene Zeichen in der Chat-Zeile
## Version: 0.9.0-rc ## Version: 0.9.1-rc
## Author: Teilzeit-Jedi ## Author: Teilzeit-Jedi
## eMail: tj@teilzeit-jedi.de ## eMail: tj@teilzeit-jedi.de

@ -2,9 +2,9 @@
local _G = _G local _G = _G
local Grichelde = _G.Grichelde or {} 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.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 --- Splits a long text in longest possible chunks of <= 255 length, split at last available space
-- @param text string -- @param text string
@ -81,7 +81,20 @@ function Grichelde:ReplaceCharacters(text, replName, replTable, consolidate, rep
ciPattern = ciPattern .. "[" ciPattern = ciPattern .. "["
p, patRest = getNextCharUtf8(patRest) p, patRest = getNextCharUtf8(patRest)
while ((p ~= nil) and (p ~= "]")) do 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) p, patRest = getNextCharUtf8(patRest)
end end
ciPattern = ciPattern .. "]" ciPattern = ciPattern .. "]"
@ -313,6 +326,8 @@ function Grichelde:ReplaceCharacters(text, replName, replTable, consolidate, rep
findText = result findText = result
-- update values for next iteration -- update values for next iteration
pos1, pos2, cap1, cap2, cap3, cap4, cap5, cap6, cap7, cap8, cap9 = find(findText, searchText, pos) 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 end
if (text ~= result) then if (text ~= result) then
@ -442,11 +457,11 @@ function Grichelde:CheckForPreversableText(text, currentChar, previousChar, repl
local pos1, pos2 = find(text, "^" .. pattern) local pos1, pos2 = find(text, "^" .. pattern)
if (pos1 == 1) and (pos2 ~= nil) then if (pos1 == 1) and (pos2 ~= nil) then
local emote = sub(text, pos1, pos2) local emote = sub(text, pos1, pos2)
if (replaceEmotes) then if (not replaceEmotes) then
self:DebugPrint("CheckForPreversableText : Found emote \"%s\" but preserved it", emote) self:DebugPrint("CheckForPreversableText : Found emote \"%s\" at (%d, %d), but preserved it", emote, pos1, pos2)
return pos2 return pos2
else 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 end
end end

@ -2,8 +2,8 @@
local _G = _G local _G = _G
local Grichelde = _G.Grichelde or {} local Grichelde = _G.Grichelde or {}
local pairs, tInsert, tClone, unpack, join, toString local pairs, tInsert, tClone, tWipe, unpack, join, toString
= Grichelde.F.pairs, Grichelde.F.tInsert, Grichelde.F.tClone, Grichelde.F.unpack, Grichelde.F.join, Grichelde.F.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() function Grichelde.getDefaultConfig()
return { return {
@ -24,7 +24,7 @@ function Grichelde.getDefaultConfig()
}, },
replacements = { replacements = {
["**"] = { ["**"] = {
order = 9999, order = 999,
searchText = "", searchText = "",
replaceText = "", replaceText = "",
exactCase = false, exactCase = false,
@ -32,34 +32,52 @@ function Grichelde.getDefaultConfig()
matchWhen = 2, matchWhen = 2,
stopOnMatch = false, 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 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() function Grichelde:LoadDatabase()
local db = LibStub("AceDB-3.0"):New(self.name .."DB", self.getDefaultConfig(), true) local db = LibStub("AceDB-3.0"):New(self.name .."DB", self.getDefaultConfig(), true)
db.RegisterCallback(self, "OnNewProfile", "RefreshOptions") db.RegisterCallback(self, "OnNewProfile", "RefreshProfiles")
db.RegisterCallback(self, "OnProfileChanged", "RefreshOptions") db.RegisterCallback(self, "OnProfileChanged", "RefreshProfiles")
db.RegisterCallback(self, "OnProfileDeleted", "RefreshOptions") db.RegisterCallback(self, "OnProfileDeleted", "RefreshProfiles")
db.RegisterCallback(self, "OnProfileCopied", "RefreshOptions") db.RegisterCallback(self, "OnProfileCopied", "RefreshProfiles")
db.RegisterCallback(self, "OnProfileReset", "RefreshOptions") db.RegisterCallback(self, "OnProfileReset", "RefreshProfiles")
db.RegisterCallback(self, "OnProfileShutdown", "RefreshProfiles")
return db return db
end end
@ -104,15 +122,15 @@ end
--- Sorts a replacements table by order sub-field and rename. --- 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 --- Do NOT reassign self.db.profile.replacements here or with its output as it will break defaults
function Grichelde:ReorderReplacements() function Grichelde:ReorderReplacements(replacements)
local replacements = self.db.profile.replacements or {} local repls = replacements or self.db.profile.replacements or {}
self:TracePrint("ReorderReplacements : unsorted table") self:TracePrint("ReorderReplacements : unsorted table")
self:TracePrint(replacements) self:TracePrint(repls)
local orderToName = {} local orderToName = {}
local size = 0 local size = 0
for replName, replTable in pairs(replacements) do for replName, replTable in pairs(repls) do
size = size + 1 size = size + 1
tInsert(orderToName, replTable.order, replName) tInsert(orderToName, replTable.order, replName)
end end
@ -125,31 +143,19 @@ function Grichelde:ReorderReplacements()
while count < size do while count < size do
local replName = orderToName[index] 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("ReorderReplacements : replName: %s, replTable", replName)
self:TracePrint(replacements[replName]) self:TracePrint(repls[replName])
local order = Grichelde.MAPPING_OFFSET + count local order = Grichelde.MAPPING_OFFSET + count
sorted["replacement_" .. order] = tClone(replacements[replName]) sorted["replacement_" .. order] = tClone(repls[replName])
sorted["replacement_" .. order].order = order sorted["replacement_" .. order].order = order
count = count + 1 count = count + 1
end end
index = index + 1 index = index + 1
if ( index > 10000) then break end if (index > 999) then break end
end end
-- self:TracePrint("ReorderReplacements : sorted") -- self:TracePrint("ReorderReplacements : sorted")
-- self:TracePrint(sorted) -- self:TracePrint(sorted)
return 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)
end end

@ -2,6 +2,10 @@
local _G = _G local _G = _G
local Grichelde = _G.Grichelde or {} local Grichelde = _G.Grichelde or {}
local cPrefix, cGreen, cRed
= Grichelde.F.cPrefix, Grichelde.F.cGreen, Grichelde.F.cRed
--- add Minimap button --- add Minimap button
function Grichelde:MinimapButton() function Grichelde:MinimapButton()
local function clickHandler(_, button) local function clickHandler(_, button)
@ -84,26 +88,42 @@ end
function Grichelde:ToggleActivation() function Grichelde:ToggleActivation()
if (self.db.profile.enabled == true) then 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() self:Deactivate()
else 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() self:Activate()
end end
end end
function Grichelde:RefreshMinimap()
if (self.db.profile.enabled == true) then
self:Activate()
else
self:Deactivate()
end
end
function Grichelde:Activate() function Grichelde:Activate()
self.db.profile.enabled = true self.db.profile.enabled = true
-- refresh option UI if open at the moment -- refresh option UI if open at the moment
if (self.dialog ~= nil) and (self.dialog.OpenFrames[self.name] ~= nil) then 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 namePlusVersion = self:Format(self.L.AddonNamePlusVersion, self.L.AddonName, self.version)
local statusText = self:Format(self.L.AddonLoaded, namePlusVersion) local statusText = self:Format(self.L.AddonLoaded, namePlusVersion)
self.dialog.OpenFrames[self.name]:SetStatusText(statusText) self.dialog.OpenFrames[self.name]:SetStatusText(statusText)
end end
self.ldb.iconR = Grichelde.MINIMAP_ENABLED if (self.ldb ~= nil) then
self.ldb.iconG = Grichelde.MINIMAP_ENABLED self.ldb.iconR = Grichelde.MINIMAP_ENABLED
self.ldb.iconB = Grichelde.MINIMAP_ENABLED self.ldb.iconG = Grichelde.MINIMAP_ENABLED
self.ldb.iconB = Grichelde.MINIMAP_ENABLED
end
end end
function Grichelde:Deactivate() function Grichelde:Deactivate()
@ -111,14 +131,16 @@ function Grichelde:Deactivate()
-- refresh option UI if open at the moment -- refresh option UI if open at the moment
if (self.dialog ~= nil) and (self.dialog.OpenFrames[self.name] ~= nil) then 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 namePlusVersion = self:Format(self.L.AddonNamePlusVersion, self.L.AddonName, self.version)
local statusText = self:Format(self.L.AddonUnloaded, namePlusVersion) local statusText = self:Format(self.L.AddonUnloaded, namePlusVersion)
self.dialog.OpenFrames[self.name]:SetStatusText(statusText) self.dialog.OpenFrames[self.name]:SetStatusText(statusText)
end end
self.ldb.iconR = Grichelde.MINIMAP_DARKENDED if (self.ldb ~= nil) then
self.ldb.iconG = Grichelde.MINIMAP_DARKENDED self.ldb.iconR = Grichelde.MINIMAP_DARKENDED
self.ldb.iconB = Grichelde.MINIMAP_DARKENDED self.ldb.iconG = Grichelde.MINIMAP_DARKENDED
self.ldb.iconB = Grichelde.MINIMAP_DARKENDED
end
end end

@ -406,24 +406,48 @@ function Grichelde:SetupOptions()
return options, dialog return options, dialog
end end
function Grichelde:RefreshOptions(event, _, profileName) function Grichelde:RefreshProfiles(event, _, profileName)
self:DebugPrint("RefreshOptions : event:", event) 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 if (event == "OnNewProfile") then
addEmptyMappingWithoutRefresh()
self:PrefixedPrint(self.L.Profiles_Created, cGreen(self.db:GetCurrentProfile())) self:PrefixedPrint(self.L.Profiles_Created, cGreen(self.db:GetCurrentProfile()))
elseif (event == "OnProfileChanged") then 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 elseif (event == "OnProfileDeleted") then
self:PrefixedPrint(self.L.Profiles_Deleted, cRed(profileName)) self:PrefixedPrint(self.L.Profiles_Deleted, cRed(profileName))
elseif (event == "OnProfileCopied") then elseif (event == "OnProfileCopied") then
self:PrefixedPrint(self.L.Profiles_Copied, cOrange(profileName)) self:DebugPrint(self.L.Profiles_Copied, cOrange(profileName))
elseif (event == "OnProfileReset") then elseif (event == "OnProfileReset") then
addEmptyMappingWithoutRefresh()
self:PrefixedPrint(self.L.Profiles_Reset, cOrange(self.db:GetCurrentProfile())) self:PrefixedPrint(self.L.Profiles_Reset, cOrange(self.db:GetCurrentProfile()))
else else
self:DebugPrint("Refreshing Profile %s on options change: %s", self.db:GetCurrentProfile(), event) self:DebugPrint("Refreshing Profile %s on options change: %s", self.db:GetCurrentProfile(), event)
end end
self:ReorderReplacements() local repls = self:ReorderReplacements()
self:RefreshReplacements(self.db.profile.replacements) replaceReplacements(repls)
self:RefreshOptions(repls)
self:RefreshDialog()
self:RefreshMinimap()
end end
function Grichelde:ToggleOptions() function Grichelde:ToggleOptions()
@ -556,19 +580,17 @@ function Grichelde:ImportExample(num)
self.db:SetProfile(profileName) self.db:SetProfile(profileName)
assert(self.db:GetCurrentProfile() == profileName, "profile was not loaded") assert(self.db:GetCurrentProfile() == profileName, "profile was not loaded")
local exampleProfile = self.db.profile tWipe(self.db.profile.replacements)
tWipe(exampleProfile.replacements)
for replName, replTable in spairs(self.L.Options_Help_Examples[num].replacements) do for replName, replTable in spairs(self.L.Options_Help_Examples[num].replacements) do
self:TracePrint("ImportExample : replacement: %s", replName) self:TracePrint("ImportExample : replacement: %s", replName)
self:TracePrint(replTable) self:TracePrint(replTable)
if (replName ~= nil) and (replTable ~= nil) and (replTable.searchText ~= nil) then 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
end end
self:RefreshReplacements(self.db.profile.replacements) self:RefreshProfiles("ImportExample" .. num)
else else
self:ErrorPrint(self.L.Profiles_AlreadyExistsError, profileName) self:ErrorPrint(self.L.Profiles_AlreadyExistsError, profileName)
end end
@ -577,8 +599,8 @@ end
--- Create UI options for the given replacement table (from DB). --- Create UI options for the given replacement table (from DB).
--- Usually called with with self.db.profile.replacements --- Usually called with with self.db.profile.replacements
-- @param replacementsTable -- @param replacementsTable
function Grichelde:RefreshReplacements(replacementsTable) function Grichelde:RefreshOptions(replacementsTable)
self:TracePrint("RefreshReplacements : DB table:") self:TracePrint("RefreshOptions : DB table:")
self:TracePrint(replacementsTable) self:TracePrint(replacementsTable)
-- remove all previous replacements from options (not DB), except header and buttons -- 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)) replacements[replName] = self:CreateMapping(toNumber(replNumber))
end end
-- self:TracePrint("RefreshReplacements : UI options:") -- self:TracePrint("RefreshOptions : UI options:")
-- self:TracePrint(replacements) -- self:TracePrint(replacements)
end
function Grichelde:RefreshDialog()
self.dialog:ConfigTableChanged(nil, self.name) self.dialog:ConfigTableChanged(nil, self.name)
end end
@ -606,7 +630,7 @@ function Grichelde:AddEmptyMapping()
self:DebugPrint("AddEmptyMapping : old DB entries:") self:DebugPrint("AddEmptyMapping : old DB entries:")
self:DebugPrint(replacements) self:DebugPrint(replacements)
local maxRepl = Grichelde.MAPPING_OFFSET local maxRepl = Grichelde.MAPPING_OFFSET - 1
for replName, _ in pairs(replacements) do for replName, _ in pairs(replacements) do
local num = match(replName, "^replacement_(%d+)") local num = match(replName, "^replacement_(%d+)")
if (num ~= nil) and (maxRepl < toNumber(num)) then if (num ~= nil) and (maxRepl < toNumber(num)) then
@ -622,7 +646,7 @@ function Grichelde:AddEmptyMapping()
self:DebugPrint("AddEmptyMapping : new DB entries:") self:DebugPrint("AddEmptyMapping : new DB entries:")
self:DebugPrint(replacements) self:DebugPrint(replacements)
self:RefreshOptions("AddEmptyMapping " .. newMapping) self:RefreshProfiles("AddEmptyMapping " .. newMapping)
self.dialog:SelectGroup(self.name, "replacements", newMapping) self.dialog:SelectGroup(self.name, "replacements", newMapping)
end end
@ -651,7 +675,7 @@ function Grichelde:MoveUp(info)
replacements[swapName].order = currentOrder replacements[swapName].order = currentOrder
replacements[currentName].order = currentOrder - 1 replacements[currentName].order = currentOrder - 1
self:RefreshOptions("MoveUp " .. currentName) self:RefreshProfiles("MoveUp " .. currentName)
self:DebugPrint("MoveUp : refresh focus on %s", swapName) self:DebugPrint("MoveUp : refresh focus on %s", swapName)
self.dialog:SelectGroup(self.name, "replacements", swapName) self.dialog:SelectGroup(self.name, "replacements", swapName)
@ -694,7 +718,7 @@ function Grichelde:MoveDown(info)
replacements[swapName].order = currentOrder replacements[swapName].order = currentOrder
replacements[currentName].order = currentOrder + 1 replacements[currentName].order = currentOrder + 1
self:RefreshOptions("MoveDown " .. currentName) self:RefreshProfiles("MoveDown " .. currentName)
self:DebugPrint("MoveDown : refresh focus on %s", swapName) self:DebugPrint("MoveDown : refresh focus on %s", swapName)
self.dialog:SelectGroup(self.name, "replacements", swapName) self.dialog:SelectGroup(self.name, "replacements", swapName)
@ -774,7 +798,7 @@ function Grichelde:DeleteMapping(info)
self:DebugPrint("delete option: %s", currentName) self:DebugPrint("delete option: %s", currentName)
self.db.profile.replacements[currentName] = nil self.db.profile.replacements[currentName] = nil
self:RefreshOptions("DeleteMapping " .. currentName) self:RefreshProfiles("DeleteMapping " .. currentName)
local _, replNumber = self:SplitOnFirstMatch(currentName, "_") local _, replNumber = self:SplitOnFirstMatch(currentName, "_")
local newMapping = "replacement_" .. toNumber(replNumber - 1) local newMapping = "replacement_" .. toNumber(replNumber - 1)
@ -788,5 +812,5 @@ function Grichelde:DeleteAllMappings()
tWipe(self.db.profile.replacements) tWipe(self.db.profile.replacements)
self:AddEmptyMapping() self:AddEmptyMapping()
self:RefreshOptions("DeleteAllMappings") self:RefreshProfiles("DeleteAllMappings")
end end

@ -18,10 +18,10 @@ function Grichelde:TestMatch(text, pattern)
end end
function Grichelde:RunTests() function Grichelde:RunTests()
local function test(name, replacements, testData) local function test(name, replacements, testData, replaceEmotes)
local i, ok, size = 0, 0, tSize(testData) local i, ok, size = 0, 0, tSize(testData)
for input, expected in pairs(testData) do 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 i = i + 1
if (actual == expected) then if (actual == expected) then
ok = ok + 1 ok = ok + 1
@ -172,7 +172,7 @@ function Grichelde:RunTests()
["abcdz"] = "aefgz", ["abcdz"] = "aefgz",
["abcd"] = "aefg", ["abcd"] = "aefg",
["bcdz"] = "efgz", ["bcdz"] = "efgz",
-- replacement_10 -- replacement_11
["uio"] = "bnm", ["uio"] = "bnm",
["auioz"] = "auioz", ["auioz"] = "auioz",
["auio"] = "auio", ["auio"] = "auio",
@ -197,6 +197,19 @@ function Grichelde:RunTests()
["awerz"] = "asdfz", ["awerz"] = "asdfz",
["awer"] = "awer", ["awer"] = "awer",
["werz"] = "werz", ["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 ok = ok + o
@ -411,21 +424,31 @@ function Grichelde:RunTests()
all = all + a all = all + a
o, a = test( o, a = test(
"Stottern", "Stottern 1",
{ {
replacement_10 = { replacement_10 = {
order = 10, order = 10,
searchText = "^([^aeiouy]*)([aeiouy])", searchText = "^([^aeiouy]-)([aeiouy])",
replaceText = "%1%2-%1%2-%1%2", replaceText = "%1%2-%1%2-%1%2",
exactCase = false, exactCase = false,
consolidate = true, consolidate = true,
matchWhen = 4, matchWhen = 4,
stopOnMatch = false, 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.", ["Ich mag dich."] = "I-I-Ich mag dich.",
["Dich mag ich."] = "Di-Di-Dich mag ich.", ["Dich mag ich."] = "Di-Di-Dich mag ich.",
["Bmm rrpss w"] = "B-B-Bmm rrp-rrp-rrpss w-w-w",
} }
) )
ok = ok + o ok = ok + o
@ -695,7 +718,7 @@ function Grichelde:RunTests()
replacement_13 = { replacement_13 = {
order = 13, order = 13,
searchText = "youe", searchText = "youe",
replaceText = "tho", replaceText = "thou",
exactCase = false, exactCase = false,
consolidate = true, consolidate = true,
matchWhen = 3, matchWhen = 3,
@ -709,6 +732,49 @@ function Grichelde:RunTests()
ok = ok + o ok = ok + o
all = all + a 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 if (ok == all) then
self:PrefixedPrint("All %d tests %s", all, cGreen("passed")) self:PrefixedPrint("All %d tests %s", all, cGreen("passed"))
else else

@ -2,8 +2,8 @@
local _G = _G local _G = _G
local Grichelde = _G.Grichelde or {} local Grichelde = _G.Grichelde or {}
local pairs, find, cGreen, cOrange, cRed, toNumber local pairs, tSize, tClone, find, sub, cGreen, cOrange, cRed, toNumber
= Grichelde.F.pairs, Grichelde.F.find, Grichelde.F.cGreen, Grichelde.F.cOrange, Grichelde.F.cRed, Grichelde.F.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() function Grichelde:Upgrade_To_v060()
self:PrefixedPrint(self.L.Upgrade_ToVersion, cOrange("0.6.0")) self:PrefixedPrint(self.L.Upgrade_ToVersion, cOrange("0.6.0"))
@ -90,67 +90,96 @@ function Grichelde:Upgrade_To_v090()
end end
function Grichelde:UpgradeDatabase() function Grichelde:UpgradeDatabase()
local dbVersion = self.db.global.version or "0.0.0" local function parseVersion(version)
self:DebugPrint("Database version:", dbVersion) 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) if (dbVersion == nil) then
local gMajor, gMinor, gPatch = self:ParseVersion(self.version) 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 local dbMajor, dbMinor, dbPatch = parseVersion(dbVersion)
if (dbMajor > gMajor) then local downGrade = false
downGrade = true if (dbMajor > gMajor) then
elseif dbMajor == gMajor then
if (dbMinor > gMinor) then
downGrade = true downGrade = true
elseif dbMinor == gMinor then elseif dbMajor == gMajor then
if (dbPatch > gPatch) then if (dbMinor > gMinor) then
downGrade = true downGrade = true
elseif dbMinor == gMinor then
if (dbPatch > gPatch) then
downGrade = true
end
end end
end end
end
if downGrade then if downGrade then
self:PrefixedPrint(cRed(self.L.Downgrade_Detected), self.L.AddonName) self:PrefixedPrint(cRed(self.L.Downgrade_Detected), self.L.AddonName)
else else
local upgrade = 0 local upgrade = 0
local error = false local error = false
if (dbMajor == 0) then if (dbMajor == 0) then
if (dbMinor < 6) 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
upgrade = upgrade + 1 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
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 if (upgrade == 0) or (error == false) then
-- bump version number even if no update is required -- bump version number even if no update is required
self.db.global.version = self:Format("%d.%d.%d", gMajor, gMinor, gPatch) self.db.global.version = self:Format("%d.%d.%d", gMajor, gMinor, gPatch)
end end
if (upgrade == 0) then if (upgrade == 0) then
self:DebugPrint("Database up-to-date") self:DebugPrint("Database was up-to-date")
elseif (error == false) then elseif (error == false) then
self:PrefixedPrint(cGreen(self.L.Upgrade_Successful)) self:PrefixedPrint(cGreen(self.L.Upgrade_Successful))
else else
self:PrefixedPrint(cRed(self.L.Upgrade_Error)) self:PrefixedPrint(cRed(self.L.Upgrade_Error))
end
end end
end end
end end

@ -2,23 +2,8 @@
local _G = _G local _G = _G
local Grichelde = _G.Grichelde or {} local Grichelde = _G.Grichelde or {}
local type, print, pairs, tSize, select, unpack, find, sub, gsub, cGray, cDarkgray, cRed, cPrefix, format, rep, toString, toNumber 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.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 = 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
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
-- show strings differently to distinguish them from numbers -- show strings differently to distinguish them from numbers
function Grichelde:plainValue(val) function Grichelde:plainValue(val)

@ -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, 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. 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. If it still does not work or gives you errors, please read the next question.

@ -37,6 +37,8 @@ L.Error_UnsupportedChannel = "Nicht unterst\195\188tzter Kanal"
L.Profiles_Available = "Verf\195\188gbare Profile:" L.Profiles_Available = "Verf\195\188gbare Profile:"
L.Profiles_Created = "Neues Profil %s angelegt." L.Profiles_Created = "Neues Profil %s angelegt."
L.Profiles_Loaded = "Profil %s geladen." 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_Refreshed = "Profil %s aktualisiert."
L.Profiles_Deleted = "Profil %s gel\195\182scht." L.Profiles_Deleted = "Profil %s gel\195\182scht."
L.Profiles_Copied = "Einstellungen von Profil %s \195\188bernommen." L.Profiles_Copied = "Einstellungen von Profil %s \195\188bernommen."
@ -549,7 +551,7 @@ L.Options_Help_Examples = {
replacements = { replacements = {
replacement_10 = { replacement_10 = {
order = 10, order = 10,
searchText = "^([^aeiouy]*)([aeiouy])", searchText = "^([^aeiouy]-)([aeiouy])",
replaceText = "%1%2-%1%2-%1%2", replaceText = "%1%2-%1%2-%1%2",
exactCase = false, exactCase = false,
consolidate = true, consolidate = true,

@ -37,10 +37,12 @@ L.Error_UnsupportedChannel = "Unsupported channel"
L.Profiles_Available = "Available profiles:" L.Profiles_Available = "Available profiles:"
L.Profiles_Created = "New profile %s created." L.Profiles_Created = "New profile %s created."
L.Profiles_Loaded = "Profile %s is loaded." 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_Deleted = "Profile %s deleted."
L.Profiles_Copied = "Settings applied from profile %s." 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_Invalid = "Invalid profile %s!"
L.Profiles_DeleteError = "The active profile cannot be deleted!" L.Profiles_DeleteError = "The active profile cannot be deleted!"
L.Profiles_AlreadyExistsError = "The profile %s already exists!" L.Profiles_AlreadyExistsError = "The profile %s already exists!"
@ -592,7 +594,7 @@ L.Options_Help_Examples = {
replacements = { replacements = {
replacement_10 = { replacement_10 = {
order = 10, order = 10,
searchText = "^([^aeiouy]*)([aeiouy])", searchText = "^([^aeiouy]-)([aeiouy])",
replaceText = "%1%2-%1%2-%1%2", replaceText = "%1%2-%1%2-%1%2",
exactCase = false, exactCase = false,
consolidate = true, consolidate = true,

@ -19,13 +19,16 @@ Templates for various situations, now also with import possibility
Help Help
Built-in help texts 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 Beispielersetzung
Eine Texteingabe wird im "Sagen"-Kanal ersetzt. Eine Texteingabe wird im "Sagen"-Kanal ersetzt.
Zeichenersetzung Zeichenersetzung
Erzeuge bedingte Zuordnungen zwischen Such- und Ersetzungetext. Erzeuge bedingte Zuordnungen zwischen Such- und Ersetzungstext.
Kanälekonfiguration Kanälekonfiguration
einzeln pro Kanal aktivierbar einzeln pro Kanal aktivierbar

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Loading…
Cancel
Save