Module:SemanticAnnotations: Difference between revisions

// via Wikitext Extension for VSCode
Tag: Manual revert
// via Wikitext Extension for VSCode
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
-- Module:SemanticAnnotations
--[[
-- Generates semantic annotations for templates in MediaWiki
* Name: SemanticAnnotations
* Author: Mark W. Datysgeld
* Description: Primary semantic integration module for generating semantic properties with transformation support and property limits
* Notes: Implements batching, deduplication and property limits (200 total, 25 per property); supports simple, object, complex, and subobject mappings; falls back to parser functions when mw.smw unavailable; includes pruning to prevent server crashes
]]


local p = {}
local p = {}
Line 10: Line 14:
local VALUE_LIMIT = 25    -- per individual property
local VALUE_LIMIT = 25    -- per individual property


-- Trim whitespace helper
--[[ Fallback for mw.smw.set using the #set parser function.
-- Now delegates to NormalizationText
local function trim(s)
    return NormalizationText.trim(s)
end
 
--[[ Generates semantic annotations using #set parser function
   @param args - Template parameters
   @param args - Template parameters
   @param mappings - Property mappings: {["Property"] = "param"} or complex format
   @param mappings - Property mappings: {["Property"] = "param"} or complex format
Line 82: Line 80:
     -- Return result or empty string
     -- Return result or empty string
     return propertyCount > 0 and table.concat(result, "\n") or ""
     return propertyCount > 0 and table.concat(result, "\n") or ""
end
-- Renders a table using TemplateStructure and adds annotations
function p.renderWithSemantics(args, config, semanticMappings, semanticOptions)
    local TemplateStructure = require('Module:TemplateStructure')
    local renderedTable = TemplateStructure.render(args, config)
    local annotations = p.generateAnnotations(args, semanticMappings, semanticOptions)
    return renderedTable .. "\n" .. annotations
end
-- Allows templates to append annotations directly via transclusion
function p.appendToTemplate(frame)
    local args = frame.args
    local parent = frame:getParent()
    local parentArgs = parent and parent.args or {}
   
    -- Build mappings from numbered parameters
    local mappings = {}
    local i = 1
    while args["property" .. i] and args["param" .. i] do
        mappings[args["property" .. i]] = args["param" .. i]
        i = i + 1
    end
   
    -- Extract options and generate annotations
    local options = {
        visible = args.visible == "true",
        prefix = args.prefix or ""
    }
    return p.generateAnnotations(parentArgs, mappings, options)
end
end


Line 117: Line 85:
local function prune(properties)
local function prune(properties)
     local total = 0
     local total = 0
    local TemplateHelpers = require('Module:TemplateHelpers')
   
     for prop,val in pairs(properties) do
     for prop,val in pairs(properties) do
         if type(val)=='table' then
         if type(val)=='table' then
             -- dedup array
             -- dedup array using centralized removeDuplicates function
            local seen, compact = {}, {}
             properties[prop] = TemplateHelpers.removeDuplicates(val)
            for _,v in ipairs(val) do if not seen[v] then seen[v]=true; compact[#compact+1]=v end end
             properties[prop] = compact
         end
         end
         -- per-property cap
         -- per-property cap
Line 161: Line 129:
         local param = mappingEntry.param
         local param = mappingEntry.param
         local metadata = mappingEntry.metadata or {}
         local metadata = mappingEntry.metadata or {}
         local value = args[param]
        -- Case-insensitive lookup: try exact match first, then lowercase
         local value = args[param] or args[param:lower()]
          
          
         if value and value ~= "" then
         if value and value ~= "" then
Line 205: Line 174:
end
end


-- Enhanced version supporting complex mappings (fallback when mw.smw unavailable)
-- Enhanced fallback for mw.smw.set with complex mapping support.
function p.generateEnhancedAnnotations(args, mappings, options)
function p.generateEnhancedAnnotations(args, mappings, options)
     args = args or {}
     args = args or {}
Line 229: Line 198:
          
          
         if type(mapping) == "string" then
         if type(mapping) == "string" then
             -- Simple string mapping
             -- Simple string mapping with case-insensitive lookup
            local value = args[mapping] or args[mapping:lower()]
             propertyCount = propertyCount + addSimplePropertyToResult(result,  
             propertyCount = propertyCount + addSimplePropertyToResult(result,  
                 fullPropertyName, args[mapping], transform[property], default[property])
                 fullPropertyName, value, transform[property], default[property])
         elseif type(mapping) == "table" then
         elseif type(mapping) == "table" then
             if mapping.param then
             if mapping.param then
                 -- Object with param structure
                 -- Object with param structure with case-insensitive lookup
                local value = args[mapping.param] or args[mapping.param:lower()]
                 propertyCount = propertyCount + addSimplePropertyToResult(result,  
                 propertyCount = propertyCount + addSimplePropertyToResult(result,  
                     fullPropertyName, args[mapping.param], transform[property], default[property])
                     fullPropertyName, value, transform[property], default[property])
             elseif mapping.mappings then
             elseif mapping.mappings then
                 -- Complex mapping with multiple parameters
                 -- Complex mapping with multiple parameters
Line 242: Line 213:
                     local param = mappingEntry.param
                     local param = mappingEntry.param
                     local metadata = mappingEntry.metadata or {}
                     local metadata = mappingEntry.metadata or {}
                     local value = args[param]
                    -- Case-insensitive lookup
                     local value = args[param] or args[param:lower()]
                      
                      
                     if value and value ~= "" then
                     if value and value ~= "" then
Line 285: Line 257:
end
end


--[[ Sets semantic properties with native API or fallback
--[[ Sets semantic properties using the native mw.smw API.
  This is the primary function for setting semantic data.
   @param args - Template parameters
   @param args - Template parameters
   @param mappings - Property mappings in formats:
   @param mappings - Property mappings in formats:
Line 311: Line 284:
          
          
         if type(mapping) == "string" then
         if type(mapping) == "string" then
             -- Simple string mapping
             -- Simple string mapping with case-insensitive lookup
             processSimpleMapping(properties, fullPropertyName, args[mapping], transform[property], default[property])
            -- Try exact match first, then lowercase
            local value = args[mapping] or args[mapping:lower()]
             processSimpleMapping(properties, fullPropertyName, value, transform[property], default[property])
         elseif type(mapping) == "table" then
         elseif type(mapping) == "table" then
             if mapping.is_subobject then
             if mapping.is_subobject then
Line 369: Line 344:
                 end
                 end
             elseif mapping.param then
             elseif mapping.param then
                 -- Single mapping with object structure
                 -- Single mapping with object structure with case-insensitive lookup
                 processSimpleMapping(properties, fullPropertyName, args[mapping.param], transform[property], default[property])
                local value = args[mapping.param] or args[mapping.param:lower()]
                 processSimpleMapping(properties, fullPropertyName, value, transform[property], default[property])
             elseif mapping.mappings then
             elseif mapping.mappings then
                 -- Complex mapping with multiple parameters
                 -- Complex mapping with multiple parameters