Changes

Jump to navigation Jump to search
18,249 bytes removed ,  01:33, 3 March 2007
no edit summary
I decided not to spoil the first day of the new year by doing real work. I also wanted to get to know a bit more about lua... The background: we produce a calendar with pictures of our kids every year. Of course, I wanted to do that with ConTeXt. There is a number of precooked scripts to produce various calendars for LaTeX, but nothing for ConTeXt, as far as I could see. So I decided to write something myself. I first did it in perl, with the Date::Calc module. Then, I tried to achieve the same result with a lua script. Without the convenience of a precooked date module, I had to do all the calculations of holidays and days of the week myself, taking my cues mostly from wikipedia, but it was relatively easy.  You invoke the script from the command line: <tt>lua calendar.lua XXXX</tt>, and it will produce a file <tt>kalenderXXXX.tex</tt>, where <tt>XXXX</tt> is a number between 1900 and 2299. This file can then be typeset with ConTeXt. The result will be a calendar for the year <tt>XXXX</tt>, with every month on one page; Sundays and German official holidays are in boldface; the first day of the week is Monday. The names of the months are in German, but that should be easy to modify. We have a simple version in black and white which we print on colored paper and into which real pictures are glued, and a digital version which we send to friends via e-mail where the pages of the typeset pdf have colored backgrounds and the pictures are included.  Neither the lua code nor the TeX code is particularly beautiful (hey, this was my first day with lua), but it may be interesting for someone out there.  <pre>#!/usr/local/bin/lua year = arg[1] -- create boolean switch for leap years if (math.mod(year,4) == 0) then if (math.mod(year,100) == 0) then if (math.mod(year,400) == 0) then leap_year = true else leap_year = false end else leap_year = true end else leap_year = falseend -- calculate easter sunday, according to Meeus/Jones/Butcher-- (see http://en.wikipedia.org/wiki/Computus#Meeus.2FJones.2FButcher_Gregorian_algorithm ) a = math.mod(year,19) b = math.floor(year / 100) c = math.mod(year,100) d = math.floor(b / 4) e = math.mod(b,4) f = math.floor((b + 8) / 25)  g = math.floor((b - f + 1) / 3) h = math.mod((19 * a + b - d - g + 15),30) i = math.floor(c / 4) k = math.mod(c,4) L = math.mod((32 + 2 * e + 2 * i - h - k),7) m = math.floor((a + 11 * h + 22 * L) / 451) eastersundaymonth = math.floor((h + L - 7 * m + 114) / 31) eastersunday = math.mod((h + L - 7 * m + 114),31) + 1 -- now, calculate other Christian holidays which depend on Easter Sunday if eastersunday + 1 <= 31 then eastermonday,eastermondaymonth = (eastersunday + 1),eastersundaymonth else eastermonday,eastermondaymonth = (eastersunday - 30),(eastersundaymonth + 1) end if eastersunday -2 >= 1 then goodfriday,goodfridaymonth = (eastersunday - 2),eastersundaymonth else goodfriday,goodfridaymonth = (eastersunday + 29),(eastersundaymonth - 1) end if leap_year == true then if eastersundaymonth == 4 then juliansunday = 91 + eastersunday elseif eastersundaymonth == 3 then juliansunday = 60 + eastersunday endelse if eastersundaymonth == 4 then juliansunday = 90 + eastersunday elseif eastersundaymonth == 3 then juliansunday = 59 + eastersunday endend  if leap_year == true thenif juliansunday + 50 <= 152 then pentecostmonday,pentecostmonth = (juliansunday - 71),5elseif (juliansunday + 50) > 152 then pentecostmonday,pentecostmonth = (juliansunday - 102),6endif juliansunday + 60 <= 152 then corpusday,corpusmonth = (juliansunday - 61),5elseif (juliansunday + 60) > 152 then corpusday,corpusmonth = (juliansunday - 92),6endif juliansunday + 39 <= 121 then ascensionday,ascensionmonth = (juliansunday - 52),4elseif (juliansunday + 39) > 121 then ascensionday,ascensionmonth = (juliansunday - 82),5endelseif juliansunday + 50 <= 151 then pentecostmonday,pentecostmonth = (juliansunday - 70),5elseif (juliansunday + 50) > 151 then pentecostmonday,pentecostmonth = (juliansunday - 101),6end if juliansunday + 60 <= 151 then corpusday,corpusmonth = (juliansunday - 60),5elseif (juliansunday + 60) > 151 then corpusday,corpusmonth = (juliansunday - 91),6end if juliansunday + 39 <= 120 then ascensionday,ascensionmonth = (juliansunday - 51),4elseif (juliansunday + 39) > 120 then ascensionday,ascensionmonth = (juliansunday - 81),5endend -- we open our outfile outfile = io.open("kalender"..year..".tex","w") outfile:write("%%% calendar for the year "..year..", produced by the lua script\n%%% calendar.lua on "..os.date().."\n\n") -- and first write the header of our document outfile:write("\\enableregime[utf]\n\n\\setuppagenumbering[state=stop]\n\n\\setuplayout[footer=0cm,\n\t margin=0cm,\n\t backspace=1cm,\n\t width=fit]\n\n\\setupcolors[state=start]\n\n\\definecolor [mycyan] [r=0, g=0.8, b=1]\n\n\\starttext\n\n%\\showframe\n\n% \\setupbackgrounds[page][background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[title][width=.9\\textwidth]}\n\n\\switchtobodyfont[38pt]\n\n\\startalignment[middle]\n\n\\strut\n\n\\vfill\n\n"..year.."\n\n\\blank[2cm]\n\nKalender\n\n\\blank[2cm]\n\n\\strut\n\n\\stopalignment\n\n\\page\n\n\\switchtobodyfont[20pt]\n\n\\strut\n\n\\vfill\n\n% \\midaligned{\\externalfigure[january][width=.9\\textwidth]}\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=orange]\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc Januar}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") -- calculate day of week for 1/1, according to Babwani's formula-- (see http://www.geocities.com/sohaelbabwani/algorithm.html ) myyear = math.abs(year) if myyear < 2000 then n,y = 19,(myyear - 1900)else n,y = 20,(myyear - 2000)end if leap_year == true thenjanfirst = math.mod((math.floor((5 * y) / 4) + 6 + 1 - (2 * (math.mod(n,4)))),7)elsejanfirst = math.mod((math.floor((5 * y) / 4) + 0 + 1 - (2 * (math.mod(n,4)))),7)end if janfirst == 0 then janfirst = 7 endif janfirst == 1 then janfirst = 8 end janindent = janfirst - 1 for jan = 1,janindent do outfile:write("\\NC ") end if janfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("{\\bf 1} ") end  for day = 2,31 do if leap_year == true then weekday = math.mod((math.floor((5 * y) / 4) + 6 + day - (2 * (math.mod(n,4)))),7) else weekday = math.mod((math.floor((5 * y) / 4) + 0 + day - (2 * (math.mod(n,4)))),7) end if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") elseif day == 6 then outfile:write("\\NC {\\bf "..day.."} ") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[february][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc Februar}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") if leap_year == true thenfebult,febvar = 29,2else febult,febvar = 28,3end febfirst = math.mod((math.floor((5 * y) / 4) + febvar + 1 - (2 * (math.mod(n,4)))),7) if febfirst == 0 then febfirst = 7 endif febfirst == 1 then febfirst = 8 end febindent = febfirst - 1 for feb = 1,febindent do outfile:write("\\NC ") end if febfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end  for day = 2,febult do weekday = math.mod((math.floor((5 * y) / 4) + febvar + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[march][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc März}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") marfirst = math.mod((math.floor((5 * y) / 4) + 3 + 1 - (2 * (math.mod(n,4)))),7) if marfirst == 0 then marfirst = 7 endif marfirst == 1 then marfirst = 8 end marindent = marfirst - 1 for mar = 1,marindent do outfile:write("\\NC ") end if marfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end for day = 2,31 do weekday = math.mod((math.floor((5 * y) / 4) + 3 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") elseif goodfridaymonth == 3 and day == goodfriday then outfile:write("\\NC {\\bf "..day.."} ") elseif eastermondaymonth == 3 and day == eastermonday then outfile:write("\\NC {\\bf "..day.."} ") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[april][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc April}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") aprfirst = math.mod((math.floor((5 * y) / 4) + 6 + 1 - (2 * (math.mod(n,4)))),7) if aprfirst == 0 then aprfirst = 7 endif aprfirst == 1 then aprfirst = 8 end aprindent = aprfirst - 1 for apr = 1,aprindent do outfile:write("\\NC ") end if aprfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end for day = 2,30 do weekday = math.mod((math.floor((5 * y) / 4) + 6 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") elseif goodfridaymonth == 4 and day == goodfriday then outfile:write("\\NC {\\bf "..day.."} ") elseif eastermondaymonth == 4 and day == eastermonday then outfile:write("\\NC {\\bf "..day.."} ") elseif ascensionmonth == 4 and day == ascensionday then outfile:write("\\NC {\\bf "..day.."} ") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[may][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc Mai}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") mayfirst = math.mod((math.floor((5 * y) / 4) + 1 + 1 - (2 * (math.mod(n,4)))),7) if mayfirst == 0 then mayfirst = 7 endif mayfirst == 1 then mayfirst = 8 end mayindent = mayfirst - 1 for may = 1,mayindent do outfile:write("\\NC ") end if mayfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("{\\bf 1} ") end for day = 2,31 do weekday = math.mod((math.floor((5 * y) / 4) + 1 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") elseif ascensionmonth == 5 and day == ascensionday then outfile:write("\\NC {\\bf "..day.."} ") elseif corpusmonth == 5 and day == corpusday then outfile:write("\\NC {\\bf "..day.."} ") elseif pentecostmonth == 5 and day == pentecostmonday then outfile:write("\\NC {\\bf "..day.."} ") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[june][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc Juni}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") junfirst = math.mod((math.floor((5 * y) / 4) + 4 + 1 - (2 * (math.mod(n,4)))),7) if junfirst == 0 then junfirst = 7 endif junfirst == 1 then junfirst = 8 end junindent = junfirst - 1 for jun = 1,junindent do outfile:write("\\NC ") end if junfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end for day = 2,30 do weekday = math.mod((math.floor((5 * y) / 4) + 4 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") elseif ascensionmonth == 6 and day == ascensionday then outfile:write("\\NC {\\bf "..day.."} ") elseif corpusmonth == 6 and day == corpusday then outfile:write("\\NC {\\bf "..day.."} ") elseif pentecostmonth == 6 and day == pentecostday then outfile:write("\\NC {\\bf "..day.."} ") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[july][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc Juli}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") julfirst = math.mod((math.floor((5 * y) / 4) + 6 + 1 - (2 * (math.mod(n,4)))),7) if julfirst == 0 then julfirst = 7 endif julfirst == 1 then julfirst = 8 end julindent = julfirst - 1 for jul = 1,julindent do outfile:write("\\NC ") end if julfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end for day = 2,31 do weekday = math.mod((math.floor((5 * y) / 4) + 6 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[august][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc August}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") augfirst = math.mod((math.floor((5 * y) / 4) + 2 + 1 - (2 * (math.mod(n,4)))),7) if augfirst == 0 then augfirst = 7 endif augfirst == 1 then augfirst = 8 end augindent = augfirst - 1 for aug = 1,augindent do outfile:write("\\NC ") end if augfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end for day = 2,31 do weekday = math.mod((math.floor((5 * y) / 4) + 2 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[september][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc September}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") sepfirst = math.mod((math.floor((5 * y) / 4) + 5 + 1 - (2 * (math.mod(n,4)))),7) if sepfirst == 0 then sepfirst = 7 endif sepfirst == 1 then sepfirst = 8 end sepindent = sepfirst - 1 for sep = 1,sepindent do outfile:write("\\NC ") end if sepfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end for day = 2,30 do weekday = math.mod((math.floor((5 * y) / 4) + 5 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[october][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc Oktober}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") octfirst = math.mod((math.floor((5 * y) / 4) + 0 + 1 - (2 * (math.mod(n,4)))),7) if octfirst == 0 then octfirst = 7 endif octfirst == 1 then octfirst = 8 end octindent = octfirst - 1 for oct = 1,octindent do outfile:write("\\NC ") end if octfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end for day = 2,31 do weekday = math.mod((math.floor((5 * y) / 4) + 0 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") elseif day == 3 then outfile:write("\\NC {\\bf "..day.."} ") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[november][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc November}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") novfirst = math.mod((math.floor((5 * y) / 4) + 3 + 1 - (2 * (math.mod(n,4)))),7) if novfirst == 0 then novfirst = 7 endif novfirst == 1 then novfirst = 8 end novindent = novfirst - 1 for nov = 1,novindent do outfile:write("\\NC ") end if novfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("{\\bf 1} ") end for day = 2,30 do weekday = math.mod((math.floor((5 * y) / 4) + 3 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\page\n\n% \\setupbackgrounds[page] [background=color,backgroundcolor=darkred]\n\n% \\midaligned{\\externalfigure[december][width=.66\\textwidth]}\n\n\\strut\n\n\\vfill\n\n\\midaligned{\\sc Dezember}\n\n\\placetable[bottom][none]{none}{\n\\starttabulate[|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|rw(4mm)|]\n") decfirst = math.mod((math.floor((5 * y) / 4) + 5 + 1 - (2 * (math.mod(n,4)))),7) if decfirst == 0 then decfirst = 7 endif decfirst == 1 then decfirst = 8 end decindent = decfirst - 1 for dec = 1,decindent do outfile:write("\\NC ") end if decfirst == 8 then outfile:write("{\\bf 1} \\NC \\NR\n")else outfile:write("1 ") end for day = 2,31 do weekday = math.mod((math.floor((5 * y) / 4) + 5 + day - (2 * (math.mod(n,4)))),7) if weekday == 1 then outfile:write("\\NC {\\bf "..day.."} \\NC \\NR\n") elseif day == 25 then outfile:write("\\NC {\\bf "..day.."} ") elseif day == 26 then outfile:write("\\NC {\\bf "..day.."} ") else outfile:write("\\NC "..day.." ") endend outfile:write("\n\\stoptabulate\n}\n\n\\stoptext\n")</pre>--[[User:Thomas|Thomas]] 21:56, 1 January 2007 (CET)TOO BAD ITS FUCKIN GONE
8

edits

Navigation menu