%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% File jslectureplanner.sty %% %% Package to manage university courses. %% %% This file is part of the jslectureplanner bundle. %% %% Author: Juergen Spitzmueller %% %% 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{2024/03/06} \def\fileversion{1.13} \def\filename{jslectureplanner.sty} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{jslectureplanner} [\filedate\space v\fileversion\space JS lecture planner] % % REQUIRED PACKAGES % \RequirePackage{etoolbox} \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\lecendyear{} \def\lecendyearsep{/} \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{} \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{\programdateformat{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 % \DeclareKeys[lec] { % type= type.code = { \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}}% }% }, % semester= semester.code = { \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}}% }% }, % title= title.code = { \def\lectitle{#1}% \ifx\lecshorttitle\empty% \def\lecshorttitle{#1}% \global\togglefalse{uniquelecshorttitle}% \fi }, % titlesep=<sep> titlesep.store = \lectitlesep, % subtitle=<sep> subtitle.store = \lecsubtitle, % shorttitle=<title> shorttitle.code = { \def\lecshorttitle{#1} \global\toggletrue{uniquelecshorttitle} }, % year=<year> year.store = \lecyear, % endyear=<year> endyear.store = \lecendyear, % uni=<university> uni.store = \lecuniversity, % institute=<institute> institute.store = \lecinstitute, % platform=<platform> platform.store = \lecplatform, % officehours=<officehours> officehours.store = \lecofficehours, % officenumber=<officenumber> officenumber.store = \lecofficenumber, % room=<room> room.store = \lecroom, % startdate=<startdate> startdate.store = \lecstartdate, % starttime=<starttime> starttime.code = { \def\@lecstarttime{#1} \def\lecstarttime{\DTMtime{#1}} }, % duration=<duration> duration.store = \lecduration, % instructor=<instructor> instructor.code = { \def\lecinstructor{#1}% \ifx\lecshortinstructor\empty \def\lecshortinstructor{#1} \fi }, % shortinstructor=<shortinstructor> shortinstructor.code = { \def\lecshortinstructor{#1}% \global\toggletrue{uniquelecshortinstructor} }, % style=<style> style.code = { \AtEndOfPackage{\input{#1.lps}} }, % interval=<interval> interval.code = { % 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 }, % sestitlesep=<sestitlesep> sestitlesep.store = \sestitlesep } % Process package options \ProcessKeyOptions[lec] % % End Options %% % % ALTERNATIVE SETUP MACROS % \RequirePackage{xparse} % LecYear parses and splits {...}{startyear/endyear} \ExplSyntaxOn \NewDocumentCommand \LecYear { m m } { % #1: semester/term \SetKeys[lec]{semester=#1} % split #2 at / if available (startyear/endyear) \seq_set_split:Nnn \seq_jslp_lec_year { / } { #2 } \seq_pop_left:NNT \seq_jslp_lec_year \tl_jslp_start_year { \SetKeys[lec]{year=\tl_jslp_start_year} } \seq_get_right:NNT \seq_jslp_lec_year \tl_jslp_end_year { \SetKeys[lec]{endyear=\tl_jslp_end_year} } } \ExplSyntaxOff \newcommand*{\LecType}[1]{\SetKeys[lec]{type=#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*{\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 \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\ifcsempty{lecendyear}{}{\lecendyearsep\lecendyear}} \def\lecsemesterverb{\lecsemverb\ \lecyear\ifcsempty{lecendyear}{}{\lecendyearsep\lecendyear}} \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 % \newif\if@jslp@semtype@nextny\@jslp@semtype@nextnyfalse \DeclareKeys[semtype] { next.store = \@ltn, nextny.if = @jslp@semtype@nextny } \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}% \if@jslp@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{ProgramList} \programlist \end{ProgramList} } % Exam schedule generation \newcommand\makeexamprogram{% \raggedright \begin{ProgramListExam} \programlistexam \end{ProgramListExam} } % Customizable environments for formatting the lists % ProgramList is the list used in programs \newenvironment{ProgramList}{\begin{labeling}{\lecprogramlistindent}}{\end{labeling}} % BeamerProgramList is the list used in programs \newenvironment{BeamerProgramList}{\begin{description}[\lecprogramlistindent]}{\end{description}} % ProgramListExam is the list used in exam schedules. By default identical to ProgramList \newenvironment{ProgramListExam}{\begin{ProgramList}}{\end{ProgramList}} % PresList is the list of presenting students \newenvironment{PresList}{\begin{ProgramList}}{\end{ProgramList}} % Same for beamer \newenvironment{BeamerPresList}{\begin{BeamerProgramList}}{\end{BeamerProgramList}} \newenvironment{BeamerProgramListExam}{\begin{BeamerProgramList}}{\end{BeamerProgramList}} % Text format of program date \newcommand*\programdateformat[1]{\textbf{#1}} % Text format of program title \newcommand*\sestitleformat[1]{#1} % Text format of program title \newcommand*\exsestitleformat[1]{\sestitleformat{#1}} % Text format of canceled session titles \newcommand*\cansestitleformat[1]{\textbf{#1}} % Text format of block titles \newcommand*\blocktitleformat[1]{\textbf{#1}} % Text format of block numbers \newcommand*\blocknumberformat[1]{\textbf{#1}} % ProgramListItem, ProgramListExamItem and ProgramListCancelItem typeset a single % session. Arguments: #1 date, #2 title, #3 title separator, #4 subtitle \newcommand*{\ProgramListItem}[4]{\item[\programdateformat{#1}] \sestitleformat{#2#3#4}} \newcommand*{\ProgramListCancelItem}[4]{\item[\programdateformat{#1}] \cansestitleformat{#2#3#4\leccancel}} \newcommand*{\ProgramListExamItem}[4]{\item[\programdateformat{#1}] \exsestitleformat{#2#3#4}} % Same for beamer program \newcommand*{\BeamerProgramListItem}[4]{\item[\programdateformat{#1}] \sestitleformat{#2#3#4}} \newcommand*{\BeamerProgramListCancelItem}[4]{\item[\programdateformat{#1}] \cansestitleformat{#2#3#4\leccancel}} \newcommand*{\BeamerProgramListExamItem}[4]{\item[\programdateformat{#1}] \exsestitleformat{#2#3#4}} % PresListItem: Program line for student presentation lists \newcommand*\PresListItem[4]{% \ProgramListItem{#1}{#2}{#3}{#4}% } \newcommand*\BeamerPresListItem[4]{% \BeamerProgramListItem{#1}{#2}{#3}{#4}% } % Format break event \newcommand*\breakevent[3]{\ifx\empty#1 #2\else#1#2#3\fi} % ProgramListBreak typesets a break. % Optional argument is date range, #2 is name of break \newcommand*{\ProgramListBreak}[2][\empty]% {% \begin{center} (\breakevent{#1}{: }{#2}) \end{center}% } % ProgramListBlock \newenvironment{ProgramListBlock}[2]% {% \ProgramBlockItem{#1}{#2} \begin{ProgramList}% }% {\end{ProgramList}} \newcommand*{\ProgramBlockItem}[2]{\item[\blocknumberformat{#1}.] \blocktitleformat{#2}} \newcommand*{\BeamerProgramBlockItem}[2]{\item[\blocknumberformat{#1}.] \blocktitleformat{#2}} \newcommand*{\BeamerProgramBlockBlocksOnlyItem}[2]{\item[#1.] #2} % % Beamer program generation \newif\if@jslp@beamerprogram@alerted\@jslp@beamerprogram@alertedfalse \newif\if@jslp@beamerprogram@blocksonly\@jslp@beamerprogram@blocksonlyfalse \newif\if@jslp@beamerprogram@uncover\@jslp@beamerprogram@uncoverfalse \DeclareKeys[beamerprogram] { % title=<title> title.store = \@bptitle, % options = <options> options.store = \@bpopts, % listoptions = <options> listoptions.store = \@bplistopts, % overlayarg = <arg> overlayarg.store = \@bpolarg, % overlayarg2 = <arg> overlayarg2.store = \@bpolargii, % overlayarg3 = <arg> overlayarg3.store = \@bpolargiii, % overlayarg4 = <arg> overlayarg4.store = \@bpolargiv, % overlayarg = <true|false> [not functional!] alerted.if = @jslp@beamerprogram@alerted, % blocksonly = <true|false> blocksonly.if = @jslp@beamerprogram@blocksonly, % uncover = <true|false> uncover.if = @jslp@beamerprogram@uncover } % Overlay specifications for uncover programs \newcommand*\beameruncoverspec{\beamerdefaultoverlayspecification{<+(1)->}} \newcommand*\beameruncoverffslidesspec{\beamerdefaultoverlayspecification{<+(-1)->}} \newcommand*\beameruncoverblocksonlyspec{\beamerdefaultoverlayspecification{<+->}} \newcommand*\beameralertspec{} \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{BeamerProgramList}} \providebool{alerted} \if@jslp@beamerprogram@alerted \booltrue{alerted} \else \boolfalse{alerted} \fi \providebool{uncoveredlist} \if@jslp@beamerprogram@uncover \booltrue{uncoveredlist} \else \boolfalse{uncoveredlist} \fi \if@jslp@beamerprogram@blocksonly \ifbool{alerted}{% \ifbool{uncoveredlist}% {\renewcommand*\beameruncoverblocksonlyspec{\beamerdefaultoverlayspecification{<+-| alert@+>}}}% {\renewcommand*\beameralertspec{\beamerdefaultoverlayspecification{<alert@+>}}}% }{} \ifcsvoid{@bpolarg}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolarg}>[label=beamerprogram]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolarg}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% \ifbool{uncoveredlist}{\beameruncoverblocksonlyspec}{\beameralertspec} \begin{BeamerProgramList} \ifcsempty{programblocklistbeamer}{\BeamerProgramBlockBlocksOnlyItem{}{}}{\programblocklistbeamer} \end{BeamerProgramList} \end{frame} \else% not \if@jslp@beamerprogram@blocksonly \ifbool{alerted}{% \ifbool{uncoveredlist}% {% \renewcommand*\beameruncoverspec{\beamerdefaultoverlayspecification{<+(1)-| alert@+(1)>}} \renewcommand*\beameruncoverffslidesspec{\beamerdefaultoverlayspecification{<+(-1)-| alert@+(-1)>}} }% {\renewcommand*\beameralertspec{\beamerdefaultoverlayspecification{<alert@+(1)>}}}% }{} % All but last slide(s) are generated in what follows \@ifundefined{programlistbeamerii}{}{% \def\btitleapp{\ (1/\pframes)} \ifcsvoid{@bpolarg}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolarg}>[label=beamerprogram]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolarg}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% \ifbool{uncoveredlist}{\beameruncoverspec}{\beameralertspec} \begin{BeamerProgramList} \programlistbeamerii \end{BeamerProgramList} \end{frame} } \@ifundefined{programlistbeameriii}{}{% \def\btitleapp{\ (2/\pframes)} \ifcsvoid{@bpolargii}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram2]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolargii}>[label=beamerprogram2]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolargii}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% \ifbool{uncoveredlist}{\beameruncoverffslidesspec}{\beameralertspec} \begin{BeamerProgramList} \programlistbeameriii \end{BeamerProgramList} \end{frame} } \@ifundefined{programlistbeameriv}{}{% \def\btitleapp{\ (3/\pframes)} \ifcsvoid{@bpolargiii}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram3]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolargiii}>[label=beamerprogram3]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolargiii}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% \ifbool{uncoveredlist}{\beameruncoverffslidesspec}{\beameralertspec} \begin{BeamerProgramList} \programlistbeameriv \end{BeamerProgramList} \end{frame} } % The last slide is generated separately: \ifnumgreater{\thefbreaks}{0}{\def\btitleapp{\ (\pframes/\pframes)}}{} \@ifundefined{programlistbeamerii}{% \ifcsvoid{@bpolarg}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolarg}>[label=beamerprogram]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolarg}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% }{% \@ifundefined{programlistbeameriii}{% \ifcsvoid{@bpolargii}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram2]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolargii}>[label=beamerprogram2]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolargii}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% }{% \@ifundefined{programlistbeameriv}{% \ifcsvoid{@bpolargiii}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram3]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolargiii}>[label=beamerprogram3]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolargiii}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% }{% \ifcsvoid{@bpolargiv}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram4]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolargiv}>[label=beamerprogram4]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolargiv}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% }% }% }% \ifbool{uncoveredlist}{\beameruncoverffslidesspec}{\beameralertspec} \begin{BeamerProgramList} \programlistbeamer \end{BeamerProgramList} \end{frame} \fi%\else\if@jslp@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{BeamerProgramList}} \providebool{alerted} \if@jslp@beamerprogram@alerted \booltrue{alerted} \else \boolfalse{alerted} \fi \providebool{uncoveredlist} \if@jslp@beamerprogram@uncover \booltrue{uncoveredlist} \else \boolfalse{uncoveredlist} \fi \if@jslp@beamerprogram@blocksonly \else% not \if@jslp@beamerprogram@blocksonly \ifbool{alerted}{% \ifbool{uncoveredlist}% {\renewcommand*\beameruncoverspec{\beamerdefaultoverlayspecification{<+(1)-| alert@+(1)>}}}% {\renewcommand*\beameralertspec{\beamerdefaultoverlayspecification{<alert@+(1)>}}}% }{} % All but last slide(s) are generated in what follows \ifcsempty{programlistbeamerexam}{}{% \def\btitleapp{} \ifcsvoid{@bpolarg}{% \ifcsvoid{@bpopts}{% \begin{frame}[label=beamerprogram]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }{% \ifcsvoid{@bpopts}{% \begin{frame}<\csuse{@bpolarg}>[label=beamerprogram]{\csuse{@bptitle}\btitleapp} }{% \begingroup\edef\tempa{\endgroup\noexpand% \begin{frame}<\csuse{@bpolarg}>[\csuse{@bpopts}]{\csuse{@bptitle}\btitleapp}}\tempa }% }% \ifbool{uncoveredlist}{\beameruncoverspec}{\beameralertspec} \begin{BeamerProgramListExam} \programlistbeamerexam \end{BeamerProgramListExam} \end{frame} }% \fi%\else\if@jslp@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} \newif\if@jslp@session@cancel\@jslp@session@cancelfalse \newif\if@jslp@session@draft\@jslp@session@draftfalse \newif\if@jslp@session@exam\@jslp@session@examfalse \DeclareKeys[session] { % titlesep = <sep> titlesep.code = { \csdef{@sestitlesep}{{#1}} }, % subtitle = <title> subtitle.code = { \csdef{@sessubtitle}{{#1}} }, % shorttitle = <title> shorttitle.code = { \csdef{@sesshorttitle}{{#1}} \csdef{@usesshorttitle}{{#1}} }, % bibsec = <keyword> bibsec.store = \@sesbibsec, % room = <room> room.code = { \csdef{@sesroom}{{#1}} }, % starttime = <starttime> starttime.code = { \csdef{@sesrtime}{#1} \csdef{@sestime}{\DTMtime{#1}} }, % duration = <duration> duration.store = \@sesduration, % instructor = <instructor> instructor.code = { \csdef{@sesinstructor}{{#1}} \csdef{@usesinstructor}{{#1}} \iftoggle{shortinstrdef}{}{% \csdef{@sesshortinstructor}{{#1}} \csdef{@usesshortinstructor}{{#1}}% } }, % shortinstructor = <instructor> shortinstructor.code = { \csdef{@sesshortinstructor}{{#1}} \csdef{@usesshortinstructor}{{#1}} \toggletrue{shortinstrdef} }, % presstudents = <instructor> presstudents.code = { \csdef{@sespresstudents}{{#1}} }, % cancel = <true|false> cancel.if = @jslp@session@cancel, % draft = <true|false> draft.if = @jslp@session@draft, % exam = <true|false> exam.if = @jslp@session@exam, % topicnumber = <true|false> topicnumber.code = { \setcounter{sestopic}{#1-1} }, % extradate = <date> extradate.store = \@xsesdate } % \newcommand*\NewSession[2][]{% \stepcounter{sesunit} \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}} \if@jslp@session@cancel \stepcounter{cancellations} \protected@eappto\programlist{\noexpand\ProgramListCancelItem{\csuse{sesshortdate\thesnum}}{\csuse{sestitle\thesnum}}{\csuse{@sestitlesep}}{\csuse{@sessubtitle}}} \protected@eappto\programlistbeamer{\noexpand\BeamerProgramListCancelItem{\csuse{sesshortdate\thesnum}}{\csuse{sestitle\thesnum}}{\csuse{@sestitlesep}}{\csuse{@sessubtitle}}} \else \if@jslp@session@exam \stepcounter{exams} \protected@csxdef{examsesno\theexams}{\thesnum} \protected@eappto\programlistexam{\noexpand\ProgramListExamItem{\csuse{sesshortdate\thesnum}}{\csuse{sestitle\thesnum}}{\csuse{@sestitlesep}}{\csuse{@sessubtitle}}} \protected@eappto\programlistbeamerexam{\noexpand\BeamerProgramListExamItem{\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 \stepcounter{sestopic} \if@jslp@session@draft \ifcsempty{@sestitle}{\protected@csxdef{sestitle\thesnum}{\sestopic}}{} \fi \protected@eappto\programlist{\noexpand\ProgramListItem{\csuse{sesshortdate\thesnum}}{\csuse{sestitle\thesnum}}{\csuse{@sestitlesep}}{\csuse{@sessubtitle}}} \protected@eappto\programlistbeamer{\noexpand\BeamerProgramListItem{\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\ProgramListBreak{#2}} \protected@eappto\programlistbeamer{\noexpand\begin{center} (#2) \noexpand\end{center}} \else \protected@eappto\programlist{\noexpand\ProgramListBreak[#1]{#2}} \protected@eappto\programlistbeamer{\noexpand\begin{center} (#1: #2) \noexpand\end{center}} \fi } % Set break of multiple interval units \DeclareKeys[break] { % units = <int> units.store = \@breakunits, % span = <int> span.store = \@breakspan, % weeks = <int> (deprecated!) weeks.code = { \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\ProgramListBreak{#2}} \protected@eappto\programlistbeamer{\noexpand\begin{center} (#2) \noexpand\end{center}} }{% \protected@eappto\programlist{\noexpand\ProgramListBreak[\csuse{@breakspan}]{#2}} \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}[3][1]{% \setcounter{autooffsetcounter}{#1} \setcounter{autooffsettrigger}{#2} \setcounter{autooffset}{#3} } % 3) Definition of thematic blocks % \newtoggle{inblock} \newcommand*\StartBlock[1]{% \stepcounter{blocks}% \protected@eappto\programlist{\noexpand\begin{ProgramListBlock}{\Roman{blocks}}{#1}} \protected@eappto\programlistbeamer{\noexpand\BeamerProgramBlockItem{\Roman{blocks}}{#1}}% \gappto\programlistbeamer{\begin{BeamerProgramList}} \protected@xappto\programblocklistbeamer{\noexpand\BeamerProgramBlockBlocksOnlyItem{\Roman{blocks}}{#1}}% \csxdef{@currentblock}{#1}% \csxdef{@currentblockno}{\Roman{blocks}}% \global\toggletrue{inblock}% } \newcommand*\EndBlock{% \gappto\programlist{\end{ProgramListBlock}} \gappto\programlistbeamer{\end{BeamerProgramList}} \csxdef{@currentblock}{}% \csxdef{@currentblockno}{}% \global\togglefalse{inblock}% } \newcommand*\NewBlock[1]{% \EndBlock \StartBlock{#1} } \newcommand*\@PauseBlock{% \gappto\programlistbeamer{\end{BeamerProgramList}} } \newcommand*\@ResumeBlock{% % the \item here is necessary since this is nested immediately into another list \gappto\programlistbeamer{\item \begin{BeamerProgramList}} } \newenvironment{SessionBlock}[1]{\StartBlock{#1}}{\EndBlock} % 4) Beamer-specific features % % Beamer frame breaks \newcommand*\SetBeamerFrameBreak{% \iftoggle{inblock}{\@PauseBlock}{}% \stepcounter{fbreaks} \ifdefined\programlistbeamerii \ifdefined\programlistbeameriii \global\let\programlistbeameriv\programlistbeamer \else \global\let\programlistbeameriii\programlistbeamer \fi \else% \global\let\programlistbeamerii\programlistbeamer \fi \global\let\programlistbeamer\empty \iftoggle{inblock}{\@ResumeBlock}{}% } % 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} \setcounter{pressession}{1} \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}% } \newcommand*\emptypressession{---} \newcommand*\presseparator{\par} % Unstarred: use sespresstudents \newcommand\@makepreslist{% \ifbool{deflastpressession}{}{\setcounter{lastpressession}{\thesnum}}% \begin{PresList} \whiledo {\not{\value{pressession} > \value{lastpressession}}}% {% \ThisSession{\thepressession}% \if\relax\sespresstudents\relax \MakePresListLine{\thepressession}\presseparator% \emptypressession \else \MakePresListLine{\thepressession}\presseparator% \SessionPresStudents{\thepressession} \fi \stepcounter{pressession}% } \end{PresList} } \newlength\blankpreslistvspace \setlength\blankpreslistvspace{2\baselineskip} % Starred: blank list \newcommand\@makeblankpreslist{% \ifbool{deflastpressession}{}{\setcounter{lastpressession}{\thesnum}}% \begin{PresList} \whiledo {\not{\value{pressession} > \value{lastpressession}}}% {% \MakePresListLine{\thepressession}\vspace{\blankpreslistvspace} \stepcounter{pressession}% } \end{PresList} } % A beamer-specific version \newcommand*\beamerpresseparator{:\ } \newcommand\makebeamerpreslist{% \ifbool{deflastpressession}{}{\setcounter{lastpressession}{\thesnum}}% \begin{BeamerPresList} \whiledo {\not{\value{pressession} > \value{lastpressession}}}% {% \MakeBeamerPresListLine{\thepressession}\beamerpresseparator% \SessionPresStudents{\thepressession} \stepcounter{pressession}% } \end{BeamerPresList} } % % 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% } % Program line suitable for preslist \newcommand*\MakePresListLine[1]{% \LocalSession{#1}% \PresListItem{\lsesshortdate}{\lsestitle}{\lsestitlesep}{\lsessubtitle}% } \newcommand*\MakeBeamerPresListLine[1]{% \LocalSession{#1}% \BeamerPresListItem{\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