\RequirePackage{jbw-list} \RequirePackage{ifthen} \RequirePackage{jbw-prog-util} \RequirePackage{pstricks} \RequirePackage{jbw-load-pst-node} \RequirePackage{jbw-parbox} % Plain TeX dependencies: \newcount % LaTeX internals dependencies: % \@namedef, \@nameuse, \@ifundefined, \@gobbletwo % NODE is {NODE_TYPE}{LABEL}{TEXT} % PRECEDENCE is {LABEL1}{LABEL2}{OPT_EDGE} % OPT_EDGE is either empty (gets default behavior) or EDGE_TYPE \newcount\jbwpd@ColumnA \newcount\jbwpd@ColumnB \newcount\jbwpd@HighestColumn \newcommand{\PrecedenceDiagramTimeSep}{1.5cm} \newcommand{\PrecedenceDiagramSimulSep}{0.4cm} \newcommand{\PrecedenceDiagramNodeMaxWidth}{2.7cm} \newcommand{\jbwpd@DiagramNumber}{0} \newboolean{jbwpd@Horiz} \newcommand{\jbwpd@StoreRegisterInMacroByName}[2] {% #1 is REGISTER % #2 is CS_NAME \Expand{\the#1} {% ##1 is the result of expanding \the#1 \@namedef{#2}{##1}}} \newcommand{\PrecedenceDiagram}[3][horiz] {% #1 is ORIENTATION % #2 is list of NODE % #3 is list of PRECEDENCE \hbox\bgroup \ifthenelse{\equal{#1}{horiz}} {\setboolean{jbwpd@Horiz}{true}} {\ifthenelse{\equal{#1}{vert}} {\setboolean{jbwpd@Horiz}{false}} {\PackageError{jbw-precedence-diagram} {Precedence diagram orientation must be either "horiz" or "vert".} {No additional help.}}}% %\TraceOn \dolist{#2} {} {% ##1 is {LABEL}{TEXT} \usetemplate{##1} {% ####1 is TYPE % ####2 is LABEL % ####3 is TEXT \@namedef{jbwpd@node@column@####2}{0}}} {}% \jbwpd@HighestColumn=0% %\TraceOn \jbwpd@ColumnA=\jbwpd@DiagramNumber\relax \advance\jbwpd@ColumnA by 1\relax \Expand{\the\jbwpd@ColumnA} {% ##1 is DIAGRAM_LABEL \global\def\jbwpd@DiagramNumber{##1}% \jbwpd@AssignColumns{#3}{#2}{##1}}} \newboolean{jbwpd@ColumnsChanged} \newcommand{\jbwpd@AssignSecondLabelHigherColumn}[2] {% #1 is LABEL1 % #2 is LABEL2 \jbwpd@ColumnA=\@nameuse{jbwpd@node@column@#1}\relax %\showthe\jbwpd@ColumnA %\TraceOn \IfNum{\jbwpd@ColumnA<\@nameuse{jbwpd@node@column@#2}\relax} {} {\advance\jbwpd@ColumnA by 1\relax \jbwpd@StoreRegisterInMacroByName{\jbwpd@ColumnA}{jbwpd@node@column@#2}% \IfNum{\jbwpd@HighestColumn<\jbwpd@ColumnA} {\jbwpd@HighestColumn=\jbwpd@ColumnA} {}% \setboolean{jbwpd@ColumnsChanged}{true}}} \newcommand{\jbwpd@AssignColumns}[1] {% #1 is list of PRECEDENCE %\showthe\jbwpd@HighestColumn \setboolean{jbwpd@ColumnsChanged}{false}% \dolist{#1} {} {% ##1 is {LABEL1}{LABEL2}... \usetemplate{##1} {% ####1 is LABEL1 % ####2 is LABEL2 % ####3 is either empty or EDGE_TYPE \jbwpd@AssignSecondLabelHigherColumn{####1}{####2}}} {}% \ifthenelse{\boolean{jbwpd@ColumnsChanged}} {\jbwpd@AssignColumns{#1}} {\jbwpd@StartDiagram{#1}}} \newcommand{\jbwpd@StartDiagram}[3] {% #1 is list of PRECEDENCE % #2 is list of NODE % #3 is DIAGRAM_LABEL %\TraceOn \ifthenelse{\boolean{jbwpd@Horiz}} {\hbox\bgroup\valign\bgroup\vfil##\vfil} {% For this case, we should probably also cancel the lineskip. % However, then we would have to reenable it inside the boxes. % And the boxes will usually be big enough that lineskip will % have no effect. So we are lazy instead. \vbox\bgroup\halign\bgroup\hfil##\hfil}% % We are now inside the \bgroup, so stay indented. \cr \jbwpd@MakeColumns{0}{#2}{#3}{#1}} \newcommand{\jbwpd@MakeColumns}[3] {% #1 is COL_NUMBER % #2 is list of NODE % #3 is DIAGRAM_LABEL \dolist{#2} {{true}} {% ##1 is {TYPE}{LABEL}{TEXT} % ##2 is IS_FIRST_ITEM \usetemplate{##1} {% ####1 is TYPE % ####2 is LABEL % ####3 is TEXT \edef\jbwpd@temp {\jbwpd@ColumnB=\@nameuse{jbwpd@node@column@####2}}% \jbwpd@temp \relax \IfNum{#1=\jbwpd@ColumnB} {\ifthenelse{\equal{##2}{true}} {} {\ifthenelse{\boolean{jbwpd@Horiz}}{\vskip}{\hskip}\PrecedenceDiagramSimulSep\relax}% \jbwpd@MakeNode{#3}{####1}{####2}{####3}% \DLNext{{false}}} {\DLNext{{##2}}}}} {}% \IfNum{#1<\jbwpd@HighestColumn} {\cr \noalign{\ifthenelse{\boolean{jbwpd@Horiz}}{\hskip}{\vskip}\PrecedenceDiagramTimeSep\relax}% \jbwpd@ColumnA=#1% \advance\jbwpd@ColumnA by 1\relax %\showthe\jbwpd@ColumnA \Expand{\the\jbwpd@ColumnA} {% ##1 is (COL_NUMBER + 1) \jbwpd@MakeColumns{##1}{#2}{#3}}} {\jbwpd@FinishDiagram{#3}}} \newcommand{\jbwpd@AddHorizLinkPoints}[2] {% #1 is LABEL % #2 is CONTENT (horizontal material) \hbox {\rnode{jbwpdXstartX#1}{}% $\vcenter{\hbox{#2}}$% \rnode{jbwpdXendX#1}{}}} \newdimen\jbwpd@savedlineskip \newdimen\jbwpd@savedbaselineskip \newcommand{\jbwpd@AddVertLinkPoints}[2] {% #1 is LABEL % #2 is CONTENT (horizontal material) $\vcenter {\jbwpd@savedlineskip=\lineskip \jbwpd@savedbaselineskip=\baselineskip \lineskip=0pt\relax \baselineskip=0pt\relax \halign{\hfil##\hfil\cr \rnode{jbwpdXstartX#1}{}% \cr\lineskip=\jbwpd@savedlineskip \baselineskip=\jbwpd@savedbaselineskip #2% \cr\rnode{jbwpdXendX#1}{}% \cr}}% $} \newcommand{\jbwpd@MakeNode}[4] {% #1 is DIAGRAM_LABEL % #2 is TYPE % #3 is LABEL % #4 is TEXT %\TraceOn \ifthenelse{\boolean{jbwpd@Horiz}} {\jbwpd@AddHorizLinkPoints} {\jbwpd@AddVertLinkPoints} % Next two are arguments to command chosen by above ifthenelse {#1X#3} {\jbwpd@WrapNode{#2}{#3}% %{\begin{tabular}{@{}c@{}}#4\end{tabular}}% {\parboxwithmaxwidth{\PrecedenceDiagramNodeMaxWidth}{\centering#4}}% }% } \newcommand{\DeclarePrecedenceDiagramNodeType}[2] {% #1 is NAME % #2 is DEFINITION \@namedef{jbwpd@ItemWrapper@#1}{#2}} \DeclarePrecedenceDiagramNodeType{activity}{\fbox} \DeclarePrecedenceDiagramNodeType{event}{\pscirclebox} \DeclarePrecedenceDiagramNodeType{}{\hbox} \DeclarePrecedenceDiagramNodeType{plain}{\hbox} \DeclarePrecedenceDiagramNodeType{frame}{\fbox} \DeclarePrecedenceDiagramNodeType{doubleframe}{\psdblframebox} \DeclarePrecedenceDiagramNodeType{shadowframe}{\psshadowbox} \DeclarePrecedenceDiagramNodeType{circle}{\pscirclebox} \DeclarePrecedenceDiagramNodeType{oval}{\psovalbox} \DeclarePrecedenceDiagramNodeType{diamond}{\psdiabox} \DeclarePrecedenceDiagramNodeType{Rtriangle}{\pstribox[trimode=R]} \DeclarePrecedenceDiagramNodeType{Utriangle}{\pstribox[trimode=U]} \DeclarePrecedenceDiagramNodeType{Ltriangle}{\pstribox[trimode=L]} \DeclarePrecedenceDiagramNodeType{Dtriangle}{\pstribox[trimode=D]} % *** Should abstract commonality of \jbwpd@WrapNode and \jbwpd@DrawEdge. \newcommand{\jbwpd@WrapNode}[3] {% #1 is TYPE % #2 is LABEL % #3 is CONTENTS (should emit a single box when executed) %\fbox{% \rnode{#2}% {% \IfBeginsWithStar{#1} {% ##1 is TYPE with leading * removed ##1} {\@ifundefined{jbwpd@ItemWrapper@#1} {\PackageError{jbw-precedence-diagram} {Undefined precedence diagram node type: #1} {No additional help.}} {\@nameuse{jbwpd@ItemWrapper@#1}}} % next line is argument of both branches of above \IfBeginsWithStar {#3}% }% %}% } \newcommand{\DeclarePrecedenceDiagramEdgeType}[2] {% #1 is NAME % #2 is DEFINITION \@namedef{jbwpd@EdgeDrawer@#1}{#2}} \DeclarePrecedenceDiagramEdgeType{}{\ncline[nodesep=3pt,arrows=->]} \DeclarePrecedenceDiagramEdgeType{arrow}{\ncline[nodesep=3pt,arrows=->]} \DeclarePrecedenceDiagramEdgeType{line}{\ncline[nodesep=3pt,arrows=-]} \DeclarePrecedenceDiagramEdgeType{silent}{\@gobbletwo} \newcommand{\jbwpd@DrawEdge}[1] {% #1 is EDGE_TYPE \IfBeginsWithStar{#1} {% ##1 is RAW_CODE ##1} {\@ifundefined{jbwpd@EdgeDrawer@#1} {\PackageError{jbw-precedence-diagram} {Undefined edge type: #1} {No additional help.}} {\@nameuse{jbwpd@EdgeDrawer@#1}}}} \newcommand{\jbwpd@FinishDiagram}[2] {% #1 is DIAGRAM_LABEL % #2 is list of PRECEDENCE \cr \egroup\egroup % ends \?box\bgroup\?align\bgroup ... \dolist{#2} {} {% ##1 is {LABEL1}{LABEL2}{EDGE_TYPE} \usetemplate{##1} {% ####1 is LABEL1 % ####2 is LABEL2 % ####3 is EDGE_TYPE %\TraceExec \jbwpd@DrawEdge{####3}{jbwpdXendX#1X####1}{jbwpdXstartX#1X####2}}} {}% \egroup % ends \hbox\bgroup } % Local variables: % tex-main-file: "jbw-precedence-diagram-test.tex" % end: