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=,&nbsp;|units=letters  --->  "1h, 2m, 3s"
* |1|2|3|sep=,|units=words  --->  "1 hours,2 minutes,3 seconds"
* |1|2|3|sep=,&nbsp;|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     = '&nbsp;',
	-- Use ' ' to ALLOW line-break in the printed duration
	--sepSpace = ' ',
	-- Use '&nbsp;' to AVOID line-break in the printed duration
	sepSpace = '&nbsp;',
}




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 &nbsp; 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