This section describes how to use Dwell.Net CodeDoc to create
documentation and formatted source code for your C# class libraries.
These are the basic steps required to create a documentation with the help of CodeDoc:
- Add XML comments to your C# source code
(example). Note that CodeDoc does not require that
you use the
/doc
option in Visual Studio—CodeDoc reads the C# source files directly.
- Optionally, write additional documentation topics
in HTML (example, with HTML source, opens in a
new window), or any document type that can display in a browser (e.g. Microsoft® Word).
You can use CodeDoc's CSS styles (defined in "_CodeDoc.css"), or your own.
- Create a CodeDoc XML project file
(example) that describes the structure of your
documentation (e.g. table of contents and index entries) and which contains other information
CodeDoc needs to generate your documentation set.
- Run the CodeDoc.exe console application. This will:
- Parse the XML comments from your C# source files
(example) and generate one documentation
topic for each C# XML comment
(example).
- Optionally, if you want to publish your source code, C# will process your C# source
files again, this time generating one formatted source code HTML file for each source
file. In this case, your XML comments become embedded "documentation topics"
(example, with HTML source, opens in a new
window).
- Create a "DocBrowser" (DHTML-based documentation browser/viewer) for your
documentation
(example, opens in a
new window). DocBrowsers include a table of contents and an index. DocBrowsers
can be viewed either online (on a Web site) or offline (on a hard disk)—though
in the latter case you need to pay attention to the "Mark of the Web" informaton in
the CodeDoc project file documentation.
The following sections explain these steps in detail.
CodeDoc parses C# source files and looks for
XML comments.
(Click here for a list of C# constructs that
can include XML comments.) This is a key difference between CodeDoc and Microsoft Visual
Studio's processing of XML source files: CodeDoc ignores constructs (classes, methods, etc.)
that don't have an XML comment.
The following is an example of a method documented using
markup elements supported by CodeDoc.
/// <summary>
/// Changes the thermostat settings. (Sample code.)
/// </summary>
///
/// <param name="desiredTemperature">The desired temperature in Fahrenheit degrees.</param>
///
/// <param name="airConditioning"><n>true</n> to turn on air conditioning, <n>false</n> to
/// turn it off.</param>
///
/// <returns>
/// <n>true</n> if the new settings are different than the previous settings.
/// </returns>
///
/// <remarks>
/// If <pr>airConditioning</pr> is set to <n>true</n>, the air conditioning system will
/// only run when the room temperature rises above <pr>desiredTemperature</pr>.
/// </remarks>
///
/// <example>
/// This example sets the thermostat to 72 degrees Fahrenheit. The current temperature
/// is checked using the <r>CurrentTemperature</r> property; if it's is above 72, air
/// conditioning is turned on.
/// <code>
/// ThermostatSample thermostat = new ThermostatSample("1.2.3.4");
/// if (thermostat.CurrentTemperature > 72)
/// thermostat.SetThermostat(72, true);
/// else
/// thermostat.SetThermostat(72, false);
/// </code>
/// </example>
///
/// <seealso cref="Home.ClimateControl.ThermostatSample" />
/// <seealso cref="CurrentTemperature" />
///
public bool SetThermostat(double desiredTemperature, bool airConditioning)
{
// real code goes here
return true;
}
|
Click here to
see the HTML documentation topic, generated by CodeDoc, corresponding to the example above.
The example above contains the following
outer elements—XML elements which must appear at the
outer level, not nested within other elements:
- <summary>: Provides a short
overview of the method—specifically, what a caller can expect from it.
- <param>: Documents each
parameter.
- <returns>: Explains what's
returned by the method.
- <remarks>: Contains
additional comments that may be helpful to the caller. This element can also be used
to include implementation notes that are only visible within documentation sets that
include internal text.
- <example>: An example of how the method is called.
- <seealso>: References to other topics. This
element can also be used to reference external Web sites.
The example above also contains the following
inner elements—XML elements which appear inside
outer elements:
- <r>: ("Reference.") Creates a
hyperlink to another topic.
- <n>: ("Non-linked reference.")
Formats text using a style that indicates an external (non-hyperlink) reference.
- <pr>: ("Parameter reference")
Formats a reference to a method parameter.
- <c>: A short in-line code
sample.
- <code>: A block of sample
code.
For more information on these XML markup elements, click the links above, or see
CodeDoc XML Markup Reference for full information about
all supported XML markup elements. In particular, here are a few XML markup elements not
demonstrated by the example above:
- <typeparam>:
Documents a type parameter of a template class.
- <value>:
Describes the value of a property.
- <exception>:
Documents an exception that may be thrown.
- <permission>:
Documents a permission that may be required.
- <s>: ("Short reference.") Creates
hyperlink to another topic, displaying a short form of the member name.
- <tpr>: ("Type parameter
reference.") Refers to a type parameter.
- <ar>: ("Ancestor reference.")
Creates a hyperlink to a topic that documents an ancestor of the current type.
- <para>: ("Paragraph.")
Designates a block of text as a paragraph.
- <list>: Formats a bulleted
list, a numbered list, or a two-column table.
CodeDoc automatically generates one documentation topic (an HTML file) for each C# comment
in the documentation set (in typical usage). However, you may have information to convey to
the readers of your documentation that doesn't fit the mold of XML comments. Examples:
- An introductory page (example).
- A user guide page (like the one you're reading now).
- File format documentation (example).
In these cases, CodeDoc allows you to supply additional documentation topics (Web pages).
CodeDoc allows you to define the overall structure of your table of contents
(see below), and you can create a fairly arbitrary page hierarchy
(tree) containing your pages. Note, however, that you can't insert additional pages within
subtrees generated by CodeDoc. For example, CodeDoc creates a subtree corresponding to the
members of each C# class—and you can't insert an additional topic into that subtree.
For each additional topic, you can specify one or more index entries which will appear
(along with other index entries generated automatically by CodeDoc) in the "Index" tab of the
DHTML-based documentation browser created by CodeDoc. For example, the page you're reading is
listed in the index of this documentation set as "CodeDoc User Guide" and "User Guide". You
can also make an index entry refer to a bookmark within a page.
Additional topics can be any type of file that can be displayed in a Web browser: HTML,
Microsoft® Word, Adobe® PDF, etc. However, keep the following in mind:
- If your page requires that users have specific software installed, then that
documentation page won't be viewable by users who don't have that software.
- If the page is HTML, you have a choice of many "flavors" of HTML. Be sure to test
with the browsers you intend to support. And, keep in mind that the HTML generated by
CodeDoc was designed for Microsoft Internet Explorer 6.0 and above, and may not work
on other browsers.
- If you'd like your documentation set to be viewable locally—i.e. on a user's
hard disk—Internet Explorer 6.0 requires that such pages include the
"Mark of
the Web" (since the CodeDoc frameset and supporting files also require the "Mark of
the Web"). For more information, see the CodeDoc project
file documentation.
If you write your additional topic pages in HTML, you're welcome to use CodeDoc's CSS style
sheet file, "_CodeDoc.css", which is included automatically in the
"pages" directory of the generated
documentation set. Click here for an example
of how to use "_CodeDoc.css" (opens in a new window). The advantage of using
"_CodeDoc.css" is that it's easy to create pages that follow the same style as the pages
generated by CodeDoc. A disadvantage is that "_CodeDoc.css" may change in future versions
(renamed).
For more information about adding additional documentation topics to your documentation
set, consult the following topics in the CodeDoc Project File
Reference, or see the example below:
CodeDoc is controlled by an XML file called the CodeDoc project file. In order to use
CodeDoc, you need to create a project file. The following project file is used to create the
"ThermostatSample" sample project included in the CodeDoc download.
Click here to view the
CodeDoc-generated documentation browser corresponding to this sample (opens in a new
window).
<CodeDoc xmlns="urn:schemas-dwell-net:codedoc:project-file">
<ExternalReferences>
<![CDATA[
Exception
List<>
]]>
</ExternalReferences>
<DeleteFilesInDirectory Path="Doc" />
<DeleteFilesInDirectory Path="Doc\Pages" />
<CreateDocBrowser
BasicFramesetFileName="BasicBrowser.htm"
FramesetFileName="Documentation.htm"
NodeId="TocRoot"
PagesRelativePath="Pages"
Path="Doc"
Title="ThermostatSample Class Library Documentation" />
<DocBrowserStaticPages NodeId="TocRoot">
<DocBrowserNode
NodeId="TocOverview"
Title="ThermostatSample Class Library API"
Path="Overview.htm">
</DocBrowserNode>
</DocBrowserStaticPages>
<ReadSource Path="ThermostatSample.cs" />
<WriteDocumentation Path="Doc\Pages">
<AddToDocBrowser NodeId="TocOverview" />
</WriteDocumentation>
<DocBrowserStaticPages NodeId="TocRoot">
<DocBrowserNode
NodeId="TocSource"
Title="ThermostatSample Class Library Source Code"
Path="SourceOverview.htm">
</DocBrowserNode>
</DocBrowserStaticPages>
<ClearSources/>
<ReadSource Path="ThermostatSample.cs" />
<WriteFormattedCode Path="Doc\Pages">
<AddToDocBrowser IndexLabelSuffix=" (Source Code)" NodeId="TocSource" />
<SourceFilesNode
Path="SourceFiles.htm"
Title="Source Code Files">
</SourceFilesNode>
</WriteFormattedCode>
</CodeDoc>
|
The CodeDoc project file example above also contains the following
XML elements. Note that the XML elements that are direct
children of <CodeDoc> are processed in the order they appear in the
file. (Other XML elements are essentially parameters.)
- <CodeDoc>: This is the root XML
element. It must be present in any CodeDoc project file, and must alway have the
namespace (xmlns) shown above.
- <ExternalReferences>:
Since the source code processed by CodeDoc (a single C# file,
ThermostatSample.cs, in this example)
contains the definition of a class (HomeDeviceException) that is based on a type
(Exception) that is not defined in this documentation set (Exception is a .NET
Framework type), and since HomeDeviceException has an XML comment, "Exception" must be
listed in <ExternalReferences>, or else CodeDoc would display a warning
about an unresolved reference to "Exception". (List<>, also listed in
<ExternalReferences>, is not used in ThermostatSample.cs, and is
included only for illustration purposes.) The "CDATA" construct is optional—it's
used so that angle brackets < and > (e.g. List<>)
don't have to be escaped as < and >, respectively.
- <DeleteFilesInDirectory>:
Later in the project file, the <CreateDocBrowser>,
<WriteDocumentation>, and <WriteFormattedCode> elements
specify that CodeDoc will automatically generate files within a directories named "Doc"
and "Doc\Pages". (These paths are relative to the directory containing the CodeDoc XML
project file.) The purpose of the <DeleteFilesInDirectory> element is
to delete any files that may have been created in the last run of CodeDoc. This
ensures that, if you run CodeDoc multiple times, changing source files between each
run, you won't end up with outdated "leftover" files in these directories.
<CreateDocBrowser>: Begins
generating the DHTML documentation browser/viewer, with the following
characteristics:
- The primary root frameset file will be named "Documentation.htm", and will be
placed in a directory named "Doc"—this path is relative to the directory
containing the CodeDoc XML project file. In other words, "Documentation.htm"
will be the file that the users open to view the documentation browser.
- The secondary root frameset file will be named "BasicBrowser.htm". This
file can be used by users of browsers that don't support all the DHTML features
required by "Documentation.htm". It's not as pretty, but it works.
- The title (in the browser title bar) of both root frameset files is
"ThermostatSample Class Library Documentation".
- Even a relatively small documentation set can result in many generated HTML
files. (Consider: one HTML page is generated for each C# comment, plus extras
for overrides.) CodeDoc gives you the option of putting these files in a
subdirectory separate from the root frameset files. In this example, these
files go in a "Pages" subdirectory of the "Doc" directory.
- The top level of the table of contents is assigned a node identifier of
"TocRoot". Node identifiers are a way of referring to a table of contents
entry from elsewhere in the project file (see below).
<DocBrowserStaticPages>,
<DocBrowserNode>: These elements
cause an additional documentation topic (i.e. in
addition to the pages generated automatically by CodeDoc) to be added to the bottom
of the table of contents. This pair of nodes occurs in two places:
- The additional documentation topic file is named "Overview.htm", and it will
appear in the table of contents with a title of "ThermostatSample Class
Library API". This table of contents entry is assigned a node identifier
(described above) of "TocOverview"—this node identifier is referred to
later in the project file.
- The additional documentation topic file is named "SourceOverview.htm", and it
will appear in the table of contents with a title of "ThermostatSample Class
Library Source Code". This table of contents entry is assigned a node
identifier of "TocSource". (This topic is a hand-authored overview of
source code files—CodeDoc-generated formatted source code files will
be generated under this table of contents entry, as shown below.)
The two additional documentation topic files are placed at the top level of the
table of contents, because both <DocBrowserStaticPages> elements
contain the attribute NodeId="TocRoot". (Unlike the NodeId attribute
on <CreateDocBrowser> and <DocBrowserNode>, this
NodeId attribute is a reference to a node identifier that appears
elsewhere in the project file.)
As an alternative to the approach taken in the example above, you can include
multiple <DocBrowserNode> elements within a single
<DocBrowserStaticPages> element.
- <ReadSource>: Causes CodeDoc to read
the C# source code file named Thermostat.cs
and process the XML comments within it. You can include multiple
<ReadSource> elements, and each element can specify either a single
source file or a directory tree which will be scanned for .cs files.
- <WriteDocumentation>: Generates
one documentation topic HTML file (plus a few extras, such as overload list topics)
for each member (class, method, etc.)
that has a C# comment. The list of C# source files that are processed is defined by
the previous <ReadSource> element(s) (since any preceding
<ClearSources> element)—in this case, only
Thermostat.cs. <AddToDocBrowser>
specifies that the table of contents entries generated by
<WriteDocumentation>—one entry per namespace, plus child entries for
types and grandchild entries for members of types—are added as children of the
table of contents entry that has a node identifier of "TocOverview".
- <ClearSources>: Tells CodeDoc to
unload from memory the source files specified by previous <ReadSource>
elements. This is typically necessary because <WriteDocumentation>
(above) and <WriteFormattedCode> (below) often filter the sources
differently: for example, <WriteDocumentation> is often used to produce
an external documentation set that excludes private and internal types, unit test code,
XML comment sections marked with internal="true" (see
CodeDoc XML Markup Reference), etc., while
<WriteFormattedCode> usually includes all source code. In the example
above, the second <ClearSources> and <ReadSource> may
not be necessary, but are shown to illustrate this typical pattern.
- <WriteFormattedCode>: Generates
one formatted source code HTML file (plus a few extras, such as overload list topics)
for each C# source file defined by
the previous <ReadSource> element(s) (since any preceding
<ClearSources> element)—in this case, again, only
Thermostat.cs. <AddToDocBrowser>
specifies that the table of contents entries generated by
<WriteDocumentation>—one entry per namespace, plus child entries for
types and grandchild entries for members of types—are added as children of the
table of contents entry that has a node identifier of "TocSource". Unlike
<WriteDocumentation>, which generates one page per XML comment,
<WriteFormattedCode> generates one page per source file, but the table of
contents still includes one entry per XML comment (pointing within the formatted source
code pages). <SourceFilesNode> specifies that CodeDoc should also generate one
table of contents entry per source file, under an
additional documentation topic named "SourceFiles.htm"
with title (in the table of contents) of "Source Code Files".
For more information on these CodeDoc XML project file elements, click the links above, or
see the CodeDoc Project File Reference for full information about
all supported elements. In particular, here are a few CodeDoc project file features not
demonstrated by the example above:
CodeDoc.exe is a console application—you execute it from a command prompt. (In
Windows® click Start, Run, type "cmd", click OK. Change
to the directory where you unzipped CodeDoc into, using "cd /d
directory-path", or add the directory containing CodeDoc to your PATH
environment variable, or include the full path to CodeDoc.exe when you run it.)
Before running CodeDoc, ensure you have the Microsoft .NET Framework 2.0 installed. To
do this, click Start, Run, type "%windir%\Microsoft.NET\Framework"
(no spaces), click OK. If you have a folder named v2.0.50727, you have
.NET Framework 2.0 (unless that folder only contains a few files, in which case it may have
been uninstalled). To install the .NET Framework 2.0, go to
Microsoft Update and click Custom to get
non-high-priority updates.
To run CodeDoc, simply provide the name of the CodeDoc XML project
file as the command-line parameter. For example, if you unzipped CodeDoc into C:\CodeDoc,
you can run CodeDoc on the ThermostatSample project file describe above, as follows:
C:\CodeDoc> codedoc Samples\ThermostatSample\CodeDoc.xml
Loading: ThermostatSample.cs
Enumerating topics to document
Converting XML to HTML
Writing 9 documentation topic(s)
Loading: ThermostatSample.cs
Enumerating topics to document
Converting XML to HTML
Writing 1 formatted source code file(s)
Writing TocRoot documentation browser
Done: 0 warning(s)
C:\CodeDoc>
|
This generates a CodeDoc documentation browser in
C:\CodeDoc\Samples\ThermostatSample\Doc; open Documentation.htm to
view the documentation.
(Click here to view it now,
in a new window).
When CodeDoc runs, it displays the names of source files it loads into memory, a count of
documentation topics generated, and other information, including warnings (one per line) and
a count of warnings generated.
CodeDoc returns one of the following exit codes, which can be tested within a batch file
using "if errorlevel":
| 0 |
Success—no warnings were displayed |
| 1 |
Success, but one or more warnings were displayed |
| 2 |
Failure |
If you like, you can generate and view documentation from within Microsoft Visual Studio.
If you do that, the warnings output from CodeDoc will be displayed in Visual Studio's Output
window, and you'll be able to double-click a warning to go directly to the source code line
containing the problem. To enable generating and viewing documentation from within Visual
Studio, do the following (for Visual Studio 2005):
- Click Tools, External Tools.
- Click Add, and enter the following:
- Title: Generate Documentation
- Command: full path to CodeDoc.exe
- Arguments: $(SolutionDir)CodeDoc.xml
- Click Add again, and enter the following:
- Title: View Documentation
- Command: C:\Program Files\Internet Explorer\iexplore.exe
- Arguments: $(SolutionDir)Doc\Documentation.htm
- Click OK.
These settings assume the following:
- For any Visual Studio solution you want to generate documentation for, you've put a
file named "CodeDoc.xml" (the CodeDoc XML project file) in the same directory as the
solution (.sln) file.
- Your "CodeDoc.xml" files specify "Doc" as the value of the "Path" attribute of
<CreateDocBrowser>,
<WriteDocumentation>, and
<WriteFormattedCode> elements
(if present).
- Microsoft Internet Explorer's
iexplore.exe file is in the location shown
above.
The directory containing CodeDoc.exe can be located anywhere on your computer. At a
minimum, CodeDoc requires the following support files:
- "CodeDocApi.dll", a .NET managed-code assembly which implements most of the
CodeDoc API used by CodeDoc.exe.
- "CodeDocRenderer.dll", a .NET managed-code assembly which implements the remainder of
the CodeDoc API used by CodeDoc.exe. (Specifically, this
DLL implements the default
topic renderer and
source file renderer.)
- The "SupportFiles" subdirectory, containing additional support files used by
CodeDoc.
The following is a partial list of the current limitations of CodeDoc. (There are undoubtedly
many other limitations that neglected to get documented here.)
- Only C# is currently supported.
- CodeDoc only works on C# code that successfully compiles using the C# compiler.
- Formatted code files don't include the dark red coloring for types.
[Conditional(...)] is allowed but ignored.
- The <include> C# XML comment tag is not supported.
- The cref attribute of the
<exception> C# XML comment
element supports the same syntax as the
<r> element. References like the
following are not supported:
- cref="C{T}"
- cref="C < T >"
- cref="T:C`1"
- Unsafe types (e.g. "char *") are not supported. You can include unsafe types in C# code
processed by CodeDoc as long as each declaration (e.g. classes and methods) containing the
types does not have an XML comment.
- Partial types are partially supported. Source code can include partial types, with the
following restriction: For each class, if the class is divided into N "partial class"
declarations, all but one will be ignored by CodeDoc, and only that one should have an XML
comment at the beginning. Assuming partial classes are only used for generated code that
doesn't include an XML comment on the generated class, this approach should work fine.
(See section 23 of the C# Language Specification 2.0 for more information about partial
types.)
- Extern aliases are not supported. (See section 25.4 of the C# Language Specification 2.0
for more information about extern aliases.)
- CodeDoc documents inherited members of classes (not structs, which don't support
inheritance, or interfaces, which conventionally don't documented inherited members).
However, CodeDoc only documents members it has XML documentation for; so, for example,
members of System.Object are not included in the member list.
- Two parameter types are considered equivalent for the purpose of overloading if they are
spelled identically. So, for example,
Foo(string), Foo(String),
and Foo(System.String) are all considered to be different signatures.
Another limitation is that the names of type parameters are considered part of the
signature. So, for example, Foo<T>(T value) and
Foo<U>(U value) are considered to be different signatures. To work
around these limitations, use consistent type spelling and type parameter naming for
methods.
In general, within "Syntax" sections of CodeDoc-generted documentation, what you see is
what you get. For example, if you declare a parameter as type "string", it will show up
in the documentation as "string", not "String" or "System.String". In some cases, this
characteristic of CodeDoc extends beyond "Syntax" sections, to topic titles and even the
names of generated HTML files. One specific case: you may want to avoid using namespace
aliases in explicit interface implementations. For example, it's fine to implement
IDisposable.Dispose like this:
void IDisposable.Dispose()
{
}
|
But, avoid implementing it like this:
namespace IDispAlias = System.IDisposable;
...
void IDispAlias.Dispose()
{
}
|
If you do, the CodeDoc-generated documentation for Dispose() will list the
member name as "IDispAlias.Dispose" instead of "IDisposable.Dispose".
- Using
#error (that isn't within #if false...#endif or equivalent)
will generate an error message from CodeDoc, similar to the message produced by the C#
compiler, except CodeDoc will halt further processing. (#error is used by
CodeDoc unit tests. This behavior is assumed to be acceptable since CodeDoc only attempts
to parse code that the C# compiler successfully compiles.)
- Lines may be terminated by a carriage return (U+000D), line feed (U+000A), or a carriage
return followed by a line feed. The other line terminators described in the C# Language
Specification 1.2 (section 2.3.1) are not supported.
- White space can be either the space character (U+0020) or the horizontal tab character
(U+0009). The other white space characters described in the C# Language Specification 1.2
(section 2.3.3) are not supported.
- The "@" character used as a prefix to allow keywords to be used as identifiers is not
supported (see section 2.4.2 of the C# Language Specification 1.2).
- Not really a limitation—more of a nice-to-have-feature: wouldn't it be cool if
formatted source code included hyperlinks within the code itself? For example, clicking on
a method name would navigate to that method's implementation, or to the documentation for
that method. That's would be tricky to implement because, to do it "properly", CodeDoc
would need to fully parse and "understand" all C# code, in order to figure out which
override of a given method you just clicked on. (Currently, CodeDoc only needs to
understand C# at the lexical level, to find XML comments, plus just enough C# structure to
parse C# declarations.) An alternative implementation would be to just search the source
code for known keywords, where the set of keywords is everything in CodeDoc's
index—much easier, but more opportunities for incorrect links. Anyway, a cool
feature to think about. In the meantime, the workaround is to type Alt+L (the shortcut
key to open the index) and type the name of method (or whatever) you want to navigate to.