Module:NYCS header

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search

local getArgs = require('Module:Arguments').getArgs
local p = {}

-- Helper: normalize the |bullets= parameter
local function makeBullets(frame, val)
	-- Nothing passed
	if not val or val == '' then
		return ''
	end

	-- If user already passed a template, leave it alone
	-- e.g. "{{NYCS Brighton|time=bullets}}"
	if val:find('{{', 1, true) then
		return val
	end

	-- Otherwise, wrap as {{NYCS [val]|time=bullets}}
	return frame:expandTemplate{
		title = 'NYCS ' .. val,
		args  = { time = 'bullets' }
	}
end

function p.main(frame)
  -- ===== ARGUMENTS =====
  local args = getArgs(frame, { parentOnly = true })

  local name        = args.name or mw.title.getCurrentTitle().text
  local bullets_raw = args.bullets
  local bullets     = makeBullets(frame, bullets_raw)
  local size        = tonumber(args.size) or 1

  -- ===== TUNABLE DEFAULTS =====
  -- Typography & spacing
  local title_pct     = tonumber(args.title_pct)     or 132  -- title size (% of base)
  local pad_em        = tonumber(args.pad_em)        or 0.38 -- single left gutter (em)
  local right_em      = tonumber(args.right_em)      or 0.70 -- right breathing room (em)
  -- Bar at top
  local bar_white_px  = tonumber(args.bar_white_px)  or 2    -- white rule thickness (px)
  local bar_cap_px    = tonumber(args.bar_cap_px)    or 11   -- black space above the rule (px)
  -- Bullets
  local bullet_scale  = tonumber(args.bullet_scale)  or 1.12 -- visual scale factor for images
  local bullet_gap_em = tonumber(args.bullet_gap_em) or 0.25 -- spacing between title & bullets (em)
  -- ===========================================

  -- ===== COMPUTED VALUES =====
  local nameFont   = (title_pct * size) .. '%'
  local leftPadEm  = (pad_em * size) .. 'em'
  local rightPadEm = (right_em * size) .. 'em'
  local whitePx    = math.max(1, math.floor(bar_white_px * size + 0.5)) .. 'px'
  local capPx      = math.max(0, math.floor(bar_cap_px   * size + 0.5)) .. 'px'

  -- ===== OUTER CONTAINER =====
  local outer = mw.html.create('div')
    :css({
      ['display']          = 'flex',
      ['flex-direction']   = 'column',
      ['background-color'] = 'black',
      ['color']            = 'white',
      ['font-family']      = 'Helvetica, Arial, sans-serif',
      ['text-align']       = 'left',
      ['line-height']      = '1.1',
      ['box-sizing']       = 'border-box',
      ['width']            = '100%',
      ['margin']           = '0',
      ['padding']          = '0',
      ['overflow']         = 'visible'
    })

  -- ===== TOP BLACK CAP =====
  outer:tag('div')
    :css({
      ['flex']             = '0 0 ' .. capPx,
      ['height']           = capPx,
      ['background-color'] = 'black'
    })

  -- ===== WHITE RULE =====
  outer:tag('div')
    :css({
      ['flex']             = '0 0 ' .. whitePx,
      ['height']           = whitePx,
      ['background-color'] = 'white'
    })

  -- ===== CONTENT AREA =====
  local content = outer:tag('div')
    :css({
      ['padding-top']    = '0.08em',  -- gap between the white rule and the title
      ['padding-bottom'] = '0.24em',  -- overall space below the bullets
      ['padding-right']  = rightPadEm,
      ['padding-left']   = '0',       -- left gutter is applied once below
      ['box-sizing']     = 'border-box',
      ['margin']         = '0'
    })

  -- ===== LEFT GUTTER WRAPPER =====
  local padded = content:tag('div')
    :css({
      ['padding-left'] = leftPadEm,
      ['margin']       = '0'
    })

  -- ===== TITLE ROW =====
  padded:tag('div')
    :css({ ['margin'] = '0', ['padding'] = '0' })
    :tag('span')
      :css({
        ['font-size']   = nameFont,
        ['font-weight'] = 'bold'
      })
      :wikitext(name)

  -- ===== BULLETS: WRAPPER (SPACING CONTROL) =====
  local bulletWrapper = padded:tag('div')
    :css({
      ['margin-top']  = bullet_gap_em .. 'em', -- distance below title
      ['display']     = 'inline-block',
      ['line-height'] = '1',
      ['padding']     = '0',
      ['margin']      = '0'
    })

  -- ===== BULLETS: INNER (SCALED) =====
  bulletWrapper:tag('div')
    :css({
      ['display']          = 'inline-block',
      ['transform']        = 'scale(' .. string.format('%.3f', bullet_scale) .. ')',
      ['transform-origin'] = 'left top',
      ['line-height']      = '1',
      ['min-height']       = '1.0em',
      ['margin']           = '0',
      ['padding']          = '0'
    })
    :wikitext(bullets)

  -- ===== OUTPUT =====
  return tostring(outer)
end

return p