Advanced Typesetting

Jason Harris

Wolfram Research

This talk will detail some of the advanced typesetting capabilities in Mathematica. It will explore ways to create your own typeset notations which are particular to your field of study / practice. We will cover boxes and in particular TemplateBoxes, together with MakeBoxes and MakeExpression rules, and discuss StyleSheets for packaging up your own notations. In detail we will cover:

Boxes and the representation of typeset structures

MakeBoxes & MakeExpression and how the typesetting system interacts between the Kernel and the FrontEnd

TemplateBoxes, and how to use these modern typeset structures

The Notation Package and how to short cut much of the work required in using MakeBoxes and MakeExpression

StyleSheets and how to package up the typeset structures onto the style sheet

Miscellaneous topics.

`

Our Goal

Our goal is to introduce new notations which can do computations.

For instance something like (Subscript[a, ∂]) and make this parse and format as the operator ADiff, etc. Or make say our own commutator as we would use in Physics. Or say:

Everything is Boxes!

(x^3)+2

(∫_0^∞)(E^(-(x^z)))\[DifferentialD]x

%/.z->3

Visual form vs. Internal form

theboxes = "";InputField[Dynamic@theboxes,Boxes,ContinuousAction->True]

Dynamic@Style[theboxes,ShowStringCharacters->True]

Generators and Graphics Boxes

All displayed graphics are actually boxes.

Graphics[Table[Line @ {{Random[],Random[]},{Random[],Random[]}},{7}], ImageSize->Small]

pts={{0,0},{1,1},{2,-1},{3,0}};
Graphics[{BezierCurve[pts],Green,Line[pts],Red,Point[pts]},ImageSize->Small]

Similarly all box control are also boxes:

3+Style[bob,FontSize->50]

Button["Hi There",Print @ "Hello"]

Slider[Dynamic[mn],{1,100,1}]

Dynamic[Factor[(y^mn)+1]]

Its all about boxes! Everything is a Box.

MakeExpression & MakeBoxes

We need to be able to do computation with our boxes.

Generators are not sufficient.

Our goal is to introduce new notations which can do computations.

Evaluation Model

Parsing 	⟷ 	MakeExpression
Formatting 	⟷ 	MakeBoxes

(∂_y)((Sin[y])/2)

?MakeBoxes

?MakeExpression

Example PartialPlus

Consider a new notation for “Partial Plus” by subscripting a partial derivate by ‘+’ and having “FullForm” PDPlus.

Typically in creating a MakeExpression rule we transform to another MakeExpression of something Mathematica actually can make.

MakeExpression[RowBox[{
  SubscriptBox["∂", "+"], v_}],StandardForm]:=
MakeExpression[RowBox[{"PDPlus","[",v,"]"}],StandardForm]

In MakeBoxes we transform from expressions to boxes and we need to further call MakeBoxes on any subparts.

MakeBoxes[PDPlus[v_],StandardForm]:=
RowBox[{SubscriptBox["∂","+"],MakeBoxes[v,StandardForm]}]

Now we can

(∂_(+))(q_+t_):=(∂_(+))q+(∂_(+))t

(∂_(+))((x^2)+Sin[t])

FullForm @ %

Trick: Often it is best to create the notation you want using the 2D editing tools in Mathematica and then just copy the underlying boxes.

ConvertTo uses MakeBoxes and MakeExpression

Trick: You can use the menu Cell > Convert To > StandardForm (⌘⇧N) to format an expression in 2D. To enter tricky notations you can enter the full form of a notation and then convert the cell to StandardForm.

Conversions only work with syntactically valid structures.

Evaluation In MakeBoxes and MakeExpression

You have to be very careful that we don’t let evaluation occur as a side effect of our transformations. (Mostly in MakeBoxes)

Example Function Notation

(a|->(a^2))

Answer :

Example Up and Down

Answer :

(b^↑)+(t^↓)

FullForm @ %

Example Format ‘List Of Lists’ as Matrix

{{2+2,a},{b,c}}

Answer

{{2+2,a},{b,c}}

Answer With Correct Holding

Now modeling your answer on how the TraditionalForm output looks, define a MakeBoxes rule which has the correct holding attributes

Tag Boxes

TagBoxes are invisible tags that have the form TagBox[boxes,tag]. tag can be any expression.TagBoxes are used to invisibly “tag” a box structure so we can identify it later.

( In Mathematica 8 onwards we transitioned to TemplateBoxes in the vast majority of cases.)

TagBoxes are still used to guide interpretation in some cases. Eg Grid

Grid[{{a,b},{c,d}}]

MakeTemplate creates generalized placeholders. These placeholders are based on TagBoxes.

The ⇥ key takes you between placeholders.

Another example of TagBox usage is in event handlers (See Lou’s talk). Or eg

We also hijack TagBoxes for MouseAppearance

MouseAppearance[bob, "x"]

Typesetting for LegendreP[n,x]

To illustrate TagBoxes consider making a notation for LegendreP[n,x]⟷(Subscript[P, n])(x)

The Rules:

Here are the MakeExpression and MakeBoxes rules to do such a thing

MakeBoxes[LegendreP[n_,x_],StandardForm]:=RowBox[{SubscriptBox["P",MakeBoxes[n,StandardForm]],"[",MakeBoxes[x,StandardForm],"]"}]

MakeExpression[RowBox[{SubscriptBox["P",n_],"[",x_,"]"}],StandardForm]:=
MakeExpression[RowBox[{"LegendreP","[",RowBox[{n,",",x}],"]"}],StandardForm]

The Problem:

Subscript[P,n][x]

(Subscript[P, n])[x]+1//FullForm

Ouch!

Solution:

We use the following TagBox structure to distinguish the “P”

RawBoxes @ TagBox["P",SelectWithContents->True,Selectable->False]

LegendreP[n,x]+1

FullForm @ %

However whatever you come up with here, the P is likely to be detachable from the rest of the notation, as well as having other problems. This gives rise to TemplateBoxes.

The Notation package

<<Notation`

The notation package allows us to automate the process that has been described for creating notations. A notation statement is of the form:
  Notation[ExternalForm ⟺ InternalForm]

Example: ring addition, ring multiplication.

a(Subscript[*, ℛ])b(Subscript[+, ℛ])c

Notation Package Functioning

The notation package internally is a notation compiler. It takes a box structure representing the notation to be compiled and returns the equivalent MakeBoxes and MakeExpression rules.

Notation[a_(Subscript[+, ℛ])b_ ⟺ RingPlus[a_,b_],Action->PrintNotationRules]
Notation[a_(Subscript[*, ℛ])b_ ⟺ RingTimes[a_,b_],Action->PrintNotationRules]

Example Up and Down Revisited

Quickly Entering Notations

Trick: You can quick create shortcuts for notations through an “add input alias” statement. (EscaddiaEsc)

AddInputAlias["opu"->(NotationTemplateTag[(\[SelectionPlaceholder]^↑)])]

BaseStyle

Consider the example of vector with a shaded background. Assume we had put the style box around the whole underscript to yield a structure like the following:

RawBoxes @ StyleBox[UnderscriptBox["v","~"],Background->GrayLevel[0.8]]

So instead we can add the style into the base style.

RawBoxes @ UnderscriptBox["v","~",BaseStyle->{Background->GrayLevel[0.8]}]

Sometimes there are lots of styles we would like to add to the base style so we can just encapsulate all these styles into a new style and add that to the style sheet.

BaseStyle and DefaultBaseStyle are options to almost every box.

TemplateBoxes: Binomial Formatting

Consider the display function for traditional form typesetting of Binomial. How is this done?

Binomial[n,k]//TraditionalForm

RawBoxes @ TemplateBox[{"a","b"},"FooLegendreP",DisplayFunction:>(RowBox[{SubscriptBox["P",#1],"[",#2,"]"}]&),Tooltip->"MyLegendreP"]

TemplateBoxes

Almost all composite typesetting in Mathematica is now done through TemplateBox. TemplateBox is:

TemplateBox[{(Subscript[box, 1]),(Subscript[box, 2]),...},tag]

is a low level box structure which displays as the DisplayFunction of the template box filled in with the (Subscript[box, i])

TemplateBox is low-level notebook structure used to represent a parameterized box structure. The DisplayFunction option of the TemplateBox is applied to the box arguments to yield a new box structure which is displayed.

The DisplayFunction option is normally specified on the style sheet in order that when the style sheet changes all displayed instances of the template box change uniformly.

If the tag of the TemplateBox is a string then that style will be used for the TemplateBox.

TemplateBoxes can be nested to any level

TemplateBox[{TemplateBox[{"n","x"},"LegendreP"],"b"},"Binomial"]//RawBoxes//TraditionalForm

You can write MakeBoxes and MakeExpression rules which use TemplateBoxes in order to define new notations.

Putting it on the StyleSheet

So consider the following:

c+RawBoxes @ TemplateBox[{"a","b"},"MyCommutator",DisplayFunction:>(SubscriptBox[RowBox[{"[",RowBox[{#1,",",#2}],"]"}],"-"]&)]

Note: the option template box option InterpretationFunction->Automatic means Mathematica chooses the tag name by default as the function name.

Answer:

Miscellaneous

I should talk here about precedence’s and SyntaxForm:

a+(∂_x)func+b

Also note that Graphics does context sensitive typesetting. Eg:

Point[{0,0}]

Graphics[ Point[{0,0}],ImageSize->50]

This is achieved by having the MakeExpression rules in Graphics be context sensitive.

Interesting Irrelevant note: The Mathematica box model to css box model, and BaseStyle to styles, ImageMargins, FrameMargins, to html margins and padding.

Conclusions

Steps to create a TemplateBox notation:

Enter a structure in 2D typesetting.

Copy the boxes for that structure into a display function replacing the arguments you want parameterized with #n

Put the resulting style on the style sheet.

Create a MakeBoxes rule for the given notation.

Bonus points: create an input alias for the notation.