Op den Inhalt sprangen

Modul:QuoteProcessor

Vu Wikipedia
Dokumentatioun vum Modul:QuoteProcessor [liesen] [änneren] [Versioune weisen]

D'Dokumentatioun fir dëst Modul steet hei ënnendrënner an ass vun der Säit Modul:QuoteProcessor/doc hei agebonne ginn. All Froe sollen och op där hirer Diskussiounssäit gestallt ginn. Kuckt och: Hëllef:Moduler.

local p = {}

-- Handle sequences of apostrophes for bold and italic mark-up.
function p.doQuotes(frame)
	-- This function is based on "doQuotes" from the MediaWiki parser:
	-- https://github.com/wikimedia/mediawiki/blob/master/includes/parser/Parser.php#L1987
	
	local text = frame.args[1]
	
	-- Split the input into alternating parts of normal text and aposthope
	-- sequences. Normal text is stored at odd indices, and apostrophe
	-- sequences at even indices.
	local arr = {}
	
	-- Extract the normal text before the first apostrophe sequence (if any) to
	-- keep the indices of apostrophe sequences even.
	local beginning = text:match("^[^']+")
	if beginning == nil then beginning = "" end
	table.insert(arr, beginning)
	
	-- Extract the apostrophe sequences and the normal text following them.
	for part1, part2 in text:gmatch("('+)([^']+)") do
	    table.insert(arr, part1) -- Add the apostrophe sequence.
	    table.insert(arr, part2) -- Add the text following the apostrophes.
	end
	
	-- Extract the trailing apostrophe sequence (if any).
	local ending = text:match("'+$")
	table.insert(arr, ending)

    local countarr = #arr

    -- If there's only one group, return the original text.
    if countarr == 1 then
        return text
    end

    -- Initialize counters for bold and italics mark-ups.
    local numbold = 0
    local numitalics = 0

    -- Iterate through even indices to process and count apostrophe sequences.
    for i = 2, countarr, 2 do
        local thislen = string.len(arr[i])

		-- In case of four apostrophes, append one to preceding normal text.
        if thislen == 4 then
            arr[i - 1] = arr[i - 1] .. "'"
            arr[i] = "'''"
            thislen = 3
        -- In case of more than five apostrophes, append all but five to the
        -- preceding normal text.
        elseif thislen > 5 then
            local extra = string.rep("'", thislen - 5)
            arr[i - 1] = arr[i - 1] .. extra
            arr[i] = "'''''"
            thislen = 5
        end
        
		-- Update counters based on the length of apostrophe sequences.
        if thislen == 2 then
            numitalics = numitalics + 1
        elseif thislen == 3 then
            numbold = numbold + 1
        elseif thislen == 5 then
            numitalics = numitalics + 1
            numbold = numbold + 1
        end
    end

	-- If both bold and italics are unbalanced (odd counts), interpret one
	-- sequence of three apostrophes as a normal apostrophe followed by two
	-- apostrophes for italics, giving priority to an apostrophe sequence
	-- 1. preceded by a single-letter word,
	-- 2. preceded by a multiletter word,
	-- 3. preceded by a space.
    if (numbold % 2 == 1) and (numitalics % 2 == 1) then
        local firstsingleletterword = -1
        local firstmultiletterword = -1
        local firstspace = -1
        
        -- Find the first appropriate apostrophe sequence for rebalancing.
        for i = 2, countarr, 2 do
            if string.len(arr[i]) == 3 then
                local preceding = arr[i - 1]
                local x1 = string.sub(preceding, -1)
                local x2 = string.sub(preceding, -2, -2)

                if x1 == ' ' then
                    if firstspace == -1 then
                        firstspace = i
                    end
                elseif x2 == ' ' then
                    firstsingleletterword = i
                    break
                elseif firstmultiletterword == -1 then
                    firstmultiletterword = i
                end
            end
        end

        -- Prioritize sequences: single-letter word > multi-letter word > space.
        if firstsingleletterword > -1 then
            arr[firstsingleletterword] = "''"
            arr[firstsingleletterword - 1] = arr[firstsingleletterword - 1] .. "'"
        elseif firstmultiletterword > -1 then
            arr[firstmultiletterword] = "''"
            arr[firstmultiletterword - 1] = arr[firstmultiletterword - 1] .. "'"
        elseif firstspace > -1 then
            arr[firstspace] = "''"
            arr[firstspace - 1] = arr[firstspace - 1] .. "'"
        end
    end
    
	-- Log results for debugging.
	--[[
	for i, t in pairs(arr) do
	  mw.log(i, t)
	end
	--]]

    return arr
end

-- Removes all bold mark-ups from the input text while preserving italics.
function p.removeBold(text)
	arr = p.doQuotes(text)
	
    for i, val in ipairs(arr) do
        if val == "'''" then
            arr[i] = ""
        elseif val == "'''''" then
            arr[i] = "''"
        end
    end
    
    return table.concat(arr)
end

-- Removes all italic mark-ups from the input text while preserving bold.
function p.removeItalic(text)
	arr = p.doQuotes(text)
	
    for i, val in ipairs(arr) do
        if val == "''" then
            arr[i] = ""
        elseif val == "'''''" then
            arr[i] = "'''"
        end
    end
    
    return table.concat(arr)
end

-- Removes all bold and italic mark-ups from the input text.
function p.removeBoldAndItalic(text)
	arr = p.doQuotes(text)
	
    for i, val in ipairs(arr) do
        if val == "''" or val == "'''" or val == "'''''" then
            arr[i] = ""
        end
    end
    
    return table.concat(arr)
end

return p