Jump to content

Module:Sandbox/Polygnotus

From Wikipedia, the free encyclopedia
-- Module:Sandbox/Polygnotus
-- Advanced citation module using wiki markup for links
local p = {}

-- Main entry point
function p.main(frame)
    local args = frame:getParent().args
    
    -- Validate parameters
    local validationError = p.validateArgs(args)
    if validationError then
        return validationError
    end
    
    -- Route to appropriate function
    local type = args.type or 'quotes'
    if type == 'inline' then
        return p.inline(args, frame)
    else
        return p.quotes(args, frame)
    end
end

-- Parameter validation
function p.validateArgs(args)
    local errors = {}
    
    -- Check required parameters based on type
    if args.type == 'inline' then
        if not args.group then
            table.insert(errors, 'Inline citations require "group" parameter')
        end
        if not args.num and not args.nums then
            table.insert(errors, 'Inline citations require "num" or "nums" parameter')
        end
    elseif not args.type or args.type == 'quotes' then
        if not args.group then
            table.insert(errors, 'Quote lists require "group" parameter')
        end
        if not args.source then
            table.insert(errors, 'Quote lists require "source" parameter')
        end
    else
        table.insert(errors, 'Invalid type parameter: must be "inline" or "quotes"')
    end
    
    -- Return error message if any
    if #errors > 0 then
        local errorMsg = table.concat(errors, '; ')
        return mw.html.create('span')
            :addClass('error')
            :attr('role', 'alert')
            :wikitext('Citation error: ' .. errorMsg)
            :done()
    end
    
    return nil
end

-- Generate inline citation
function p.inline(args, frame)
    local group = args.group
    local page = args.page
    local pageDisplay = page and (', p.' .. page) or ''
    
    -- Handle multiple citations
    if args.nums then
        local nums = mw.text.split(args.nums, ',')
        local citations = {}
        
        for i, num in ipairs(nums) do
            num = mw.text.trim(num)
            
            -- Use wiki markup with preprocess
            local citation = frame:preprocess(string.format(
                '<sup id="%s-%s" class="reference">[[#%s-quotes|<span class="cite-bracket">[</span>%s%s<span class="cite-bracket">]</span>]]</sup>',
                group, num, group, num, pageDisplay
            ))
            
            table.insert(citations, citation)
        end
        
        -- Join without separator
        return table.concat(citations, '')
    else
        -- Single citation using wiki markup
        local num = args.num
        
        return frame:preprocess(string.format(
            '<sup id="%s-%s" class="reference">[[#%s-quotes|<span class="cite-bracket">[</span>%s%s<span class="cite-bracket">]</span>]]</sup>',
            group, num, group, num, pageDisplay
        ))
    end
end

-- Generate quotes section
function p.quotes(args, frame)
    local group = args.group
    local source = args.source
    
    -- Start with basic div
    local output = {}
    table.insert(output, '<div class="citation citation-quotes" role="region" aria-label="References for ' .. mw.text.nowiki(group) .. '">')
    
    -- Add source header
    table.insert(output, '<h3 id="' .. mw.text.nowiki(group) .. '-source" class="citation-source">' .. source .. '</h3>')
    
    -- Add URLs if provided
    if args.url then
        table.insert(output, ' [' .. args.url .. ' <span class="visually-hidden">External link to source</span>]')
    end
    
    if args['archive-url'] then
        table.insert(output, ' <span class="citation-archive">(Archived: [' .. args['archive-url'] .. 
                     ' <span class="visually-hidden">Archived version</span>]')
        if args['archive-date'] then
            table.insert(output, ' Date: ' .. args['archive-date'])
        end
        table.insert(output, ')</span>')
    end
    
    -- Create quotes list
    table.insert(output, '<ol id="' .. mw.text.nowiki(group) .. '-quotes" class="citation-quotes-list">')
    
    -- Add quotes dynamically
    local i = 1
    while args['quote' .. i] do
        local quote = args['quote' .. i]
        local quotePage = args['quote' .. i .. '-page']
        local pageInfo = quotePage and (' (p. ' .. quotePage .. ')') or ''
        
        table.insert(output, string.format(
            '<li id="%s-quote-%d" class="citation-quote-item">' ..
            '<span class="quote-text">%s%s</span> ' ..
            '<span class="quote-backlink">[[#%s-%d|↑]]</span>' ..
            '</li>',
            mw.text.nowiki(group), i, quote, pageInfo,
            group, i
        ))
        
        i = i + 1
    end
    
    -- Handle edge case of no quotes
    if i == 1 then
        table.insert(output, '<li class="citation-no-quotes">No quotes provided</li>')
    end
    
    table.insert(output, '</ol>')
    table.insert(output, '</div>')
    
    return frame:preprocess(table.concat(output))
end

-- Export module functions
return p