Complex Patterns and Advanced Features
This tutorial is intended for advanced users.
Due to the complex inner workings of the
Notation package it is helpful to outline some of the more advanced features and structures of the
Mathematica front end and how they relate to the
Notation package. The following sections give a small overview of the functionality of tag boxes the specific tags used by the
Notation package and the tag box option SyntaxForm.
Tag boxes
A
TagBox is a box structure just like
RowBox,
SubscriptBox,
GridBox. It is used to change the structure of an expression or indicate a grouping or interpretation of a subexpression at an underlying level. To illustrate tag boxes consider the following input which contains an embedded
TagBox.
All
Mathematica input and output is made up of box structures at a low level. When
Mathematica receives input, these box structures are parsed into internal expressions, which can be thought of as full form expressions. Internal evaluation then takes place, and finally the internal structures are transformed back into box structures for displaying in the
Mathematica front end. We can reveal how
Mathematica sees this input at a low level by using the
Show Expression command under the
Cell menu.
Here is the underlying representation of the expression above in terms of boxes, displayed using the Show Expression menu item located under the Cell menu. |
The above expression contains a subexpression
TagBox[SuperscriptBox["x", "2"], foo]]. It is important to note that this box expression as normally viewed in
Mathematica looks visually like
x2 even though it has an embedded
TagBox. Information contained in the tag is visually hidden from the user. When an expression containing a
TagBox is input into
Mathematica the default interpretation of the subexpression surrounded by the
TagBox is to wrap the
TagBox name around the parsed subexpression, in this case to wrap foo around x^2.
The embedded TagBox tag foo has no special parsing behavior associated with it.
| Out[55]= |  |
|
However you can define your own rules for the way specific tag boxes are parsed. For instance by using the low level function
MakeExpression we can change how
Mathematica will parse expressions containing
TagBoxes.
By defining a new rule for MakeExpression we can change how Mathematica will parse expressions containing a TagBox with the tag literalBoxes. |
The embedded TagBox tag literalBoxes now has the special parsing behavior associated with it to just return the boxes.
| Out[57]= |  |
|
Knowing that special behaviors can be set up for specific tags we can now examine the tags defined by the
Notation package. The
Notation package defines three tags that have special behaviors:
NotationTemplateTag,
NotationPatternTag, and
NotationMadeBoxesTag. These are all string tags for two reasons. One, by using string tags we can avoid any potential problems to do with package contexts and redefinition of the symbols. Secondly, in
Mathematica if a
TagBox has a string tag and there is a named-style on the stylesheet path with the same name as the string tag then the
TagBox will be displayed in that style. This lets us omit the
BaseStyle option from the
TagBox and consequently our box structures are smaller and more readable.
The tag NotationTemplateTag
NotationTemplateTag is a string tag used by the
Notation package to grab box structures before they can be parsed by
Mathematica. In fact
NotationTemplateTag acts rather like the tag
literalBoxes defined above. All
Notation ,
Symbolize and
InfixNotation templates on the
notation palette contain tag boxes with an embedded string tag:
NotationTemplateTag. The embedded
TagBox ensures that the
Notation package can obtain the correct parsing information and retain the proper styling and grouping information. This embedded tag is used to capture the box structure, and the captured structure is thus wrapped with a "ParsedBoxWrapper".
An expression containing an embedded NotationTemplateTag tag.
Out[517]//FullForm= |
| |  |
|
We can avoid using notation templates if we wrap raw box structures with a ParsedBoxWrapper.
Out[60]//FullForm= |
| |  |
|
Complex Patterns and the tag NotationPatternTag
For normal purposes it is usually sufficient that the patterns present in
Notation and
Symbolize statements are simple patterns. However, it is sometimes necessary or desirable to use more complicated patterns in notations. For example, a notation might only be valid when a certain pattern is a number. To allow more complex patterns you can embed a
NotationPatternTag tag box inside a notation statement. It is critical that any notation you define which uses a complex pattern has an embedded
NotationPatternTag, otherwise the pattern will be treated as a verbatim expression and not function as a pattern. Like
NotationTemplateTag this should be a string tag. The notation palette has a button labeled InsertPatternWrapper which will embed a
NotationPatternTag around the selection, as well as tint the background of the selection to indicate that a complex pattern is present. (This tinting occurs as a result of the named style
NotationPatternTag since this is a string tag.)
It must also be pointed out that the pattern matching on the external representation is performed on the box structures, so usually you will have to make small transformations to convert box structures into normal expressions. Pattern matching on the internal representation follows conventional pattern matching.
This defines a function analogous to NumericQ that operates on box structures. |
Now only input which matches the above pattern will be interpreted as a foo object.
| Out[63]= |  |
|
Reciprocally only foo objects with numerical arguments will be formatted using the notation.
Out[64]//TraditionalForm= |
| |  |
|
You should be careful to avoid unwanted evaluation through testing functions when parsing expressions (see
parsing without evaluation.)
We can see that the patterns
a_?StringNumericQ and
a_?NumericQ do not appear literally since they were surrounded by a
NotationPatternTag in the notation statement.
The tag NotationMadeBoxesTag
The tag
NotationMadeBoxesTag is intended for advanced users. It is also a string tag. It is used to indicate that box processing and formatting has already been done and that the Notation package should not perform any processing. Typically you would use this tag for surrounding your own functions that return expressions that have already been turned into boxes or parsed into expressions. To illustrate the tag
NotationMadeBoxesTag we can examine a notation statement that might be part of a number of statements used to create a notation for Tensors.
We can see from the internal definition returned that there is no further processing of the expression
createGridBox[inds], i.e. it is not surrounded by a
MakeBoxes[..., StandardForm].
Changing precedences and the TagBox option SyntaxForm
Using the option
SyntaxForm you can change the precedence of an expression containing a
TagBox. A tag box containing a
SyntaxForm option will look like
TagBox[box structure, tag, SyntaxForm -> string], where
string is a string indicating the operator on which the precedence of the tag box is modeled. The following examples illustrate the
SyntaxForm option .
An expression which uses the arrow  with standard precedences.
Out[67]//FullForm= |
| |  |
|
We can define a new notation for a composite arrow  surrounded by a TagBox that has the SyntaxForm option set to a low precedence. |
This new composite arrow has a low precedence.
Out[69]//FullForm= |
| |  |
|
We can illustrate the underlying groupings of the expressions above in the following table.
| | |
a+b c | a+(b c) | Cell[BoxData[RowBox[{"a", "+",
RowBox[{"b", " ", " ", " ", "c"}]}]], "Input"] |
a+b c | (a+b) c | Cell[BoxData[RowBox[{RowBox[{"a", "+","b"}], " ",
TagBox[" ",Identity,SyntaxForm ->","], " ", "c"}]], "Input"] |
A table illustrating the precedences and grouping of expressions with and without precedence changing tag boxes.
The
SyntaxForm option value can be any operator string valid in
Mathematica, that is, any operator contained in the
UnicodeCharacters.tr file. The
SyntaxForm value can also include symbols before and after the operator to indicate whether the precedence is that of a prefix operator, an infix operator, or a postfix operator. Some typical values for the
SyntaxForm option are given in the table below.
| |
| "*" | group as the operator times |
| "a" | group as a symbol |
| "a+b" | group as an infix plus operator |
" " | group as a for all operator |
" " | group as an integrate operator |
" a" | group as a prefix union operator |
| " " | group as white space |
Typical SyntaxForm values and their associated precedence behaviors.