Skip to content

Instantly share code, notes, and snippets.

@jason-s13r
Created August 2, 2012 10:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jason-s13r/3236114 to your computer and use it in GitHub Desktop.
Save jason-s13r/3236114 to your computer and use it in GitHub Desktop.
Practising lua by making a calendar thing.
#!/usr/bin/env lua
function february(year)
if year == nil or year == "context" then year = os.date("%Y"); end
if year%4==0 and (year%100~=0 or year%400==0) then
return 29
else
return 28
end
end
-- month is 1 .. 12, where January = 1 and December = 12
function weekday(year, month, day)
local h = 0
month = month or 1
day = day or 1
if month < 3 then
month = month + 12
year = year - 1
end
h = day + math.floor((month + 1)*26/10)
h = h + year + math.floor(year / 4)
h = h + 6*math.floor(year / 100) + math.floor(year / 400)
h = h % 7
return (h + 5) % 7 + 1
end
function get_months(year, month, day)
day = day
local padding = ""
local result = {
title = "",
week = "",
days = "",
lines = {}
}
for i = 1,7 do
result.week = result.week .. string.sub(days[i], 1, 2) .. " "
end
result.week = string.sub(result.week,1,# result.week - 1)
for i = 2,((# result.week - # (months[month][1] .. " " .. year))/2) do
padding = padding .. " "
end
result.title = "<" .. padding .. result.title .. months[month][1] .. " " .. year
while (# result.title) < (# result.week)-1 do
result.title = result.title .. " "
end
result.title = result.title .. ">"
if day ~= nil then
result.title = string.gsub(result.title, "<", "{")
result.title = string.gsub(result.title, ">", "}")
end
for i = 1,months[month][2] do
if day ~= nil and i == day+0 then
result.days = result.days .. "## "
else
result.days = result.days..string.format("%2d", i) .. " "
end
end
for i = 1,weekday(year, month, 1)-1 do
result.days = " " .. result.days
end
local i = 1
while i < (# result.days) do
local j = i + (# result.week)
table.insert(result.lines, string.sub(result.days, i, j))
i = j + 1
end
for i = 1,# result.lines do
result.lines[i] = string.sub(result.lines[i],1,(# result.lines[i])-1)
end
while (# result.lines[# result.lines]) < (# result.week) do
result.lines[# result.lines] = result.lines[# result.lines] .. " "
end
while # result.lines < 6 do
local line = ""
while (# line) < (# result.week) do
line = line .. " "
end
table.insert(result.lines, line)
end
return result
end
-- year = four digit year (or more digits if you're planning a trip far into the future)
-- month = current month, 1 to 12, January = 1 and December = 12
-- day = current day, 1 to 28, 29, 30 or 31
-- rows
-- cols
-- range = {1, 12} for full year, {1, 3} for Jan-Mar, etc. 0 = last year's december, 13 = next year's January.
function print_calendar(year, month, day, rows, cols, range)
local calendar = {}
for i = range[1],range[2] do
if i == month+0 and year == os.date("%Y") then
table.insert(calendar, get_months(year, i, day))
else
if i == 0 then
table.insert(calendar, get_months(year-1, i+12))
elseif i == 13 then
table.insert(calendar, get_months(year+1, i-12))
else
table.insert(calendar, get_months(year, i))
end
end
end
if arg[1] ~= nil then
local title = year .. " Calendar"
local line = ""
while # line < ((# cols + 1)*(#calendar[1].week) + (# tab)*(# cols) - (# title))/2 do
line = line .. " "
end
line = line .. title
while # line < (# cols + 1)*(#calendar[1].week) + (# tab)*(# cols) do
line = line .. " "
end
print(string.char(27) .. "[7m" .. line .. string.char(27) .. "[0m")
end
for a,b in pairs(rows) do
if cols[1] ~= 0 then
for h,i in pairs(cols) do
calendar[b].title = calendar[b].title .. tab .. calendar[b+i].title
calendar[b].week = calendar[b].week .. tab .. calendar[b+i].week
for c = 1,6 do
calendar[b].lines[c] = calendar[b].lines[c] .. tab .. calendar[b+i].lines[c]
end
end
end
calendar[b].title = string.gsub(calendar[b].title, "<", string.char(27) .. "[7m" .. string.char(27) .. "[2m" .. " ")
calendar[b].title = string.gsub(calendar[b].title, ">", " " .. string.char(27) .. "[0m")
calendar[b].title = string.gsub(calendar[b].title, "{", string.char(27) .. "[7m" .. " ", 1)
calendar[b].title = string.gsub(calendar[b].title, "}", " " .. string.char(27) .. "[0m", 1)
calendar[b].week = string.gsub(calendar[b].week, "Mo", string.char(27) .. "[4m" .. "Mo")
calendar[b].week = string.gsub(calendar[b].week, "Su", "Su" .. string.char(27) .. "[0m")
print(calendar[b].title)
print(calendar[b].week)
for key,value in pairs(calendar[b].lines) do
value = string.gsub(value, "#", string.char(27) .. "[7m" .. string.format("%2d", day+0), 1)
value = string.gsub(value, "#", string.char(27) .. "[0m", 1)
print(value)
end
end
end
days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }
months = {
{"January",31},
{"February",february(arg[1] or os.date("%Y"))},
{"March",31},
{"April",30},
{"May",31},
{"June",30},
{"July",31},
{"August",31},
{"September",30},
{"October",31},
{"November",30},
{"December",31},
}
tab = " "
local help = false
if arg[1] == nil then
help = true
end
if arg[2] ~= nil then
if arg[2] ~= "wide" then
tab = ""
while # tab < arg[2]+0 do
tab = tab .. " "
end
elseif arg[3] ~= nil then
tab = ""
while # tab < arg[3]+0 do
tab = tab .. " "
end
end
end
if arg[1] == "context" then
-- 3 month calendar view
print_calendar(os.date("%Y"), os.date("%m"), os.date("%d"), {1}, {1,2}, {os.date("%m") - 1, os.date("%m") + 1})
elseif arg[2] == "wide" then
-- 1 month calendar view for current year
print_calendar(arg[1] or os.date("%Y"), os.date("%m"), os.date("%d"), {1, 5, 9}, {1, 2, 3}, {1, 12})
elseif arg[1] ~= nil then
-- 12 month calendar view for given year
print_calendar(arg[1] or os.date("%Y"), os.date("%m"), os.date("%d"), {1, 4, 7, 10}, {1, 2}, {1, 12})
else
-- 1 month calendar view for current year
print_calendar(os.date("%Y"), os.date("%m"), os.date("%d"), {1}, {0}, {os.date("%m"), os.date("%m")})
end
if help == true then
local usage = "" .. arg[-1] .. " " .. arg[0] .. " "
print("Usage:")
print(usage, "\t# Shows calendar for this month.")
print(usage .. "context", "# Shows 3 month calendar.")
print(usage .. os.date("%Y"), "\t# Show calendar for given year.")
print(usage .. os.date("%Y") .. " 1", "\t# Above but with 1 space between months.")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment