Module:HelperMethods: Difference between revisions
From MaRDI portal
No edit summary |
No edit summary |
||
(32 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
------------------------------------------------------------------------------------ | |||
-- HelperMethods -- | |||
-- -- | |||
-- This module includes a number of helper functions for dealing with lists, -- | |||
-- e.g. in the person template. It is a meta-module, meant to be called from -- | |||
-- other Lua modules, and should not be called directly from #invoke. -- | |||
------------------------------------------------------------------------------------ | |||
local M = {} | local M = {} | ||
Line 11: | Line 20: | ||
return str:lower() | return str:lower() | ||
end | end | ||
-- Utility function to count number of results in JSON answer of the SPQARL query | |||
function M.countElementsInBindings(bindings) | |||
if not bindings then return 0 end | |||
local count = 0 | |||
while bindings[count] do | |||
count = count + 1 | |||
end | |||
return count | |||
end | |||
-- This function will replace spaces with + and encode other non-alphanumeric | |||
-- characters into their percent-encoded representations, making the string | |||
-- safe to use in a URL. | |||
function M.urlencode(str) | |||
if str then | |||
str = string.gsub(str, "\n", "\r\n") | |||
str = string.gsub(str, "([^%w %-%_%.%~])", | |||
function (c) return string.format("%%%02X", string.byte(c)) end) | |||
str = string.gsub(str, " ", "+") | |||
end | |||
return str | |||
end | |||
-- Function to convert JSON results into a Lua table | -- Function to convert JSON results into a Lua table | ||
Line 17: | Line 51: | ||
if jsonResults and jsonResults.results and jsonResults.results.bindings then | if jsonResults and jsonResults.results and jsonResults.results.bindings then | ||
local bindings = jsonResults.results.bindings | local bindings = jsonResults.results.bindings | ||
for j = | for j = 0, #bindings do | ||
local row = {} | local row = {} | ||
for key, value in pairs(bindings[j]) do | for key, value in pairs(bindings[j]) do | ||
Line 25: | Line 59: | ||
end | end | ||
end | end | ||
return resultsTable | |||
end | |||
-- Function to convert JSON results into a Lua table with specified field order | |||
function M.convertJsonToTableOrdered(jsonResults, fieldOrder) | |||
local resultsTable = {} | |||
if jsonResults and jsonResults.results and jsonResults.results.bindings then | |||
local bindings = jsonResults.results.bindings | |||
-- Iterate through each result row in the bindings | |||
for j = 0, #bindings do | |||
local row = {} | |||
for _, fieldName in ipairs(fieldOrder) do | |||
-- Extract the value from the current binding | |||
local value = bindings[j][fieldName] | |||
if value and value.value then | |||
table.insert(row, value.value) | |||
else | |||
-- Use " " for missing or empty fields | |||
table.insert(row, ' ') | |||
end | |||
end | |||
table.insert(resultsTable, row) | |||
end | |||
end | |||
return resultsTable | return resultsTable | ||
end | end | ||
Line 85: | Line 145: | ||
-- Function to create a HTML table from a Lua table | -- Function to create a HTML table from a Lua table where columns are merged | ||
function M. | -- mergeColumns: contains a list of which columns should be merged, e.g. {{1, 2}, {4}} or {{2, 4}, {1, 3}} | ||
function M.createHtmlTableWithMergedCols(dataTable, headers, mergeColumns, itemprop) | |||
local htmlTable = mwHtml.create('table') | |||
htmlTable:addClass('wikitable'):attr('border', '1') | |||
htmlTable:addClass('sortable') -- This line ensures your table has the 'sortable' class | |||
local headerRow = htmlTable:tag('tr') | |||
-- Use the provided headers | |||
for _, header in ipairs(headers) do | for _, header in ipairs(headers) do | ||
headerRow:tag('th'):wikitext(header) | headerRow:tag('th'):wikitext(header) | ||
end | end | ||
for _, row in ipairs(dataTable) do | |||
if not string.find(row[1], "/entity/statement/") then | |||
local dataRow = htmlTable:tag('tr') | |||
for _, cols in ipairs(mergeColumns) do | |||
local combinedData | |||
if #cols == 1 then | |||
-- If only one column index is provided, use it as is, default to "N/A" string if nil | |||
combinedData = row[cols[1]] or "N/A" | |||
else | |||
-- If two column indices are provided, merge them, defaulting to "N/A" string if nil | |||
local col1Data = row[cols[1]] or "N/A" | |||
local col2Data = row[cols[2]] or "N/A" | |||
-- Check if col1Data is " " | |||
if col1Data == " " then | |||
combinedData = col2Data | |||
-- Check if both col1Data and col2Data are " " | |||
elseif col1Data == " " and col2Data == " " then | |||
combinedData = " " | |||
else | |||
combinedData = '[' .. col1Data .. ' ' .. col2Data .. ']' | |||
end | |||
if itemprop then | |||
combinedData = combinedData .. ' <link itemprop="' .. itemprop .. '" href="' .. col1Data .. '"/> ' | |||
end | |||
end | |||
dataRow:tag('td'):wikitext(combinedData) | |||
end | |||
end | |||
end | |||
-- mw.log(htmlTable) | |||
return tostring(htmlTable) | |||
end | |||
-- Helper function to convert table contents to a single string | |||
function tableToString(t) | |||
local stringParts = {} | |||
for key, value in pairs(t) do | |||
if type(value) == 'string' then | |||
table.insert(stringParts, value) | |||
elseif type(value) == 'table' then | |||
-- Recursively convert nested tables to string | |||
table.insert(stringParts, tableToString(value)) | |||
elseif type(value) == 'number' or type(value) == 'boolean' then | |||
-- Convert numbers and booleans to string directly | |||
table.insert(stringParts, tostring(value)) | |||
end | |||
end | |||
return table.concat(stringParts, " ") -- Combine with a space as separator | |||
end | end | ||
-- Function to convert Markdown text to Mediawiki format | |||
function M.markdownToMediawiki(mdText) | |||
-- Check if the input is a table and convert it | |||
if type(mdText) == 'table' then | |||
mdText = tableToString(mdText) | |||
elseif type(mdText) ~= 'string' then | |||
error("Expected a string or a table, got " .. type(mdText)) | |||
end | |||
-- Process the string to convert Markdown to MediaWiki formatting | |||
mdText = string.gsub(mdText, "%*%*(.-)%*%*", "'''%1'''") | |||
mdText = string.gsub(mdText, "%[(.-)%]%((.-)%)", "[%2 %1]") | |||
mdText = string.gsub(mdText, "\\N", "\n") | |||
mdText = string.gsub(mdText, "\\T", "\t") | |||
mdText = string.gsub(mdText, "\n### (.-)\n", "\n=== %1 ===\n") | |||
mdText = string.gsub(mdText, "\n## (.-)\n", "\n== %1 ==\n") | |||
mdText = string.gsub(mdText, "\n# (.-)\n", "\n= %1 =\n") | |||
return mdText | |||
end | |||
return M | return M |
Latest revision as of 20:08, 16 November 2024
Documentation for this module may be created at Module:HelperMethods/doc
------------------------------------------------------------------------------------
-- HelperMethods --
-- --
-- This module includes a number of helper functions for dealing with lists, --
-- e.g. in the person template. It is a meta-module, meant to be called from --
-- other Lua modules, and should not be called directly from #invoke. --
------------------------------------------------------------------------------------
local M = {}
-- Required modules for SPARQL queries and HTML table generation
local sparql = require('SPARQL')
local mwHtml = require('mw.html')
-- Utility function to trim and lowercase a string
function M.trimAndLower(str)
if str == nil then return nil end
str = str:gsub("^%s*(.-)%s*$", "%1")
return str:lower()
end
-- Utility function to count number of results in JSON answer of the SPQARL query
function M.countElementsInBindings(bindings)
if not bindings then return 0 end
local count = 0
while bindings[count] do
count = count + 1
end
return count
end
-- This function will replace spaces with + and encode other non-alphanumeric
-- characters into their percent-encoded representations, making the string
-- safe to use in a URL.
function M.urlencode(str)
if str then
str = string.gsub(str, "\n", "\r\n")
str = string.gsub(str, "([^%w %-%_%.%~])",
function (c) return string.format("%%%02X", string.byte(c)) end)
str = string.gsub(str, " ", "+")
end
return str
end
-- Function to convert JSON results into a Lua table
function M.convertJsonToTable(jsonResults)
local resultsTable = {}
if jsonResults and jsonResults.results and jsonResults.results.bindings then
local bindings = jsonResults.results.bindings
for j = 0, #bindings do
local row = {}
for key, value in pairs(bindings[j]) do
table.insert(row, value.value)
end
table.insert(resultsTable, row)
end
end
return resultsTable
end
-- Function to convert JSON results into a Lua table with specified field order
function M.convertJsonToTableOrdered(jsonResults, fieldOrder)
local resultsTable = {}
if jsonResults and jsonResults.results and jsonResults.results.bindings then
local bindings = jsonResults.results.bindings
-- Iterate through each result row in the bindings
for j = 0, #bindings do
local row = {}
for _, fieldName in ipairs(fieldOrder) do
-- Extract the value from the current binding
local value = bindings[j][fieldName]
if value and value.value then
table.insert(row, value.value)
else
-- Use " " for missing or empty fields
table.insert(row, ' ')
end
end
table.insert(resultsTable, row)
end
end
return resultsTable
end
-- Additional function to generate the histogram data
-- colWithYear: Contains the index of the column that contains the year information. Expected format "2023-12-30"
function M.generateHistogramChartFromTable(dataTable, colWithYear)
local yearCounts = {}
for _, row in ipairs(dataTable) do
-- Extract the year from the fourth column (publication date)
local date = row[colWithYear]
if date then -- Check if the date exists
local year = date:sub(1, 4) -- Extract the year
if year ~= "" then
yearCounts[year] = (yearCounts[year] or 0) + 1
end
end
end
local years = {}
local counts = {}
for year, count in pairs(yearCounts) do
table.insert(years, year)
table.insert(counts, count)
end
-- Sort the years to maintain chronological order
table.sort(years)
local sortedCounts = {}
for _, year in ipairs(years) do
table.insert(sortedCounts, yearCounts[year])
end
local chartData = {
type = 'bar',
data = {
labels = years, -- x-axis labels (years)
datasets = {{
label = 'Number of Publications',
data = sortedCounts, -- y-axis data (counts)
backgroundColor = 'rgba(54, 162, 235, 0.2)',
borderColor = 'rgba(54, 162, 235, 1)',
hoverBackgroundColor = 'red',
borderWidth = 1
}}
},
options = {
scales = {
y = {
beginAtZero = true
}
}
}
}
return chartData
end
-- Function to create a HTML table from a Lua table where columns are merged
-- mergeColumns: contains a list of which columns should be merged, e.g. {{1, 2}, {4}} or {{2, 4}, {1, 3}}
function M.createHtmlTableWithMergedCols(dataTable, headers, mergeColumns, itemprop)
local htmlTable = mwHtml.create('table')
htmlTable:addClass('wikitable'):attr('border', '1')
htmlTable:addClass('sortable') -- This line ensures your table has the 'sortable' class
local headerRow = htmlTable:tag('tr')
-- Use the provided headers
for _, header in ipairs(headers) do
headerRow:tag('th'):wikitext(header)
end
for _, row in ipairs(dataTable) do
if not string.find(row[1], "/entity/statement/") then
local dataRow = htmlTable:tag('tr')
for _, cols in ipairs(mergeColumns) do
local combinedData
if #cols == 1 then
-- If only one column index is provided, use it as is, default to "N/A" string if nil
combinedData = row[cols[1]] or "N/A"
else
-- If two column indices are provided, merge them, defaulting to "N/A" string if nil
local col1Data = row[cols[1]] or "N/A"
local col2Data = row[cols[2]] or "N/A"
-- Check if col1Data is " "
if col1Data == " " then
combinedData = col2Data
-- Check if both col1Data and col2Data are " "
elseif col1Data == " " and col2Data == " " then
combinedData = " "
else
combinedData = '[' .. col1Data .. ' ' .. col2Data .. ']'
end
if itemprop then
combinedData = combinedData .. ' <link itemprop="' .. itemprop .. '" href="' .. col1Data .. '"/> '
end
end
dataRow:tag('td'):wikitext(combinedData)
end
end
end
-- mw.log(htmlTable)
return tostring(htmlTable)
end
-- Helper function to convert table contents to a single string
function tableToString(t)
local stringParts = {}
for key, value in pairs(t) do
if type(value) == 'string' then
table.insert(stringParts, value)
elseif type(value) == 'table' then
-- Recursively convert nested tables to string
table.insert(stringParts, tableToString(value))
elseif type(value) == 'number' or type(value) == 'boolean' then
-- Convert numbers and booleans to string directly
table.insert(stringParts, tostring(value))
end
end
return table.concat(stringParts, " ") -- Combine with a space as separator
end
-- Function to convert Markdown text to Mediawiki format
function M.markdownToMediawiki(mdText)
-- Check if the input is a table and convert it
if type(mdText) == 'table' then
mdText = tableToString(mdText)
elseif type(mdText) ~= 'string' then
error("Expected a string or a table, got " .. type(mdText))
end
-- Process the string to convert Markdown to MediaWiki formatting
mdText = string.gsub(mdText, "%*%*(.-)%*%*", "'''%1'''")
mdText = string.gsub(mdText, "%[(.-)%]%((.-)%)", "[%2 %1]")
mdText = string.gsub(mdText, "\\N", "\n")
mdText = string.gsub(mdText, "\\T", "\t")
mdText = string.gsub(mdText, "\n### (.-)\n", "\n=== %1 ===\n")
mdText = string.gsub(mdText, "\n## (.-)\n", "\n== %1 ==\n")
mdText = string.gsub(mdText, "\n# (.-)\n", "\n= %1 =\n")
return mdText
end
return M