Ir para o conteúdo

Módulo:Cite

De Undertale Wiki

Erro em Lua em package.lua na linha 80: module 'Dev:Docbunto' not found.


--- Generates citations across the wiki to ensure standard formatting.
--  The module accepts several different types of citations and processes each
--  differently, based on the <code>f</code> table's functions. When the module
--  is called without a type, it acts as a citation needed template.
--  @module             cite
--  @alias              p
--  @require            Module:Date
--  @require            Module:User error
--  @require            Module:Yesno
--  @require            Module:Tags
--  @author             [[User:KockaAdmiralac|KockaAdmiralac]]
--  <nowiki>
local p = {}

-- Module dependencies
local Date = require('Module:Date')
local userError = require('Module:User error')
local yesno = require('Module:Yesno')
local tags = require('Module:Tags')
local data = mw.loadData('Module:Cite/data')
local title = mw.title.getCurrentTitle()

--  Private logic.

local DATE_FORMAT = '%B %d, %Y.'

--- Wrapper for <code>userError</code> that places the page under the Pages with
--  user errors category.
--  @function           err
--  @param              {string} text Text to display as an error
--  @return             {string} Wikitext with the error and category
--  @local
local function err(text)
    return userError(text, 'Pages with user errors')
end

--- Checks whether a given date string is a valid date.
--  @function           valid_date
--  @param              {string} d Date string to check
--  @return             {bool} Whether the string is a valid date
--  @local
function valid_date(d)
    return pcall(function()
        Date(d)
    end)
end

--- Table of possible citation types and the way they are processed.
--  Each type has a function associated with it that gets passed the arguments
--  after the type, does validation of these arguments and returns the whole
--  citation text.
--  @table              cite_functions
--  @alias              f
local f = {}

--- Handles Twitter citations.
--  Twitter citations receive arguments in this order:
--  * Twitter snowflake
--  * Tweet author's handle
--  * Citation from the tweet
--  * (Optional) Timestamp of the tweet's archival
--  * (Optional) Whether the original tweet link is dead
--  @function           f.twitter
--  @param              {table} args Citation type arguments
--  @return             {string} Citation text
function f.twitter(args)
    -- Check validity of arguments
    if not args[1] or not tonumber(args[1]) then
        return err('Tweet snowflake invalid or not specified')
    end
    if not args[2] or not args[3] then
        return err('Tweet author or citation not specified')
    end
    -- Twitter snowflake date extraction
    -- Credits: https://github.com/client9/snowflake2time
    local snowflake = tonumber(args[1])
    local epoch = math.floor(snowflake / 4194304 + 1288834974657)
    local date1 = Date(math.floor(epoch / 1000))
    -- Format citation
    local deadurl = yesno(args[5], false)
    local archived = yesno(args[4], true)
    local str = {
        '\'\'',
        args[3],
        '\'\' - ['
    }
    if deadurl and archived then
        table.insert(str, 'https://web.archive.org/web/')
        table.insert(str, args[4])
        table.insert(str, '/')
    end
    table.insert(str, 'https://twitter.com/')
    table.insert(str, args[2])
    table.insert(str, '/status/')
    table.insert(str, args[1])
    if data.twitter[args[2]] then
        table.insert(str, ' ')
        table.insert(str, data.twitter[args[2]])
        table.insert(str, ' (@')
        table.insert(str, args[2])
        table.insert(str, ')')
    else
        table.insert(str, ' @')
        table.insert(str, args[2])
    end
    table.insert(str, ' on Twitter,] ')
    table.insert(str, date1:fmt(DATE_FORMAT))
    if deadurl then
        if archived then
            table.insert(str, ' Archived on ')
            table.insert(str, Date(args[4]):fmt(DATE_FORMAT))
        else
            table.insert(str, ' \'\'\'[deletado]\'\'\'')
        end
    end
    return table.concat(str)
end

--- Handles Bluesky citations.
--  Bluesky citations receive arguments in this order:
--  * Bluesky account handle
--  * Bluesky post ID
--  * Citation from the post
--  * Date in YYYY-MM-DD format (or any other standard format)
function f.bluesky(args)
    if not args[1] or not args[3] then
        return err('Author or quote not specified')
    end
    if not args[2] then
        return err('Post ID not specified')
    end
    if not args[4] or not valid_date(args[4]) then
        return err('Date invalid or not specified')
    end
    return table.concat({
        '\'\'',
        tags.replace(args[3]),
        '\'\' - [https://bsky.app/profile/',
        args[1],
        '/post/',
        args[2],
        ' @',
        args[1],
        ' on Bluesky,] ',
        Date(args[4]):fmt(DATE_FORMAT)
    })
end

--- Handles citations of text in the game.
--  Game citations receive arguments in this order:
--  * Quotation line 1
--  * Quotation line 2
--  * ...
--  * Quote author and the situation in which they made the quote
--  @function           f.game
--  @param              {table} args Citation type arguments
--  @return             {string} Citation text
function f.game(args)
	num_args = #args
    if num_args == 0 then
        return err('Quote not specified')
    end
    if num_args == 1 then
        return err('Quote author not specified')
    end
    author = args[num_args]
    args[num_args] = nil
    return table.concat({
        '\'\'',
        tags.replace(table.concat(args, '<br />')),
        '\'\' - ',
        author
    })
end

--- Handles citations of YouTube videos.
--  YouTube citations receive arguments in this order:
--  * YouTube video ID
--  * Video title
--  * (Optional) Time at which the video plays
--  @function           f.youtube
--  @param              {table} args Citation type arguments
--  @return             {string} Citation text
function f.youtube(args)
    if not args[1] or not args[2] then
        return err('Video ID or title not specified')
    end
    local str = {
        '\'\'',
        args[2],
        '\'\' - [https://youtu.be/',
        args[1]
    }
    if args[3] then
        table.insert(str, '?t=')
        table.insert(str, args[3])
    end
    table.insert(str, ' YouTube]')
    return table.concat(str)
end

--- Handles Tumblr citations.
--  Tumblr citations receive arguments in this order:
--  * Tumblr name of the author
--  * Tumblr post ID
--  * Citation from the post
--  * Date in YYYY-MM-DD format (or any other standard format)
--  @function           f.tumblr
--  @param              {table} args Citation type arguments
--  @return             {string} Citation text
function f.tumblr(args)
    if not args[1] or not args[3] then
        return err('Author or quote not specified')
    end
    if not args[2] or not tonumber(args[2]) then
        return err('Post ID invalid or not specified')
    end
    if not args[4] or not valid_date(args[4]) then
        return err('Date invalid or not specified')
    end
    return table.concat({
        '\'\'',
        tags.replace(args[3]),
        '\'\' - [http://',
        args[1],
        '.tumblr.com/post/',
        args[2],
        ' ',
        args[1],
        ' on Tumblr,] ',
        Date(args[4]):fmt(DATE_FORMAT)
    })
end

--- Handles citations of the game's code.
--  Code citations receive arguments in this order:
--  * GML script name
--  * (Optional) Starting line number
--  * (Optional) Ending line number
--  @function           f.code
--  @param              {table} args Citation type arguments
--  @return             {string} Citation text
--  @see                https://github.com/KockaAdmiralac/deltarune-viewer
function f.code(args)
    local str = {}
    if not args[1] then
        return err('Script name not specified')
    end
    if (args[2] and not tonumber(args[2])) or (args[3] and not tonumber(args[3])) then
        return err('Line number is not a number')
    end
    str = {
        '[[code:',
        args[1],
        '.html',
    }
    if args[2] then
        table.insert(str, '#L')
        table.insert(str, args[2])
    end
    table.insert(str, '|')
    table.insert(str, args[1])
    table.insert(str, ' script]]')
    if args[2] then
        table.insert(str, ', line')
        if args[3] then
            table.insert(str, 's ')
            table.insert(str, args[2])
            table.insert(str, '–')
            table.insert(str, args[3])
        else
            table.insert(str, ' ')
            table.insert(str, args[2])
        end
    end
    return table.concat(str)
end

--- Handles citations from news sources.
--  News citations receive arguments in this order:
--  * Excerpt from the news
--  * News post title
--  * News site name
--  * News post URL
--  * News post date
--  * (Optional) First name of the author
--  * (Optional) Last name of the author
--  @function           f.news
--  @param              {table} args Citation type arguments
--  @return             {string} Citation text
function f.news(args)
    if not args[1] then
        return err('Relevant news post excerpt not specified')
    end
    if not args[2] then
        return err('News post title not specified')
    end
    if not args[3] then
        return err('News site name not specified')
    end
    if not args[4] then
        return err('News post URL not specified')
    end
    if not args[5] or not valid_date(args[5]) then
        return err('News post date invalid or not specified')
    end
    local author = {}
    if args[6] then
        if args[7] then
            table.insert(author, args[7])
            table.insert(author, ', ')
        end
        table.insert(author, args[6])
        table.insert(author, ', ')
    end
    return table.concat({
        '\'\'',
        tags.replace(args[1]),
        '\'\' - [',
        args[4],
        ' ',
        args[2],
        '] (',
        table.concat(author),
        Date(args[5]):fmt(DATE_FORMAT),
        ') \'\'',
        args[3],
        '\'\'.'
    })
end

--- Handles citations from Twitch clips.
--  Twitch clip citations receive arguments in this order:
--  * Clip URL segment (the part after https://clips.twitch.tv/)
--  * Clip title
--  * Twitch username of the streamer
--  * Stream date (not clipping date)
--  @function f.twitch
--  @param {table} args Citation type arguments
--  @return {string} Citation text
function f.twitch(args)
    if not args[1] then
        return err('Clip URL segment not specified')
    end
    if not args[2] then
        return err('Clip title not specified')
    end
    if not args[3] then
        return err('Streamer username not specified')
    end
    if not args[4] or not valid_date(args[4]) then
        return err('Stream date invalid or not specified')
    end
    return table.concat({
        '"\'\'[https://clips.twitch.tv/',
        args[1],
        ' "',
        args[2],
        ',]\'\'" a clip from [https://twitch.tv/',
        mw.ustring.lower(args[3]),
        ' @',
        args[3],
        '\'s] Twitch stream on ',
        Date(args[4]):fmt(DATE_FORMAT)
    })
end

-- Package items.

--- Template entrypoint for [[Template:Cite]].
--  @function           p.main
--  @param              {table} frame Scribunto frame object
--  @return             {string} Citation text
function p.main(frame)
    local args = frame:getParent().args
    local t = args[1]
    if t then
        if f[t] then
            local nargs = {}
            for i, v in ipairs(args) do
                if i > 1 then
                    nargs[i - 1] = v
                end
            end
            return f[t](nargs);
        else
            return err('Invalid citation type specified')
        end
    else
        -- {{cite}} was used
        local str = '<sup>&#91;[[Project:Manual de Estilo#Necessidade de referência|<span title="Essa afirmação precisa de citação.">precisa de citação</span>]]&#93;</sup>'
        if title.namespace == 0 or title.namespace == 14 then
            return str .. '[[Categoria:Artigos com Falta de Fonte]]'
        else
            return str
        end
    end
end

return p