Code Block Component

This topic describes the Code Block Component features.

Usage Benefits

The Code Block Component is used to extend the functionality of the XML comments <code> tag. It provides the following features:

  • Excess leading whitespace is stripped from the <code> blocks to left-align them correctly.

  • It adds support for optional line numbering.

  • It adds support for optional collapsible regions for code in #region and #if/#else/#endif blocks with support for nested collapsible regions. The C++ and VB.NET equivalents are supported too.

  • A default title can be added based on the language that the code represents.

  • A "Copy" link appears to the right on the title line that allows you to copy the code sample to the clipboard. The code is copied as plain text without the highlighting and line numbers if used.

  • It adds support for reading in an external source file or a defined region of an external source file so that you can keep code samples in a buildable project to test them for correctness and to do away with managing the code samples in the XML comments or include files.

  • Support is provided for nested code tags which allows you to merge code from two or more code snippets into a single code example.

  • Syntax highlighting of code blocks in <code> tags. Languages supported include C#, VB.NET, JScript.NET, C++, J#, C, JavaScript, VBScript, XAML, XML, HTML, SQL script, Python, PowerShell script, and batch file script. An external configuration file is used so that it is possible to extend the colorizer to support other languages. The style sheet is also replaceable. All of the features noted above are available whether or not you enable the colorizing feature. The code colorizer is a modified and extended version of the one written by Jonathan de Halleux in the Code Project article Multiple Language Syntax Highlighting, Part 2: C# Control. The modified code is available with the source download for the help file builder and the build components.

Custom Attributes

The following attributes can be added to the <code> tag in XML comments. They can be used in any combination with each other with the exception of region and removeRegionMarkers which, if used, must be paired with a source attribute. All attribute names and values are case-sensitive.

The source, region, and removeRegionMarkers Attributes

This feature is based on an idea suggested by Morten Nielsen in the MSDN Documentation Forum. The source attribute is used to specify that the code block's content should be read from an external source code file. If used alone, the entire file is used. The optional region attribute can be used to limit the code to a specific section of the file delimited with the named #region (#pragma region for C++). The #region and #endregion tags are excluded from the extracted section of code.

This is not to be confused with the XML comments <include> tag. This extension is intended to extract code from actual source files. This allows you to manage your code examples in buildable projects to test them for correctness as a project is developed and altered in the future. It also saves you from managing the code in the XML comments and does not require that the code be HTML encoded as it is when written in the comments. The code will be HTML encoded when it is read in for processing. When used, it is assumed that there is no code within the comment tag itself and thus it will always be self-closing. Here are some examples:

Retrieve all code from an external file and use the VB.NET syntax to color it. The path is relative to the basePath configuration element. Typically, the base path is the path of the documentation project file. So, if your documentation project is in a subfolder and the code is in the parent folder in an Examples subfolder, the path would look like the following example.

 
<code source="..\Examples\WholeDemo.vb" language="vbnet" />

Retrieve a specific #region from an external file.

 
<code source="..\Examples\SeveralExamples.vb"
  region="Example 1" language="vbnet" title="Example #1" />

Note that VB.NET does not allow #Region and #End Region within a method body. Other file types such as XML, XAML, and SQL script do not understand #region statements. However, if you want to extract a region from a VB.NET method body or a section of another file type, you can add the region statements in comments to workaround the limitation. The component will still find it and extract the region.

Commented Region Examples
--------------------------------------------------------
VB.NET Example
--------------------------------------------------------
Public Sub SomeMethod()
    ' #Region "VB.NET Snippet"
    Dim x As Integer

    For x = 1 To 10
        Console.WriteLine(x)
    Next x
    ' #End Region
End Sub

--------------------------------------------------------
XAML Example
--------------------------------------------------------
<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
  <Style.Triggers>
    <!-- #region XAML Snippet -->
    <Trigger Property="Button.IsMouseOver" Value="true">
      <Setter Property = "Background" Value="Red"/>
    </Trigger>
    <!-- #endregion -->
  </Style.Triggers>
</Style>

--------------------------------------------------------
SQL Example
--------------------------------------------------------
-- #region SQL snippet
Select *
From   tblName
Where  LastName = 'SMITH'
-- #endregion

/* #region Another snippet */
Select *
From   tblName
Where  FirstName = 'JOHN'
/* #endregion */

The removeRegionMarkers attribute can be used to specify whether or not region markers within the imported code file or region are removed. If not specified or set to false, any nested region markers are left in the imported code block. If specified and set to true, nested region markers are removed from the imported code. This is useful for removing nested region markers from larger code samples that contain smaller snippets of code used in other examples. The default setting (false) can be overridden via the component configuration.

The lang or language Attribute

These attributes allows you to override the default language specified in the component's configuration. Either one will have the same effect. Any <code> tag without a lang/language attribute will use the value specified in the component's configuration. For example, if most or all of your code examples are in C#, you can set the default language in the configuration to "cs". If you have an example in VB.NET, you can add language="vbnet" to colorize that example as VB.NET code. The possible language values in the supplied configuration file are as follows:

Language ID (case-insensitive)

Language Syntax Used

cs, C#, CSharp

C#

cpp, cpp#, C++, CPlusPlus

C++

c

C

fs, f#, FSharp, fscript

F#

EcmaScript, js, JavaScript

JavaScript

jscript, jscript#, jscriptnet, JScript.NET

JScript.NET

VB, VB#, vbnet, VB.NET

VB/VB.NET

vbs, vbscript

VBScript

htm, html, xml, xsl

XML

XAML

XAML

jsharp, J#

J#

sql, sql server, sqlserver

SQL script

py, python

Python

pshell, powershell, ps1

PowerShell script

bat, batch

batch file script

Anything else (i.e. "none")

No highlighting

  Important

The full name "language" should be used for the attribute name rather than the abbreviated form "lang". The reason is that the XSL transformations used by the presentation styles expect the full name when they search for the language attribute. The abbreviated form is a legacy syntax that should be avoided. The code block component will auto-correct the attribute name so that it is not missed by the transformations.

It is recommended that you always specify a language attribute.

The numberLines Attribute

This attribute allows you to override the default setting in the component's configuration. For example, if the default setting is false to turn off line numbering, you can add numberLines="true" to enable numbering on a specific code example.

The outlining Attribute

This attribute allows you to override the default setting in the component's configuration. For example, if the default setting is false to not add collapsible regions, you can add outlining="true" to enable collapsible regions on a specific code example. Note that if a code block contains no #region or #if blocks, outlining is automatically disabled and it will not reserve space in the margin for the markers.

The keepSeeTags Attribute

When set to true, this attribute allows you to tell the code colorizer to preserve <see> tags within the code so that they can be rendered as clickable links to the related topic. If set to false, the default, any <see> tags within the code will be colorized and passed through as literal text. When using this option, you may find that you need to specify inner text for the <see> tag so that the link text appears as you want it. If the self-closing version of the tag is used, Sandcastle will generally set the link text to the name of the item plus any parameters if it is a generic type or takes parameters which may not be appropriate within a code sample.

The tabSize Attribute

When the code blocks are formatted, tab characters are replaced with a set number of spaces to preserve formatting. This attribute can be used to override the default setting for a language which is specified in the syntax file. For example, if the default tab size for a language is four, adding tabSize="8" will force it to use eight spaces instead. If set to zero, the syntax file setting is used. This attribute sets the default tab size for unknown languages when used in the component's configuration.

The title Attribute

This attribute allows you to add a title that appears before the code block. An example of its use would be to label the example with a description. If omitted and the defaultTitle attribute on the code block component's colorizer element is true, the language name will appear for the title. If it is set to false, no title will appear. If using default titles and you do not want a title on a particular block, set the title attribute to a single space (" ").

Literal XML And Other Special Characters

NDoc had an additional escaped attribute that let you enter literal XML in the code block without having to HTML encode things like the angle brackets. An attempt was made to support that attribute in the code block component. However, the XML document as created by Sandcastle and passed to the component has all inter-element whitespace and line feeds stripped from it. As such, it loses all formatting in the escaped XML and renders it on a single, unbroken line. This made the escaped attribute useless and it was removed. If you want to include XML or other unencoded information you can do one of the following:

  • Utilize the source attribute to read it in from an external file instead.

  • Use a CDATA section to encapsulate the code so that special characters and formatting are preserved. For example:

    CDATA Example
    /// <example>
    /// <code language="xml" title="Example Configuration">
    /// <![CDATA[
    /// <?xml version="1.0" encoding="utf-8"?>
    /// <config>
    ///   <path>C:\Test\</path>
    ///   <filespec mask="*.txt" />
    /// </config>]]>
    /// </code>
    /// </example>

    Be sure to start the example code on a new line after the opening "<![CDATA[" tag as shown so that the leading whitespace can be normalized correctly.

Using either of the methods above preserves the formatting and has the same effect as the escaped attribute in NDoc.

Nested Code Tags

You can import multiple code snippets into one common colorized code block by nesting code tags within a parent code tag. On nested code tags, only the source and region attributes will be utilized. All other attributes that control colorization of the merged code block will be retrieved from the parent code tag.

Nested Code Tag Example
<code title="Nested code tag example" language="VB.NET">
    <code source="..\Class1.vb" region="Snippet #1" />
    <code source="..\Class1.vb" region="Snippet #2" />
</code>

Literal code can also be mixed in between the nested code tags. However, there are some limitations. All tags and literal code should be flush left within the parent code tag or you will end up with additional spaces before the first line of each nested code tag. There may still be additional spaces before the literal code. This is caused by the indentation included when the XML comments file is created by the compiler. If this is a problem, move the example to an include file and remove the excess leading whitespace. Use an include tag to bring it into the XML comments. When done this way, the compiler preserves the spacing when writing the example out to the XML comments file.

Nested Code Tag Example
<code title="Nested code tag example" language="VB.NET">
<code source="..\Class1.vb" region="Snippet #1" />

' ... Some stuff happens here ...

<code source="..\Class1.vb" region="Snippet #2" />
</code>

Example Configuration

The following is the default configuration for the code block component. It should be inserted into the configuration file just ahead of the TransformComponent. All attribute names and values are case-sensitive.

Example Configuration
<!-- Code block component configuration.  This must appear before the
     TransformComponent. -->
<component id="Code Block Component">
    <!-- Base path for relative filenames in source attributes
         (optional) -->
    <basePath value="{@HtmlEncProjectFolder}" />

    <!-- Base output paths for the files (required).  These should match
         the parent folder of the output path of the HTML files (see each of
         the SaveComponent instances below). -->
    <outputPaths>
        {@HelpFormatOutputPaths}
    </outputPaths>

    <!-- Allow missing source files (Optional).  If omitted,
         it will generate errors if referenced source files
         are missing. -->
    <allowMissingSource value="false" />

    <!-- Remove region markers from imported code blocks.  If omitted,
         region markers in imported code blocks are left alone. -->
    <removeRegionMarkers value="false" />

    <!-- Code colorizer options (required).
         Attributes:
           Language syntax configuration file (required)
           XSLT style sheet file (required)
           CSS style sheet file (required)
           Script file (required)
           Disabled (optional, leading whitespace normalization only)
           Default language (optional)
           Enable line numbering (optional)
           Enable outlining (optional)
           Keep XML comment "see" tags within the code (optional)
           Tab size override (optional, 0 = Use syntax file setting)
           Use language name as default title (optional) -->
    <colorizer syntaxFile="{@SHFBFolder}Colorizer\highlight.xml"
      styleFile="{@SHFBFolder}Colorizer\highlight.xsl"
      stylesheet="{@SHFBFolder}Colorizer\highlight.css"
      scriptFile="{@SHFBFolder}Colorizer\highlight.js"
      disabled="{@DisableCodeBlockComponent}" language="cs" numberLines="false"
      outlining="false" keepSeeTags="false" tabSize="0" defaultTitle="true" />
</component>

The example given above is taken from the Sandcastle Help File Builder's configuration file. When used with it, you may specify the replacement tag {@SHFBFolder} to insert the help file builder's folder in the file path and the {@ProjectFolder} replacement tag to specify the current project's folder. These are replaced at build time with the appropriate values. These replacement tags can also be specified in the configuration dialog when configuring project-specific configurations for the component from within the help file builder. If using the component in your own build scripts, replace the tags with an actual absolute or relative path.

The basePath element is optional. If specified, it defines the base path to use for relative paths in the source attributes of code blocks. If omitted or left blank, the current folder at build time is assumed to be the base path.

The outputPaths element is required. It defines the output paths to use for each help file format in the build. These will be used when copying the colorizer script and style sheet files. The help file builder will fill these in automatically. If using this with your own build scripts, specify one path element for each help file output format being generated with a value attribute set to the relative path of the format's output folder (i.e. Output\HtmlHelp1).

The allowMissingSource element is optional. If omitted, or if specified and set to false, any code block that references a source code file or region within a file will generate an error and stop the build if the source code file or the region in it cannot be found. If specified and set to true, only warnings will be generated and the build will be allowed to run to completion. The code blocks with the missing information will contain an error message referring you to the log file. This option can be overridden on a case by case basis by adding an allowMissingSource attribute to individual code elements in the XML comments. When set to true on the individual elements, it allows them to be missing. If omitted or set to false, the global setting from this option is inherited.

The removeRegionMarkers element is option. If omitted, or if specified and set to false, any region markers in imported code blocks are left in the imported code. If specified and set to true, any region markers nested within the imported code file or region are removed. This is useful for getting rid of region markers in code that is used both for a larger example and parts of it that are used in smaller snippet examples. This setting can be overridden by specifying the attribute on individual code elements.

The colorizer element is required along with the syntaxFile, styleFile, stylesheet, and scriptFile attributes which define the default syntax definition file, the transformation file used by the colorizer, the style sheet to use for the colorized code, and the colorized code script file. The supplied highlight.xml file contains the syntax definitions for the languages supported by the colorizer. The supplied highlight.xsl file defines the XSLT transformation used to convert the parsed code block into the colorized HTML. The supplied highlight.css and highlight.js files contain the default styles and script used for the colorized code. All other attributes are optional. If specified, they define the defaults for code blocks that do not specify the matching attribute. The optional defaultTitle attribute specifies whether or not to use the language name as the title if a specific title is not supplied. The optional disabled attribute will turn off code colorization if set to true.

See Also