core-book/lib/rpgdeprecated.sty
Joe bellus 7b33fef50e Initial commit
Initial project scaffolding
2025-03-10 18:21:53 -04:00

621 lines
18 KiB
TeX

\RequirePackage {keycommand}
\ExplSyntaxOn
\NewDocumentCommand{\RpgDeprecate}{ mmm }
{
\__rpg_deprecated:nnn {#1} {#2} {#3}
}
\ExplSyntaxOff
% Either hilariously, or infuriatingly, the \ifcommandkey
% implementation is buggy. Here is a re-implementation
% from tex.stackexchange.
\begingroup
\makeatletter
\catcode`\/=8 %
\@firstofone
{
\endgroup
\renewcommand{\ifcommandkey}[1]{%
\csname @\expandafter \expandafter \expandafter
\expandafter \expandafter \expandafter \expandafter
\kcmd@nbk \commandkey {#1}//{first}{second}//oftwo\endcsname
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rpgcolors.sty - to be removed in version 1.0.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Sets the themecolor and colors for all themed elements
% If called without the optional color, resets the color of all themed elements to the current themecolor
\newcommand{\setthemecolor}[1][themecolor]{%
\RpgDeprecate{\noexpand\setthemecolor}{1.0.0}{Use \noexpand\RpgSetThemeColor to set the theme color.}%
\colorlet{themecolor}{#1}
\colorlet{commentcolor}{#1}
\colorlet{sidebarcolor}{#1}
\colorlet{tablecolor}{#1}
}
% Backwards-compatible aliases and colours
\colorlet {commentgreen} {PhbLightGreen}
\colorlet {itemtablepink} {DmgCoral}
\colorlet {monstertan} {statblockbg}
\definecolor {monstertandark} {HTML} {F0DBB5}
% Old interface
\colorlet {commentboxcolor} {commentcolor}
\colorlet {paperboxcolor} {sidebarcolor}
\colorlet {quoteboxcolor} {readaloudcolor}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rpgcomment.sty - to be removed in version 1.0.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Usage \begin{commentbox}[options]{title}[color]
\ExplSyntaxOn
\DeclareTColorBox{commentbox}{O{} m O{commentboxcolor}}{%
before~upper={%
\bool_if:NT \l__rpg_layout_bool
{
\bool_if:NF \l__rpg_justified_bool
{ \RaggedRight }
}
},
code={\RpgDeprecate{\noexpand\commentbox}{1.0.0}{Use~\noexpand\RpgComment~for~breakable~comment~boxes.}\linespread{.9}},
frame~hidden,
boxrule=0pt,
breakable,
enhanced,
before~skip=13pt plus 4pt minus 4pt,
toptitle=2pt,
boxsep=3pt,
left=6pt,
right=6pt,
top=0pt,
bottom=2pt,
sharp~corners,
fonttitle=\RpgFontCommentTitle,
fontupper=\RpgFontCommentBody,
fontlower=\RpgFontCommentBody,
title={#2},
parbox=false,
colback=#3,
colbacktitle=#3,
coltitle=black,
after~skip=13pt plus 4pt minus 4pt,
#1
}
\ExplSyntaxOff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rpgmonster.sty - to be removed in version 1.0.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Fancy DnD 5e stat block rule
\newcommand{\rpgline}{%
\RpgDeprecate{\noexpand\rpgline}{1.0.0}{Use \noexpand\RpgMonsterLine for stat block rules.}%
\noindent
\begin{tikzpicture}[]
\draw [rulered, fill=rulered] (0, 0) --(0,0.1) -- (\textwidth, 0.05);
\end{tikzpicture}%
\par%
}
\RequirePackage{fp}
\RequirePackage{xstring}
% Macro to print stats with auto-computed modifier
% e.g. \stat{12} prints "12 (+1)"
\newcommand{\stat}[1]{%
\RpgDeprecate{\noexpand\stat}{1.0.0}{Use \noexpand\RpgMonsterAbilityScores for the stat block ability score table.}%
\FPeval{\mod}{(#1 - 10)/2}%
\FPifpos\mod%
\FPeval{\mod}{clip(trunc(mod,0))}#1\ (+\mod)%
\else%
\FPeval{\mod}{clip(abs(trunc(mod-0.5,0)))}#1\ (--\mod)%
\fi%
}
% Macro to print avarage dice based value
% e.g. \dice{2d6+3} prints "10 (2d6 + 3)"
\newcommand{\dice}[1]{%
\RpgDeprecate{\noexpand\dice}{1.0.0}{Use \noexpand\RpgDice to typeset a dice roll with the average value.}%
\StrSubstitute{#1}{ }{}[\DiceArg]% strip whitespaces
\StrCut{\DiceArg}{d}\DiceNum\DiceSides% split string
\StrCut{\DiceSides}{+}\DiceSides\DiceAddMod%
\StrCut{\DiceSides}{-}\DiceSides\DiceSubMod%
\FPeval{\DiceAvg}{(\DiceSides+1)/2*\DiceNum}% calculate avg roll
\IfInteger{\DiceAddMod}{%
\FPadd{\DiceAvg}{\DiceAvg}{\DiceAddMod}% add value
\def\DiceMod{ + \DiceAddMod}%
}{%
\IfInteger{\DiceSubMod}{%
\FPsub{\DiceAvg}{\DiceAvg}{\DiceSubMod}% subtract value
\def\DiceMod{ -- \DiceSubMod}%
}{%
\def\DiceMod{}%
}%
}%
\FPtrunc{\DiceAvg}{\DiceAvg}{0}% round down
\FPprint{\DiceAvg\ (\DiceNum \dname\DiceSides\DiceMod)}%
}
% Stat block without the background
\newtcolorbox{monsterboxnobg}[2][]{
enhanced,
code={\RpgDeprecate{\noexpand\monsterboxnobg}{1.0.0}{Use \noexpand\RpgMonsterNoBg for stat blocks without a background.}},
frame hidden,
boxrule=0pt,
breakable,
parbox=false,
boxsep=0pt,
toptitle=3mm,
left=0pt,
right=0pt,
sharp corners,
opacityback=0,
colframe=titlered,
fonttitle=\RpgFontStatBlockTitle,
fontupper=\RpgFontStatBlockBody,
fontlower=\RpgFontStatBlockBody,
title=#2,
coltitle=titlered,
#1
}
% Stat block with background
\newtcolorbox{monsterboxbg}[2][]{
enhanced,
code={\RpgDeprecate{\noexpand\monsterboxbg}{1.0.0}{Use \noexpand\RpgMonsterBg for stat blocks with a background.}},
frame hidden,
before skip=12pt plus 3pt minus 3pt,
boxrule=0pt,
breakable,
parbox=false,
boxsep=2pt,
toptitle=8pt,
top=0pt,
left=2pt,
right=2pt,
bottom=7pt,
sharp corners,
oversize=0pt,
borderline north={3pt}{0pt}{titlered},
borderline north={2pt}{0.5pt}{statblockribbon},
borderline south={3pt}{0pt}{titlered},
borderline south={2pt}{0.5pt}{statblockribbon},
colback=statblockbg,
colbacktitle=statblockbg,
colframe=titlered,
fonttitle=\RpgFontStatBlockTitle,
coltitle=titlered,
fontupper=\RpgFontStatBlockBody,
fontlower=\RpgFontStatBlockBody,
title=#2,
#1
}
\ExplSyntaxOn
\bool_if:NTF \l__rpg_show_background_bool
{
\let\monsterbox\monsterboxbg%
\let\endmonsterbox\endmonsterboxbg%
}
{
\let\monsterbox\monsterboxnobg%
\let\endmonsterbox\endmonsterboxnobg%
}
\ExplSyntaxOff
% Define Monster subsection header style
\newcommand{\monstersection}[1]{%
\RpgDeprecate{\noexpand\monstersection}{1.0.0}{Use \noexpand\RpgMonsterSection for stat blocks sections.}%
\begingroup
\par\medskip\noindent
\RpgFontStatBlockSection #1
% \rule is a horizontal command, so placing it under the title incurs extra
% line spacing. Use \hrule (a vertical command) instead.
\vspace{3pt}
\hrule height 0.6pt
\vspace{2pt}
\endgroup%
}
\NewDocumentEnvironment{monsteraction}{o}{%
\RpgDeprecate{\noexpand\monsteraction}{1.0.0}{Use \noexpand\RpgMonsterAction for stat block actions.}%
\IfValueTF{#1}{%
\par\medskip\noindent\emph{\textbf{#1.}}%
}{\unskip}%
}{\par}
% A description variant used to list creature attributes.
\newlist{rpg@monsterattrs}{description}{1}
\ExplSyntaxOn
\setlist[rpg@monsterattrs]{
before=\color{titlered},
font=\RpgFontStatBlockBody,
labelsep=\l__rpg_space_dim,
noitemsep,
nosep,
}
\ExplSyntaxOff
% A rpg@monsterattrs helper macro that always displays an attribute.
\newcommand{\rpg@monsterattr}[2]{%
\item[#2] \commandkey{#1}
}
% A rpg@monsterattrs helper macro that displays an attribute if the user defined
% it.
\newcommand{\rpg@ifmonsterattr}[2]{%
\ifcommandkey{#1}{%
\item[#2] \commandkey{#1}
}{}%
}
%
% Macros for use within the monster environment
%
\newkeycommand\basics[armorclass=0, hitpoints=0, speed=0]{%
\RpgDeprecate{\noexpand\basics}{1.0.0}{Use \noexpand\RpgMonsterBasics for stat block AC, HP, and speed.}%
\begin{rpg@monsterattrs}
\rpg@monsterattr{armorclass}{\armorclassname}
\rpg@monsterattr{hitpoints}{\hitpointsname}
\rpg@monsterattr{speed}{\speedname}
\end{rpg@monsterattrs}%
}
% Taubular enviornment for stats-block
\newkeycommand\stats[%
STR=\stat{10},
DEX=\stat{10},
CON=\stat{10},
INT=\stat{10},
WIS=\stat{10},
CHA=\stat{10}]{%
\RpgDeprecate{\noexpand\stats}{1.0.0}{Use \noexpand\RpgMonsterAbilityScores for the stat block ability score table.}%
\begingroup%
\color{titlered}%
\par\vspace{5pt}\noindent%
\begin{tabularx}{\linewidth}{YYYYYY}
\textbf{\strstatname} &
\textbf{\dexstatname} &
\textbf{\constatname} &
\textbf{\intstatname} &
\textbf{\wisstatname} &
\textbf{\chastatname} \\
\commandkey{STR} &
\commandkey{DEX} &
\commandkey{CON} &
\commandkey{INT} &
\commandkey{WIS} &
\commandkey{CHA}
\end{tabularx}%
\par\vspace{4pt}%
\endgroup%
}
\newkeycommand\details[
skills=,
damageimmunities=,
savingthrows=,
conditionimmunities=,
damageresistances=,
damagevulnerabilities=,
senses=---,
languages=---,
challenge=1,
]{%
\RpgDeprecate{\noexpand\details}{1.0.0}{Use \noexpand\RpgMonsterDetails for stat block details like resistances and CR.}%
\begin{rpg@monsterattrs}
\rpg@ifmonsterattr{savingthrows}{\savesname}
\rpg@ifmonsterattr{skills}{\skillsname}
\rpg@ifmonsterattr{damagevulnerabilities}{\dvulname}
\rpg@ifmonsterattr{damageresistances}{\dresname}
\rpg@ifmonsterattr{damageimmunities}{\dimmname}
\rpg@ifmonsterattr{conditionimmunities}{\cimmname}
\rpg@monsterattr{senses}{\sensesname}
\rpg@monsterattr{languages}{\languagesname}
\item[\challengename] \RpgCRExp{\commandkey{challenge}}
\end{rpg@monsterattrs}%
}
\ExplSyntaxOn
\newcommand{\rpg@hit}[1]{%
\__rpg_caption:nn {\tohitname} {#1}
}
\ExplSyntaxOff
\newcommand{\rpg@damage}[2]{%
\commandkey{#1}\ \commandkey{#2}\ \damagename%
}
\newcommand{\rpg@ifplusdmg}[2]{%
\ifcommandkey{#1}{%
{ }\plusname\ \commandkey{#1}\ \commandkey{#2}\ \damagename%
}{}%
}
\newcommand{\rpg@ifordmg}[5]{%
\ifcommandkey{#1}{%
, \orname\ \commandkey{#1}\ \commandkey{#2}\ \damagename\rpg@ifplusdmg{#4}{#5}\ \commandkey{#3}%
}{}%
}
\newkeycommand+[\|]\monstermelee[
name=Club,
mod=+0,
reach=5,
targets=\defaulttargetsname,
dmg=\dice{1d4},
dmgtype=bludgeoning,
plusdmg=,
plusdmgtype=,
ordmg=,
ordmgwhen=,
extra=,
]{%
|\monsterattack|[
name={\commandkey{name}},
type=melee,
mod={\commandkey{mod}},
reach={\commandkey{reach}},
targets={\commandkey{targets}},
dmg={\commandkey{dmg}},
dmgtype={\commandkey{dmgtype}},
plusdmg={\commandkey{plusdmg}},
plusdmgtype={\commandkey{plusdmgtype}},
ordmg={\commandkey{ordmg}},
ordmgwhen={\commandkey{ordmgwhen}},
extra={\commandkey{extra}},
]
}
\newkeycommand+[\|]\monsterranged[
name=Shortbow,
mod=+0,
range=80/320,
targets=\defaulttargetsname,
dmg=\dice{1d6},
dmgtype=piercing,
plusdmg=,
plusdmgtype=,
ordmg=,
ordmgwhen=,
extra=,
]{%
|\monsterattack|[
name={\commandkey{name}},
type=ranged,
mod={\commandkey{mod}},
range={\commandkey{range}},
targets={\commandkey{targets}},
dmg={\commandkey{dmg}},
dmgtype={\commandkey{dmgtype}},
plusdmg={\commandkey{plusdmg}},
plusdmgtype={\commandkey{plusdmgtype}},
ordmg={\commandkey{ordmg}},
ordmgwhen={\commandkey{ordmgwhen}},
extra={\commandkey{extra}},
]
}
\newkeycommand\monsterattack[
name=Dagger,
enum* type={both,melee,ranged},
mod=+0,
reach=5,
range=20/60,
targets=\defaulttargetsname,
dmg=\dice{1d4},
dmgtype=piercing,
plusdmg=,
plusdmgtype=,
ordmg=,
ordmgwhen=,
extra=,
]{%
\RpgDeprecate{\noexpand\monsterattack}{1.0.0}{Use \noexpand\RpgMonsterMelee, \noexpand\RpgMonsterRanged, or \noexpand\RpgMonsterAttack for attacks that are melee, ranged, or both, respectively.}%
\begin{monsteraction}[\commandkey{name}]
\IfStrEqCase{\commandkey{type}}{%
{melee}{\textit{\RpgCaption{\meleeattackname}{\weaponname}:} \rpg@hit{mod}, \reachname\ \commandkey{reach} \unitsname}%
{ranged}{\textit{\RpgCaption{\rangedattackname}{\weaponname}:} \rpg@hit{mod}, \rangename\ \commandkey{range} \unitsname}%
{both}{\textit{\RpgCaption{\meleeorrangedattackname}{\weaponname}:} \rpg@hit{mod}, \reachname\ \commandkey{reach} \unitsname\ \orname\ \rangename\ \commandkey{range} \unitsname}%
}[]%
, \commandkey{targets}.
\textit{\hitname:} \rpg@damage{dmg}{dmgtype}%
\rpg@ifplusdmg{plusdmg}{plusdmgtype}%
\rpg@ifordmg{ordmg}{dmgtype}{ordmgwhen}{plusdmg}{plusdmgtype}%
\ifcommandkey{extra}{\commandkey{extra}}{}.
\end{monsteraction}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rpgpaperbox.sty - to be removed in version 1.0.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Usage \begin{paperbox}[options]{title}[color]
\ExplSyntaxOn
\DeclareTColorBox{paperbox}{O{} m O{paperboxcolor}}{%
before~upper={%
\bool_if:NT \l__rpg_layout_bool
{
\bool_if:NF \l__rpg_justified_bool
{\RaggedRight}
}
},
code={\RpgDeprecate{\noexpand\paperbox}{1.0.0}{Use \noexpand\RpgSidebar for sidebars.}\linespread{.9}},
frame~hidden,
boxrule=0pt,
enhanced,
before~skip=13pt plus 4pt minus 4pt,
toptitle=2pt,
boxsep=3pt,
left=6pt,
right=6pt,
top=0pt,
bottom=3pt,
fonttitle=\RpgFontSidebarTitle,
fontupper=\RpgFontSidebarBody,
fontlower=\RpgFontSidebarBody,
title={#2},
sharp~corners,
parbox=false,
borderline~north={1pt}{-0.5pt}{black},
borderline~south={1pt}{-0.5pt}{black},
colback=#3,
colbacktitle=#3,
coltitle=black,
fuzzy~shadow={0mm}{-3.5pt}{-0.5pt}{0.4mm}{black!60!white},
overlay={%
\fill[black] (frame.south~west) -- ++ (7pt,0) -- ++ (0,-5pt) -- cycle;
\fill[black] (frame.north~west) -- ++ (7pt,0) -- ++ (0,5pt) -- cycle;
\fill[black] (frame.north~east) -- ++ (-7pt,0) -- ++ (0,5pt) -- cycle;
\fill[black] (frame.south~east) -- ++ (-7pt,0) -- ++ (0,-5pt) -- cycle;
},
after~skip=14pt plus 4pt minus 4pt,
#1
}
\ExplSyntaxOn
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rpgquote.sty - to be removed in version 1.0.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Usage \begin{quotebox}[options][color]
\ExplSyntaxOn
\DeclareTColorBox{quotebox}{O{} O{quoteboxcolor}}{%
before~upper={%
\bool_if:NT \l__rpg_layout_bool
{
\bool_if:NF \l__rpg_justified_bool
{\RaggedRight}
}
},
code={\RpgDeprecate{\noexpand\quotebox}{1.0.0}{Use~\noexpand\RpgReadAloud~for~read-aloud~text.}\linespread{1.1}},
enhanced~jigsaw,
frame~hidden,
boxrule=0pt,
breakable,
enhanced,
before~skip=13pt plus 4pt minus 4pt,
boxsep=8pt,
top=0pt,
left=0pt,
right=0pt,
bottom=0pt,
colback=#2,
sharp~corners,
parbox=false,
borderline~west={1pt}{-0.5pt}{titlered},
borderline~east={1pt}{-0.5pt}{titlered},
fontupper=\RpgFontReadAloud,
fontlower=\RpgFontReadAloud,
overlay={%
\foreach\n in {north~east,north~west,south~east,south~west}
{\draw[titlered, fill=titlered] (frame.\n) circle (1.5pt); }; },
after~skip=13pt plus 4pt minus 4pt,
#1
}
\ExplSyntaxOff
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rpgsections.sty - to be removed in version 1.0.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Special command for magic items, traps, and the like.
\newcommand{\subtitlesection}[2]{%
\RpgDeprecate{\noexpand\subtitlesection}{1.0.0}{Use \noexpand\RpgItemHeader for item headers.}%
\subsubsection{#1}%
\textit{#2}
\par\vspace{3pt plus 1pt minus 1pt}\noindent\ignorespaces}
% Map Areas and their References
% Labelling helpers
\newcommand{\AreaLabel@Prefix}{area}
\newcommand{\SetAreaLabelPrefix}[1]{%
\renewcommand{\AreaLabel@Prefix}{#1}}
\newcounter{Area}
\newcommand\ResetAreas{%
\RpgDeprecate{\noexpand\ResetAreas}{1.0.0}{Use \noexpand\RpgResetAreas to reset area counters.}%
\setcounter{Area}{0}
}
\NewDocumentCommand\area{mo}{%
\RpgDeprecate{\noexpand\area}{1.0.0}{Use \noexpand\RpgArea to typeset a section with an area counter.}%
\refstepcounter{Area}%
\IfNoValueTF{#2}%
{\label{\AreaLabel@Prefix:#1}}%
{\label{\AreaLabel@Prefix:#2}}%
\subsection{\arabic{Area}. #1}%
}
% defines sub-areas, like '5a', '5b'
\newcounter{SubArea}[Area]
\NewDocumentCommand\subarea{mo}{%
\RpgDeprecate{\noexpand\subarea}{1.0.0}{Use \noexpand\RpgSubArea to typeset a section with an sub-area counter.}%
\refstepcounter{SubArea}%
\IfNoValueTF{#2}%
{\label{\AreaLabel@Prefix:#1}}%
{\label{\AreaLabel@Prefix:#2}}%
\subsubsection{\arabic{Area}\alph{SubArea}. #1}%
}
% sub area references should be '5a', '5b', not '1', '2'
\renewcommand\p@SubArea{\arabic{Area}}
\renewcommand\theSubArea{\alph{SubArea}}
\newcounter{DetailArea}[subsection]
\newcommand{\DetailArea@Prefix}{}
\newcommand{\SetDetailAreaPrefix}[1]{\renewcommand{\DetailArea@Prefix}
{#1--\arabic{DetailArea}\par\expandafter\ignorespaces\noindent}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rpgspell.sty - to be removed in version 1.0.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\spellheader}[6]{%
\RpgDeprecate{\noexpand\spellheader}{1.0.0}{Use \noexpand\RpgSpellHeader to typeset a spell header.}%
\subtitlesection{#1}{#2}
\begin{description}[noitemsep,nosep,after=\smallskip,leftmargin=1em]
\item[\spellcastingtimename:] #3
\item[\spellrangename:] #4
\item[\spellcomponentsname:] #5
\item[\spelldurationname:] #6
\end{description}
}
\newenvironment{spell}[6]
{\spellheader{#1}{#2}{#3}{#4}{#5}{#6}}
% Environment encloses description.
{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rpgtable.sty - to be removed in version 1.0.0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Table Header
\newcommand{\header}[1]{%
\begingroup%
\par\vspace{10pt plus 3 pt minus 3pt}%
\noindent%
\RpgFontTableTitle%
#1%
\endgroup%
}
% Table Environment
\NewDocumentEnvironment{rpgtable}{O{XX} O{tablecolor}}{%
\RpgDeprecate{\noexpand\rpgtable}{1.0.0}{Use \noexpand\RpgTable for tables.}%
\par\vspace{2pt plus 1pt minus 1pt}%
\noindent%
\RpgFontTableBody%
\setlength{\extrarowheight}{3pt}%
\rowcolors{1}{}{#2}%
\tabularx{\linewidth}{#1}%
}{%
\endtabularx%
\par\vspace{10pt plus 3 pt minus 3pt}%
}