Module:Mgsub

--

-- Multiline global substitution: -- Like mw.ustring.gsub, but '^' and '$' match the beginning and end of each -- line, respectively.

local checkType = require('libraryUtil').checkType local checkTypeMulti = require('Dev:CheckTypeMulti')

-- Reduce table lookups local uGsub = mw.ustring.gsub

return function (s, pttrn, repl, n)   checkType('Dev:Mgsub', 1, s, 'string') checkType('Dev:Mgsub', 2, pttrn, 'string') checkTypeMulti('Dev:Mgsub', 3, repl, {'function', 'table', 'string'}) checkType('Dev:Mgsub', 4, n, 'number', true)

-- Return the original string if no matches are allowed. if n and n < 1 then return s, 0 end

-- Use mw.ustring.gsub if multiline substitution does not make sense. if not s:find('\n') or pttrn:sub(1, 1) ~= '^' and pttrn:sub(-1) ~= '$' then return uGsub(s, pttrn, repl, n)   end

local lines = mw.text.split(s, '\n') local totalMatches = 0 local remainingMatches, newMatches

for i = 1, #lines do       -- Stop updating lines if no more matches are allowed. if n and totalMatches == n then break end

remainingMatches = n and n - totalMatches lines[i], newMatches = uGsub(lines[i], pttrn, repl, remainingMatches) totalMatches = totalMatches + newMatches end

return table.concat(lines, '\n'), totalMatches end

-- -- (Add categories here.)