Main Content

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:

CreateHole.PNG

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:

TextWithHole.PNG

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.

TextWithFilledHole.PNG

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.

  1. Create Word document.

  2. Edit Word document and add holes for the contents to be filled in from MATLAB.

  3. Create MATLAB contents.

  4. Fill them into a preview document using fillReportFromWorkspace (in the Preview mode).

  5. Repeat steps 2-4 as required.

  6. Fill the MATLAB contents to the main document using fillReportFromWorkspace in the Publish 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. If PresavedContentsFiles 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.

CoverageBasicMATLABTypes.PNG

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.

CoverageDOMTypes.PNG

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.

CoverageReporterTypes.PNG

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:

  1. Loop through the composite structure and format each element (double, string, logical, etc.) as explained above.

  2. 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 by mlreportgen.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.

  1. You can overwrite the formatter that is used for the given content.

  2. 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, Value2,...), where

  • ClassName is the name of the formatter class or function that you use (or the word Default 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 as mrm.reporting.format.Scalar, or the mrm.reporting.customize.ClassName, or 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 or mlreportgen.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 (an mlreportgen.report.Report object) and options (a FillReportOptions 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.

  1. Create a Word document in a shared location that allows simultaneous editing, for example SharePoint.

  2. Edit the Word document as before, adding holes for the contents to be filled in from MATLAB.

  3. Create MATLAB contents.

  4. Fill them into the Word document using fillReportFromWorkspace in the Preview mode and check that contents are correctly displayed. The authors may also use the PresavedContentsFiles argument to include any MATLAB contents the other users may have already made available.

  5. Repeat steps 2-4 as required.

  6. Fill in the MATLAB contents using fillReportFromWorkspace still in Preview mode but using the NewContentsFile 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.

  7. When all authors have contributed their document contents into different mat files, run fillReportFromWorkspace, passing in all the mat files through the PresavedContentsFiles argument. Check that all the contents are correctly displayed.

  8. Run fillReportFromWorkspace, this time in Publish mode, again with all the mat files listed as the PresavedContentsFiles argument.

Note that authors are free to reference contents provided in each other's mat files.