Module:Magenta message: Difference between revisions

From PickiPedia: A knowledge base of bluegrass, old time psychedelic jams, and other public domain music
Jump to navigationJump to search
Re (talk | contribs)
Magenta message: add whenInline helper (keep the full-date when for the card) (via update-page on MediaWiki MCP Server)
Re (talk | contribs)
Magenta message: inline mode — compact link built from id, who/at/mood as decoration (via update-page on MediaWiki MCP Server)
 
(One intermediate revision by the same user not shown)
Line 42: Line 42:
end
end
return table.concat(lines, '<br>')
return table.concat(lines, '<br>')
end
local function when(at)
if at == '' then return '' end
local ok, shown = pcall(function()
return mw.getContentLanguage():formatDate('j M Y, H:i', at, false) .. ' UTC'
end)
return ok and shown or at
end
end


Line 48: Line 56:
if at == '' then return '' end
if at == '' then return '' end
local ok, shown = pcall(function()
local ok, shown = pcall(function()
return mw.getContentLanguage():formatDate('j M Y, H:i', at, false) .. ' UTC'
return mw.getContentLanguage():formatDate('H:i', at, false) .. 'Z'
end)
end)
return ok and shown or at
return ok and shown or at
Line 62: Line 70:
local who, user, mood = arg(args, 'who'), arg(args, 'user'), arg(args, 'mood')
local who, user, mood = arg(args, 'who'), arg(args, 'user'), arg(args, 'mood')
local block, at = arg(args, 'block'), arg(args, 'at')
local block, at = arg(args, 'block'), arg(args, 'at')
local here = MAGENTA .. '/messages/' .. id
-- Inline: one compact link built from the id alone -- "justin, 15:45Z in #docs-tests-qa".
-- who, at and mood are decoration; the link works with none of them set.
if arg(args, 'inline') ~= '' then
local parts = {}
if who ~= '' then table.insert(parts, who) end
if at ~= '' then table.insert(parts, whenInline(at)) end
local label = table.concat(parts, ', ')
if mood ~= '' then
label = label ~= '' and (label .. ' in #' .. mood) or ('#' .. mood)
end
if label == '' then label = id end
return '[' .. here .. ' ' .. label .. ']'
end
local text = mw.text.trim(mw.text.decode(args.text or '', true))
local text = mw.text.trim(mw.text.decode(args.text or '', true))
local shown, cut = trimmed(text, arg(args, 'chars'))
local shown, cut = trimmed(text, arg(args, 'chars'))
local here = MAGENTA .. '/messages/' .. id


local head = {}
local head = {}

Latest revision as of 17:58, 3 November 2026

Documentation for this module may be created at Module:Magenta message/doc

-- A magenta message, shown on PickiPedia as a card: who said it, where (its Mood), when (its date and
-- its Ethereum block), and its words -- as many characters as `chars` asks (280 unless told; "all" for
-- every one) -- with a link to the message in its Mood. Used by [[Template:Magenta message]].
-- With inline=yes it instead draws one compact inline link -- "justin, 15:45Z in #docs-tests-qa" --
-- built from the id alone (who, at and mood are decoration), for citing a message in running prose.
--
-- The words travel inside the template call, written there by magenta with every character that wikitext
-- would read as markup turned into an entity (& < > { } | [ ] ~), so a message's own pipes, braces and
-- tildes can't break the call. They are decoded here and shown exactly as said: nothing in them is a link,
-- a template or a heading. (magenta: memory-lane conversations/services/wiki_embed.py writes the call.)

local p = {}

local MAGENTA = 'https://magenta.cryptograss.live'
local DEFAULT_CHARS = 280

local function arg(args, name)
	local v = args[name]
	if v == nil then return '' end
	return mw.text.trim(v)
end

-- The words cut to `chars` characters, at a word's end where one is near, with an ellipsis; and whether cut.
local function trimmed(text, chars)
	if chars == 'all' then return text, false end
	local n = tonumber(chars) or DEFAULT_CHARS
	if n < 1 or mw.ustring.len(text) <= n then return text, false end
	local cut = mw.ustring.sub(text, 1, n)
	local lastSpace = mw.ustring.find(cut, '%s%S*$')
	if lastSpace and lastSpace > n * 0.6 then
		cut = mw.ustring.sub(cut, 1, lastSpace - 1)
	end
	cut = mw.ustring.gsub(cut, '[%s%p]+$', '')
	return cut .. '…', true
end

-- Exactly as said: escaped, line breaks kept.
local function literal(text)
	local lines = {}
	for line in mw.text.gsplit(text, '\n', true) do
		table.insert(lines, mw.text.nowiki(line))
	end
	return table.concat(lines, '<br>')
end

local function when(at)
	if at == '' then return '' end
	local ok, shown = pcall(function()
		return mw.getContentLanguage():formatDate('j M Y, H:i', at, false) .. ' UTC'
	end)
	return ok and shown or at
end

-- Compact time for the inline mode: 15:45Z.
local function whenInline(at)
	if at == '' then return '' end
	local ok, shown = pcall(function()
		return mw.getContentLanguage():formatDate('H:i', at, false) .. 'Z'
	end)
	return ok and shown or at
end

function p.card(frame)
	local args = frame:getParent().args
	local id = arg(args, 'id')
	if id == '' then id = arg(args, 1) end
	if not id:match('^%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x$') then
		return '<strong class="error">Magenta message: id= wants a message id (the part after #m- in its link)</strong>'
	end
	local who, user, mood = arg(args, 'who'), arg(args, 'user'), arg(args, 'mood')
	local block, at = arg(args, 'block'), arg(args, 'at')
	local here = MAGENTA .. '/messages/' .. id

	-- Inline: one compact link built from the id alone -- "justin, 15:45Z in #docs-tests-qa".
	-- who, at and mood are decoration; the link works with none of them set.
	if arg(args, 'inline') ~= '' then
		local parts = {}
		if who ~= '' then table.insert(parts, who) end
		if at ~= '' then table.insert(parts, whenInline(at)) end
		local label = table.concat(parts, ', ')
		if mood ~= '' then
			label = label ~= '' and (label .. ' in #' .. mood) or ('#' .. mood)
		end
		if label == '' then label = id end
		return '[' .. here .. ' ' .. label .. ']'
	end

	local text = mw.text.trim(mw.text.decode(args.text or '', true))
	local shown, cut = trimmed(text, arg(args, 'chars'))

	local head = {}
	if who ~= '' then
		table.insert(head, user ~= '' and ('[[User:' .. user .. '|' .. who .. ']]') or ("'''" .. who .. "'''"))
	end
	if mood ~= '' then
		table.insert(head, '[' .. MAGENTA .. '/moods/' .. mood .. '/ #' .. mood .. ']')
	end
	if at ~= '' then
		table.insert(head, '[' .. here .. ' ' .. when(at) .. ']')
	end
	if block:match('^%d+$') then
		table.insert(head, '[https://etherscan.io/block/' .. block .. ' block '
			.. mw.getContentLanguage():formatNum(tonumber(block)) .. ']')
	end

	local box = mw.html.create('div')
		:addClass('magenta-message')
		:attr('data-message', id)
		:css({
			['border-left'] = '3px solid #d6249f',
			['border-radius'] = '4px',
			['background'] = 'rgba(214, 36, 159, 0.06)',
			['padding'] = '6px 12px',
			['margin'] = '8px 0',
		})
	box:tag('div')
		:addClass('magenta-message-head')
		:css({ ['font-size'] = '85%', ['opacity'] = '0.8' })
		:wikitext(table.concat(head, ' · '))
	box:tag('div')
		:addClass('magenta-message-words')
		:css({ ['margin'] = '4px 0 2px' })
		:wikitext(shown ~= '' and literal(shown) or "''(no words)''")
	box:tag('div')
		:css({ ['font-size'] = '85%' })
		:wikitext('[' .. here .. ' ' .. (cut and 'the rest, in the Mood ↗' or 'in the Mood ↗') .. ']')
	return tostring(box)
end

return p