summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/brandeis-problemset/brandeis-problemset.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/brandeis-problemset/brandeis-problemset.sty
Initial commit
Diffstat (limited to 'macros/latex/contrib/brandeis-problemset/brandeis-problemset.sty')
-rw-r--r--macros/latex/contrib/brandeis-problemset/brandeis-problemset.sty426
1 files changed, 426 insertions, 0 deletions
diff --git a/macros/latex/contrib/brandeis-problemset/brandeis-problemset.sty b/macros/latex/contrib/brandeis-problemset/brandeis-problemset.sty
new file mode 100644
index 0000000000..209138d390
--- /dev/null
+++ b/macros/latex/contrib/brandeis-problemset/brandeis-problemset.sty
@@ -0,0 +1,426 @@
+\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-ci>=?,char-ci>?,char-downcase,char-lower-case?,%
+ char-numeric?,char-ready?,char-upcase,char-upper-case?,%
+ char-whitespace?,char<=?,char<?,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-ci>=?,%
+ string-ci>?,string-copy,string-fill!,string-length,string-ref,%
+ string-set!,string<=?,string<?,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}}