Module:Cite Print
Jump to navigation
Jump to search
This is the main module for the following templates:
local p = {}
local h = {}
local data = mw.loadData("Module:Cite Print/Data")
local Cite = require("Module:Cite")
local Franchise = require("Module:Franchise")
local utilsArg = require("Module:UtilsArg")
p.Templates = mw.loadData("Module:Cite Print/TemplateData")
local CAT_BOOK_QUOTES = "[[Category:Book Citations Using Quotes]]"
local CAT_INVALID_ARGS = "[[Category:"..require("Module:Constants/category/invalidArgs").."]]"
-- We encapsulate Module:Error so that it is only transcluded on pages that actually have errors
local function errFn(msg, warn)
local utilsError = require("Module:UtilsError")
return utilsError.error(msg, warn)
end
local function warn(msg)
local utilsError = require("Module:UtilsError")
utilsError.warn(msg)
end
function p.Book(frame)
local args, err = utilsArg.parse(frame:getParent().args, p.Templates["Cite Book"])
local categories = err and err.categoryText or ""
local citation, categories2 = h.printBookCitation(args)
return citation, categories..categories2
end
function h.printBookCitation(args)
local categories = ""
if args.quote then
categories = categories..CAT_BOOK_QUOTES
end
local bookTitle = args.book
if args.book and not h.hasItalics(args.book) then
local bookLink = Franchise.link(args.book)
if not bookLink then
warn(string.format("<code>%s</code> must be a code from [[Data:Franchise]] or else be written with italics.", bookTitle))
categories = categories..CAT_INVALID_ARGS
else
bookTitle = bookLink
end
end
local phraseLink = args.book and Franchise.phraseLink(args.book) -- for manga and comics and such
if phraseLink and phraseLink ~= "" then
local byAuthor = string.find(phraseLink, " by ")
if byAuthor then
phraseLink = phraseLink.sub(phraseLink, 1, byAuthor - 1) -- strip the "by <author>" part
end
bookTitle = phraseLink
end
if not bookTitle then
bookTitle = errFn("book title required", true)
categories = categories..CAT_INVALID_ARGS
end
local publisher
local localization
if args.book and args.lang then
local bookData = data.books[args.book] and data.books[args.book][args.lang]
if not bookData then
warn(string.format("No data exists for book <code>%s</code> in language <code>%s</code>. Consider adding the book to [[Module:Cite Print/Data]] or remove the <code>lang</code> parameter.", args.book, args.lang))
categories = categories..CAT_INVALID_ARGS
elseif not bookData.display then
publisher = bookData.publisher
localization = args.lang
else
bookTitle = string.format("''[[%s|%s]]''", Franchise.article(args.book) or bookData.display, bookData.display)
publisher = bookData.publisher
end
end
if not publisher then
publisher = args.publisher and p.getPublisherFromShortcut(args.publisher) or (args.book and Franchise.publisher(args.book))
end
if not publisher then -- if after all that we still didn't manage to get a publisher...
publisher = errFn("publisher required", true)
categories = categories..CAT_INVALID_ARGS
end
local source = args
source.title = bookTitle
source.publisher = publisher
source.localization = localization
local citation = h.printCitation(source, args.quote, args.character)
return citation, categories
end
-- Backwards compatibility for deprecated feature
function p.getPublisherFromShortcut(publisher)
local publishers = {
["enix"] = "Enix Corporation",
["nintendo"] = "Nintendo Co., Ltd.",
["piggyback"] = "Piggyback Interactive Limited",
["prima"] = "Prima Games",
["soleil"] = "Les Éditions Soleil",
["tokuma shoten"] = "Tokuma Shoten Publishing Co., Ltd.",
}
local fullName = publishers[string.lower(publisher)]
if fullName then
warn(string.format("Publisher shortcuts are a deprecated feature. Please enter the full publisher name <code>%s</code> instead of <code>%s</code>", fullName, publisher))
return fullName..CAT_INVALID_ARGS
else
return publisher
end
end
function p.Guide(frame)
local Guide = require("Module:Guide")
local args, err = utilsArg.parse(frame:getParent().args, p.Templates["Cite Guide"])
local categories = err and err.categoryText or ""
if args.quote then
categories = categories..CAT_BOOK_QUOTES
end
local guideArgs = {args.game, args.guide, "-"}
local guideTitle, guideCategories, guidePublisher = Guide.guide(guideArgs, "Guide", true)
categories = categories..guideCategories
if args.year or args.edition then
local editionYear = h.concat(", ", {args.edition, args.year})
guideTitle = guideTitle.." ("..editionYear..")"
end
local source = {
title = guideTitle,
publisher = guidePublisher,
page = args.page,
translation = args.translation,
romanization = args.romanization,
}
return h.printCitation(source, args.quote)..categories
end
function p.Magazine(frame)
local Magazine = require("Module:Magazine")
local args, err = utilsArg.parse(frame:getParent().args, p.Templates["Cite Magazine"])
local categories = err and err.categoryText or ""
if not args.magazine then
return errFn("Magazine name required")..categories
end
-- We use italics as the cue for a custom magazine name - otherwise the magazine must be one supported by [[Template:Magazine]]
if h.hasItalics(args.magazine) then
args.title = args.magazine
else
local err = utilsArg.enum(Magazine.enum(), args.magazine, "magazine")
if err then
categories = categories.."[["..err.category.."]]"
end
args.title = "''[["..args.magazine.."]]''"
if args.date then
args.date = string.format("[[%s (%s)|%s]]", args.magazine, args.date, args.date)
end
end
return h.printCitation(args, args.quote, args.interviewee, args.url)..categories
end
function p.Manual(frame)
local args, err = utilsArg.parse(frame:getParent().args, p.Templates["Cite Manual"])
local categories = err and err.categoryText or ""
if not args.game and not args.product then
categories = categories..CAT_INVALID_ARGS
return errFn("game required"), categories
end
if args.game then
local gameLink = Franchise.link(args.game)
if not gameLink then
warn(string.format("Invalid game <code>%s</code>. See [[Data:Franchise]] for supported games.", args.game))
categories = categories..CAT_INVALID_ARGS
else
args.title = gameLink
end
end
args.title = (args.title or args.game or args.product).." manual"
args.localization = args.lang
if args.version then
args.title = string.format("%s, %s version", args.title, args.version)
end
return h.printCitation(args, args.quote), categories
end
function h.printCitation(sourceData, quote, speaker, archive)
local source, sourceComponents = h.formatSourceComponents(sourceData)
local citation = Cite.printCitation({
quote = quote,
translation = sourceData.translation,
romanization = sourceData.romanization,
localization = sourceData.localization,
speaker = speaker,
source = source,
sourceComponents = sourceComponents,
})
if archive then
citation = string.format("%s ([%s archive])", citation, archive)
end
return citation
end
function h.formatSourceComponents(source)
local volume, issue, page = source.volume, source.issue, source.page
if volume then
volume = "vol. "..volume
end
if issue then
issue = "no. "..issue
end
if page then
page = "pg. "..page
else
page = "<sup>[[[:Category:Pages with Vague Citations|''which page?'']]]</sup>[[Category:Pages with Vague Citations]]"
end
local title = mw.getCurrentFrame():preprocess(source.title)
local titleVolumeIssue = h.concat(" ", {title, volume, issue})
local sourceComponents = {source.publisher, source.edition, source.date, page}
return titleVolumeIssue, sourceComponents
end
function h.concat(separator, items)
local strings = {}
for i = 1, table.maxn(items) do
if items[i] and items[i] ~= "" then
table.insert(strings, items[i])
end
end
return table.concat(strings, separator)
end
function h.hasItalics(str)
return string.find(str, "''.*''")
end
function p.Data()
-- Performance optimization; importing this at the top with the others adds processing time to Template:Cite
-- these dependencies are only needed on Module:Cite Print/Data/Documentation
local Language = require("Module:Language")
local utilsLayout = require("Module:UtilsLayout")
local utilsMarkup = require("Module:UtilsMarkup")
local utilsTable = require("Module:UtilsTable")
local tableRows = {}
for i, bookCode in ipairs(Franchise.enum({ includeNonfiction = true })) do
local bookData = data.books[bookCode]
if bookData then
table.insert(tableRows, {
{
content = string.format("<code>[[%s|%s]]</code>", Franchise.article(bookCode) or bookCode, bookCode),
rowspan = utilsTable.size(bookData) + 1,
styles = {
["text-align"] = "center",
},
},
})
for i, langCode in ipairs(Language.enum()) do
local bookLangData = bookData[langCode]
if bookLangData then
local source = h.printBookCitation({
book = bookCode,
lang = langCode,
page = 1,
})
local lect = Language.getLect(langCode)
table.insert(tableRows, {
lect.flags[1] .. " " .. lect.abbr,
source,
})
end
end
end
end
local booksTable = utilsLayout.table({
headers = {"Book", "Language", "Citation Source Sample"},
rows = tableRows,
sortable = {1, 2},
})
booksTable = utilsMarkup.heading(3, utilsMarkup.anchor("books", "Books in Other Languages"))..booksTable
return booksTable
end
function p.Schemas()
local Language = require("Module:Language")
return {
Data = {
type = "record",
required = true,
properties = {
{
name = "books",
required = true,
desc = "Associates a book code from [[Data:Franchise]] to information about the publication of the book in other languages. Used by [[Template:Cite Book]].",
type = "map",
keyPlaceholder = "bookCode",
keys = { type = "string" },
values = {
type = "map",
keyPlaceholder = "langCode",
keys = {
type = "string",
enum = Language.enum(),
desc = "A language code from [[Module:Language/Data]].",
},
values = {
type = "record",
properties = {
{
name = "display",
type = "string",
desc = "The subtitle of the book in the given language.",
},
{
name = "publisher",
required = true,
type = "string",
desc = "The book's publisher."
},
},
},
},
},
},
},
}
end
return p