\ProvidesPackage{brandeis-problemset}[2019/04/15 0.5.5 Commands for COSI problem sets at Brandeis University] \NeedsTeXFormat{LaTeX2e} % utility \RequirePackage{xparse} \RequirePackage{xkeyval} \RequirePackage{kvoptions} \SetupKeyvalOptions{ family=bps, prefix=bps@, } % initializes complementary #1 and no#1 options \NewDocumentCommand{\bps@comploption}{O{false} m}{% \DeclareBoolOption[#1]{#2}% \DeclareComplementaryOption{no#2}{#2}} \bps@comploption{scheme} \bps@comploption{pseudocode} \bps@comploption{assembly} \bps@comploption{gantt} \bps@comploption{solution} \bps@comploption{maketitle} \bps@comploption{header} \bps@comploption{tabu} \bps@comploption{listings} \bps@comploption{config} \ProcessKeyvalOptions* \let\bps@comploption\relax \RequirePackage{changepage} \newif\iffontspec@ok \fontspec@okfalse \ExplSyntaxOn \sys_if_engine_luatex:T { \fontspec@oktrue } \sys_if_engine_xetex:T { \fontspec@oktrue } \ExplSyntaxOff \newif\ifbps@listingssetup \newcommand{\bps@setuplistings}{% \ifbps@listingssetup \else \RequirePackage{listings}% \lstset{ basicstyle=\ttfamily, numbers=left, numberstyle=\color{gray}\ttfamily, aboveskip=1em, belowskip=0.5em, breaklines, breakatwhitespace=true, tabsize=4, keywordstyle={\bf\ttfamily\color[rgb]{0,.3,.7}}, commentstyle={\color[rgb]{0.133,0.545,0.133}}, stringstyle={\color[rgb]{0.75,0.49,0.07}}, }% \RequirePackage{xcolor}% \bps@listingssetuptrue \fi } \ifbps@listings \bps@setuplistings \lstnewenvironment{java}[1][] {\lstset{language=java, #1}} {} \fi \ifbps@scheme \bps@setuplistings % Language definition by Rebecca Turner and Andreas Stuhlmüller. \lstdefinelanguage[R5RS]{Scheme}{ morekeywords={*,/,<=,<,=>,=,>=,>,+,-,% % ``These procedures are compositions of car and cdr \dots\ % Arbitrary compositions, up to four deep, are provided. There are % twenty-eight of these procedures in all.'' (6.3.2) car,cdr,caar,cadr,cdar,cddr,caaar,caadr,cadar,caddr,cdaar,% cdadr,cddar,cdddr,caaaar,caaadr,caadar,caaddr,cadaar,cadadr,% caddar,cadddr,cdaaar,cdaadr,cdadar,cdaddr,cddaar,cddadr,cdddar,% cddddr,% % Define the rest of the primitives, from R5RS' % \href{https://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-15.html#%_chap_Temp_11}{``Alphabetic % Index of Definitions of Concepts, Keywords, and Procedures''} abs,acos,and,angle,append,apply,asin,assoc,% assq,assv,atan,begin,boolean?,% call-with-current-continuation,call-with-input-file,% call-with-output-file,call-with-values,case,% ceiling,char->integer,char-alphabetic?,char-ci<=?,char-ci=?,char-ci>?,char-downcase,char-lower-case?,% char-numeric?,char-ready?,char-upcase,char-upper-case?,% char-whitespace?,char<=?,char=?,char>?,char?,% close-input-port,close-output-port,complex?,cond,cons,cos,% current-input-port,current-output-port,define,define-syntax,delay,% denominator,display,do,dynamic-wind,else,eof-object?,eq?,% equal?,eqv?,eval,even?,exact->inexact,exact?,exp,expt,floor,% for-each,force,gcd,if,imag-part,inexact->exact,inexact?,% input-port?,integer->char,integer?,interaction-environment,lambda,% lcm,length,let,let*,let-syntax,letrec,letrec-syntax,list,% list->string,list->vector,list-ref,list-tail,list?,load,log,% magnitude,make-polar,make-rectangular,make-string,make-vector,% map,max,member,memq,memv,min,modulo,negative?,newline,not,% null-environment,null?,number->string,number?,numerator,odd?,% open-input-file,open-output-file,or,output-port?,pair?,peek-char,% port?,positive?,procedure?,quasiquote,quote,quotient,rational?,% rationalize,read,read-char,real-part,real?,remainder,reverse,% round,scheme-report-environment,set!,set-car!,set-cdr!,setcar,% sin,sqrt,string,string->list,string->number,string->symbol,% string-append,string-ci<=?,string-ci=?,% string-ci>?,string-copy,string-fill!,string-length,string-ref,% string-set!,string<=?,string=?,string>?,% string?,substring,symbol->string,symbol?,syntax-rules,tan,% transcript-off,transcript-on,truncate,values,vector,vector->list,% vector-fill!,vector-length,vector-ref,vector-set!,vector?,% with-input-from-file,with-output-to-file,write,write-char,zero?}, otherkeywords={\#b,\#o,\#d,\#x,\#e,\#i,\#t,\#f,% ',`,{,},\,\@,...}, alsoletter={!\$\%&*/:<=>?@^_~+-}, alsodigit={.}, sensitive=true, morecomment=[l]{;}, morecomment=[s]{\#|}{|\#}, morestring=[b]", upquote=true, literate=*{`}{{`}}{1} }[keywords,comments,strings] \lstset{ defaultdialect=[R5RS]Scheme } \lstnewenvironment{scheme}[1][] {\lstset{language=Scheme, #1}} {} \fi \ifbps@assembly \bps@setuplistings \lstdefinelanguage{assembly}{ keywords={LOAD,STORE,ADD,SUB,MUL,DIV,INC,SKIP,BR,BLT,BGT,BLEQ,BGEQ, BEQ,BNEQ,READ,WRITE,HALT}, firstnumber=-3, numberstyle={\color{gray}\ttfamily\addtocounter{lstnumber}{3}x +\ }, morecomment=[l]{;}, } \lstnewenvironment{assembly}[1][] {\lstset{language=assembly, #1}}{} \fi \ifbps@gantt \RequirePackage{tikz} \RequirePackage{fp} \RequirePackage{calc} \newcounter{bps@gantt@time} \newcounter{bps@gantt@time@after} \newlength{\bps@gantt@unit} \NewDocumentEnvironment{ganttschedule}{m o} % total size, title {\setlength{\bps@gantt@unit}{\linewidth / \real{#1}}% \setcounter{bps@gantt@time}{0}% \DeclareDocumentCommand{\burst}{m m} % pid, burst {\setcounter{bps@gantt@time@after}{\value{bps@gantt@time}}% \addtocounter{bps@gantt@time@after}{##2}% \FPeval\gantthalf{(\arabic{bps@gantt@time} + \arabic{bps@gantt@time@after}) / 2}% \draw (\value{bps@gantt@time}, 0) rectangle (\value{bps@gantt@time@after}, 1); \node at (\gantthalf, 0.5) {$P_{##1}$}; \draw [|<->|] (\value{bps@gantt@time} + 0.05, 1.25) -- node[above=1mm] {##2} (\value{bps@gantt@time@after} - 0.05, 1.25); \setcounter{bps@gantt@time}{\value{bps@gantt@time@after}}}% \IfValueT{#2}{\begin{center} #2 \end{center}}% \begin{tikzpicture}[x=\bps@gantt@unit]} {\end{tikzpicture}} \else \NewDocumentEnvironment{ganttschedule}{m o} {\PackageError{brandeis-problemset}{ganttschedule enviornment not loaded in preamble}{Did you mean to use the 'gantt' option for the brandeis-problemset package/document class?}}{} \fi \let\pseudocodesymbolfont\ttfamily \ifbps@pseudocode \bps@setuplistings % pseudocode commands \iffontspec@ok % use unicode shortcuts \newcommand{\bps@pcsym}[2] {\expandafter\providecommand \csname pseudocode#1\endcsname {\pseudocodesymbolfont #2}} \bps@pcsym{leftarrow} {←} \bps@pcsym{rightarrow}{→} \bps@pcsym{le} {≤} \bps@pcsym{ge} {≥} \bps@pcsym{emptyset} {∅} \bps@pcsym{ne} {≠} \bps@pcsym{infty} {∞} \@ifundefined{lmmath}{\@ifundefined{newfontface}{}{% \newfontface{\lmmath}{latinmodern-math.otf}% }}{}% \@ifundefined{lmmath}{}{% \let\pseudocodesymbolfont\lmmath }% \else % use math-mode fallbacks \newcommand{\bps@pcsym}[2] {\expandafter\providecommand \csname pseudocode#1\endcsname {\ensuremath{#2}}} \bps@pcsym{leftarrow} {\leftarrow} \bps@pcsym{rightarrow}{\rightarrow} \bps@pcsym{le} {\le} \bps@pcsym{ge} {\ge} \bps@pcsym{emptyset} {\emptyset} \bps@pcsym{ne} {\ne} \bps@pcsym{infty} {\infty} \fi \lstdefinelanguage{Pseudocode}{ keywords={Input,Output,Complexity,while,do,return,for,to,if,then,else,True,False,None,and,or,nil,len}, literate={<-}{{\pseudocodeleftarrow}}2 {->} {{\pseudocoderightarrow}}2 {(/)}{{\pseudocodeemptyset}}2 {inf}{{\pseudocodeinfty}}3 {!=} {{\pseudocodene}}2 {>=} {{\pseudocodege}}2 {<=} {{\pseudocodele}}2, morecomment=[l]{\#}, } \lstnewenvironment{pseudocode}[1][] {\lstset{ language=Pseudocode, morekeywords={#1}, }}{} \fi \let\bps@setuplistings\relax % tables \ifbps@tabu \ProvideExpandableDocumentCommand{\Th}{O{l} m} {\multicolumn{1}{#1}{\Bf{#2}}} \fi \newcommand{\solutionstyle}{\color{blue}} \ifbps@solution \newenvironment{solution} {\solutionstyle} {} \else \RequirePackage{comment} \excludecomment{solution} \fi \ifbps@maketitle \bps@configtrue \fi \ifbps@header \bps@configtrue \fi \ifbps@config % config commands \define@cmdkeys{bps}[bps@]{duedate, instructor, course, assignment} % wrappers \define@key{bps}{author}{\author{#1}} \define@key{bps}{date}{\date{#1}} % helpers \define@key{bps}{number}{\def\bps@assignment{Problem Set #1}} \define@key{bps}{coursenumber}{\def\bps@course{\textsc{cosi} #1}} \define@key{bps}{codefont}{\setcodefont{#1}} \newcommand{\bpsset}[1]{\setkeys{bps}{#1}} \let\problemsetsetup\bpsset \fi \ifbps@maketitle \NewDocumentCommand{\bps@titlerow}{o m}{\@ifundefined{bps@#2}{}% {\IfValueTF{#1}{#1}{#2} & \csname bps@#2\endcsname \\}} \renewcommand{\maketitle}{\thispagestyle{empty}% \begin{center}% \Large\begin{tabular}{r|l} \bps@titlerow{assignment}% by & \@author \\ \bps@titlerow{course}% \bps@titlerow{instructor}% \bps@titlerow[due]{duedate}% \end{tabular}% \end{center}% \vspace*{2em}} \newcommand{\maketitlepage}{\thispagestyle{empty}% \vspace*{2in}% \maketitle \pagebreak} \fi \ifbps@header % page headers \RequirePackage{fancyhdr} \fancyhf{} \lhead{\@author \hfill \@ifundefined{bps@assignment}{}{\bps@assignment}% \@ifundefined{bps@duedate}{}{\ (due \bps@duedate)}\hfill \@ifundefined{bps@instructor}{}{\bps@instructor\hfill}% \thepage} \setlength{\headheight}{24pt} \fancypagestyle{plain}{\fancyhead[L]{}} \AtBeginDocument{\pagestyle{fancy}} \fi \let\ac\textsc \ProvideDocumentCommand{\newacronym}{o m} {\IfValueTF{#1}% {\def#1{\ac{#2}}}% {\expandafter\def\csname #2\endcsname{\ac{#2}}}} \ProvideDocumentCommand{\newacronyms}{>{\SplitList{,}} m} {\ProcessList{#1}{\newacronym}} % #1: env name % #2: pagebreak default \newcommand{\bps@problemkeys}[2]{% \expandafter\newlength\csname bps@#1indent\endcsname \expandafter\setlength\csname bps@#1indent\endcsname{1in}% \expandafter\def\csname bps@#1@title\endcsname{% \@ifundefined{cmdKV@#1@title}% {}% {: \csname cmdKV@#1@title\endcsname}}% \expandafter\def\csname bps@#1@number\endcsname{\arabic{#1number}}% \expandafter\def\csname bps@#1pagebreak\endcsname{% \csname ifKV@#1@pagebreak\endcsname \vfill\pagebreak \fi}% \define@boolkey{#1}{pagebreak}[true]{\csname bps@#1pagebreak\endcsname}% \expandafter\def\csname bps@#1@tocstar\endcsname{% \csname ifKV@#1@toc\endcsname \else *% \fi}% \define@boolkey{#1}{toc}[true]{}% \define@cmdkeys{#1}{number, label, title}% \presetkeys{#1}{pagebreak=#2, toc}{}% } \newcounter{problemnumber} \newcounter{subproblemnumber}[problemnumber] \bps@problemkeys{problem}{true} \bps@problemkeys{subproblem}{false} \define@cmdkeys{problem}{partlabel} \define@cmdkey{problem}{part}[]{% \part{\cmdKV@problem@part}% \@ifundefined{cmdKV@problem@partlabel}{}{% \expandafter\label{\cmdKV@problem@partlabel}% }% } % common code for subproblem and problem envs % #1: env name % #2: @currentlabel code % #3: sectioning command \newcommand{\bps@problem@}[3]{% % define problem number based on user input (or lack thereof) \@ifundefined{cmdKV@#1@number}{% \stepcounter{#1number}% }{% \expandafter\def\csname bps@#1@number\endcsname {\expandafter\noexpand\csname cmdKV@#1@number\endcsname}% }% % define labels for \ref and the like \def\@currentlabel{#2}% \edef\bps@problem@title@{Problem \@currentlabel% the problem number \expandafter\noexpand\csname bps@#1@title\endcsname} \def\@currentlabelname{\bps@problem@title@}% % no spaces or numbers before the \section command \renewcommand{\@seccntformat}[1]{}% \typeout{\@currentlabelname} \csname ifKV@#1@toc\endcsname \def\bps@problem@section{#3}% \else \def\bps@problem@section{#3*}% \fi % make the section (#3 is \section or something) % NOTE: If you use \@currentlabelname for the title, the document % will pause on compilation on this line; I don't know why this is, % but it goes away if hyperref isn't loaded (my guess is that % hyperref redefines \@currentlabelname to do something weird and % possibly-recursive with \@currentlabel). Either way, defining an % alternate command for the title works here. \bps@problem@section{\bps@problem@title@}% % fix up ref commands \@ifundefined{cmdKV@#1@label}{}{% \expandafter\label{\csname cmdKV@#1@label\endcsname}% }% } \NewDocumentEnvironment{problem}{O{}}{% \setkeys{problem}{#1}% \@ifundefined{cmdKV@problem@number}{}{\setcounter{subproblemnumber}{0}}% \bps@problem@{problem}{\bps@problem@number}{\section}% \begin{adjustwidth}{\bps@problemindent}{0pt}} {\end{adjustwidth}} % make sure to keep this code in sync with the problem env code \NewDocumentEnvironment{subproblem}{O{}}{% \setkeys{subproblem}{#1}% \bps@problem@{subproblem}{\bps@problem@number.\bps@subproblem@number}{\subsection}% \begin{adjustwidth}{\bps@subproblemindent}{0pt}} {\end{adjustwidth}}