Modul:Hms/sandbox
Dokumentaciju za ovaj modul možete napraviti na stranici Modul:Hms/sandbox/dok
--[[ Template:Duration implemented by Module:Hms
Adds microformat markup to a time duration. Converts >60 seconds and minutes to minutes and hours.
Any part (h/m/s) of the timestamp can be omitted, that won't be part of the output with a default 0. Except if minutes are omitted between hours and seconds, that will be shown with a default of 0.
Syntax:
{{Duration | [<hours>] | [<minutes>] | [<seconds>] }}
{{Duration [|h=<hours> ][ |m=<minutes>] [ |s=<seconds> ] }}
{{Duration | <hh:mm:ss.sss> }}
{{Duration |duration=<hh:mm:ss.sss> }}
* |1:2:3 ---> "1:02:03" (hours:minutes:seconds)
* |duration=1:2:3 ---> "1:02:03" (hours:minutes:seconds)
* |1|2|3 ---> "1:02:03" (hours:minutes:seconds)
* |h=1|m=2|s=3 ---> "1:02:03" (hours:minutes:seconds)
* |2:3 ---> "2:03" (minutes:seconds)
* |duration=2:3 ---> "2:03" (minutes:seconds)
* |1|2 ---> "1:02" (hours:minutes)
* ||2|3 ---> "2:03" (minutes:seconds)
* |1||3 ---> "1:00:03" (hours:minutes:seconds)
* |h=1|m=2 ---> "1:02" (hours:minutes)
* |m=2|s=3 ---> "2:03" (minutes:seconds)
* |h=1|s=3 ---> "1:00:03" (hours:minutes:seconds)
* |1 ---> "1 hours"
* ||2 ---> "2 minutes"
* |||3 ---> "3 seconds"
* |h=1 ---> "1 hours"
* |m=2 ---> "2 minutes"
* |s=3 ---> "3 seconds"
Printing units "h m s" and "H hours MM minutes SS seconds":
{{Duration <...> [ |units={letters/words/none} ] [ |sep=:] }}
* |1|2|3|units=none (default) ---> "1:02:03"
* |1|2|3|units=letters ---> "1h 2m 3s" (hours:minutes:seconds)
* |1|2|3|units=words ---> "1 hours 2 minutes 3 seconds"
* |1|2|3|units=letters ---> "1h 2m 3s"
* |1|2|3|units=words ---> "1 hours 2 minutes 3 seconds"
* |1|2|units=letters ---> "1h 2m" (hours:minutes)
* ||2|3|units=letters ---> "2m 3s" (minutes:seconds)
* |1|units=letters ---> "1h"
* ||2|units=letters ---> "2m"
* |||3|units=letters ---> "3s"
* |h=1|m=2|s=3|units=letters ---> "1h 2m 3s"
* |h=1|m=2|s=3|units=words ---> "1 hours 2 minutes 3 seconds"
* |h=1|m=2|units=letters ---> "1h 2m" (hours:minutes)
* |m=2|s=3|units=letters ---> "2m 3s" (minutes:seconds)
* |h=1|units=letters ---> "1h"
* |m=2|units=letters ---> "2m"
* |s=3|units=letters ---> "3s"
Separator:
* |1|2|3|sep=. ---> "1.02.03"
* |1|2|3|sep=: (default) ---> "1:02:03"
* |1|2|3|sep=,|units=letters ---> "1h,2m,3s"
* |1|2|3|sep=, |units=letters ---> "1h, 2m, 3s"
* |1|2|3|sep=,|units=words ---> "1 hours,2 minutes,3 seconds"
* |1|2|3|sep=, |units=words ---> "1 hours, 2 minutes, 3 seconds"
* |1|2|3|sep=:|units=letters ---> "1h:2m:3s" (not the default when units is set)
* |1|2|3|sep=.|units=letters ---> "1h.2m.3s"
In templates:
{{#invoke:hms|main|<..args from above>}}
--]]
-- Localization, ad-hoc
local Locale = {
en = { -- default translations
hours = { 'hour','hours' },
minutes = { 'minute','minutes' },
seconds = { 'second','seconds' },
h = 'h',
m = 'm',
s = 's',
},
bs = {
hours = { 'sat','sata','sati' },
minutes = { 'minuta','minute','minuta' },
seconds = { 'sekunda','sekunde','sekundi' },
},
}
Locale._def = Locale.en
-- Get language object
local lang = mw.language.getContentLanguage()
-- Get translation with language code
local L = Locale[ lang:getCode() ] or Locale._def -- default to English
-- Inherit the default translations
if L ~= Locale._def then setmetatable( L, { __index = Locale._def } ) end
-- Html entities used
local entity = {
nbsp = ' ',
-- Use ' ' to ALLOW line-break in the printed duration
--sepSpace = ' ',
-- Use ' ' to AVOID line-break in the printed duration
sepSpace = ' ',
}
local p = {} -- Module object
local units = {
none = { '', '', '' },
letters = { L.h, L.m, L.s },
words = { L.hours, L.minutes, L.seconds }
}
local function transfer(dur, from)
if not dur[from] or dur[from] < 60 then return end
if dur[from-1] then
return p._error('Value of '..units.words[from][2]..' ('..dur[from]..') must be less than 60 if '..units.words[from-1][2]..' ('..dur[from-1]..') are specified.')
else
dur[from-1] = math.floor( dur[from]/60 )
dur[from] = dur[from] - dur[from-1]*60
end
end
local function zeroPad(dur, i, unitsArg)
-- Zero padding if units are not output
if unitsArg == units.none and dur[i-1] and dur[i] and dur[i] < 10 then return '0'..dur[i] end
return dur[i]
end
function p._error( error_str )
return '[[Category:Duration with input error]]<strong class="error">{{Duration|...}} parameter error: ' .. error_str .. '</strong>'
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {wrappers = {'Template:Duration', 'Template:Duration/sandbox'}})
local dur = {}
local argsUsed, err
-- Show units as letters/words/none
local unitsArg = units[args.units]
if args.units and not unitsArg then p._error('Parameter "|units='..args.units..'" is unknown, use "letters/words".') end
-- Duration parameters
if tonumber(args[1]) or args[2] or args[3] then
-- "|1|2|3"
if args[4] then return p._error('Parameter number 4 ("'..args[4]..'") should not be specified') end
argsUsed = args
elseif args.h or args.m or args.s then
-- "|h=1|m=2|s=3"
argsUsed = { args.h, args.m, args.s }
else
-- "|duration=<hh:mm:ss.sss>"
local duration = args.duration or args[1] or ''
if duration == '' then return p._error('Parameter 1 or duration is empty, should be MM:SS or HH:MM:SS') end
-- If there is already a microformat, don't do anything
if mw.ustring.find(duration, 'class="duration"', 1, true) then return duration end
-- Match hh:mm:ss.sss, split into table
argsUsed = mw.text.split( mw.ustring.match(duration, '%d*:?%d+:%d+%.?%d*') or '', ':' )
-- Did not match at all?
if not argsUsed[1] then return duration ..' [[Category:Duration without hAudio microformat]]' end
-- Insert hour value if missing
if not argsUsed[3] then table.insert(argsUsed, 1, nil) end
end
-- Parse parameters i=1-3
for i = 1,3 do if argsUsed[i] then
dur[i] = tonumber(argsUsed[i])
if not dur[i] then return p._error('Parameter '..i..' ("'..argsUsed[i]..'") must be a number') end
end end -- for if
-- Zero duration -> output nothing
if ( (dur[1] or 0) + (dur[2] or 0) + (dur[3] or 0) ) == 0 then return nil end
-- Check hours and minutes are integers
if dur[1] and dur[1] ~= math.ceil(dur[1]) then return p._error('Hours value ("'..dur[1]..'") must be integer') end
if dur[2] and dur[2] ~= math.ceil(dur[2]) then return p._error('Minutes value ("'..dur[2]..'") must be integer') end
-- Transfer 60* minutes to hours
err = transfer(dur, 2)
if err then return err end
-- Transfer 60* seconds to minutes
err = transfer(dur, 3)
if err then return err end
-- If only one value is set then default |units= parameter to 'words'. Must happen before zero-padding.
if not unitsArg then
local count = 0
for i = 1,3 do if dur[i] then count = count + 1 end end -- for if
unitsArg = count == 1 and units.words or units.none
end
-- Separator, default: ':', with unitsArg: ' ' (space)
local sep = args.sep or unitsArg ~= units.none and entity.sepSpace or ':'
-- When units are words then separate value and unit with to avoid line-breaks between them
local unitSep = unitsArg == units.words and entity.nbsp or ''
-- If hours and seconds are set, then set minutes too, if necessary. Must happen before zero-padding.
if dur[1] and not dur[2] and dur[3] then dur[2] = 0 end
-- Build the html
local output = '<span class="duration">'
.. (dur[1] and ( '<span class="h">' .. zeroPad(dur, 1, unitsArg) ..'</span>'..unitSep.. lang:plural(dur[1], unitsArg[1]) .. (dur[2] and sep or '') ) or '')
.. (dur[2] and ( '<span class="min">'.. zeroPad(dur, 2, unitsArg) ..'</span>'..unitSep.. lang:plural(dur[2], unitsArg[2]) .. (dur[3] and sep or '') ) or '')
.. (dur[3] and ( '<span class="s">' .. zeroPad(dur, 3, unitsArg) ..'</span>'..unitSep.. lang:plural(dur[3], unitsArg[3]) ) or '')
.. '</span>'
if duration then
-- Add any extra content around the timestamp from the duration parameter
output = mw.ustring.gsub(duration, '%d-:?%d+:%d+%.?%d*', output, 1) or output
end
return output
end
return p