Module:TA4TK:myTest: Difference between revisions

From MaRDI portal
No edit summary
No edit summary
Line 441: Line 441:


-- Loop through the bindings
-- Loop through the bindings
for index, item in ipairs(jsonResults.results.bindings) do
for index, item in pairs(jsonResults.results.bindings) do
     if not item or not item.Label or not item.Label.value then
     if not item or not item.Label or not item.Label.value then
         return "Error: Missing item.Label.value"
         return "Error: Missing item.Label.value"

Revision as of 13:55, 26 March 2025

Documentation for this module may be created at Module:TA4TK:myTest/doc

-- Required modules for SPARQL queries and HTML table generation
local sparql = require('SPARQL')
local mwHtml = require('mw.html')
local json = require("mw.text") 

local p = {}

function p.getImageWithLegend(frame)
    local pidLocalImage  = "P1088"    -- Property ID for the local image
    local pidMediaLegend = "P648"   -- Property ID for the (qualifier) media legend
	local qid = "Q4610"           -- The target entity
    local width = "480px"  
    local defaultLegend = "No legend available."
    local imageLegend1 = "No legend available."
    local imageLegend2 = "No legend available."
    
    
    -- Attempt to retrieve entity data
    local entity = mw.wikibase.getEntity(qid)
    if not entity or not entity.claims[pidLocalImage] then
        return "No image found"
    end
    
    
    local imageClaims = entity.claims[pidLocalImage]
    -- Extract the first image filename from P1088
    local imageFilename1 = imageClaims[1].mainsnak.datavalue.value
    if not imageFilename1 then
        return "No valid image found"
    end
	
	imageLegend1 = imageClaims[1].qualifiers[pidMediaLegend][1].datavalue.value.text

	-- Extract the second image filename from P1088
	local imageFilename2 = imageClaims[2].mainsnak.datavalue.value
    if not imageFilename2 then
    	--return one image
	    return string.format("[[File:%s|thumb|center|%s|%s]]", imageFilename1,width, imageLegend1)
    else     	
		imageLegend2 = imageClaims[2].qualifiers[pidMediaLegend][1].datavalue.value.text
    end

    --return two images
	return string.format("[[File:%s|thumb|left|%s|%s]]  [[File:%s|thumb|center|%s|%s]]", imageFilename1, width, imageLegend1, imageFilename2, width, imageLegend2)
   
end

function p.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 comma-separated string
function p.convertJsonToCommaSeparatedList(jsonResults)
	local resultsString = ""
	
	if jsonResults and jsonResults.results and jsonResults.results.bindings then
        local bindings = jsonResults.results.bindings
        for i = 0, #bindings do
            local binding = bindings[i]
            if binding.valueLabel and binding.valueLabel.value then
                if resultsString ~= "" then
                    resultsString = resultsString .. ", "
                end
                
                local name = binding.valueLabel.value
                if string.find(name, "https://") then
                	name = "Unnamed task"
                end
                
                local link = binding.value.value
                link = link:gsub("entity/Q", "wiki/Task:")
                
                local nameAndLink = "[" .. link .. " " .. name .. "]"

                resultsString = resultsString .. nameAndLink
            end
        end
    end

    return resultsString
end


-- Function to build the list
function p.buildList(frame)
	
    -- Retrieve target1 from frame arguments or return error message if not set
	local target1 = frame.args[1]
    if not target1 or target1 == '' then
        return "No ID given"
    end    
    
    -- Constructing the SPARQL query with dynamic entity target1
    local sparqlQuery = [[
PREFIX target1: <https://staging.mardi4nfdi.org/entity/]] .. target1 .. [[>
SELECT ?value ?valueLabel WHERE {
  ?value wdt:P715 target1:.
  target1: rdfs:label ?valueLabel
}
    ]]
    
	-- Executing the SPARQL query and retrieving results in JSON format
	local jsonResults = sparql.runQuery(sparqlQuery)
	
	-- Handle error in SPARQL query execution
	if jsonResults and jsonResults.error then
    	mw.log("Error in SPARQL query: " .. tostring(jsonResults.error))
    	return nil
	end

	if not jsonResults then
        return "Could not fetch data."
	end
	
	local resultString = p.convertJsonToCommaSeparatedList(jsonResults)
    return resultString
    
end

-- Function to build the list
function p.getFormulations(frame)
	
    -- Constructing the SPARQL query with dynamic entity target1
    local sparqlQuery = [[
    SELECT ?Formula ?defining_formulation
	# Q4610 refers to Electron Shuttling Model
	# P715 refers to contains 
	# P29 refers to defining formulation
	WHERE {
      wd:Q4610 wdt:P715 ?IDFormula.
      ?IDFormula  rdfs:label ?Formula.
      ?IDFormula wdt:P29 ?defining_formulation
	}
    ]]
    
	-- Executing the SPARQL query and retrieving results in JSON format
	local jsonResults = sparql.runQuery(sparqlQuery)
	
	-- Handle error in SPARQL query execution
	if jsonResults and jsonResults.error then
    	mw.log("Error in SPARQL query: " .. tostring(jsonResults.error))
    	return nil
	end

	if not jsonResults then
        return "Could not fetch data."
	end
	
	--local testResults = p.convertJsonToCommaSeparatedList(jsonResults)
	--return testResults
	local resultTable = p.convertJsonToTable(jsonResults)
    -- return resultTable
    
    --return "<pre>" .. mw.text.nowiki(json.jsonEncode(resultTable)) .. "</pre>"
    local jsonString = mw.text.jsonEncode(jsonResults)
    -- return "<pre>" .. mw.text.nowiki(jsonString) .. "</pre>"
    return p.extractDefiningFormulations(jsonString)

end

local json = require("mw.text") -- Load the JSON library

function p.extractDefiningFormulations(jsonString)
	local frame = mw.getCurrentFrame()
    local data = mw.text.jsonDecode(jsonString) -- Convert JSON string to Lua table
    
    if not data or not data.results or not data.results.bindings then
        return "Error: Invalid JSON structure"
    end

    local formulations = {} -- Table to store extracted values

    -- Loop through the bindings and collect "defining_formulation" values
    for _, item in ipairs(data.results.bindings) do
        if not item or not item.defining_formulation or not item.defining_formulation.value then
        	return "Error: Missing item.defining_formulation.value"
        else
        	local mathML = item.defining_formulation.value -- Get the MathML string
        	local equationLabel = item.Formula.value
        	 -- Use pattern matching to find the alttext attribute
    		local alttext = mathML:match('alttext="([^"]+)"')
    		-- Pattern to match content after "\displaystyle " and before the last "}"
		    local match = alttext:match("\\displaystyle%s*(.*)}%s*$")
            --table.insert(formulations, item.defining_formulation.value)
              local mathTag = frame:extensionTag{
            	name = "math",
            	content = match
        	  }
              -- table.insert(formulations, "| " .. mathTag) -- Add row to the table
              table.insert(formulations, "| " .. equationLabel .. " || " .. mathTag)
       --     table.insert(formulations, match)
        end
        
    end
  
    -- Construct the Wikitext table
    local wikitextTable = "{| class='wikitable'\n" .. table.concat(formulations, "\n|-\n") .. "\n|}"
	return wikitextTable
end

function p.extractDefiningFormulationsWithQuantities(jsonString)
	local frame = mw.getCurrentFrame()
    local data = mw.text.jsonDecode(jsonString) -- Convert JSON string to Lua table
    
    if not data or not data.results or not data.results.bindings then
        return "Error: Invalid JSON structure"
    end

    local formulations = {} -- Table to store extracted values

    -- Loop through the bindings and collect "defining_formulation" values
    for _, item in ipairs(data.results.bindings) do
        if not item or not item.defining_formulation or not item.defining_formulation.value then
           return "Error: Missing item.defining_formulation.value"
        else
        	local mathML = item.defining_formulation.value -- Get the MathML string
        	local equationLabel = item.Formula.value
        	local alttext = mathML:match('alttext="([^"]+)"')
		    local match = alttext:match("\\displaystyle%s*(.*)}%s*$")
            local mathTag = frame:extensionTag{
                name = "math",
            	content = match
        	}
        	
        	local equationIDURL = item.IDFormula.value
        	
        	
        	-- table.insert(formulations, "| '''" .. equationLabel .. "''' || " .. mathTag)
        	table.insert(formulations, "| [" .. equationIDURL .. " '''" .. equationLabel .. "'''] || " .. mathTag)

   	 
        	local equationID = equationIDURL:match(".*/(.-)$") or equationIDURL -- Extracts the part after the last '/'
        	local  quantitySymbolNamePairs = p.extractQuantities(equationID)
        	 -- Use pattern matching to find the alttext attribute
    		 -- Pattern to match content after "\displaystyle " and before the last "}"
        	-- local quantityMathML = item.in_defining_formula.value
    		  -- Match the content inside alttext="{\displaystyle ... }"
    		-- local alttext = string.match(quantityMathML, 'alttext="{\\displaystyle%s*(.-)%s*}"')
            --   local mathQuantity = frame:extensionTag{
            --  	name = "math",
            --  	content = alttext
        	--   }
            --  table.insert(formulations, "| " .. mathQuantity ..  " || " .. "symbol represents:"  ..  " || " ..  quantityLabel)
            --  table.insert(formulations, "| " .. equationIDURL)
              -- Accessing the stored pairs
			for i, pair in ipairs(quantitySymbolNamePairs) do
				local quantitySymbolMathTag = frame:extensionTag{
            	name = "math",
            	content = pair[1]
        		}
            	table.insert(formulations, "| " .. quantitySymbolMathTag   ..  " symbol represents " .. pair[2])
			end
			table.insert(formulations, "| " .. " " )
       
        end
        
    end
        
    -- Construct the Wikitext table
    local wikitextTable = "{| class='wikitable'\n" .. table.concat(formulations, "\n|-\n") .. "\n|}"
	return wikitextTable
end

function p.extractQuantities(qid)
    local pidInDefiningFormula  = "P597"    -- Property ID for in defining formula 
    local pidSymbolRepresents = "P598"   -- Property ID for the (qualifier) symbol represents

    -- Attempt to retrieve entity data
    local entity = mw.wikibase.getEntity(qid)
    if not entity or not entity.claims[pidInDefiningFormula] then
        return "No formulation found"
    end
    
    
    local inDefiningFormulaClaims = entity.claims[pidInDefiningFormula]
    local count = 0
    -- Table to store pairs of quantity symbol and quantity name
    local quantitySymbolNamePairs = {}
	for _ in pairs(inDefiningFormulaClaims or {}) do
    	count = count + 1
    	-- Extract the first image filename from P1088
    	local quantitySymbol = inDefiningFormulaClaims[count].mainsnak.datavalue.value
    	if not quantitySymbol then
        	return "No valid formulation found"
    	end
    	quantity = inDefiningFormulaClaims[count].qualifiers[pidSymbolRepresents][1].datavalue.value.text
        test =  inDefiningFormulaClaims[count].qualifiers[pidSymbolRepresents]
    	quantityId = inDefiningFormulaClaims[count].qualifiers[pidSymbolRepresents][1].datavalue.value.id
	    local quantityName = mw.wikibase.label(quantityId)
	    -- Insert pair into the table
	    table.insert(quantitySymbolNamePairs, {quantitySymbol, quantityName}) 
    end

   return quantitySymbolNamePairs
end


-- Function to build the list
function p.getFormulationsWithQuantities(frame)
	
    -- Constructing the SPARQL query with dynamic entity target1
    local sparqlQuery = [[
	SELECT ?Formula ?defining_formulation ?IDFormula 
	# Q4610 refers to Electron Shuttling Model
	# P715 refers to contains 
	# P29 refers to defining formula
	WHERE {
      wd:Q4610 wdt:P715 ?IDFormula.
      ?IDFormula  rdfs:label ?Formula.
      ?IDFormula wdt:P29 ?defining_formulation.
	}
    ]]
    
	-- Executing the SPARQL query and retrieving results in JSON format
	local jsonResults = sparql.runQuery(sparqlQuery)
	
	-- Handle error in SPARQL query execution
	if jsonResults and jsonResults.error then
    	mw.log("Error in SPARQL query: " .. tostring(jsonResults.error))
    	return nil
	end

	if not jsonResults then
        return "Could not fetch data."
	end
	
	--local testResults = p.convertJsonToCommaSeparatedList(jsonResults)
	--return testResults
	local resultTable = p.convertJsonToTable(jsonResults)
    --return resultTable
    
    --return "<pre>" .. mw.text.nowiki(json.jsonEncode(resultTable)) .. "</pre>"
    local jsonString = mw.text.jsonEncode(jsonResults)
    -- return "<pre>" .. mw.text.nowiki(jsonString) .. "</pre>"
    return p.extractDefiningFormulationsWithQuantities(jsonString)

end

-- Function to build the description
function p.buildDescription(frame)
	
    -- Retrieve target1 from frame arguments or return error message if not set
	local target1 = frame.args[1]
    if not target1 or target1 == '' then
        return "No ID given"
    end    
    
    -- Constructing the SPARQL query with dynamic entity target1
    local sparqlQuery = [[
	SELECT ?Description
		WHERE {
    	wd:Q4610 wdt:P896 ?Description.
	}
    ]]

	-- Executing the SPARQL query and retrieving results in JSON format
	local jsonResults = sparql.runQuery(sparqlQuery)
    return jsonResults['results']['bindings'][0]['Description']['value']
end



function p.getImage(frame)
    local entityId = "Q4610"  -- The target entity
    local propertyId = "P1088" -- Property assumed to store the image
    local width = "480px"      -- Desired image width

    -- Attempt to retrieve entity data
    local entity = mw.wikibase.getEntity(entityId)
    if not entity or not entity.claims[propertyId] then
        return "No image found"
    end

    -- Extract the first image filename from P1088
    local imageFilename1 = entity.claims[propertyId][1].mainsnak.datavalue.value
    if not imageFilename1 then
        return "No valid image found"
    end
	-- Extract the second image filename from P1088
	local imageFilename2 = entity.claims[propertyId][2].mainsnak.datavalue.value
    if not imageFilename2 then
    	--return one image
	    return string.format("[[File:%s|thumb|center|%s]]", imageFilename1, width)
    else     	
    	--return two images
	     return string.format("[[File:%s|left|%s]]  [[File:%s|center|%s]] \n \n  \n ", imageFilename1, width, imageFilename2, width)
    end
end


function p.getComputationalTasks(frame)
    -- Constructing the SPARQL query with dynamic entity target1
    local sparqlQuery = [[
	SELECT ?URL ?Label  
	# Q4610 refers to Electron Shuttling Model
	# P348 refers to used by 
	WHERE {
		wd:Q4610 wdt:P348 ?URL.
		?URL rdfs:label ?Label
	}
	]]

	-- Executing the SPARQL query and retrieving results in JSON format
	local jsonResults = sparql.runQuery(sparqlQuery)
	
	-- Handle error in SPARQL query execution
	if jsonResults and jsonResults.error then
    	mw.log("Error in SPARQL query: " .. tostring(jsonResults.error))
    	return nil
	end

	if not jsonResults then
    	return "Could not fetch data."
	end
	--unocomment the following two lines to see how the jsonResults look like 
	-- local jsonString = mw.text.jsonEncode(jsonResults)
    -- return "<pre>" .. mw.text.nowiki(jsonString) .. "</pre>"
    
    if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
        return "Error: Invalid JSON structure"
    end


    
	local computationalTasks = {}

	-- Debug: Log the bindings table
	mw.logObject(jsonResults.results.bindings)

	-- Loop through the bindings
	for index, item in pairs(jsonResults.results.bindings) do
    	if not item or not item.Label or not item.Label.value then
        	return "Error: Missing item.Label.value"
    	elseif not item.URL or not item.URL.value then
        	return "Error: Missing item.URL.value"
    	else
        	local label = item.Label.value
        	local url = item.URL.value
        	local labelWithUrl = string.format('[%s %s]', tostring(url), tostring(label))
        	table.insert(computationalTasks, "| " .. index .. " ".. labelWithUrl)
    	end
	end

	-- Construct the Wikitext table
    local wikitextTable = "{| class='wikitable'\n" .. table.concat(computationalTasks, "\n|-\n") .. "\n|}"
	return wikitextTable
	
end

return p