Přeskočit na obsah

Modul:Test

Z Wikislovníku

Tento modul je místo, kde si lidé mohou zkoušet kód Lua, aniž by tím něco jiného zásadně pokazili. Anglicky se jmenuje W:en: Module:Sandbox.


-- Adoptováno z anglické Wikipedie (https://en.wikipedia.org/w/index.php?title=Module:Table_row_counter&oldid=926041407)
-- Rozšíření o parametr column=číslo pro počítání neprázdných buněk v daném skloupci s vynecháním záhlaví
-- Poznámky se nepočítají
-- Parametry v angličtině a češtině s detekcí jazyka

-- Adopted from english Wikipedia (https://en.wikipedia.org/w/index.php?title=Module:Table_row_counter&oldid=926041407)
-- Extended with column=number that counts non-blank cells in that column (headers are skipped)
-- Comments are not counted
-- Parameters in English and Czech with language detection

-- This module counts table rows in wikitext.

local p = {}
local getArgs

function p.main(frame)
	-- Detect language code
	local langCode = mw.language.getContentLanguage():getCode()
	-- Arguments are taken differently because of missing Module:Arguments here
	return p._main(langCode, frame:getParent().args)
end

function replacePipesInInternalLinks(wikitable)
	-- Replace | with space in internal links
    return wikitable:gsub("%[%[(.-)%]%]", function(templateContent)
        -- Replace | with space inside the link
        local replaced = templateContent:gsub("|", " ")
        return "[[" .. replaced .. "]]"
    end)
end

function replacePipesInTemplates(wikitable)
	-- Replace | with space in templates
    return wikitable:gsub("{{(.-)}}", function(templateContent)
        -- Replace | with space inside the template
        local replaced = templateContent:gsub("|", " ")
        return "{{" .. replaced .. "}}"
    end)
end

function countNonBlankCells(wikitable, column)
    local count = 0
    local rows = {}
    local current_row = nil

	-- Replace | with space in internal links and templates
	wikitable = replacePipesInInternalLinks(wikitable)
	wikitable = replacePipesInTemplates(wikitable)

    -- Loop through each line in the wikitable
    for line in wikitable:gmatch("[^\r\n]+") do
		line = line:gsub("^%s*(.-)%s*$", "%1")  -- Trim spaces
		
        -- Detect new row (`|-` or `|}`)
        if line:match("^|%-") or line:match("^|}") then
			-- If we were processing a row, add it to rows
            if current_row and current_row ~= "" then
				table.insert(rows, current_row)
            end
            current_row = ""  -- Start a new row
		else
			-- Detect new row line
			if line:match("^|") then
				if current_row then
					current_row = current_row .. " " .. line
				else
					current_row = line
				end
			end
		end
	end	
		
    -- Add last row if exists
    if current_row and current_row ~= "" then
        table.insert(rows, current_row)
    end

    -- Process each row
    for row_index, row in ipairs(rows) do
		-- Normalize cell separators: Convert `||` to ` | ` for consistent splitting
		row = row:gsub("||", " | ")

		-- Split row into columns based on `|` separator
		local cells = {}
		for cell in row:gmatch("|%s*([^|]*)") do
			cell = cell and cell:gsub("^%s*(.-)%s*$", "%1") or "" -- Trim spaces, ensure non-nil
			table.insert(cells, cell)
		end

		-- Check if the specified column exists and is non-blank
		if #cells >= column then
			local cell_value = cells[column]
			if cell_value and cell_value ~= "" then
				count = count + 1
			end
		end
        -- end
    end

    return count
end

function p._main(langCode, args)
	-- Multilanguage parameters
	local langCodes = {'en', 'cs'}
	local id = {en='id', cs='id'}
	local tabno = {en='tabno', cs='pořadí tabulky'}
	local ignore = {en='ignore', cs='vynechat'}
	local column = {en='column', cs='sloupec'}
	local page = {en='page', cs='stránka'}
	
	local index
	local foundLangCode = false
	for index = 0, #langCodes do
		if (langCode == langCodes[index]) then
			foundLangCode = true
			break
		end
	end
	if not foundLangCode then
		-- Default language
		langCode = 'en'
	end

	-- Get the title object.
	local titleObj
	do
		local success
		success, titleObj = pcall(mw.title.new, args[page[langCode]])
		if not success or not titleObj then
			titleObj = mw.title.getCurrentTitle()
		end
	end

	-- Get the page content.
	local content = titleObj:getContent()
	if not content then
		return nil
	end
	
	-- Remove comments
	content = content:gsub('<!%-%-.-%-%->', '')

	-- Find the wikitables on that page.
	local wikitables = {}
	do
		local iWikitable = 0
		for s in content:gmatch('{|.-\n|}') do
			iWikitable = iWikitable + 1
			wikitables[iWikitable] = s
		end
		for s in content:gmatch('\n({|.-\n|})') do
			iWikitable = iWikitable + 1
			wikitables[iWikitable] = s
		end
	end

	-- Find the wikitable to work on.
	local wikitable
	if args[id[langCode]] then
		for i, s in ipairs(wikitables) do
			if s:match('^{|[^\n]*id *= *" *(%w+) *"') == args[id[langCode]] then
				wikitable = s
				break
			end
		end
	else
		wikitable = wikitables[tonumber(args[tableno[langCode]]) or 1]
	end
	if not wikitable then
		return nil
	end

	-- If column parameter is provided, count non-blank cells in that column.
	local column = tonumber(args[column[langCode]])
	if column then
		return countNonBlankCells(wikitable, column)
	end
	
	-- Count the number of rows.
	local count
	do
		local temp
		temp, count = wikitable:gsub('\n|%-', '\n|-')
	end

	-- Control for missing row markers at the start.
	if not wikitable:find('^{|[^\n]*%s*\n|%-') then
		count = count + 1
	end

	-- Control for extra row markers at the end.
	if wikitable:find('\n|%-[^\n]-%s*\n|}$') then
		count = count - 1
	end

	-- Subtract the number of rows to ignore, or the number of header
	--  rows if it's empty, and make sure the result isn't below zero.
	local headers
	do
		local temp
		temp, headers = wikitable:gsub('\n|%-\n!', '\n|-\n!')
	end
	if not wikitable:find('^{|[^\n]*%s*\n|%-\n!') then
		headers = headers + 1
	end
	count = count - (tonumber(args[ignore[langCode]]) or headers)
	if count < 0 then
		count = 0
	end
    return count
end

return p