Programmatic Content Generation - Maple Programming Help

Online Help

All Products    Maple    MapleSim

Home : Support : Online Help : Applications and Example Worksheets : App Authoring : examples/ProgrammaticContentGeneration

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





Layout Elements


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:







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.



The sum of the first n positive integers i=1ni is equal to nn+12

Embedded Components and Application Authoring


The DocumentTools:-Components subpackage contains commands for constructing Embedded Components as content.






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]];
      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)))):



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.




The test string of the worksheet can also be saved as a worksheet file.


fname := FileTools:-TemporaryFile():
FileTools:-Text:-WriteFile(fname, appstring);




The saved file is an application that functions independently of any definitions made in the current worksheet.



Programmable Tables


Tables can be created in a procedure using the DocumentTools commands:




                              Row(Cell("x"), Cell("y"), Cell("z")),
                              Row(Cell(1), Cell(2), Cell(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 ≔ 15 x 2 MatrixData Type: anythingStorage: rectangularOrder: Fortran_order


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,
                         seq( Row( seq( Cell( `fillcolor`=`if`(row=1,
                                                               `if`(row mod 2 = 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):


Mean Sunspot Number





























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.




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.  



Grid Lines:






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.  


AreaChartPlot := module()

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.









































































































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.


ProgressBar := module()


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:


The following Code Edit Region implements ProgressSlider, an appliable module that generates and controls a Slider to indicate progress.


ProgressSlider := module()


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:




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.


EmbedAnim := module()


P  plots:-animateplot, sina*x,x=Pi..Pi, a=1.0..5, frames=20:


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.


Pause := module()

for i from 1 to 4 do  printi;  Pause maxwait=5 ; end do; Pause:-Blank;