Create a routine that will generate a text calendar for any year.
Test the calendar by generating a calendar for the year 1969, on a device of the time.
Choose one of the following devices:

 A line printer with a width of 132 characters.
 An IBM 3278 model 4 terminal (80×43 display with accented characters). Target formatting the months of the year to fit nicely across the 80 character width screen. Restrict number of lines in test output to 43.


(Ideally, the program will generate well-formatted calendars for any page width from 20 characters up.)

Kudos (κῦδος) for routines that also transition from Julian to Gregorian calendar.

This task is inspired by Real Programmers Don't Use PASCAL by Ed Post, Datamation, volume 29 number 7, July 1983.

THE REAL PROGRAMMER'S NATURAL HABITAT
"Taped to the wall is a line-printer Snoopy calender for the year 1969."

For further Kudos see task CALENDAR, where all code is to be in UPPERCASE.

For economy of size, do not actually include Snoopy generation in either the code or the output, instead just output a place-holder.



Related task

   Five weekends


with javascript_semantics
constant year = 1969
 
include builtins\timedate.e
 
function centre(string s, integer width)
    integer gap = width-length(s),
            left = floor(gap/2),
            right = gap-left
    return repeat(' ',left) & s & repeat(' ',right)
end function
 
function one_month(integer year, integer month, bool sun_to_sat)
    string weekdays = iff(sun_to_sat?"Su Mo Tu We Th Fr Sa"
                                    :"Mo Tu We Th Fr Sa Su"),
           line = repeat(' ',20)
    sequence ldm = adjust_timedate(iff(month=12?{year+1,1,1,0,0,0,0,0}
                                               :{year,month+1,1,0,0,0,0,0}),
                                   timedelta(days:=-1)),
             res = {centre(format_timedate(ldm,"Mmmm"),20),weekdays}
    integer dow = day_of_week(year,month,1)
    if sun_to_sat then dow = remainder(dow,7)+1 end if
    integer lastday = ldm[DT_DAY],
            p = dow*3-2
    for d=1 to lastday do
        line[p..p+1] = sprintf("%2d",d)
        p += 3
        if dow=7 or d=lastday then
            res = append(res,line)
            line = repeat(' ',20)
            dow = 1
            p = 1
        else
            dow += 1
        end if
    end for
    return res
end function
 
procedure print_calendar(integer year, width, bool sun_to_sat=false)
    sequence months = repeat(0,12)
    integer wide = floor((width+2)/22)
    printf(1,centre("[Spot Reserved For Snoopy]",width)&"\n")
    printf(1,centre(sprintf("%d",year),width)&"\n")
    for month=1 to 12 do
        months[month] = one_month(year,month,sun_to_sat)
    end for
    for month=1 to 12 by wide do
        for k=1 to 9 do -- (more than enough)
            integer any = 0
            string line = ""
            for j=0 to wide-1 do
                if length(line) then
                    line &= "  "
                end if
                if k>length(months[month+j]) then
                    line &= repeat(' ',20)
                else
                    line &= months[month+j][k]
                    any = 1
                end if
            end for
            if any=0 then exit end if
            printf(1,centre(line,width)&"\n")
        end for
    end for
end procedure
 
print_calendar(year,80)
printf(1,join(repeat("1234567890",8),"")&"\n")
print_calendar(year,132,true)
printf(1,join(repeat("1234567890",13),"")&"12\n")
