% $Id: asciiArt.tex,v 1.1.1.5 2004/10/16 15:20:47 nthiery Exp $
\begin{Mhelppage}{asciiArt}{N.~Thiéry}
  [ImplState=stable,TestState=stable,DocState=stable]
\Mproofread{nthiery}{28/09/2004}{reasonably complete, but not proofread}

\MDeclareOption{\Center}{Center}
\MDeclareOption{\Bottom}{Bottom}
\MDeclareOption{\Top}{Top}
  
\begin{MInfo}
  \eng{A domain for 2D ascii art graphics}
\end{MInfo}

\begin{MIntro}
  \eng{This domain allows for creating 2D ascii art graphics, which
    can be displayed by the text pretty-printer of MuPAD.}
\end{MIntro}

\begin{MDetails}
  \eng{A graphic \Mex{g} consists of a rectangle of characters, where
    the bottom left corner has coordinates \Mex{[1,1]}, and the upper
    right corner has coordinates
    \Mex{[g::dom::width(g),g::dom::height(g)]}.}
  
  \eng{With MuPAD up to version 2.5.3, an element of this domain is
    aligned vertically on its topmost row.}
  
  \eng{Starting from MuPAD 3.0.0, an element of this domain is
    centered vertically by default. Furthermore, you can choose the
    alignment style between \Bottom, \Center, \Top, or set the
    baseline explicitly, as a number in the range
    \Mex{[1..g::dom::height(g)]}. Setting a baseline of $1$ has the
    same effect as choosing the style \Bottom.}
  
  \eng{Internally, the first operand of an element of this domain is a
    list of strings of same lengths. The character of coordinate
    \Mex{[x,y]} is stored in the \Mex{x}-th character of the
    \Mex{y}-th string. The second operand describes the alignment
    style.}
\end{MDetails}

\begin{MDomElConst}
  \MCall{list}
\end{MDomElConst}

\begin{MParameters}
  \param{list}%
  \eng{A list of strings.}
\end{MParameters}

\begin{MDetails}
  \eng{Construct a graphic by stacking vertically the strings in
    \Mpar{list}, ragged left, from bottom to top (and not from top to
    bottom, in order to be consistent with the orientation of the y
    axis).}
\end{MDetails}

\begin{MMethodDetails}{fromArray}
  \infoEng{boxed (or partially boxed) cell graphic from 2D array}
  \call{\Mtype{2D array} a, \Mtype{2D array} separator (optionnal)}%
  \eng{Constructs a graphic made of vertically and horizontally
    aligned boxed (or partially boxed with the separator option) cells filled with the initialized values of the
    array. The optionnal array is constructed as follow: if you don't want a separation between two consecutive cells, then put the same number in the correponding case. And if you want a separation, then put two different values into the corresponding cases. Currently, the values themselves are represented in 1D and
    not pretty printed.}
\end{MMethodDetails}

\begin{MMethodDetails}{width}
  \infoEng{width of a graphic}
  \call{\Mtype{graphic} g}%
  \eng{Returns the width of \Mpar{g} in characters.}
\end{MMethodDetails}

\begin{MMethodDetails}{height}
  \infoEng{height of a graphic}
  \call{\Mtype{graphic} g}%
  \eng{Returns the height of \Mpar{g} in characters.}
\end{MMethodDetails}

\begin{MMethodDetails}{alignment}
  \infoEng{vertical alignment}
  \call{\Mtype{graphic} g}%
  \eng{Returns the vertical alignment style or base line of
    \Mpar{g}.}
\end{MMethodDetails}

\begin{MMethodDetails}{setAlignment}
  \infoEng{sets the vertical alignment}
  \call{\Mtype{graphic} g, \Mtype{style} align}%
  \eng{Returns a copy of \Mpar{g}, with the vertical alignment style
    set to align.}
  \call{\Mtype{graphic} g, \Mtype{integer} baseline}%
  \eng{Returns a copy of \Mpar{g} with the baseline set to
    \Mpar{baseline}. If needed, the result is extended vertically so
    that its height is no less than its baseline. }
  
  \eng{This method has no effect with MuPAD up to version 2.5.3.}
\end{MMethodDetails}

\begin{MMethodDetails}{flipx}
  \infoEng{horizontal flip}
  \call{\Mtype{graphic} g}%
  \eng{Returns a copy of \Mpar{g} flipped horizontally.}
\end{MMethodDetails}

\begin{MMethodDetails}{flipy}
  \infoEng{vertical flip}
  \call{\Mtype{graphic} g}%
  \eng{Returns a copy of \Mpar{g} flipped vertically.}
\end{MMethodDetails}

\begin{MExample}{ex-basic}
  We demonstrate some basic usage of this domain. Here is a little
  graphic:
  \begin{Mexin}
tom := output::asciiArt([" \\_/ ", "| _ |", "|o o|", "//|\\\\", " ___"])
  \end{Mexin}
  \begin{Mexout}
                              ___
                             //|\\
                             |o o|
                             | _ |
                              \_/
  \end{Mexout}
  The output is not yet quite perfect, but such a graphic can be
  included in a complex formula:
  \begin{Mexin}
(2*tom + 1)/(x + tom^2)
  \end{Mexin}
  \begin{Mexout}
                             ___
                            //|\\
                          2 |o o| + 1
                            | _ |
                             \_/
                          -----------
                                ___ 2
                               //|\\
                           x + |o o|
                               | _ |
                                \_/
  \end{Mexout}
  We fetch some information on this graphic. This is its size:
  \begin{Mexin}
[tom::dom::height(tom), tom::dom::width(tom)]
  \end{Mexin}
  \begin{Mexout}
                            [5, 5]
  \end{Mexout}
  Here are some of its characters:
  \begin{Mexin}
tom[1, 1], tom[3, 1], tom[1, 3], tom[2, 3]
  \end{Mexin}
  \begin{Mexout}
                      " ", "_", "|", "o"
  \end{Mexout}
  Fetching a character out of bounds raises an error.
  \begin{Mexin}
tom[6, 6]
  \end{Mexin}
  \begin{Mexout}
Error: Out of range [output::asciiArt::_index]
  \end{Mexout}
  \eng{The graphic can more or less be fliped around:}
  \begin{Mexin}
tom::dom::flipx(tom)
  \end{Mexin}
  \begin{Mexout}
                              ___
                             \\|//
                             |o o|
                             | _ |
                              /_\
  \end{Mexout}

  \begin{Mexin}
tom::dom::flipy(tom)
  \end{Mexin}
  \begin{Mexout}
                              \_/
                             | _ |
                             |o o|
                             //|\\
                              ___
  \end{Mexout}

  \begin{Mexin}
tom::dom::transpose(tom)
  \end{Mexin}
  \begin{Mexout}
                              /_\
                             | _ |
                             |o o|
                             \\|//
                              ___
  \end{Mexout}
  \eng{It is time to do some drawing now:}
  \begin{Mexin}
tom[2, 3] := "v":
tom
  \end{Mexin}
  \begin{Mexout}
                              ___
                             //|\\
                             |v o|
                             | _ |
                              \_/
  \end{Mexout}
  \begin{Mexin}
tom[3, 5] := tom[4, 6] := "/":
tom[4, 7] := "ooo": tom[5, 8] := tom[5, 6] := "o":
tom;
  \end{Mexin}
  \begin{Mexout}
                                o
                               ooo
                               /o
                             _/_
                            //|\\
                            |v o|
                            | _ |
                             \_/
  \end{Mexout}
  \eng{All of this does not look very serious, does it? Well, do not be
    misleaded. This hack is very handy for quick and simple preview of
    combinatorial structures. And, as usual with combinatorics, fun and
    seriousness are never very far away.}
  \begin{Mexin}
combinat::dyckWords::printPretty([1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0])
  \end{Mexin}
  \begin{Mexout}
                                   /\
                      /\          /  \/\
                     /  \/\/\  /\/      \
                    /        \/          \
  \end{Mexout}
  \begin{Mexin}
combinat::binaryTrees(([a, [b,[c], [d]], [e, [],[f]]]));
  \end{Mexin}
  \begin{Mexout}
                               a
                              / \
                              b e
                             / \ \
                             c d f
  \end{Mexout}
  \begin{Mexin}
combinat::partitions::printPretty([5, 3, 1])
  \end{Mexin}
  \begin{Mexout}
                     +---+
                     |   |
                     +---+---+---+
                     |   |   |   |
                     +---+---+---+---+---+
                     |   |   |   |   |   |
                     +---+---+---+---+---+
  \end{Mexout}
  \begin{Mexin}
combinat::tableaux([[3], [1, 2, 4]])
  \end{Mexin}
  \begin{Mexout}
                         +---+
                         | 3 |
                         +---+---+---+
                         | 1 | 2 | 4 |
                         +---+---+---+
  \end{Mexout}
\begin{Mexin}
combinat::ribbonsTableaux(
    [[1],
     [0],
     [0, 1, 4, 0, 0],
     [-1, 0, 3, 0, 0, 3],
     [-1, 0, 2, 0, 0, 0, 0],
     [-1, -1, 1, 0, 0, 2, 0, 0]])
\end{Mexin}
\begin{Mexout}
               +---+
               | 1 |
               +   +
               | 1 |
               +   +---+---+---+---+
               | 1 | 1 | 4   4   4 |
               +---+   +---+---+---+---+
               |   | 1 | 3   3   3 | 3 |
               +   +   +---+---+---+   +---+
               |   | 1 | 2   2   2 | 3   3 |
               +   +---+---+---+---+---+---+---+
               |       | 1   1   1 | 2   2   2 |
               +---+---+---+---+---+---+---+---+
\end{Mexout}

\end{MExample}

\begin{MExample}{ex-fromArray}
  \eng{The constructor \Mup{output::asciiArt::fromArray} is handy to
    create graphics with boxed cells. Here is how to draw a ribbon:}
  \begin{Mexin}
t := array(1..3, 1..6,
          (1, 1) = 1, (1, 2) = 3, (1, 3) = 5,
                                  (2, 3) = 4, (2, 4) = 6,
                                              (3, 4) = 2):
output::asciiArt::fromArray(t)
  \end{Mexin}
  \begin{Mexout}
                       +---+---+---+
                       | 1 | 3 | 5 |
                       +---+---+---+---+
                               | 4 | 6 |
                               +---+---+
                                   | 2 |
                                   +---+
  \end{Mexout}

  \eng{We now illustrate some options that allow to customize the
    produced asciiArt:}
  \begin{Mexin}
output::asciiArt::fromArray(t,
                            RowSeparator = "", Cross = "",
                            ColumnSeparator = "*", HorizontalPadding = "")
  \end{Mexin}
  \begin{Mexout}
                           *1*3*5*
                               *4*6*
                                 *2*
  \end{Mexout}
  \begin{Mexin}
output::asciiArt::fromArray(t, RowSeparator = "", Cross = "", HorizontalPadding = "")
  \end{Mexin}
  \begin{Mexout}
                           |1|3|5|
                               |4|6|
                                 |2|
  \end{Mexout}
  \begin{Mexin}
output::asciiArt::fromArray(t, RowSeparator = "", Cross = "")
  \end{Mexin}
  \begin{Mexout}
                       | 1 | 3 | 5 |
                               | 4 | 6 |
                                   | 2 |
  \end{Mexout}
  \begin{Mexin}
output::asciiArt::fromArray(t, Compact)
  \end{Mexin}
  \begin{Mexout}
                           |1|3|5|
                               |4|6|
                                 |2|
  \end{Mexout}
  % Check that there are no extra empty lines in the asciiArt
  \begin{Mvin}{hide=true}
[output::asciiArt::fromArray(t, Compact)]
  \end{Mvin}
  \begin{Mvout}{hide=true}
                        -- |1|3|5|   --
                        |      |4|6|  |
                        --       |2| --
  \end{Mvout}

  \begin{Mexin}
output::asciiArt::fromArray(t, Packed)
  \end{Mexin}
  \begin{Mexout}
                             135
                               46
                                2
  \end{Mexout}

  \eng{We now illustrate the separator options with the following
    array of values:}
  \begin{Mexin}
A := array(1..4, 1..4,
  (1, 1) = a, (1, 2) = b, (1, 3) = c, (1, 4) = d,
  (2, 1) = b, (2, 2) = c, (2, 3) = d, (2, 4) = a,
  (3, 1) = c, (3, 2) = d, (3, 3) = a, (3, 4) = b,
  (4, 1) = d, (4, 2) = a, (4, 3) = b, (4, 4) = c):
  \end{Mexin}
  \begin{Mexout}
  \end{Mexout}
  \eng{Separations conditions are given by the following array:}
  \begin{Mexin}
separator := array(1..4, 1..4,
  (1, 1) = 1, (1, 2) = 1, (1, 3) = 1, (1, 4) = 1,
  (2, 1) = 1, (2, 2) = 2, (2, 3) = 2, (2, 4) = 1,
  (3, 1) = 1, (3, 2) = 2, (3, 3) = 2, (3, 4) = 1,
  (4, 1) = 1, (4, 2) = 1, (4, 3) = 1, (4, 4) = 1):
  \end{Mexin}
  \begin{Mexout}
  \end{Mexout}
  \begin{Mexin}
output::asciiArt::fromArray(A, separator)
  \end{Mexin}
  \begin{Mexout}
                       +---+---+---+---+
                       | a   b   c   d |
                       +   +---+---+   +
                       | b | c   d | a |
                       +   +   +   +   +
                       | c | d   a | b |
                       +   +---+---+   +
                       | d   a   b   c |
                       +---+---+---+---+
  \end{Mexout}
\end{MExample}

\begin{MChanges}
  \version{3.0}
    \new
\end{MChanges}

\end{Mhelppage}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: main
%%% End: 
