Sandcastle, DocProject and creating custom topics

While looking into DocProject, I wanted to see how easy it would be to add custom topics into a project but didn’t get chance to do it in my original post.

One of the nice features of DocProject is that you can add your own code into the build process.  The file BuildProcess.cs has a number of event methods which are called at various points within the build process.  In the How To… there is a a guide to creating custom topics for the webpage, however I wanted to use my existing HTML pages within the help file. It would have been nice just to be able to select these from within the options menu – hint hint Dave.  I am going to create my own for now.

What I want to do, is take a folder and include it within a CHM/Help 1.0 fie.  For this there are two important concepts, one, everything needs to be included in the html folder. Second, the index for the help file is .hhc and .hhk which is loosely based on html file and uses and

  • tags for each entry.  For this you should really use a template for your HTML and add content based on that so all the pages look the same, but I’m just going to look at the core concept.

    Firstly, I created a directory structure in my solution which looks like below.

    • /Root Folder
      • /Custom Topics
        • /test
          • test.htm
          • HtmlPage2.htm
        • HTMLPage1.htm

    This is what I want to appear within my CHM file. However, it’s not as simple as it first seems. I included test.htm to be the default page for when a user clicks the Test namespace, as Test is a folder in the structure, it needs a related page.

    Firstly, I had to hook into the DocProject build process.  This is really nice as Dave has already provided the methods/events there for you, it was just finding where to place the call as when Sandcastle is creating its own files, it will override any changes you have made previously.  The method BeforeExecuteStep is called before every step in the build process, so I simply did a check to see if the I was before the step I was interested in:

    if (step.Name.Equals(“Compile Help 1.x”))
                    ProcessHelpCustomTopics(context, “Html”);

    Now a method is called just before the help file is about to be compiled, this method writes out some information to the trace and calls CustomTopics.Import.  Here, I simply copy all the content from Custom Topics into the html folder, keeping the correct folder structure (Method CopyAllFilesInSourceToTarget).  So now all the files are in the correct place, we need to tell the help compiler about them, now this is where it started to get tricky.

    There are two important files for the help structure, .hhc and .hhk.  Both look very similar but are different. The compiler looks at these files to work out which files to include, and where they should be in the hierarchy of the contents.  Firstly, I thought it would be simple to just create these files automatically based on the directory structure, hence why I wanted to keep the directory structure intact when I copied over the files.  Well, the problem is then you have no control over what order the files should appear in – that’s really not good so I had to come up with a not so great solution.  Ideally, it would be an option within the addin dialog where you could build a custom table of contents, but that would require changing the core code.  I have my own .hhc and .hhk files within Custom Topics which simply outline how the table contents should be for that particular folder. Then, the user has the power to say which files should be where and lay it out correctly. I then just merge the two files with the Sandcastle created files for the table of contents.  The contents of hhc file would for example look like this:

    <li><object type="text/sitemap"> <param name="Name" value="HTMLPage1"> <param name="Local" value="htmlHTMLPage1.htm"> object> <li><object type="text/sitemap"> <param name="Name" value="Test"> <param name="Local" value="htmltesttest.htm"> object> <ul> <li><object type="text/sitemap"> <param name="Name" value="HTMLPage2"> <param name="Local" value="htmltestHTMLPage2.htm"> object> ul>

    It works well, the only problem is that the file format is not the easiest to understand, as its not XML and its not really HTML.  But to be fair, Help 1.0 is from 98, and Help 2.0 does have a XML based TOC file.

    For a simple file to be displayed in the contents, the file hhc file should have a entry like

    <li><object type="text/sitemap"> <param name="Name" value="HTMLPage1"> <param name="Local" value="htmlHTMLPage1.htm"> object>

    Notice, li is not closed. If you wanted a page as a child node of another page, underneath an entry like above, you would add

    <ul> <li><object type="text/sitemap"> <param name="Name" value="HTMLPage2"> <param name="Local" value="htmltestHTMLPage2.htm"> object> ul>

    Adding an entry for each page between the ul tags.

    Within hhk you simple just have a single entry for all of the pages, like below

    <li><object type="text/sitemap"> <param name="Name" value="HTMLPage2"> <param name="Local" value="html/test/HTMLPage2.htm"> object>

    So, its not that difficult, but trying to out it would wasn’t a great experience.

    You can download my code BuildProcess.cs and CustomTopics.cs.  I have also zipped up the complete project for download here

    While, I haven’t implemented the support for Help 2.0, you would simply need to copy all of the html into the Html2 folder and modify the HxT file.  Plus, with this solution it also works with the DocSite web applications.

    One thing to be aware of was that if I changed BuildProcess.cs without changing the target assembly, then it would never build as there was no point because the the source hadn’t changed. That’s fine, unless BuildProcess.cs changes, but selecting ReBuild gets around this and forces a fresh build. 

    Another tip, Sandcastle builds a lot quicker when your laptop isn’t on Power Saving mode…

  • SandCastle and DocProject

    Creator of DocProject, Dave Sexton, made some interesting comments about his software on my previous posts about Sandcastle and Creating Sandcastle websites which made me want to look at his software again.  DocProject is quite different to the other UI’s for Sandcastle as it actually integrates into Visual Studio and MSBuild so very easy to integrate into new and existing solutions,  Dave has also put good How To’s on the site for getting started with the project.  For this post, I am using version 1.6.2 RC and June CTP Refresh of Sandcastle.

    I plan to have DocProject generate both compiled help in CHM and HxS format and also output a website for an online version of the help files for an existing solution, SandcastleDocumentationTest.  Following Dave’s advice, I ran Visual Studio as Administrator on Vista, if you don’t you will run into problems and load my solution like normal.  I then add a new project, and under the Visual C# tab select DocProject and the Project Documentation item.  It then gives you a simple wizard, where you can select the output type, assemblies to output, and template is a very simple and straight forward way.  After it has done that, in the solution there will be a project for your documentation.

    The first thing I did was do a build, as it uses MsBuild this was done right within Visual Studio which was nice.  It would have been cool if the Sandcastle output was also being displayed as part of the build, within the build windows as Sandcastle tasks a while and knowing what is happening would be nice. (Turns out, after the Addin is loaded, it actually does this, makes for a much better experience – you even get a progress bar on the status.).  Note, while this is building, you can’t rebuild your main solution so one of the recommendations is “Open the solution configuration manager and for each configuration (e.g., Debug and Release) uncheck the Build column for the DocProject so that it’s only built on-demand and not when the solution is built.”  Once the build has finished, in the project directory you will find the complied help files, or select Show All Files in VS for the project and it will be listed within the solution.  So its really simple to get going with this and to output your first project.

    Now that we have a base project in place, we can look at extending it.  DocProject integrates into Visual Studio’s Options menu (Tools > Options > DocProject) which lead onto my second sight problem, the Addin wasn’t being extended into the Options menu, after one or two quick emails to Dave it turns out the problem was with Visual studio and his software did the correct thing.

    So, with the addin now loaded correctly, I can look at the software.  With the Options menu, DocProject provides you with the core options for the current active project.  The main options which I like are

    • Use friendly HTML file names
    • API Topic Management, where you can set summaries for the namespaces
    • API Topic Designer, for HTML header and footer for docs

    The API Topic Management and Designer are also accessible via a toolbar which is installed.

    So that’s how to configure the additional options, all the settings are saved into project.xml.  Now we have our documentation being created in an offline format, lets have a look at how to create it in an online format.

    The other project template which is provided is for DocSite.  This option creates a ASP.net Ajax enabled website to display the created documentation online. It also outputs the CHM and HxS which are linked to the main site so the user can download them.  This means that you could just have one build which outputs all the three formats for your help which is nice.   The site itself looks really nice, uses ASP.net master pages so can be easily modified and is good enough to put on your site, in fact the Xml MVP’s have here.  One problem is that the search doesn’t work with partial worlds, for example Hello doesn’t bring up HelloWorld which is a shame and the icons look very much like 98 style help – having simple +/- like MSDN could look better.  But that’s one of the great things about DocProject, if you want a different icon then you just need to change the style sheet.  But, its great that the site is provided to the standard out the box.

    Visit my example here

    Finally, as I mentioned.  Because this is just a MSBuild script, it can be easily executed as part of a build and the output included within your install/package.

    Summary

    So, I was wrong, DocProject is a very nice tool and really worth using, so is SHFB.  My experience was tainted by the Addin problem wasn’t the project’s fault.  After that was installed, it worked like a dream!  The fact that the website it outputs looks amazing and is ready to go is a big plus, together with the fact that it is just a MSBuild script makes it so simple to integrate into an existing project or build script.

    SandCastle – Creating a website

    Something which I forgot to mention in yesterday’s post was that SandCastle can create a website for your API.

    When executing the example included within the CTP, in the output folder there is a subfolder called HTML. However, this isn’t very useful as it is simply all the pages which are later compiled in the CHM.  However, Sandcastle Help File Builder (SHFB) has an excellent feature, where it takes this output and actually makes it useful.

    SHFB takes the Sandcastle HTML files created via either external content or from the XmlComments, together with some magic files, mainly a Tables of contents in XML and some Javascript files which creates a table of contents for use within a HTML page, or use within an ASP.net page – both created for you.  From this page, it loads the HTML, created by Sandcastle, in an IFrame allowing for all of the Help content to be displayed online. Very cool, however it doesn’t look very nice.

    I have been nice and uploaded the example which SHFB outputs to here with the ASP.net output here.  The project I used was different to the previous post as SHFB couldn’t import the example, required a real solution file but its more to demonstrate something.

    Just to summarise, SHFB can use the Html outputted from Sandcastle, to convert it into a website which can be uploaded onto a site.

    How to use ASP.net to create a ‘nice’ API website

    I am now going to go over the process of creating a website based on the output from SHFB and make it look how you want, this could then be incorporated into your own documentation site.

    The first thing I did was create a new ASP.net Ajax enabled C# based website.  I then copied the following files into the solution.

    • html folder
    • icons folder
    • scripts folder
    • styles folder
    • Collapsed.gif
    • Expanded.gif
    • Item.gif

    These are all the files I will be using, if you want other items for different requirements you can include them as well. The most important files, are the folders which Sandcastle outputs and WebTOC.xml which SHFB generates.

    From this, we can now generate the documentation site based on your own requirements. I simply processed the WebTOC xml file, created a TreeNode for each item, using the Value property for the URL of the related HTML page.  After adding all of them to the TreeView, I hooked into the SelectedNodeChanged event on the TreeView so when a item was clicked, I could load up the related page.

    To display the page, I used an embedded iFrame, however to be able to set the URL of the iFrame from the code behind, I had to manually create the HTML for an iFrame within the code-behind and set it to the Text property of a Literal control on the page.

    To make the whole thing a bit more pleasing for the user, I wrapped everything in a UpdatePanel and set the UpdateMode to Conditional.

    View default.aspx.cs which contains the C# for the site
    View my example site
    Download all code

    That’s it, very simple once you have the XML processed into the navigation control.  With the HTML and the WebTOC.xml are left as loose files so an automated process could simply replace these from a newly created output and the site would automatically update.  While my example might not look ‘better’, it was move to prove a point that it could be done.

    Note, full credit goes to Eric Woodruff for creating SHFB and the code for the original example.  Visit Sandcastle Help File Builder

    Technorati tags: ,

    SandCastle – What you need to know

    Recently, the SandCastle team released the June CTP of their software, so I decided to dig a little deeper and see what Sandcastle offers and how it works.  Note, the Sandcastle team released the June CTP on Friday 22nd, however released a Refresh a few days later renaming the template VSOrcas to Hana and making it look a lot cleaner.  If you was a little quick off the mark with your download, you will have to re-install the refresh.

    Sandcastle is a command-line application which takes XMLDocs (/// comments at the top of classes and methods) from your .Net code and output them in a readable and distributable format.  Microsoft are using Sandcastle to produce both internal and external documentation on the .Net framework and seems to have a lively release schedule.

    After installing the CTP, as there isn’t a GUI or any kind of integration, you are left to search for everything yourself.  Luckily, there are a range of GUI’s and help support available online which I will cover later.  For now, I’m just going to cover the core application.

    Sandcastle can produce three types of help file format.

    • HTML files
    • CHM (Help 1.0) Format
    • HxS (Help 2.0) Format

    These are styled based on predefined themes within the framework, these should fit most of your requirements and you can add your own however that’s beyond the scope of this post.  I think you create another folder similar to the ones in C:Program FilesSandcastlePresentation, however I’m not 100% sure on this.  The three styles included are:

    • Codename Hana. This is new within June CTP, this was called VSOrcas however due to VS no longer being called Orcas this had to change.  This will be the template for .Net 3.5 help I think.
    • Prototype.  Some ideas which have been now migrated to Hana
    • VS2005.  2005 style documentation.

    This gives you enough flexibility to be able to produce helps files to meet your own needs with the look and feel you want.  Lets have a look at how to create the files.

    Included within the install is an example folder which can be used to check everything is working, and for you to quickly see what the output of each template and XmlDoc tag looks like.  Within the directory C:Program FilesSandcastleExamplesSandcastle there is three files.

    1. build.proj – MsBuild script
    2. test.cs – Documented sample code which will be built.
    3. build_Sandcastle.bat – Batch file for creating the output.

    The example is very simple to run, unless your running vista.  If your running vista, the build will try and save files into the Program Files directory, if your not running the command prompt with Administrator rights, its going to fail in a not very helpful way.  Either run the cmd with admin rights (right click > Run As Admin) or copy the examples to a directory you can write too.  I copied the Sandcastle examples directory to my own space to work with. Once you are in a position to run the build you will need to execute the batch file and pass in a parameter for which template you would like to use,  for example “build_Sandcastle.bat Hana” or “build_Sandcastle.bat vs2005”.  Creating the example takes a while, a minute on my laptop so if your machine is a little old then it could take longer – or my laptop is just slow. Once it has been done you will notice a lot of new files in the examples directory, but the most important file is in the new Output folder and is called test.chm.  This is the help file created from the XmlDocs using the standard Microsoft Compiled Help Format. 

    Screenshot of Hana output
    Screenshot of output using the Hana template.

    If you want to have a closer look at the samples, you can download Hana here and vs2005 here.  So that’s what is created by default, lets have a little closer look at what is going on under the covers.

    Within the batch file, there is a number of different commands it executes in order to process the creation of the help file.

    1. Set PATH variables.  When installing Sandcastle, it should create a Environment Variable called DXROOT which points to the install directory.  The script just makes sure all the Path variables are set for it to use the command names without having to type in the directory names.
    2. Create the output directory where all the useful files are to be placed.
    3. Compile the test.cs file.  Output all of the comments to a separate file called comments.xml.  There is an checkbox within VS2005 Build settings for a project to enable this compiler option.
    4. MRefBuilder is then called which reflects on managed assemblies to produce an XML-formatted reflection information file.  This XML file contains everything about the assembly, all the classes, methods, properties, type information etc. Everything you would expect to see via Reflection. Produces (reflection.org)
    5. The code then applies some XSLT to the output file from MRefBuilder to produce reflection.xml.  The transforms it applies depends on the parameter passed in. 
    6. It then calls more XSLT on the reflection.xml to produce manifest.xml.
    7. A batch file is called which copies all of the output from one template to the output folder for local use.
    8. BuildAssembler is called which combines the reflection information generated, together with the comments file to create a set of HTML files.
    9. More XSLT based on reflection.xml is called to create a hhp (HTML Help Workshop Project) file.
    10. The Table Of Contents is then created, again using XSLT and reflection.xml.
    11. Finally, the chm is created using a bit more XSLT and the hhc exe.  Creating the document is complex process, using lots of XSLT but thankfully
    12. There is one more step, Generation of a HxS file.  I will discuss the HxS below.

    That’s how it creates the file, but now lets look a bit more closely at what is actually created.

    CHM (Help 1.0) Format

    CHM has been around since Windows 98 and is a way to distribute help files, with open source readers for other platforms.  The format is viewable windows without installing any additional readers, so makes it a perfect choice for targeting the most people with the new templates actually making the contents look acceptable. The format is a bit limiting, doesn’t really offer much but offline HTML.  Simple but effective.

    HxS (Help 2.0) Format

    HxS is a bit more interesting, but also comes with added complexity.  HxS was first released under the VSIP license with VS2003.  It has now been included within the Visual Studio 2005 SDK, which must be installed in order for Sandcastle to be able to create the HxS help files. 

    So, why would you actually want to use it?  Well, the purpose of HxS is to integrate into the Visual Studio help system, so instead of having to load a separate file you can simple hit F1 within VS and go to the help section. However, it comes at a cost.

    Firstly, you either need to use Visual Studio to view the help file, or a separate application, such as H2Viewer.

    Secondly, you need to actually install the help file using a MSI. There is a walk through on MSDN and the process isn’t very complicated, however if your install script is not MSI, i’m not sure how easy it is to integrate which could cause some issues.  Also, not sure how to integrate it into an existing MSI however I think this is just because of my limited installer knowledge.

    To get the batch script example to work, I had to add the directory of where hxcomp.exe is located to the PATH variable, which on my system was: 

    C:Program FilesVisual Studio 2005 SDK2007.02VisualStudioIntegrationArchiveHelpIntegration

    You can see the output here, but you will need something to view it.

    Hopefully, that has given you an overview so the different sections but doesn’t really provide you with any information for your own project so let’s look at the GUI support and how to integrate Sandcastle into your build script, but also why you might not want to.

    GUI Support

    There is a range of GUIs for Sandcastle, each very different and tailor to your own requirements and needs.  There are two main projects on codeplex, one is DocProject which integrates into Visual Studio where you include the template within your solution and reference the assemblies you wish to document, it can then create the help files when the project is built.  It’s good as it integrates into Visual Studio, but I found it to be more difficult to configure and it doesn’t work well with Vista.  The other is Sandcastle Help File Builder, SHFB, also on codeplex.  I found this to be very easy and straight to the point. You reference an assembly and then set a series of properties for the help file like you would on a object in Visual Studio. It can output both CHM and HxS, but you can also include your own custom files which can then be included as additional ‘pages’ within the help file, this is good for getting start documents or licensing information – DocProject also allows for this.  You can then click build and have the help files created for you. The only requirements are that Sandcastle is installed, and the Visual Studio SDK if you want Help 2.0 content.  The great thing is, you can save all of the settings in an external file for use again.

    Automating

    There is two ways to integrate Sandcastle into your build process, one way is via MSBuild with complicated script commands, or if your using SHFB you simply have a command which executes the Console part of the application, passing in the shfb project file which can be saved via the GUI and it will create your help files with the latest source.


      
      

    If your using DocProject, then you simply need to build the project and this will output the files.

    However, you might not want it executing every time you build the system as it will definitely add a lot of time onto your build process.  Just something to take into consideration.

    Summary

    That is an overview of Sandcastle and what it can offer.  Sandcastle is really good and its improving all the time.  While there is no official GUI’s or integration yet, the existing projects available are up to the task in hand. I hope it has been of some use to you, if you have any questions then please let me know.

    Links

    Samples I created from Example: Hana Help 1.0 | VS2005 Help 1.0 | Hana Help 2.0

    Download: http://www.microsoft.com/downloads/details.aspx?FamilyId=E82EA71D-DA89-42EE-A715-696E3A4873B2&displaylang=en

    Visual Studio SDK: http://msdn2.microsoft.com/en-us/vstudio/aa700819.aspx

    Creating MSI for HxS: How to- Use the Help Integration Wizard to Add a Help Collection to Visual Studio

    MSDN: http://msdn2.microsoft.com/en-us/vstudio/bb608422.aspx

    Sandcastle projects on Codeplex: http://codeplex.com/tagging/tagdetail.aspx?tagname=sandcastle

    Sandcastle Help File Builder

    Technorati tags: ,