10. Customizing Tree Appearance: Stylesheets
Prev |  | Next

## 10. Customizing Tree Appearance: Stylesheets

### 10.1. Introduction to stylesheets

In TrEd, the way a tree is displayed is controlled by so called display stylesheets. Display stylesheets define what text will be rendered as node and edge labels and how, the way tree edges are to be drawn (much more can be achieved than just straight lines connecting a node and its parent node), the shape of the nodes, coloring of various visual elements, the text to be displayed as a tool-tip (hint) when mouse pointer hovers over a node, and also the content of text window displayed above the tree. All these properties of the visual representation of the tree are specified using so called styling patterns.

TrEd maintains a list of stylesheets from which stylesheets can selected and swithched between. The easiest way to select a stylesheet is to click on the stylesheet menu-button shown on the picture Figure 6, “Switching between stylesheets” below. This button can be found on the right side of the toolbar next to the button. Another way to select a stylesheet is using View → Select Stylesheet....

Figure 6. Switching between stylesheets

The stylesheet currently selected on the picture and named <From File> is always present. This is a rather virtual stylesheet whose content is always the styling patterns specified in the currently displayed file (some - but not all - file formats such as FS allow storing stylesheet information). These file-specific stylesheets are rather hard to maintain especially when one is working with hunderds of files. It is thus much more convenient to create a named stylesheet that can be used for any file at any time.

To create a new named stylesheet (based on the current pattern settings), select an item labeled <New From Current> from the stylesheet list and fill a name into the displayed dialog entry. The new stylesheet immediatelly appears as the selected item in the list.

### Warning

Although the API for stylesheets is case sensitive, for compatibility with Microsoft Windows, there must not be two stylesheets whose names differ only in case.

While a file-specific stylesheet is stored directly in the FS file, named stylesheets are all saved in similarly named files in `.tred.d/stylesheets/` in user's home directory. Stylesheet files are updated every time a named stylesheet is added removed or edited. Currently selected named stylesheet can be completely removed from the list by selecting <Delete Current> item from the pattern-set list.

Selected stylesheet can be edited in a stylesheet editor which appears when button is pressed or Setup → Edit Stylesheet... menu command issued.

Figure 7. Stylesheet editor

The dialog window contains two main elemens: a list of node attributes and an editor of stylesheet paterns. Double-clicking an attribute in the list inserts an attribute reference at the current cursor position in the pattern editor.

### 10.2. Stylesheet syntax: the styling patterns

A stylesheet consists of one or more styling patterns. A styling pattern begins with a pattern prefix which must occur at the very beginning of a line (no whitespace allowed) and is followed by a comma. After the comma follows a body of the pattern.

TrEd recognizes the following pattern prefixes (described in detail below): `node`, `edge`, `style`, `text` and `rootstyle`. If any other prefix is used, TrEd ignores the pattern.

`node:`

  defines a line of text to be displayed under each node of the tree. A stylesheet may contain one or more `node:` patterns, in which case the lines are displayed in the tree one under another in the order as they appear in the stylesheet.

`edge:`

  defines a line of text displayed across (or beside) the edge connecting each node with its parent. Of course, this label is not rendered for the root node. Likewise `node:` patterns, several `edge:` patterns may be specified. Note however that `edge:` patterns make the tree look quite wide and it is usually better to avoid them.

`style:`

  defines a pattern affecting the visual representation of various components of a tree. `style:` patterns do not result in any text visible on the screen but may contain special tree styling instructions described below. These instructions may dynamically alter the appearance (such as coloring, line thickness, etc) of the nodes, edges and text labels.

`text:`

  defines a portion of the text representing each node in the text window above the tree.

`rootstyle:`

  defines a pattern which behaves quite the same as a `style:` pattern but is only interpolated once (for the root node), applies to every node of the tree, but the styling instructions defined in this pattern have lower precedence than those of `style:` patterns. Beside the use for setting default style values for all nodes, there are some style instructions with global effect which can only be used in the `rootstyle:` pattern. See Table 2, “Rootstyle instructions”.

`hint:`

  defines the content of a tool-tip shown when mouse pointer lingers over a node. No styling instructions are allowed in the `hint:` patterns.

Pattern body consists of a text which is interpreted as follows:

`<?`code`?>`

  Perl-code expansion. This sequence may encapsulate any Perl code. The code is interpreted in the time of evaluation of the pattern (i.e. just before the line is actually to be displayed) and the result returned by the code replaces the code sequence in the pattern.

  Note that the returned value may contain other special sequences, but can't contain another `<?`...`?>` sequences.

  The `code` is subject to very similar rules as macros in TrEd (see Section 15, “User Macros”). One may refer to any attribute value of the node currently being styled as either `$${`attr`}` or `$this->attr('`attr`')`. The current node object itself can be refered to as `$this` (so e.g. `$this->parent` gives access to its parent). Regardless of what annotation mode is currently selected, the code occuring in the styling patterns is always evaluated within the `TredMacro` namespace. In order to call a user-defined macro from another namespace, it is therefore necessary to use a complete namespace (package name) prefix. So, a call to a macro named `bar` from a package (annotation mode) `Foo` should look like `Foo::bar(`arguments...`)`.

`${`attr`}`

  Attribute reference. Any occurence of this substring is replaced by current node's value of attribute named `attr`. Using attribute references only makes sense in the `node:`, `edge:`, `text:` and `hint:` patterns. In the labels rendered from `node:`, `edge:` patterns, this reference is actually linked with the corresponding node's attribute, so double-clicking on the displayed value in the tree shows a dialog where the attribute value can be edited.

`${`attr`=`value`}`

  This is a special form of an attribute reference, which is only useful in `node:`, `edge:` patterns. It always renders as `value`, but still retains the reference to the attribute `attr` of the corresponding node, so that double-clicking on the displayed `value` in the tree shows a dialog where the attribute `attr` can be edited.

`#{`color`}`

  This sequence of characters may be used to change the color of any possible following text generated by the pattern. The `color` may be either an english name of a color, such as `black`, `red` or `darkblue`, or one of user defined colors `custom`XXX`` (that can be defined in the configuration file using `CustomColor`XXX`` configuration option), or an RGB value specified as `#`RRGGBB``, where `RR`, `GG`, `BB` are hexadecimal numbers from 00 to FF representing respectively the red, green, and blue components of the color.

`#{`object`-`feature`:`value`}`

  These instructions may affect appearence of all elements of the tree. They should be used within `style` and `rootstyle` labeled patterns only, but may be created dynamically utilizing the `<? ... ?>` perl-code evaluation.

  See Table 3, “Style instructions” for list of `objects`, their `features` and possible `values`.

any other text

  Any other text occuring within a `node:`, `edge:`, `text:`, or `hint:` pattern is render as is (using the default font and the default or previously selected color and styling). Plain text occuring in a `style:` or `rootstyle:` pattern is ignored (note however that this may change in the future versions).

white space

  Leading and trailing white space of a pattern is ignored. To all other occurences of white-space the above rule for any other text applies.

Table 2. Rootstyle instructions

`name` | Description
--- | ---
`balance` | Has the same effect as the BalanceTree configuration option. Use either `#{balance}` or `#{balance:1}` for balanced trees horizontally compressed, `#{balance:spread}` for non-compressed balanced trees or `#{balance:0}` for ordered trees.
`baseXPos` | Has the same effect as the BaseXPos configuration option. Usage: `#{baseXPos:`value`}`.
`baseYPos` | Has the same effect as the BaseYPos configuration option. Usage: `#{baseYPos:`value`}`.
`nodeXSkip` | Has the same effect as the NodeXSkip configuration option. Usage: `#{nodeXSkip:`value`}`.
`nodeYSkip` | Has the same effect as the NodeYSkip configuration option. Usage: `#{nodeYSkip:`value`}`.
`lineSpacing` | Coeficient for line spacing in text labels. The value can be float. Default coeficient is 1 (single line spacing). This style has the same effect as the LineSpacing configuration option. Usage: `#{lineSpacing:`value`}`.
`skipHiddenParents` | Has the same effect as the SkipHiddenParents configuration option. Usage: `#{skipHiddenParents}` or `#{skipHiddenParents:1}` to turn on, or `#{skipHiddenParents:0}` to turn off.
`skipHiddenLevels` | Has the same effect as the SkipHiddenLevels configuration option. Usage: `#{skipHiddenLevels}` or `#{skipHiddenLevels:1}` to turn on, or `#{skipHiddenLevels:0}` to turn off.
`vertical` | Turns on the vertical mode. Use `#{vertical}` or `#{vertical:1}` to set the option on, `#{vertical:0}` or none to set it off.
`labelsep` | Vertical mode only. The distance between a node and the label next to it. Usage: `#{labelsep:`integer`}`.
`columnsep` | Vertical mode only. The distance between two columns of labels. Usage: `#{columnsep:`integer`}`.
`columnsep[`i`]` | Vertical mode only. The distance before the `i`-th column of labels. Usage: `#{columnsep[`i`]:`integer`}`.
`stackOrder` | A comma separated list of item tags defining a z-axis ordering of canvas items (lowest first). The default stackOrder is: line, node, textbox, edgetextbox, textbg, text, plaintext.
`NodeLabel-valign` | This instruction takes one of the following values: “`top`”, “`center`”, and “`bottom`”. This feature specifies which side of the group of node labels should be placed towards the node. If “`top`” is selected (which is the default value), node labels appear below the node. If “`bottom`” is selected, node labels are displayed above the node. If the value of “`center`” is used, node labels are displayed across the node.

Table 3. Style instructions

`object`-`feature` | Description and a list of possible values
--- | ---
`Node-hide` | Nodes for which this feature is non-zero are not displayed at all. The following `rootstyle` options control how child nodes of hidden nodes are displayed: `skipHiddenParents` and `skipHiddenLevels`.
`Node-shape` | The shape of the point representing the node in the tree. Possible values are `oval`, `rectangle`, and `polygon` (see also `Node-polygon` below).
`Node-polygon` | Specifies the relative coordinates for three or more points that define a closed polygon. The first and last points may be the same; whether they are or not, TrEd will draw the polygon as a closed polygon.
`Node-width` | Width of an oval- or rectangle-shaped node.
`Node-height` | Height of an oval- or rectangle-shaped node.
`Node-currentwidth` | Width of an oval- or rectangle-shaped node when current.
`Node-currentheight` | Height of the node an oval- or rectangle-shaped node when current.
`Node-addwidth` | Increase width of an oval- or rectangle-shaped node by a given amount.
`Node-addheight` | Increase height of an oval- or rectangle-shaped node by a given amount.
`Node-rellevel` | Allows altering the default vertical position of a subtree. The values are multiples of one default level height. Positive values move the subtree down, while negative values move the subtree up.
`Node-level` | Very similar to `Node-rellevel` above, except that this option affects one node only rather than the whole subtree.
`Node-addbeforeskip` | Additional horizontal space before node in pixels
`Node-addafterskip` | Additional horizontal space after node in pixels
`Node-disableedgelabelspace` | If set the value is “`yes`” no additional horizontal skip for edge labels is added during positioning the node.
`Node-textalign` | Alignment of the node labels: `right`, `center`, or `left`.
`Node-textalign[`i`]` | Alignment of the `i`-th node label: `right`, `center`, or `left`.
`NodeLabel-skipempty` | This option controls whether an empty node label should be skipped to make the nearest preceding and following non-empty labels vertically adjacent. This produces considerably more compact trees.
`NodeLabel-valign` | This instruction may be used only within `rootstyle` patterns, see the table above.
`NodeLabel-halign` | One of the following values may be used: “`left`”, “`center`”, and “`right`”. This feature specifies which side of the group of node labels should be placed towards the node. E.g, if “`right`” is selected (which is the default value), node labels appear left of the node.
`NodeLabel-yadj` | Adjust vertical position of node labels by extra amount of pixels.
`NodeLabel-dodrawbox` | If Setup → Appearance → Draw Boxes Around Labels is not selected and this instruction is set to “`yes`” for a given node , box is still drawn around the node's labels.
`NodeLabel-nodrawbox` | If Setup → Appearance → Draw Boxes Around Labels is selected and this instruction is set to “`yes`” for a given node, no box is drawn around the node's labels.
`EdgeLabel-yadj` | Adjust vertical position of edge labels by extra amount of pixels. The horizontal position is adjusted automatically.
`EdgeLabel-coords` | This option can be used to specify custom (non-standard) positioning of the edge label by specifying the exact point to which the edge label is anchored. The format of this option is similar to `Line-coords`, except that only one pair of coordinates (X,Y) is allowed. See Line-coords for more information.
`EdgeLabel-halign` | One of the values “`right`”, “`center`”, and “`left`” may be used to specify which side of the edge label should be oriented towards the edge.
`EdgeLabel-valign` | One of the values “`top`”, “`center`”, and “`bottom`” may be used to specify which side of the edge label should be oriented towards the edge.
`EdgeLabel-dodrawbox` | If Setup → Appearance → Draw Boxes Around Edge Labels is not selected and this instruction is set to “`yes`” for a given node , box is still drawn around the node's edge labels.
`EdgeLabel-nodrawbox` | If Setup → Appearance → Draw Boxes Around Edge Labels is selected and this instruction is set to “`yes`” for a given node, no box is drawn around the node's edge labels.
`Oval-dash` | Dash pattern for the outline of the point representing the node of the tree. A dash pattern is either a sequence of arbitrary of the following characters “.,-_” where space can be used to enlarge the space between other line elements, and can not occur as the first position in the string, or a comma-separated list of integer numbers specifying the lengths of dashes and spaces between them.
`Oval-activedash` | Dash pattern for the outline of the point when mouse is over the point. See description of `Oval-dash` for more information on dash patterns.
`Oval-dashoffset` | The starting offset (in pixels) into the pattern provided by the `Oval-dash` instruction.
`Oval-fill` | The color that fills the node.
`Oval-activefill` | The color to fill the node when mouse is over it.
`Oval-outline` | The color of the outline of the node.
`Oval-activeoutline` | The color of the outline of the node when mouse is over it.
`Oval-width` | Width of the outline of the node.
`Oval-activewidth` | Width of the outline of the node when mouse is over it.

`Line-coords`

This, very complex, option allows to setup one or more lines leading from the node. Unless this option is set, only a line (edge) starting at the node and leading to its parent is drawn.

This option may consist of one or more tuples of coordinates separated with `&` of the form `x1, y1..., xn, yn`, where x1 through yn give the coordinates for a series of two or more points that describe a series of connected line segments.

The coordinates may be either absolute or relative to the node, its parent, or if necessary to any node in the tree. In fact, each corrdinate can be specified as an arithmetic expressions involving the operations `+`, `-`, `*`, `/`, `%` (modulus), functions `abs()`, `sgn()`, and `sqrt()`, and the ternary operator `condition ? exp-if-true : exp-if-else` where condition can be a boolean expression involving `&&` as conjunction, `||` as disjunction, and `==`, `<` `>`, `<=`, and `>=` as numeric comparison operators. Use the letter `n` to refer to the coordinate of the current node on the current axes and the letter `p` to refer to the coordinate of the parent node of the current node. Use `xn` and `yn`, or `xp` and `yp` to refer to a coordinate of the current node or its parent (resp.) on an explicit axis.

Coordinates of other nodes may be queried using the following constructions:

Simple search

  The construction of the form `x[attribute_name = value]` or `y[attribute_name = value]` may be used to query x-coordinate or y-coordinate (respectively) of the first node whose attribute `attribute_name` has the given `value`.

Simple perl search

  The construction of the form `x[? code ?]` or `y[? code ?]` may be used to query a coordinate of the first node for which the given Perl code returns non-zero defined value. Within the code, use `$this` to refer to the current node and `$node` to the node being tested.

Custom perl search

  Sometimes it is not necessary to go through the whole tree to find the desired node. In such a case, the user may provide a code that finds the node and returns it. This type of query has the form `x[! code !]` or `y[! code !]`, where `code` is the user's custom node search algorithm written in Perl. Within the code, use `$this` to refer to the current node.

`Line-arrow` | One of the values “`first`”, “`both`”, “`last`”, may be used to make arrow to be drawn on one or both sides of the edge connecting the given node with its parent. If multiple lines pertain to a node, values for individual lines should be separated by `&` in the same order in which lines are specified in `Line-coords`.
`Line-tag` | Values are arbitrary strings that will be passed to `line_click_hook` if the line is clicked. If multiple lines pertain to a node, values for individual lines should be separated by `&` in the same order in which lines are specified in `Line-coords`. The individual tag values must not contain `&`.
`Line-hint` | Values are arbitrary strings that will be shown when the user hovers mouse pointer over the line. If multiple lines pertain to a node, values for individual lines should be separated by `&` in the same order in which lines are specified in `Line-coords`. For this reason the text for no line must not contain `&`.
`Line-smooth` | Values are 1 or 0. It indicates whether or not the line should be drawn as a curve. If so, the line is rendered as a set of parabolic splines: one spline is drawn for the first and second line segments, one for the second and third, and so on. Straight-line segments can be generated within a curve by duplicating the end-points of the desired line segment. If multiple lines pertain to a node, values for individual lines should be separated by `&` in the same order in which lines are specified in `Line-coords`.

`Line-decoration`

This option can be use to define various line decorations to be drawn along individual lines specified in `Line-coords`. A decoration is basically an item of the Tk::Canvas widget. This option can specify the shape type, relative coordinates, size, and other properties of an decoration item and the way in which the item is to be copied along the line path.

The value consists of a `&`-separated sequence of decoration specifications for the individual lines (in the same order in which lines are specified in `Line-coords`).

Each line can have multiple decorations; individual decoration definitions are separated by `|`. A decoration is defined by a semi-colon-separated list of ``option`=`value`` pairs.

The following options are allowed in a decoration definition:

shape

  One of `line`, `text`, `rectangle`, `polygon`, `oval`, `arc`, `image`.

coords

  A comma-separated list of coordinates relative to the current point on the line. The shapes `text` and `image` require one pair of coordinates, `oval`, `arc`, and `rectangle` require two pairs of coordinates, `line` requires at least two pairs of coordinates and `polygon` requires at least three pairs of coordinates.

step

  Distance between two adjacent instances of decoration on the line. The value can be a percent string from 0% to 100% defines the distance in percents of the length of the line path or an absolute distance (integer) from the start of the line along the line path.

start

  A distance (relative or absolute - see `step`) from the start-point of the line in which the first decoration should be drawn.

stop

  A distance (relative or absolute - see `step`) from the end-point of the line beyond which no further decoration should be drawn.

force

  If used, it must provide a distance in which a decoration is drawn in case that the distance defined using `stop` precedes the distance defined using `start`.

repeat

  Defines maximum number of decorations to be drawn along the line path.

rotate

  If set to a true value, the coordinates specified with `coords` will be rotated around the current point on the line so as to preserve the same angle to the tangent of the line as the initial coordinates have to the axis X.

tag

  A comma-separated list of tags to associate with the decoration objects.

`other`

  Any option such as `fill, dash, outline,width` supported by the given Tk::Canvas item-type (shape) can be passed here. Please consult Tk::Canvas#OVERVIEW_OF_ITEM_TYPES documentation for a complete list. The options must be passed without the leading dashes.

`Line-``feature` | Features `dash`, `activedash`, `fill`, `activefill`, `width`, and `activewidth` may be used to style the edge. Their values and meaning is similar to those of `Oval`, as described above. If multiple lines pertain to a node, values for individual lines should be separated by `&` in the same order in which lines are specified in `Line-coords`.
`Text`<position>`-fill` | This feature may be used to set the color of a certain text object. The object is determined by its `position` which may have one of the following forms: `[`attribute-name`]`, `[`attribute-name`][`n`]`, or `[`attribute-name`][`n`][`m`]`, where `attribute-name` is name of an attribute, `n` is the ordinal number of pattern which is the source of the text object and `m` is ordinal number of the attribute reference (`${`attribute-name`}`) within that pattern.
`Text`<position>`-activefill` | This feature may be used to set the color of a certain text object when mouse is over it. The syntax of `position` is as above.
`TextBg`<position>`-`feature`` | This instruction may be used to set features of an underlying rectangle of certain text object. The syntax of `position` is as above, except that only the first two forms are accepted, because text objects appearing on one line have common underlying rectangle. The following features are supported: `dash`, `activedash`, `dashoffset`, `fill`, `activefill`, `outline`, `activeoutline`, `width`, and `activewidth`.
`TextBox-`feature`` | This instruction may be used to set features of the frame drawn around the group of node labels. The following features are supported: `dash`, `activedash`, `dashoffset`, `fill`, `activefill`, `outline`, `activeoutline`, `width`, and `activewidth`.
`EdgeTextBox-`feature`` | This instruction may be used to set features of the frame drawn around the group of node's edge labels. The list of supported features is the same as that of `TextBox`.

Prev |  | Next
9. Tree Orientation | Home | ToC | 11. Printing Trees