November 09, 2007

DocProject Tips and Tricks I

As you probably already know, DocProject is kind of weak in the documentation department (that is, in its own API documentation :)  I plan to address this issue for the first RTW, after I include first-class support for generating conceptual content and after Sandcastle's first RTW.  If you are new to DocProject, the articles on CodePlex should provide more than enough information to get you started.

In a series of blog posts, with this post as the leader, I'm going to provide some supplementary information that you may find useful.  Tips and tricks that will add value to DocProject and allow you to make the most of it.  Code examples can be found at the end of posts and will have names like, Example #.

Community Tricksters

As the author, I probably know more about DocProject than anyone.  But as an end-user, I haven't taken advantage of the full range of its capabilities yet - including things like using DocProject with Team Build, building AJAX documentation or customizing Help 2.x output.  Therefore, I'd be happy to accept tips and tricks from the community that I can include in this series.  If you have ideas please submit them as blog comments or email them to me and I'll consider including them in my posts.  Thanks!

General-Purpose Tips

Here are some tips for DocProject that apply to all types of templates and build engines:

  1. If you do not want to include build output as project items, and you don't want to be prompted after you build a project for the first time, then set Include Project Output Dialog | Don't ask me this again to True in the DocProject Properties window before you build.  You can leave the default values for the two related options, which should both be False.  (Note that the Apply to all default option is not used when Don't ask me this again is True.)
  2. You can insert dynamic build steps using your project's Build Process Component (see Example 1 below).
  3. Use an external or third-party Build Process Component:
    1. Open the DocProject Properties window (right-mouse click your project in Solution Explorer and select, DocProject Properties).  Visual Studio Express users must use the DocProject External UI.
    2. Locate the Extensibility | Process component type name option.
    3. Enter an assembly-qualified type name (the assembly must be located in the GAC or your project's output folder).
    4. Alternatively, you can enter a full type name and an absolute or relative assembly path, separated by a vertical bar; e.g., MyNamespace.MyType|..\anotherproj\bin\Debug\anotherproj.dll
DocSites Tips

These tips apply to the DocSite Templates only:

  1. To change the DocSite logo simply replace the Images\Logo.jpg file with a file of your own.  To use a different file name, change the value of the ImageUrl attribute on the <asp:Image ... id="logoImage" ... /> element in the Controls\DocSiteHeader.ascx file.
  2. To show rank information in DocSite search results, for the purpose of fine-tuning the search index, open the App_Themes\BasicBlue\DocSiteSearch.skin file and set Visible="True" on <asp:Label ... SkinId="searchResultRank" ... />.  When performing a search the rank value will appear before the title of each matching topic.  If you already have search results in your browser just refresh the page.
  3. To change the DocSite title, company name and copyright, set the value of the AssemblyTitle, AssemblyCompany and AssemblyCopyright attributes, respectively, in the Properties\AssemblyInfo.(cs|vb) file and then restart the web application.  (The DocSite caches these values in memory upon the first request to the site.)
Sandcastle Tips

This section provides some useful tips for projects that use the Sandcastle or Sandcastle/Deployment build engine providers.

  1. Set the Help 1.x Configuration File Name and Help 2.x Configuration File Name options to the same values and DocProject will only run Build Assembler once to build both Help 1.x and Help 2.x output.  The cost of doing this is that reference link types in one of the help output formats might not be valid (this was the main reason for splitting the Sandcastle configuration file into two distinct files in the first place.)
  2. Use XML documentation files generated in the API Topic Management dialog for IntelliSense by adding a short code snippet in your DocProject's Build Process Component (see Example 2 below).
  3. In your Build Process Component, you can get access to all of the Sandcastle-specific project options and APIs.
    1. Add a reference in your DocProject or DocSite to the DaveSexton.DocProject.Sandcastle.dll assembly, commonly found at C:\Program Files\Dave Sexton\DocProject\bin\.
    2. Check out the code in Example 3 below, which illustrates how to access the custom Sandcastle APIs that are provided by DocProject.
  4. Insert images into your documentation using the XML documentation editor in the API Topic Management dialog:
    1. In design mode, place the text cursor where you want to insert an image.
    2. Click the InsertPictureHSbutton on the editor's tool strip or right-mouse click and select Insert > Picture.
    3. In the Picture dialog enter the full path and name of an existing image or click the Browse... button to locate one.
    4. You can enter a local file path or even a web address such as, http://example.com/someimage.jpg.  Click OK and the image is inserted.
    5. After you are done authoring your documentation, click OK on the API Topic Management dialog and DocProject will automatically import the image into your project's Help\Art folder.  It will also rebase the reference in the XML documentation to ..\Art\{image name}.
      1. Note: If you enter a web address then DocProject will copy the image from your web browser's cache; otherwise, the file is copied from the location that you specify.
    6. Note: The next time that you view the XML documentation in the API Topic Management dialog, the path will be rebased so that it's rooted, for display purposes only.  The path in your actual XML documentation on disc will remain relative, however.
  5. Filter out <Module> topics when the Documentation scope option is set to Complete by adding a dynamic regular expression filter:
    1. Open the API Topic Management dialog.
    2. Select the Topic Filters tab.
    3. Select the Regular Expression tab.
    4. Enter the following into the Pattern text box: \<Module\>
    5. Click the Save button.  The Saved Filters tab will be shown automatically and your filter will appear in the list.
    6. For the new filter, ensure that the Build column is checked and that the Include column is unchecked.
    7. Enter a short description of this filter into the Memo field (optional).
    8. Click OK on the API Topic Management dialog to commit your changes.
C# Code Examples

The following examples illustrate points made in the information above.  They are referenced by number.

Example 1:

The following example shows how to inject a dynamic build step immediately before the Help 1.x compiler step using your project's Build Process Component.  The step will be executed in full and partial builds and will run on a background thread.  It outputs some text in the build trace window:

Step # of ##: Hello

World!

To use this example, replace the BuildStarting method in your project's BuildProcess.(cs|vb) file.  (Keep the existing code though).

   1: protected override void BuildStarting(BuildContext context)
   2: {
   3:   // existing code goes here 
   4:  
   5:   base.InsertBeforeBuildStep("Compile Help 1.x", "Hello", true, false, true,
   6:     delegate(BuildContext stepContext)
   7:     {
   8:       stepContext.TraceLine("World!");
   9:     });
  10: }

Example 2:

The following example will overwrite the source XML documentation file (that contains your code comments) with the merged XML documentation file (that contains both your external documentation and the source code comments) after each help build completes.

To use this example, replace the BuildCompleted method in your project's BuildProcess.(cs|vb) file.  (The existing code should be placed at the end).  You must also add a using System.IO declaration at the top of the file.

   1: protected override void BuildCompleted(BuildContext context)
   2: {
   3:   TraceLine();
   4:   TraceLine("Overwriting XML documentation files in source projects..."); 
   5:  
   6:   IDocProject project = context.Engine.Project;
   7:   BuildSettings settings = context.Engine.Settings; 
   8:  
   9:   foreach (ISourceProject source in project.Sources)
  10:   {
  11:     string target = source.Output.XmlDocumentationFile; 
  12:  
  13:     FileInfo autoGenFile = new FileInfo(Path.Combine(
  14:       settings.WorkingXmlDocumentationPath, 
  15:       Path.GetFileName(target))); 
  16:  
  17:     if (autoGenFile.Exists)
  18:       autoGenFile.CopyTo(target, true);  // overwrite
  19:   } 
  20:  
  21:   TraceLine("Done."); 
  22:  
  23:   // existing code goes here
  24: }

Example 3:

You can access Sandcastle-specific project options and APIs in your Build Process Components by adding a reference to the DaveSexton.DocProject.Sandcastle.dll assembly.  The following example shows how to obtain the SandcastleBuildEngine instance, and from that retrieve the SandcastleSettings and SandcastleProjectOptions:

   1: SandcastleBuildEngine engine = (SandcastleBuildEngine) context.Engine;
   2: SandcastleSettings settings = engine.Settings;
   3: SandcastleProjectOptions options = engine.Options;

The context is an argument that is passed to all of the four main Build Process Component overrides: BuildStarting, BeforeExecuteStep, AfterExecuteStep and BuildCompleted.

Add comment