From 2a2064a6703227e76bda9c3b1a62373ab6d92b9f Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Wed, 21 Aug 2013 09:14:54 -0400 Subject: [PATCH] Began refactoring dwspec.sty into lvspec.cls and dwspec.cls --- lvspec.cls | 495 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 495 insertions(+) create mode 100644 lvspec.cls diff --git a/lvspec.cls b/lvspec.cls new file mode 100644 index 0000000..5b84fce --- /dev/null +++ b/lvspec.cls @@ -0,0 +1,495 @@ +% LoVullo Specification class + +\NeedsTeXFormat{LaTeX2e} +\ProvidesClass{lvspec} +\RequirePackage{kvoptions} +\RequirePackage{kvoptions-patch} + +\DeclareBoolOption{bw} +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{scrreprt}} +\ProcessOptions\relax + +% base class +\LoadClass{scrreprt} + +\RequirePackage[top=3.5cm,bottom=5cm,width=\textwidth]{geometry} +\RequirePackage{makeidx} +\RequirePackage{minitoc} +\RequirePackage{titlesec} +\RequirePackage{hyperref} +\RequirePackage[usenames,dvipsnames]{xcolor} +\RequirePackage{url} +\RequirePackage{varioref} +\RequirePackage{amsmath} +\RequirePackage{multirow} + +% default hyperlink color +\definecolor{hyperlink}{HTML}{000040} +% unless black and white +\iflvspec@bw + \definecolor{hyperlink}{HTML}{000000} +\fi +\hypersetup{ + % get rid of box in older versions of hyperref + colorlinks=true, + linkcolor=hyperlink, + citecolor=black, + filecolor=black, + urlcolor=blue, + final % enable links in draft mode +} + +% reduce section spacing after sections and before subsections (carefully +% balanced with \parskip below) +\titlespacing{\section}{0em}{1em plus 1em minus 0.5em}{0em plus 0.5em} +\titlespacing{\subsection}{0em}{0em plus 0.5em}{0em} +\titlespacing{\subsubsection}{0em}{0em plus 0.5em}{0em} + +% remove indentation and provide flexible paragraph spacing (this style of +% display is more appropriate for paragraph numbering) +\parindent0ex +\parskip1em plus 0.2em minus 0.5em + +% show subsubsection numbers +\setcounter{tocdepth}{4} +\setcounter{minitocdepth}{4} +\setcounter{secnumdepth}{4} + +% the version string is taken directly from a file written by the build process +\def\@verstr{{\footnotesize\tt\input{verstr.tex}}} + +\def\@oddhead{\small\sc\rightmark\hfill TODO} +\let\@evenhead\@oddhead +\def\@oddfoot{\S\thefullsection\hfill\thepage\hfill\@verstr} +\let\@evenfoot\@oddfoot + +% section numbers will appear in the margin and the chapter number will be +% slightly enlarged +\titleformat{\chapter} + {\huge\bfseries\sffamily} + {\llap{{\Huge\thechapter}\hskip1ex}} + {0em} + {\aftergroup\minitoc\aftergroup\minilot\aftergroup\minilof} +\titleformat{\section} + {\Large\bfseries\sffamily} + {\llap{\thesection\hskip1ex}} + {0em} + {} +\titleformat{\subsection} + {\large\bfseries\sffamily} + {\llap{\thesubsection\hskip1ex}} + {0em} + {} +\titleformat{\subsubsection} + {\normalsize\bfseries\sffamily} + {\llap{\thesubsubsection\hskip1ex}} + {0em} + {} + + +% lazy +\let\@minitoc@orig\minitoc +\def\minitocoff{\gdef\minitoc{}} +\def\minitocon{\global\let\minitoc\@minitoc@orig} + +% enable index generation +\makeindex + + +%% +% Paragraph numbering and example environment +% +\newcount\pn \newcount\pnn +\pn0\relax \pnn1\relax + +\newcount\pne +\pne1\relax + +\def\pnum{{% + % never show paragraph numbers within an environment (LaTeX stores the name of + % the current environment in @currenvir) + \def\@@document{dwspec}% + \def\@@premcalc{premcalc}% + % allow dwspec by default + \let\@@cmp\@currenvir + % allow premcalc env + \ifx\@currenvir\@@premcalc + \let\@@cmp\@@document + \fi + % output if match + \ifx\@@cmp\@@document% + \ifx\haspnum1\relax + \@margin@sig% + \global\advance\pn1\relax% + \global\advance\pnn1\relax% + \global\pne0\relax% + \ifvmode\leavevmode\fi% + \llap{\the\pn. \,\,}% + \fi + \fi +}} + +% margin area for paragraph signatures (initials) +\def\@margin@sig{% + % if in draft mode, add a spot next to the paragraph for initials + \ifdwspec@draft% + \pnumoff% + \marginpar{% + \ifx\@@margin@sig@repl\empty% + % generate signature line slightly below the line itself + \underline{\hspace{3em}}% + \ifx\@@margin@sig@dept\relax + % one needs to be assigned + \PackageWarning{dwspec}{missing authorization party in% + \space\thechapter.\thesection}% + \else + \space{\scriptsize(\@@margin@sig@dept)}% + % clear the department, if necessary + \@margin@sig@cleardept + \fi + \else% + % use custom line and clear it + \@@margin@sig@repl% + \if@keepsigtext\else + \gdef\@@margin@sig@repl{}% + \fi + \fi% + }% + \pnumon% + \fi% +} + +% for use externally +\let\signline\@margin@sig +\def\sigkeep{\global\@keepsigtexttrue} +\def\sigunkeep{ + \global\@keepsigtextfalse + \gdef\@@margin@sig@repl{}% +} + +% optional replacement text for next signature line +\let\@@margin@sig@repl\relax +% department that should do the signing +\let\@@margin@sig@dept\relax + +\newif\if@@sectiondept +\let\@@groupdept\relax + +\def\@margin@sig@cleardept{% + % do not clear if we're in a department group + \ifx\@@groupdept\relax + \global\let\@@margin@sig@dept\relax + \fi +} + +% specifies the department(s) that are the intended audience (applies for a +% single signature line) +\def\dept#1{% + \def\@@margin@sig@dept{% + \hyperref[s:authorize]{\uppercase{#1}}% + }% +} +% indicates that an entire section applies to a given department (will be +% automatically cleared when a new section is encountered) +\def\sectiondept#1{% + \dept{#1}% + \@@sectiondepttrue + \def\@@groupdept{}% +} +% applies a department until the group is closed (may be nested); will clear +% section grouping +\def\begindeptgroup#1{% + \begingroup + \dept{#1}% + % using this def instead of an if boolean allows us to nest (will go out of + % scope when the group is ended) + \def\@@groupdept{}% + % disable section grouping (to prevent clearing the department when a new + % section is encountered) + \@@sectiondeptfalse +} +\def\enddeptgroup{% + \endgroup +} + + +% add paragraph numbering (we can't just set \everypar like we can in good 'ol +% TeX because LaTeX has its way with it) +\let\oldep\everypar +\let\haspnum0\relax +\let\hadpnum0\relax +\newtoks\everyparon +\newtoks\everyparoff +\def\pnumon{% + \oldep{\the\everyparon\pnum}% + \let\hadpnum\haspnum% + \let\haspnum1% +} +\def\pnumoff{% + \oldep{\the\everyparoff}% + \let\hadpnum\haspnum% + \let\haspnum0% +} +\def\pnumrest{% + \ifx\hadpnum1\relax + \pnumon% + \else% + \pnumoff% + \fi% +} +% outputs what will be the next page number +\def\sinit{% + \pn0\relax \pnn1\relax + % clear any department sections, if necessary + \if@@sectiondept + \@@sectiondeptfalse + \global\let\@@margin@sig@dept\relax + \fi +} + +\let\@chapterorig\chapter +\let\@sectionorig\section +\let\@subsectionorig\subsection +\let\@subsubsectionorig\subsubsection +\let\@footnoteorig\footnote +\let\@footnotetextorig\footnotetext + +% override chapter/section macros (it is important not to do this until we are +% sure that nothing with use \chapter, as that formally does not accept an +% argument...we treat it as though it does in order to make life easier) +\def\@hgrab{ + \gdef\chapter##1{\pnumoff\@chapterorig{##1}\pnumrest\sinit} + \gdef\section##1{\pnumoff\@sectionorig{##1}\pnumrest\sinit\smarkright{##1}} + \gdef\subsection##1{\pnumoff\@subsectionorig{##1}\pnumrest\sinit\smarkright{##1}} + \gdef\subsubsection##1{\pnumoff\@subsubsectionorig{##1}\pnumrest\sinit\smarkright{##1}} + \gdef\footnote##1{\pnumoff\@footnoteorig{##1}\pnumrest} + \gdef\footnotetext##1{\pnumoff\@footnotetextorig{##1}\pnumrest} +} + +% restore headings +\def\@hrestore{ + \let\chapter\@chapterorig + \let\section\@sectionorig + \let\subsection\@subsectionorig + \let\subsubsection\@subsubsectionorig + \let\footnote\@footnoteorig + \let\footnotetext\@footnotetextorig +} + +\def\smarkright#1{\markright{\S\thefullsection~#1}} + +% these may be used for included files that aren't sure what level of section +% nesting they may be included at +\def\nextsection{% + \begingroup% + \ifnum\value{subsubsection}>0\relax% + \errmessage{Sorry; section nesting is too deep}% + \else\ifnum\value{subsection}>0\relax% + \aftergroup\subsubsection% + \else\ifnum\value{section}>0\relax% + \aftergroup\subsection% + \else% + \aftergroup\section% + \fi\fi\fi% + \endgroup% +} + + +% outputs the full section number, regardless of current depth +\def\thefullsection{% + \ifnum\value{subsubsection}>0\relax% + \thesubsubsection% + \else\ifnum\value{subsection}>0\relax% + \thesubsection% + \else\ifnum\value{section}>0\relax% + \thesection% + \else% + \thechapter% + \fi\fi\fi% +} +\def\thepne{\ifnum\the\pne>1\relax-\the\pne\fi} + +\newenvironment{ex}% + {% + \goodbreak% + \global\advance\pne1\relax% + \list{}{% + \leftmargin4ex + \item\relax + \small% + }% + {\bf Example \thefullsection-\the\pn\thepne:\space}% + \ignorespaces + }% + {% + $\square$ + \endlist + \par + \goodbreak + } + + +%% +% Common macros +% +\def\shall {Shall } +\def\shallnot {Shall Not } +\def\must {Must } +\def\mustnot {Must Not } +\def\may {May } +\def\exempt {Exempt } +\def\unspecified{Unspecified} +\AtBeginDocument{% + % this guy causes problems with some macros that make the poor choice of using + % \undefined to represent a macro that is, well, not defined + \gdef\undefined{Undefined} +} + +% formatting +\def\dt#1{% + \goodbreak% + \@dt@idx#1;||% + \item[#1]\hfill\\% + % display signature area in margin + \@margin@sig% + % get rid of mysterious magical hspace that appears from the marginpar + \hskip-1ex\relax% +} +\def\dfn#1{{\sl\@idxhat@idx{#1}\/}} +\def\rfc#1{{\tt RFC #1}} +\def\hex#1{{\tt 0x#1}} +\def\code#1{{\tt#1}} +\def\func#1{{\tt #1()}} +\def\set#1{% + \ifmmode% + \left\{#1\right\}% + \else% + $\set{#1}$% + \fi% +} + +% non-technical-reader-friendly if not in math mode +\def\true{\ifmmode\top\else Yes\fi} +\def\false{\ifmmode\bot\else No\fi} + +\def\vecset#1{% + \ifmmode% + \left[\,#1\,\right]% + \else% + $\vecset{#1}$% + \fi% +} + +\def\todo#1{{\sc Todo: \it#1\/}} + +% trim a single space from the left, if present +\def\@triml#1{\ifx#1\ \else#1\fi} +% trim all spaces at the right, if present +\def\@trimr#1 |||{#1} + +% properly adds semicolon-delimited terms to the index +\def\@dt@idx#1;#2||{% + \def\@second{#2}% + \index{\@triml#1}% + % recurse if we have more + \ifx\@second\empty\else% + % will already having a trailing semi-colon, so do not re-add + \@dt@idx#2|| + \fi% +} + +% refs +\def\fref#1{Figure~\ref{f:#1} on page~\pageref{f:#1}} +\def\tref#1{Table~\ref{t:#1} on page~\pageref{t:#1}} +\def\sref#1{\S\vref*{s:#1}} +\def\srefnopg#1{\S\ref{s:#1}} +\def\srefrange#1#2{\S\vrefrange{s:#1}{s:#2}} +\def\srefpagerange#1#2{\vpagerefrange*{s:#1}{s:#2}} +\let\Sref\sref +\def\p#1{% + % define pref and prefp macros that store, respectively, the section number + % and page number (for example, if #1=foo, then this will create pref@foo and + % prefp@foo); note that this is used before a paragraph begins, so we increase + % the paragraph number by one before storing it + \label{@pref:#1} + \expandafter\xdef\csname pref@#1\endcsname{\thefullsection-\the\pnn} + \expandafter\xdef\csname prefp@#1\endcsname{\thepage} +} +% TODO: forward references +\def\pref#1{% + \P\hyperref[@pref:#1]{\csname pref@#1\endcsname}% + % only output the page number if it is not the current page (we decrease the + % current page number by 1 to account for the fact that the page number may be + % off by one due to page box calculations; this consequently means that we may + % not display the page number on a following page, which should be fine) + \newcount\@@thepage \@@thepage\thepage \advance\@@thepage-1 + \expandafter\let\expandafter\@pg\csname prefp@#1\endcsname + \ifx\@pg\relax\else + \ifnum\@@thepage>\@pg\relax% + \space on page~\pageref{@pref:#1}% + \fi + \fi +} + +\newif\if@keepsigtext +\@keepsigtextfalse + +% denotes incomplete sections/paragraphs +\def\@incomplete@default{{\small\bf Incomplete.}} +\def\incomplete{% + \gdef\@@margin@sig@repl{\@incomplete@default}% +} +\def\incompletei{% + \gdef\@@margin@sig@repl{% + \@incomplete@default\\% + \begingroup + \scriptsize + \space(Need more info% + \ifx\@@margin@sig@dept\relax\else + \space from\space\@@margin@sig@dept% + % clear the department, if necessary + \@margin@sig@cleardept + \fi + .)% + \endgroup + }% +}% + + +%% +% idxhat (index) +% +\def\@idxhat#1{% + \begingroup% + \ifmmode\@hat#1\else% + \ifx#1[% + \aftergroup\@idxhat@contained% + \else + \aftergroup\@idxhat@term% + \fi% + \aftergroup#1% + \fi% + \endgroup% +} +% term ends at the first space +\def\@idxhat@term#1 {\@idxhat@idx{#1} } +% grouped in [square brackets] +\def\@idxhat@contained[#1]{\@idxhat@idx{#1}} +\def\@idxhat@idx#1{\index{#1}\@idxhat@tail#1!||} +% strips all parents +\def\@idxhat@tail#1!#2||{% + % we're done once #2 is empty + \def\@chk{#2}% + \ifx\@chk\@empty% + #1% + \else% + % will already have a trailing '!'; don't add another + \@idxhat@tail#2||% + \fi% +} + + +%% +% Hyphenation +% +\hyphenation{Concept-One}