Main Content

Model Documentation in Modelscape

This example shows how to add content to a Microsoft® Word document from MATLAB®.

Many tasks in financial institutions involve writing and submitting reports to internal control functions or regulatory bodies. These documents often conform to a house style and are typically Microsoft Word documents.

This example shows how to create a link from the MATLAB model development environment to a Word document. You can then push text, visualizations, and tables from MATLAB to the Microsoft Word document. This automation removes the need for error-prone processes involving screenshots and copy-pasting, and ensures that the Word document is always in a consistent state. You can go back and forth between Microsoft Word and MATLAB, add new text at the Microsoft Word side, and refresh the MATLAB contents according to your needs.

Insert a Variable from Workspace into Word Document

Create a Microsoft Word document and add some text to it. Create a placeholder for your MATLAB content to the document. This is called a hole in MATLAB Report Generator terminology.

In Word, make the Developer tab visible. Click File > Options, and then click Customize Ribbon. Under Main Tabs, click the Developer check box. If you do not see the Developer check box in the list, set Customize the Ribbon to Main Tabs.

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 this figure indicates.

CreateHole.PNG

The 'Title' you enter here is the identifier of the hole. Different holes generally have different identifiers. The tag tells MATLAB that this is a placeholder that it needs to fill in. The tag is always Hole. This figure shows an example of what the Word document looks like:

TextWithHole.PNG

Save your document with the name myTestDocument and the .docx extension. Open MATLAB and navigate to the folder with the document.

Specify the content as the current date and time.

HoleContent = datetime("now");

The variable name must match the Title you chose earlier.

Preview the document by calling fillReportFromWorkspace. Calling fillReportFromWorkspace pushes the date and time content to a temporary document. previewDoc contains the name of this document. Calling winopen opens the document.

myDoc = "myTestDocument.docx";
previewDoc = fillReportFromWorkspace(myDoc); 
winopen(previewDoc);

TextWithFilledHole.PNG

Reformat the date and time and then recreate the hole content.

HoleContent = datetime("now",Format="dd-MMM-uuuu");

Rerun the fillReportFromWorkspace and winopen calls. The Word document contains only the date and not the hours, minutes, or seconds.

You can discard the temporary document. To modify your original file, myTestDocument, close the main myTestDocument file and run these commands:

fillReportFromWorkspace(myDoc,OutputMode="Publish");
winopen(myDoc);

The date now appears in the main document. The HoleContent placeholder in your document remains refillable after this operation. Running fillReportFromWorkspace in the Publish mode refreshes the document 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 inserts the text "Place-holder for hole id 'HoleContent'" in red, boldface text. Similarly, other formatting errors show different messages depending on the error.

Use Model Documentation Workflow

Use the following workflow to document in Modelscape™ Reporting.

  1. Create a Word document.

  2. Edit the Word document and add holes for the content fill in from MATLAB.

  3. Create MATLAB content.

  4. Fill your MATLAB content into a preview document using fillReportFromWorkspace in Preview mode.

  5. Repeat steps 2-4 as required.

  6. Fill the MATLAB content in the main document using fillReportFromWorkspace in Publish mode.

Use Optional fillReportFromWorkspace Arguments

You can use optional arguments with fillReportFromWorkspace.

  • OutputMode Output mode, specified as "Preview" or "Publish". When you specify this argument as "Preview", the function fills the document into a copy of the input document. When you specify this argument as 'Publish', the function overwrites the input document. The default option is "Preview".

  • PresavedContentsFiles — MAT files containing presaved contents, specified as a string array. fillReportFromWorkspace searches for the MATLAB content to insert first from these files, then from the workspace. Use this argument when you work on projects with multiple authors. For details, see Work on Projects with Multiple Authors.

  • NewContentsFile — MAT file containing new contents, specified as a string scalar. The function saves inserted MATLAB contents to this file. If you specify PresavedContentsFiles in addition to this argument, the function saves only the contents in the workspace and not in the presaved MAT files. Use this argument when you work on projects with multiple authors.

  • MappingRules — Formatter mapping rules, specified as a FillReportMappings object. For details, see Map Overrides.

  • Options — Options to modify formatter output, specified as a FillReportOptions object. For details, see Format Controls at Document Level.

Use Supported MATLAB Content Types

Document holes have two types. Inline holes insert content within paragraphs, such as text. Block holes are for content that requires its own paragraph, such as figures and tables. You can insert some content only into block holes.

Preview Content

Use the previewContent function to create a document, add the specified input, and then open the document.

The function saves the document with name Preview-xyz, where xyz is the type of input content. Delete this preview document after you view it.

previewDoc = previewContent(datetime("now"));

Insert Basic MATLAB Content Types

The appearance of MATLAB content in a Word document is governed by helper classes called formatters. This table lists the formatter types and describes how they work for the supported MATLAB content types.

CoverageBasicMATLABTypes.PNG

Insert a plot or other kind of a figure created in a Live Script, use the following MATLAB commands.

FigureContent = figure();
plot(rand(10)); 
figure();

Insert MATLAB Report Generator Types

You can bypass the Modelscape formatters by wrapping MATLAB content in mlreportgen.dom or mlreportgen.report objects. These types do not fully support the PresavedContentFiles and NewContentsFile arguments in projects with multiple authors because the Report Generator objects do not generally support saving and loading into MAT files.

Report Generator DOM Types

This table lists the supported Reporter Generator DOM types. The type names are shortened. For the class definitions, see mlreportgen.dom.Text, mlreportgen.dom.Paragraph, and so on.

CoverageDOMTypes.PNG

Report Generator Reporter Types

This table lists the supported report generator types. The type names are shortened. For the class definitions, see mlreportgen.report.Equation and so on.

CoverageReporterTypes.PNG

Insert Composite Types

Modelscape Reporting automatically handles some composite types such as arrays of numerical data, strings, logicals, 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 this command. Delete the resulting Word document file afterwards.

previewDoc = previewContent({pi,true,3; "abc",datetime("now"),hours(1)});

Insert File Contents

You can also insert the content of some types of file directly into the target document without loading them into the MATLAB workspace. The MATLAB workspace must contain a file content object for each inserted file. The name of this object must match the title of the hole to fill.

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");

The fileContent helper tries to infer the type of the file from its extension. The function supports these file types and extensions.

  • Images — all the extensions supported by mlreportgen.dom.Image, including png, svg and jpg.

  • Tables — 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 the returned file content class understands. Currently this is supported for table contents, for which fileContent accepts the parameters used by readtable. Supply the file content type when you use these extra arguments.

TableFromFile = fileContent("myTable.csv","table","ReadRowNames",false);

Use Custom File Contents

You can create your own file content classes. To learn more, contact MathWorks Consulting Services.

Format Controls for Individual Content

Usually, the document hole title names match the name of the MATLAB variables to fill 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 default or custom formatter.

To use these controls, specify a hole title in 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 arguments that you pass to the formatter.

Modelscape searches for an implementation of ClassName to use in the following order:

  • a ClassName, if the class name is scoped explicitly in a namespace, for example mrm.reporting.format.Scalar

  • mrm.reporting.customize.ClassName

  • mrm.reporting.format.ClassName

If Modelscape does not find any of these classes, it inserts into the hole a placeholder with a warning that it did not find a class definition.

Example: Use mrm.reporting.customize.Exp for Exponential Notation

Use the mrm.reporting.customize.Exp custom class to display numerical data in exponential notation. Set the ExpPrecision property to determine how many digits the class uses to display a number. The default value is 3.

Suppose you want to display a MATLAB variable myNumber that takes the value 123456.54321. If you create a Word document hole MyNumber for this placeholder, this content appears in a Word document as 123456.5432. To override this setting, rename the document hole.

  • Use Exp(MyNumber) to display the number as 1.235e+05.

  • Use Exp(MyNumber,ExpPrecision,1) to display the number as 1.2e+05.

You can also specify name-value arguments as properties of the underlying Report Generator class. For example, use Exp(MyNumber,"Color","blue") to display the text 1.2345e+05 in blue font in the Word document.

Format Controls at Document Level

Formatting contents using hole titles is not practical if you want to change the number of decimal places for every numeric variable you insert into a document. To apply a change to every hole in a document, use a FillReportOptions object to specify 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. Any relevant formatters will use these name-value pairs. For example, change the ExpPrecision parameter in all numerical contents formatted in the exponential notation. The content 123456.54321 in the Exp(MyNumber) hole appears as 1.2e+05 instead of 1.235e+05.

myOptions = FillReportOptions(ExpPrecision=1); 
previewDoc = fillReportFromWorkspace(myDocument,Options=myOptions); 

Map Overrides

You can use properties of Report Generator DOM objects at the document level, as explained above. For example, set the argument Color to "blue" to render the text in all the contents in blue. This setting applies to all data types. However, applying these settings at the document level has limitations. For example, StyleName makes sense for table and text formatters, but you can only specify the value Grid Table 2 for tables. For changes of this type, use mapping overrides and custom classes.

To map overrides, use a FillReportMappings object.

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 match the table in the Basic MATLAB Content Types section. 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 checkboxes. Use this formatter for all logical variables in a document.

myMappings = FillReportMappings("logical","mrm.reporting.customize.CheckBox");
previewDoc = fillReportFromWorkspace(myDocument,MappingRules=myMappings);

Similarly, you can add mapping data for custom 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 a custom formatter mrm.reporting.customize.MyTableFormatter, then you can add this to the mapping rules using this command. For more information about custom formatters, see Customize Formatters.

myMappings = FillReportMappings("EnrichedTable","mrm.reporting.customize.MyTableFormatter");

You can then call fillReportFromWorkspace with myMappings as the MappingRules argument value.

To find the applicable mapping, MRM Reporting runs the test isa(content,t) for all the types t in the left column of the FillReportMappings display. The applicable formatter corresponds to the last type for which this test returns a logical 1. If the software does not find a mapping, it inserts a placeholder with that message into the document.

Customize Formatters

To change the style of a formatter that you cannot control using the FillReportOptions argument or to create a new content type, you can write a new formatter.

Place custom formatters in a mrm.reporting.customize namespace by saving them to the +mrm\+reporting\+customize\ folder on the MATLAB path. Formatter classes have these interface requirements.

  • The formatter must be a subclass of mlreportgen.dom.Element or mlreportgen.report.Reporter.

  • The formatter constructor must take as inputs the MATLAB variable to format, a mlreportgen.report.Report object, and a FillReportOptions object, in this order.

Alternatively, the formatter can be a function that returns an mlreportgen.dom.Element or a mlreportgen.report.Reporter object with the same signature as the class constructor.

For example, to apply the Word table style Grid Table 2 to all tables in a safe way, create this 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 class for all tables.

myMappings = FillReportMappings("table","mrm.reporting.customize.MyTableFormatter");
previewDoc = fillReportFromWorkspace("TestDoc.docx",MappingRules=myMappings);
winopen(previewDoc);

To run this example, you must ensure that the Grid Table 2 style is present in your test document. To apply this style, create and select an empty table, press Ctrl+Alt+S, and select Grid Table 2 from the dropdown menu. Save the document and delete the empty table.

Work on Projects with Multiple Authors

Several authors can work on a documentation project simultaneously by following a slight modification of the reporting workflow explained above. All authors can perform steps 2-6 in parallel. A lead author should carry out steps 1, 7, and 8. To avoid clashes between the hole names created by different authors, use a naming convention such as prefixing the hole names by the initials of each author.

  1. Create a Word document in a shared location that supports simultaneous editing.

  2. Edit the Word document and add holes for the content to fill from MATLAB.

  3. Create MATLAB contents.

  4. Populate the Word document using fillReportFromWorkspace in Preview mode and check that the contents display correctly. You can use the PresavedContentsFiles argument to include any MATLAB content your collaborators have made available.

  5. Repeat steps 2-4 as required.

  6. Fill in the MATLAB content using fillReportFromWorkspace in Preview mode and using the NewContentsFile argument to save the MATLAB contents you are contributing to the document. Store the resulting MAT file with the Word document in the shared location.

  7. When all authors have saved their document contents in MAT files, run fillReportFromWorkspace, specifying all the MAT files in the PresavedContentsFiles argument. Check that all the contents display correctly.

  8. Run fillReportFromWorkspace in Publish mode, specifying the MAT files in the PresavedContentsFiles argument.

All authors can reference content provided in any of the MAT files.