|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article explains the steps to generate MSDN-style documentation with Sandcastle, using NAnt, a scripting language. The scripts were developed to be started from a CruiseControl.NET project, but you can easily start them directly from NAnt as well. BackgroundSandcastle is Microsoft's new generator for MSDN-style documentation. The Sandcastle components gather information about your assemblies through Reflection, and combine this with the XML comments from your source code. The output is a set of HTML pages that you can optionally compile to CHM or HxS format. The NAnt scripts that I propose in this article are part of a CruiseControl.NET project, and closely follow the 12-step procedure to generate a CHM as elaborated in this official Sandcastle blog entry, and graphically represented in the image above. PreparationThe presented set of NAnt scripts will work under the following assumptions:
CodeProperties SectionTo keep the core of the buildscripts readable and maintainable, let's first create some properties for all fixed paths to directories, executables, and XSL transformations: <!-- Directories -->
<property name="sandcastle.dir"
value="F:\Program Files\Sandcastle" />
<property name="sandcastle.workingdir"
value="${projects.dir}\${CCNetProject}\SandcastleWorkingDir" />
<property name="sandcastle.output.dir"
value="${sandcastle.workingdir}\Output" />
<!-- Executables -->
<property name="sandcastle.mrefbuilder.exe"
value="${sandcastle.dir}\productiontools\mrefbuilder.exe" />
<property name="sandcastle.buildassembler.exe"
value="${sandcastle.dir}\productiontools\buildassembler.exe" />
<property name="sandcastle.xsltransform.exe"
value="${sandcastle.dir}\productiontools\xsltransform.exe" />
<!-- Transformations -->
<property name="sandcastle.addoverloads.xsl"
value="${sandcastle.dir}\ProductionTransforms\AddOverloads.xsl" />
<property name="sandcastle.addguidfilenames.xsl"
value="${sandcastle.dir}\ProductionTransforms\AddGuidFilenames.xsl" />
<property name="sandcastle.reflectiontomanifest.xsl"
value="${sandcastle.dir}\ProductionTransforms\ReflectionToManifest.xsl" />
<property name="sandcastle.reflectiontochmproject.xsl"
value="${sandcastle.dir}\ProductionTransforms\ReflectionToChmProject.xsl" />
<property name="sandcastle.reflectiontochmcontents.xsl"
value="${sandcastle.dir}\ProductionTransforms\ReflectionToChmContents.xsl" />
<property name="sandcastle.reflectiontochmindex.xsl"
value="${sandcastle.dir}\ProductionTransforms\ReflectionToChmIndex.xsl" />
<!-- Help Compiler -->
<property name="hhc.exe" overwrite="false"
value="F:\Program Files\HTML Help Workshop\hhc.exe" />
Create an Empty Working DirectoryThe first task in the NAnt Project is the creation of an empty working directory: <!-- Create or Cleanup Working Directory -->
<mkdir dir="${sandcastle.workingdir}"
if="${not directory::exists(sandcastle.workingdir)}" />
<delete>
<fileset basedir="${sandcastle.workingdir}">
<include name="**\*" />
</fileset>
</delete>
Prepare the Input for the BuildAssemblerThe Sandcastle component that creates the actual HTML documentation is the so-called BuildAssembler. It takes three input files:
The following steps create these files: Create the Configuration FileThis NAnt-task copies the original sandcastle.config file to the working directory. The relative paths in the original file are substituted by fixed paths, and we replace the built-in reference to a comments.xml file with a reference to the folder containing the XML documentation of our own assemblies: <!-- Copy configuration file, and hard code references -->
<copy file="${sandcastle.dir}/Presentation/Configuration/Sandcastle.config"
tofile="${sandcastle.workingdir}/Sandcastle.config">
<filterchain>
<replacestring from=""..\..\" to=""${sandcastle.dir}\" />
<replacestring from=""..\" to=""${sandcastle.dir}\Examples\" />
<replacestring from=""comments.xml" to=""${documentation.dir}\*.xml" />
</filterchain>
</copy>
Create the Initial Reflection FileMRefBuilder is one of the core Sandcastle console applications. It uses reflection to create an XML file that describes the inner structure of a set of assemblies. Its complete command line contains:
<!-- Run MRefBuilder (introspection on assemblies) to create basic Reflection XML -->
<exec program="${sandcastle.mrefbuilder.exe}" workingdir="${sandcastle.workingdir}">
<arg value="${bin.intern.dir}/*.dll" />
<arg value="${bin.intern.dir}/*.exe" />
<arg value="/out:reflection.org1.xml" />
<arg value="/dep:${bin.extern.dir}\*.dll" />
</exec>
The file that was generated by MRefBuilder -reflection.org- contains two types of XML elements:
Create the Final Reflection.xml FileThese tasks create the final Reflection.xml file, containing all the necessary information, but no presentation at all. Using Sandcastle's XSLTransform tool, we apply two XSL transformations on the reflection.org file:
It is possible to apply the two transformations in one step, but I've split them to easily verify the results: <!-- Create final Reflection XML -->
<!-- Regroup overloads -->
<exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}">
<arg value="reflection.org1.xml" />
<arg value="/xsl:"${sandcastle.addoverloads.xsl}"" />
<arg value="/out:reflection.org2.xml" />
</exec>
<!-- Create filenames for html documents -->
<exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}">
<arg value="reflection.org2.xml" />
<arg value="/xsl:"${sandcastle.addguidfilenames.xsl}"" />
<arg value="/out:reflection.xml" />
</exec>
If you want to expose this directory to the end-users of your application, then you would probably not use GUIDs as file name. I suggest to create your own transformation as an alternative for addguidfilenames.xsl. Create the ManifestThe so-called Manifest is again an XML file. It's a list of Topic entries, one for each <!-- Create Manifest (list of Topics) -->
<exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}">
<arg value="/xsl:"${sandcastle.reflectiontomanifest.xsl}"" />
<arg value="reflection.xml" />
<arg value="/out:manifest.xml" />
</exec>
Generate the HTML DocumentationPrepare the Output EnvironmentThe output directory has four subfolders. The BuildAssembler tool will generate its documentation in the html subfolder, the art, scripts, and styles folder are copied from the installation. They contain the necessary scripts, stylesheets, and images to give the documentation its MSDN look-and-feel. <!-- Create Output Environment -->
<mkdir dir="${sandcastle.output.dir}" />
<mkdir dir="${sandcastle.output.dir}/html" />
<copy todir="${sandcastle.output.dir}">
<fileset basedir="${sandcastle.dir}/Presentation">
<include name="art/*" />
<include name="scripts/*" />
<include name="styles/*" />
</fileset>
</copy>
Generate HTML DocumentationBuildAssembler is a generic console-application. It sends an XML document (reflection.xml) through a pipeline of components (like transformators, file creators, flow controllers, ...). The pipeline is constructed via the sandcastle.config, and is executed for each topic (i.e. each entry in the manifest.xml). BuildAssemblers command line consists of references to the manifest.xml file and sandcastle.config. The links to reflection.xml and the files containing the XML source code documentation are stored in the config file. <!-- Run BuildAssembler (create html topic files) -->
<exec program="${sandcastle.buildassembler.exe}" workingdir="${sandcastle.workingdir}" >
<arg value="manifest.xml" />
<arg value="/config:Sandcastle.config" />
</exec>
The output of this process is a directory with linked HTML-file for each topic. The files in the arts, scripts, and styles folders apply an MSDN look-and-feel. The documentation is fully functional, the rest of the process is optional. Generate the CHM FileThe next tasks transform the current Output directory to a single CHM file, through HTML Help Workshop. Create the Input for the HTML Help CompilerThe HTML Help compiler expects three input files:
The input files are all XML files that can be generated by applying an XSL transformation on reflection.xml: <!-- Create html Help project -->
<exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}">
<arg value="/xsl:"${sandcastle.reflectiontochmproject.xsl}"" />
<arg value="reflection.xml" />
<arg value="/out:"${sandcastle.output.dir}\test.hhp"" />
</exec>
<!-- Create html Help project Table Of Contents -->
<exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}" >
<arg value="/xsl:"${sandcastle.reflectiontochmcontents.xsl}"" />
<arg value="reflection.xml" />
<arg value="/arg:html=Output\html" />
<arg value="/out:"${sandcastle.output.dir}\test.hhc"" />
</exec>
<!-- Create html Help project Index -->
<exec program="${sandcastle.xsltransform.exe}" workingdir="${sandcastle.workingdir}" >
<arg value="/xsl:"${sandcastle.reflectiontochmindex.xsl}"" />
<arg value="reflection.xml" />
<arg value="/out:"${sandcastle.output.dir}\test.hhk"" />
</exec>
Compile the Help ProjectFinally, we compile the project to a CHM file through the Microsoft HTML Help Compiler (v1.4). I had to put the <!-- Generate CHM file -->
<exec program="${hhc.exe}"
commandline="test.hhp"
workingdir="${sandcastle.output.dir}"
failonerror="false"/>
History
About Diederik KrolsDiederik Krols is a .NET Architect and Trainer. As a Certified Scrum Master he embraces all tools that keep the development pace and quality as high as possible, and the overhead as low as possible. He has posted many articles on CruiseControl.NET and other components of the Open Source N*Stack (NAnt, NUnit, NCover, ...) on the Real Developer Network. His personal blog contains articles on Anti-Patterns.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||