summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/jslectureplanner/jslectureplanner.sty
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/jslectureplanner/jslectureplanner.sty
Initial commit
Diffstat (limited to 'macros/latex/contrib/jslectureplanner/jslectureplanner.sty')
-rw-r--r--macros/latex/contrib/jslectureplanner/jslectureplanner.sty1544
1 files changed, 1544 insertions, 0 deletions
diff --git a/macros/latex/contrib/jslectureplanner/jslectureplanner.sty b/macros/latex/contrib/jslectureplanner/jslectureplanner.sty
new file mode 100644
index 0000000000..dcbe0ce604
--- /dev/null
+++ b/macros/latex/contrib/jslectureplanner/jslectureplanner.sty
@@ -0,0 +1,1544 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% File jslectureplanner.sty
+%%
+%% Package to manage university courses.
+%%
+%% This file is part of the jslectureplanner bundle.
+%%
+%% Author: Juergen Spitzmueller <juergen.spitzmueller@univie.ac.at>
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2003/12/01 or later.
+%%
+%% This work has the LPPL maintenance status "maintained".
+%%
+%% The Current Maintainer of this work is Juergen Spitzmueller.
+%%
+%% Code repository and issue tracker: https://github.com/jspitz/jslectureplanner
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\def\filedate{2019/02/06}
+\def\fileversion{1.8}
+\def\filename{jslectureplanner.sty}
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{jslectureplanner}
+ [\filedate\space v\fileversion\space JS lecture planner]
+
+
+%
+% REQUIRED PACKAGES
+%
+\RequirePackage{etoolbox}
+\RequirePackage{xkeyval}
+\RequirePackage[calc,useregional]{datetime2}
+\RequirePackage{calc}
+\RequirePackage{ifthen}
+
+
+%
+% VARIABLES
+%
+\def\lectype{}
+\def\lectypeverb{}
+\def\lectypesession{}
+\def\lectitle{}
+\def\lectitlesep{}
+\def\lecsubtitle{}
+\def\lecshorttitle{}
+\def\lecsemshort{}
+\def\lecnsemshort{}
+\def\lecsemverb{}
+\def\lecnsemverb{}
+\def\lecnsemny{}
+\def\lecyear{}
+\def\lecsemester{}
+\def\lecsemesterverb{}
+\def\lecuniversity{}
+\def\lecinstitute{}
+\def\lecroom{}
+\def\lecstartdate{}
+\def\lecstarttime{}
+\def\@lecstarttime{}
+\def\lecduration{90}
+\def\lecinstructor{}
+\def\lecshortinstructor{}
+
+\def\lecplatform{}
+\def\officenumber{}
+\def\officehours{}
+
+\def\sesdate{}
+\def\sesshortdate{}
+\def\sesdtmdate{}
+\def\sesstarttime{}
+\def\sestitle{}
+\def\sesshorttitle{}
+\def\sestitlesep{}
+\def\sessubtitle{}
+\def\sesnr{}
+
+\def\programlist{}
+\def\programlistexam{}
+\def\programlistbeamer{}
+\def\programlistbeamerexam{}
+\def\programblocklistbeamer{\item}
+\def\jsbiblist{}
+
+
+%
+% COUNTERS
+%
+\newcounter{sesunit}
+\newcounter{dateratio}
+\setcounter{dateratio}{1}
+\newcounter{cancellations}
+\newcounter{snum}
+\newcounter{blocks}
+\newcounter{fbreaks}
+\newcounter{lecinterval}
+\setcounter{lecinterval}{7}
+\newcounter{sesoffset}
+\newcounter{autooffset}
+\newcounter{autooffsettrigger}
+\newcounter{autooffsetcounter}
+\newcounter{breakunits}
+\newcounter{loopcounter}
+\newcounter{adjsession}
+\newcounter{sestopic}
+\newcounter{exams}
+
+
+%
+% STRINGS
+%
+
+% 1) Course types
+%
+% vl
+\def\lectypeverb@vl{Vorlesung}
+\def\lectype@vl{VL}
+\def\lectypesession@vl{Vorlesung}
+% vo (redundant and undocumented;
+% just kept for historical reasons)
+\def\lectypeverb@vo{Vorlesung}
+\def\lectype@vo{VO}
+\def\lectypesession@vo{Vorlesung}
+% ps
+\def\lectypeverb@ps{Proseminar}
+\def\lectype@ps{PS}
+\def\lectypesession@ps{Sitzung}
+% se
+\def\lectypeverb@se{Seminar}
+\def\lectype@se{SE}
+\def\lectypesession@se{Sitzung}
+% ue
+\def\lectypeverb@ue{\"Ubung}
+\def\lectype@ue{UE}
+\def\lectypesession@ue{Sitzung}
+% ko
+\def\lectypeverb@ko{Kolloquium}
+\def\lectype@ko{KO}
+\def\lectypesession@ko{Sitzung}
+% pv
+\def\lectypeverb@pv{Privatissimum}
+\def\lectype@pv{PV}
+\def\lectypesession@pv{Sitzung}
+
+% 2.) Term types
+%
+% fs
+\def\lecsemverb@fs{Fr\"uhjahrssemester}
+\def\lecsemshort@fs{FS}
+\def\lecsemnext@fs{hs}
+\def\lecsemnextny@fs{n}
+% hs
+\def\lecsemverb@hs{Herbstsemester}
+\def\lecsemshort@hs{HS}
+\def\lecsemnext@hs{fs}
+\def\lecsemnextny@hs{y}
+% ss
+\def\lecsemverb@ss{Sommersemester}
+\def\lecsemshort@ss{SoSe}
+\def\lecsemnext@ss{ws}
+\def\lecsemnextny@ss{n}
+% ws
+\def\lecsemverb@ws{Wintersemester}
+\def\lecsemshort@ws{WS}
+\def\lecsemnext@ws{ss}
+\def\lecsemnextny@ws{y}
+
+
+% 3.) misc.
+%
+% Suffix to cancelled sessions
+\newcommand*\leccancel{\ -- keine \lectypesession}
+% Beamer program heading
+\newcommand*\lecprogram{Programm}
+% Program list indentation
+\newcommand*\lecprogramlistindent{\textbf{88.\,88.}}
+% Session topic placeholder
+\newcommand*\sestopic{Thema~\thesestopic}
+% Time slot
+\newcommand*\jstimeslot[2]{#1\,--\,#2}
+
+
+%
+% Booleans
+%
+\newtoggle{uniquelecshortinstructor}
+\newtoggle{uniquesesinstructor}
+\newtoggle{uniquesesshortinstructor}
+\newtoggle{uniquelecshorttitle}
+\newtoggle{uniquesesshorttitle}
+
+%
+% HELPERS
+%
+
+% Helper command that uses etoolbox's \AtEndPreamble iff
+% we actually are in a preamble. If not, the argument is
+% output as is.
+\newcommand\js@AtEndPreambleIfInPreamble[1]{%
+ \ifx\@onlypreamble\@notprerr
+ #1
+ \else
+ \AtEndPreamble{#1}
+ \fi
+}
+
+%
+% PACKAGE OPTIONS
+%
+\define@key{lec}{lectype}{%
+ \js@AtEndPreambleIfInPreamble{%
+ \ifcsundef{lectype@#1}{%
+ \PackageError{jslectureplanner}{Lecture type '#1' is not defined!}{%
+ Please consult the package manual for instructions how to define it}
+ }{}
+ \def\lectype{\csuse{lectype@#1}}%
+ \def\lectypeverb{\csuse{lectypeverb@#1}}%
+ \def\lectypesession{\csuse{lectypesession@#1}}%
+ }%
+}
+\DeclareOptionX{type}{\setkeys{lec}{lectype=#1}}
+
+\define@key{lec}{lecsem}{%
+ \js@AtEndPreambleIfInPreamble{%
+ \ifcsundef{lecsemshort@#1}{%
+ \PackageError{jslectureplanner}{Semester type '#1' is not defined!}{%
+ Please consult the package manual for instructions how to define it}
+ }{}
+ \def\lecsemshort{\csuse{lecsemshort@#1}}%
+ \def\lecsemverb{\csuse{lecsemverb@#1}}%
+ \def\@nextsem{\csuse{lecsemnext@#1}}%
+ \def\lecnsemshort{\csuse{lecsemshort@\@nextsem}}%
+ \def\lecnsemverb{\csuse{lecsemverb@\@nextsem}}%
+ \def\lecnsemny{\csuse{lecsemnextny@#1}}%
+ }%
+}
+\DeclareOptionX{semester}{\setkeys{lec}{lecsem=#1}}
+
+\define@key{lec}{title}{\def\lectitle{#1}%
+ \ifx\lecshorttitle\empty%
+ \def\lecshorttitle{#1}%
+ \global\togglefalse{uniquelecshorttitle}%
+ \fi}
+\define@key{lec}{titlesep}{\def\lectitlesep{#1}}
+\define@key{lec}{subtitle}{\def\lecsubtitle{#1}}
+\define@key{lec}{shorttitle}{%
+ \def\lecshorttitle{#1}%
+ \global\toggletrue{uniquelecshorttitle}}
+\define@key{lec}{year}{\def\lecyear{#1}}
+\define@key{lec}{uni}{\def\lecuniversity{#1}}
+\define@key{lec}{institute}{\def\lecinstitute{#1}}
+\define@key{lec}{platform}{\def\lecplatform{#1}}
+\define@key{lec}{officehours}{\def\officehours{#1}}
+\define@key{lec}{officenumber}{\def\officenumber{#1}}
+\define@key{lec}{room}{\def\lecroom{#1}}
+\define@key{lec}{startdate}{\def\lecstartdate{#1}}
+\define@key{lec}{starttime}{\def\@lecstarttime{#1}\def\lecstarttime{\DTMtime{#1}}}
+\define@key{lec}{duration}{\def\lecduration{#1}}
+\define@key{lec}{instructor}{\def\lecinstructor{#1}%
+ \ifx\lecshortinstructor\empty\def\lecshortinstructor{#1}\fi}
+\define@key{lec}{shortinstructor}{%
+ \def\lecshortinstructor{#1}%
+ \global\toggletrue{uniquelecshortinstructor}}
+\define@key{lec}{style}{\AtEndOfPackage{\input{#1.lps}}}
+\define@key{lec}{interval}{%
+ % test if the input is a number
+ % courtesy of egreg at http://tex.stackexchange.com/a/50131
+ \if\relax\detokenize\expandafter{\romannumeral-0#1}\relax
+ \setcounter{lecinterval}{#1}%
+ \else
+ \PackageError{jslectureplanner}{%
+ Value of 'interval' option must be a number\MessageBreak
+ ('#1' was given instead)}{}%
+ \fi
+}
+\define@key{lec}{sestitlesep}{\def\sestitlesep{#1}}
+
+\DeclareOptionX{title}{\setkeys{lec}{title={#1}}}
+\DeclareOptionX{titlesep}{\setkeys{lec}{titlesep={#1}}}
+\DeclareOptionX{subtitle}{\setkeys{lec}{subtitle={#1}}}
+\DeclareOptionX{shorttitle}{\setkeys{lec}{shorttitle={#1}}}
+\DeclareOptionX{year}{\setkeys{lec}{year=#1}}
+\DeclareOptionX{uni}{\setkeys{lec}{uni={#1}}}
+\DeclareOptionX{institute}{\setkeys{lec}{institute={#1}}}
+\DeclareOptionX{startdate}{\setkeys{lec}{startdate=#1}}
+\DeclareOptionX{starttime}{\setkeys{lec}{starttime=#1}}
+\DeclareOptionX{instructor}{\setkeys{lec}{instructor={#1}}}
+\DeclareOptionX{shortinstructor}{\setkeys{lec}{shortinstructor={#1}}}
+\DeclareOptionX{platform}{\setkeys{lec}{platform={#1}}}
+\DeclareOptionX{officehours}{\setkeys{lec}{officehours={#1}}}
+\DeclareOptionX{officenumber}{\setkeys{lec}{officenumber={#1}}}
+\DeclareOptionX{room}{\setkeys{lec}{room={#1}}}
+\DeclareOptionX{style}{\setkeys{lec}{style=#1}}
+\DeclareOptionX{interval}{\setkeys{lec}{interval=#1}}
+\DeclareOptionX{sestitlesep}{\setkeys{lec}{sestitlesep=#1}}
+
+\ProcessOptionsX
+
+%
+% End Options
+%%
+
+
+%
+% ALTERNATIVE SETUP MACROS
+%
+
+\newcommand*{\LecType}[1]{\setkeys{lec}{lectype=#1}}
+\newcommand*{\LecTitle}[2][]{\setkeys{lec}{shorttitle={#2},#1,title={#2}}}
+\newcommand*{\LecTitleSep}[1]{\setkeys{lec}{titlesep={#1}}}
+\newcommand*{\LecSubTitle}[1]{\setkeys{lec}{subtitle={#1}}}
+\newcommand*{\LecYear}[2]{\setkeys{lec}{lecsem=#1,year=#2}}
+\newcommand*{\LecUni}[1]{\setkeys{lec}{uni={#1}}}
+\newcommand*{\LecInstitute}[1]{\setkeys{lec}{institute={#1}}}
+\newcommand*{\LecRoom}[1]{\setkeys{lec}{room={#1}}}
+\newcommand*{\LecStartDate}[1]{\setkeys{lec}{startdate=#1}}
+\newcommand*{\LecStartTime}[1]{\setkeys{lec}{starttime=#1}}
+\newcommand*{\LecDuration}[1]{\setkeys{lec}{duration=#1}}
+\newcommand*{\LecInstructor}[2][\empty]{%
+ \ifx#1\empty
+ \setkeys{lec}{instructor={#2}}%
+ \else
+ \setkeys{lec}{instructor={#2},shortinstructor={#1}}%
+ \fi
+}
+\newcommand*{\LecInterval}[1]{\setkeys{lec}{interval=#1}}
+\newcommand*{\SessionTitleSep}[1]{\setkeys{lec}{sestitlesep=#1}}
+
+
+%
+% END TIME CALCULATION
+%
+% Courtesy of Christian Hupfer at
+% https://tex.stackexchange.com/a/473552/19291
+\RequirePackage{xparse}
+
+\ExplSyntaxOn
+\cs_generate_variant:Nn \int_set:Nn {NV}
+\cs_generate_variant:Nn \seq_set_split:Nnn {NVn,NVV}
+
+\NewDocumentCommand{\jslp@endtime}{+m+m}{%
+ \group_begin:
+ \tl_set:Nx \l_tmpa_tl {#1}
+ \seq_set_split:NVV \l_tmpa_seq {\c_colon_str} \l_tmpa_tl
+ \exp_args:NNx \fp_set:Nn \l_tmpa_fp {\seq_item:Nn \l_tmpa_seq {1} * 3600 + \seq_item:Nn \l_tmpa_seq {2} * 60 + \seq_item:Nn \l_tmpa_seq {3} }
+ \exp_args:NNx \fp_set:Nn \l_tmpb_fp {#2 * 60}
+ \fp_add:Nn \l_tmpa_fp {#2 * 60}
+ \tl_clear:N \l_tmpa_tl
+ % Compute hours
+ \exp_args:NNx \int_set:Nn \l_tmpa_int {\int_div_truncate:nn {\fp_use:N \l_tmpa_fp}{3600}}
+ \int_compare:nNnTF {\l_tmpa_int } > {23} {% After midnight?
+ \exp_args:NNx \int_set:Nn \l_tmpb_int {\int_mod:nn {\l_tmpa_int } {24}}
+ }{%
+ \int_set_eq:NN \l_tmpb_int \l_tmpa_int
+ }
+ \tl_put_right:NV \l_tmpa_tl {\l_tmpb_int\c_colon_str}
+
+ % Remaining seconds, split them into minutes and seconds
+ \int_set:Nn \l_tmpa_int {\fp_use:N \l_tmpa_fp}
+
+ \exp_args:NNx \int_set:Nn \l_tmpb_int {\int_mod:nn {\l_tmpa_int}{3600}}
+ \exp_args:NNx \int_set:Nn \l_tmpb_int {\int_div_truncate:nn {\l_tmpb_int}{60}}
+ \tl_put_right:NV \l_tmpa_tl {\l_tmpb_int\c_colon_str}
+ % Finally splitting: Seconds
+ \exp_args:NNx \int_set:Nn \l_tmpa_int {\int_mod:nn {\l_tmpa_int}{60}}
+ \tl_put_right:NV \l_tmpa_tl {\l_tmpa_int}
+ % Display output:
+ \exp_args:NV \DTMtime{\l_tmpa_tl}
+ \group_end:
+}
+
+\ExplSyntaxOff
+
+
+%
+% CONCATENATED VARIABLES
+%
+\def\lecsemester{\lecsemshort~\lecyear}
+\def\lecsemesterverb{\lecsemverb\ \lecyear}
+\def\lecfulltitle{\lectitle\lectitlesep\lecsubtitle}
+\def\sesfulltitle{\sestitle\sestitlesep\sessubtitle}
+\def\lecendtime{\jslp@endtime{\@lecstarttime}{\lecduration}}
+\newcommand*\lecslot{\jstimeslot{\lecstarttime}{\lecendtime}}
+
+
+%
+% CUSTOM DATE FORMATS (via datetime2)
+%
+
+\DTMnewdatestyle{lecdate}{% long date: DD.\,MM.~YYYY
+ \renewcommand*{\DTMdisplaydate}[4]{\DTMtwodigits{##3}.\,\DTMtwodigits{##2}.~##1}%
+ \renewcommand*{\DTMDisplaydate}{\DTMdisplaydate}%
+}
+
+\DTMnewdatestyle{lecshortdate}{% short date: DD.\,MM.
+ \renewcommand*{\DTMdisplaydate}[4]{\DTMtwodigits{##3}.\,\DTMtwodigits{##2}.}%
+ \renewcommand*{\DTMDisplaydate}{\DTMdisplaydate}%
+}
+
+
+%
+% CUSTOM TIME FORMATS (via datetime2)
+%
+
+\DTMsettimestyle{default}
+\DTMsetup{showseconds=false}
+
+% Simple test for substring. Courtesy of egreg at
+% https://tex.stackexchange.com/a/26873/19291
+\def\jslp@instring#1#2{TT\fi\begingroup
+ \edef\x{\endgroup\noexpand\in@{#1}{#2}}\x\ifin@}
+
+% Internal macro to set the date to a given value
+% Code adapted from advdate.sty
+\newcommand\jslp@SetDate[1][\s@v@dT@d@y]{\edef\d@t@{#1}%
+\if\jslp@instring{-}{\d@t@}%
+ \expandafter\iso@t@d@y\d@t@\iso@t@d@y%
+\else%
+ \expandafter\t@d@y\d@t@\t@d@y%
+\fi}
+\def\t@d@y#1/#2/#3\t@d@y{\day#1 \month#2 \year#3 \relax}
+\def\iso@t@d@y#1-#2-#3\iso@t@d@y{\day#3 \month#2 \year#1 \relax}
+
+
+%
+% CUSTOMIZATION OF STRINGS
+%
+
+% 1) Course types
+%
+\newcommand*\DefLecType[4]{%
+ \csdef{lectype@#1}{#2}
+ \csdef{lectypeverb@#1}{#3}
+ \csdef{lectypesession@#1}{#4}
+}
+%
+% Kept for backwards compatibility
+% vl
+\newcommand*\DefTypeVL[3]{%
+ \DefLecType{vl}{#1}{#2}{#3}
+}
+% vo (redundant and undocumented;
+% just kept for historical reasons)
+\newcommand*\DefTypeVO[3]{%
+ \DefLecType{vo}{#1}{#2}{#3}
+}
+% ps
+\newcommand*\DefTypePS[3]{%
+ \DefLecType{ps}{#1}{#2}{#3}
+}
+% se
+\newcommand*\DefTypeSE[3]{%
+ \DefLecType{se}{#1}{#2}{#3}
+}
+% ue
+\newcommand*\DefTypeUE[3]{%
+ \DefLecType{ue}{#1}{#2}{#3}
+}
+% ko
+\newcommand*\DefTypeKO[3]{%
+ \DefLecType{ko}{#1}{#2}{#3}
+}
+% pv
+\newcommand*\DefTypePV[3]{%
+ \DefLecType{pv}{#1}{#2}{#3}
+}
+
+% 2.) Term types
+%
+\define@key{semtype}{next}{\csdef{@ltn}{#1}}
+\define@boolkey{semtype}{nextny}[true]{}
+\newcommand*\DefSemType[4][\empty]{%
+ \csdef{@ltn}{}
+ \csdef{lecsemshort@#2}{#3}
+ \csdef{lecsemverb@#2}{#4}
+ \ifx\empty#1\else%
+ \setkeys{semtype}{nextny=false}%
+ \setkeys{semtype}{#1}%
+ \ifKV@semtype@nextny
+ \csdef{lecsemnextny@#2}{y}
+ \else
+ \csdef{lecsemnextny@#2}{n}
+ \fi%
+ \protected@csxdef{lecsemnext@#2}{\csuse{@ltn}}%
+ \fi
+}
+%
+% Kept for backwards compatibility
+% fs
+\newcommand*\DefTypeFS[2]{%
+ \DefSemType{fs}{#1}{#2}
+}
+% hs
+\newcommand*\DefTypeHS[2]{%
+ \DefSemType{hs}{#1}{#2}
+}
+% ss
+\newcommand*\DefTypeSS[2]{%
+ \DefSemType{ss}{#1}{#2}
+}
+% ws
+\newcommand*\DefTypeWS[2]{%
+ \DefSemType{ws}{#1}{#2}
+}
+
+
+%
+% RETRIEVE COURSE INFORMATION
+%
+
+% 1) Course program
+%
+% Define labeling list if not available
+\@ifundefined{labeling}{%
+ \newenvironment{labeling}[2][]{%
+ \def\sc@septext{#1}%
+ \list{}{\settowidth{\labelwidth}{{%
+ \textbf{#2\sc@septext}%
+ }}%
+ \leftmargin\labelwidth \advance\leftmargin by \labelsep
+ \let\makelabel\labelinglabel
+ }%
+ }{%
+ \endlist
+ }
+ \newcommand\labelinglabel[1]{%
+ \textbf{#1\hfil\sc@septext}%
+ }
+}{}
+%
+% Program generation
+\newcommand\makeprogram{%
+ \raggedright
+ \begin{labeling}{\lecprogramlistindent}
+ \programlist
+ \end{labeling}
+}
+
+% Exam schedule generation
+\newcommand\makeexamprogram{%
+ \raggedright
+ \begin{labeling}{\lecprogramlistindent}
+ \programlistexam
+ \end{labeling}
+}
+
+%
+% Beamer program generation
+\define@key{beamerprogram}{title}{\csdef{@bptitle}{#1}}
+\define@key{beamerprogram}{options}{\csdef{@bpopts}{#1}}
+\define@key{beamerprogram}{listoptions}{\csdef{@bplistopts}{#1}}
+\define@key{beamerprogram}{overlayarg}{\csdef{@bpolarg}{#1}}
+\define@key{beamerprogram}{overlayarg2}{\csdef{@bpolargii}{#1}}
+\define@key{beamerprogram}{overlayarg3}{\csdef{@bpolargiii}{#1}}
+\define@key{beamerprogram}{overlayarg4}{\csdef{@bpolargiv}{#1}}
+\define@boolkey{beamerprogram}{alerted}[true]{}
+\define@boolkey{beamerprogram}{blocksonly}[true]{}
+\define@boolkey{beamerprogram}{uncover}[true]{}
+
+\newcommand*\makebeamerprogram[1][]{%
+ \csdef{@bptitle}{\lecprogram}
+ \def\btitleapp{}
+ \numdef\pframes{\thefbreaks + 1}
+ \setkeys{beamerprogram}{alerted=false}
+ \setkeys{beamerprogram}{blocksonly=false}
+ \setkeys{beamerprogram}{uncover=false}
+ \setkeys{beamerprogram}{#1}
+ \def\bpdescbeg{\begin{description}[\lecprogramlistindent]}
+ \ifKV@beamerprogram@alerted
+ \fi
+ \providebool{uncoveredlist}
+ \ifKV@beamerprogram@uncover
+ \booltrue{uncoveredlist}
+ \else
+ \boolfalse{uncoveredlist}
+ \fi
+ \ifKV@beamerprogram@blocksonly
+ \ifcsdef{@bpolarg}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolarg}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolarg}>[label=beamerprogram]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ \ifbool{uncoveredlist}{%
+ \begin{description}[<+->][\lecprogramlistindent]
+ }{%
+ \begin{description}[\lecprogramlistindent]
+ }
+ \programblocklistbeamer
+ \end{description}
+ \end{frame}
+ \else% not \ifKV@beamerprogram@blocksonly
+ % All but last slide(s) are generated in what follows
+ \@ifundefined{programlistbeamerii}{}{%
+ \def\btitleapp{\ (1/\pframes)}
+ \ifcsdef{@bpolarg}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolarg}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolarg}>[label=beamerprogram]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ \ifbool{uncoveredlist}{%
+ \begin{description}[<+(1)->][\lecprogramlistindent]
+ }{%
+ \begin{description}[\lecprogramlistindent]
+ }
+ \programlistbeamerii
+ \end{description}
+ \end{frame}
+ }
+ \@ifundefined{programlistbeameriii}{}{%
+ \def\btitleapp{\ (2/\pframes)}
+ \ifcsdef{@bpolargii}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolargii}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolargii}>[label=beamerprogram2]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram2]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ \ifbool{uncoveredlist}{%
+ \begin{description}[<+->][\lecprogramlistindent]
+ }{%
+ \begin{description}[\lecprogramlistindent]
+ }
+ \programlistbeameriii
+ \end{description}
+ \end{frame}
+ }
+ \@ifundefined{programlistbeameriv}{}{%
+ \def\btitleapp{\ (3/\pframes)}
+ \ifcsdef{@bpolargiii}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolargiii}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolargiii}>[label=beamerprogram3]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram3]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ \ifbool{uncoveredlist}{%
+ \begin{description}[+(1)->][\lecprogramlistindent]
+ }{%
+ \begin{description}[\lecprogramlistindent]
+ }
+ \programlistbeameriv
+ \end{description}
+ \end{frame}
+ }
+ % The last slide is generated separately:
+ \ifnumgreater{\thefbreaks}{0}{\def\btitleapp{\ (\pframes/\pframes)}}{}
+ \@ifundefined{programlistbeamerii}{%
+ \ifcsdef{@bpolarg}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolarg}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolarg}>[label=beamerprogram]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ }{%
+ \@ifundefined{programlistbeameriii}{%
+ \ifcsdef{@bpolargii}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolargii}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolargii}>[label=beamerprogram2]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram2]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ }{%
+ \@ifundefined{programlistbeameriv}{%
+ \ifcsdef{@bpolargiii}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolargiii}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolargiii}>[label=beamerprogram3]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram3]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ }{%
+ \ifcsdef{@bpolargiv}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolargiv}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolargiv}>[label=beamerprogram4]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram4]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ }%
+ }%
+ }%
+
+ \ifbool{uncoveredlist}{%
+ \begin{description}[<+->][\lecprogramlistindent]
+ }{%
+ \begin{description}[\lecprogramlistindent]
+ }
+ \programlistbeamer
+ \end{description}
+ \end{frame}
+ \fi%\else\ifKV@beamerprogram@blocksonly
+}
+
+
+% Exam schedule generation
+\newcommand\makebeamerexamprogram[1][]{%
+ \csdef{@bptitle}{\lecprogram}
+ \def\btitleapp{}
+ \numdef\pframes{\thefbreaks + 1}
+ \setkeys{beamerprogram}{alerted=false}
+ \setkeys{beamerprogram}{blocksonly=false}
+ \setkeys{beamerprogram}{uncover=false}
+ \setkeys{beamerprogram}{#1}
+ \def\bpdescbeg{\begin{description}[\lecprogramlistindent]}
+ \ifKV@beamerprogram@alerted
+ \fi
+ \providebool{uncoveredlist}
+ \ifKV@beamerprogram@uncover
+ \booltrue{uncoveredlist}
+ \else
+ \boolfalse{uncoveredlist}
+ \fi
+ \ifKV@beamerprogram@blocksonly
+ \else% not \ifKV@beamerprogram@blocksonly
+ % All but last slide(s) are generated in what follows
+ \@ifundefined{programlistbeamerexam}{}{%
+ \def\btitleapp{}
+ \ifcsdef{@bpolarg}{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}<\csuse{@bpolarg}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}<\csuse{@bpolarg}>[label=beamerprogram]{\csuse{@bptitle}\btitleapp}
+ }%
+ }{%
+ \ifcsdef{@bpopts}{%
+ \begingroup\edef\tempa{\endgroup\noexpand%
+ \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa
+ }{%
+ \begin{frame}[label=beamerprogram]{\csuse{@bptitle}\btitleapp}
+ }%
+ }%
+ \ifbool{uncoveredlist}{%
+ \begin{description}[<+->][\lecprogramlistindent]
+ }{%
+ \begin{description}[\lecprogramlistindent]
+ }
+ \programlistbeamerexam
+ \end{description}
+ \end{frame}
+ \fi%\else\ifKV@beamerprogram@blocksonly
+ }%
+}
+
+
+% 2) Bibliography
+%
+\newcommand\makesessionbib{%
+ \jsbiblist
+}
+
+
+% 3) Next term
+%
+\newcommand*\adjsemester{%
+ \def\lecnyear{\lecyear}%
+ \ifthenelse{\equal{\lecnsemny}{y}}{%
+ \def\lecnyear{\the\numexpr\lecyear+1\relax}%
+ }{}%
+ \lecnsemshort~\lecnyear%
+}
+
+\newcommand*\adjsemesterverb{%
+ \def\lecnyear{\lecyear}%
+ \ifthenelse{\equal{\lecnsemny}{y}}{%
+ \def\lecnyear{\the\numexpr\lecyear+1\relax}%
+ }{}%
+ \lecnsemverb~\lecnyear%
+}
+
+%
+% COURSE SCHEDULE SETUP
+%
+
+% 1) Session definition
+%
+\newtoggle{shortinstrdef}
+\define@key{session}{titlesep}{\csdef{@sestitlesep}{{#1}}}
+\define@key{session}{subtitle}{\csdef{@sessubtitle}{{#1}}}
+\define@key{session}{shorttitle}{\csdef{@sesshorttitle}{{#1}}\csdef{@usesshorttitle}{{#1}}}
+\define@key{session}{bibsec}{\csdef{@sesbibsec}{#1}}
+\define@key{session}{room}{\csdef{@sesroom}{{#1}}}
+\define@key{session}{starttime}{\csdef{@sesrtime}{#1}\csdef{@sestime}{\DTMtime{#1}}}
+\define@key{session}{duration}{\csdef{@sesduration}{#1}}
+\define@key{session}{instructor}{%
+ \csdef{@sesinstructor}{{#1}}\csdef{@usesinstructor}{{#1}}%
+ \iftoggle{shortinstrdef}{}{\csdef{@sesshortinstructor}{{#1}}\csdef{@usesshortinstructor}{{#1}}}}
+\define@key{session}{shortinstructor}{%
+ \csdef{@sesshortinstructor}{{#1}}\csdef{@usesshortinstructor}{{#1}}\toggletrue{shortinstrdef}}
+\define@key{session}{presstudents}{\csdef{@sespresstudents}{{#1}}}
+\define@boolkey{session}{cancel}[true]{}
+\define@boolkey{session}{draft}[true]{}
+\define@key{session}{extradate}{\csdef{@xsesdate}{#1}}
+\define@boolkey{session}{exam}[true]{}
+%
+\newcommand*\NewSession[2][]{%
+ \stepcounter{sesunit}
+ \stepcounter{sestopic}
+ \setcounter{snum}{\thesesunit-\thecancellations}
+ \protected@csxdef{sesnr\thesnum}{\thesnum}
+ \togglefalse{shortinstrdef}
+ \csdef{@sestitlesep}{\ifcsempty{@sessubtitle}{}{\sestitlesep}}
+ \csdef{@sessubtitle}{}
+ \csdef{@sesshorttitle}{#2}
+ \csdef{@usesshorttitle}{}
+ \csdef{@sesbibsec}{}
+ \csdef{@sesroom}{\lecroom}
+ \csdef{@sestime}{\lecstarttime}
+ \csdef{@sesrtime}{\@lecstarttime}
+ \csdef{@sesduration}{\lecduration}
+ \csdef{@sesinstructor}{\lecinstructor}
+ \csdef{@sesshortinstructor}{\lecshortinstructor}
+ \csdef{@usesinstructor}{}
+ \csdef{@usesshortinstructor}{}
+ \csdef{@sespresstudents}{}
+ \csdef{@xsesdate}{}
+ \setkeys{session}{cancel=false}
+ \setkeys{session}{draft=false}
+ \setkeys{session}{exam=false}
+ \setkeys{session}{#1}
+ \csdef{@sestitle}{#2}
+ % only calculate the date if it is not fixed via extradate.
+ \ifcsempty{@xsesdate}{%
+ \setcounter{dateratio}{(\thesesunit-1)*\thelecinterval+\thesesoffset}
+ \ifnumcomp{\value{autooffsettrigger}}{>}{0}{%
+ \ifnumcomp{\value{autooffsettrigger}}{=}{\value{autooffsetcounter}}{%
+ \addtocounter{sesoffset}{\theautooffset}%
+ \setcounter{autooffsetcounter}{1}%
+ }{\stepcounter{autooffsetcounter}}
+ }{}
+ \protected@csxdef{sesdate\thesnum}{%
+ \bgroup\ifx\lecstartdate\empty\else\jslp@SetDate[\lecstartdate]\fi%
+ \DTMsetdatestyle{lecdate}\DTMdate{\year-\month-\day+\thedateratio}\egroup}
+ \protected@csxdef{sesshortdate\thesnum}{%
+ \bgroup\ifx\lecstartdate\empty\else\jslp@SetDate[\lecstartdate]\fi%
+ \DTMsetdatestyle{lecshortdate}\DTMdate{\year-\month-\day+\thedateratio}\egroup}
+ \protected@csxdef{sesdtmdate\thesnum}{%
+ \bgroup\ifx\lecstartdate\empty\else\jslp@SetDate[\lecstartdate]\fi%
+ \DTMdate{\year-\month-\day+\thedateratio}\egroup}
+ }{%
+ \protected@csxdef{sesdate\thesnum}{%
+ \bgroup\DTMsetdatestyle{lecdate}\expandafter\DTMdate{\csuse{@xsesdate}}\egroup}
+ \protected@csxdef{sesshortdate\thesnum}{%
+ \bgroup\DTMsetdatestyle{lecshortdate}\expandafter\DTMdate{\csuse{@xsesdate}}\egroup}
+ \protected@csxdef{sesdtmdate\thesnum}{%
+ \bgroup\expandafter\DTMdate{\csuse{@xsesdate}}\egroup}
+ }
+ \protected@csxdef{sestitle\thesnum}{\csuse{@sestitle}\ifcsempty{@sestitle}{\strut}{}}
+ \protected@csxdef{sestitlesep\thesnum}{\csuse{@sestitlesep}}
+ \protected@csxdef{sessubtitle\thesnum}{\csuse{@sessubtitle}}
+ \protected@csxdef{sesshorttitle\thesnum}{\csuse{@sesshorttitle}}
+ \protected@csxdef{usesshorttitle\thesnum}{\csuse{@usesshorttitle}}
+ \protected@csxdef{sesbib\thesnum}{\csuse{@sesbibsec}}
+ \protected@csxdef{sesroom\thesnum}{\csuse{@sesroom}}
+ \protected@csxdef{sestime\thesnum}{\csuse{@sestime}}
+ \protected@csxdef{sesrtime\thesnum}{\csuse{@sesrtime}}
+ \protected@csxdef{sesduration\thesnum}{\csuse{@sesduration}}
+ \protected@csxdef{sesinstructor\thesnum}{\csuse{@sesinstructor}}
+ \protected@csxdef{sesshortinstructor\thesnum}{\csuse{@sesshortinstructor}}
+ \protected@csxdef{usesinstructor\thesnum}{\csuse{@usesinstructor}}
+ \protected@csxdef{usesshortinstructor\thesnum}{\csuse{@usesshortinstructor}}
+ \protected@csxdef{sespresstudents\thesnum}{\csuse{@sespresstudents}}
+ \protected@csxdef{sesblock\thesnum}{\csuse{@currentblock}}
+ \protected@csxdef{sesblockno\thesnum}{\csuse{@currentblockno}}
+ \ifKV@session@cancel
+ \stepcounter{cancellations}
+ \protected@eappto\programlist{\noexpand\item[{\noexpand\bfseries\csuse{sesshortdate\thesnum}}]%
+ \noexpand\bgroup\noexpand\bfseries\csuse{sestitle\thesnum}\csuse{@sestitlesep}\csuse{@sessubtitle}%
+ \noexpand\leccancel\noexpand\egroup}
+ \protected@eappto\programlistbeamer{\noexpand\item[{\noexpand\bfseries\csuse{sesshortdate\thesnum}}]%
+ \noexpand\bgroup\noexpand\bfseries\csuse{sestitle\thesnum}\csuse{@sestitlesep}\csuse{@sessubtitle}%
+ \noexpand\leccancel\noexpand\egroup}
+ \else
+ \ifKV@session@exam
+ \stepcounter{exams}
+ \protected@csxdef{examsesno\theexams}{\thesnum}
+ \protected@eappto\programlistexam{\noexpand\item[{\noexpand\bfseries\csuse{sesshortdate\thesnum}}]%
+ \csuse{sestitle\thesnum}\csuse{@sestitlesep}\csuse{@sessubtitle}}
+ \protected@eappto\programlistbeamerexam{\noexpand\item[{\noexpand\bfseries\csuse{sesshortdate\thesnum}}]%
+ \csuse{sestitle\thesnum}\csuse{@sestitlesep}\csuse{@sessubtitle}}
+ \ifcsempty{sesbib\thesnum}{}{%
+ \xappto\jsbiblist{\noexpand\section{\csuse{sestitle\thesnum}\csuse{@sestitlesep}\csuse{@sessubtitle}}%
+ \noexpand\nocite{*}%
+ \noexpand\printbibliography[keyword=\csuse{sesbib\thesnum},heading=none]}%
+ }%
+ \else
+ \ifKV@session@draft
+ \ifcsempty{@sestitle}{\protected@csxdef{sestitle\thesnum}{\sestopic}}{}
+ \fi
+ \protected@eappto\programlist{\noexpand\item[{\noexpand\bfseries\csuse{sesshortdate\thesnum}}]%
+ \csuse{sestitle\thesnum}\csuse{@sestitlesep}\csuse{@sessubtitle}}
+ \protected@eappto\programlistbeamer{\noexpand\item[{\noexpand\bfseries\csuse{sesshortdate\thesnum}}]%
+ \csuse{sestitle\thesnum}\csuse{@sestitlesep}\csuse{@sessubtitle}}
+ \ifcsempty{sesbib\thesnum}{}{%
+ \xappto\jsbiblist{\noexpand\section{\csuse{sestitle\thesnum}\csuse{@sestitlesep}\csuse{@sessubtitle}}%
+ \noexpand\nocite{*}%
+ \noexpand\printbibliography[keyword=\csuse{sesbib\thesnum},heading=none]}%
+ }%
+ \fi
+ \fi
+}
+
+% 2) Semester breaks and schedule offsets
+%
+% Set break of one interval unit
+\newcommand*\SetBreak[2][\empty]{%
+ \stepcounter{sesunit}
+ \stepcounter{cancellations}
+ \ifnumcomp{\value{autooffsettrigger}}{>}{0}{%
+ \ifnumcomp{\value{autooffsettrigger}}{=}{\value{autooffsetcounter}}{%
+ \addtocounter{sesoffset}{\theautooffset}%
+ \setcounter{autooffsetcounter}{1}%
+ }{\stepcounter{autooffsetcounter}}
+ }{}
+ \ifx\empty#1
+ \protected@eappto\programlist{\noexpand\begin{center} (#2) \noexpand\end{center}}
+ \protected@eappto\programlistbeamer{\noexpand\begin{center} (#2) \noexpand\end{center}}
+ \else
+ \protected@eappto\programlist{\noexpand\begin{center} (#1: #2) \noexpand\end{center}}
+ \protected@eappto\programlistbeamer{\noexpand\begin{center} (#1: #2) \noexpand\end{center}}
+ \fi
+}
+
+% Set break of multiple interval units
+\define@key{break}{units}{\csdef{@breakunits}{#1}}
+\define@key{break}{span}{\csdef{@breakspan}{#1}}
+\define@key{break}{weeks}{%
+ \PackageWarning{jslectureplanner}{\protect\SetBreaks\space option 'weeks' is deprecated. Use 'units' instead.}%
+ \setkeys{break}{units=#1}%
+}
+\newcommand*\SetBreaks[2][units=1]{%
+ \csdef{@breakunits}{}
+ \csdef{@breakspan}{}
+ \setkeys{break}{#1}
+ \setcounter{breakunits}{\csuse{@breakunits}}
+ \setcounter{sesunit}{\thesesunit+\thebreakunits}
+ \setcounter{cancellations}{\thecancellations+\thebreakunits}
+ \setcounter{loopcounter}{0}
+ \loop\ifnum\theloopcounter<\thebreakunits\relax
+ \ifnumcomp{\value{autooffsettrigger}}{>}{0}{%
+ \ifnumcomp{\value{autooffsettrigger}}{=}{\value{autooffsetcounter}}{%
+ \addtocounter{sesoffset}{\theautooffset}%
+ \setcounter{autooffsetcounter}{1}%
+ }{\stepcounter{autooffsetcounter}}
+ }{}
+ \stepcounter{loopcounter}
+ \repeat
+ \ifcsempty{@breakspan}{%
+ \protected@eappto\programlist{\noexpand\begin{center} (#2) \noexpand\end{center}}
+ \protected@eappto\programlistbeamer{\noexpand\begin{center} (#2) \noexpand\end{center}}
+ }{%
+ \protected@eappto\programlist{\noexpand\begin{center} (\csuse{@breakspan}: #2) \noexpand\end{center}}
+ \protected@eappto\programlistbeamer{\noexpand\begin{center} (\csuse{@breakspan}: #2) \noexpand\end{center}}
+ }
+}
+
+% Offset in days
+\newcommand*\SetLecOffset[1]{%
+ \addtocounter{sesoffset}{#1}
+}
+
+% Automatic Offset after n sessions
+\newcommand*\SetAutoOffset[2]{%
+ \setcounter{autooffsettrigger}{#1}
+ \setcounter{autooffset}{#2}
+}
+
+% 3) Definition of thematic blocks
+%
+\newcommand*\StartBlock[1]{%
+ \stepcounter{blocks}%
+ \protected@eappto\programlist{\noexpand\item[{\noexpand\bfseries\Roman{blocks}}.]%
+ \noexpand\bgroup\noexpand\bfseries #1\noexpand\egroup}%
+ \gappto\programlist{\begin{labeling}{\lecprogramlistindent}}%
+ \protected@eappto\programlistbeamer{\noexpand\item[{\noexpand\bfseries\Roman{blocks}}.]%
+ \noexpand\bgroup\noexpand\bfseries #1\noexpand\egroup}%
+ \gappto\programlistbeamer{\begin{description}[\lecprogramlistindent]}
+ \protected@xappto\programblocklistbeamer{\noexpand\item[{\Roman{blocks}}.] #1}%
+ \csxdef{@currentblock}{#1}%
+ \csxdef{@currentblockno}{\Roman{blocks}}%
+}
+
+\newcommand*\EndBlock{%
+ \gappto\programlist{\end{labeling}}
+ \gappto\programlistbeamer{\end{description}}
+ \csxdef{@currentblock}{}%
+ \csxdef{@currentblockno}{}%
+}
+
+\newcommand*\NewBlock[1]{%
+ \EndBlock
+ \StartBlock{#1}
+}
+
+\newenvironment{SessionBlock}[1]{\StartBlock{#1}}{\EndBlock}
+
+% 4) Beamer-specific features
+%
+% Beamer frame breaks
+\newcommand*\SetBeamerFrameBreak{%
+ \stepcounter{fbreaks}
+ \@ifundefined{programlistbeamerii}{%
+ \global\let\programlistbeamerii\programlistbeamer
+ }{%
+ \@ifundefined{programlistbeameriii}{%
+ \global\let\programlistbeameriii\programlistbeamer
+ }{%
+ \global\let\programlistbeameriv\programlistbeamer
+ }
+ }
+ \global\let\programlistbeamer\empty
+}
+
+% Beamer program hook
+\newcommand*\SetBeamerHook[1]{%
+ \protected@eappto\programlistbeamer{\noexpand#1}
+}
+
+% 5) Infrastructure
+%
+% Office hours
+\newcommand\SetOfficeHours[1]{%
+ \def\officehours{#1}%
+}
+
+% Office number
+\newcommand\SetOfficeNumber[1]{%
+ \def\officenumber{#1}%
+}
+
+% (E-learning) platform
+\newcommand\SetPlatform[1]{%
+ \def\lecplatform{#1}%
+}
+
+
+%
+% 6) Student presentations
+%
+
+\newcounter{pressession}
+\newcounter{lastpressession}
+\providebool{deflastpressession}
+
+% Allow to change first output session
+\newcommand*\setfirstpressession[1]{%
+ \setcounter{pressession}{#1}%
+}
+
+% Allow to change last output session
+\newcommand*\setlastpressession[1]{%
+ \setcounter{lastpressession}{#1}%
+ \booltrue{deflastpressession}%
+}
+
+% Generate presentation list
+\newcommand\makepreslist{%
+ \@ifstar{\@makeblankpreslist}{\@makepreslist}%
+}
+% Unstarred: use sespresstudents
+\newcommand\@makepreslist{%
+ \ifbool{deflastpressession}{}{\setcounter{lastpressession}{\thesnum}}%
+ \begin{labeling}{\lecprogramlistindent}
+ \whiledo {\not{\value{pressession} > \value{lastpressession}}}%
+ {%
+ \ThisSession{\thepressession}%
+ \if\relax\sespresstudents\relax
+ \MakeProgramline{\thepressession}\par
+ ---
+ \else
+ \MakeProgramline{\thepressession}\par
+ \SessionPresStudents{\thepressession}
+ \fi
+ \stepcounter{pressession}%
+ }
+ \end{labeling}
+}
+% Starred: blank list
+\newcommand\@makeblankpreslist{%
+ \ifbool{deflastpressession}{}{\setcounter{lastpressession}{\thesnum}}%
+ \begin{labeling}{\lecprogramlistindent}
+ \whiledo {\not{\value{pressession} > \value{lastpressession}}}%
+ {%
+ \MakeProgramline{\thepressession}\vspace{2\baselineskip}
+ \stepcounter{pressession}%
+ }
+ \end{labeling}
+}
+
+% A beamer-specific version
+\newcommand\makebeamerpreslist{%
+ \ifbool{deflastpressession}{}{\setcounter{lastpressession}{\thesnum}}%
+ \begin{description}[\lecprogramlistindent]
+ \whiledo {\not{\value{pressession} > \value{lastpressession}}}%
+ {%
+ \MakeProgramline{\thepressession}: \SessionPresStudents{\thepressession}
+ \stepcounter{pressession}%
+ }
+ \end{description}
+}
+
+
+%
+% RETRIEVE SESSION-SPECIFIC INFORMATION
+%
+
+% Define current session
+\newcommand\ThisSession[1]{%
+ \gdef\sesnr{\csuse{sesnr#1}}%
+ \gdef\sesdate{\csuse{sesdate#1}}%
+ \gdef\sesshortdate{\csuse{sesshortdate#1}}%
+ \gdef\sesdtmdate{\csuse{sesdtmdate#1}}%
+ \gdef\sestitle{\csuse{sestitle#1}}%
+ \gdef\sestitlesep{\csuse{sestitlesep#1}}%
+ \gdef\sesshorttitle{\csuse{sesshorttitle#1}}%
+ \gdef\@usesshorttitle{\csuse{usesshorttitle#1}}%
+ \gdef\sessubtitle{\csuse{sessubtitle#1}}%
+ \gdef\sesroom{\csuse{sesroom#1}}%
+ \gdef\sesstarttime{\csuse{sestime#1}}%
+ \gdef\sesendtime{\jslp@endtime{\csuse{sesrtime#1}}{\csuse{sesduration#1}}}%
+ \gdef\sesslot{\jstimeslot{\sesstarttime}{\sesendtime}}%
+ \gdef\@sesinstructor{\csuse{sesinstructor#1}}%
+ \gdef\@sesshortinstructor{\csuse{sesshortinstructor#1}}%
+ \gdef\@usesinstructor{\csuse{usesinstructor#1}}%
+ \gdef\@usesshortinstructor{\csuse{usesshortinstructor#1}}%
+ \gdef\sespresstudents{\csuse{sespresstudents#1}}%
+ \gdef\sesblocktitle{\csuse{sesblock#1}}%
+ \gdef\sesblocknumber{\csuse{sesblockno#1}}%
+ \if\hfuzz\@usesinstructor\hfuzz%
+ \global\togglefalse{uniquesesinstructor}%
+ \else
+ \global\toggletrue{uniquesesinstructor}%
+ \fi
+ \if\hfuzz\@usesshortinstructor\hfuzz%
+ \global\togglefalse{uniquesesshortinstructor}%
+ \else
+ \global\toggletrue{uniquesesshortinstructor}%
+ \fi
+ \if\hfuzz\@usesshorttitle\hfuzz%
+ \global\togglefalse{uniquesesshorttitle}%
+ \else
+ \global\toggletrue{uniquesesshorttitle}%
+ \fi
+}
+
+% Define a local session
+% (independent of current session)
+\newcommand\LocalSession[1]{%
+ \gdef\lsesnr{\csuse{sesnr#1}}%
+ \gdef\lsesdate{\csuse{sesdate#1}}%
+ \gdef\lsesshortdate{\csuse{sesshortdate#1}}%
+ \gdef\lsesdtmdate{\csuse{sesdtmdate#1}}%
+ \gdef\lsestitle{\csuse{sestitle#1}}%
+ \gdef\lsestitlesep{\csuse{sestitlesep#1}}%
+ \gdef\lsesshorttitle{\csuse{sesshorttitle#1}}%
+ \gdef\lsessubtitle{\csuse{sessubtitle#1}}%
+ \gdef\lsesroom{\csuse{sesroom#1}}%
+ \gdef\lsesstarttime{\csuse{sestime#1}}%
+ \gdef\lsesendtime{\jslp@endtime{\csuse{sesrtime#1}}{\csuse{sesduration#1}}}%
+ \gdef\lsesslot{\jstimeslot{\lsesstarttime}{\lsesendtime}}%
+ \gdef\@lsesinstructor{\csuse{sesinstructor#1}}%
+ \gdef\@lsesshortinstructor{\csuse{sesshortinstructor#1}}%
+ \gdef\@lusesinstructor{\csuse{usesinstructor#1}}%
+ \gdef\@lusesshortinstructor{\csuse{usesshortinstructor#1}}%
+ \gdef\lsespresstudents{\csuse{sespresstudents#1}}%
+ \gdef\lsesblocktitle{\csuse{sesblock#1}}%
+ \gdef\lsesblocknumber{\csuse{sesblockno#1}}%
+}
+
+% Get the session no of exam no #1
+\newcommand*\examsesno[1]{%
+ \csuse{examsesno#1}%
+}
+
+% \ses[short]instructor and \ses[short]instructor*.
+% The starred versions only output something if the session
+% instructor differs from the general lecture instructor
+\newcommand\sesinstructor{\@ifstar{\@usesinstructor}{\@sesinstructor}}
+\newcommand\sesshortinstructor{\@ifstar{\@usesshortinstructor}{\@sesshortinstructor}}
+% same for local instructor macros
+\newcommand\lsesinstructor{\@ifstar{\@lusesinstructor}{\@lsesinstructor}}
+\newcommand\lsesshortinstructor{\@ifstar{\@lusesshortinstructor}{\@lsesshortinstructor}}
+
+% Get information for a specific (local) session
+%
+% Full title
+\newcommand*\SessionFullTitle[1]{%
+ \LocalSession{#1}%
+ \lsestitle\lsestitlesep\lsessubtitle%
+}
+
+% Date
+\newcommand*\SessionDate[1]{%
+ \LocalSession{#1}%
+ \lsesdate%
+}
+
+% Short title
+\newcommand*\SessionShortTitle[1]{%
+ \LocalSession{#1}%
+ \lsesshorttitle%
+}
+
+% Main title
+\newcommand*\SessionTitle[1]{%
+ \LocalSession{#1}%
+ \lsestitle%
+}
+
+% Short date
+\newcommand*\SessionShortDate[1]{%
+ \LocalSession{#1}%
+ \lsesshortdate%
+}
+
+% Short date
+\newcommand*\SessionDTMDate[1]{%
+ \LocalSession{#1}%
+ \lsesdtmdate%
+}
+
+% Time
+\newcommand*\SessionStartTime[1]{%
+ \LocalSession{#1}%
+ \lsesstarttime%
+}
+% End Time
+\newcommand*\SessionEndTime[1]{%
+ \LocalSession{#1}%
+ \lsesendtime%
+}
+% Time Slot
+\newcommand*\SessionTimeSlot[1]{%
+ \LocalSession{#1}%
+ \lsesslot%
+}
+
+% Room
+\newcommand*\SessionRoom[1]{%
+ \LocalSession{#1}%
+ \lsesroom%
+}
+
+% Instructor relay
+\newcommand*\SessionInstructor{%
+ \@ifstar{\@@SessionInstructor}{\@SessionInstructor}%
+}
+
+% Instructor, unstarred
+\newcommand*\@SessionInstructor[1]{%
+ \LocalSession{#1}%
+ \lsesinstructor%
+}
+
+% Instructor, starred
+\newcommand*\@@SessionInstructor[1]{%
+ \LocalSession{#1}%
+ \lsesinstructor*%
+}
+
+% Instructor (Short Form) relay
+\newcommand*\SessionShortInstructor{%
+ \@ifstar{\@@SessionShortInstructor}{\@SessionShortInstructor}%
+}
+
+% Instructor (Short Form), unstarred
+\newcommand*\@SessionShortInstructor[1]{%
+ \LocalSession{#1}%
+ \lsesshortinstructor%
+}
+
+% Instructor (Short Form), starred
+\newcommand*\@@SessionShortInstructor[1]{%
+ \LocalSession{#1}%
+ \lsesshortinstructor*%
+}
+
+% Presenting students
+\newcommand*\SessionPresStudents[1]{%
+ \LocalSession{#1}%
+ \lsespresstudents%
+}
+
+% Session block title
+\newcommand*\SessionBlockTitle[1]{%
+ \LocalSession{#1}%
+ \lsesblocktitle%
+}
+
+% Session block number
+\newcommand*\SessionBlockNumber[1]{%
+ \LocalSession{#1}%
+ \lsesblocknumber%
+}
+
+% Program line suitable for
+% a description or labeling list
+\newcommand*\MakeProgramline[1]{%
+ \LocalSession{#1}%
+ \item[{\bfseries\lsesshortdate}]%
+ \lsestitle\lsestitlesep\lsessubtitle%
+}
+
+% Get information for adjacent (next, previous etc.) sessions
+%
+% Full title
+\newcommand*\AdjSessionFullTitle[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionFullTitle{\theadjsession}%
+ \fi
+}
+% Date
+\newcommand*\AdjSessionDate[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionDate{\theadjsession}%
+ \fi
+}
+% Short date
+\newcommand*\AdjSessionShortDate[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionShortDate{\theadjsession}%
+ \fi
+}
+% DTM Date
+\newcommand*\AdjSessionDTMDate[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionDTMDate{\theadjsession}%
+ \fi
+}
+% Time
+\newcommand*\AdjSessionStartTime[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionStartTime{\theadjsession}%
+ \fi
+}
+% Time
+\newcommand*\AdjSessionEndTime[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionEndTime{\theadjsession}%
+ \fi
+}
+% Time
+\newcommand*\AdjSessionTimeSlot[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionTimeSlot{\theadjsession}%
+ \fi
+}
+% Short title
+\newcommand*\AdjSessionShortTitle[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionShortTitle{\theadjsession}%
+ \fi
+}
+% Main title
+\newcommand*\AdjSessionTitle[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionTitle{\theadjsession}%
+ \fi
+}
+% Session block title
+\newcommand*\AdjSessionBlockTitle[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionBlockTitle{\theadjsession}%
+ \fi
+}
+% Session block number
+\newcommand*\AdjSessionBlockNumber[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionBlockNumber{\theadjsession}%
+ \fi
+}
+% Room
+\newcommand*\AdjSessionRoom[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionRoom{\theadjsession}%
+ \fi
+}
+% Instructor relay
+\newcommand*\AdjSessionInstructor{%
+ \@ifstar{\@@AdjSessionInstructor}{\@AdjSessionInstructor}%
+}
+% Instructor, unstarred
+\newcommand*\@AdjSessionInstructor[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionInstructor{\theadjsession}%
+ \fi
+}
+% Instructor, starred
+\newcommand*\@@AdjSessionInstructor[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionInstructor*{\theadjsession}%
+ \fi
+}
+% Instructor (Short Form) relay
+\newcommand*\AdjSessionShortInstructor{%
+ \@ifstar{\@@AdjSessionShortInstructor}{\@AdjSessionShortInstructor}%
+}
+% Instructor (Short Form), unstarred
+\newcommand*\@AdjSessionShortInstructor[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionShortInstructor{\theadjsession}%
+ \fi
+}
+% Instructor (Short Form), starred
+\newcommand*\@@AdjSessionShortInstructor[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionShortInstructor*{\theadjsession}%
+ \fi
+}
+% Presenting students
+\newcommand*\AdjSessionPresStudents[1][1]{%
+ \ifnum0<0\sesnr\relax
+ \setcounter{adjsession}{\numexpr\sesnr+#1\relax}%
+ \SessionPresStudents{\theadjsession}%
+ \fi
+}
+%
+%%%%%%%%%%%%%
+
+%
+% DEPRECATED THINGS
+%
+
+% Reset to today
+% DEPRECATED as of v.0.8,
+\newcommand*\ResetDate{%
+ \PackageWarning{jslectureplanner}{%
+ \protect\ResetDate\space is deprecated (not needed anymore).}%
+}
+
+% datetime (v.1) date formats
+% DEPRECATED as of v.1.3
+% Issue a warning if redefined.
+\newcommand*\lecdateformat{}
+\newcommand*\lecdateshortformat{}
+\AtEndPreamble{%
+ \ifcsempty{lecdateformat}{}{
+ \PackageWarning{jslectureplanner}{\protect\lecdateformat\space is deprecated and non-functional.\MessageBreak
+ Please refer to the manual for the new way of customizing date output.
+ }
+ }
+ \ifcsempty{lecdateshortformat}{}{
+ \PackageWarning{jslectureplanner}{\protect\lecdateshortformat\space is deprecated and non-functional.\MessageBreak
+ Please refer to the manual for the new way of customizing date output.
+ }
+ }
+}
+
+% Finis