Defining and Programming Graphical Directives

• To: mathgroup at smc.vnet.net
• Subject: [mg39232] Defining and Programming Graphical Directives
• From: "David Park" <djmp at earthlink.net>
• Date: Tue, 4 Feb 2003 02:23:50 -0500 (EST)
• Sender: owner-wri-mathgroup at wolfram.com

```Dear MathGroup,

I am working on an application where I define a number of graphical objects,
which can then be used like graphical primitives. I also want to define
graphical primitives that will control the color, position and size of some
of these objects. The use of color is slightly complicated because the color
that is set may be used for lines, or in SurfaceColor or in EdgeForm and it
may be lightened or darkened.

My basic approach is to store the value of the directives in internal
variables and then the graphical primitives use these values.

But it is difficult to make it all behave just like regular Mathematica
graphical directives.

1) The list of primitives must be HoldFirst. Premature evaluation will cause
the last instance of a programmed directive to be used for all cases.
2) The default values of any primitives must be set before the primitives
are evaluated else whatever is left over from the last plot will be used.

I can pretty much handle those problems. The last problem is more difficult
and is the core of my question.

3) Regular graphics directives are nested in the sense that if one is set
inside brackets, {directive,... }, then, after exiting the brackets, the
directive reverts to the value existing before the brackets were entered.

Is it possible to program that behavior?

Here is an example. It could be done with regular Mathematica directives,
but it was picked to be a simple example. In my actual cases I have to use
programming. The extra graphical primitive is a ColoredLine. The color to be
used for subsequent ColoredLines is set with the programmed directive
LineColor. The value is stored in currentcolor.

Needs["Graphics`Colors`"]

currentcolor = Black;
ColoredLine[start_, end_] := {currentcolor, Line[{start, end}]}
LineColor[color_] := (currentcolor = color; Sequence[])

Attributes[PlottingLines] = {HoldFirst};
PlottingLines[primitives_List, opts___?OptionQ] :=
Show[Graphics[
{LineColor[Black], Sequence @@ primitives}], opts]

In the following use everything works.

PlottingLines[
{ColoredLine[{0, 0}, {1, 0}],
LineColor[Red],
ColoredLine[{0, 1}, {1, 1}],
LineColor[Blue],
Coloredline[{0, 2}, {1, 2}]},
Background -> Linen,
ImageSize -> 400];

But if I use nesting it, of course, doesn't work like regular Mathematica
directives. The color does not revert to Black.

PlottingLines[
{ColoredLine[{0, 0}, {1, 0}],
{LineColor[Red],
ColoredLine[{0, 1}, {1, 1}]},
Coloredline[{0, 2}, {1, 2}]},
Background -> Linen,
ImageSize -> 400];

It appears that I need to somehow implement a recursive evaluation of the
primitives list. Any ideas on how I could do that.

David Park