(Matching how quotebox looks with quote) |
(Adds debug string for quotebox) |
||
Line 144: | Line 144: | ||
addQuoteMarks = false |
addQuoteMarks = false |
||
return Quote.quote(frame) |
return Quote.quote(frame) |
||
+ | .. '<br />Source:' .. tostring(mw.html.create('pre'):wikitext(mw.text.nowiki(buildStr))) |
||
end |
end |
||
Revision as of 06:28, 8 April 2021
This module attempts to abide by the dev:Quotes customization guidelines seen here: https://dev.fandom.com/wiki/Global_Lua_Modules/Quote but with some major changes.
- The "align" parameter instead refers to text-alignment while "float" replaces the old "align" parameter.
- This module currently works with no custom stylesheets. Instead, quote marks are programmatically added by the module. The quotemarks class is:
pull-quote__qmarks
To disable the module itself from adding the quotes, use the following invocation:
{{#invoke:Quote|quotebox}}
Sample output: Lua error in mw.text.lua at line 129: bad argument #1 to 'gsub' (string expected, got nil).
The default invocation below auto-adds the quote marks at the beginning and end of the quote:
{{#invoke:Quote|quote}}
Sample output:
“ Type in text without quote marks here. (Second line of text will appear as such with all spaces preserved.)”
― Name
Note: The dialog module is dependent on this module.
CSS
Check the Dev:Quote module documentation for the latest stylesheet sample. A version of the stylesheet captured upon development of this module is shown below for reference:
:root { --pull-quote-max-width: 80%; --pull-quote-text-color: rgba(0, 0, 0, .8); --pull-quote-mark-color: rgba(0, 0, 0, .15); --pull-quote-mark-font: "Times New Roman", serif; --pull-quote-hyphens: auto; --pull-quote-frame-color: #bbb; } /* .WikiaPage added as a parent selector to the following in order to override default blockquote styles. */ .WikiaPage .pull-quote { display: flex; flex-wrap: wrap; max-width: var(--pull-quote-max-width); margin: 1em auto; font-size: 1em; line-height: 1.8; } .WikiaPage .pull-quote__text { flex-basis: 100%; position: relative; padding: 0 2em; hyphens: var(--pull-quote-hyphens); color: var(--pull-quote-text-color); } .WikiaPage .pull-quote__text::before, .WikiaPage .pull-quote__text::after { position: absolute; font-size: 3em; font-family: var(--pull-quote-mark-font); font-weight: 700; color: var(--pull-quote-mark-color); } .WikiaPage .pull-quote__text::before { content: "“"; top: 0; left: 0; line-height: 1; } .WikiaPage .pull-quote__text::after { content: "”"; bottom: 0; right: 0; line-height: 0.2; } .WikiaPage .pull-quote__source { margin-left: auto; } .WikiaPage .pull-quote__source::before { content: "—"; } .WikiaPage .pull-quote--right, .WikiaPage .pull-quote--left { border: 1px solid var(--pull-quote-frame-color); border-left: 0; border-right: 0; padding: 1em 0; text-align: justify; } .WikiaPage .pull-quote--right { float: right; margin: 1em 0 1em 2em; } .WikiaPage .pull-quote--left { float: left; margin: 1em 2em 1em 0; }
-- this module implements {{quote}}
-- follows customization guidelines of Dev:Quote
local Quote = {}
-- this module can add actual quote marks instead of relying on CSS styling
local addQuoteMarks = true
local isDialog = false
local tracking, preview
local function trim(s)
return mw.ustring.gsub(mw.ustring.gsub(s, '%s+', ' '), '^%s*(.-)%s*$', '%1')
end
local function convertNewLines(s)
return mw.ustring.gsub(mw.ustring.gsub(s, '^\n*(.-)\n*$', '%1'), '\n', '<br />')
end
local function checkArg(k,v)
local validArgs = {
'Quote', 'quotetext', 'quote', 'text',
'Name', 'name', 'person', 'speaker', 'personquoted', 'context',
'Source', 'source', 'quotesource',
'class', 'style', 'align', 'width', 'quotewidth', 'float', 'fstyle'
}
if isDialog == true then
validArgs = {
'description', 'context',
'source',
'class', 'style', 'align', 'width', 'float', 'pstyle', 'lstyle', 'fstyle'
}
end
if k and type(k) == 'string' then
if k:match('^speaker%d+$') then
hasSpeaker = true
return true
end
local lookup = {}
for k, v in ipairs(validArgs) do
lookup[v] = true
end
if lookup[k] or k:match('^%d+$') then
return true
else
local vlen = mw.ustring.len(k)
k = mw.ustring.sub(k, 1, (vlen < 25) and vlen or 25)
k = mw.ustring.gsub(k, '[^%w\-_ ]', '?')
table.insert(tracking, '[[Category:Pages using ' .. (isDialog and 'dialog' or 'quote') .. ' with unknown parameters|' .. k .. ']]')
table.insert(preview, '"' .. k .. '"')
end
else
if k and type(k) == 'number' then
return true
end
end
return false
end
local function build(quoteContents, context, source, options)
local quoteSource
if context ~= '' then
local quoteStr
if source ~= '' then
quoteStr = '― ' .. context .. tostring(mw.html.create('sup')
:css('white-space', 'nowrap')
:css('margin-left', '2px')
:wikitext('[[' .. source .. '|[src]]]'))
else
quoteStr = '― ' .. context
end
quoteSource = mw.html.create('cite')
:addClass('pull-quote__source')
:css('line-height', '1')
:wikitext(quoteStr)
end
local quoteContainer = mw.html.create('blockquote')
:addClass('pull-quote')
:addClass(options.align)
:addClass(options.extraclasses)
:css(options.styles)
:css('text-align', options.textAlign)
:cssText(options.extrastyles)
if not addQuoteMarks then
quoteContainer:node(quoteContents)
if quoteSource then
quoteContainer:node(quoteSource)
end
else
quoteContainer:wikitext([[
{| style= "border-spacing: 0; "
|-
| style= "vertical-align: top; margin: 0; padding: 0; " |]] ..
tostring(mw.html.create('span')
:addClass('pull-quote__qmarks')
:css('font-family', "'Times New Roman', serif")
:css('padding-right', '2px')
:wikitext('“')) .. [[
| style= "width: 100%; " |]] .. tostring(quoteContents) .. (quoteSource and ([[
|-
| colspan= "2" style= "line-height: 1; " |]] ..
tostring(quoteSource)) or '') .. [[
|}]])
end
return tostring(quoteContainer)
end
local function options(args)
local options = {}
options.styles = {}
options.extraclasses = args.class
options.extrastyles = args.style
options.align = ''
local float = args.float
if float then
options.align = 'pull-quote--' .. float
options.styles['width'] = args.width or
args.quotewidth or
'300px'
options.styles['float'] = float
if args.fstyle then
options.extrastyles = (options.extrastyles or '') .. ';' .. args.fstyle
end
end
if string.lower(trim(args.align or '')) == 'center' then
options.textAlign = 'center'
else
if string.lower(trim(args.align or '')) == 'right' then
options.textAlign = 'right'
else
options.textAlign = nil
end
end
return options
end
function Quote.quotebox(frame)
addQuoteMarks = false
return Quote.quote(frame)
.. '<br />Source:' .. tostring(mw.html.create('pre'):wikitext(mw.text.nowiki(buildStr)))
end
function Quote.quote(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
local origArgs = (type(frame.getParent) == 'function') and frame:getParent().args or frame
local args = {}
tracking, preview = {}, {}
for k, v in pairs(origArgs) do
if checkArg(k,v) == true then
args[k] = v
end
end
local options = options(args)
local origText = convertNewLines(args[1] or
args.quotetext or
args.quote or
args.Quote or
args.text or '')
local quoteText = (origText ~= '' and origText or [[Type in text without quote marks here.
(Second line of text will appear as such with all spaces preserved.)]])
local person = trim(args[2] or
args.name or
args.Name or
args.person or
args.speaker or
args.personquoted or '')
if person == '' then
if origText == '' then
person = 'Name'
end
end
local source = trim(args[3] or
args.source or
args.Source or
args.quotesource or '')
local quoteContents = mw.html.create('p')
:addClass('pull-quote__text')
:css('white-space', 'pre-wrap')
:css('margin', '0')
:css('padding', '0')
if addQuoteMarks then
if options.textAlign == 'center' then
quoteContents:tag('span')
:addClass('pull-quote__qmarks')
:css('font-family', "'Times New Roman', serif")
:css('padding-right', '2px')
:wikitext('“')
:done()
addQuoteMarks = false
end
quoteContents:wikitext(quoteText):tag('span')
:css('font-family', "'Times New Roman', serif")
:css('white-space', 'nowrap')
:css('padding-left', '2px')
:wikitext('”')
else
quoteContents:wikitext(quoteText)
end
local buildStr = build(quoteContents, person, source, options)
local trackStr = (#tracking > 0) and table.concat(tracking, '') or ''
if #preview > 0 and frame:preprocess( "{{REVISIONID}}" ) == "" then
local hatnote = require('Dev:Hatnote')
trackStr = hatnote.makeWikitextError('Unknown parameters: ' .. table.concat(preview, '; '))
end
return buildStr .. trackStr
-- .. '<br />Source:' .. tostring(mw.html.create('pre'):wikitext(mw.text.nowiki(buildStr)))
end
function Quote.dialog(frame)
isDialog = true
addQuoteMarks = false
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
local origArgs = (type(frame.getParent) == 'function') and frame:getParent().args or frame
local args, dialog, speakers = {}, {}, {}
tracking, preview = {}, {}
for k, v in pairs(origArgs) do
if checkArg(k,v) == true then
args[k] = v
end
end
local options = options(args)
local block = mw.html.create('div')
:addClass('pull-quote__text')
:tag('div')
:cssText('display: block; white-space: pre-wrap; margin: 0; padding: 0; ')
local lineCount = #args
if hasSpeaker == true then
for i = 1, lineCount do
local speaker = trim(args['speaker' .. i] or '')
if speaker ~= '' then
speaker = tostring(mw.html.create('strong')
:addClass('pull-quote__speaker')
:cssText('text-align: left; ' .. (args.pstyle or ''))
:wikitext(speaker .. ':'))
table.insert(speakers, speaker)
end
end
local speakerCount, j = #speakers, 1
for i = 1, lineCount do
local line = convertNewLines(args[i] or '')
if line ~= '' then
local speaker = speakers[j] or ''
line = mw.html.create('span')
:addClass('pull-quote__line')
:cssText('text-align: left; ' .. (args.lstyle or ''))
:wikitext(speaker .. ' ' .. (line ~= '' and string.format("''%s''", line) or ''))
table.insert(dialog, tostring(line))
j = (j % speakerCount) + 1
end
end
else
lineCount = math.ceil(lineCount / 2)
for i = 1, lineCount do
local speaker = trim(args[i * 2 - 1] or '')
local line = convertNewLines(args[i * 2] or '')
line = (line ~= '' and string.format("''%s''", line) or '')
if speaker ~= '' then
speaker = tostring(mw.html.create('strong')
:addClass('pull-quote__speaker')
:cssText('text-align: left; ' .. (args.pstyle or ''))
:wikitext(speaker .. ':'))
line = speaker .. ' ' .. line
end
table.insert(dialog, tostring(mw.html.create('span')
:addClass('pull-quote__line')
:cssText('text-align: left; ' .. (args.lstyle or ''))
:wikitext(line)))
end
end
local context = args.description or args.context
if #dialog == 0 then
table.insert(dialog, tostring(mw.html.create('span')
:addClass('pull-quote__line')
:cssText('text-align: left; ' .. (args.lstyle or ''))
:tag('strong')
:addClass('pull-quote__speaker')
:cssText('text-align: left; ' .. (args.pstyle or ''))
:wikitext('{{{speaker1}}}:')
:done()
:wikitext(" ''{{{1}}}''")))
table.insert(dialog, tostring(mw.html.create('span')
:addClass('pull-quote__line')
:cssText('text-align: left; ' .. (args.lstyle or ''))
:tag('strong')
:addClass('pull-quote__speaker')
:cssText('text-align: left; ' .. (args.pstyle or ''))
:wikitext('{{{speaker2}}}:')
:done()
:wikitext(" ''{{{2}}}''")))
if not context then
context = 'describe the context of the dialog'
end
end
local source = trim(args.source or '')
local dialogContents = block:wikitext(table.concat(dialog, '<br />'))
local buildStr = build(dialogContents, context, source, options)
local trackStr = (#tracking > 0) and table.concat(tracking, '') or ''
if #preview > 0 and frame:preprocess( "{{REVISIONID}}" ) == "" then
local hatnote = require('Dev:Hatnote')
trackStr = hatnote.makeWikitextError('Unknown parameters: ' .. table.concat(preview, '; '))
end
return buildStr .. trackStr
-- .. '<br />Source:' .. tostring(mw.html.create('pre'):wikitext(mw.text.nowiki(buildStr)))
end
return Quote