% Mark's handout style. % % Source is at https://git.betalupi.com/Mark/ormc-handouts \NeedsTeXFormat{LaTeX2e} \ProvidesClass{ormc_handout}[2022/05/07 1.1.0 ORMC Handout] % Boolean that determines solution behavior. % If false, solutions and instructor notes are hidden. \newif{\ifsolutions} \solutionstrue % Boolean that determines object numbering % If true, the same counter is used for all objects. \newif{\ifsinglenumbering} \singlenumberingfalse % Boolean. If true, don't number pages. \newif{\ifnopagenumber} \nopagenumberfalse % Boolean. If true, show a smaller solutions warning \newif{\ifshortwarning} \shortwarningfalse % Boolean. If true, do not show solution warning \newif{\ifnowarning} \nowarningfalse % Declare and parse arguments \DeclareOption{solutions}{\solutionstrue} \DeclareOption{nosolutions}{\solutionsfalse} \DeclareOption{singlenumbering}{\singlenumberingtrue} \DeclareOption{nopagenumber}{\nopagenumbertrue} \DeclareOption{shortwarning}{\shortwarningtrue} \DeclareOption{nowarning}{\nowarningtrue} \DeclareOption*{\ClassWarning{ormc_handout}{\CurrentOption ignored}} \ProcessOptions\relax % Based on article class \LoadClass{article} \makeatletter % Allow commands with @ (\makeatother is at end of this file) \newcommand\sbullet[1][.5]{\mathbin{\vcenter{\hbox{\scalebox{#1}{$\bullet$}}}}} \renewcommand{\labelitemi}{$\sbullet$} \renewcommand{\labelitemii}{$\cdot$} % Hack for command-line arguments. % To force a build with solutions, run % latexmk % -synctex=1 % -interaction=nonstopmode % -file-line-error % -outdir=%OUTDIR% % -xelatex % -jobname=%DOCFILE%.sol % -pdfxelatex="xelatex %O \"\\def\\argYesSolutions{1}\\input{%S}\"" % %DOC% % % Or, make a new file with the contents % \def\argYesSolutions{1}\input{} % and build that with latex. \ifdefined\argYesSolutions \solutionstrue \else \ifdefined\argNoSolutions \solutionsfalse \fi \fi %%% PACKAGES %%% % Set up page geometry. % MUST BE DONE FIRST! \RequirePackage{geometry} \geometry{ paper = letterpaper, top = 25mm, bottom = 30mm, left = 30mm, right = 30mm, headheight = 75mm, footskip = 15mm, headsep = 75mm, } \RequirePackage{enumitem} % list customization \RequirePackage{xparse} % Provides powerful macros via \NewDocumentCommand \RequirePackage{xcolor} % For colored text \RequirePackage{tcolorbox} % For solution boxes \RequirePackage{tikz} % Used by \boxlinehack \RequirePackage{comment} % Used to hide solutions \RequirePackage{fancyhdr} % Header/Footer customization \RequirePackage{adjustbox} % Used for title \RequirePackage[ left = ``, right = '', leftsub = `, rightsub = ' ]{dirtytalk} % Not used by this class, but likely to be used in documents \RequirePackage{amsmath} \RequirePackage{amssymb} \RequirePackage{multicol} %%% CONFIG %%% % No paragraph indentation, no list item spacing, % raggedright layout (hyphenation is excessive). \setlength{\parindent}{0mm} \setlist{noitemsep, topsep=0mm} \raggedright \renewcommand*{\thefootnote}{\arabic{footnote}} % One space after a period. \frenchspacing % Fancyhdr setup \pagestyle{fancy} \fancyhf{} \renewcommand{\headrulewidth}{0mm} \ifnopagenumber \else \fancyfoot[C]{\thepage} \fi %%% COMMANDS %%% % Make a heading. % Arguments: % % First: Top-left text % Second: Top-right text % Both are optional, but should only be provided TOGETHER. % % Third: Title % Forth: author \RenewDocumentCommand{\maketitle}{ d<> d<> m m } { \begin{adjustbox}{minipage=0.7\textwidth, margin=0pt \smallskipamount,center} \begin{center} \IfNoValueF{#1}{\textsc{#1}} \hfill \IfNoValueF{#2}{\textsc{#2}} \par \rule{\linewidth}{0.2mm} \par \huge #3 \par \normalsize \vspace{1ex} #4 \rule{\linewidth}{0.2mm} \par % Instructor's handout warning \ifnowarning\else \ifsolutions % Short warning \ifshortwarning \begin{tcolorbox}[ colback=white, colframe=red ] \begin{center} \large \textcolor{red}{ \textbf{Instructor's Handout} } \par \normalsize \end{center} \end{tcolorbox} \else % Regular warning \begin{tcolorbox}[ colback=white, colframe=red ] \begin{center} \large \textcolor{red}{ \textbf{Instructor's Handout} } \par \normalsize \end{center} \vspace{1ex} \textcolor{red}{This file contains solutions and notes.} \textcolor{red}{Compile with the ``nosolutions'' flag before distributing.} \end{tcolorbox} \fi \fi\fi \end{center} \end{adjustbox} } % Helper command that creates a label with custom text. % First arg: label name % Second arg: custom text \newcommand{\customlabel}[2]{% \protected@write \@auxout {}{ \string \newlabel {#1}{{#2}{}} } } % Commands for problems, theorems, and definitions % % Each of these take two arguments. For example: % % \problem{} makes an unnamed problem % \problem{Division} makes a named problem % \problem{} % makes a problem and a label "problem:gcd" % that gives text "Problem X" when referenced. \newcounter{section_counter} \newcounter{problempartcounter} \ifsinglenumbering \newcounter{object_counter} \def\problemcounter{object_counter} \def\theoremcounter{object_counter} \def\definitioncounter{object_counter} \def\examplecounter{object_counter} \def\propositioncounter{object_counter} \else \newcounter{problem_counter} \newcounter{theorem_counter} \newcounter{definition_counter} \newcounter{example_counter} \newcounter{proposition_counter} \def\problemcounter{problem_counter} \def\theoremcounter{theorem_counter} \def\definitioncounter{definition_counter} \def\examplecounter{example_counter} \def\propositioncounter{proposition_counter} \fi % Generic object command. % First arg: counter name (mandatory) % Second arg: object type (optional) % Third arg: object title (mandatory, can be empty) % % If the second argument is ommited, the counter is hidden % and only the object title is shown. For example: % \@object{counter}[Problem]{Example Problem} -> Problem 1: Example Problem % \@object{counter}{Example Problem} -> Example Problem % % Only used internally (See following definitions) \NewDocumentCommand{\@object}{ m d[] m}{ \stepcounter{#1} \vspace{3mm} \IfNoValueTF{#2} { {\bf\normalsize #3} } { {\bf\normalsize #2 \arabic{#1}:\IfNoValueF{#3}{ #3}} } } % Generic object. % Does the same thing as \problem, \theorem, etc, but with no counter. \NewDocumentCommand{\generic}{ m d<> }{ \vspace{3mm} {\bf\normalsize #1} \\lat* \IfNoValueF{#2}{ \customlabel{#2}{#1} } } % If not starred, text is "Part X: " % If starred, text is "<title>" \RenewDocumentCommand{\section}{ s m d<> }{ \stepcounter{section_counter} \vspace{8mm} \IfBooleanTF{#1}{ {\bf\Large \hfill #2 \hfill} \IfNoValueF{#3}{\customlabel{#3}#2} \\* } { {\bf\Large \hfill Part \arabic{section_counter}\IfNoValueF{#2}{: #2} \hfill} \IfNoValueF{#3}{\customlabel{#3}Part \arabic{section_counter}} \\* } \vspace{2mm} } \RenewDocumentCommand{\paragraph}{}{ \hspace{1cm} } \NewDocumentCommand{\problem}{ m d<> }{ \setcounter{problempartcounter}{0} \@object{\problemcounter}[Problem]{#1} \IfNoValueF{#2}{ \customlabel{#2}{Problem \arabic{\problemcounter}} \customlabel{NUM:#2}{\arabic{\problemcounter}} } \\* } \NewDocumentCommand{\problempart}{ m d<> }{ \@object{problempartcounter}[Part]{#1} \IfNoValueF{#2}{ \customlabel {#2} {Problem \arabic{\problemcounter}\alph{problempartcounter}} \customlabel{NUM:#2}{\arabic{\problemcounter}\alph{problempartcounter}} } \\* } \NewDocumentCommand{\definition}{ m d<> }{ \@object{\definitioncounter}[Definition]{#1} \IfNoValueF{#2}{ \customlabel{#2}{Definition \arabic{\definitioncounter}} \customlabel{NUM:#2}{\arabic{\definitioncounter}} } \\* } \NewDocumentCommand{\theorem}{ m d<> }{ \@object{\theoremcounter}[Theorem]{#1} \IfNoValueF{#2}{ \customlabel{#2}{Theorem \arabic{\theoremcounter}} \customlabel{NUM:#2}{\arabic{\theoremcounter}} } \\* } \NewDocumentCommand{\proposition}{ m d<> }{ \@object{\propositioncounter}[Proposition]{#1} \IfNoValueF{#2}{ \customlabel{#2}{Proposition \arabic{\propositioncounter}} \customlabel{NUM:#2}{\arabic{\propositioncounter}} } \\* } \NewDocumentCommand{\example}{ m d<> }{ \@object{\examplecounter}[Example]{#1} \IfNoValueF{#2}{ \customlabel{#2}{Example \arabic{\examplecounter}} \customlabel{NUM:#2}{\arabic{\examplecounter}} } \\* } % Solution environment. % examplesolution environment is always shown (useful for example problems) % solution environments do the same thing, but are hidden when the [nosolutions] flag is passed. \newenvironment{examplesolution} { \begin{tcolorbox}[ colback=white, colframe=gray!75!black, title={\textbf{Example Solution}} ] }{ \end{tcolorbox} } \def\ORMCbgcolor{white} % \if isn't parsed inside of LaTeX environents, % so we have to use the comment package. \newenvironment{@shown_solution} { \def\ORMCbgcolor{red!5!white} \begin{tcolorbox}[ colback=red!5!white, colframe=red!75!black, title={\textbf{Solution}} ] \raggedright }{ \end{tcolorbox} } \newenvironment{@shown_note} { \def\ORMCbgcolor{cyan!5!white} \begin{tcolorbox}[ colback=cyan!5!white, colframe=cyan!75!black, title={\textbf{Note for Instructors}} ] \raggedright }{ \end{tcolorbox} } % tcolorbox only give us two sections. % This macro makes a macro \linehack that draws % lines across a tcolorbox. % % Inside every environment that needs a % \linehack macro, put \@makelinehack{color}. \newcommand{\@makelinehack}[1]{ \newcommand{\linehack}{ \begin{tikzpicture} \path[use as bounding box] (0, 0) -- (\linewidth, 0); \draw[ color=#1, dashed, dash phase=1mm ] ( 0 - \kvtcb@leftlower-\kvtcb@boxsep, 0 ) -- ( \linewidth + \kvtcb@rightlower + \kvtcb@boxsep, 0 ); \end{tikzpicture} \par \vspace{2mm} } } \ifsolutions \newenvironment{solution}{ \@makelinehack{red!75!black} \begin{@shown_solution} } { \end{@shown_solution} } \newenvironment{instructornote}{ \@makelinehack{cyan!75!black} \begin{@shown_note} } { \end{@shown_note} } \else \excludecomment{solution} \excludecomment{instructornote} \fi \NewDocumentCommand{\note}{ d<> m }{ \IfNoValueTF{#1} { \textcolor{gray}{#2} \par } { \textcolor{gray}{\textit{#1:} #2} \par } } \NewDocumentCommand{\hint}{ m }{ \note<Hint>{#1} } \makeatother