2007-06-20

Windows Live Writer, Spell Checker, Pascal Code Formatting

September 2007 edit: Steve Dunn has updated his control, and so this no longer applies. Check my other post about using his newer version and "fixing" the used Pascal definition file.

After reading this post from Primoz Gabrijelcic, which took me to this other post from Jimmy Bergmark, my Windows Live Writer has once again the Spell check option.

In the 2nd post mentioned above, I saw a reference to another plug-in, a code-formatting plug-in, something that I wanted to add to WLW too, so I decided to check it out. I downloaded it (from here), and was a bit surprised about the lack of Pascal as a choice for language. A quick check later and I saw the different languages each had an XML file, so I thought for myself: "It can't be that hard to grab one and modify it for Pascal". And so, I started the conversion process. Unfortunately, I had placed too much faith on the recently fixed "Improved Help" of Delphi 2007: needless to say that, after a few minutes of fighting with the help, which, although improved since Delphi 2007's release as at least now it no longer renders the IDE unusable if you press F1 on a menu, I had nevertheless to give up. Finding basic things in that help is a pain in the ***, and that's putting it nicely! Be that using filters or no filters, language filters or no language filters, finding Pascal help for a list of basic types has proven to be a much greater challenge than it should have been.

So, attempt number two: Google to the rescue! I googled a bit and within seconds had found this other page, from where I could download the controls that were used by this code formatting plug-in, so, after typing a fake name and e-mail (I hate these "we want your name before you can download" type of sites!), I downloaded the free controls. Extracted the ActiproSoftware.Pascal.xml file and placed it in the code formatting plug-in Languages folder and fired up WLW.

Things didn't quite work out: no Pascal available in the language choices. A little bit more digging, and I found that the DunnHQ.Wlw.CodeFormatter.dll.config file is in fact an XML file with a list of all available languages and definitions, so, after adding the following line:

<language key="Pascal" definitionPath="./plugins/Languages/ActiproSoftware.Pascal.xml" />

and restarting WLW, I "Pasted Clipboard as Code", selected Pascal from the list of languages and got this as result:


Bugger


Humm... Something is amiss surely...


After another quick check, I found the source: the language definition XML files used in the plug-in have LanguageDefinitionVersion="3.0", while this one downloaded from ActivePro has LanguageDefinitionVersion="4.0", so, time to go check if I can find one of those for version 3...


(At this point, I can not even save a draft of this post as I get this when trying to do it:)


Another bugger


(D:\XDesk is my Desktop folder: somehow it's trying to load the language definition for the small line of XML above from the Desktop instead of from the program's start location..)


So, after a quick copy/paste of that plugins folder to my desktop, I saved, quit WLW and resumed Googling...


It turns out that the format has been significantly changed between versions 3 and 4 and that the Pascal definition was added only in version 4. Luckily, at this point I also found another code-formatting plug-in that seems to be based around v 4 as it lists Pascal in the available languages! So, after downloading and trying SyntaxColor4Writer, I was again in a dead end: it's for Beta 1 and would not work on Beta 2!


Well, I ended up clicking the "Add a Plugin..." button in WLW and downloading Code Snippet plugin for Windows Live Writer so that's what I'll try next. If it doesn't work ok, I'll update this blog post asap. Another dead end... List of supported languages:


image


Uninstall this one, try the "Add a Plugin..." button again... Another quick look finds another one that is probably based around the same source as the list of languages is identical, so, back to Google again... (I really should be working instead!)


Back to the starting idea and let's see how hard it is to retrofit v 4 Pascal definition XML into v3 controls. It turns out that it's VERY easy! All you need to do for it to start working is change both 4s in the first line of the Pascal.xml file into 3s. Like this:



<SyntaxLanguage Key="Pascal" LanguageDefinitionVersion="3.0" Secure="True" xmlns="http://ActiproSoftware/SyntaxEditor/3.0/LanguageDefinition">


So, after that it's now working with Pascal code. There are a couple things that don't look that good, namely the wrong color of keywords such as "unit", "uses" and others, but it should be easy now to fix the Pascal.xml file and simply add those keywords. So, with a little help from Delphi Basics to get what the built-in help in Delphi 2007 won't give me (a list of reserved keywords), here's how some sample Pascal code looks like:


unit uHeader;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Outlook2000, adxolFormsManager, StdCtrls;

type
TfrmHeader
= class(TadxOlForm)
lbxHeader: TListBox;
procedure adxOlFormADXSelectionChange(Sender: TObject);
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;

{NOTE: The adxOlForm1 variable is intended for the exclusive use
by the TadxOlFormsCollectionItem Designer.
NEVER use this variable for other purposes.
}
var
frmHeader : TfrmHeader;

implementation

{$R *.DFM}

uses MapiDefs, MapiTags, MAPIUtil;

procedure StringToList( Str: string; lstResult: TStrings );
// Convert a header string containing CR/LFs and TABs into
// a stringlist where each new property starts on a new line
var
iPos : integer;
const
CRLF
= #13#10;
begin
lstResult.Clear;
iPos :
= Pos( CRLF, Str );
while (iPos > 0) and (iPos < (Length( Str )-1) ) do begin
// If the new line starts with a Space or Tab, it's a continuation line
if (Str[iPos+2] = #9) or (Str[iPos+2] = #32) then begin
Delete( Str, iPos,
2 );
end else begin
lstResult.Add( Copy( Str,
1, Pred(iPos) ) );
Delete( Str,
1, Succ( iPos ) );
end;
iPos :
= Pos( CRLF, Str );
end;
end;

procedure TfrmHeader.adxOlFormADXSelectionChange( Sender: TObject );
var
Selection: Outlook2000.Selection;
IMail : _MailItem;
IMessage : MAPIDefs.IMessage;
PropValue: PSPropValue;
begin
lbxHeader.Items.Clear;
Selection :
= Self.ExplorerObj.Selection;
if Selection.Count > 0 then begin
try
// Try for a "normal" mail item
Selection.Item(1).QueryInterface( IID__MailItem, IMail );
if not Assigned( IMail ) then begin
// If it failed, try for a Read/Delivery Receipt item
Selection.Item(1).QueryInterface( IID__ReportItem, IMail );
end;
if not Assigned( IMail ) then begin
// I don't use Remote Mail, but for completeness this should be tested also...
Selection.Item(1).QueryInterface( IID__RemoteItem, IMail );
end;
except // Ignore exceptions
end;
if Assigned(IMail) then begin
try
if IMail.Sent then begin
IMail.MAPIOBJECT.QueryInterface(MapiDefs.IMessage, IMessage);
if Assigned(IMessage) then begin
try
PropValue :
= nil;
if HrGetOneProp(IMessage, PR_TRANSPORT_MESSAGE_HEADERS, PropValue) = S_OK then begin
StringToList( PropValue^.Value.lpszA, lbxHeader.Items );
end;
finally
MAPIFreeBuffer(PropValue);
IMessage :
= nil;
end;
end;
end;
finally
IMail :
= nil;
end;
end else begin
// If no headers found...
lbxHeader.Items.Add( 'This type of message does' );
lbxHeader.Items.Add(
'not have mail headers' );
end;
end;
end;

(* Test Comment *)
initialization
(* Another test comment
spanning 2 lines
*)
RegisterClass(TPersistentClass(TfrmHeader));
(* Another comment w/ a
{ Nested comment }
*)
finalization
{ Another test of nested comments
(* This is
another one *)
}
end.


Wrap up


Edit: Check this post for the updated files.



So, if you got kind of lost, go here to download the WLW code formatting plug-in then download this file which is my updated ActiproSoftware.Pascal.xml file and place it in the plugins\languages folder. Download this file and place it in the plugins folder overwriting the existing one (updated languages definition file for the plugin). And you're good to go!


From now on you'll be able to easily insert Pascal formatted code onto your WLW post!


If you find some syntax formatting error, let me know: I'll fix whatever needs fixing and, in a couple days, I'll send this updated file to the plugin's author so he can update his plug-in and also to the component's vendor since they're providing this for free so they too can update their component.


Have fun blogging about code... :)


Note: Somehow, either this plug-in's fault or WLW beta 2 fault, extra empty lines were added to my post, so don't be surprised if you need to delete some extra lines after publishing... :)

Also, for no good reason, even though it was displaying properly in WLW, some spaces were removed from the code, either from publishing or from my editing of this post afterwards. Just added those extra spaces and will see if they stick after re-publishing...
Update: apparently did not work! :( Still, not a big issue so I won't be spending time on it for now...


Yet another update: I'm now re-editing the post from within WLW: first time I try this!! It appears to work just fine, so I'll try to re-publish it from WLW and see if the missing spaces in the code somehow re-appear as they show nicely in WLW...


Well, it appears to be the plug-in's fault for adding the extra space: probably some style change that was not undone. As for the spaces, as long as I don't edit the post in the browser they display correctly. I'll have to get back to work, so maybe later I'll check the generated html from the code plug-in and try to find the bug. Until then, just ignore the extra spacing that makes this post look a bit ugly... :)

5 comments:

Marko said...

Well done! Works perfectly.

Steve Dunn said...

Hi,
Thanks for using my plug-in. I'll look into updating it to work with ActiPro v4.
Cheers,

Steve

Steve Trefethen said...

My online code highlighter uses the ActiPro software as well. I need to check out the WLW intregration so I appreciate the write-up!

Fernando Madruga said...

Thks all for the comments and I'm glad you find this useful: it's much more fun finding a way to make something I use better and know that others can profit from that work too as I've profited from other people's time on other subjects! :)

As for the bug that causes the text to have the extra spacing, I'm afraid it falls into the realms of weirdness of HTML/CSS: even though I can write my own HTML by hand, I don't have that much experience with CSS and after copying this page's source to my HDD, and cleaning it up to only a hundred lines or so, I still can't find what is causing that to happen.

If some of you or any other reader has a clue, then by all means please share it as I'd love to have my blogs look a bit better! :)

Salvador Gomez Retamoza said...

Excelent Fernando! That is going to help me a lot. Thanks you as well to Steven Dunn for his plug-in.