summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/semesterplannerlua/semesterplannerlua_calendar.lua
blob: f2fa0e5e32dc520d89133ef2f5b10ccd842aa475 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
local dateLib = require "date"
function init(clear)
    -- clean up first
    -- global variable
    if clear then
        EVENTS = {}
    end
end

text = {
    print = function(s)
        -- print("\"" .. s .. "\"")
        tex.print(s)
    end
}

function genDot(opts)
    dot = ""
    if opts.draw then
        dot = string.format([[\tikz[baseline=(X.base)]\node (X) [fill opacity=.5,fill=red,circle,inner sep=0mm, %s] {\phantom{D}};]], opts.tikz)
    end
    return dot
end

function addEvent(opts)
    opts.inputlineno = tex.inputlineno
    -- print(string.format("collecting from line %d", opts.inputlineno))
    if opts.draw then
        assert(opts.date ~= nil and opts.tikz ~= nil, "date and tikz has to be given")
        if opts.endDate == nil or opts.endDate == '' then
            table.insert(EVENTS, {shift=opts.shift,date=dateLib(opts.date), tikz=opts.tikz, period=opts.period, endDate=nil, inputlineno=opts.inputlineno})
        else
            table.insert(EVENTS, {shift=opts.shift,date=dateLib(opts.date), tikz=opts.tikz, period=opts.period, endDate=dateLib(opts.endDate), inputlineno=opts.inputlineno})
        end
    end
end

function addAppointment(opts)
    addEvent(opts)
    dot = genDot(opts)
    if opts.print then
        tex.sprint(string.format([[\textit{%s} & %s & %s%s & %s & %s & %s\\]], opts.date, opts.time, dot, opts.course, opts.desc, opts.room, opts.prio))
    else
        tex.sprint("%")
    end
end

function addExam(opts)
    addEvent(opts)
    dot = genDot(opts)
    if opts.print then
        tex.sprint(string.format([[\textit{%s} & %s & %s%s & %s & %s \\]], opts.date, opts.time, dot, opts.course, opts.type, opts.desc))
    else
        tex.sprint("%")
    end
end

function addDeadline(opts)
    addEvent(opts)
    dot = genDot(opts)
    if opts.print then
        tex.sprint(string.format([[\textit{%s} & %s%s & %s & %s \\]], opts.date, dot, opts.course, opts.desc, opts.prio))
    else
        tex.sprint("%")
    end
end

function drawCalendar(minDate, maxDate, cols)
    minDate = dateLib(minDate)
    maxDate = dateLib(maxDate)
    text.print([[\begin{tikzpicture}[every calendar/.style={day headings=red!50,day letter headings,inner sep=2pt, week list, month label above centered, month text={\textcolor{red}{\%mt} \%y-}, every month/.style={yshift=3ex}}] ]])
    text.print([[\matrix[column sep=1em, row sep=1em]{]])
        local i = 1
        running = true
        while running do
            -- derive end from start, then check if maxDate is reached
            endDate = minDate:copy():addmonths(1):setday(1):adddays(-1)
            if endDate >= maxDate then
                endDate = maxDate
                running = false
            end
            text.print(string.format(
            [[\calendar (%04d-%02d) [dates=%04d-%02d-%02d to %04d-%02d-%02d] if (Sunday) [red] if (Saturday) [red!50!white] if (equals=\year-\month-\day) [nodes={inner sep=.25em,rectangle,line width=1pt,draw}] if (at least=\year-\month-\day) {} else [nodes={strike out, draw}]; ]],
                    minDate:getyear(), minDate:getmonth(), minDate:getyear(), minDate:getmonth(), minDate:getday(), endDate:getyear(), endDate:getmonth(), endDate:getday()))

            minDate:addmonths(1)
            minDate:setday(1)

            if i % cols == 0 or not running then
                text.print([[\\]])
            else
                text.print([[&]])
            end
            i = i + 1
        end
        text.print([[ }; ]])

        local usedDates = {}
        text.print([[\begin{scope}[on background layer] ]])
        for i,ele in ipairs(EVENTS) do
            -- print(string.format("Drawing item from line %d", ele.inputlineno))
            while ele.date <= maxDate and (ele.endDate == nil or ele.date <= ele.endDate) do
                local xshift = 0
                if ele.shift then
                    if usedDates[tostring(ele.date)] ~= nil then
                        xshift = math.ceil(usedDates[tostring(ele.date)] / 2)
                        if usedDates[tostring(ele.date)] % 2 == 0 then
                            xshift = -xshift
                        end
                        usedDates[tostring(ele.date)] = usedDates[tostring(ele.date)] + 1
                    else
                        usedDates[tostring(ele.date)] = 1
                    end
                end
                text.print(string.format([[\node[xshift=%d mm, fill opacity=.5,fill=red,circle,text width=0ex,inner sep=1.1ex, %s] at (%04d-%02d-%04d-%02d-%02d) {};]],
                    xshift, ele.tikz, ele.date:getyear(), ele.date:getmonth(), ele.date:getyear(), ele.date:getmonth(), ele.date:getday()))
                if ele.period == nil then break end
                ele.date:adddays(ele.period)
            end
        end
        text.print([[\end{scope}]])
    text.print([[\end{tikzpicture}]])
end

semesterplannerLuaCal = {
    init = init,
    addAppointment = addAppointment,
    addDeadline = addDeadline,
    addExam = addExam,
    drawCalendar = drawCalendar,
}
return semesterplannerLuaCal