Module:D'ni Time/dni: Difference between revisions

From Guild of Archivists
mNo edit summary
mNo edit summary
 
(12 intermediate revisions by the same user not shown)
Line 26: Line 26:
-- Return dniTime (table) as string of table
-- Return dniTime (table) as string of table


   return '{'..'hahr = '..dniTime['hahr']..', vailee = '..dniTime['vailee']..', yahr = '..dniTime['yahr']..', gahrtahvo = '..dniTime['gahrtahvo']..', tahvo = '..dniTime['tahvo']..', gorahn = '..dniTime['gorahn']..', prorahn = '..dniTime['prorahn']..'}'
   return '{'..'hahr = '..dniTime['hahr']..', vailee = '..dniTime['vailee']..', vaileeName = '..getVaileeName(dniTime['vailee'])..', yahr = '..dniTime['yahr']..', gahrtahvo = '..dniTime['gahrtahvo']..', tahvo = '..dniTime['tahvo']..', gorahn = '..dniTime['gorahn']..', prorahn = '..dniTime['prorahn']..'}'


end
end
Line 205: Line 205:


function p.parseDniDateStr(s, fmt)
function p.parseDniDateStr(s, fmt)
   parseDniDateStr(s, fmt)
   return parseDniDateStr(s, fmt)
end
end


function p.formatDniTime(dniTime,format)
function p.formatDniTime(dniTime,format)
   formatDniTime(dniTime,format)
   return formatDniTime(dniTime,format)
end
end


function p.displayDniTime(dniTime)
function p.displayDniTime(dniTime)
   displayDniTime(dniTime)
   return displayDniTime(dniTime)
end
end


return p
return p

Latest revision as of 02:14, 18 August 2020

Documentation for this module may be created at Module:D'ni Time/dni/doc

dnitools = require("Module:D'ni Tools")

local p = {}

local args = {}
local origArgs
local root

local vaileetee = {"Leefo","Leebro","Leesahn","Leetar","Leevot","Leevofo","Leevobro","Leevosahn","Leevotar","Leenovoo"}
local vaileetee_dnifont = {"lEfo","lEbro","lEsan","lEtar","lEvot","lEvofo","lEvobro","lEvosan","lEvotar","lEnovU"}

local function getVaileeName(vailee, useDniFont)
-- Return name of vailee given number (zero-indexed)
-- If useDniFont is true, return it in Dnifont text 

    useDniFont = useDniFont or false

    if(useDniFont) then
       return vaileetee_dnifont[vailee+1]
    else
       return vaileetee[vailee+1]
    end
end

local function displayDniTime(dniTime)
-- Return dniTime (table) as string of table

   return '{'..'hahr = '..dniTime['hahr']..', vailee = '..dniTime['vailee']..', vaileeName = '..getVaileeName(dniTime['vailee'])..', yahr = '..dniTime['yahr']..', gahrtahvo = '..dniTime['gahrtahvo']..', tahvo = '..dniTime['tahvo']..', gorahn = '..dniTime['gorahn']..', prorahn = '..dniTime['prorahn']..'}'

end

-- Much of this code derived from https://help.interfaceware.com/code/details/dateparse-lua

-- Create index table for vailee
if true then
   local function index_by_name(array)
      local dict = {}
      for i,name in pairs(array) do
         name = name:lower()
         dict[name] = i - 1
      end
      return dict
   end
   vailee_by_name = index_by_name(vaileetee)
end

-- Given string s, return name of vailee
local function lookup_vailee(s)
   local vailee = vailee_by_name[s:lower()]
   if not vailee then error('expected vailee, got "'..s..'"') end
   return vailee
end

local function fix_hahr(BE,DE)
   return function(s,d)
             if s:upper() == BE then
                d.hahr = - math.abs(d.hahr)
             elseif s:upper() == DE then
                d.hahr = math.abs(d.hahr)
             else
                error('expected '..BE..' or '..DE..', got "'..s..'"')
             end
          end
end

--Just returns a number (serves as 'default' for function table)
local function parseint(s)
   return tonumber(s)
end
 
-- Possible codes in Dni format string, with associated patterns and functions. 
-- The default function is parseint(), since most values are just integers, exactly 
-- as we need them.
local fmt_details = {
   hhhh = { '%d%d%d%d', 'hahr' };
   v    = { '%d+',    'vailee' };
   vv   = { '%d%d',   'vailee' };
   vvvv = { '%a+', 'vailee', lookup_vailee }; 
   y    = { '%d+',  'yahr' };
   yy   = { '%d%d', 'yahr' };
   g    = { '%d+',  'gahrtahvo' };
   gg   = { '%d%d', 'gahrtahvo' };
   t    = { '%d+',  'tahvo' };
   tt   = { '%d%d', 'tahvo' };
   r    = { '%d+',  'gorahn' };
   rr   = { '%d%d', 'gorahn' };
   p    = { '%d+',  'prorahn' };
   pp   = { '%d%d', 'prorahn' };
   xx   = { '%a%a', 'BE or DE', fix_hahr('BE','DE') };
   [' '] = { '%s*', 'whitespace' }; -- Allow omission.
   [','] = { '%s*,?', 'a comma' };  -- Allow omission and leading whitespace.
   w     = { '%a+', 'a word' };     -- Value ignored.
   n     = { '%d+', 'a number' };   -- Value ignored.
}
 
-- Splits one part of a format string off; returns that and the rest.
local function split_fmt(fmt)
   local c = fmt:match('^(%a)')
   if c then
      return fmt:match('^('..c..'+)(.*)')
   elseif #fmt > 0 then
      return fmt:sub(1,1), fmt:sub(2)
   end
end
 

local function parseDniDateStr(s, fmt)
-- Parses the string, s, according to the format, fmt.

   fmt = fmt or "hhhh vvvv y g:t:r:p"

   local matched, d = '', {hahr=1,yahr=1,vailee=0,gahrtahvo=0,tahvo=0,gorahn=0,prorahn=0} --Sets default
   local function fail(what, pattern) --Error msg function
      if pattern then what = what..' ('..pattern..')' end
      if matched ~= '' then what = what..' after "'..matched..'"' end
      error('expected '..what..', got "'..s..'"')
   end
   while fmt ~= '' do
      local head_fmt, rest_fmt = split_fmt(fmt)
      local pattern, field, fun = unpack(fmt_details[head_fmt] or {})
      local part, rest
      if pattern then
         part, rest = s:match('^('..pattern..')(.*)')
         if not part then fail(field,head_fmt) end
         d[field] = (fun or parseint)(part,d)
         matched = matched .. part
      elseif head_fmt:find('^%a') then
         error('unknown date/time pattern: '..head_fmt)
      elseif s:sub(1,#head_fmt) ~= head_fmt then
         fail('"'..head_fmt..'"')
      else
         matched = matched .. s:sub(1,#head_fmt)
         rest = s:sub(#head_fmt + 1)
      end
      s, fmt = rest, rest_fmt
   end
   if s ~= '' then fail('nothing') end
   return d
end

local function formatDniTime(dniTime,format)
-- Given a DniTime (table), returns formatted string.
-- format is a string with patterns for parts of the date, like standard dates
-- Patterns in capitals padded with zeroes
-- HHHH, hhhh = hahr (4-digits, Uppercase includes +/-)
-- hh = last two digits of the hahr
-- XX = 'era' (BE or DE)
-- VVVV = vailee by name
-- VV,vv = vailee (1 indexed)
-- YY, yy = yahr
-- GG, gg = gahrtahvo
-- TT, tt = tahvo
-- RR, rr = gorahnn
-- PP, pp = prorahn

   format = format or "HHHH XX VVVV yy gg:tt:rr:pp"

   result = format

   if (dniTime['hahr'] < 0) then 
       era = "BE"
       sign = "-" 
   else 
       era = "DE"
       sign = "" 
   end

result = string.gsub(result,"%a+", {
                               ["dHHHH"] = dnitools._num2dnifont(math.abs(dniTime['hahr']),4),
                               ["HHHH"] = string.format("%04d",tostring(math.abs(dniTime['hahr']))),
                               ["dhhhh"] = dnitools._num2dnifont(math.abs(dniTime['hahr'])),
                               ["hhhh"] = math.abs(dniTime['hahr']),
                               ["dhh"] = dnitools._num2dnifont(string.sub(dniTime['hahr'],-2)),
                               ["hh"] = string.sub(dniTime['hahr'],-2),
                               ["dYY"] = dnitools._num2dnifont(dniTime['yahr'],2),
                               ["YY"] = string.format("%02d",tostring(dniTime['yahr'])),
                               ["dyy"] = dnitools._num2dnifont(dniTime['yahr']),
                               ["yy"] = dniTime['yahr'],
                               ["dVVVV"] = getVaileeName(dniTime['vailee'],true),
                               ["VVVV"] = getVaileeName(dniTime['vailee']),
                               ["VV"] = string.format("%02d",tostring(dniTime['vailee']+1)),
                               ["dvv"] = dnitools._num2dnifont(dniTime['vailee'] + 1),
                               ["vv"] = dniTime['vailee'] + 1,
                               ["GG"] = string.format("%02d",tostring(dniTime['gahrtahvo'])),
                               ["dgg"] = dnitools._num2dnifont(dniTime['gahrtahvo']),
                               ["gg"] = dniTime['gahrtahvo'],
                               ["TT"] = string.format("%02d",tostring(dniTime['tahvo'])),
                               ["dtt"] = dnitools._num2dnifont(dniTime['tahvo']),
                               ["tt"] = dniTime['tahvo'],
                               ["RR"] = string.format("%02d",tostring(dniTime['gorahn'])),
                               ["drr"] = dnitools._num2dnifont(dniTime['gorahn']),
                               ["rr"] = dniTime['gorahn'],
                               ["PP"] = string.format("%02d",tostring(dniTime['prorahn'])),
                               ["pp"] = dniTime['prorahn'],
                               ["dpp"] = dnitools._num2dnifont(dniTime['prorahn']),
                               ["XX"] = era,
                               ["X"] = sign,
})

   return result

end

-- Public API

function p.parseDniDateStr(s, fmt)
   return parseDniDateStr(s, fmt)
end

function p.formatDniTime(dniTime,format)
   return formatDniTime(dniTime,format)
end

function p.displayDniTime(dniTime)
   return displayDniTime(dniTime)
end

return p