Anonymous
Not logged in
Talk
Contributions
Log in
Request account
Rest of What I Know
Search
Editing
Module:HackerNewsUtil
From Rest of What I Know
Namespaces
Module
Discussion
More
More
Page actions
Read
Edit
History
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local p = {} local function trim(s) if type(s) ~= 'string' then return nil end return (s:gsub('^%s+', ''):gsub('%s+$', '')) end local function parse_from_url(url) if type(url) ~= 'string' then return {} end local host, id = url:match('^https?://([^/]+)/item%?id=(%d+)') if id then return { id = id, site = host } end return {} end -- Render plain text with paragraphs preserved. -- Two or more newlines => new <p>. Single newline => <br>. local function render_paragraph_text(parent, s) if type(s) ~= 'string' or s == '' then return end s = s:gsub('\r\n', '\n') local paras, i = {}, 1 while true do local a, b = s:find('\n\n+', i) if not a then table.insert(paras, s:sub(i)); break end table.insert(paras, s:sub(i, a - 1)) i = b + 1 end for _, para in ipairs(paras) do local pnode = parent:tag('p') local first = true for line in (para .. '\n'):gmatch('(.-)\n') do if not first then pnode:tag('br') end pnode:wikitext(mw.text.nowiki(line)) first = false end end end local function anchor_text(id, site) if id and site then return string.format('Permalink: HN β’ %s β’ %s', site, id) elseif id then return 'Permalink: HN β’ ' .. id else return 'Permalink' end end local function gen_refname(id, url) if id and id ~= '' then return 'hn-' .. id end return 'hn-' .. mw.hash.hashValue('md5', url or tostring(mw.title.getCurrentTitle())) end function p.render(frame) local args = frame:getParent() and frame:getParent().args or frame.args local url = trim(args.url) local siteArg = trim(args.site) local author = trim(args.author) local authorURL = trim(args.author_url) local title = trim(args.title) local text = trim(args.text) local dateHuman = trim(args.date) local dateISO = trim(args.datetime) or dateHuman local score = trim(args.score) local comments = trim(args.comments) local isComment = trim(args.comment) == 'yes' local refname = trim(args.refname) local noreference = (trim(args.noreference) == 'yes') or (trim(args.ref) == 'no') local parsed = parse_from_url(url or '') local id = parsed.id local site = siteArg or parsed.site or 'news.ycombinator.com' -- Fallback permalink if url omitted but id present if (not url or url == '') and id then url = 'https://news.ycombinator.com/item?id=' .. id end -- Auto author URL if not provided and single author if author and author ~= '' and (not authorURL or authorURL == '') and not author:find('|') then local enc = mw.uri.encode(author, 'QUERY') authorURL = 'https://news.ycombinator.com/user?id=' .. enc end local h = mw.html.create('div') :addClass('mw-hn') :cssText('border:1px solid #e2e8f0;border-radius:8px;padding:12px 14px;margin:8px 0;background:#fff;') -- Header with icon via CSS data-URI local header = h:tag('div'):addClass('mw-hn-header') :cssText('font-size:0.9em;color:#475569;margin-bottom:6px;display:flex;gap:8px;align-items:center;') header:tag('span') :addClass('mw-hn-logo') :attr('aria-hidden', 'true') :cssText('display:inline-block;width:18px;height:18px;background:#f60;color:#fff;text-align:center;line-height:18px;font-weight:bold;font-size:12px;font-family:Verdana,Geneva,sans-serif;position:relative;') :tag('span') :cssText('position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);') :wikitext('Y') header:tag('span'):wikitext('Hacker News') -- Title if title and title ~= '' then local titleDiv = h:tag('div') :addClass('mw-hn-title') :cssText('font-weight:600;margin:2px 0 6px 0;') if isComment then titleDiv:tag('span') :cssText('font-weight:normal;font-style:italic;') :wikitext('Comment on') titleDiv:wikitext(' ' .. title) else titleDiv:wikitext(title) end end -- Body text (optional) if text and text ~= '' then local bq = h:tag('blockquote') :addClass('mw-hn-text') :cssText('margin:6px 0 10px 0;padding:0 0 0 12px;border-left:3px solid #e2e8f0;color:#0f172a;') render_paragraph_text(bq, text) end -- Meta line local meta = h:tag('div'):addClass('mw-hn-meta') :cssText('font-size:0.85em;color:#475569;display:flex;flex-wrap:wrap;gap:8px;align-items:center;') local function addBullet() meta:tag('span'):wikitext('β’'):css('opacity','0.6') end local hasContent = false if author and author ~= '' then meta:wikitext(mw.text.nowiki(author)) hasContent = true end if dateHuman and dateHuman ~= '' then if hasContent then addBullet() end meta:tag('time'):attr('datetime', dateISO or ''):wikitext(dateHuman) hasContent = true end if score and score ~= '' then if hasContent then addBullet() end meta:wikitext(tostring(score) .. ' points') hasContent = true end if comments and comments ~= '' then if hasContent then addBullet() end meta:wikitext(tostring(comments) .. ' comments') hasContent = true end -- Footnote reference (permalink) if url and url ~= '' and not noreference then local name = refname or gen_refname(id, url) -- Build reference text with author if provided local ref_parts = {} if author and author ~= '' then local parts = mw.text.split(author, '%s*|%s*') local author_links = {} for i, authorName in ipairs(parts) do local authorUrl = authorURL if not authorUrl or authorUrl == '' or #parts > 1 then local enc = mw.uri.encode(authorName, 'QUERY') authorUrl = 'https://news.ycombinator.com/user?id=' .. enc end table.insert(author_links, string.format('[%s %s]', authorUrl, mw.text.nowiki(authorName))) end table.insert(ref_parts, table.concat(author_links, ', ')) table.insert(ref_parts, ' on ') end table.insert(ref_parts, string.format('[%s %s]', url, anchor_text(id, site))) local text_ref = table.concat(ref_parts, '') local ref_markup = frame:extensionTag('ref', text_ref, { name = name }) meta:wikitext(' ' .. ref_markup) end return tostring(h) end return p
Summary:
Please note that all contributions to Rest of What I Know are considered to be released under the Creative Commons Attribution-ShareAlike (see
Rest of What I Know:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:HackerNewsUtil/doc
(
view source
)
Navigation
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Wiki tools
Wiki tools
Special pages
Page tools
Page tools
User page tools
More
What links here
Related changes
Page information
Page logs