summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/wargame/source/util/core.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/wargame/source/util/core.dtx')
-rw-r--r--macros/latex/contrib/wargame/source/util/core.dtx1299
1 files changed, 1299 insertions, 0 deletions
diff --git a/macros/latex/contrib/wargame/source/util/core.dtx b/macros/latex/contrib/wargame/source/util/core.dtx
new file mode 100644
index 0000000000..a3c656a2b3
--- /dev/null
+++ b/macros/latex/contrib/wargame/source/util/core.dtx
@@ -0,0 +1,1299 @@
+% \iffalse
+% ====================================================================
+% \fi
+%
+% \subsection{The \texttt{wargame.util} \TikZ{} library}
+% \label{sec:impl:util}
+%
+% This library contains some utilities for use in the other
+% libraries.
+%
+% \iffalse
+%<*utils>
+%\fi
+%
+%
+% \iffalse
+% --------------------------------------------------------------------
+% \fi
+%
+% \subsubsection{Miscellaneous macros}
+%
+% \begin{Macro}{\wg@dbg}
+% Debugging support. The counter \cs{wargamedbglvl} sets the debug
+% level. The package code then uses \cs{wg@dbg} to print out
+% debugging messages. This macro takes two arguments --- the first
+% is the \emph{least} debug level at which the message is printed, and
+% the second is the message it self.
+%
+% \begin{macrocode}
+\newcount\wargamedbglvl\wargamedbglvl=0
+\def\wg@dbg#1#2{%
+ \ifnum#1>\wargamedbglvl\relax\else\message{^^J#2}\fi}
+% \end{macrocode}
+% \end{Macro}
+%
+% \begin{Macro}{\wg@addto@macro}
+%
+% The macro \cs{wg@addto@macro}\marg{macro}\marg{other} adds the
+% definition of the macro \meta{other} to the macro \meta{macro}.
+% This uses the \cs{toks} trick of storing the \emph{tokens} of the
+% definition of a \meta{macro} and \meta{other} into \spec{@} and
+% expanding that token into the definition of \meta{macro}.
+% Effectively, this means that the top-level definition of
+% \meta{macro} and \meta{other} are expanded (i.e., macros used in
+% the definition of either macro is \emph{not} expanded) and then
+% that becomes the new definition of \meta{macro}.
+%
+% We will use this macro to do \emph{shallow} definitions of macros
+% to contain keys and such.
+%
+% \begin{macrocode}
+\long\def\wg@addto@macro#1#2{%
+ \begingroup
+ \toks@\expandafter\expandafter\expandafter{\expandafter#1#2}%
+ \xdef#1{\the\toks@}%
+ \endgroup}
+% \end{macrocode}
+% \end{Macro}
+%
+%
+% \begin{Macro}{\wg@sub@nchor}
+% Get anchor from sub node. We cannot use \cs{pgfpointanchor} since
+% that returns the anchor coordinates in the global coordinate
+% system.
+%
+% \begin{macrocode}
+\def\wg@sub@nchor#1#2{%
+ \wg@dbg{3}{^^JGet `#2' in `#1'}%
+ \@ifundefined{pgf@sh@ns@#1}{%
+ \pgf@x=0cm\pgf@y=0cm}{%
+ \pgf@process{%
+ \csname pgf@sh@ma@#1\endcsname% MW
+ \csname pgf@sh@np@#1\endcsname%
+ \pgf@sh@reanchor{\csname pgf@sh@ns@#1\endcsname}{#2}}}%
+ \wg@dbg{10}{-> \the\pgf@x,\the\pgf@y}%
+}
+% \end{macrocode}
+% \end{Macro}
+%
+%
+% Scratch dimensions
+%
+% \begin{macrocode}
+\newdimen\wg@tmpa
+\newdimen\wg@tmpb
+\newdimen\wg@tmpc
+\newdimen\wg@tmpd
+% \end{macrocode}
+%
+%
+% Macro to easy restore a saved path
+%
+% \begin{macrocode}
+\def\settosave#1{
+ \pgfsyssoftpath@setcurrentpath{#1}}
+% \end{macrocode}
+%
+% \iffalse
+% --------------------------------------------------------------------
+% \fi
+%
+% \subsubsection{Pictures in compound nodes}
+%
+% \begin{Macro}{\wg@pic}
+% The macro \cs{wg@pic} will render a \texttt{pic}. This is used by
+% the \texttt{natoapp6cs}, \texttt{chit}, and \texttt{hex} node
+% shapes extensively.
+%
+% The arguments are
+% \begin{enumerate}
+% \item Prefix
+% \item Position
+% \item Fixed options
+% \item User options
+% \item Picture.
+% \end{enumerate}
+%
+% That is, the macro expects calls like
+% \begin{Syntax}
+% \cs{wg@pic}\oarg{options}\meta{picture}\cs{@endwg@pic}\marg{prefix}\marg{position}\marg{options}
+% \end{Syntax}
+%
+% Note the \cs{@endwg@pic} at the end of the call to swallow up
+% \meta{picture}. Typically this macro is used as
+%
+% \begin{Syntax}
+% \cs{edef}\cs{args}\{\meta{something}\}
+% \cs{expandafter}\cs{wg@pic}\cs{args}\cs{@endwg@pic}\marg{prefix}\parg{position}\marg{options}
+% \end{Syntax}
+%
+% where \meta{something} typically expands to \oarg{user
+% option}\meta{picture}
+%
+% First, the top-level macro \cs{wg@pic} that looks for user
+% options.
+%
+% \begin{macrocode}
+\def\wg@pic{%
+ \@ifnextchar[{\wg@@pic}{\wg@@pic[]}%]
+}
+% \end{macrocode}
+%
+% This macro then forwards to \cs{wg@@pic} to gobble up
+% \meta{picture}.
+%
+% \begin{enumerate}
+% \item User options
+% \item Arguments
+% \end{enumerate}
+%
+% \begin{macrocode}
+\def\wg@@pic[#1]#2\@endwg@pic{%
+ \wg@dbg{2}{Options: `#1', picture: `#2'}%
+ \wg@@@pic{#1}{#2}%
+}
+% \end{macrocode}
+%
+% \begin{enumerate}
+% \item User options
+% \item Arguments
+% \item Prefix
+% \item Coordinates
+% \item Fixed options
+% \end{enumerate}
+%
+% \begin{macrocode}
+\def\wg@@@pic#1#2#3#4#5{%
+ \ifx|#2|\wg@dbg{3}{No picture given}%
+ \else%
+ \wg@dbg{3}{^^JWG Pic:
+ ^^J User options: #1
+ ^^J Picture: #2
+ ^^J Prefix: #3
+ ^^J Coordinates: #4
+ ^^J Fixed options: #5}%
+ % \wg@dbg{2}{\string\pic[#5,#1] at (#4) {#3#2}}%
+ \pic[#5,#1] at (#4) {#3#2};%
+ \ifwg@s@ve%
+ \pgf@relevantforpicturesizetrue%
+ \begin{getbbl}%
+ \pic[draw=none,fill=none,transform shape] at (#4) {#3#2};%
+ \end{getbbl}%
+ \wg@dbg{5}{Clipping to local bounding box}%
+ \clip (L.south west) rectangle (L.north east);%
+ \pgf@relevantforpicturesizefalse \global\wg@s@vefalse%
+ \fi
+ \fi%
+ \wg@dbg{3}{End of WG Pic}
+}
+% \end{macrocode}
+% \end{Macro}
+%
+%
+% \begin{Macro}{\wg@pic@all}
+%
+% This macro sets all pictures in a list.
+%
+% \begin{enumerate}
+% \item List
+% \item Prefix
+% \item Position
+% \item Styles
+% \end{enumerate}
+%
+%
+% \begin{macrocode}
+\def\wg@pic@all#1#2#3#4{%
+ \wg@dbg{2}{WG picture loop
+ ^^J List: \meaning#1
+ ^^J Prefix: `#2'
+ ^^J Position: `#3'
+ ^^J Styles: `#4'}
+ \foreach \p in #1{%
+ \wg@dbg{2}{WG picture element: \meaning\p}%
+ \expandafter\wg@pic\p\@endwg@pic {#2}{#3}{#4}%
+ }%
+}
+% \end{macrocode}
+% \end{Macro}
+%
+% \iffalse
+% --------------------------------------------------------------------
+% \fi
+%
+% \subsubsection{Nodes in compound nodes}
+%
+% \begin{Macro}{\wg@node}
+% The macro \cs{wg@node} will render a \texttt{node}. This can be
+% used by the \texttt{natoapp6cs}, \texttt{chit}, and \texttt{hex}
+% node shapes.
+%
+% The arguments are
+% \begin{enumerate}
+% \item Prefix
+% \item Position
+% \item Fixed options
+% \item User options
+% \item Body.
+% \end{enumerate}
+%
+% That is, the macro expects calls like
+% \begin{Syntax}
+% \cs{wg@node}\oarg{options}\meta{body}\cs{@endwg@node}\marg{prefix}\marg{position}\marg{options}
+% \end{Syntax}
+%
+% Note the \cs{@endwg@node} at the end of the call to swallow up
+% \meta{body}. Typically this macro is used as
+%
+% \begin{Syntax}
+% \cs{edef}\cs{args}\{\meta{something}\}
+% \cs{expandafter}\cs{wg@node}\cs{args}\cs{@endwg@node}\marg{prefix}\parg{position}\marg{options}
+% \end{Syntax}
+%
+% where \meta{something} typically expands to \oarg{user
+% option}\meta{body}
+%
+% First, the top-level macro \cs{wg@node} that looks for user
+% options.
+%
+% \begin{macrocode}
+\def\wg@node{%
+ \@ifnextchar[{\wg@@node}{\wg@@node[]}%]
+}
+% \end{macrocode}
+%
+% This macro then forwards to \cs{wg@@node} to gobble up
+% \meta{body}.
+%
+% \begin{enumerate}
+% \item User options
+% \item Arguments
+% \end{enumerate}
+%
+% \begin{macrocode}
+\def\wg@@node[#1]#2\@endwg@node{%
+ \wg@dbg{2}{Options: `#1', body: `#2'}%
+ \wg@@@node{#1}{#2}%
+}
+% \end{macrocode}
+%
+% \begin{enumerate}
+% \item User options
+% \item Arguments
+% \item Prefix
+% \item Coordinates
+% \item Fixed options
+% \end{enumerate}
+%
+% \begin{macrocode}
+\def\wg@@@node#1#2#3#4#5{%
+ \ifx|#2|\wg@dbg{3}{No body given}%
+ \else%
+ \wg@dbg{3}{^^JWG Pic:
+ ^^J User options: #1
+ ^^J Body: #2
+ ^^J Prefix: #3
+ ^^J Coordinates: #4
+ ^^J Fixed options: #5}%
+ % \wg@dbg{2}{\string\pic[#5,#1] at (#4) {#3#2}}%
+ \node[#5,#1] at (#4) {#3#2};%
+ \fi%
+ \wg@dbg{3}{End of WG Node}
+}
+% \end{macrocode}
+% \end{Macro}
+%
+%
+% \begin{Macro}{\wg@node@all}
+%
+% This macro sets all pictures in a list.
+%
+% \begin{enumerate}
+% \item List
+% \item Prefix
+% \item Position
+% \item Styles
+% \end{enumerate}
+%
+%
+% \begin{macrocode}
+\def\wg@node@all#1#2#3#4{%
+ \wg@dbg{2}{WG picture loop
+ ^^J List: \meaning#1
+ ^^J Prefix: `#2'
+ ^^J Position: `#3'
+ ^^J Styles: `#4'}
+ \foreach \p in #1{%
+ \wg@dbg{2}{WG picture element: \meaning\p}%
+ \expandafter\wg@node\p\@endwg@node {#2}{#3}{#4}%
+ }%
+}
+% \end{macrocode}
+% \end{Macro}
+%
+% \iffalse
+% --------------------------------------------------------------------
+% \fi
+%
+% \subsubsection{Bounding boxes}
+%
+% Bounding box dimensions
+%
+%
+% \begin{macrocode}
+\newdimen\wg@bb@minx
+\newdimen\wg@bb@miny
+\newdimen\wg@bb@maxx
+\newdimen\wg@bb@maxy
+% \end{macrocode}
+%
+%
+%
+% Enable or disable bounding box tracking
+%
+% \begin{macrocode}
+\newif\ifwg@notrelevantforpathsize\wg@notrelevantforpathsizefalse
+% \end{macrocode}
+%
+%
+% \begin{Macro}{wg@resetbb}
+% Reset the bounding box tracking dimensions
+%
+% \begin{macrocode}
+\def\wg@resetbb{%
+ \global\wg@bb@minx=16000pt\relax%
+ \global\wg@bb@miny=16000pt\relax%
+ \global\wg@bb@maxx=-16000pt\relax%
+ \global\wg@bb@maxy=-16000pt\relax%
+}
+% \end{macrocode}
+% \end{Macro}
+%
+% \begin{Macro}{\old@pgf@protocolsize}
+% Save PGF's bounding box algorithm
+%
+% \begin{macrocode}
+\let\old@pgf@protocolsize\pgf@protocolsizes
+% \end{macrocode}
+% \end{Macro}
+%
+% \begin{Macro}{\wg@protocolsizes}
+% Our bounding box algorithm
+%
+% \begin{macrocode}
+\def\wg@protocolsizes#1#2{%
+ \old@pgf@protocolsize{#1}{#2}
+ \ifwg@notrelevantforpathsize\else%
+ \ifdim#1<\wg@bb@minx\global\wg@bb@minx#1\fi%
+ \ifdim#1>\wg@bb@maxx\global\wg@bb@maxx#1\fi%
+ \ifdim#2<\wg@bb@miny\global\wg@bb@miny#2\fi%
+ \ifdim#2>\wg@bb@maxy\global\wg@bb@maxy#2\fi%
+ \fi
+}
+% \end{macrocode}
+% \end{Macro}
+%
+% % \begin{environment}{getbbl}
+% Environment that tracks the local bounding box
+%
+% \begin{macrocode}
+\newenvironment{getbbl}{%
+ \wg@resetbb%
+ \wg@notrelevantforpathsizefalse%
+ \global\let\pgf@protocolsizes\wg@protocolsizes}{%
+ \gdef\pgf@sh@ns@L{rectangle}
+ \gdef\pgf@sh@np@L{%
+ \def\southwest{\pgfqpoint{\the\wg@bb@minx}{\the\wg@bb@miny}}%
+ \def\northeast{\pgfqpoint{\the\wg@bb@maxx}{\the\wg@bb@maxy}}%
+ }
+ \gdef\pgf@sh@nt@L{{1}{0}{0}{1}{0pt}{0pt}}
+ \gdef\pgf@sh@pi@L{\pgfpictureid}
+ \global\let\pgf@protocolsizes\old@pgf@protocolsize
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \begin{environment}{getbb}
+% Environment to track global bounding box
+%
+% \begin{macrocode}
+\newenvironment{getbb}{%
+ \wg@resetbb%
+ \wg@notrelevantforpathsizefalse%
+ \global\let\pgf@protocolsizes\wg@protocolsizes}{%
+ \gdef\pgf@sh@ns@M{rectangle}
+ \gdef\pgf@sh@np@M{%
+ \def\southwest{\pgfqpoint{\the\wg@bb@minx}{\the\wg@bb@miny}}%
+ \def\northeast{\pgfqpoint{\the\wg@bb@maxx}{\the\wg@bb@maxy}}%
+ }
+ \gdef\pgf@sh@nt@M{{1}{0}{0}{1}{0pt}{0pt}}
+ % \pgfgettransform\pgf@temp%
+ % \xdef\pgf@sh@nt@M{\pgf@temp}
+ % \pgfgettransformentries{\wg@tmp@a}{\wg@tmp@b}{\wg@tmp@c}{\wg@tmp@d}{\pgf@temp}{\pgf@temp}
+ % \message{^^JTransform of M: \meaning\pgf@temp}
+ % \xdef\pgf@sh@nt@M{{\wg@tmp@a}{\wg@tmp@b}{\wg@tmp@c}{\wg@tmp@d}{0pt}{0pt}}%
+ % \message{^^JTransform of M: \meaning\pgf@sh@nt@M}
+ \gdef\pgf@sh@pi@M{\pgfpictureid}
+ \global\let\pgf@protocolsizes\old@pgf@protocolsize
+}
+% \end{macrocode}
+% \end{environment}
+%
+% \iffalse
+% --------------------------------------------------------------------
+% \fi
+%
+% \subsubsection{Other Tikz utilities}
+%
+% \begin{TikzKey}{tikz/reverseclip}
+%
+% A reverse clipping path. This is used to cut out stuff outside of
+% path defined.
+%
+% \begin{macrocode}
+\tikzstyle{reverseclip}=[insert path={(current bounding box.north east) --
+ (current bounding box.south east) --
+ (current bounding box.south west) --
+ (current bounding box.north west) --
+ (current bounding box.north east)}]
+% \end{macrocode}
+% \end{TikzKey}
+%
+% \begin{TikzKey}{tikz/clip even odd rule}
+% A reverse clipping path
+%
+% \begin{macrocode}
+\tikzset{
+ clip even odd rule/.code={\pgfseteorule}, % Credit to Andrew Stacey
+}
+% \end{macrocode}
+% \end{TikzKey}
+%
+%
+% \begin{TikzKey}{tikz/invclip}
+%
+% Inverse clipping. This should be an option \emph{after} the path to
+% do the inverse clipping by. This works by adding a \emph{large}
+% (page) path to the current path, and then use that as clipping.
+%
+% \begin{macrocode}
+\tikzset{
+ invclip/.style={
+ clip,insert path=
+ [clip even odd rule]{
+ [reset cm](-\maxdimen,-\maxdimen)rectangle(\maxdimen,\maxdimen)
+ }
+ },
+}
+% \end{macrocode}
+% \end{TikzKey}
+%
+% \begin{TikzKey}{save clip}
+%
+% An option for use with sub-elements of NATO App 6(c) or chit
+% nodes. This will save the current path as a clipping path for the
+% next paths to be drawn in the sub-element
+%
+% \begin{macrocode}
+\newif\ifwg@s@ve\wg@s@vefalse
+\tikzset{
+ save clip/.is choice,
+ save clip/true/.code={\global\wg@s@vetrue},
+ save clip/false/.code={\global\wg@s@vefalse},
+ save clip/.default={true},
+ save clip/.initial={false},
+}
+% \end{macrocode}
+% \end{TikzKey}
+%
+% \begin{TikzKey}{scale line widths}
+%
+% Scales any line width specified in the node options.
+%
+% Use like
+%
+% \begin{verbatim}
+% \tikzset{
+% some/.style={
+% scale line widths,
+% line width=1pt}
+% }
+% \end{verbatim}
+%
+% Note that the order is important.
+%
+% \begin{macrocode}
+\tikzset{
+ scale line widths/.style={%
+ /utils/exec=\def\tikz@semiaddlinewidth##1{%
+ \pgfgettransformentries{%
+ \wg@jaca}{%
+ \wg@jacb}{%
+ \wg@jacc}{%
+ \wg@jacd}{%
+ \wg@tmp}{%
+ \wg@tmp}%
+ \pgfmathsetmacro{\wg@jac}{sqrt(abs(\wg@jaca*\wg@jacd-\wg@jacb*\wg@jacc))}%
+ \wg@dbg{4}{Scaling line width ##1 by \wg@jac}
+ \pgfmathsetmacro{\wg@lw}{\wg@jac*##1}%
+ \wg@dbg{4}{Scaled ##1 -> \wg@lw}
+ \tikz@addoption{\pgfsetlinewidth{\wg@lw pt}}%
+ \wg@dbg{4}{Added scaled option \wg@lw}
+ \pgfmathsetlength\pgflinewidth{\wg@lw pt}
+ \wg@dbg{4}{Did set line width \wg@lw pt}
+ }},
+ relative line width/.style={%
+ /utils/exec=\def\tikz@semiaddlinewidth##1{%
+ \wg@dbg{4}{Relative line width #1 times ##1}%
+ \pgfmathsetmacro{\wg@lv}{#1*##1}%
+ \tikz@addoption{\pgfsetlinewidth{\wg@lw pt}}%
+ \pgfmathsetlength\pgflinewidth{\wg@lw pt}}}
+}
+% \end{macrocode}
+% \end{TikzKey}
+%
+% \begin{TikzKey}{sub pic actions}
+%
+% This is key that propagates actions to sub pictures of pictures.
+% The normal \texttt{pic actions} cannot be used as it causes an
+% infinite loop.
+%
+% \begin{macrocode}
+\tikzset{
+ sub pic actions/.code={%
+ \tikz@picmode%
+ \edef\opts{%
+ \iftikz@mode@draw draw,\else draw=none,\fi
+ \iftikz@mode@fill fill\else fill=none\fi}
+ \wg@dbg{5}{^^JSub Mode: \meaning\tikz@picmode \meaning\opts}
+ \pgfset{/tikz/.cd}
+ \pgfkeysalsofrom{\opts}
+ }}
+% \end{macrocode}
+% \end{TikzKey}
+%
+% \begin{TikzKey}{wg/debug show}
+%
+% Show debugging information
+%
+% \begin{macrocode}
+\tikzset{
+ wg/debug show/.code={%
+ \extractcolorspec{pgfstrokecolor}{\wg@tmp@fg}
+ \def\wg@tmp@bg{none}
+ \@ifundefinedcolor{pgffillcolor}{}{
+ \extractcolorspec{pgffillcolor}{\wg@tmp@bg}}
+ \begingroup
+ \tikz@mode
+ \wargamedbglvl=#1
+ \wg@dbg{3}{Drawing with w/stroke `\wg@tmp@fg'
+ (\tikz@strokecolor,\iftikz@mode@draw\else not\space\fi drawing)
+ and fill `\wg@tmp@bg' (\tikz@fillcolor,\iftikz@mode@fill\else
+ not\space\fi filling)}
+ \endgroup
+ }
+}
+% \end{macrocode}
+% \end{TikzKey}
+%
+%
+% \iffalse
+% --------------------------------------------------------------------
+% \fi
+%
+% \subsubsection{Random IDs}
+%
+%
+% \begin{macrocode}
+\def\wg@r@ndom@id{%
+ \def\wg@uuid{}
+ \foreach \i in {1,...,8}{%
+ \pgfmathparse{Hex(random(0,15))}
+ \xdef\wg@uuid{\wg@uuid\pgfmathresult}}}
+% \end{macrocode}
+%
+% \iffalse
+%</utils>
+%\fi
+% \iffalse
+% ====================================================================
+% \fi
+%
+% \subsection{The \texttt{wgexport} class}
+% \label{sec:impl:util}
+%
+% This document class is used for exporting game component to be used
+% in a VASSAL module
+% libraries.
+%
+% \iffalse
+%<*exportcls>
+%\fi
+%
+% Class identification and load \texttt{wargame} package
+%
+% \begin{macrocode}
+\ProvidesClass{wgexport}
+\PassOptionsToClass{multi=tikzpicture,varwidth=false}{standalone}
+\DeclareOption{noterrainpic}{%
+ \PassOptionsToPackage{\CurrentOption}{wargame}}
+\DeclareOption{terrainpic}{%
+ \PassOptionsToPackage{\CurrentOption}{wargame}}
+\DeclareOption*{%
+ \PassOptionsToClass{\CurrentOption}{standalone}}
+\ProcessOptions\relax
+\LoadClass{standalone}
+\RequirePackage{wargame}
+% \end{macrocode}
+%
+% We need a few utilities before we get to the actual environment.
+% First, we need a tools to write out literal left and right curly
+% braces. We do a bit of catcode hackery to accomplish that.
+%
+% \begin{macrocode}
+\begingroup
+\catcode`\^^I=12
+\def\@tabchar{^^I}
+\catcode`<=1 \catcode`>=2
+\catcode`{=12 \catcode`}=12
+\gdef\@lbchar<{>
+\gdef\@rbchar<}>
+\endgroup
+% \end{macrocode}
+%
+% Above, we temporarily set the tab, and left and right curly brace
+% characters to be regular letters (12), and the catcodes of less than
+% and greater than to be those of left and right curly braces
+% respectively. We then define the macros \cs{@tabchar},
+% \cs{@lbchar}, and \cs{@rbchar} to produce literal characters.
+% \LaTeX already has \cs{@percentchar}.
+%
+% Everything we do should go inside this environment. The single
+% optional argument is the file name stem of the output JSON file.
+%
+% \begin{macrocode}
+\newenvironment{imagelist}[1][\jobname]{%
+ \newwrite\mk@out%
+ \def\mk@i{}%
+ \def\mk@w{\immediate\write\mk@out}%
+ \immediate\openout\mk@out=#1.json
+ \mk@w{[}
+}{
+ \mk@w{\mk@i \@lbchar "name":"End of list", "category": "<<eol>>",
+ "subcategory": "" \@rbchar }
+ \mk@w{]}
+ \immediate\closeout\mk@out
+}
+% \end{macrocode}
+%
+%
+% Preceed all images (\textsf{tikzpicture}) with this command
+%
+% First argument is the name of the image. This can be anything.
+% Note that for counters, if the name ends in \texttt{flipped} then it
+% is considered the backside of a counter.
+%
+% Second argument is the type of image. Recognised types are
+%
+% \begin{itemize}
+% \item \texttt{board} for boards
+% \item \texttt{oob} for OOBs
+% \item \texttt{chart} for charts
+% \item \texttt{counter} for counters
+% \item \texttt{front} for front page
+% \end{itemize}
+%
+% Other types can be used, and the images will be exported, but the
+% Python script pays no particular attention to those then. Use for
+% example to prepare images for help or the like.
+%
+% The third argument is the sub type. This is most relevant for the
+% counters. Sub types can be anything, but since the counters will
+% receive different prototypes based on the sub type, it makes sense
+% to divide into sub types a la
+%
+% \begin{itemize}
+% \item factions
+% \item common markers
+% \end{itemize}
+%
+% The faction sub types should just be the name of the faction.
+% E.g., Allies, Axis, Soviet, NATO, Warsaw Pact. Spaces should not
+% matter.
+%
+% For common markers, there are a few names that are recognised
+% specifically by the Python script. These are
+%
+% \begin{itemize}
+% \item \texttt{common}
+% \item \texttt{all}
+% \item \texttt{marker}
+% \item \texttt{markers}
+% \end{itemize}
+%
+% Counters that has these sub-types will no be considered to belong
+% to any faction.
+%
+% Note that the Python script uses the faction names to guess the
+% players of the game, and uses them in several places.
+%
+%
+% \begin{macrocode}
+\def\info{%
+ \@ifstar{\@@info{,}}{\@@info{\@rbchar,}}}
+\def\@@info#1#2#3#4{%
+ \chit@dbg{2}{Making image `#2' of type `#3'/`#4' on page \thepage}%
+ \mk@w{ \@lbchar}%
+ \mk@w{ \space "name": "#2",}%
+ \mk@w{ \space "category": "#3",}%
+ \mk@w{ \space "subcategory": "#4", }%
+ \mk@w{ \space "number": \thepage #1}%
+ \let\oldmk@i\mk@i%
+ \ifx#1,\relax\edef\mk@i{\mk@i\space\space}\fi}
+\def\end@info{%
+ \let\mk@i\oldmk@i%
+ \mk@w{ \space \@rbchar,}}
+% \end{macrocode}
+%
+% Make separate images for each counter (single sided).
+%
+% \begin{macrocode}
+\newcommand\chitimages[2][]{%
+ \begingroup%
+ \let\chit@report\do@chit@report%
+ \let\natoapp@report\do@natoapp@report%
+ \chit@dbg{2}{chits to make images of `#2'}%
+ \foreach[count=\ti from 0] \t/\x in #2{%
+ \ifx\t\empty\else% Ignore empty rows
+ \message{^^JSubcategory: `\x' (default `#1')}
+ \ifx\t\x\def\x{#1}\fi% Take sub-category or default
+ \foreach \u/\m in \t{%
+ \ifx\u\empty\else% Ignore empty cells
+ \chit@dbg{2}{Next chit `\u' with possible multiplicity `\m'}%
+ \ifx\m\@empty\def\m{1}\fi% If not multiplicity defined
+ \ifx\u\m\def\m{1}\fi% If the same as unit
+ \chit@dbg{2}{Next chit `\u' multiplicity `\m'}%
+ %% We only make one copy of the chit, since we can duplicate
+ %% it in VASSAL
+ \info*{\u}{counter}{\x}
+ \begin{tikzpicture}
+ \chit[\u=\ti]%
+ \end{tikzpicture}
+ \end@info%
+ %% \foreach \n in {1,...,\m}{% Make a number of copies
+ %% \ifx\u\chit@blank%
+ %% \chit@dbg{3}{Ignoring blank chit:\u}%
+ %% \else%
+ %% \info{\u}{counter}{#2}
+ %% \begin{tikzpicture}
+ %% \chit[\u=\ti](\c,\r)%
+ %% \end{tikzpicture}
+ %% \fi%
+ %% }%
+ \fi%
+ }%
+ \chit@dbg{2}{End of inner loop}%
+ \fi%
+ }%
+ \chit@dbg{2}{End of outer loop}%
+ \endgroup%
+}
+% \end{macrocode}
+%
+% Make separate images for each counter (double sided). The back-side
+% counters must be defined by append `\texttt{ flipped}' the front
+% face name
+%
+% \begin{macrocode}
+\newcommand\doublechitimages[2][]{%
+ \begingroup%
+ \let\chit@report\do@chit@report%
+ \let\natoapp@report\do@natoapp@report%
+ \foreach[count=\ti from 0] \t/\x in #2{%
+ \ifx\t\empty\else% Ignore empty rows
+ \message{^^JSubcategory: `\x' (default `#1')}
+ \ifx\t\x\def\x{#1}\fi% Take sub-category or default
+ \foreach \u/\m in \t{%
+ \ifx\u\empty\else% Ignore empty cells
+ \chit@dbg{2}{Next chit `\u' with possible multiplicity `\m'}%
+ \ifx\m\@empty\def\m{1}\fi% If not multiplicity defined
+ \ifx\u\m\def\m{1}\fi% If the same as unit
+ \chit@dbg{2}{Next chit `\u' multiplicity `\m'}%
+ %% Flipped chit
+ \edef\s{\u\space flipped}%
+ %% We only make one copy of the chit, since we can duplicate
+ %% it in VASSAL
+ \info*{\u}{counter}{\x}%
+ \begin{tikzpicture}%
+ \chit[\u=\ti]%
+ \end{tikzpicture}%
+ \end@info%
+ \info*{\s}{counter}{\x}%
+ \begin{tikzpicture}%
+ \chit[\s=\ti]%
+ \end{tikzpicture}%
+ \end@info%
+ %% \foreach \n in {1,...,\m}{% Make a number of copies
+ %% \ifx\u\chit@blank%
+ %% \chit@dbg{3}{Ignoring blank chit:\u}%
+ %% \else%
+ %% \info{\u}{counter}{#2}
+ %% \begin{tikzpicture}
+ %% \chit[\u=\ti](\c,\r)%
+ %% \end{tikzpicture}
+ %% \fi%
+ %% }%
+ \fi%
+ }%
+ \fi%
+ }%
+ \endgroup%
+}
+% \end{macrocode}
+%
+% Special for boards, we have the environment \textsf{boardimage}.
+% Like \cs{info} we must specify the name and sub-category of the
+% board, but the category is assumed to be \texttt{board} (though the
+% optional argument can specify a different category).
+%
+% Within this environment some specific styles are defined that allows
+% the user to specify VASSAL zones on the board. For this to work
+% properly, the parent \textsf{tikzpicture} \emph{must} have the style
+% \texttt{zoned}. This style will record the bounding box of the
+% picture which we will need to calculate VASSAL coordinates later
+% on.
+%
+% Other styles are \texttt{zone scope}, to be applied to
+% \texttt{scope}s in the picture, and \texttt{zone path} to be applied
+% to \texttt{path}s (or \cs{draw}, \cs{fill}, or the like) in the
+% picture. These will record coordinates of these elements in side
+% the picture. The Python script will then define VASSAL zones based
+% on these coordinates.
+%
+% For \texttt{zone scope} applied to a \texttt{scope}, what is
+% recorded are
+%
+% \begin{itemize}
+% \item The current coordinate transformation matrix
+% \item The current translation
+% \item The bounding box, within the current transformation and
+% translation.
+% \end{itemize}
+%
+% To define a zone in the board, simply enclose it in a
+%
+% \begin{verbatim}
+% \begin{scope}[zone scope=name]
+% ...
+% \end{scope}
+% \end{verbatim}
+%
+% The \meta{name} will be the name of the scope. If this contains the
+% sub-string \texttt{hex} (upper, lower, or mixed case), then the zone
+% will get a hex grid with numbering attached to it.
+%
+% If the \meta{name} contains the sub-string \texttt{turn} (any case),
+% then it is assumed to be a turn track and a rectangular grid will be
+% attached. The column and row separator will be set to \texttt{T},
+% so that it won't collide with the main zone. Similar if \meta{name}
+% contains \texttt{oob}, except the separator is set to \texttt{O}.
+%
+% If \meta{name} contains the sub-string \texttt{pool}, then it is
+% assumed to be a pool of counters, and \emph{no} grid is attached.
+%
+% For \texttt{zone path} applied to a \texttt{path}, what is recorded
+% is the path coordinates (as straight line segments) in the global
+% coordinate system.
+%
+% Both styles take one argument --- the name of the zone. If that
+% name contains the sub-string \texttt{hex} anywhere in the name, then
+% the zone is assumed to contain a hex grid. Otherwise, a rectangular
+% grid (of fixed size) will be applied to it.
+%
+% The environment \texttt{boardimage} also records the coordinate
+% options currently in use (keys \texttt{hex/first row is},
+% \texttt{hex/row direction is}, and so on), as well as the current
+% label option (as defined by \texttt{every hex} or \texttt{every hex
+% node}).
+%
+% All coordinates, and such are recorded in centimetres. It is worth
+% remembering that the Tikz coordinate system has the $y$ axis point
+% upward, while typical image software has the $y$ axis point down.
+% \texttt{pdftocairo} typically assumes a 150 PPI (pixels-per-inch)
+% resolution.
+%
+% That means that scaling factor becomes
+%
+% $$\frac{150\mathrm{pixel}}{2.54\mathrm{cm}}=59.055\frac{\mathrm{pixel}}{\mathrm{cm}}$$
+%
+% \iffalse
+% Using definition in terms of printers feet - the one to use!
+%
+% PNG: 1674 x 1101
+% PDF: "lower left": [-0.02107,-0.02107],
+% "upper right": [28.31705,18.60843]
+% Width: 28.31705+0.02107 = 28.33812
+% Height: 18.60843+0.02107 = 18.62950
+% Pixel / cm: 1674 / 28.33812 = 59.07237318495369488166
+% 1101 / 18.62950 = 59.09981480984460130438
+% Average = 59.08609399739914809302
+%
+% Calculated = 150 / 2.54 = 59.05511811023622047244
+%
+% Using 1/72.27
+%
+% "lower left": [-0.02109,-0.02109],
+% "upper right": [28.321,18.61102]
+% Width: 28.321+0.02109=28.34209
+% Height: 18.61102+0.02109=18.63211
+% Pixel / cm: 1674 / 28.34209 = 59.06409866033168337267
+% 1101 / 18.63211 = 59.09153606328000425072
+% Average = 59.07781736180584381169
+% \fi
+%
+% The information extracted is written to the
+% \cs{jobname}\texttt{.json} file as a sub-object (with name given by
+% the first optional argument) of the image object. In that way, we
+% can later on easily get the information from our catalogue of
+% images.
+%
+% Note, the styles \texttt{zoned}, \texttt{zone scope}, and
+% \texttt{zone path} are defined in \texttt{wargame} to be dummies so
+% that one can have them in the definition of the board without
+% impact.
+%
+% Since we want to write all dimensions in centimetres, we need to be
+% able to convert \texttt{pt} dimensions to centimetres. We make two
+% macros to do that for us.
+%
+% The exact definition of 1pt is
+%
+% $$1\,\mathrm{pt} = \frac{249}{250}12"\frac{1}{864}=\frac{83}{6000}1"
+% = 0.03513\overline{6}$$
+%
+% \begin{macrocode}
+% 2.54 / 72.27 = .03514598035145980351
+% \def\pt@to@cm#1{\pgfmathparse{#1 * 0.0351460}}
+\def\pt@to@cm#1{\pgfmathparse{#1 * 0.0351367}}
+\def\ptpoint@to@cm#1#2{%
+ \pt@to@cm{#1}\edef\x{\pgfmathresult}%
+ \pt@to@cm{#2}\edef\y{\pgfmathresult}}
+% \end{macrocode}
+% \begin{macrocode}
+\def\get@bb#1{%
+ \pgfpointanchor{#1}{south west}%
+ \pgfgetlastxy\tmp@llx\tmp@lly%
+ \pgfpointanchor{#1}{north east}%
+ \pgfgetlastxy\tmp@urx\tmp@ury%
+ \pt@to@cm{\tmp@llx}\edef\llx{\pgfmathresult}
+ \pt@to@cm{\tmp@lly}\edef\lly{\pgfmathresult}
+ \pt@to@cm{\tmp@urx}\edef\urx{\pgfmathresult}
+ \pt@to@cm{\tmp@ury}\edef\ury{\pgfmathresult}}
+% \end{macrocode}
+% \begin{macrocode}
+\def\mk@transform{%
+ \pgfgettransformentries{\mxx}{\mxy}{\myx}{\myy}{\ptdx}{\ptdy}
+ \pt@to@cm{\ptdx}\edef\dx{\pgfmathresult}
+ \pt@to@cm{\ptdy}\edef\dy{\pgfmathresult}
+ \mk@w{ \mk@i "xx": \mxx,}
+ \mk@w{ \mk@i "xy": \mxy,}
+ \mk@w{ \mk@i "yx": \myx,}
+ \mk@w{ \mk@i "yy": \myy,}
+ \mk@w{ \mk@i "dx": \dx,}
+ \mk@w{ \mk@i "dy": \dy,}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\def\mk@bb#1{%
+ \get@bb{#1}
+ \mk@w{ \mk@i "lower left": [\llx,\lly],}
+ \mk@w{ \mk@i "upper right": [\urx,\ury],}
+ \begingroup
+ % \pgftransforminvert
+ \pgfpointanchor{#1}{south west}%
+ \pgfgetlastxy\tmp@llx\tmp@lly%
+ \pgfpointtransformed{\pgfpoint{\tmp@llx}{\tmp@lly}}
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ %
+ \pgfpointanchor{#1}{north east}%
+ \pgfgetlastxy\tmp@urx\tmp@ury%
+ \pgfgetlastxy\tmp@llx\tmp@lly%
+ \pgfpointtransformed{\pgfpoint{\tmp@urx}{\tmp@ury}}
+ \pgf@xb=\pgf@x
+ \pgf@yb=\pgf@y
+ \pt@to@cm{\the\pgf@xa}\edef\llx{\pgfmathresult}
+ \pt@to@cm{\the\pgf@ya}\edef\lly{\pgfmathresult}
+ \pt@to@cm{\the\pgf@xb}\edef\urx{\pgfmathresult}
+ \pt@to@cm{\the\pgf@yb}\edef\ury{\pgfmathresult}x
+ \mk@w{ \mk@i "global lower left": [\llx,\lly],}
+ \mk@w{ \mk@i "global upper right": [\urx,\ury]}
+ \endgroup
+}
+% \end{macrocode}
+%
+% For the key \texttt{zone path} to work, we need to be able to record
+% the path as it moves along. To that end, we make a custom
+% decoration that will do that for us, and, once the path is finished,
+% write the path to our JSON file.
+%
+% \begin{macrocode}
+\pgfdeclaredecoration{record path construction}{initial}{%
+ \state{initial}[width=0pt,next state=more]{
+ \begingroup
+ \pgf@decorate@inputsegment@first
+ \ptpoint@to@cm{\the\pgf@x}{\the\pgf@y}
+ \xdef\wg@path{[\x,\y]}
+ \endgroup
+ }%
+ \state{more}[width=\pgfdecoratedinputsegmentremainingdistance]{%
+ \begingroup
+ \pgf@decorate@inputsegment@last
+ \ptpoint@to@cm{\the\pgf@x}{\the\pgf@y}
+ \xdef\wg@path{\wg@path,[\x,\y]}
+ \endgroup
+ }
+ \state{final}{%
+ \begingroup
+ \pgf@decorate@inputsegment@last
+ \ptpoint@to@cm{\the\pgf@x}{\the\pgf@y}
+ \xdef\wg@path{\wg@path,[\x,\y]}
+ \endgroup
+ \mk@w{ \mk@i "zone path \wg@record@path@name": \@lbchar}
+ \mk@w{ \mk@i\space "path": [\wg@path] \@rbchar,}
+ }
+}%
+% \end{macrocode}
+%
+% Now we can make our environment
+%
+% The first thing we do is to use the \cs{info} macro to mark the
+% image. Then we open our JSON file. We make a short-hand macro for
+% writing to that file. The macro \cs{bd@i} records the current
+% indention (which is important in JSON)
+%
+% \begin{macrocode}
+\newenvironment{boardimage}[3][board]{%
+ \def\bd@n{#2}
+ \newcount\mk@point
+ \mk@point=0
+ \let\oomk@i\mk@i%
+% \end{macrocode}
+%
+%
+% Then, to extract the label option, we make a dummy \texttt{node}
+% with the styles \texttt{every hex} and \texttt{every hex node}, so
+% we can extract that option.
+%
+% \begin{macrocode}
+ \info{dummy}{<<dummy>>}{}%
+ %\tikz{}%
+ \tikz{\scoped[every hex/.try,every hex node/.try]{%
+ \node[inner sep=0,outer sep=0]{%
+ \global\let\mk@label\hex@label}}}%
+% \end{macrocode}
+%
+% The next thing we do is to make an object. The first things we put
+% in are the units used (``cm''), and the grid options.
+%
+% \begin{macrocode}
+ \info*{#2}{#1}{#3}%
+ \mk@w{ \mk@i "zones": \@lbchar}%
+ \edef\mk@i{\mk@i\space}
+ %% Everything is made into centimeters
+ \mk@w{ \mk@i "units": "cm",}
+ \message{^^Jlabel: \meaning\mk@label}
+ \@ifundefined{mk@label}{}{\mk@w{ \mk@i "labels": "\mk@label",}}
+ %% Write out coordinate options as "coords" object
+ \mk@w{ \mk@i"coords": \@lbchar}%
+ \mk@w{ \mk@i "row": \@lbchar}%
+ \mk@w{ \mk@i\space "offset": \hex@coords@row@off,}%
+ \mk@w{ \mk@i\space "factor": \hex@coords@row@fac \@rbchar,}%
+ \mk@w{ \mk@i "column": \@lbchar}%
+ \mk@w{ \mk@i\space "offset": \hex@coords@col@off,}%
+ \mk@w{ \mk@i\space "factor": \hex@coords@col@fac,}%
+ \mk@w{ \mk@i\space "top short": "\hex@top@short@col",}%
+ \mk@w{ \mk@i\space "bottom short": "\hex@bot@short@col" \@rbchar}%
+ \mk@w{ \mk@i\@rbchar,}%
+% \end{macrocode}
+%
+% We then monkey-patch \cs{boardframe} to also output coordinates to
+% our JSON file. Note that this will probably be embedded in a
+% different object.
+%
+% \begin{macrocode}
+ %%
+ \let\oldbo@rdframe\bo@rdframe%
+ \def\bo@rdframe[##1](##2)(##3){%
+ \oldbo@rdframe[##1](##2)(##3)%
+ \mk@w{ \mk@i"board frame": \@lbchar}
+ \mk@w{ \mk@i\space "lower left": [\llx,\lly],}
+ \mk@w{ \mk@i\space "upper right": [\urx,\ury],}
+ \mk@w{ \mk@i\space "margin": \margin,}
+ \mk@w{ \mk@i\space "width": \w,}
+ \mk@w{ \mk@i\space "height": \h \@rbchar,}}%
+% \end{macrocode}
+%
+% Next, we make the style \texttt{zoned} to be applied to the
+% \texttt{tikzpicture} environment. This records the bounding box of
+% the full picture.
+%
+% \begin{macrocode}
+ \tikzset{
+ zoned/.code={% Apply to whole picture
+ \pgfkeys{%
+ % This needs to be done in the picture!
+ /tikz/execute at end picture={%
+ \mk@w{ \mk@i "zoned": \@lbchar}
+ \mk@transform%
+ \mk@bb{current bounding box}
+ \mk@w{ \mk@i \@rbchar,}
+ }
+ }
+ },
+% \end{macrocode}
+%
+% The next style is the \texttt{zone scope}. At the start of the
+% scope we record the current transformation matrix. Then we install
+% a handler to extract the bounding box at the end of the scope. Note
+% that we increase indention here.
+%
+% \begin{macrocode}
+ zone scope/.code={%
+ \mk@w{ \mk@i"zone scope ##1": \@lbchar}
+ \let\omk@i\mk@i
+ \edef\mk@i{\mk@i\space}
+ \mk@transform%
+ %\bd@w{ \@rbchar,}
+ \gdef\wg@export@box{##1}%
+ \pgfkeys{%
+ /tikz/local bounding box=wg export box,
+ /tikz/execute at end scope={
+ \mk@bb{wg export box}
+ \let\mk@i\omk@i
+ \mk@w{ \mk@i\@rbchar,}},
+ } % pgfkeys
+ }, % zone scope
+% \end{macrocode}
+% The next style gets the global coordinates of the current (0,0)
+% point - f.ex. in a node - and outputs that
+% \begin{macrocode}
+ zone point/.code n args={3}{
+ \advance\mk@point1
+ \global\mk@point=\mk@point
+ \pgf@xa=##2 cm
+ \pgf@ya=##3 cm
+ \pgfpointtransformed{\pgfpoint{\pgf@xa}{\pgf@ya}}
+ % \pgfpointtransformed{\pgfpoint{0pt}{0pt}}
+ \pgf@xa=\pgf@x
+ \pgf@ya=\pgf@y
+ \pt@to@cm{\the\pgf@xa}\edef\px{\pgfmathresult}
+ \pt@to@cm{\the\pgf@ya}\edef\py{\pgfmathresult}
+ \mk@w{ \mk@i "point\the\mk@point": \@lbchar "name": "##1", "type": "point", "coords": [\px,\py]
+ \@rbchar, }
+ %\message{^^JZone point \the\mk@point\space ##1: ##2,##3 -> \px,\py}
+ },
+% \end{macrocode}
+%
+% The \texttt{zone path} style is a bit more simple, but only because
+% the bulk of the work is done in a decoration. We need to be able to
+% pass a name to that decoration, s we make a key for that. The user
+% need not think about that though.
+%
+% \begin{macrocode}
+ /pgf/decoration/record path name/.store in=\wg@record@path@name,
+ zone path/.style={%
+ postaction={decorate,decoration={
+ record path construction,
+ record path name=##1}}
+ } % zone path
+ }% tikzset
+}
+% \end{macrocode}
+%
+% That finishes the first part of the environment. At the end of the
+% environment, we simple write the name of the picture, and close our
+% JSON output.
+%
+% \begin{macrocode}
+{%
+ \mk@w{ \mk@i "name": "\bd@n" }%
+ \let\mk@i\oomk@i%
+ \mk@w{ \mk@i\@rbchar}%
+ \end@info%
+}
+% \end{macrocode}
+%
+%
+% TO BE DONE: We could add hooks to both the \texttt{hex} and
+% \texttt{chit} shapes that would allow us to write out the settings
+% for each of these. This would allow us to make data files that
+% contain the information available in the \LaTeX{} code. For
+% example, we could write a counters
+%
+% \begin{itemize}
+% \item Left and right identifiers
+% \item Upper left, upper right, lower left, and lower right
+% identifiers. (some care must be taken if these contains graphics
+% and not just text.)
+% \item Factors
+% \item NATO symbol
+% \begin{itemize}
+% \item Faction, command, echelon
+% \item Mains
+% \item Left, right, top, and bottom attributes and modifiers
+% \item Below attribute
+% \end{itemize}
+% \end{itemize}
+%
+% If one then assumed that for example the upper left corner holds the
+% start-up hex, then one could use that information.
+%
+% The code below exports the chit information to the JSON file. Not
+% sure how to use it though.
+%
+% \begin{macrocode}
+\tikzset{
+ zone turn/.store in=\zone@turn,
+ zone mult/.store in=\zone@mult
+}
+\def\do@chit@report{%
+ \mk@w{ \mk@i "chit": \@lbchar}
+ \@ifundefined{id}{} {\mk@w{ \mk@i\space "id": "\id", }}%
+ \@ifundefined{chit@symbol}{} {\mk@w{ \mk@i\space "symbol": "true", }}%
+ \@ifundefined{chit@full}{} {\mk@w{ \mk@i\space "full": "\chit@full", }}
+ \@ifundefined{chit@factors}{} {\mk@w{ \mk@i\space "factors": "\chit@factors", }}%
+ \@ifundefined{chit@left}{} {\mk@w{ \mk@i\space "left": "\chit@left", }}%
+ \@ifundefined{chit@right}{} {\mk@w{ \mk@i\space "right": "\chit@right", }}%
+ \@ifundefined{chit@upper@left}{} {\mk@w{ \mk@i\space "upper left": "\chit@upper@left", }}%
+ \@ifundefined{chit@lower@left}{} {\mk@w{ \mk@i\space "lower left": "\chit@lower@left", }}%
+ \@ifundefined{chit@upper@right}{}{\mk@w{ \mk@i\space "upper right": "\chit@upper@right", }}%
+ \@ifundefined{chit@lower@right}{}{\mk@w{ \mk@i\space "lower right": "\chit@lower@right}", }%
+ \mk@w{ \mk@i\space "end": 0}
+ \@ifundefined{chit@symbol}{
+ \mk@w{ \mk@i \@rbchar }
+ }{
+ \mk@w{ \mk@i \@rbchar, }% NATOAPP6c will follow
+ }%
+}
+\def\do@natoapp@report{%
+ \mk@w{ \mk@i "natoapp6c": \@lbchar}
+ \@ifundefined{id}{}{\mk@w{ \mk@i\space "id": "\id", }}
+ \@ifundefined{natoapp@fac}{}{\mk@w{ \mk@i\space "faction": "\natoapp@fac", }}
+ \@ifundefined{natoapp@cmd}{}{\mk@w{ \mk@i\space "command": "\natoapp@cmd", }}
+ \@ifundefined{natoapp@ech}{}{\mk@w{ \mk@i\space "echelon": "\natoapp@ech", }}
+ \@ifundefined{natoapp@main}{}{\mk@w{ \mk@i\space "main": "\natoapp@main", }}
+ \@ifundefined{natoapp@left}{}{\mk@w{ \mk@i\space "left": "\natoapp@left", }}
+ \@ifundefined{natoapp@right}{}{\mk@w{ \mk@i\space "right": "\natoapp@right", }}
+ \@ifundefined{natoapp@upper}{}{\mk@w{ \mk@i\space "upper": "\natoapp@upper", }}
+ \@ifundefined{natoapp@lower}{}{\mk@w{ \mk@i\space "lower": "\natoapp@lower", }}
+ \@ifundefined{natoapp@below}{}{\mk@w{ \mk@i\space "below": "\natoapp@below", }}
+ \mk@w{ \mk@i\space "end": 0}
+ \mk@w{ \mk@i \@rbchar}
+}
+% \end{macrocode}
+% \iffalse
+%</exportcls>
+%\fi
+%