Documenting modules - arklumpus/TreeViewer GitHub Wiki

TreeViewer automatically generates documentation for modules, including the module name, author, version and description, as well as a list of all the parameters defined in the module.

It is possible to customise this documentation, adding e.g. more detailed descriptions for the module parameters or examples by using XML comments.

When the module is compiled, lines of code starting with three slashes /// will be joined together and parsed as an XML document. The elements in this XML document will be used to augment the default documentation.

For example, the following module code:

using System;
using System.Collections.Generic;
using PhyloTree;
using TreeViewer;
using VectSharp;
using System.Runtime.InteropServices;

namespace @NamespaceHere
{
    /// <summary>
    /// The summary is a brief description of what the module does, which complements the module's
    /// `HelpText`.
    ///
    /// This text will be shown at the beginning of the manual, just after the module author, version
    /// and help text.
    /// </summary>
    /// 
    /// <description>
    /// The description of the module appears at the bottom of the module's manual and can describe in
    /// more detail how the module works or provide examples.
    /// </description>

    public static class MyModule
    {
        public const string Name = "A name for your module.";
        public const string HelpText = "A very short description for your module.";
        public const string Author = "Your name";
        public static Version Version = new Version("1.0.0");
        public const ModuleTypes ModuleType = ModuleTypes.Plotting;

        public const string Id = "@GuidHere";

        private static string Icon16Base64 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAB2AAAAdgAUeEWlIAAAFHSURBVDhPY2RAA0VFRf+hTKygr68PQw8KIGQAOmAhRgNJhmJTjM8AosOAoN/xAZJcAAJuDevEdjUEvYJysRqA00XuVWslvWo3TIVyCQImKA0HzEzMEUCHhRmnzWSFCqGAzsitDVAmGICd4V230ZvhH6MOiP2fkSEeSGr+Z/w/mekf09N/DP//cPz9u2B9e9BbqOZ6IG4sX+4NNgjsgq9MfHv/Mf0TBGpqA2kGiTH+Z8z9z/gvk4nx/ymQZpAYENQDNYIsBRkCBmADDjQ4/tjeFFABNADZ73//MP8z29occBjEQXc6jI8SBoz/GG2B1Eegxw4BaWbmP6xWYAkIgNnOgOwKuAG+DZs1gBp//mVmMNnW5OfAyMCYzsT4zxcqDQZAW//DMFQIAYAGyDk07GeBcsHAu2GLEpQJ1gxlggFWQ/AB7AYwMAAAcQ2Fj94R5YcAAAAASUVORK5CYII=";
        private static string Icon24Base64 = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxEAAAsRAX9kX5EAAAHUSURBVEhL1ZM9SAJRHMDfO7XagqAvqiXaipaaCqIgkLogh7CMGqvdRUOFowySwjWKppbAFpO0paFJaGhtCtoq3YKCyPT1f/ee1314d3rV0A+O/wfc//thZEIwGCRctSWZTJrGMaWRBFYIXP4Z2KpSR63rsNyBVYIfj9AuQL0JrCr8BOFiVm1+Y4Sm/LgDO+wS1NXdyPqhh6uOsXwHHZ1dq17pfICbjrBMAD0uCWXs56YjTBPMbObaQUxhQhaZxxmmCbDrg1buhjaGvbHMIPM2jrxpuVpXaQ9j1CN7GTRoN1PRHXyPTEWIIJwvFp7it0cbJe5CiUB2MnQqXnNTQTml6VCqtcnTfACeAHfVokww2S8+F2K64BKIMHy7kITqCsqIrhL+l1x8fhnqWwPzjXk1POAKmbjc8oXVwTlhCNxCJTO/Mewgt+07BkFHoucsu+PLc12BV6+gtw0JROmiH8Qo1WF+ryAqVIfO4JqI5nUSZlerR9UuuF9G8wNFjKYjBOM4qDdlF1pxV1AfIegE7F4Y0bi6C9Xs9Si7cMumCriQBVhkQrXIeziAIXoARBDom1CPSaleDSR+B6EZlYxXSrWJkfQYNw3MRjNzXJXhgQyY+f8jCH0Bcv6odgXoqPQAAAAASUVORK5CYII=";
        private static string Icon32Base64 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAHySURBVFhH5Za/SsRAEMbvxMLCwkawsFDwAbze4uxECwst9AEsBAuNiljIeVwlarDwHawFFQtLS0HfwMZCsLGwsBDO70smR/7sbubCHgj+4GOyu0lmZ3Z2k3qthCAIjmFacas/wjAsff+QWBeVnHsDGehS0vSOJgMDpa6NTrOeVfA2garFqtkF0QQVExhMnfDFmpdr78ujzoCWfmtFswvaYv82A1sCLf04Ty+T+iBaPLpekEsjVc8J1UNwPgLzCk3fdZa/o05PaDPA6CfEekU7gZWc9UbpEiD9wzAf0Bj0BY37XAZNBpoQnZNRyOsy9DKASLdgduNWBjpPJkA+RXnOkZlLuVbTy4A8vAEx5VMppZ0TttPj3CGbNucn67fO8yGzBHjJA0wDuok6yrmHGniOtgCc8xPdsyasRShLcgoxwjw/0CEcn8VNMxI9vyWtg6sloy9rEUpK3+JWgXeF8yhqOHZmwToBZGAWZiZuFZjE+Jxc2+DfUfIljbIQX2ZxbcP0ocP9fyE2wXoo5aN3ZcE1gTWxLxALbYcWemInWBVrIh19gjELxsKQ9D9DjHofzll0ERjjNu1Ae9A8xh7ZnyBRun5O20lGrMDJNuQ88TDehDiJDJhA11Zw7Oe4NP2jccBx3idNZw1UwbT2eaw74j9Sq/0C/Em1T70ILNwAAAAASUVORK5CYII=";

        public static Page GetIcon(double scaling)
        {
            byte[] bytes;

            if (scaling <= 1)
            {

                bytes = Convert.FromBase64String(Icon16Base64);
            }
            else if (scaling <= 1.5)
            {
                bytes = Convert.FromBase64String(Icon24Base64);
            }
            else
            {
                bytes = Convert.FromBase64String(Icon32Base64);
            }

            IntPtr imagePtr = Marshal.AllocHGlobal(bytes.Length);
            Marshal.Copy(bytes, 0, imagePtr, bytes.Length);

            RasterImage icon;

            try
            {
                icon = new VectSharp.MuPDFUtils.RasterImageStream(imagePtr, bytes.Length, MuPDFCore.InputFileTypes.PNG);
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
            finally
            {
                Marshal.FreeHGlobal(imagePtr);
            }

            Page pag = new Page(16, 16);
            pag.Graphics.DrawRasterImage(0, 0, 16, 16, icon);

            return pag;
        }


        public static List<(string, string)> GetGlobalSettings()
        {
            return new List<(string, string)>()
            {
                
            };
        }

        public static List<(string, string)> GetParameters(TreeNode tree)
        {
            return new List<(string, string)>()
            {

            };
        }

        public static bool OnParameterChange(object tree, Dictionary<string, object> previousParameterValues, Dictionary<string, object> currentParameterValues, out Dictionary<string, ControlStatus> controlStatus, out Dictionary<string, object> parametersToChange)
        {
            controlStatus = new Dictionary<string, ControlStatus>();
            parametersToChange = new Dictionary<string, object>();
            return false;
        }

        public static Point[] PlotAction(TreeNode tree, Dictionary<string, object> parameterValues, Dictionary<string, Point> coordinates, Graphics graphics)
        {
            Point topLeft = new Point();
            Point bottomRight = new Point();

            return new Point[] { topLeft, bottomRight };
        }
    }
}

Will produce the following XML code:

<summary>
The summary is a brief description of what the module does, which complements the module's
`HelpText`.

This text will be shown at the beginning of the manual, just after the module author, version
and help text.
</summary>

<description>
The description of the module appears at the bottom of the module's manual and can describe in
more detail how the module works or provide examples.
</description>

TreeViewer will search the XML document for some predefined elements, and if they are found it will include the contents of the elements in the manual it generates. The manual is generated in Markdown format, and accordingly the documentation included in the XML comments will be treated as Markdown code.

The Markdown code generated as the manual for the module code above is:

# <img src="data:image/svg+xml;base64,..." height="52.706" /> A name for your module.

### _Version 1.0.0, by Your name_

**Description**: A very short description for your module.

**Module type**: Plotting

**Module ID**: `@GuidHere`


 The summary is a brief description of what the module does, which complements the module's
 `HelpText`.

 This text will be shown at the beginning of the manual, just after the module author, version
 and help text.
 


 The description of the module appears at the bottom of the module's manual and can describe in
 more detail how the module works or provide examples.

Note that the Markdown source contains the module icon encoded as a base64 image. This produces the following module manual:

A name for your module.

Version 1.0.0, by Your name

Description: A very short description for your module.

Module type: Plotting

Module ID: @GuidHere

The summary is a brief description of what the module does, which complements the module's HelpText.

This text will be shown at the beginning of the manual, just after the module author, version and help text.

The description of the module appears at the bottom of the module's manual and can describe in more detail how the module works or provide examples.

The elements that can be defined in XML comments are the following:

  • <summary></summary>: text that is shown at the beginning of the manual, just below the module author and before any module parameters. You can use this to briefly describe the module.

  • <description></description>: this text is shown at the bottom of the manual, after any module parameters. You can use this space to provide more detailed information about the module and examples. You should probably start this with a Markdown header, otherwise it might be confusing for users.

  • <param></param>: this element is used to describe the function of a module parameter. Attributes of this element are used to select which parameter is being described and to override default visualisation options:

    • name: this attribute is used to select the parameter to which the param element applies. E.g. <param name="Thickness:">.

    • display: this attribute is used override the name of the parameter that is shown. E.g. <param name="Thickness:" display="Branch thickness"> ensures that the parameter which appears as Thickness: in the interface is referred to as Branch thickness in the manual. By default, parameters are described in the manual based on their name, with any trailing spaces and colons (:) removed (thus, without the display override, the parameter would be shown as Thickness).

    • default: this attribute is used to override the way in which the default value for the parameter is shown. If you set this to an empty string, no default display will be shown.

    • value-header: this attribute is used to override the header of the "possible values" of the parameter.

    • values: this attribute is used to override the text describing the possible values of the parameter.

    The inner content of the param element contains the description of the parameter, which is placed after the parameter name, default value and possible values. If you do not like the way the default value and possible values are shown by default, you can set the default attribute and the value-header attribute so that these are not shown, and use the content of the param element to describe this information in a more suitable way.

If you wish to include images in the manual, you should embed them as base64 encoded elements. You can include the base64 encoding of a file using the buttons in the ribbon tab of the Module Creator window

Note that if you wish to include HTML elements in the documentation (currently, the only supported elements are the <a> element to create links, the <img> element to include images, and the <p> element to provide alignment information for images), you need to place the whole contents of the documentation element in a CDATA section. For example:

/// <description>
/// <![CDATA[
/// ## Further information
/// The module picks the children of the selected node and drafts them on the parent node. For example, consider the tree
/// `((a,(b,(c,d))),e);`:
/// 
/// <p align="center">
/// <img height="300" src="data:image/svg+xml;base64,...">
/// </p>
///
/// If the LCA of `b`, `c` and `d` (highlighted in the tree) is selected as the subject of this module, then its two
/// direct children (`b` and `(c,d)`) are pruned off of it and grafted on its parent, so that they become siblings of
/// `a`:
///
/// <p align="center">
/// <img height="300" src="data:image/svg+xml;base64,...">
/// </p>
/// 
/// ]]>
/// </description>

Important note: to avoid issues with text being mistaken for HTML code, there must be an empty line after any HTML code block. This line cannot even contain a single whitespace ( ). For example, in the code above, the line below the first </p> is empty and does not even contain the single whitespace after the ///.

⚠️ **GitHub.com Fallback** ⚠️