Programmatic Content Generation
Subpackages and commands within the DocumentTools package allow for fully programmatic functionality to create and make use of Worksheet and Document content, including creating customized tables, sections and subsections, Document Blocks and Execution Groups, customized text, and input and output. Programmatic commands also make it possible to author applications containing Embedded Components and Code Edit Regions, as well as insert content into the current document, and launching or saving as a new document.
This example page covers the following topics:
Table of Contents
Layout Elements
Embedded Components and Application Authoring
Programmable Tables
Hidden Options
Progress Bar and Slider
Animation
Pause
The DocumentTools:-Layout subpackage contains commands for constructing basic elements of a Document or Worksheet.
The following command loads the subpackage and lists the available commands:
restart:
with(DocumentTools:-Layout);
Cell,Column,DocumentBlock,Equation,Font,Group,Image,InlinePlot,Input,Output,Row,Section,Table,Textfield,Title,Worksheet
These commands can be used to construct a structure of nested Maple function calls which comprise an XML format representation of a complete Document or Worksheet. The resulting document content can be inserted, launched, or saved.
The following is a simple example of construction and insertion of such content. This example uses the constructor commands Worksheet, Table, Row, Textfield, and Equation.
E1 := Equation('sum(i, i = 1 .. n)', style = TwoDimInput):
E2 := Equation(factor(sum(i, i = 1 .. n)), style = TwoDimInput, typesetting = extended):
T := Textfield("The sum of the first n positive integers ", E1, " is equal to ", E2, alignment = centered):
xml := Worksheet(Table(Row(T), alignment = center, width = 50)):
The InsertContent command can be used to insert this content directly into the current document.
DocumentTools:-InsertContent(xml):
The sum of the first n positive integers ∑i=1ni is equal to n⁢n+12
The DocumentTools:-Components subpackage contains commands for constructing Embedded Components as content.
with(DocumentTools:-Components);
Button,CheckBox,CodeEditRegion,ComboBox,DataTable,Dial,Label,ListBox,MathContainer,Meter,Microphone,Plot,RadioButton,RotaryGauge,Shortcut,Slider,Speaker,State,TextArea,ToggleButton,VideoPlayer,VolumeGauge
An interactive application can be completely programmatically constructed as content.
The following example consists of constructing a Plot and a Button component, each with their own action code. Each time the mouse cursor is clicked within the Plot component a new data point is added to the list assigned to the global name L, and a least squares linear fit of this data is plotted. Clicking on the Button clears the plot.
The application is inserted into the current document for this first example. This example uses the commands Plot and Button to construct the components' contents.
This example also uses two procedures, update and clear, which must be defined (and left as defined) for the inserted application to function. These procedures are called whenever the respective components are clicked.
update := proc(comp) local cx, cy, v; global L; (cx, cy) := DocumentTools:-Do(comp(clickx)), DocumentTools:-Do(comp(clicky)); if type(L, listlist) then L := [L[], [cx, cy]]; else L := [[cx, cy]]; end if; DocumentTools:-Do(comp = plots:-display(plot(L, style = point, symbol = solidcircle, symbolsize = 15, color = blue, axes = normal), plot(CurveFitting:-LeastSquares(L, v), v = 0 .. 10), view = [0 .. 10, 0 .. 10])); end proc:
clear := proc(comp) DocumentTools:-Do(comp = plot([[0, 0]], color = white, axes = normal, view = [0 .. 10, 0 .. 10])); end proc:
Next, the two components are constructed. Their respective action code, executed whenever the components are clicked, call the aforementioned procedures.
P := Plot(plot([[0, 0]], color = white, axes = normal, view = [0 .. 10, 0 .. 10]), identity = "Plot0", clickdefault, clickaction = "update(%Plot0);"): B := Button("Clear", identity = "Button0", action = "unassign(':-L'); clear(%Plot0);"):
The content construction is then completed, forming a full worksheet in XML representation. Next, this is inserted into the current worksheet.
xmlapp := Worksheet(Group(Input(Textfield(B, P)))):
DocumentTools:-InsertContent(xmlapp):
In the following example, the same application is regenerated, but now defining the supporting procedures update and clear is done within the constructed application itself. This allows the application to function even if it is launched or saved as a new worksheet.
In this revision, the procedure definitions are part of the action code of the two components. An alternative approach is to put those procedure definitions into a Code Edit Region constructed as an additional part of the content. This makes the application self-contained, so that it can be used if launched in a new worksheet.
P2 := Plot(plot([[0, 0]], color = white, axes = normal, view = [0 .. 10, 0 .. 10]), identity = "Plot0", clickdefault, clickaction = cat(sprintf("update:=%a;", eval(update)), "update(%Plot0);")):
B2 := Button("Clear", identity = "Button0", action = cat(sprintf("clear:=%a;", eval(clear)), "unassign(':-L'); clear(%Plot0);")):
xmlapp2 := Worksheet(Group(Input(Textfield(B2, P2)))):
The ContentToString command is used to create a text string of an actual worksheet. This string can be launched directly in a new window or saved as a worksheet file.
appstring := DocumentTools:-ContentToString(xmlapp2):
This worksheet string can be launched directly in a new window using the Display command from the Worksheet package. In such a new window, the application functions independently of any definitions inside the current worksheet.
The following invocation uses the global name syntax :-Worksheet in order to reference the package by that name rather than the export by that same name in the previously loaded Layout package.
:-Worksheet:-Display(appstring);
The test string of the worksheet can also be saved as a worksheet file.
fname := FileTools:-TemporaryFile(): FileTools:-Text:-WriteFile(fname, appstring);
1820
The saved file is an application that functions independently of any definitions made in the current worksheet.
:-Worksheet:-DisplayFile(fname);
Tables can be created in a procedure using the DocumentTools commands:
restart;
with(DocumentTools):
with(DocumentTools:-Layout):
InsertContent(Worksheet(Table(Column()$3, Row(Cell("x"), Cell("y"), Cell("z")), Row(Cell(1), Cell(2), Cell(3))))):
x
y
z
1
2
3
The Tabulate command provides built-in support for laying out lists, Arrays, and Matrices containing all sorts of data. By constructing the content using the DocumentTools constructor commands further customization is possible, and the inserted Table can also be subsequently altered programmatically.
M := ImportMatrix(cat(kernelopts(datadir), "/datasets/sunspots.csv"))[1 .. 15, () .. ()];
m := upperbound(M, 1); n := upperbound(M, 2);
m ≔ 15
n ≔ 2
wks := Worksheet( Table( 'identity'="sunspot_table", 'alignment'='center', 'interior'='none', 'width'=300, 'widthmode'=pixels, Column()$n, seq( Row( seq( Cell( `fillcolor`=`if`(row=1, blue, `if`(row mod 2 = 1, "#ccddff", white)), `if`(row=1, Textfield( Font(M[row,col], color=white,bold) ), sprintf( "%a", M[row,col] )) ), col=1..n) ), row = 1..m ) ) ):
lookup := InsertContent(wks, 'output' = table):
Date
Mean Sunspot Number
1700
5.0
1701
11.0
1702
16.0
1703
23.0
1704
36.0
1705
58.0
1706
29.0
1707
20.0
1708
10.0
1709
8.0
1710
3.0
1711
0.
1712
1713
2.0
The Table inserted above may receive a new identity, if the identity supplied to the Table constructor is already in use in the document. The name lookup has been assigned a table which can be used to look up the identity that has been used.
lookup["sunspot_table"];
sunspot_table
The next command hides rows 11 through 14 of the above Table.
SetProperty(lookup["sunspot_table"], visible[11 .. 14, () .. ()], false);
And those rows can be made visible again.
SetProperty(lookup["sunspot_table"], visible[11 .. 14, () .. ()], true);
Hidden Options Example
In this example we use the table's ability to show or hide cells, rows, or columns. A plot generated by Statistics:-AreaChart is presented as an interactive application where you can easily choose some options that affect how the plot is displayed. After you get the look you want, you can hide the options in order to reduce screen clutter. For demonstration purposes, the "Hide Options" button is implemented using a captioned button, but this could be reduced to a simple unobtrusive icon.
Format:
Grid Lines:
Markers:
Scale:
The above application was created by dragging components off the Components palette. The action handlers all use the AreaChartPlot module, defined in the Code Edit Region below, to get the relevant options and generate the plot. Note how the export AreaChartPlot:-Options implements hiding the options column.
More Application Examples
Progress Bar and Slider Examples
Filled Table Cells
Here is a sample application that uses filled Table Cells to implement a progress bar. Click the Compute button to see a demonstration.
ProgressBarExample1:
The following Code Edit Region implements ProgressBar, the module that generates and controls the above progress bar. Calling this appliable module creates the embedded Table. Calling the Set export fills in the leading Cells in blue, indicating the percentage of work done.
Execute the following to create a new progress bar. Then execute the code below to see how it might be updated within a program.
bar ≔ ProgressBar:
for i from 1 to 10000 do if i mod 100 = 0 then ProgressBar:-Setbar,i/10000.; end if; Computex;od:
Slider
The following Code Edit Region implements ProgressSlider, an appliable module that generates and controls a Slider to indicate progress.
F ≔ proc local i, result, idlist; # Insert the Slider. idlist ≔ ProgressSlider:-Insert; for i from 1 to 7 do ProgressSlider:-Updateidlist, i, 7; # Now do computations, which is simulated here by sleeping a little. Threads:-Sleep1; result ≔ i; end do; # Now remove the progress Slider. ProgressSlider:-Clear; return result;end proc:
F
7
Animation Example
This example provides a command EmbedAnim that inserts a 2-D or 3-D plot animation along with animation controls inside a Table.
The resulting Table can be copy and pasted elsewhere in the worksheet, as a self-contained assembly.
The choice of controlling Buttons is optional. The Buttons have brief, explanatory tooltips.
The command also accepts an option autoplay, which if supplied causes the animation to begin playing upon insertion.
P ≔ plots:-animateplot, sina*x,x=−Pi..Pi, a=1.0..5, frames=20:
EmbedAnimP:
EmbedAnimP, 'buttons'='back','forward':
EmbedAnimP, 'buttons'='tostart','play','pause','toend','loop',autoplay:
Pause Example
In this example the module Pause is used to pause computation until a colored button is pressed or maxwait seconds elapses.
for i from 1 to 4 do printi; Pause maxwait=5 ; end do; Pause:-Blank;
4
Julia and Mandelbrot fractals
This example shows an application of the Fractals:-EscapeTime package.
JuliaMandelbrot();
Click or drag on the Mandelbrot fractal on the left in order to create a Julia fractal on the right. The parameter of the Julia fractal is given by the coordinates of the point selected.
Download Help Document