Newer
Older
Handbook / calendar / generate_lecturedates.php
  1. <?php
  2.  
  3. /*
  4. This script generates a LaTeX include file that contains macros for generating
  5. the dates for every lecture in a teaching period. It doesn't generate dates
  6. for multiple papers; rather, you should generate a separate include file for
  7. each paper individually. The main reason for this approach is that each paper
  8. will have different lecture offsets in a week, and possibly also a different
  9. number of lectures each week. It's easier to keep track of this in paper-
  10. specific files rather than a single file for all papers. The configuration
  11. for a specific paper is read from a separate file.
  12. The output of the script should be placed at the root of the tree for the
  13. target paper, alongside the paper_init.tex file.
  14. */
  15.  
  16. // LaTeX macro names can't include numbers, so we have to convert them to words.
  17. require 'Numbers/Words.php';
  18.  
  19. /*
  20. Configuration requires the following variables to be specified in the file
  21. lecturedates_config.php:
  22. $period_config
  23. An array whose key is the teaching period code (e.g., "SS", "S1", "S2",
  24. "FY"). Each element is an array comprising the following sub-elements:
  25. "start_dates"
  26. A list of starting dates for contiguous teaching weeks, e.g., the six
  27. weeks up to mid-semester break, and the seven weeks after. We pretty
  28. much ignore breaks, etc., otherwise; all we want to know is what the
  29. date(s) are for the lecture(s) in each week. It also means that we
  30. don't have to do anything clever for things like full year papers that
  31. span more than one semester. The variable $year (defined to be current
  32. year below) can be used here.
  33. "period_lengths"
  34. A list of integers representing the length in weeks of each period
  35. specifed in $start_dates. Both the "start_dates" and "period_lengths"
  36. elements must therefore have the same length!
  37. Example (full year with one break in each semester):
  38. "full year" => array(
  39. "start_dates" => array(
  40. new DateTime( "{$year}-02-27" ),
  41. new DateTime( "{$year}-04-24" ),
  42. new DateTime( "{$year}-07-10" ),
  43. new DateTime( "{$year}-09-04" ),
  44. ),
  45. "period_lengths" => array(7, 6, 7, 6),
  46. ),
  47. $paper_config
  48. An array whose key is the paper code (e.g., "INFO214"). Each element
  49. is an array comprising the following sub-elements:
  50. "class_offsets"
  51. For each class in a week, specify the offset interval from the start
  52. of week (Monday). Thus, a class on Monday will be 'P0D', Wednesday
  53. 'P2D', Friday 'P4D', etc. Include as many entries in the list as there
  54. are classes per week (e.g., two lectures => two entries).
  55. Example (INFO 408 2017, one lecture per week, on Wednesday):
  56. "class_offsets" => array(
  57. new DateInterval( 'P2D' ),
  58. );
  59. A complete example:
  60. $period_config = array(
  61. ...
  62. "FY" => array(
  63. "start_dates" => array(
  64. new DateTime( "{$year}-02-27" ),
  65. new DateTime( "{$year}-04-24" ),
  66. new DateTime( "{$year}-07-10" ),
  67. new DateTime( "{$year}-09-04" ),
  68. ),
  69. "period_lengths" => array(7, 6, 7, 6),
  70. ),
  71. );
  72.  
  73. $paper_config = array(
  74. "COMP101" => array(
  75. "class_offsets" = array(
  76. new DateInterval( 'P0D' ),
  77. new DateInterval( 'P2D' ),
  78. ),
  79. ),
  80. ...
  81. );
  82. */
  83. $year = date("Y");
  84.  
  85. require 'lecturedates_config.php';
  86.  
  87. // Process command line arguments.
  88. // This only accepts paper codes in the usual form XXXX999, and will fail for
  89. // unusual papers like "INFO5H". However, it's extremely unlikely that such
  90. // papers will ever need to use this script.
  91. ($argc == 3 && preg_match('/[A-Z]{4}\d{3}/', $argv[1]) && preg_match('/S[S12]|FY/', $argv[2]))
  92. or die("Usage: php generate_lecturedates.php paper_code period_code\n");
  93.  
  94. $paper_code = $argv[1];
  95. $period_code = $argv[2];
  96.  
  97. // A handy date interval: seven days to the start of next week.
  98. $plus_seven_days = new DateInterval('P7D');
  99.  
  100. $week_num = 1;
  101.  
  102. printf( "%% Lecture dates for %s %s %s.\n", $paper_code, $period_code, $year );
  103.  
  104. $period_settings = $period_config[$period_code];
  105. $paper_settings = $paper_config[$paper_code];
  106.  
  107. print <<<EOT
  108. \\newcount\\lecnum
  109. \\newcount\\weeknum
  110.  
  111. \\newcommand{\\LectureDate}[1]{%
  112. \\lecnum #1\\relax%
  113. \\advance\\lecnum by -1\\relax%
  114. \\ifcase\\lecnum
  115. EOT;
  116.  
  117. $first_lecture = true;
  118.  
  119. foreach ($period_settings['start_dates'] as $period => $period_start)
  120. {
  121. $week_start = clone($period_start);
  122. for ($w = 0; $w < $period_settings['period_lengths'][$period]; $w++)
  123. {
  124. $lecture_num = 1;
  125. foreach ($paper_settings["class_offsets"] as $offset)
  126. {
  127. $class_date = clone($week_start);
  128. $class_date->add($offset);
  129. if ($first_lecture) {
  130. $first_lecture = false;
  131. }
  132. else {
  133. print " \\or ";
  134. }
  135. printf("%s%%\n", $class_date->format('j F'));
  136. $lecture_num++;
  137. } // for every class in week
  138. $week_start->add($plus_seven_days);
  139. $week_num++;
  140. } // for every week in period
  141. } // for every period
  142.  
  143. print <<<EOT
  144. \\else ????%
  145. \\fi%
  146. }
  147.  
  148. \\newcommand{\\LectureDateByWeek}[2]{%
  149. \\weeknum #1\\relax%
  150. \\advance\\weeknum by -1\\relax%
  151. \\multiply\\weeknum by 2\\relax%
  152. \\advance\\weeknum by #2\\relax%
  153. \\LectureDate{\\the\\weeknum}%
  154. }
  155.  
  156. EOT;