Bahaipedia
Bahaipedia
Menu
About Bahaipedia
Ask a question
General help
Random page
Recent changes
In other projects
Tools
What links here
Related changes
Upload file
Special pages
Printable version
Permanent link
Page information
Module
Discussion
View history
Talk
Contributions
Create account
Log in
Navigation
About Bahaipedia
Ask a question
General help
Random page
Recent changes
In other projects
Learn more
Core topics
Bahá’í Faith
Central Figures
Teachings
Practices
Tools
What links here
Related changes
Upload file
Special pages
Printable version
Permanent link
Page information
Translations

Module:Cite

From Bahaipedia
Jump to:navigation, search
Module documentation[view] [edit] [history] [purge]

This module is used by Template:Cite to generate a citation based on a book title. See the template page for more documentation.

The above documentation is transcluded from Module:Cite/doc. (edit | history)
Editors can experiment in this module's sandbox (create | mirror) and testcases (create) pages.
Subpages of this module.

local p = {}

-- Helper: Get all labels from a list of claims
local function getLabelsFromClaims(claims)
    local labels = {}
    for _, claim in ipairs(claims or {}) do
        if claim.mainsnak and claim.mainsnak.datavalue then
            local id = claim.mainsnak.datavalue.value.id
            local label = mw.wikibase.getLabel(id)
            if label then table.insert(labels, label) end
        end
    end
    return labels
end

-- Helper: Format contributors, apply "et al." if needed
local function formatContributors(contributors)
    local n = #contributors
    if n == 0 then return "" end
    if n > 10 then
        local firstSeven = {}
        for i = 1, 7 do table.insert(firstSeven, contributors[i]) end
        return table.concat(firstSeven, ", ") .. ", et al."
    else
        return table.concat(contributors, ", ")
    end
end

-- Helper: Format secondary contributors (e.g., "ed.", "comp.", "trans.")
local function formatSecondaryContributors(contributors, label)
    local list = formatContributors(contributors)
    if list ~= "" then
        return ", " .. label .. " " .. list
    end
    return ""
end

-- Helper: Parse page range string into start and end pages
local function parsePageRange(pageRangeStr)
    local startPage, endPage
    if not pageRangeStr or pageRangeStr == "" then
        return nil, nil
    end
    pageRangeStr = mw.text.trim(pageRangeStr)
    if pageRangeStr:find("%-") then
        startPage, endPage = pageRangeStr:match("^(%d+)%s*%-%s*(%d+)$")
    else
        startPage = pageRangeStr:match("^(%d+)$")
        endPage = startPage
    end
    if startPage then
        startPage = tonumber(startPage)
        endPage = tonumber(endPage)
        return startPage, endPage
    else
        return nil, nil
    end
end

-- Helper: Check if two page ranges overlap
local function rangesOverlap(aStart, aEnd, bStart, bEnd)
    return aStart <= bEnd and bStart <= aEnd
end

function p.generateCitation(frame)
    local userInput = frame.args[1] or ""
    local pageNumbers = frame.args[2] or ""
    local itemNumber = nil
    local needsInput = false
    local category = "[[Category:Articles requiring Bahaidata input]]"

    -- Determine item number
    if mw.wikibase.isValidEntityId(userInput) then
        itemNumber = userInput
    else
        itemNumber = mw.wikibase.getEntityIdForTitle(userInput)
        if not itemNumber then
            local page = mw.title.new(userInput)
            if page then
                local rtarget = page.redirectTarget
                if rtarget then
                    itemNumber = mw.wikibase.getEntityIdForTitle(rtarget.fullText)
                end
            end
        end
    end

    if not itemNumber then
        return "''" .. userInput .. "''" .. (pageNumbers ~= "" and ", p." .. pageNumbers or "") .. " " .. category
    end

    -- Get entity and data
    local entity = mw.wikibase.getEntity(itemNumber)
    local titleValue = entity.claims['P47'] and entity.claims['P47'][1].mainsnak.datavalue.value.text or ""
    if titleValue == "" then
        return "''" .. userInput .. "''" .. (pageNumbers ~= "" and ", p." .. pageNumbers or "") .. " " .. category
    end

    local authors = getLabelsFromClaims(entity.claims['P10'])
    local editors = getLabelsFromClaims(entity.claims['P14'])
    local compilers = getLabelsFromClaims(entity.claims['P43'])
    local translators = getLabelsFromClaims(entity.claims['P32'])

    local authorValue = formatContributors(authors)
    local editorValue = formatContributors(editors)
    local compilerValue = formatContributors(compilers)
    local translatorValue = formatContributors(translators)

    local publicationDate = entity.claims['P29'] and mw.text.split(entity.claims['P29'][1].mainsnak.datavalue.value.time, '-')[1]:gsub('^%+', '') or ""
    local publisherValue = entity.claims['P26'] and mw.wikibase.getLabel(entity.claims['P26'][1].mainsnak.datavalue.value.id) or ""
    local countryValue = entity.claims['P48'] and mw.wikibase.getLabel(entity.claims['P48'][1].mainsnak.datavalue.value.id) or ""
    local isbn10Value = entity.claims['P31'] and entity.claims['P31'][1].mainsnak.datavalue.value or ""
    local isbn13Value = entity.claims['P49'] and entity.claims['P49'][1].mainsnak.datavalue.value or ""

    if authorValue == "" and compilerValue == "" and translatorValue == "" then
        needsInput = true
    end

    -- Page prefix logic
    local pagePrefix = "p."
    if pageNumbers:find(",") or pageNumbers:find("-") then
        pagePrefix = "pp."
    end

    -- Parse the page numbers passed in
    local citedStartPage, citedEndPage = parsePageRange(pageNumbers)
    if not citedStartPage then
        citedStartPage, citedEndPage = 1, math.huge  -- Default to all pages
    end

    -- Initialize variables for chapter data
    local chapterAuthorValue = ""
    local chapterTitleValue = ""
    local chapterTranslators = {}
    local chapterFound = false

    -- Check if the item has chapters (P59)
    if entity.claims['P59'] and citedStartPage then
        for _, chapterClaim in ipairs(entity.claims['P59']) do
            if chapterClaim.mainsnak and chapterClaim.mainsnak.datavalue then
                local chapterId = chapterClaim.mainsnak.datavalue.value.id
                local chapterEntity = mw.wikibase.getEntity(chapterId)
                if chapterEntity then
                    -- Get the chapter's pages (P6)
                    local chapterPagesValue = chapterEntity.claims['P6'] and chapterEntity.claims['P6'][1].mainsnak.datavalue.value or ""
                    if chapterPagesValue ~= "" then
                        local chapterStartPage, chapterEndPage = parsePageRange(chapterPagesValue)
                        if chapterStartPage and chapterEndPage then
                            -- Check if the cited pages overlap with chapter's pages
                            if rangesOverlap(citedStartPage, citedEndPage, chapterStartPage, chapterEndPage) then
                                -- We have found the chapter
                                chapterFound = true
                                -- Get chapter title from label
                                chapterTitleValue = mw.wikibase.getLabel(chapterId) or ""
                                -- Get chapter authors (P10)
                                local chapterAuthors = getLabelsFromClaims(chapterEntity.claims['P10'])
                                chapterAuthorValue = formatContributors(chapterAuthors)
                                -- Use the chapter's translators if available
                                chapterTranslators = getLabelsFromClaims(chapterEntity.claims['P32'])
                                -- Use the chapter's publication date if available
                                local chapterPublicationDate = chapterEntity.claims['P29'] and mw.text.split(chapterEntity.claims['P29'][1].mainsnak.datavalue.value.time, '-')[1]:gsub('^%+', '') or ""
                                if chapterPublicationDate ~= "" then
                                    publicationDate = chapterPublicationDate
                                end
                                break -- We found the matching chapter, exit the loop
                            end
                        end
                    end
                end
            end
        end
    end

    -- Build the citation
    local citation = ""

    if chapterFound then
        -- Chapter author
        if chapterAuthorValue ~= "" then
            citation = chapterAuthorValue
            if publicationDate ~= "" then
                citation = citation .. " (" .. publicationDate .. "). "
            else
                citation = citation .. ". "
            end
        elseif publicationDate ~= "" then
            citation = "(" .. publicationDate .. "). "
        end

        -- Chapter title
        if chapterTitleValue ~= "" then
            citation = citation .. "\"" .. chapterTitleValue .. ".\" "
        end

        -- 'In' main work
        citation = citation .. "In " .. "''" .. titleValue .. "''"

        -- Volume number (P50)
        local volumeNumber = entity.claims['P50'] and entity.claims['P50'][1].mainsnak.datavalue.value.amount or ""
        if volumeNumber ~= "" then
            citation = citation .. ", Vol. " .. volumeNumber
        end

        -- Secondary contributors (editors, compilers)
        if editorValue ~= "" then
            citation = citation .. ", edited by " .. editorValue
        elseif compilerValue ~= "" then
            citation = citation .. ", compiled by " .. compilerValue
        end

        -- Page numbers with prefix
        if pageNumbers ~= "" then
            citation = citation .. ", " .. pagePrefix .. " " .. pageNumbers
        end

        -- Location and publisher
        if countryValue ~= "" and publisherValue ~= "" then
            citation = citation .. ". " .. countryValue .. ": " .. publisherValue
        elseif publisherValue ~= "" then
            citation = citation .. ". " .. publisherValue
        end

        -- ISBN
        if isbn10Value ~= "" or isbn13Value ~= "" then
            citation = citation .. ". ISBN " .. (isbn10Value ~= "" and isbn10Value or isbn13Value)
        end

        -- Translators
        local combinedTranslators = formatContributors(chapterTranslators)
        if combinedTranslators ~= "" then
            citation = citation .. ". Translated by " .. combinedTranslators
        elseif translatorValue ~= "" then
            citation = citation .. ". Translated by " .. translatorValue
        end

        citation = citation .. "."

    else
        -- Existing logic when no chapter is found
        -- Primary contributor
        if authorValue ~= "" then
            citation = authorValue
            if publicationDate ~= "" then
                citation = citation .. " (" .. publicationDate .. "). "
            else
                citation = citation .. ". "
            end
        elseif compilerValue ~= "" then
            citation = compilerValue .. ", comp."
            if publicationDate ~= "" then
                citation = citation .. " (" .. publicationDate .. "). "
            else
                citation = citation .. ". "
            end
        elseif editorValue ~= "" then
            citation = editorValue .. ", ed."
            if publicationDate ~= "" then
                citation = citation .. " (" .. publicationDate .. "). "
            else
                citation = citation .. ". "
            end
        end

        -- Title
        citation = citation .. "''" .. titleValue .. "''"

        -- Secondary contributors
        if authorValue ~= "" then
            citation = citation .. formatSecondaryContributors(compilers, "comp.")
            citation = citation .. formatSecondaryContributors(editors, "ed.")
        end

        citation = citation .. formatSecondaryContributors(translators, "trans.")

        -- Location and publisher
        if countryValue ~= "" and publisherValue ~= "" then
            citation = citation .. ". " .. countryValue .. ": " .. publisherValue
        elseif publisherValue ~= "" then
            citation = citation .. ". " .. publisherValue
        end

        -- Fallback date if no author
        if publicationDate ~= "" and authorValue == "" then
            citation = citation .. ". " .. publicationDate
        end

        -- Page numbers with prefix
        if pageNumbers ~= "" then
            citation = citation .. ". " .. pagePrefix .. " " .. pageNumbers
        end

        -- ISBN
        if isbn10Value ~= "" or isbn13Value ~= "" then
            citation = citation .. ". ISBN " .. (isbn10Value ~= "" and isbn10Value or isbn13Value)
        end

        citation = citation .. "."
    end

    -- Add category if needed
    if needsInput then
        citation = citation .. " " .. category
    end

    return citation
end

return p
Retrieved from "https://bahaipedia.org/index.php?title=Module:Cite&oldid=143157"
This page was last edited on 9 June 2025, at 00:10.
Text is available under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License.
Privacy policy
About Bahaipedia
Disclaimers
Powered by MediaWiki