Atomineer Documentation Rules and Templates
Atomineer uses special XML templates that define the documentation entries that make up a comment and the order in which they appear. Each code element type (classes, methods, etc) has its own template so you can precisely control your documentation comments.
When there's no existing documentation entry for a code element, and Atomineer can't find any appropriate user-supplied documentation in the same class or base classes that it can make use of, it falls back to a simple but surprisingly powerful rule-based auto-generation system.
This system is entirely data-driven, from rules defined in a simple XML format, which are easily changed or augmented to suit your own coding style. (If you do modify your rules, or have any suggestions for improving the default rules, please consider emailing us your feedback so we can develop and improve the rules to cover different coding styles and situations better).
Rules.xml and custom files
The default Atomineer rules are provided in Rules.xml. This is installed into the Atomineer installation folder (which defaults to ...Documents\Visual Studio 2010\Addins\AtomineerUtils). While you could edit this file directly, a customisation system is provided to allow you to add to the default rules without losing your changes if you upgrade your Atomineer install (When you re-install Atomineer, the rules.xml will be overwritten, but any customisation files in the same folder or the folders in your configured 'rules path' will be preserved).
To add custom rules, open the Atomineer options and switch to the Advanced Customisation tab. For each section of the rules there is a button. Click the approriate button and that section of the rules will be exported to a separate custom XML file, and then opened in your editor. Note that the default rules are copied as an example to help you get started, but you should comment them out or delete them once you have added your own rules. This allows your rules to be executed followed by the default rules, thus adding your rules without losing any existing auto-doc functionality.
The full set of customisation files that can be added is:
A similar set of files can be used to override the settings in prefs.xml:
The file contents should be in exactly the same format as the corresponding section of rules.xml or prefs.xml. For example, you can augment the method documentation with a Methods.xml containing the following:
<?xml version="1.0" encoding="utf-8"?> <Methods> <If name="SelfDestruct" desc="Starts a 5-minute countdown before the computer explodes."/> </Methods>
If you create the customisation files using the buttons in the Advanced Customisation tab of the Atomineer Preferences dialog, then the relevant section of rules.xml is copied into the customisation file as an example. The idea is that you can use the default rules to guide you in the creation of new rules, and then you should delete the default rules out of your custom file. This will allow Atomineer to fall back to the default handling if none of your custom rules are triggered, and you will get the full benefit of any new rules added to the defaults when you upgrade to new versions of Atomineer.
To remove your customisations, simply delete the custom file.
By using the Rules Path in the Advanced Customisation tab, you can place your customisations in any folder(s) you wish, which allows them to be easily checked into your source control system for safekeeping, and for quick and easy deployment of customisations across your entire team.
Defining Rules and Templates
The rules fall into the following main groups, which are described in more detail below:
When generating documentation, Atomineer uses variables to pass information into your rules, to allow information to be stored during rule execution, and to control the output that Atomineer generates.
The User Variables section allows you to override the built in variables and add your own custom variables. These can be output in description text or used in subsequent variable definitions using the %varName% syntax (see below).
The default variables also allow you to control certain features or text-replacements in the rules and templates. These variables are as follows, and can contain other %variables% if required. (These can be edited in the Atomineer Options)
When documenting, each type being documented provides a set of useful variables. (For example, for a method, the method's name, return type, and parameter names and types are all supplied to the rules being executed). More details of the type-specific variables are listed later in this document.
In addition the following global variables are always provided internally by Atomineer:
Note that if you create a variable with the same name as a global, the global will be replaced
by your definition.
There are two templates sections: <DocXmlTemplates> (used for generating Documentation XML comments) and <DoxygenTemplates> (used for Doxygen and JavaDoc comments). These two sections are identical in operation, but there are slight differences to the actual format used to better support these different systems.
In both cases, the types that can be independently templated are:
If no template is supplied for a type, a default Atomineer layout will be used.
For example, here is a template for a Method, and the comment that it generates:
<method> <summary/> <_/> <remarks>%user%, %date%</remarks> <_/> <exception/> <_/> <param/> <_/> <returns/> </method> //////////////////////////////////////////////////////////////////////////////////////// /// <summary> An example method for documentation. </summary> /// /// <remarks> Jason, 12/3/2010. </remarks> /// /// <exception cref="ExampleCodeException"> Thrown when we feel like it. </exception> /// /// <param cref="firstParameter"> The first parameter. </param> /// <param cref="secondParameter"> The second parameter. </param> /// /// <returns> The result. </returns> ////////////////////////////////////////////////////////////////////////////////////////
When creating new comments, Atomineer builds content for the most common entries for you. The position of the following XML elements specifies where in the comment the entry (or block of entries, in the case of 'exception' and 'param') will be placed.
<summary/> <remarks/> <exception/> <param/> <returns/> <value/>
When updating an existing comment, Atomineer will re-order the entries it finds to match the order given in the template, ensuring consistency of commenting across your project(s). Any comment entries found that do not have a matching XML entry in the template will be deleted (placed at the bottom of the comment, marked with ###, and then removed the next time you execute Add Doc Comment).
The special element <_/> adds a blank line between entries (note that using this tag within an entry simply adds "<_>" to the output comment. Instead, use newlines within an entry to add newlines to the output comment - but note that these may still be removed by the word wrap feature. Any indentation in your template will also be used, so you may have to remove unwanted indentation to achieve the desired result). Note that multiple blank lines will be merged, and any leading/trailing blanks (on the entire block) will be stripped, regardless of what is in the template.
The XML elements in your template are not limited to the standard ones that Atomineer knows. You can add any element you like to add a custom entry. For example, you could add an <author> entry, or a <design-document> element. Atomineer will then support these custom tags. (If you are generating external documentation with a tool such as SandCastle or Doxygen, you will need to configure your documentation generator to handle these additional entries correctly)
Any element containing attributes (other than the special ones listed below) or text content will simply be copied into the documentation comment, allowing you to add custom tags or override the output of the auto-generated text provided by Atomineer with fixed text.
<remarks> TODO - fill this in </remarks>
Variables (see below) can be included in your template using the %varName% syntax. For example, to create a fixed-text entry for 'remarks' that contains the author's name and the date, you can add an XML element like this:
In addition to internal Atomineer variables, the %varName% syntax can be used to expand OS environment variables. (Note that an Atomineer variable will take precedence over any environment variable of the same name)
Special attributes for code-element templates
The following attributes can be added to the main template xml element to control how this type of code element is documented:
Special attributes for code-element entries
Special attributes can be added to control the output of each documentation entry type individually:
<method> ... <remarks _punctuate="false" _wordwrap="false">%user%, %date%</remarks> ... </method>
Adding "TODO" items to the Visual Studio Task List window
You can add TODO, HACK, UNDONE entries to be displayed automatically in the Visual Studio Task Window. However, there are some limitations:
More Template Entry examples
<summary> Place the summary first, using Atomineer-generated content <remarks> No comment </remarks> Place remarks next, containing the text "No comment" <_/> Add a blank line <info author="%user%"/> Add custom entry: <info author="Jason Williams"/> <author> %user% </author> Add custom entry: <author> Jason Williams </author>
File Header and Footer Templates
The <file>, <filefooter> (C#, C++, C) and <file-vb>, <filefooter-vb> (Visual Basic) templates are different from regular comment blocks because you aren't documenting a code element. Atomineer offers two options:
In both cases, you can insert any of the global variables (in the table above) or the following special file-header variables:
Below are examples of different styles of file comment that you may find useful:
Default plain-text Atomineer header (for C#, C++, C)
<file> // file: %projectpathname% // // summary: %fileDescription% </file>
Default plain-text Atomineer header (for Visual Basic)
<file-vb _separators="false"> '--------------------------------------------------------------------------------------------------- ' file: %projectpathname% ' ' summary: %fileDescription% '--------------------------------------------------------------------------------------------------- </file-vb>
Free-form text example. This template simply contains the verbatim text you want in the final comment, with %variables% as needed. If you wish to include XML tags in this style of comment you must use '<' and '>' to represent the < and > characters.
<file> // project: %project% // file: %projectpathname% // // summary: %fileDescription% // // %copyright% // // Date Developer Change // %date% %user% Created </file>
StyleCop-compatible Xml-based file header. Note that this uses < and > so that it will be treated as plain text rather than XML (You will also need to set up the %useremail% user-variable appropriately in the UserVariables section to support this example)
<file> // <copyright file="%leafname%%extension%" company="%company%"> // Copyright (c) %year% All Rights Reserved // </copyright> // <author>%user%</author> // <email>%useremail%</email> // <date>%date%</date> // <summary>%fileDescription%</summary> </file>
XML comment example. If you include one or more XML elements in the comment, Atomineer treats the template as a normal XML template.
<file> <prototype>%projectpathname%</prototype> <_/> <summary/> </file>
Further control of file header/footer comments can be achieved using the following attributes:
Due to the number of options available, achieving the exact file header you want can sometimes be a bit tricky, so if you would like help, just email support with an example of the header text you wish to achieve, and we'll be happy to help you design the templates.
Atomineer is capable of converting between different comment styles/skins and also between DocXML, Doxygen, Qt QDoc and JavaDoc comment formats.
Note that at this time, the primary conversion process that is supported is Doxygen/JavaDoc to DocXML, simply because there has so far been no demand to convert DocXML the other way. However, basic conversions are already in place to convert from DocXml if required. Please email us if you encounter any markup that is not converted well, and where possible we will try to upgrade Atomineer to support your conversion needs
To convert between Doc Comment styles/formats, you may do any of the following:
AutoDoc section - Commands
Atomineer's automatically generated documentation is built by executing the rules in the <AutoDoc> section. This is broken into sub-sections for all the main documentation entries (classes, methods, parameters, returns, etc) plus an additional <WordExpansions> section that defines abbreviations and the text that they should be expanded into.
The rules for the appropriate entry type are executed as a script. There are a few very simple commands:
This command evaluates a set of conditions. If any condition is true, the command is executed. Each condition tests a variable using an XML attribute, where the name of the attribute is the variable to test, and the attribute value to test is a string to test against. The matches are case insensitive, and multiple tests on a single variable can be combined by using a comma as a logical 'or':
<If name="vehicleSpeed,carSpeed,carVelocity" .../>
Different variables can be tested simultaneously by using several attributes. These are combined in a logical 'and' operation. ie. the following only matches a method called 'GetIndex' that returns an 'int':
<If name="GetIndex" retType="int" .../>
A special wildcard '#' can be used to match any sequence of characters. It can be used in the following ways: #text, text#, te#xt, #text#. If a string with one wildcard is matched, then Atomineer sets the variable %match% to the matched text. If two wildcards are used, the matches are placed into %match1% and %match2%.
The <If> condition can also test if a variable is defined. This is useful for determining if an indexed argument or meta-data attribute is available for the current code element. As above, a comma-separated list of variables can be tested and the condition will evaluate true if one or more of them are defined:
<If defined="argName3"> desc="This method has a 3rd Argument"/> <If defined="attr-conditional"> desc="This method is marked Conditional"/> <If defined="attr-description,attr-information"> desc="This has a Description or Information attribute"/>
If a string is matched, Atomineer appends the text from the desc="" attribute (if present) to the output description. This text can include variables which will be expanded, for example:
<If name="#Width" desc="The width of the %containingClass%'s %match%." />
If the <If> command has child elements, these are then executed, so 'if's can be nested to make the rules more efficient or achieve 'and' logic.
<If containingClass="#Rectangle,#Triangle,#Circle"> <If name="#Area" desc="The area of the shape." /> </If>
Normally, when a match is made, Atomineer will exit the script and use the description that has been built. However, by setting the attribute continue="y", you can instruct Atomineer to continue executing commands. Any text you set in desc will be appended to allow several phrases to be concatenated to build a final output. For example, this:
<If isPointer="y" continue="y" desc="null if it fails, else "/> <If sName="Clone,Duplicate" desc="A copy of this object"/>
...will generate the description "null if it fails, else a copy of this object" for a method called Clone that returns a pointer type, or just "A copy of this object" if the method returns a reference type. Note that Atomineer corrects the capitalisation to make the sentence structure correct.
Note that as these commands are executed in the order they are defined, you must place more-specific tests before less-specific ones, so that they match correctly.
These work exactly the same way as <If> commands, but the logic is reversed - they only execute if all conditions evaluate to false.
This command is unconditional - It is always executed, and simply sets one or more variables or the 'desc'. In most cases this is used for a 'catch-all' rule at the end of the rules script, as you usually set an unconditional value for 'desc' and processing then ends:
<If name="Equals"> <If numArgs="1" desc="Specific description for numArgs=1 case"/> <Set desc="Catch-all description for all other cases"/> </If>
However, it can also be used to create and alter internal variables, to change the outputs of following rules. In this case you need to use the continue="y" attribute so that rules processing continues after the Set command, as well as setting any variables needed. For example, the following sets the isOptional variable to 'y':
<If type="_optional #"> <Set isOptional="y" continue="y" /> </If>
The text within the Set attributes can also use any %variables% and the processing commands that can be embedded within them:
<Set upperName="%name:UCase%" continue="y" />
This acts like a subroutine call (or a #include) - it executes the given AutoDoc section and (if it doesn't return a description) continues execution at the command following the Execute.
Special 'abortComment' option
Atomineer can optionally only apply comments to code elements with given access levels. This is usually used to stop documentation being generated for private members. A special feature allows you to extend this 'do not document' handling to any specific code element. This is done simply by adding an attribute to an If, IfNot or Set condition:
<If access="private" abortComment="yes"/>
If this attribute is hit while processing, AddDocComment exits immediately without inserting a comment at all.
AutoDoc section - Using Variables
Variables may be used as tests in If commands by using the varName="test" attributes described above.
Variables may also be embedded in the desc="" text to insert special text into the output. Each variable is delimited by % characters (use %% to insert a literal % symbol). Any variable (except %ip%) can be used as many times as you like within a description.
The following variables are defined:
Variables used to insert text can have additional processing commands applied to that text. Each command is of the form ":command", and you can append as many commands as you like. e.g. "%match:Sentence:StripLastWord:SCase:Plural%" would have the effect of converting the name "DivideByZeroException" into the text "Divide by zeroes".
The available commands are:
Most of these commands are of little use on their own, but once combined with Sentence, (e.g. :Sentence:SCase or :Sentence:LCase) can produce much more useful or readable text output.
Special handling for better quality output
The following special handling is provided to improve the quality of autodoc output. These methods use heuristics to detect and correct the English, which do not always succeed, but do improve the output text in the majority of cases:
AutoDoc section - Documenting specific Code Elements
Various types of code elements (e.g. classes, exceptions, methods) require different approaches for documenting them. The AutoDoc section is thus divided into a number of type-specific sections, which are applied as appropriate to the item being documented. These are described below.
The global variables (listed above) and any User variables you have set can be used within these rules. In addition, the following variables are always set for each code element being documented:
In addition to the rules described above, each of these sections can add an optional prefix or suffix to the generated description text. These are set as attributes on the section, e.g.
<Exceptions prefix="Thrown when " suffix="."> ... </Exceptions>
The special-cases for the various code elements that can be documented are handled in a number of sub-sections of the AutoDoc section, and are described in detail below:
<File>, <Namespace>, <Interfaces>, <Exceptions>
Rules used to generate the description used in (respectively):
For these sections, no additional variables are available.
Rules used to generate the description for generic/template type parameters. The following special variables can be used in these sections:
Rules used to generate the description for enumerated types. The following special variables can be used in this section:
<Typedefs>, <Variables>, <Parameters>
Rules used to generate the description for parameters, variables and C++/C typedefs. (Note: The Execute Command is used to 'include' (duplicate) the Variables rules into both the Typedefs and Parameters sections). The following special variables can be used in these sections:
In addition, the following variables are available only for the Variables section:
In addition, the following variables are available only for the Parameters section:
Rules used to generate the description for classes and structs. The following special variables can be used in this section:
Rules used to generate the description for methods (including VB subs and functions), constructors, destructors, finalisers, properties, indexers, delegates and event handlers. The following special variables can be used in this section:
Rules used to generate the description for the return values for methods (VB functions). The following special variables can be used in this section:
<WordExpansions> and <Prefixes>
This is a special set of rules that are executed to detect and expand abbreviations, and remove prefixes. They are called for each word in turn in a generated description in order to allow abbreviations to be expanded. The 'desc' that they generate should usually be given in lowercase to create tidy results. For example:
<If name="ack" desc="acknowledge"/> <If name="fg,fore" desc="foreground"/>
To delete unwanted words (luch as library naming prefixes) from documentation, simply replace the word with desc="-" to delete it from the final documentation. That is, a member like 'lpszUserName' might be documented as 'the lpsz user name'. By removing the prefix 'lpsz', this can be cleaned up to 'the user name'.
The difference between the handling of the WordExpansions and Prefixes sections is that for Prefixes, only the first word of any symbol is processed; all words are processed for abbreviation expansions.
Copyright © 1996-2021 Atomineer. All Rights Reserved. Any trademarks reproduced in this text are the property of their respective owners - Contact us - Company Info