Přeskočit na obsah

Modul:Table row counter

Z Wikipedie, otevřené encyklopedie

Modul:Table row counter slouží pro výpočet počtu řádků v tabulce. Používá ho šablona {{Table row counter}}.

Použití ve wiki textu

[editovat zdroj]

Modul může být použit ve wiki textu stejně jako šablona {{Table row counter}}. Modul se volá příkazem {{#invoke:Table row counter|main}}.

Použití v Lua modulech

[editovat zdroj]

Chcete-li použít tento modul v jiných Lua modulech, nejprve jej načtěte:

local mTRC = require('Modul:Table row counter')

Potom můžete spočítat řádky tabulky pomocí funkce _main:

mTRC._main(args)

args obsahuje parametry modulu. Více informací o parametrech a použití naleznete v dokumentaci šablony.

-- 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 hlaviček
-- Extended with column=number that counts non-blank cells in that column (headers are skipped)

-- This module counts table rows in wikitext.

local p = {}
local getArgs

function p.main(frame)
	-- Arguments are taken differently because of missing Module:Arguments here
	return p._main(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(args)
	-- Get the title object.
	local titleObj
	do
		local success
		success, titleObj = pcall(mw.title.new, args.page)
		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
		local s1 = content:match('^({|.-\n|})')
		if s1 then
			iWikitable = iWikitable + 1
			wikitables[iWikitable] = s1
		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 then
		for i, s in ipairs(wikitables) do
			if s:match('^{|[^\n]*id *= *" *(%w+) *"') == args.id then
				wikitable = s
				break
			end
		end
	else
		wikitable = wikitables[tonumber(args.tableno) 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)
	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) or headers)
	if count < 0 then
		count = 0
	end
	return count
end

return p