Wednesday, March 08, 2006

Help Insight

I like Help Insight in Delphi 2006. I think it's going to prove to be very useful. The cool thing is that it's customizable: the popup window is a browser view of an HTML page generated from the XML compiler output by applying HelpInsight.xsl and HelpInsight.css files located in your $(BDS)\Objrepos directory.
If you want to have a look at what the XML compiler output looks like, you can modify your HelpInsight.xsl (back up the original first!) like this:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<script language="javascript">
function showsrc() {
window.alert(document.body.innerHTML);
}
</script>
<body>
<a href="javascript:showsrc();">source</a>
<xsl:copy-of select="."/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Then move your mouse over some identifiers in your source code to bring up the Help Insight browser window, and click on the "source" link to see the original XML produced by the compiler.
The format is basically the following:
<MEMBER DisplayName=|DisplayName| name=|name|>
<SOURCE declaredOn=|declaredOn|
declaredIn=|declaredIn|
declaredInShort=|declaredInShort|></SOURCE>
[|your XML comments|]
<SUMMARY><PARA>|summary|</PARA></SUMMARY>
[|params|]
</MEMBER>
I'm not going to write up a complete description of the elements, here are just a few quick examples. Given the following source code, you get the XML shown below when you invoke Help Insight for Const1, TForm1, Field, Func, Prop, Event and Form1, respectively:
const
Const1 = 42; // the answer to life, the universe and everything

type
TForm1 = class(TForm)
public
Field: Integer;
FEvent: TNotifyEvent;
function Func(X, Y: Integer; const S: string): Boolean;
property Prop: Integer read Field;
property Event: TNotifyEvent read FEvent;
end;

var
Form1: TForm1;

Const1:
<MEMBER DisplayName="Const1 Constant" name="C:Const1">
<SOURCE declaredOn="10,3"
declaredIn="C:\Temp\Unit1.pas"
declaredInShort="Unit1.pas"></SOURCE>
<SUMMARY><PARA>Const1 = 42 - System.Integer</PARA></SUMMARY>
<MEMBER>

TForm1:
<MEMBER DisplayName="TForm1 Type" name="T:Unit1.TForm1">
<SOURCE declaredOn="13,3"
declaredIn="C:\Temp\Unit1.pas"
declaredInShort="Unit1.pas"></SOURCE>
<SUMMARY><PARA>Declared in Unit1</PARA></SUMMARY>
</MEMBER>

Field:
<MEMBER DisplayName="Field Field" name="F:Unit1.TForm1.Field">
<SOURCE declaredOn="15,5"
declaredIn="C:\Temp\Unit1.pas"
declaredInShort="Unit1.pas"></SOURCE>
<SUMMARY><PARA>Field - System.Integer</PARA></SUMMARY>
</MEMBER>

Func:
<MEMBER DisplayName="TForm1.Func(Integer,Integer,string) Method"
name="M:Unit1.TForm1.Func(System.Integer,System.Integer,System.string)">
<SOURCE declaredOn="17,14"
declaredIn="C:\Temp\Unit1.pas"
declaredInShort="Unit1.pas"></SOURCE>
<SUMMARY><PARA>Declared in <SEE DisplayName="Unit1.TForm1"
cref="Unit1|Unit1.TForm1"></SEE></PARA></SUMMARY>
<PARAM name="X">System.Integer
<PARAM name="Y">System.Integer
<PARAM name="S">System.string
<RETURNS><PARA>System.Boolean</PARA></RETURNS>
</MEMBER>

Prop:
<MEMBER DisplayName="Prop Property" name="P:Unit1.TForm1.Prop">
<SOURCE declaredOn="18,14"
declaredIn="C:\Temp\Unit1.pas"
declaredInShort="Unit1.pas"></SOURCE>
<SUMMARY><PARA>Prop - System.Integer</PARA></SUMMARY>
</MEMBER>

Event:
<MEMBER DisplayName="Event Event" name="E:Unit1.TForm1.Event">
<SOURCE declaredOn="19,14"
declaredIn="C:\Temp\Unit1.pas"
declaredInShort="Unit1.pas"></SOURCE>
<SUMMARY><PARA>Declared in <SEE DisplayName="Unit1.TForm1"
cref="Unit1|Unit1.TForm"></SEE></PARA></SUMMARY>
<PARAM name="Sender">System.TObject
</MEMBER>

Form1:
<MEMBER DisplayName="Form1 Field" name="F:Unit1.Form1">
<SOURCE declaredOn="23,3"
declaredIn="C:\Temp\Unit1.pas"
declaredInShort="Unit1.pas"></SOURCE>
<SUMMARY><PARA>Form1 - <SEE DisplayName="Unit1.TForm1"
cref="Unit1|Unit1.TForm"></SEE></PARA></SUMMARY>
</MEMBER>
As you can see, the <SOURCE> node contains information about the source code file name, line number and column of the declaration. Also note the unclosed <PARAM> tags ;-)

The above XML is what you get when the source code doesn't contain any XML comments. If it does, they are simply inserted between Help Insight's <SOURCE> and <SUMMARY> nodes. Whatever your comments are, they all go there. The weird part is that if your comments contain any <PARAM> or <RETURNS> tags, or even any tags starting with these strings, such as <PARAMDEF> or <RETURNSDESC>, you will suppress the Help Insight's own <PARAM> and <RETURNS> sections (they will not be included anymore). If you want to have, for example, a list of parameters from the compiler mixed with your own descriptions of them, you'll have to use different tag names (I use <xparam> and <xreturns>) and write some XSL to produce the combined output.

As one can see in the original HelpInsight.xsl, the Help Insight browser supports some special URLs, e.g. a link with href="helpinsight:typelink:Unit1|Unit1.TForm1" would open Help Insight window for my TForm1 type. Another I've found is href="helpinsight:filelink:C:\Temp\Unit1.pas?10,3" which would make your IDE editor go to Unit1.pas at line 10, character position 3.

My current modifications to HelpInsight.xsl are such that my Help Insight shows me its own parameter list for methods, combined with my own descriptions of them. Summary and remarks are also included. I can also use URLs within my comments; these will produce HTML links which open a new IE window with the URL.
I've also modified HelpInsight.css a little bit to change colors, fonts etc.

No comments: