544 lines
13 KiB
TOML
544 lines
13 KiB
TOML
# Global variables - available to all commands
|
|
[variables]
|
|
foobar = 4
|
|
multiply = 1.5
|
|
prefix = 'NEW_'
|
|
enabled = true
|
|
|
|
# Multi-regex example using variable in Lua
|
|
[[commands]]
|
|
name = 'RFToolsMultiply'
|
|
regexes = [
|
|
'generatePerTick = !num',
|
|
'ticksPer\w+ = !num',
|
|
'generatorRFPerTick = !num',
|
|
]
|
|
lua = '* foobar'
|
|
files = [
|
|
'polymc/instances/**/rftools*.toml',
|
|
'polymc\instances\**\rftools*.toml',
|
|
]
|
|
reset = true
|
|
|
|
# Named capture groups with arithmetic and string ops
|
|
[[commands]]
|
|
name = 'UpdateAmountsAndItems'
|
|
regex = '(?P<amount>!num)\s+units\s+of\s+(?P<item>[A-Za-z_\-]+)'
|
|
lua = 'amount = amount * multiply; item = upper(item); return true'
|
|
files = ['data/**/*.txt']
|
|
|
|
# Full replacement via Lua 'replacement' variable
|
|
[[commands]]
|
|
name = 'BumpMinorVersion'
|
|
regex = 'version\s*=\s*"(?P<major>!num)\.(?P<minor>!num)\.(?P<patch>!num)"'
|
|
lua = 'replacement = format("version=\"%s.%s.%s\"", major, num(minor)+1, 0); return true'
|
|
files = ['config/*.ini', 'config/*.cfg']
|
|
|
|
# TOML multiline regex example - single quotes make regex natural!
|
|
[[commands]]
|
|
name = 'StressValues'
|
|
regex = '''
|
|
\[kinetics\.stressValues\.v2\.capacity\]
|
|
steam_engine = !num
|
|
water_wheel = !num
|
|
copper_valve_handle = !num
|
|
hand_crank = !num
|
|
creative_motor = !num'''
|
|
lua = 'v1 * multiply'
|
|
files = ['*.txt']
|
|
isolate = true
|
|
|
|
# Network configuration with complex multiline regex
|
|
[[commands]]
|
|
name = 'NetworkConfig'
|
|
regex = '''
|
|
networking\.firewall\.allowPing = true
|
|
networking\.firewall\.allowedTCPPorts = \[ 47984 47989 47990 \]
|
|
networking\.firewall\.allowedUDPPortRanges = \[
|
|
\{ from = \d+; to = \d+; \}
|
|
\{ from = 8000; to = 8010; \}
|
|
\]'''
|
|
lua = "replacement = string.gsub(block[1], 'true', 'false')"
|
|
files = ['*.conf']
|
|
isolate = true
|
|
|
|
# Simple regex with single quotes - no escaping needed!
|
|
[[commands]]
|
|
name = 'EnableFlags'
|
|
regex = 'enabled\s*=\s*(true|false)'
|
|
lua = '= enabled'
|
|
files = ['**/*.toml']
|
|
|
|
# Demonstrate NoDedup to allow overlapping replacements
|
|
[[commands]]
|
|
name = 'OverlappingGroups'
|
|
regex = '(?P<a>!num)(?P<b>!num)'
|
|
lua = 'a = num(a) + 1; b = num(b) + 1; return true'
|
|
files = ['overlap/**/*.txt']
|
|
nodedup = true
|
|
|
|
# Isolate command example operating on entire matched block
|
|
[[commands]]
|
|
name = 'IsolateUppercaseBlock'
|
|
regex = '''BEGIN
|
|
(?P<block>!any)
|
|
END'''
|
|
lua = 'block = upper(block); return true'
|
|
files = ['logs/**/*.log']
|
|
loglevel = 'TRACE'
|
|
isolate = true
|
|
|
|
# Using !rep placeholder and arrays of files
|
|
[[commands]]
|
|
name = 'RepeatPlaceholderExample'
|
|
regex = 'name: (.*) !rep(, .* , 2)'
|
|
lua = '-- no-op, just demonstrate placeholder; return false'
|
|
files = ['lists/**/*.yml', 'lists/**/*.yaml']
|
|
|
|
# Using string variable in Lua expression
|
|
[[commands]]
|
|
name = 'PrefixKeys'
|
|
regex = '(?P<key>[A-Za-z0-9_]+)\s*='
|
|
lua = 'key = prefix .. key; return true'
|
|
files = ['**/*.properties']
|
|
|
|
# HTTP fetch example - get version from API and update config
|
|
[[commands]]
|
|
name = 'UpdateVersionFromAPI'
|
|
regex = 'version\s*=\s*"(?P<version>[^"]+)"'
|
|
lua = '''
|
|
local response = fetch("https://api.example.com/version", {
|
|
method = "GET",
|
|
headers = { ["Accept"] = "application/json" }
|
|
})
|
|
if response and response.body then
|
|
local data = fromJSON(response.body)
|
|
if data.latest then
|
|
version = data.latest
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
'''
|
|
files = ['version.conf']
|
|
|
|
# Complex multiline block replacement with state machine
|
|
[[commands]]
|
|
name = 'ModifyConfigBlock'
|
|
regex = '''(?x)
|
|
\[server\]
|
|
\s+host\s*=\s*"(?P<host>[^"]+)"
|
|
\s+port\s*=\s*(?P<port>\d+)
|
|
\s+ssl\s*=\s*(?P<ssl>true|false)'''
|
|
lua = '''
|
|
port = num(port) + 1000
|
|
ssl = "true"
|
|
replacement = format('[server]\n host = "%s"\n port = %d\n ssl = %s', host, port, ssl)
|
|
return true
|
|
'''
|
|
files = ['server.conf']
|
|
|
|
# Regex with !any to capture entire sections
|
|
[[commands]]
|
|
name = 'WrapInComment'
|
|
regex = 'FEATURE_START\n(?P<feature>!any)\nFEATURE_END'
|
|
lua = '''
|
|
replacement = "FEATURE_START\n# " .. feature:gsub("\n", "\n# ") .. "\nFEATURE_END"
|
|
return true
|
|
'''
|
|
files = ['features/**/*.txt']
|
|
|
|
# Advanced capture groups with complex logic
|
|
[[commands]]
|
|
name = 'UpdateDependencies'
|
|
regex = 'dependency\("(?P<group>[^"]+)", "(?P<name>[^"]+)", "(?P<version>[^"]+)"\)'
|
|
lua = '''
|
|
local major, minor, patch = version:match("(%d+)%.(%d+)%.(%d+)")
|
|
if major and minor and patch then
|
|
-- Bump minor version
|
|
minor = num(minor) + 1
|
|
version = format("%s.%s.0", major, minor)
|
|
return true
|
|
end
|
|
return false
|
|
'''
|
|
files = ['build.gradle', 'build.gradle.kts']
|
|
|
|
# JSON mode examples - modify single field
|
|
[[commands]]
|
|
name = 'JSONModifyField'
|
|
json = true
|
|
lua = '''
|
|
data.value = 84
|
|
modified = true
|
|
'''
|
|
files = ['data/**/*.json']
|
|
|
|
# JSON mode - add new field
|
|
[[commands]]
|
|
name = 'JSONAddField'
|
|
json = true
|
|
lua = '''
|
|
data.newField = "added"
|
|
modified = true
|
|
'''
|
|
files = ['config/**/*.json']
|
|
|
|
# JSON mode - modify nested fields
|
|
[[commands]]
|
|
name = 'JSONNestedModify'
|
|
json = true
|
|
lua = '''
|
|
if data.config and data.config.settings then
|
|
data.config.settings.enabled = true
|
|
data.config.settings.timeout = 60
|
|
modified = true
|
|
end
|
|
'''
|
|
files = ['settings/**/*.json']
|
|
|
|
# JSON mode - modify array elements
|
|
[[commands]]
|
|
name = 'JSONArrayMultiply'
|
|
json = true
|
|
lua = '''
|
|
if data.items then
|
|
for i, item in ipairs(data.items) do
|
|
data.items[i].value = item.value * multiply
|
|
end
|
|
modified = true
|
|
end
|
|
'''
|
|
files = ['data/**/*.json']
|
|
|
|
# JSON mode - modify object version
|
|
[[commands]]
|
|
name = 'JSONObjectUpdate'
|
|
json = true
|
|
lua = '''
|
|
data.version = "2.0.0"
|
|
data.enabled = enabled
|
|
modified = true
|
|
'''
|
|
files = ['config/**/*.json']
|
|
|
|
# JSON mode - surgical editing of specific row
|
|
[[commands]]
|
|
name = 'JSONSurgicalEdit'
|
|
json = true
|
|
lua = '''
|
|
if data.Rows and data.Rows[1] then
|
|
data.Rows[1].Weight = 999
|
|
modified = true
|
|
end
|
|
'''
|
|
files = ['items/**/*.json']
|
|
|
|
# JSON mode - remove array elements conditionally
|
|
[[commands]]
|
|
name = 'JSONRemoveDisabled'
|
|
json = true
|
|
lua = '''
|
|
if data.features then
|
|
local i = 1
|
|
while i <= #data.features do
|
|
if data.features[i].enabled == false then
|
|
table.remove(data.features, i)
|
|
else
|
|
i = i + 1
|
|
end
|
|
end
|
|
modified = true
|
|
end
|
|
'''
|
|
files = ['config/**/*.json']
|
|
|
|
# JSON mode - deep nested object manipulation
|
|
[[commands]]
|
|
name = 'JSONDeepUpdate'
|
|
json = true
|
|
lua = '''
|
|
if data.game and data.game.balance and data.game.balance.economy then
|
|
local econ = data.game.balance.economy
|
|
econ.inflation = (econ.inflation or 1.0) * 1.05
|
|
econ.taxRate = 0.15
|
|
econ.lastUpdate = os.date("%Y-%m-%d")
|
|
modified = true
|
|
end
|
|
'''
|
|
files = ['settings/**/*.json']
|
|
|
|
# JSON mode - iterate and transform all matching objects
|
|
[[commands]]
|
|
name = 'JSONTransformItems'
|
|
json = true
|
|
lua = '''
|
|
local function processItem(item)
|
|
if item.type == "weapon" and item.damage then
|
|
item.damage = item.damage * multiply
|
|
item.modified = true
|
|
end
|
|
end
|
|
|
|
if data.items then
|
|
for _, item in ipairs(data.items) do
|
|
processItem(item)
|
|
end
|
|
modified = true
|
|
elseif data.inventory then
|
|
for _, item in ipairs(data.inventory) do
|
|
processItem(item)
|
|
end
|
|
modified = true
|
|
end
|
|
'''
|
|
files = ['data/**/*.json']
|
|
|
|
# CSV processing example - read, modify, write
|
|
[[commands]]
|
|
name = 'CSVProcess'
|
|
regex = '(?P<csv>!any)'
|
|
lua = '''
|
|
local rows = fromCSV(csv, { hasheader = true })
|
|
for i, row in ipairs(rows) do
|
|
if row.Value then
|
|
row.Value = num(row.Value) * multiply
|
|
end
|
|
end
|
|
replacement = toCSV(rows, { hasheader = true })
|
|
return true
|
|
'''
|
|
files = ['data/**/*.csv']
|
|
|
|
# CSV processing with custom delimiter (TSV)
|
|
[[commands]]
|
|
name = 'TSVProcess'
|
|
regex = '(?P<tsv>!any)'
|
|
lua = '''
|
|
local rows = fromCSV(tsv, { delimiter = "\t", hasheader = true, hascomments = true })
|
|
for i, row in ipairs(rows) do
|
|
if row.Price then
|
|
row.Price = num(row.Price) * 1.1
|
|
end
|
|
end
|
|
replacement = toCSV(rows, { delimiter = "\t", hasheader = true })
|
|
return true
|
|
'''
|
|
files = ['data/**/*.tsv']
|
|
|
|
# CSV processing - modify specific columns
|
|
[[commands]]
|
|
name = 'CSVModifyColumns'
|
|
regex = '(?P<csv>!any)'
|
|
lua = '''
|
|
local rows = fromCSV(csv, { hasheader = true })
|
|
for i, row in ipairs(rows) do
|
|
if row.Name then
|
|
row.Name = prefix .. row.Name
|
|
end
|
|
if row.Status then
|
|
row.Status = upper(row.Status)
|
|
end
|
|
end
|
|
replacement = toCSV(rows, { hasheader = true })
|
|
return true
|
|
'''
|
|
files = ['exports/**/*.csv']
|
|
|
|
# XML mode - multiply numeric attributes using helper functions
|
|
[[commands]]
|
|
name = 'XMLMultiplyAttributes'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
visitElements(data, function(elem)
|
|
if elem._tag == "Item" then
|
|
modifyNumAttr(elem, "Weight", function(val) return val * multiply end)
|
|
modifyNumAttr(elem, "Value", function(val) return val * foobar end)
|
|
end
|
|
end)
|
|
modified = true
|
|
'''
|
|
files = ['game/**/*.xml']
|
|
|
|
# XML mode - modify specific element attributes
|
|
[[commands]]
|
|
name = 'XMLUpdateAfflictions'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
local afflictions = findElements(data, "Affliction")
|
|
for _, affliction in ipairs(afflictions) do
|
|
local id = getAttr(affliction, "identifier")
|
|
if id == "burn" or id == "bleeding" then
|
|
modifyNumAttr(affliction, "strength", function(val) return val * 0.5 end)
|
|
setAttr(affliction, "description", "Weakened effect")
|
|
end
|
|
end
|
|
modified = true
|
|
'''
|
|
files = ['config/Afflictions.xml']
|
|
|
|
# XML mode - add new elements using helpers
|
|
[[commands]]
|
|
name = 'XMLAddItems'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
local items = findFirstElement(data, "Items")
|
|
if items then
|
|
local newItem = {
|
|
_tag = "Item",
|
|
_attr = {
|
|
identifier = "new_item",
|
|
Weight = "10",
|
|
Value = "500"
|
|
}
|
|
}
|
|
addChild(items, newItem)
|
|
modified = true
|
|
end
|
|
'''
|
|
files = ['items/**/*.xml']
|
|
|
|
# XML mode - remove elements by attribute value
|
|
[[commands]]
|
|
name = 'XMLRemoveDisabled'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
visitElements(data, function(elem)
|
|
if elem._tag == "Feature" and getAttr(elem, "enabled") == "false" then
|
|
-- Mark for removal (actual removal happens via parent)
|
|
elem._remove = true
|
|
end
|
|
end)
|
|
|
|
-- Remove marked children
|
|
visitElements(data, function(elem)
|
|
if elem._children then
|
|
local i = 1
|
|
while i <= #elem._children do
|
|
if elem._children[i]._remove then
|
|
table.remove(elem._children, i)
|
|
else
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
modified = true
|
|
'''
|
|
files = ['config/**/*.xml']
|
|
|
|
# XML mode - conditional attribute updates based on other attributes
|
|
[[commands]]
|
|
name = 'XMLConditionalUpdate'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
visitElements(data, function(elem)
|
|
if elem._tag == "Weapon" then
|
|
local tier = getAttr(elem, "tier")
|
|
if tier and num(tier) >= 3 then
|
|
-- High tier weapons get damage boost
|
|
modifyNumAttr(elem, "damage", function(val) return val * 1.5 end)
|
|
setAttr(elem, "rarity", "legendary")
|
|
end
|
|
end
|
|
end)
|
|
modified = true
|
|
'''
|
|
files = ['weapons/**/*.xml']
|
|
|
|
# XML mode - modify nested elements
|
|
[[commands]]
|
|
name = 'XMLNestedModify'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
local config = findFirstElement(data, "Configuration")
|
|
if config then
|
|
local settings = findFirstElement(config, "Settings")
|
|
if settings then
|
|
setAttr(settings, "timeout", "120")
|
|
setAttr(settings, "maxRetries", "5")
|
|
|
|
-- Add or update nested element
|
|
local logging = findFirstElement(settings, "Logging")
|
|
if not logging then
|
|
logging = {
|
|
_tag = "Logging",
|
|
_attr = { level = "DEBUG", enabled = "true" }
|
|
}
|
|
addChild(settings, logging)
|
|
else
|
|
setAttr(logging, "level", "INFO")
|
|
end
|
|
end
|
|
end
|
|
modified = true
|
|
'''
|
|
files = ['config/**/*.xml']
|
|
|
|
# XML mode - batch attribute operations
|
|
[[commands]]
|
|
name = 'XMLBatchAttributeUpdate'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
-- Update all Price attributes across entire document
|
|
visitElements(data, function(elem)
|
|
if hasAttr(elem, "Price") then
|
|
modifyNumAttr(elem, "Price", function(val) return val * 1.1 end)
|
|
end
|
|
if hasAttr(elem, "Cost") then
|
|
modifyNumAttr(elem, "Cost", function(val) return val * 0.9 end)
|
|
end
|
|
end)
|
|
modified = true
|
|
'''
|
|
files = ['economy/**/*.xml']
|
|
|
|
# XML mode - clone and modify elements
|
|
[[commands]]
|
|
name = 'XMLCloneItems'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
local items = findElements(data, "Item")
|
|
local newItems = {}
|
|
|
|
for _, item in ipairs(items) do
|
|
local id = getAttr(item, "identifier")
|
|
if id and id:match("^weapon_") then
|
|
-- Clone weapon as upgraded version
|
|
local upgraded = {
|
|
_tag = "Item",
|
|
_attr = {
|
|
identifier = id .. "_mk2",
|
|
Weight = getAttr(item, "Weight"),
|
|
Value = tostring(num(getAttr(item, "Value")) * 2)
|
|
}
|
|
}
|
|
table.insert(newItems, upgraded)
|
|
end
|
|
end
|
|
|
|
-- Add all new items
|
|
for _, newItem in ipairs(newItems) do
|
|
addChild(data, newItem)
|
|
end
|
|
|
|
if #newItems > 0 then
|
|
modified = true
|
|
end
|
|
'''
|
|
files = ['items/**/*.xml']
|
|
|
|
# XML mode - remove all children with specific tag
|
|
[[commands]]
|
|
name = 'XMLRemoveObsolete'
|
|
regex = '(?P<xml>!any)'
|
|
lua = '''
|
|
visitElements(data, function(elem)
|
|
-- Remove all "Deprecated" children
|
|
removeChildren(elem, "Deprecated")
|
|
removeChildren(elem, "Legacy")
|
|
end)
|
|
modified = true
|
|
'''
|
|
files = ['config/**/*.xml'] |