1
0
Fork 0

Extrated a number of rater-general specification logic from dwelling

master
Mike Gerwitz 2014-05-08 12:08:01 -04:00
parent d57cfeff86
commit cd285a2c4c
9 changed files with 983 additions and 0 deletions

126
raterspec.cls 100644
View File

@ -0,0 +1,126 @@
% LoVullo rater specification class
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{lvspec}}
\ProcessOptions\relax
% we're an extension of the base lvspec
\LoadClass[insuranceterms]{lvspec}
%%
% Default package includes
%
% Note that these are not all the packages that are available; see the
% raterspec/ directory in the lvspec repo
%
\RequirePackage{raterspec/param}
\RequirePackage{raterspec/class}
\RequirePackage{raterspec/question}
\RequirePackage{raterspec/rates}
\RequirePackage{raterspec/form}
\RequirePackage{raterspec/c1import}
\RequirePackage{lvflow}
%\RequirePackage{premcalc}
%%
% Formatting
%
% we gots some big section numbers
\renewcommand\l@subsubsection{\@dottedtocline{3}{7em}{4.6em}}
%%
% Rater-specific specification additions
%
% This should be called before beginning the documet environment
%
\def\@RaterProgramName#1{
\gdef\@lvspec@pretitle{%
#1 Supplier\\Specifications:\\
\vspace{0.5em}%
}
\gdef\@lvspec@premarktitle{#1:\space}
\abstract{%
This document is a formal specification for the integration of
\@title@short{} with the Dwelling Program of the Quote Server, Program
UI and~ConceptOne. This document should contain all information
necessary to complete a conforming implementation with minimal
clarification and will serve as a reference for future development,
including bug fixes and feature requests.
}
}
\terminology{%
\subsection{Rater Terminology}
\input{dfn/rater}
}
%%
% Code generation
%
% Right now the code generation is tightly coupled with the packages that it
% is applicable to; they need to be refactored and hooks added
\newwrite\@@codegen
\immediate\openout\@@codegen=gen.xml
\def\@codegen{%
\begingroup
% prepare common cases for plain-text output
\def\sref##1{the specification}%
\def~{ }%
\def\emph{}%
\def\nobreakspace{ }%
\def\${}%
\@do@codegen
}
\def\@do@codegen#1{%
\immediate\write\@@codegen{#1}%
\endgroup
}
%%
% Misc
%
\def\@firstchar #1#2||{#1}
\def\@secondchar #1#2#3||{#2}
\def\@ifnumeric#1{{%
\edef\@@chk{\@firstchar#1||}%
% determine if this is a number
\def\@@result{0}%
% strip any negative sign
\ifnum\expandafter`\@@chk=`-
\edef\@@chk{\@secondchar#1--||}%
\fi
% perform number check
\ifnum\expandafter`\@@chk<`0\else
\ifnum\expandafter`\@@chk>`9\else
% is a number
\def\@@result{1}%
\fi
\fi
% use the result to output a conditional that will match a closing \fi
\aftergroup\ifnum
\expandafter\aftergroup\@@result
\aftergroup=%
\aftergroup1%
\aftergroup\relax
}}
\def\beginundersletter{%
\begingroup% ended by \@dotypedef
\catcode`\_=11\relax
}
\def\endundersletter{%
\endgroup
}

View File

@ -0,0 +1,32 @@
% LoVullo rater specification c1 import
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec/c1import}
\ProcessOptions\relax
\newenvironment{c1glclass}[1]%
{%
\sigkeep
\def\@@class{#1}%
\let\basis\@coglclass@basis
\let\prem\@coglclass@prem
}%
{%
\par This class \shall only be applicable when each of the following is
true:
\begin{enumerate}
\@cmatch@enable
\matchin{class}{\@@class}%
\end{enumerate}
\sigunkeep
}
\def\@coglclass@basis#1{%
\par The premium basis \shall be the~\paramrefd{#1}~(\paramref{#1}).
}
\def\@coglclass@prem#1{%
\par The premium and~rate \shall be derived from~\sref{#1}.
}

355
raterspec/class.sty 100644
View File

@ -0,0 +1,355 @@
% LoVullo rater specification classification
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec/class}
\ProcessOptions\relax
% the first argument (optionally) provides a unique id for this classification
% (see further information on this below)
\newenvironment{classification}[1][]%
{%
\def\@cid{#1}%
\leavevmode
\label{@classify:#1}%
% if a classification id was provided, output it in the left margin (this
% allows us to eyeball summaries or common classifications across
% specifications, as well as match it up to the code)
\if\@cid\empty\else
% typeset id
\llap{{\scriptsize\bf\@cid\hskip4ex\relax}}%
\fi%
% enable rule definitions
\@cmatch@enable
% the first paragraph will constitute the description (and will contain a
% signature line)
\@margin@sig\@class@mkdesc\@cid
}
{%
% this is opened by \@class@mkdesc
\@codegen{</lv:classify>}%
\end{@classification@rules}%
}
\newenvironment{@classification@rules}
{%
{\bf Rules:}%
\penalty1000\relax
\begin{enumerate}
}
{%
\end{enumerate}
}
\def\@match@formal#1{{%
\\\footnotesize{\bf Formally:}%
\space#1%
}}
\def\@matchany #1 {%
\@codegen{ <lv:any>}%
\item Any one of the following \must be true:
\begin{enumerate}
#1
\end{enumerate}
\@codegen{ </lv:any>}%
}
\def\@matchall #1 {%
\@codegen{ <lv:all>}%
\item Each of the following \must be true:
\begin{enumerate}
#1
\end{enumerate}
\@codegen{ </lv:all>}%
}
\def\@matchtodo#1{\item\todo{#1}}
% determine what ref is appropriate
\def\@magicref#1{{%
% param?
\expandafter\let\expandafter\@@chk\csname param@#1\endcsname
\ifx\@@chk\relax
\expandafter\let\expandafter\@@chk\csname classify@#1\endcsname
\ifx\@@chk\relax
% no known custom type (may be a normal ref)
\PackageWarning{dwspec}{unknown magic ref `#1'}%
\else
\classifyref{#1}%
\fi
\else
\paramref{#1}%
\fi
}}
\def\@cmatcheq{%
\begingroup
\catcode`\_=11\relax
\@docmatcheq
}
\def\@docmatcheq#1#2{%
\@codegen{ <lv:match on="#1" value="#2" />}%
% whatever we are matching on must exist as either a classification or an
% input field (param)
\item\@cmatch@desc@or@fail{#1}%
\space \must be a(n)\space
% ensure that the constant exists
\@const@exists@err{#2}%
% typeset
\csname const@#2\endcsname.
\@match@formal{\@magicref{#1} $=$ \constref{#2}}%
\endgroup
}
\def\@cmatchneq{%
\begingroup
\catcode`\_=11\relax
\@docmatchneq
}
\def\@docmatchneq#1#2{%
\@codegen{ <lv:match on="#1">}%
\@codegen{ <c:ne>}%
\@codegen{ <c:value-of name="#2" />}%
\@codegen{ </c:ne>}%
\@codegen{ </lv:match>}%
% whatever we are matching on must exist as either a classification or an
% input field (param)
\item\@cmatch@desc@or@fail{#1}%
\space \mustnot be a(n)\space
% ensure that the constant exists
\@const@exists@err{#2}%
% typeset
\csname const@#2\endcsname.
\@match@formal{\@magicref{#1} $\neq$ \constref{#2}}%
\endgroup
}
\def\@cmatchlt{%
\begingroup
\catcode`\_=11\relax
\@docmatchlt
}
\def\@docmatchlt#1#2{%
\@codegen{ <lv:match on="#1">}%
\@codegen{ <c:lt>}%
\@codegen{ <c:value-of name="#2" />}%
\@codegen{ </c:lt>}%
\@codegen{ </lv:match>}%
% whatever we are matching on must exist as either a classification or an
% input field (param)
\item\@cmatch@desc@or@fail{#1}%
\space \must be less than\nobreakspace
% ensure that the constant exists
\@const@exists@err{#2}%
% typeset
\@const@desc{#2}.%
\@match@formal{\@magicref{#1} $<$ \constref{#2}}%
\endgroup
}
\def\@cmatchleq{%
\begingroup
\catcode`\_=11\relax
\@docmatchleq
}
\def\@docmatchleq#1#2{%
\@codegen{ <lv:match on="#1">}%
\@codegen{ <c:leq>}%
\@codegen{ <c:value-of name="#2" />}%
\@codegen{ </c:leq>}%
\@codegen{ </lv:match>}%
% whatever we are matching on must exist as either a classification or an
% input field (param)
\item\@cmatch@desc@or@fail{#1}%
\space \must be less than or equal to%
% ensure that the constant exists
\@const@exists@err{#2}%
% typeset
\nobreakspace\@const@desc{#2}.%
\@match@formal{\@magicref{#1} $\leq$ \constref{#2}}%
\endgroup
}
\def\@cmatchgt{%
\begingroup
\catcode`\_=11\relax
\@docmatchgt
}
\def\@docmatchgt#1#2{%
\@codegen{ <lv:match on="#1">}%
\@codegen{ <c:gt>}%
\@codegen{ <c:value-of name="#2" />}%
\@codegen{ </c:gt>}%
\@codegen{ </lv:match>}%
% whatever we are matching on must exist as either a classification or an
% input field (param)
\item\@cmatch@desc@or@fail{#1}%
\space \must be greater than\nobreakspace
% ensure that the constant exists
\@const@exists@err{#2}%
% typeset
\@const@desc{#2}.%
\@match@formal{\@magicref{#1} $>$ \constref{#2}}%
\endgroup
}
\def\@cmatchgeq#1#2{%
\@codegen{ <lv:match on="#1">}%
\@codegen{ <c:gte>}%
\@codegen{ <c:value-of name="#2" />}%
\@codegen{ </c:gte>}%
\@codegen{ </lv:match>}%
% whatever we are matching on must exist as either a classification or an
% input field (param)
\item\@cmatch@desc@or@fail{#1}%
\space \must be greater than or equal to\nobreakspace
% ensure that the constant exists
\@const@exists@err{#2}%
% typeset
\@const@desc{#2}.%
\@match@formal{\@magicref{#1} $\geq$ \constref{#2}}%
}
\def\@cmatchin#1#2{%
\@codegen{ <lv:match on="#1" anyOf="#2" />}%
% whatever we are matching on must exist as either a classification or an
% input field (param)
\item\@cmatch@desc@or@fail{#1}%
\space \must be a defined\space
% ensure that the param type exists
\@type@exists@err{#2}%
% output the param type description
\csname ptype@#2\endcsname.
\@match@formal{\@magicref{#1} $\in$ \typeref{#2}}%
}
\def\@match#1{%
\@codegen{ <!-- TODO: custom match; see specs -->}%
\item#1.%
}
\def\@matchtrue#1{%
\@codegen{ <lv:match on="#1" value="TRUE" />}%
\item\@cmatch@desc@or@fail{#1}.%
\@match@formal{\@magicref{#1} $=\top$}%
}
\def\@matchfalse#1{%
\@codegen{ <lv:match on="#1" value="FALSE" />}%
\item It is not true that: \@cmatch@desc@or@fail{#1}.%
\@match@formal{\@magicref{#1} $=\bot$}%
}
\def\@cmatch@enable{%
% we're being lazy with this cat code so that it applies to all \match
% invocations grouped between this enable cmd and the disable one; this will
% cause problems if we need math mode, so it may need to be revisited in the
% future
\catcode`_=11\relax
\let\matchany\@matchany
\let\matchall\@matchall
\let\matcheq\@cmatcheq
\let\matchneq\@cmatchneq
\let\matchgt\@cmatchgt
\let\matchgeq\@cmatchgeq
\let\matchlt\@cmatchlt
\let\matchleq\@cmatchleq
\let\matchin\@cmatchin
\let\matchtrue\@matchtrue
\let\matchfalse\@matchfalse
\let\matchtodo\@matchtodo
\let\match\@match
}
\def\@class@mkdesc#1 #2 \par{%
\@codegen{<lv:classify as="#1" desc="#2">}%
{\bf Description:}\space#2\par
% record this definition
\index{classification!#1@\texttt{#1}}%
\expandafter\gdef\csname classify@#1\endcsname{#2}%
% place definition into aux file; will be available next pass
\protected@write\@auxout{}{%
\string\expandafter\string\gdef
\string\csname\space classify@#1\string\endcsname{#2}%
}%
% immediately following the description are the rules
\begin{@classification@rules}
}
\def\@class@desc#1{{%
\expandafter\let\expandafter\@@chk\csname classify@#1\endcsname
\ifx\@@chk\relax
\PackageWarning{dwspec}{unknown classification `#1'}%
\else
\@@chk
\fi
}}
\def\@cmatch@desc@or@fail#1{{%
% grab tokens to check against for param and class definitions
\expandafter\let\expandafter\@@pchk\csname param@#1\endcsname
\expandafter\let\expandafter\@@cchk\csname classify@#1\endcsname
% fail if neither exists
\ifx\@@pchk\relax
\ifx\@@cchk\relax
\PackageWarning{dwspec}{unknown identifier for classification match: #1}
\else
% output
\@@cchk
\fi
\else
% output
\@@pchk
\fi
}}
\def\classifyref#1{%
\index{classification!#1@\texttt{#1}}%
\hyperref[@classify:#1]{%
\tt#1%
}%
}
\def\classifyrefd#1{%
\index{classification!#1@\texttt{#1}}%
\hyperref[@classify:#1]{%
\csname classify@#1\endcsname
}%
}
\def\classifyrefalt#1#2{%
\index{classification!#1@\texttt{#1}}%
\hyperref[@classify:#1]{#2}%
}
\def\assign#1#2{$#1$ $=$ #2}%
\def\loc{\ifmmode\ell\else$\ell$\fi}%
\def\y{yield}%
\def\prem{{\tt premium}}%
\newcommand\rate[1][]{%
\begingroup
\ifmmode\aftergroup\mathop\fi
\endgroup
{\tt #1rate}%
}
\newenvironment{submission}[2]%
{%
\begin{classification}[submit-#1-#2]%
}%
{%
\end{classification}
}
\def\when#1{%
\Shall be applicable only when each of the following is true:%
\begin{enumerate}
\@cmatch@enable
\scantokens{#1}
\end{enumerate}%
}
\let\When\when

53
raterspec/form.sty 100644
View File

@ -0,0 +1,53 @@
% LoVullo rater specification forms
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec/form}
\ProcessOptions\relax
\newenvironment{forms}[2]%
{%
\let\mandatory\@form@mandatory
\sigkeep
Applicable form code(s): \@formfmt#1,||.
\par The form description \shall read:
\begin{quote}
\sf\hskip-0.52em``#2''
\end{quote}
% TODO: remove once we're using sPxTeX
\pnumon
The form(s) \shall be applicable only when each of the following conditions
is met:%
\begin{enumerate}
\@cmatch@enable
\ignorespaces
}%
{%
\end{enumerate}
\sigunkeep
}
\def\@form@mandatory{%
\item Form is mandatory and \shall always be applicable.%
}
\newcount\@formprev
\def\@formfmt#1,#2||{%
\index{forms!codes!#1}%
\def\@@chk{#2}%
\ifnum\@formprev>0\relax
\ifx\@@chk\empty
\space and~%
\else
,\space
\fi
\fi
{\sf#1}%
% recurse
\ifx\@@chk\empty\else
\advance\@formprev by 1\relax
\@formfmt#2||%
\fi
}

View File

@ -0,0 +1,26 @@
% LoVullo rater specification iso class abstraction
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec/isoclass}
\ProcessOptions\relax
\def\isoclassdef#1 #2\par{%
\index{ISO!class code!#1|(}%
% indicate that this has been defined (semantic checking)
\expandafter\gdef\csname isoclass@code@#1\endcsname{}%
% typeset and provide hyperlink (intended for a description env)
\item[\hypertarget{@isoclass:#1}{#1}] #2\par%
\index{ISO!class code!#1|)}%
}
\def\isoclassref#1{%
% ensure that the iso class exists
\expandafter\ifx\csname isoclass@code@#1\endcsname\relax%
\errmessage{unknown ISO class code `#1'}
\fi
\index{ISO!class code!#1}%
\hyperlink{@isoclass:#1}{#1}%
}
\let\isoclass\isoclassref

View File

@ -0,0 +1,16 @@
% LoVullo rater specification iso territory abstraction
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec/isoterr}
\ProcessOptions\relax
%
% N.B. Expects s:isoterr-zips to be a defined reference
%
\def\isoterr#1{%
\hyperref[s:isoterr-zips]{ISO Territory #1}%
}

269
raterspec/param.sty 100644
View File

@ -0,0 +1,269 @@
% LoVullo rater specification params
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec/param}
\ProcessOptions\relax
% special keywords for base param types
\def\@coreptype{core}
\def\@enumptype{enum}
\def\@unionptype{union}
\def\typedef{%
\begingroup% ended by \@dotypedef
\catcode`\_=11\relax
\@dotypedef
}
\def\@dotypedef#1 #2: #3 \par{%
\goodbreak%
\index{parameter type!#2@\texttt{#2}|(}%
\begingroup%
% given foo<bar>, get foo and bar separately
\edef\@root{\@ptype@root#1<||}%
\edef\@type{\@ptype@type#1<#1>||}%
\expandafter\gdef\csname ptype@#2\endcsname{#3}%
% typeset definition with link
\item[%
\hypertarget{@ptype:#2}{#2}%
\ifx\@root\@coreptype\else%
\ $\in\textrm{\rm\@type}$%
\fi%
]\hfill\\%
\@margin@sig%
% ensure that the parent type actually exists
\ifx\@root\@coreptype\else%
\expandafter\ifx\csname ptype@\@type\endcsname\relax%
\errmessage{unknown parent param type `\@type' for `#2'}
\fi%
\fi%
% process any keywords
\ifx\@root\@enumptype
\aftergroup\@typedef@enum
\else\ifx\@root\@unionptype
\aftergroup\@typedef@union
\fi\fi
\index{parameter type!#2@\texttt{#2}|)}%
#3\par
\endgroup
\endgroup% from \typedef
}
% given a type foo<bar>, returns foo
\def\@ptype@root#1<#2||{#1}
% given a type foo<bar>, returns bar
\def\@ptype@type#1<#2>#3||{#2}
% strips the description and then puts all enums in an aligned environment
\def\@typedef@enum#1\enumv#2\par{%
#1%
\vskip0em\relax
\begingroup
\small
% provide some extra give to prevent this from appearing on its own line
\vspace{0em plus 0.5\parskip}%
\goodbreak
{\bf Defined values:}\\
\vspace{0.5\parskip}%
\begin{tabular}{lc|l}
% restore the enumv that we gobbled up
\enumv#2
\end{tabular}
\endgroup
}
\def\enumv[#1]#2#3{%
% define constant
\expandafter\gdef\csname const@#2\endcsname{#1}%
\expandafter\gdef\csname const@value@#2\endcsname{#3}%
% typeset
\index{constant!{\tt#2}}%
{\tt\hypertarget{@const:#2}{#2}} & $#3$ & #1 \\
}
% strips the description and then puts all enums in an aligned environment
\def\@typedef@union#1\unionv#2\par{%
#1%
\vskip0em\relax
\begingroup
\small
{\bf Any defined value of:}%
\vspace{-\parskip}%
\begin{itemize}
\setlength{\itemsep}{-\parskip}%
% restore the unionv that we gobbled up
\unionv#2
\end{itemize}
\endgroup
}
\def\unionv#1{%
% does this type exist?
\expandafter\ifx\csname ptype@#1\endcsname\relax%
\errmessage{unknown param type `#1' for union}
\fi%
\item{\typeref{#1}}
}
\def\typeref#1{%
\index{parameter type!#1@\texttt{#1}}%
\hyperlink{@ptype:#1}{\tt#1}%
}
\let\type\typeref
\def\constref #1{%
\@ifnumeric{#1}%
% numeric constants are simply output with no hyperlink
$#1$%
\else
\index{constant!{\tt#1}}\hyperlink{@const:#1}{\tt#1}%
\fi
}
\let\const\constref
% constant reference, show description
\def\constrefd#1{%
\@ifnumeric{#1}%
% numeric constants are simply output with no hyperlink
$#1$%
\else
\index{constant!{\tt#1}}%
\hyperlink{@const:#1}%
{\csname const@#1\endcsname}%
\fi
}
\def\constrefdd#1{\constrefd{#1}\dotfill}
% constant reference, show value
\def\constrefv#1{%
\@ifnumeric{#1}%
% numeric constants are simply output with no hyperlink
$#1$%
\else
\index{constant!{\tt#1}}%
\hyperlink{@const:#1}%
{\csname const@value@#1\endcsname}%
\fi
}
% link to constant with alternate text
\def\constrefalt#1#2{%
\index{constant!{\tt#1}}%
\hyperlink{@const:#1}{#2}%
}
\def\@type@exists@err#1{{%
\expandafter\let\expandafter\@chk\csname ptype@#1\endcsname
\ifx\@chk\relax
\errmessage{parameter `#1' is undefined}%
\fi
}}
\def\@const@exists@err#1{{%
% ignore numeric constants (lazy check; anything that begins with a number)
\@ifnumeric{#1}\else
\expandafter\let\expandafter\@chk\csname const@#1\endcsname
\ifx\@chk\relax
\errmessage{constant `#1' is undefined}%
\fi
\fi
}}
\def\@const@desc#1{{%
\@ifnumeric{#1}%
% just output the text
$#1$%
\else
% output desc
\csname const@#1\endcsname
\fi
}}
% denotes a param that will likely be calculated
\def\metaparamdef{\paramdef}
% param definition
% note that the description is included in this input as well; this allows us to
% use this information for code generation/etc
\def\paramdef{%
\begingroup
\catcode`_=11\relax
\@doparamdef
}
\def\@doparamdef#1 #2: #3 \par{%
\goodbreak%
\index{parameter!#2@\texttt{#2}|(}%
\begingroup%
\def\@given{#1}%
% given foo<bar>, get foo and bar separately
\edef\@root{\@ptype@root#1<||}%
\edef\@type{\@ptype@type#1<#1>||}%
\expandafter\gdef\csname param@#2\endcsname{#3}%
% does the given type exist (note that this check assumes that the typedef
% appears before the param in the specs, as is currently the case)
\expandafter\ifx\csname ptype@\@type\endcsname\relax%
\errmessage{unknown param type: \@type}
\fi%
% typeset definition with link
\item[%
\hypertarget{@param:#2}{{\tt#2}}%
\ $\in\textrm{%
\rm\typeref{\@type}%
% output root only if provided (if not, then because of how \@type
% called \@ptype@type, it will be equal to #1)
\ifx\@root\@given\else%
\ $\langle$\@root$\rangle$
\fi
}$%
]\hfill\\%
\@margin@sig%
% remove mysterious space from margin sig
\hskip-1ex\relax%
#3%
\ifx\@root\@given
\@codegen{<lv:param name="#2" type="\@type" desc="#3"/>}%
\else
\@codegen{<lv:param name="#2" type="\@type" set="\@root"%
\space desc="#3"/>%
}%
\fi
\endgroup%
\index{parameter!#2@\texttt{#2}|)}%
\endgroup
}
\def\paramref{%
\begingroup% ended by \@dotypedef
\catcode`\_=11\relax
\@doparamref
}
\def\@doparamref#1{%
% prevent scantokens from adding a space at the end
\endlinechar-1\relax
\expandafter\let\expandafter\@@chk\csname param@#1\endcsname
\ifx\@@chk\relax
\PackageError{dwspec}{unknown param: #1}
\fi
\index{parameter!#1@\texttt{#1}}%
\hyperlink{@param:#1}%
{\tt\scantokens{#1}}%
\endgroup
}
\let\param\paramref
\def\paramrefd#1{%
\expandafter\let\expandafter\@@pchk\csname param@#1\endcsname
\ifx\@@pchk\empty
\PackageError{dwspec}{Unknown parameter: #1}%
\else
% output
\@@pchk
\fi
}
\def\locparam#1{%
\ifmmode
\mathop{\paramref{#1}_\loc}
\else
$\locparam{#1}$%
\fi
}

View File

@ -0,0 +1,62 @@
% LoVullo rater specification questions
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec/question}
\ProcessOptions\relax
\newlength\questionparsep
\questionparsep\the\marginparsep
\newenvironment{qgroup}[1]%
{%
\subsubsection{#1}%
\begin{description}%
}%
{%
\end{description}%
}
\newenvironment{subquestions}%
{%
\begin{description}%
\advance\questionparsep by \leftmargin\relax
}
{%
\end{description}%
}
\def\@qtypedesc@text{any string of characters.}
\def\@qtypedesc@number{any whole number.}
\def\@qtypedesc@float{any floating point value.}
\def\@qtypedesc@noyes{one of either {\sl No\/} or~{\sl Yes}.}
\def\@qtypedesc@select{one of the options enumerated below:}
\newcommand\question[5][]{%
\item[%
\beginundersletter
\llap{%
\tt\scriptsize\raisebox{-1em}[0em][0em]{%
\shortstack[r]{%
\scantokens{#2}\\
{\tiny \scantokens{#4}}%
}%
}%
\hspace{\the\questionparsep}%
}%
\endundersletter
\ignorespaces#5\unskip
]\hfill\\
\@margin@sig
\begingroup
\def\@mapsto{#3}%
\ifx\@mapsto\empty
\May not map to any rater input parameter.%
\else
\Shall map to rater input parameter \paramref{#3}.%
\fi
\endgroup
\space Input value \shall be \csname @qtypedesc@#4\endcsname\space
\ignorespaces
}

View File

@ -0,0 +1,44 @@
% LoVullo rater specification rate tables
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{raterspec/rates}
\ProcessOptions\relax
\newenvironment{ratetable*}[5][]%
{%
\def\@@lotcaption{#1}
\def\@@label{#2}
\def\@@caption{#3}
\ifx\@@lotcaption\empty
\let\@@lotcaption\@@caption
\fi
\begin{table}[#5]
\caption[\@@lotcaption]{\@@caption}
\label{t:\@@label}
\centering\footnotesize\sf
\hspace*{-\marginparwidth}%
\begin{tabular}{#4}
\toprule
}
{%
\bottomrule
\end{tabular}
\hspace*{-\marginparwidth}%
\medskip
\end{table}
}
% simplified syntax where a rate table should always appear on a page of floats
% (which is often the case, since many rate tables tend to be within close
% proximity to one-another)
\newenvironment{ratetable}[4][]%
{%
\begin{ratetable*}[#1]{#2}{#3}{#4}{p}%
}%
{%
\end{ratetable*}%
}