Jump to content

Module:Quote

From The Petit Planet Wiki
Revision as of 16:18, 26 September 2026 by ReisuDesign (talk | contribs)
Module documentation

This module implements {{Quote}}.

-- <nowiki>
local Quote = {}

local getArgs = require('Module:Arguments').getArgs
local i18n = require('Module:I18n').loadMessages('Quote')


-- =========================================================
-- Helpers
-- =========================================================

local function parameter(args, ...)
    local names = { ... }

    for _, name in ipairs(names) do
        local value = i18n:parameter(name, args)

        if value ~= nil and value ~= '' then
            return value
        end
    end

    return nil
end


local function paragraph(text)
    return '\n' .. text .. '\n'
end


-- =========================================================
-- Options
-- =========================================================

local function parseOptions(args)
    local options = {
        classes = {},
        styles = {}
    }

    local extraClasses = parameter(args, 'class')

    if extraClasses then
        options.extraClasses = extraClasses
    end

    local extraStyles = parameter(args, 'style')

    if extraStyles then
        options.extraStyles = extraStyles
    end

    local align = parameter(args, 'align')

    if align then
        align = string.lower(align)

        if align == 'left' or align == 'right' then
            options.align = align
            options.classes[#options.classes + 1] = 'pp-quote--' .. align

            local width = parameter(args, 'width', 'quotewidth')

            if width then
                options.styles['width'] = width
            end
        end
    end

    return options
end


-- =========================================================
-- Quote builder
-- =========================================================

local function build(quoteContents, quoteSource, options)

    local quote = mw.html.create('div')
        :addClass('pp-quote')

    -- Alignment
    for _, className in ipairs(options.classes) do
        quote:addClass(className)
    end

    -- User-supplied classes
    if options.extraClasses then
        quote:addClass(options.extraClasses)
    end

    -- User-supplied styles
    for property, value in pairs(options.styles) do
        quote:css(property, value)
    end

    if options.extraStyles then
        quote:cssText(options.extraStyles)
    end

    -- Quote text
    quote:node(quoteContents)

    -- Source
    if quoteSource and quoteSource ~= '' then
        quote
            :tag('div')
                :addClass('pp-quote__source')
                :wikitext(quoteSource)
                :done()
    end

    return quote
end


-- =========================================================
-- Normal quote
-- =========================================================

function Quote.quote(frame)

    local args = getArgs(frame)
    local options = parseOptions(args)

    local quoteText =
        args[1]
        or parameter(args, 'quotetext', 'quote', 'text')
        or ''

    local person =
        args[2]
        or parameter(args, 'person', 'speaker', 'personquoted')

    local source =
        args[3]
        or parameter(args, 'source', 'quote_source')

    -- Quote text container
    local quoteContents = mw.html.create('div')
        :addClass('pp-quote__text')
        :wikitext(quoteText)

    -- Build source
    local quoteSource

    if person and source then
        quoteSource = person .. ', ' .. source
    elseif person then
        quoteSource = person
    elseif source then
        quoteSource = source
    end

    return build(
        quoteContents,
        quoteSource,
        options
    )
end


-- =========================================================
-- Dialogue
-- =========================================================

function Quote.dialogue(frame)

    local args = getArgs(frame)
    local options = parseOptions(args)

    local quoteContents = mw.html.create('div')
        :addClass('pp-quote__text')
        :addClass('pp-quote__text--dialogue')

    -- Dialogue lines
    for i = 1, #args, 2 do

        local speaker = args[i]
        local line = args[i + 1]

        if speaker and line then
            quoteContents
                :tag('div')
                    :addClass('pp-quote__line')

                    :tag('strong')
                        :addClass('pp-quote__speaker')
                        :wikitext(speaker .. ':')
                        :done()

                    :wikitext(' ' .. paragraph(line))

                    :done()
        end
    end

    -- Dialogue source
    local context = parameter(args, 'context')
    local source = parameter(args, 'source')

    local quoteSource

    if context and source then
        quoteSource = context .. ', ' .. source
    elseif context then
        quoteSource = context
    elseif source then
        quoteSource = source
    end

    return build(
        quoteContents,
        quoteSource,
        options
    )
end


return Quote