Newer
Older
XML / generate_calendar_dates.php
  1. <?php
  2.  
  3. /*
  4. File: $Id$
  5. This script generates an XSLT include file that contains templates specifying the date ranges for every week of the three main teaching periods through the year (i.e., summer school, first semester, second semester). Simply set the configuration as outlined below and make to regenerate the templates.
  6. */
  7.  
  8.  
  9. /*
  10. Teaching period configuration. It's easily extensible to a new teaching period simply by adding a new specification for that period. The key should be mixed-case alphanumeric (i.e., no whitespace, no punctuation or other special characters). The components of each period specification are:
  11. start_date: The date of the first day of the first week of the period.
  12. num_weeks: The total number of weeks in the period, /including/ any
  13. breaks (e.g., 13 teaching weeks plus 1 week mid-semester
  14. break = 14 weeks).
  15. break_weeks: A list of breaks that occur during the teaching period.
  16. Each is specified by the start (break_start) and end
  17. (break_end) week. If a break is only one week long, then
  18. break_start and break_end should be equal. If there are no
  19. breaks in the teaching period, include a single break
  20. specification with both break_start and break_end set to zero.
  21. The list should ideally be in ascending order, but the
  22. script doesn't assume this and sorts the list anyway. Weeks
  23. are numbered by absolute calendar week number (i.e., week
  24. 1 is the first calendar week of the year). The date of the
  25. first Monday of the year is stored in $first_monday below
  26. (everything is Monday-indexed).
  27. */
  28. $first_monday = new DateTime( "2012-01-02" );
  29.  
  30. $periods = array(
  31. 'SummerSchool' => array(
  32. 'first_week' => 2,
  33. 'last_week' => 7,
  34. 'break_weeks' => array(
  35. array(
  36. 'break_starts' => 0,
  37. 'break_ends' => 0,
  38. ),
  39. ),
  40. ),
  41. 'SemesterOne' => array(
  42. 'first_week' => 9,
  43. 'last_week' => 22,
  44. 'break_weeks' => array(
  45. array(
  46. 'break_starts' => 15,
  47. 'break_ends' => 15,
  48. ),
  49. ),
  50. ),
  51. 'SemesterTwo' => array(
  52. 'first_week' => 28,
  53. 'last_week' => 41,
  54. 'break_weeks' => array(
  55. array(
  56. 'break_starts' => 35,
  57. 'break_ends' => 35,
  58. ),
  59. ),
  60. ),
  61. 'FullYear' => array(
  62. 'first_week' => 9,
  63. 'last_week' => 41,
  64. 'break_weeks' => array(
  65. array(
  66. 'break_starts' => 23,
  67. 'break_ends' => 27,
  68. ),
  69. array(
  70. 'break_starts' => 15,
  71. 'break_ends' => 15,
  72. ),
  73. array(
  74. 'break_starts' => 35,
  75. 'break_ends' => 35,
  76. ),
  77. ),
  78. ),
  79. );
  80.  
  81.  
  82. // A couple of handy date intervals: four days to the end of the current week,
  83. // and seven days to the start of next week.
  84. $plus_four_days = new DateInterval( 'P4D' );
  85. $plus_seven_days = new DateInterval( 'P7D' );
  86.  
  87.  
  88. // Header boilerplate.
  89. print<<<EOT
  90. <?xml version="1.0" encoding="utf-8"?>
  91. <!-- Do not edit! Automatically generated by generate_calendar_dates.php! -->
  92.  
  93. <stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  94. xmlns:xs="http://www.w3.org/2001/XMLSchema">
  95. <!--
  96. General template for formatting teaching dates.
  97. -->
  98.  
  99.  
  100. EOT;
  101.  
  102. // printf( " <template name=\"%sTeachingDate\" match=\"%sTeachingDate\">\n" );
  103. // print( " <common>\n" );
  104. // print( " <xsl:variable name=\"period-start\" as=\"xs:date\">\n" );
  105. // print( " <xsl:if test=\"@period-start\">\n" );
  106. // print( " <xsl:value-of select=\"@period-start\">\n" );
  107. // print( " </xsl:if\n" );
  108. // printf( " <xsl:text>%s</xsl:text> \n", );
  109. // print( " </xsl:variable name=\"period-start\">\n" );
  110. // <xsl:variable name="break-start" select="@break-start" />
  111. // <xsl:variable name="period-start" select="@period-start" />
  112. // <xsl:variable name="period-start" select="@period-start" />
  113. // <xsl:value-of select="infosci:format-number( node() )" />
  114. // </common>
  115. // </template>
  116.  
  117.  
  118. foreach ( $periods as $period_name => $period_data )
  119. {
  120. $week_start = clone( $first_monday );
  121. // Jump forward the correct number of weeks to the start of the teaching period.
  122. $week_start->add( new DateInterval( sprintf( "P%dD", ( $period_data['first_week'] - 1 ) * 7 ) ) );
  123. $week_number = 0;
  124. $num_breaks = 0;
  125. // Grab the first break week off the front of the list.
  126. sort( $period_data['break_weeks'] );
  127. $break_week = array_shift( $period_data['break_weeks'] );
  128. for ( $week = $period_data['first_week']; $week <= $period_data['last_week']; $week++ )
  129. {
  130. $week_end = clone( $week_start );
  131. $week_end->add( $plus_four_days );
  132. // Handle break weeks.
  133. if ( ( $week >= $break_week['break_starts'] ) && ( $week <= $break_week['break_ends'] ) )
  134. {
  135. if ( $week == $break_week['break_starts'] )
  136. {
  137. $num_breaks++;
  138. // Work out the end date of the break.
  139. $break_end = clone( $week_start );
  140. // Note: +4 days to get to Friday.
  141. $break_end->add(
  142. new DateInterval(
  143. sprintf( "P%dD", ( ( $break_week['break_ends'] - $break_week['break_starts'] ) * 7 ) + 4 )
  144. )
  145. );
  146. // Output template for inclusion in paper calendar.
  147. printf( "\t<xsl:template name=\"%sBreak%d\" match=\"%sBreak%d\">\n",
  148. $period_name,
  149. $num_breaks,
  150. $period_name,
  151. $num_breaks
  152. );
  153. printf( "\t\t<xsl:text>%s</xsl:text>\n",
  154. // If the week start and end dates are in the same month, we only
  155. // need to output the month name once.
  156. ( $week_start->format( 'n' ) == $break_end->format( 'n' ) ) ? $week_start->format( 'j' ) : $week_start->format( 'j M' )
  157. );
  158. print( "\t\t<xsl:call-template name=\"endash\" />\n" );
  159. printf( "\t\t<xsl:text%s</xsl:text>\n", $break_end->format( 'j M' ) );
  160. print( "\t</xsl:template>\n\n" );
  161. } // if current week == first week of break
  162. if ( $week == $break_week['break_ends'] )
  163. {
  164. // Grab the next break week off the front of the list.
  165. $break_week = array_shift( $period_data['break_weeks'] );
  166. } // if current week == last week of break
  167. } // if current week is a break week
  168. else
  169. {
  170. $week_number++;
  171. // Output template for inclusion in paper calendar.
  172. printf( "\t<xsl:template name=\"%sWeek%d\" match=\"%sWeek%d\">\n",
  173. $period_name,
  174. $week_number,
  175. $period_name,
  176. $week_number
  177. );
  178. // If the week start and end dates are in the same month, we only
  179. // need to output the month name once.
  180. if ( $week_start->format( 'n' ) == $week_end->format( 'n' ) )
  181. {
  182. printf( "\t\t<xsl:text>%s</xsl:text>\n", $week_start->format( 'j' ) );
  183. print( "\t\t<xsl:call-template name=\"endash\" />\n" );
  184. printf( "\t\t<xsl:text>%s</xsl:text>\n", $week_end->format( 'j' ) );
  185. print( "\t\t<xsl:call-template name=\"newline\" />\n" );
  186. printf( "\t\t<xsl:text>%s</xsl:text>\n", $week_end->format( 'M' ) );
  187. } // if same month
  188. else
  189. {
  190. printf( "\t\t<xsl:text>%s</xsl:text>\n", $week_start->format( 'j M' ) );
  191. print( "\t\t<xsl:call-template name=\"endash\" />\n" );
  192. printf( "\t\t<xsl:text>%s</xsl:text>\n", $week_end->format( 'j M' ) );
  193. } // else different months
  194. printf( "\t</xsl:template>\n\n" );
  195. } // else normal teaching week
  196. $week_start->add( $plus_seven_days );
  197. }
  198. }
  199.  
  200.  
  201. // Footer boilerplate.
  202. print( "</xsl:stylesheet>\n" );
  203. ?>
  204.