Model Documentation in Modelscape
This example shows how to add content to a Microsoft® Word document from MATLAB®.
Many workflows in financial institutions involve writing and submitting reports to internal control functions or regulatory bodies. These documents often conform to a given house style and are typically Microsoft Word documents.
This example shows how to create a link from the MATLAB model development environment to the Word document. This enables the authors to push text, visualizations, and tables from MATLAB to the Microsoft Word document. This removes the need for error-prone processes involving screenshots and copy-pasting and ensures that the Word document contents are always in a consistent state. Authors can go back and forth between Microsoft Word and MATLAB, adding new text at the Microsoft Word side and refreshing the MATLAB contents as needed.
This example begins with a simple case of inserting a single MATLAB variable from the workspace to a Microsoft Word document. This example then describes the workflow you can use to insert more content from MATLAB to a Microsoft Word document.
Insert a single MATLAB Variable from Workspace to Word Document
Open a blank Microsoft Word document and add some text such as a title to it. Create a placeholder for your MATLAB content to the document - in MATLAB Report Generator terminology these are called holes. To do this, on the Developer tab, click the 'Rich Text Content Control' symbol Aa in the Controls area. Then click 'Properties' and fill in the Title and Tag fields as follows:
The 'Title' you have entered here will be the identifier of the hole - different holes will in general have different identifiers. By contrast, the tag tells MATLAB this is a placeholder it should fill in. The tag should always be 'Hole' as shown above. Your document should now look something like this:
Save your document to, say, myTestDocument
.docx
. Open MATLAB and navigate to the folder with the document.
Create the content you want to fill in, for example:
HoleContent = datetime("now");
The variable name must match the Title you chose earlier.
Preview how the content will appear in the document by calling fillReportFromWorkspace
.
myDoc = "myTestDocument.docx";
previewDoc = fillReportFromWorkspace(myDoc);
winopen(previewDoc);
Calling fillReportFromWorkspace
pushes the datetime content to a temporary document whose name is stored in previewDoc
. Calling winopen
opens this document.
If you want the datetime to be formatted in a different way, you can recreate the hole content.
HoleContent = datetime("now", "Format", "dd-MMM-uuuu");
Rerun the fillReportFromWorkspace
and winopen
calls. You should then see only the date in the Word document, not the hours, minutes, and seconds.
previewDoc
is intended as a preview which you can discard later. To modify your original file myTestDocument.docx
, close the main myTestDocument
file and run:
fillReportFromWorkspace(myDoc, "OutputMode","Publish"); winopen(myDoc);
The date now appears in the main document. The HoleContent
placeholder in your document remains refillable even after this operation. Running fillReportFromWorkspace
in the Publish
mode refreshes every time you fill the document. You will however need to close the document in Word every time you do this.
If fillReportFromWorkspace
cannot find the required MATLAB content for a hole, it will insert the text "Place-holder for hole id 'HoleContent'" in red boldface font to highlight this to the user. Similarly, other formatting errors show different messages depending on the error.
Use the Model Documentation Workflow
Use the following workflow to document in Modelscape™ Reporting.
Create Word document.
Edit Word document and add holes for the contents to be filled in from MATLAB.
Create MATLAB contents.
Fill them into a preview document using
fillReportFromWorkspace
(in thePreview
mode).Repeat steps 2-4 as required.
Fill the MATLAB contents to the main document using
fillReportFromWorkspace
in thePublish
mode.
Use Optional fillReportFromWorkspace Arguments
You can use the following optional arguments with fillReportFromWorkspace
.
OutputMode
: 'Preview
' or 'Publish
'. 'Preview
' fills the document into a copy of the input document, whereas 'Publish
' overwrites the input document. The default option is 'Preview
'.PresavedContentsFiles
: an array of strings giving the names of .mat files.fillReportFromWorkspace
searches for the MATLAB content to insert first from these files, then from the workspace. This argument is intended to be used primarily in multi-author projects - see below.NewContentsFile
: a string specifying the name of a .mat file. Inserted MATLAB contents will be saved to this file. IfPresavedContentsFiles
are provided as well, only the contents found in the workspace and not in the presaved mat files will be saved. This argument is primarily for multi-author projects.MappingRules
:FillReportMappings
object specifying the formatter mapping rules - see below for details.Options
:FillReportOptions
object specifying any overrides to formatter defaults - see below for details.
Use Supported MATLAB Content Types
This section shows you what MATLAB contents are supported and how to format them when filling the holes in a Word document.
There are two types of holes: inline and block holes. Inline holes insert contents within paragraphs (text, scalar numbers, ...) whereas block holes are for contents that require their own paragraph (such as figures and tables). You can insert some contents only into block holes
Preview Content
Use function previewContent
to check how a MATLAB variable appears in a document.
previewDoc = previewContent(datetime("now"));
This function creates and opens a document to which the input content has been added. The resulting document is saved in a file with name Preview-xyz.docx
, where xyz
is the type of input content. You may delete this preview document after viewing it.
Insert Basic MATLAB Content Types
The appearance of MATLAB contents in a Word document is governed by helper classes called formatters. The table below lists these formatters and describes how they work for the supported core MATLAB content types.
To insert a plot or other kind of a figure created in a Live Script, use the following MATLAB commands.
FigureContent = figure(); % "open" figure plot(rand(10)); % do the work to plot the figure figure(); % mark the work on FigureContent as finished
Insert MATLAB Report Generator Types
If you are familiar with MATLAB Report Generator, you can bypass the Modelscape formatters by wrapping MATLAB content into mlreportgen.dom
or mlreportgen.report
objects. The supported types are listed below. Note however that these types are not guaranteed to support the PresavedContentFiles
and NewContentsFile
arguments used in multi-author projects, as the Report Generator objects do not, in general, allow saving and loading into MAT files.
Report Generator DOM Types
The following types are supported. The type names are shortened - for class definitions, see mlreportgen.dom.Text
, mlreportgen.dom.Paragraph
and so on.
Report Generator Reporter Types
The following types are supported. Again, the type names are shortened - see mlreportgen.report.Equation
and so on for the class definitions.
Insert Composite Types
Modelscape Reporting automatically handles certain "composite" types such as arrays of numerical data (or strings, or logicals, or categoricals,...) and cell arrays of mixed-type data. The logic is the same:
Loop through the composite structure and format each element (double, string, logical, etc.) as explained above.
Display this table of formatted cells.
To see an example, run the following command (and delete the resulting Preview-cell.docx file afterwards).
previewDoc = previewContent({pi, true, 3; "abc", datetime("now"), hours(1)});
Insert File Contents
You can also insert the contents of certain types of files directly from files to the target document without loading them first into the MATLAB workspace using Modelscape Reporting. In this case the MATLAB workspace must contain a file content object for each inserted file, and the name of this object must match the title of the hole to be filled.
Construct the file content objects using a fileContent
helper function. For example, insert the contents of myTable.csv
as a table to a hole titled TableFromFile
and then use fillReportFromWorkspace
. .
TableFromFile = fileContent('myTable.csv');
fileContent
helper will try to infer the type of the file from its extension. The following file types and recognized extensions are supported.
image
: all the extensions are recognized bymlreportgen.dom.Image
including png, svg and jpg.table
: csv, xml, xls* and the common spreadsheet variants.text
: txt and log.
You can explicitly specify the file type for unrecognized extensions.
TableOfErrors = fileContent('errorLogs.err', 'table');
You can also pass arguments to fileContent
that will be understood by the returned file content class. Currently this is supported for table contents, for which fileContent
accepts the parameters used by readtable.
TableFromFile = fileContent('myTable.csv', 'table', 'ReadRowNames', false);
Supply the file content type when you use these extra arguments.
Using Custom File Contents
You can create your own file content classes. To learn more, contact MathWorks Consulting Services.
Format Controls - Individual Contents
Usually, the document hole title names match the name of the MATLAB variables to be filled in. You can control how this content appears in the Word document.
You can overwrite the formatter that is used for the given content.
You can pass extra control parameters to the formatter (be it the default formatter or a custom one).
To use these controls, use a hole title should be of the form ClassName
(
ContentName
, Label1, Value1, Label2, Value
2,...
)
, where
ClassName
is the name of the formatter class or function that you use (or the wordDefault
in which case no override is used).ContentName
is the name of the MATLAB workspace variable defining the content.Label1, Value1, ...
are name-value pairs that you pass to the formatter.
The rules for looking up the overriding class are as follows:
In decreasing order of priority, either the
ClassName
such asmrm.reporting.format.Scalar
,
or themrm
.reporting.customize.ClassName
,
mrm.reporting.format.ClassName
,
is used.
Otherwise, a placeholder with a warning that no class definition was found is inserted.
Example: Using mrm.reporting.customize.Exp
for Exponential Notation
Modelscape Reporting has an example custom class mrm.reporting.customize.Exp
that you can use for displaying numerical data in the exponential notation. This class supports an argument called ExpPrecision
that controls how many digits are shown after the decimal point (the default being 3).
Suppose you want to display a MATLAB variable MyNumber
that carries the number 123456.54321. Using a Word document hole title MyNumber
for this placeholder, this content appears in a Word document as 123456.5432. To override this, rename the document hole.
Exp(
MyNumber
)
- the number appears as 1.235e+05.Exp(
MyNumber,"ExpPrecision",1)
- the number appears as 1.2e+05.
The name-value pairs can also be properties of the underlying Report Generator class. For example, Exp(
MyNumber
, "Color", "blue")
shows the text 1.2345e+05 in blue font in the Word document.
Format Controls at Document Level
Formatting contents is not practical if you want to change the number of decimal places for every numeric variable inserted into a document. To apply a change to every hole in the given document, use a FillReportOptions
object for these options, and pass the object to fillReportFromWorkspace
using the 'Options' label. However, note that hole-level arguments take precedence over the top-level options.
The following control options are available.
ImageSnapshotFormat
: option used by Modelscape Figure formatter to control the format of the image taken of plots and other figures - defaults to svg.MaxNumericPrecision
: number of decimal places shown in (non-integer) numeric variables - defaults to 4.PlaceHolderColor
: colour of the text placed into document holes to alert user of missing MATLAB contents etc - defaults to crimson.TableDisplayUnits
: option used by MRM FormalTable formatter to decide whether units are displayed in the formatted table - defaults to false.
You can add any name-value pairs to the options object to pass to fillReportFromWorkspace
, to be picked up by the appropriate classes. For example, change the ExpPrecision
parameter in all numerical contents formatted in the exponential notation.
myOptions
=
FillReportOptions
(
"
ExpPrecision
"
, 1);
previewDoc
=
fillReportFromWorkspace
(
myDocument
,
"Options"
,
myOptions
);
In the setup of the example in the previous section, the content 123456.54321 placed into a hole titled as Exp(
MyNumber
)
will then appear as 1.2e+05 and not as 1.235e+05.
Map Overrides
You can use properties of Report Generator DOM objects at the document level. These will be picked up by the respective formatters. For example, adding the argument Color
with value blue
to the options makes the text in all the contents to appear in blue - this includes doubles, logicals, categoricals, strings and so on. However, this must be used with caution. For example, StyleName
makes sense for at least table and text formatters, but the value Grid Table 2
will only be understood by tables. For these kinds of changes, it is better to use mapping overrides and custom classes.
To map overrides, use the FillReportMappings
objects.
FillReportMappings
ans = "categorical" "mrm.reporting.format.Categorical" "char" "mrm.reporting.format.Text" "datetime" "mrm.reporting.format.Datetime" "duration" "mrm.reporting.format.Duration" "logical" "mrm.reporting.format.Logical" "numeric" "mrm.reporting.format.Scalar" "string" "mrm.reporting.format.Text" "table" "mrm.reporting.format.FormalTable" "timetable" "mrm.reporting.format.FormalTable" "matlab.ui.Figure" "mrm.reporting.format.Figure" "matlab.ui.control.UIAxes" "mrm.reporting.format.Axes"
FillReportMappings
objects contain two columns that should match the table shown above in the section "Basic MATLAB Content Types". You can override these mappings, add new mappings, and pass the customized mapping object to fillReportFromWorkspace
using the MappingRules
argument.
For example, Modelscape Reporting has a CheckBox
formatter to display logical variables as ticked or unticked checkboxes (and not as strings 'true'/'false'). To use this formatter for all logicals in a document, you can write the following:
myMappings = FillReportMappings("logical", "mrm.reporting.customize.CheckBox"); previewDoc = fillReportFromWorkspace(myDocument, "MappingRules", myMappings);
Similarly, you can add mapping data for in-house data types that are not directly supported by Modelscape Reporting. For example, if your model development process involves a custom class EnrichedTable
for which you have written a custom formatter mrm.reporting.customize.MyTableFormatter
(see next section), then you can add this to the mapping rules
myMappings = FillReportMappings("EnrichedTable", "mrm.reporting.customize.MyTableFormatter");
and call fillReportFromWorkspace
with this as the MappingRules
argument, as above.
To find the applicable mapping, MRM Reporting runs the test isa(
content, t)
for all the types t
that show up in the left-hand column of the FillReportMappings
display. The applicable formatter is the one corresponding to the last type for which this returns true; if no mapping is found, a placeholder with that message is inserted into the document.
Customize Formatters
Writing new formatters may be necessary for at least two reasons:
Changing the style of an existing formatter in a way that is not controllable through
FillReportOptions
.Creating a formatter for a new content type.
Place all custom formatters in a mrm.reporting.customize
package - that is, in a +
mrm
\+reporting\+customize\
folder on the MATLAB path. The interface requirements for a formatter class are as follows:
The formatter should be a subclass either
mlreportgen.dom.Element
ormlreportgen.report.Reporter
- in practice this will mean one of the classes listed in the section "MATLAB Report Generator Types" above.The formatter constructor should take as inputs
content
(the MATLAB variable to be formatted),rpt
(anmlreportgen.report.Report
object) andoptions
(aFillReportOptions
object) - in this order.
Alternatively, the formatter can be a function that returns either an mlreportgen.dom.Element
or an mlreportgen.report.Reporter
object and has the same signature as the class constructor described above.
For example, to apply Word table style Grid Table 2
to all tables in a safe way, create the following custom formatter.
classdef MyTableFormatter < mrm.reporting.format.FormalTable methods function this = MyTableFormatter(content, report, options) arguments content table report(1,1) mlreportgen.report.Report = mlreportgen.report.Report() options(1,1) FillReportOptions = FillReportOptions() end this@mrm.reporting.format.FormalTable(content, report, options); this.StyleName = "Grid Table 2"; mrm.reporting.internal.setDOMOptions(this, options); end end end
Use this for all tables.
myMappings = FillReportMappings('table','mrm.reporting.customize.MyTableFormatter'); previewDoc = fillReportFromWorkspace('TestDoc.docx', 'MappingRules', myMappings); winopen(previewDoc);
Note that if you want to run this example, you must ensure that the Grid Table 2 style is present in your test document. To do this, create and click an empty table, hit Ctrl+Alt+S and select Grid Table 2 from the dropdown menu to apply the style. Then save the document. You can now delete your empty table. The style definition will remain in the docx file.
Work on Multi-Author Projects
Several authors can co-operate on a documentation project simultaneously by following a slight modification of the reporting workflow explained above. Most of the work (steps 2-6) can be done by the authors in parallel; only the document creation and building the final version (steps 1, 7 and 8) should be coordinated and carried out by a lead author or similar. To avoid clashes between the hole names created by different authors, it may be advantageous to use a naming convention such as prefixing the hole names by the author's initials.
Create a Word document in a shared location that allows simultaneous editing, for example SharePoint.
Edit the Word document as before, adding holes for the contents to be filled in from MATLAB.
Create MATLAB contents.
Fill them into the Word document using
fillReportFromWorkspace
in the Preview mode and check that contents are correctly displayed. The authors may also use thePresavedContentsFiles
argument to include any MATLAB contents the other users may have already made available.Repeat steps 2-4 as required.
Fill in the MATLAB contents using
fillReportFromWorkspace
still in Preview mode but using theNewContentsFile
argument to save the MATLAB contents you are contributing to the document. Store the resulting mat file next to the Word document in the shared location.When all authors have contributed their document contents into different mat files, run
fillReportFromWorkspace
, passing in all the mat files through thePresavedContentsFiles
argument. Check that all the contents are correctly displayed.Run
fillReportFromWorkspace
, this time inPublish
mode, again with all the mat files listed as thePresavedContentsFiles
argument.
Note that authors are free to reference contents provided in each other's mat files.