at*mineer
Follow us on Twitter
productsreviewscompareskinsuserguidefaqdownloadchangeslogin

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:

  • UserVariables.xml
  • DocXmlTemplates.xml
  • DoxygenTemplates.xml
  • File.xml
  • Namespace.xml
  • Exceptions.xml
  • Typedefs.xml
  • Enums.xml
  • Variables.xml
  • Classes.xml
  • Interfaces.xml
  • Methods.xml
  • MethodReturns.xml
  • Parameters.xml
  • TypeParameters.xml
  • WordExpansions.xml
  • Replacements.xml (replacements/acronyms)
  • NonSplittable.xml (non-splittable terms)
  • Prefixes.xml

A similar set of files can be used to override the settings in prefs.xml:

  • DocComment.xml
  • DocXml.xml
  • Doxygen.xml
  • Format.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:


<UserVariables> section

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)

%company%Your company's name.
%copyright%Your company's copyright declaration.
%useremail%Your contact email address.
%property-getonly%Description prefix for a read-only property.
%property-setonly%Description prefix for a write-only property.
%property-getset%Description prefix for a read/write property.
%indexer-getonly%Description prefix for a read-only indexer.
%indexer-setonly%Description prefix for a write-only indexer.
%indexer-getset%Description prefix for a read/write indexer.
%param-optional%Text prefixed to optional parameter descriptions.
%true%The text used for documenting 'true' boolean values e.g. 'true', 'TRUE', '<c>true<c>'.
%false%The text used for documenting 'false' boolean values.
%null%The text used for documenting null pointer/reference values.
%nullptr%The text used for documenting nullptr pointer values.
%stylecop%true/false to enable or disable stylecop compatible descriptions. Note that this is overridden by the value set in the main preferences.
%docBasesWithSee%set to true to document the primary base class (only) with a <see cref='...'>>
%docPrimaryBaseWithSee%set to true to document ALL base classes and/or interfaces with <see cref='...'>
%docOverridesWithSee%set to true to document overrides (where possible) with <see cref='...'>. (Note that you also need to disable duplication of base documentation in the preferences to allow these rules to be applied for overrides).
%docUseAttributes%set to true to use Attribute meta-data when generating documentation.
%alwaysAddInForParams%set to true to always add [in] for parameters that are not [out] or [in,out]. This setting is ignored if %suppressInOut%=true.
%suppressInOut%set to true to suppress the addition of [in], [out], [in,out] to paramter descriptions. Note that this overrides %alwaysAddInForParams%.

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:

%user%User's login name (or the overridden name provided in the Atomineer Options)
%time%The current time, in the format specified in the Atomineer Options
%date%The current date, in the format specified in the Atomineer Options
%day%The current day, e.g. "Tuesday"
%dayofmonth%The current day of the month as a number, e.g. "2"
%month%The current month, e.g. "June"
%monthofyear%The current month as a number, e.g. "6"
%year%The current year, e.g. "2009"
%pathname%Full pathname of the current file, e.g. "C:\MyProject\Source\MenuHandlers\FileOpen.cpp"
%projectpathname%Pathname of the current file relative to the project folder (or a full pathname if it's outside the project root), e.g. "Source\MenuHandlers\FileOpen.cpp"
%projectfolder%Project folder containing the current file, e.g. "Source\MenuHandlers"
%folder%Leafname of the folder containing the current file, e.g. "MenuHandlers"
%leafname%Leafname of the current file (not including the file extension) e.g. "FileOpen"
%extension%File extension of the current file (including the ".") e.g. ".cpp"
%project%Name of the Project containing the current file
%containingclass%Name of the parent class, struct, interface or enum containing the cursor (or the file leafname if intellisense information is unavailable). Note that you can use %containingClass:Leaf% if you don't want the fully qualified name.
%namespace%The namespace portion of containingClass.
%assemblyname%Assembly name for the Project containing the current file
%assemblyversion%Assembly version
%assemblyfileversion%Assembly file version
%assemblytitle%Assembly title
%assemblydesc%Assembly description
%assemblycompany%Assembly company name
%assemblycopyright%Assembly copyright
%assemblytrademark%Assembly trademark

Note that if you create a variable with the same name as a global, the global will be replaced by your definition.
The type-specific variables (e.g. %retType%) cannot be overridden.


Templates section

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:

  • file
  • namespace
  • enum, bitfield
  • struct, class, interface
  • method, property, indexer, delegate, constructor, destructor (c++), finaliser (c#), operator, eventhandler, eventsender

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.

Custom Elements

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)

    <design-document/>

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

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:

    <remarks>%user%, %date%</remarks>

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:

access="[AccessLevels]"If specified, this attribute overrides the global 'Restrict documentation by access level' preference, allowing finer-grained control over what is or is not documented based on its access levels. For example to only allow methods to be documented if they are public or internal, modify the <method> element like this:
	    <method access="public,internal">
		    ...
	    </method>
	

You can also use access="all" to override the default to use an unrestricted accesslevel, or access="none" to totally disable documentation of that type of code element. If an access level is applied to a property, then it will affect the accessors independently (i.e. for { public get; private set; } with private access suppressed, Atomineer will document the property as if it only has a 'get'.

Special attributes for code-element entries

Special attributes can be added to control the output of each documentation entry type individually:

_tagName="name"This is used to change the name of the element tag that is output by atomineer. For example, Atomineer generates 'exception' entries, but some people prefer 'throws'. Adding _tagName="throws" to the template makes Atomineer output the entry with the preferred name.
_aliases="name1,name2,..."This attribute contains a comma-separated list of aliases for the tag - for example, "exception,exceptions,throw,throws". When parsing legacy comments, Atomineer will treat all of these names as aliases for the given entry type.
_style="multiline"For standalone entries such as 'summary' and 'returns', by Atomineer can format the text as a single-line entry if possible - this is controlled by the global option 'Keep short entries as a single line'. However, if you wish to contro this behaviour on a per-entry basis, you can add this attribute to force the entry to always use the multi-line format. This attribute would normally be applied to all 'summary' templates, giving more space by default to the summary, but allowing 'returns' to remain in the compact single line style.
_wordwrap="true"true = (default) If the word wrapping preference is enabled, word-wrap the text in this element.
false = Ignore the preference and disable word-wrap in this element.
_punctuate="true"true = (default) Add punctuation at the end of the element if it does not appear to end in punctuation.
false = Do not add any additional punctuation.
_verbatim="true"true = Copy the text from this element verbatim (no word wrap, no punctuation, no header on each line, etc)
false = (default) Format the text from this element, using line headers and word wrap as configured.
_optional="false"true = This entry is "legal", and should be formatted to the given position in the final documentation comment, but should not be added by Atomineer if it is missing.
false = (default) This entry should be added by Atomineer if it is not present.

This attribute can also use a conditional expression of the form
'variable == value1,value2,value3' or
'variable != value1,value2,value3'.
These expressions compare the contents of the given variable with the comma-separated list of values, and return true (==) or false (!=) if there is a match. Note that the values to match can use the # wild-card in the same manner as <If> commands in the auto-doc rules.

For example, to suppress generation of an entry on methods that are overrides or static, use _optional="specialType == override,static"
...or to suppress generation of an entry for Test methods, you could use _optional="methodName == #Test"
_copyFromBase="n"If you use the Atomineer option to copy base class documentation to derived class methods, entries in the base class will (by default) be copied to the derived class unless there is a matching entry already present. However, in some circumstances you may wish the derived class to not inherit the base documentation for that entry (usually these are rare cases where you end up with both a generated entry and one duplicated from the base class). In this case, add _copyFromBase="n" to your template's entry to suppress the duplication of the entry from base class documentation.
_blankEntry="text"In the case of auto-generated entries such as param and exception, the standard is to have no entries if there are no params/exceptions to document. However, some companies require that an entry is retained, as in <param>None</param> If you specify a _blankEntry, this text will be used to create an entry in these circumstances.

For example:

    <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:

C#:Visual Studio doesn't recognise task comments that directly follow an XML start tag, so you must place the TODO on a blank line:
    <remarks>
	    TODO: Don't forget to fill in the remarks!
    </remarks>
C++:Visual Studio ignores task comments inside DocXml /// blocks. You must use the _verbatim="true" tag to emit a normal comment into the middle of the documentation block. Note that the indentation used in your template XML is significant, so you must set the indentation of the element's text carefully.
    <remarks _verbatim="true">
// TODO: Don't forget to fill in the remarks!
    </remarks>

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:

  1. If this template includes any embedded XML elements, it will be treated as a regular Documentation XML comment, and will thus take on the separators and other style configured for your comments.
  2. If there are no embedded XML elements, this template is treated as a block of freeform text - WYSIWYG.

In both cases, you can insert any of the global variables (in the table above) or the following special file-header variables:

%fileDesc%Description of this file as generated by the <File> autodoc rules (see below).

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 '&lt;' and '&gt;' 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 &lt; and &gt; 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)

    &lt;file&gt;
        // &lt;copyright file="%leafname%%extension%" company="%company%"&gt;
        // Copyright (c) %year% All Rights Reserved
        // &lt;/copyright&gt;
        // &lt;author&gt;%user%&lt;/author&gt;
        // &lt;email&gt;%useremail%&lt;/email&gt;
        // &lt;date&gt;%date%&lt;/date&gt;
        // &lt;summary&gt;%fileDescription%&lt;/summary&gt;
    &lt;/file&gt;

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:

  • _separators="false". By default, Atomineer will use your configured Atomineer comment syle (separators) for the file comment. For full control of the text that is inserted, this can be disabled so that the text can be treated verbatim.
  • _filetypes=".h.hpp": Target a template to specific set of file extensions, so you can use a different header style in .h and .cpp files, for example. The first template that matches the filetype will be used, so this must precede any file template that doesn't specify any specific filetypes.
  • _addfooter="true" in a file hader will instruct Atomineer to automatically add the file footer as well. This is handy if you use a paired header/footer (such as an #ifdef...#endif in a header file)

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.


Conversions section

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:

  1. To convert between different block format "skins", set the Alt-Separator, Alt-LineHeader and Alt-SeparatorB preferences in your Prefs.xml so that Atomineer knows what the 'old' comment format looks like. (See the User Manual for details)
  2. Set your Doxygen or DocXML templates up to indicate the 'legal' entries in your new comment format, and how they should be ordered within the new comment block. Any entries that have the same tag in both old and new formats (e.g. param -> param) will be automatically 'converted' (reformatted in the new style). Any entries that are not considered 'legal' by Atomineer will be marked as 'deleted' with a ### prefix.
  3. Common Doxygen/DocXml markup is automatically converted. e.g.
            \c ClassName         ->  <see cref="ClassName"/>
            \code ... \endcode   ->  <code> ... </code>
  4. Where an old entry should be removed entirely, add an entry like this within this <Conversions> section:
            <ingroup convertTo=""/>            - delete all '\ingroup' entries
  5. Where an old entry needs to be renamed, add an entry like this:
            <author convertTo="programmer"/>   - convert all '<author>' entries to '@programmer'
  6. A special pair of commands can be used to convert simple plain-text lists into a set of tags, e.g.
       To convert:
    		@references
    			- \c MyClass
    			- \c BaseClass
    
       into a set of separate entries, you can use two forms:
    		<references convertEachLineTo="seealso cref" stripPrefix="-" /> will produce:		   
    			<seealso cref='MyClass'/>
    			<seealso cref='BaseClass'/>
    
    		<references convertEachLineTo="seealso" stripPrefix="- \c" /> will produce:
    			<seealso>MyClass</seealso>
    			<seealso>BaseClass</seealso>

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:

<If> command

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.


<IfNot> command

These work exactly the same way as <If> commands, but the logic is reversed - they only execute if all conditions evaluate to false.


<Set> command

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" />

<Execute> command

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.

<Execute rules="Variables"/>

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:

%ip%Insertion Point. The place where the cursor will be left after the comment is inserted. Use only one %ip% in any doc comment.
%match%For wildcard matches, the %match% command inserts the text that matched the wildcard. (In cases involving two wildcards, the variables %match1% and %match2% are used).
%???%Depending on the context, more variables will exist. In most cases "name" will return the full name of the code element being documented, and "sName" will return it in sentence form (with spaces between words, and abbreviated words expanded to their full name), but some contexts will provide much more information - For example, Methods provide %name%, %sname%, %retType%, %numArgs%, %argName1%, %argType1% ...

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:

(no suffix)Use the text verbatim
- DivideByZeroException
:SentenceInsert spaces between words, retaining existing capitalisation
- Divide By Zero Exception
Conversion to sentence form also expands any abbreviated words,
e.g. InfoMgr -> Information Manager
:FirstWordThe first word of the text
- Divide
:LastWordThe last word of the text
- Exception
:StripFirstWordEverything except the first word
- ByZeroException
:StripLastWordEverything except the last word
- DivideByZero
:LCaselowercase the text
- dividebyzeroexception
:UCaseuppercase the text
- DIVIDEBYZEROEXCEPTION
:WCaseUppercase the first letter of each word in a (space-separated) sentence
- This Is A Sentence
:SCasesentence-case the text (uppercase the first character, lowercase the rest - usually used on a sentence)
- This is a sentence
:Camelcamel-case a multi-word symbol (lowercase the first character of the first word, uppercase the the first character of the remaining words - usually used on a name)
- thisIsASentence
:Pascalpascal-case a multi-word symbol (uppercase the the first character of each word in the symbol - usually used on a name)
- ThisIsASentence
:Pluralattempts to pluralise a word. This will give results like:
"square -> squares, box -> boxes, party -> parties, goose -> gooses"
- DivideByZeroExceptions
:LeafThe 'leafname' in text assuming that it is a filename or a fully qualified type name. e.g. 'System.Exception' would return only 'Exception'.
:StripGenFor generic/template types such as List<int> this returns the main type without its type-params, i.e. 'List'

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:

  • :Plural command can be used to attempt to pluralise a word as it is expanded. e.g. "Box" -> "Boxes"
  • Any text that has the word "a" in it is processed to replace the "a" with "an" or "the", so it is generally better to use 'a' in preference to 'an' or 'the' in your rule description text. Typical results of this are:
        "Report a warning"
        "Report an error"
        "Report the warnings"
        "Report the errors"

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:

%name%The name of the item being documented (e.g. 'm_SomeVariable', 'some_variable')
%sName%The name of the item being documented, converted to a 'sentence' form (words separated by spaces. Anything that looks like a common prefix (e.g. 'm_') will be removed. e.g. 'some variable')
%sNameRaw%As %sName%, but without any prefix removal (e.g. 'm some variable').

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 File header comments (%fileDescription%)
  • for Namespace comments
  • for Interfaces
  • for any Exceptions thrown in a method
  • for any Generic Type Parameters in a class or method

For these sections, no additional variables are available.


<TypeParameters>

Rules used to generate the description for generic/template type parameters. The following special variables can be used in these sections:

%isOut%"y" or "n", indicating if the type parameter is covariant ('out').
%isIn%"y" or "n", indicating if the type parameter is contravariant ('in').

<Enums>

Rules used to generate the description for enumerated types. The following special variables can be used in this section:

%specialType%The type of the enum (enum, bitfield)

<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:

%type%The type of the variable (const int*)
%typeBase%The type of the variable, not including any modifiers (int)
%index%The 1-based index of the variable within the method's variable list
%word1%The first word of the variable (often used for prefixes, e.g. m_, lpsz, etc)
%coreName%The name with the first word removed (to allow processing of prefixed names)
%isPointer%"y" or "n", indicating if the variable type includes a "*" or "^"
%isReference%"y" or "n", indicating if the parameter type includes an "&" or "ref"

In addition, the following variables are available only for the Variables section:

%isEvent%"y" or "n", indicating if the variable is an event declaration

In addition, the following variables are available only for the Parameters section:

%isOut%"y" or "n", indicating the parameter type includes an "out"
%isOptional%"y" or "n", indicating if the parameter is optional
%methodName%The name of the method for which this is a parameter
%numArgs%The total number of arguments for the method


<Classes>

Rules used to generate the description for classes and structs. The following special variables can be used in this section:

%numBases%The number of base classes/interfaces this class imherits from/implements
%baseNameX%Base class/interface name, where X is the 1-based index of the base (e.g. baseName1, baseName2)
%isStatic%'y' or 'n', indicating if this class is static
%isPartial%'y' or 'n', indicating if this class is partial
%isSealed%'y' or 'n', indicating if this class is sealed
%isAbstract%'y' or 'n', indicating if this class is abstract
%isGeneric%'y' or 'n', indicating if this class is generic
%isTemplate%'y' or 'n', indicating if this class is a template


<Methods>

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:

%methodType%The type of the method (one of: method, property, indexer, delegate, eventhandler)
%methodName%(alias for %name%) The name of the method
%rawMethodName%The name of the method, including any generic type specifiers
%specialType%Extra info on the method: normal, static, inline, abstract, virtual, override
%retType%The return type for this method (const int*)
%retTypeBase%The core return type for this method, without modifiers (int)
%numWordsInName%The number of words detected in %name%
%numArgs%The number of arguments for this method
%argTypeX%Argument type, where X is the 1-based index of the argument (e.g. argType1, argType2)
%argTypeBaseX%Core argument type (without modifiers), where X is the 1-based index of the argument (e.g. argType1, argType2)
%argNameX%Argument name, where X is the 1-based index of the argument (e.g. argName1, argName2)
%getSet%(For methodType="property" or "indexer") the appropriate "Gets", "Sets", or "Gets or sets" text for this property/indexer
%eventSender%(For methodType="eventhandler" only) the sender of the event
%eventType%(For methodType="eventhandler" only) the type of the event
%attr-????%When a method has one or more meta-data Attributes assigned to it, each one generates an attr-???? variable, e.g. attr-conditional, attr-description. The value of the variable is the list of parameters to the attribute (e.g. the description text from a DescriptionAttribute). This is usually used with the defined='attr-description' syntax of the <If> command (see above) to detect when attributes are applied to a method, and add appropriate notes to the documentation.


<MethodReturns>

Rules used to generate the description for the return values for methods (VB functions). The following special variables can be used in this section:

%methodType%The type of the method (one of: method, property, indexer, delegate, eventhandler)
%type%The return type for the method (const int*)
%typeBase%The return type for the method, not including any modifiers (int)
%isPointer%"y" or "n", indicating if the variable type includes a "*" or "^"
%isReference%"y" or "n", indicating if the parameter type includes an "&" or "ref"


<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-2024 Atomineer. All Rights Reserved. Any trademarks reproduced in this text are the property of their respective owners - Contact us - Company Info