10. Customizing Tree Appearance: Stylesheets

10.1. Introduction to stylesheets
10.2. Stylesheet syntax: the styling patterns

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 wizard button. Another way to select a stylesheet is using ViewSelect Stylesheet....

Figure 6. Switching between stylesheets

stylesheet-menu

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 wizard button is pressed or SetupEdit Stylesheet... menu command issued.

Figure 7. Stylesheet editor

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 customXXX (that can be defined in the configuration file using CustomColorXXX 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

nameDescription
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-featureDescription 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 SetupAppearanceDraw 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 SetupAppearanceDraw 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 SetupAppearanceDraw 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 SetupAppearanceDraw 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.