%D \module
%D   [       file=m-steps,
%D        version=2011.10.07, % 2001.05.28,
%D          title=\CONTEXT\ Modules,
%D       subtitle=Step Charts \& Tables,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

% This code is not optimized.

\registerctxluafile{m-steps}{}

\unprotect

\defineMPinstance
  [steps]
  [\s!format=metafun,
   \s!extensions=\v!yes,
   \s!initializations=\v!yes]
  %\c!method=\s!double]

\startMPdefinitions{steps}
    loadmodule "step" ;
\stopMPdefinitions

\installcorenamespace {stepcharts}
\installcorenamespace {stepcells}
\installcorenamespace {steptexts}
\installcorenamespace {steplines}

\installstylisticautosetuphandler \??stepcharts {STEPchart}
\installstylisticautosetuphandler \??stepcells  {STEPcell}
\installstylisticautosetuphandler \??steptexts  {STEPtext}
\installstylisticautosetuphandler \??steplines  {STEPline}

\let\setupSTEPcharts\setupSTEPchart
\let\setupSTEPtables\setupSTEPchart % one can define categories so no need
\let\setupSTEPcells \setupSTEPcell
\let\setupSTEPtexts \setupSTEPtext
\let\setupSTEPlines \setupSTEPline

\let\setSTEPchartsparameter\setSTEPchartparameter
\let\setSTEPcellsparameter \setSTEPcellparameter
\let\setSTEPtextsparameter \setSTEPtextparameter
\let\setSTEPlinesparameter \setSTEPlineparameter

% numeric text_text_distance ; text_text_distance   := 20pt ;
% numeric step_distance      ; step_distance        := 20pt ;

\setupSTEPcharts
  [%c!alternative=\v!horizontal, % travels with stored so dealt with in lua
  %\c!offset=.15\bodyfontsize
  %\c!height=2ex
   \c!before=\blank,
   \c!after=\blank]

\setupSTEPcells
  [\c!alternative=24,
   \c!style=,
   \c!color=,
   \c!dx=\bodyfontsize,
   \c!dy=\bodyfontsize,
 % \c!background=\v!color,
   \c!backgroundcolor=STEPbackgroundcolor,
   \c!rulethickness=.1\bodyfontsize,
   \c!framecolor=STEPframecolor,
   \c!offset=.25\bodyfontsize]

\setupSTEPtexts
  [\c!alternative=24,
   \c!style=\v!smallbodyfont,
   \c!color=,
 % \c!background=\v!color,
   \c!backgroundcolor=STEPbackgroundcolor,
   \c!rulethickness=.1\bodyfontsize,
   \c!framecolor=STEPframecolor,
   \c!distance=.5\bodyfontsize,
   \c!offset=.25\bodyfontsize]

\setupSTEPlines
  [\c!alternative=1,
   \c!rulethickness=.15\bodyfontsize,
   \c!height=\STEPlineparameter\c!width,
   \c!width=3\bodyfontsize,
   \c!distance=.5\bodyfontsize,
   \c!offset=.25\bodyfontsize,
   \c!color=STEPlinecolor]

\definecolor [STEPlinecolor]       [s=.5]
\definecolor [STEPframecolor]      [s=.7]
\definecolor [STEPbackgroundcolor] [s=.9]

\newcount\c_module_steps_tag
\newmacro\m_module_steps_category

\unexpanded\def\setSTEPbox#tag#str%
  {\setbox\scratchbox\hbox\bgroup
     \begstrut
     \ignorespaces
     #str%
     \removeunwantedspaces
     \endstrut
   \egroup
   \ifzeropt\wd\scratchbox
     \let#1\empty
   \else
     \global\advance\c_module_steps_tag\plusone
     \edef#tag{\the\c_module_steps_tag}%
     \putboxincache{\??stepcharts\m_module_steps_category}{#tag}\scratchbox
   \fi}

\newtoks\everySTEPchart

% we used to save charts but that is tricky with so much delegated to lua
% and mp so now we do support a buffered way only

\def\module_steps_syncronize
  {\let\currentSTEPtext\p_category
   \let\currentSTEPcell\p_category
   \let\currentSTEPline\p_category
   \checkSTEPcellparent
   \checkSTEPtextparent
   \checkSTEPlineparent}

\unexpanded\def\startSTEPchart
  {\begingroup
   \dodoubleempty\module_steps_start_chart}

\def\module_steps_start_chart[#name][#settings]%
  {\iffirstargument
     \doifelseassignment{#name}
       {\let\currentSTEPchart\empty
        \let\m_module_steps_category\empty
        \setupcurrentSTEPchart[#name]%
        \def\module_steps_flush_chart{\module_steps_chart[][#name]}}
       {\edef\currentSTEPchart{#name}%
        \setupcurrentSTEPchart[#settings]%
        \let\m_module_steps_category\currentSTEPchart
        \resetboxesincache{\??stepcharts\m_module_steps_category}%
        \doifelse{\STEPchartparameter\c!buffer}\v!no
          {\def\module_steps_flush_chart{\STEPchart[#name]}}
          {\let\module_steps_flush_chart\relax}}%
   \else
     \let\currentSTEPchart\empty
     \def\module_steps_flush_chart{\module_steps_chart[][]}%
   \fi
   \edef\p_category{\STEPchartparameter\c!category}%
   \let\currentSTEPtext\p_category
   \let\currentSTEPcell\p_category
   \let\currentSTEPline\p_category
   \checkSTEPcellparent
   \checkSTEPtextparent
   \checkSTEPlineparent
   \the\everySTEPchart
   \startnointerference
   \clf_step_start_chart{\currentSTEPchart}{\STEPchartparameter\c!alternative}}

\unexpanded\def\stopSTEPchart
  {\clf_step_stop_chart
   \stopnointerference
   \module_steps_flush_chart
   \ifx\m_module_steps_category\empty
      \resetboxesincache{\??stepcharts}%
   \fi
   \endgroup}

\unexpanded\def\startSTEPtable
  {\begingroup
   \setupSTEPchart[\c!alternative=\v!vertical]%
   \dodoubleempty\module_steps_start_chart}

\let\stopSTEPtable\stopSTEPchart

\unexpanded\def\startSTEPaligntable
  {\begingroup
   \setupSTEPchart[\c!alternative={\v!vertical,\v!three}]%
   \let\module_steps_cells\module_steps_cells_three % no nesting yet
   \dodoubleempty\module_steps_start_chart}

\let\stopSTEPaligntable\stopSTEPchart

\let\module_steps_flush_chart\relax

% \resetboxesincache\??stepcharts

\unexpanded\def\STEPchart
  {\dodoubleempty\module_steps_chart}

\unexpanded\def\module_steps_chart[#name][#settings]%
  {\begingroup
   \edef\m_module_steps_category{#name}%
   \setupSTEPchart[#settings]%
   \ifinsidefloat
     \makeSTEPchart[#name]%
   \else
     \STEPchartparameter\c!before
     \startbaselinecorrection
       \setlocalhsize
       \dontleavehmode\vpack{\makeSTEPchart[#name]}% we need to ensure leftskip
     \stopbaselinecorrection
     \STEPchartparameter\c!after
   \fi
   \endgroup}

\unexpanded\def\makeSTEPchart[#name]%
  {\clf_step_make_chart
        chart {
            category        {\??stepcharts\m_module_steps_category}
            name            {#name}
            alternative     {\STEPchartparameter\c!alternative}
        }
        cell {
            alternative     {\STEPcellparameter\c!alternative}
            offset          \dimexpr\STEPcellparameter\c!offset\relax
            rulethickness   \dimexpr\STEPcellparameter\c!rulethickness\relax
            framecolor      {\STEPcellparameter\c!framecolor}
            backgroundcolor {\STEPcellparameter\c!backgroundcolor}
            dx              \dimexpr\STEPcellparameter\c!dx\relax
            dy              \dimexpr\STEPcellparameter\c!dy\relax
        }
        text {
            alternative     {\STEPtextparameter\c!alternative}
            offset          \dimexpr\STEPtextparameter\c!offset\relax
            distance        \dimexpr\STEPtextparameter\c!distance\relax
            rulethickness   \dimexpr\STEPtextparameter\c!rulethickness\relax
            framecolor      {\STEPtextparameter\c!framecolor}
            backgroundcolor {\STEPtextparameter\c!backgroundcolor}
        }
        line {
            alternative     {\STEPlineparameter\c!alternative}
            rulethickness   \dimexpr\STEPlineparameter\c!rulethickness\relax
            height          \dimexpr\STEPlineparameter\c!height\relax
            distance        \dimexpr\STEPlineparameter\c!distance\relax
            offset          \dimexpr\STEPlineparameter\c!offset\relax
            color           {\STEPlineparameter\c!color}
        }
  \relax}

\unexpanded\def\startSTEPcell{\clf_step_start_cell}
\unexpanded\def\stopSTEPcell {\clf_step_stop_cell}

\unexpanded\def\module_steps_cells      {\dosingleempty\module_steps_cells_indeed}
\unexpanded\def\module_steps_cells_three{\dosingleempty\module_steps_cells_three_indeed}
\unexpanded\def\module_steps_texts      {\dosingleempty\module_steps_texts_indeed}
\unexpanded\def\module_steps_cell       {\dosingleempty\module_steps_cell_indeed}
\unexpanded\def\module_steps_text       {\dosingleempty\module_steps_text_indeed}
\unexpanded\def\module_steps_toptext    {\dosingleempty\module_steps_toptext_indeed}
\unexpanded\def\module_steps_bottext    {\dosingleempty\module_steps_bottext_indeed}
\unexpanded\def\module_steps_topcell    {\dosingleempty\module_steps_topcell_indeed}
\unexpanded\def\module_steps_botcell    {\dosingleempty\module_steps_botcell_indeed}

\def\module_steps_check_cell#category%
  {\edef\p_category{#category}%
   \ifx\p_category\empty \else
     \let\currentSTEPcell\p_category
     \let\currentSTEPline\p_category
     \checkSTEPcellparent
     \checkSTEPlineparent
   \fi}

\def\module_steps_check_text#category%
  {\edef\p_category{#category}%
   \ifx\p_category\empty \else
     \let\currentSTEPtext\p_category
     \let\currentSTEPline\p_category
     \checkSTEPtextparent
     \checkSTEPlineparent
   \fi}

\def\module_steps_pass_data#1#2%
  {{
       text  {
         #2
       }
       shape {
         rulethickness   \dimexpr#1\c!rulethickness\relax
         alternative     {#1\c!alternative}
         framecolor      {#1\c!framecolor}
         backgroundcolor {#1\c!backgroundcolor}
       }
       line {
         rulethickness \dimexpr\STEPlineparameter\c!rulethickness\relax
         alternative   {\STEPlineparameter\c!alternative}
         color         {\STEPlineparameter\c!color}
         offset        \dimexpr\STEPlineparameter\c!offset\relax
       }
    }}

\def\module_steps_cells_indeed[#category]#top#bot%
  {\begingroup
   \iffirstargument
     \module_steps_check_cell{#category}%
   \fi
   \useSTEPcellstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#top}%
   \setSTEPbox\module_steps_tag_b{#bot}%
   \clf_step_cells \module_steps_pass_data \STEPcellparameter {
     top {\module_steps_tag_a}
     bot {\module_steps_tag_b}
   }
   \endgroup}

\def\module_steps_cells_three_indeed[#category]#one#two#three%
  {\begingroup
   \iffirstargument
     \module_steps_check_cell{#category}%
   \fi
   \useSTEPcellstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#one}%
   \setSTEPbox\module_steps_tag_b{#two}%
   \setSTEPbox\module_steps_tag_c{#three}%
   \clf_step_cells_three \module_steps_pass_data \STEPcellparameter {
     left   {\module_steps_tag_a}
     middle {\module_steps_tag_b}
     right  {\module_steps_tag_c}
   }%
   \endgroup}

\def\module_steps_texts_indeed[#category]#top#bot%
  {\begingroup
   \iffirstargument
     \module_steps_check_text{#category}%
   \fi
   \useSTEPtextstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#top}%
   \setSTEPbox\module_steps_tag_b{#bot}%
   \clf_step_texts \module_steps_pass_data \STEPtextparameter {
     top {\module_steps_tag_a}
     bot {\module_steps_tag_b}
   }%
   \endgroup}

\def\module_steps_cell_indeed[#category]#str%
  {\begingroup
   \iffirstargument
     \module_steps_check_cell{#category}%
   \fi
   \useSTEPcellstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#str}%
   \clf_step_cell \module_steps_pass_data \STEPcellparameter {
     top {\module_steps_tag_a}
   }%
   \endgroup}

\def\module_steps_text_indeed[#category]#str%
  {\begingroup
   \iffirstargument
     \module_steps_check_text{#category}%
   \fi
   \useSTEPtextstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#str}%
   \clf_step_text \module_steps_pass_data \STEPtextparameter {
     top {\module_steps_tag_a}
   }%
   \endgroup}

\def\module_steps_toptext_indeed[#category]#top%
  {\begingroup
   \iffirstargument
     \module_steps_check_text{#category}%
   \fi
   \useSTEPtextstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#top}%
   \clf_step_text_top \module_steps_pass_data \STEPtextparameter {
     top {\module_steps_tag_a}
   }%
   \endgroup}

\def\module_steps_bottext_indeed[#category]#bot%
  {\begingroup
   \iffirstargument
     \module_steps_check_text{#category}%
   \fi
   \useSTEPtextstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#bot}%
   \clf_step_text_bot \module_steps_pass_data \STEPtextparameter {
     bot {\module_steps_tag_a}
   }%
   \endgroup}

\def\module_steps_topcell_indeed[#category]#top%
  {\begingroup
   \iffirstargument
     \module_steps_check_cell{#category}%
   \fi
   \useSTEPcellstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#top}%
   \clf_step_cell_top \module_steps_pass_data \STEPcellparameter {
     top {\module_steps_tag_a}
   }%
   \endgroup}

\def\module_steps_botcell_indeed[#category]#bot%
  {\begingroup
   \iffirstargument
     \module_steps_check_cell{#category}%
   \fi
   \useSTEPcellstyleandcolor\c!style\c!color
   \setSTEPbox\module_steps_tag_a{#bot}%
   \clf_step_cell_bot \module_steps_pass_data \STEPcellparameter {
     bot {\module_steps_tag_a}
   }%
   \endgroup}

\appendtoks
    \let\cells  \module_steps_cells
    \let\texts  \module_steps_texts
    \let\cell   \module_steps_cell
    \let\text   \module_steps_text
    \let\toptext\module_steps_toptext
    \let\bottext\module_steps_bottext
    \let\topcell\module_steps_topcell
    \let\botcell\module_steps_botcell
\to \everySTEPchart

% The xml interface:

\unexpanded\def\setSTEPxmldirective#1#2#3%
  {\begincsname setSTEP#1parameter\endcsname{#2}{#3}}

\xmlinstalldirective{stepchart}{setSTEPxmldirective}

\startxmlsetups xml:step:define
    \xmlsetsetup
        {#1}
        {stepchart|steptable|stepaligntable|cells|texts|stepcell|cell|text|br}
        {xml:step:*}
\stopxmlsetups

\xmlregistersetup{xml:step:define}

\startxmlsetups xml:step:br
    \crlf
\stopxmlsetups

\startxmlsetups xml:step:stepchart
    \startSTEPchart[\c!category=\xmlatt{#1}{class}]
        \xmlflush{#1}
    \stopSTEPchart
\stopxmlsetups

\startxmlsetups xml:step:steptable
    \startSTEPtable[\c!category=\xmlatt{#1}{class}]
        \xmlflush{#1}
    \stopSTEPtable
\stopxmlsetups

\startxmlsetups xml:step:stepaligntable
    \startSTEPaligntable[\c!category=\xmlatt{#1}{class}]
        \xmlflush{#1}
    \stopSTEPaligntable
\stopxmlsetups

\startxmlsetups xml:step:cells
    \xmldoifelse {#1} {/c1} {
        \cells
          [\xmlatt{#1}{class}]
          {\xmltext{#1}{/c1}}
          {\xmltext{#1}{/c2}}
          {\xmltext{#1}{/c3}}
    } {
        \cells
          [\xmlatt{#1}{class}]
          {\xmltext{#1}{/top}}
          {\xmltext{#1}{/bot}}
    }
\stopxmlsetups

\startxmlsetups xml:step:texts
    \texts
      [\xmlatt{#1}{class}]
      {\xmltext{#1}{/top}}
      {\xmltext{#1}{/bot}}
\stopxmlsetups

\startxmlsetups xml:step:stepcell
    \cells
      [\xmlatt{#1}{class}]
      {\xmltext{#1}{/topcell}}
      {\xmltext{#1}{/botcell}}
    \texts
      [\xmlatt{#1}{class}]
      {\xmltext{#1}{/toptext}}
      {\xmltext{#1}{/bottext}}
\stopxmlsetups

\startxmlsetups xml:step:cell
    \cell
      [\xmlatt{#1}{class}]
      {\xmlflush{#1}}
\stopxmlsetups

\startxmlsetups xml:step:text
    \doifelse {\xmlatt{#1}{option}} {paragraph} {
        \text
          [\xmlatt{#1}{class}]
          {\framed
             [\c!location=\v!middle,\c!align={\v!lohi,\v!flushleft},\c!offset=0pt,\c!frame=\v!no]
             {\ignorespaces\xmlflush{#1}\removeunwantedspaces}}
    } {
        \text
          [\xmlatt{#1}{class}]
          {\xmlflush{#1}}
    }
\stopxmlsetups

\protect

\continueifinputfile{m-steps.mkvi}

\starttext

\setupSTEPcells[demo-1][style=bold]

\startbuffer
<stepchart>
  <cell> some cell </cell>
  <text> some text </text>
  <cell class="demo-1"> some cell </cell>
  <text> some text </text>
  <cell> some cell </cell>
</stepchart>
\stopbuffer

\typebuffer \processxmlbuffer

\startbuffer
<steptable>
  <cell> some cell A</cell>
  <text> some text 1</text>
  <cell> some cell B</cell>
  <text> some text 2</text>
  <cell> some cell C</cell>
</steptable>
\stopbuffer

\typebuffer \processxmlbuffer

\startbuffer
<steptable>
  <cell> some cell A</cell>
  <text option="paragraph"> some more<br/>text 1</text>
  <cell> some cell B</cell>
</steptable>
\stopbuffer

\typebuffer \processxmlbuffer

\page

\startSTEPchart
    \cells {A}     {B}
    \cells {one}   {five}  \texts{$+2$}{$-2$}
    \cells {two}   {four}  \texts{$+3$}{$-3$}
    \cells {three} {three} \texts{$+4$}{$-4$}
    \cells {four}  {two}   \texts{$+5$}{$-5$}
    \cells {five}  {one}
\stopSTEPchart

\startbuffer
<stepchart>
  <cells> <top> some text </top> <bot> some text </bot> </cells>
  <texts> <top> text      </top> <bot> text      </bot> </texts>
  <cells> <top> some text </top> <bot> some text </bot> </cells>
</stepchart>
\stopbuffer

\processxmlbuffer

\startbuffer
<stepchart>
  <cell> some text </cell>
  <texts> <top> text </top> <bot> text </bot> </texts>
  <cell> some text </cell>
</stepchart>
\stopbuffer

\processxmlbuffer

\page

\startSTEPchart[second]
    \startSTEPcell
        \topcell {A}
        \botcell {B}
    \startSTEPcell
        \topcell {one}
        \botcell {five}
        \toptext {$+2$}
        \bottext {$-2$}
    \stopSTEPcell
    \startSTEPcell
        \topcell {two}
        \botcell {four}
        \toptext {$+3$}
        \bottext {$-3$}
    \stopSTEPcell
    \startSTEPcell
        \topcell {three}
        \botcell {three}
        \toptext {$+4$}
        \bottext {$-4$}
    \stopSTEPcell
    \startSTEPcell
        \topcell {four}
        \botcell {two}
        \toptext {$+5$}
        \bottext {$-5$}
    \stopSTEPcell
    \startSTEPcell
        \topcell {five}
        \botcell {one}
    \stopSTEPcell
\stopSTEPchart

\STEPchart[first][alternative=horizontal]
\STEPchart[first][alternative=vertical]

\page

\STEPchart[second][alternative=horizontal]
\STEPchart[second][alternative=vertical]

\page

\setupSTEPchart
  [mytable]
  [before={\blank[2*big]},
   after={\blank[2*big]}]

\starttext

\startSTEPaligntable[mytable]
    \cells {$2c$} {$=$} {$2a+3b$}
    \text  {with $a=5$}
    \cells {$2c$}{$=$} {$10+3b$}
    \text  {and $b=6$}
    \cells {$2c$} {$=$} {$10+18$}
    \text  {we get}
    \cells {$2c$} {$=$} {$28$}
    \text  {and therefore}
    \cells {$c$} {$=$} {$28/2$}
    \text  {which reduces to}
    \cells {$c$} {$=$} {$14$}
\stopSTEPaligntable

\input tufte

\STEPchart[mytable]

\input tufte

\setupSTEPchart
  [mytable]
  [buffer=no]

\startSTEPaligntable[mytable]
    \cells {$2c$} {$=$} {$2a+3b$}
    \text  {with $a=5$}
    \cells {$2c$}{$=$} {$10+3b$}
    \text  {and $b=6$}
    \cells {$2c$} {$=$} {$10+18$}
    \text  {we get}
    \cells {$2c$} {$=$} {$28$}
    \text  {and therefore}
    \cells {$c$} {$=$} {$28/2$}
    \text  {which reduces to}
    \cells {$c$} {$=$} {$14$}
\stopSTEPaligntable

\input tufte

\STEPchart[mytable]

\stoptext
