June 03, 2008

MAML Editor: Progress

This blog post is just an update on my progress creating a WYSIWYG (what you see is what you get) MAML editor.  I've received a lot of feedback (relative) for the MAML editor and I know that people are waiting for one, so I'd like to share with you some information about the one that I'm working on and when it will be available.

For those of you who are unaware of what MAML is, you can read about it here.

I've created a very basic MAML editor using .NET 3.5, C# 3.0, LINQ to XML and WPF, but it's not currently my priority since I'm planning to release DocProject 1.11.0 RC later this week.  A preview of the editor will be released though in the next couple of weeks as a standalone WPF application, a VS 2008 package (with MAML item templates) and also a standalone class library so that other tool developers can use the editor in their own applications - although note the dependency on the .NET 3.5 runtime and the DocProject license, which is currently the GNU-GPL.

The editor isn't schema based yet - I've hard-coded support for the Conceptual document type only, although since that type shares many common elements with other types, like How To and UI Reference, they're basically supported as well.  The only difference now is that there's no schema validation and the UI cannot create several elements that are optional in the schema for the other document types.  Though the current implementation has been designed to be flexible enough so that adding these things should be easy to do later on.

Since the editor is based on a WPF RichTextBox control, we get a free spell checker with squiggly underlines and an undo/redo buffer.  It's also really simple to implement custom control logic for various elements (the current implementation uses a factory pattern to generate parsers for the individual elements, by name), such as a link editor, tables, images, and other stuff.  So far I've added collapsible sections that actually function when you click the button, some custom logic that controls input behavior for various key presses, and also whitespace normalization for text (Run content in WPF).

Loading and saving also works, however synchronization between the data model in memory and the logical tree of the WPF content model still needs to be implemented - a major part of the editor - but with the event model and my current architecture I don't think it'll be too difficult; e.g., the data model currently uses XElement instances (from LINQ to XML) that contain annotations for their corresponding WPF content elements (Section, TableCell, Paragraph, Run, etc.) when the data is first parsed.  The idea is to update the document directly when changes in the UI are detected.  Saving the changes are then as simple as saving the XDocument.

Metadata is also editable, so I've decided to generate two separate files when saving a single topic.  The first file is the topic file itself, which contains the root topic node, its id and revisionNumber attributes, as well as the actual MAML content.  The second file is an XML companion file (to use the Sandcastle lingo) that contains metadata such as the topic's title, TOC title, MS Help attributes and index keywords.  I may have another XML-based file created in the future to save editor settings for individual topics, such as the visibility status of individual sections; i.e., a designer file.

MAML topics are saved with an .aml extension (Assistance Markup Language) and companion files use a .cmp extension with the same base file name as the .aml topic.  In the VS 2008 package, the .cmp file will be created with a dependency on the .aml so that it appears as a child in Solution Explorer.  The next version of DocProject will provide support for these extensions so that when I release a preview of the editor your existing DocProjects and DocSites will already be compatible.

There's still a lot more to do before the editor is actually usable for generating quality MAML topics, but it's on its way.  After a bit more functionality is implemented I'll blog about it in more depth and post some screenshots.  For now, check out a screenshot below of the editor as I edit a simple How To topic that was previously written using Visual Studio's XML editor.

(Note that this is just a temporary WPF app that hosts the control while I develop it.  The final app will have command buttons for semantic markup, such as database, ui, application, system, localUri, etc. and block-level elements such as section, procedure, list and table.   I didn't implement them yet because commands seem pretty simple in WPF and I wanted to concentrate on the basic editor support first, as a WPF proof of concept (I'm a first-time WPF developer :)


The image above shows a MAML topic with introduction text, a collapsible section, a procedure and a code example.  I also splashed some style in there, like the large font for the section title, just for the screenshot (the final editor will most likely get style information at runtime from WPF content resource themes so that its appearance will be completely customizable, without having to rebuild the source code).

Clicking the toggle button for the section will actually toggle the visibility of the section's content in the editor (note that the image is ugly only because it's on a button and I didn't remove the border yet).  I plan to add other controls as well for functions such as adding links, tokens and media.  The controls will actually be inside the document as part of the flow like the section toggle button - this is one of the really powerful features of WPF 3.5 flow documents.

There's even a context menu with Cut, Copy and Paste commands that I didn't have to write since it's provided by WPF.  Editing the text and everything else behaves exactly like you would expect from a WYSIWYG editor, which also means that I'm going to have to add custom logic to attach behavior to specific elements so that everything is a bit less fragile.  For example, one thing that I've done already is to add a behavior so that when the Enter key is pressed the cursor moves to a new line instead of an entirely new paragraph.  Pressing Enter a second time, while on the new blank line, will delete the blank line and start a new paragraph (it's more complicated than that, but you get the idea).  Having a new line within the same paragraph won't change the MAML output, it just provides some control over the appearance while editing.  Of course, if this is confusing or annoying I can always remove it later.

I'd like to get feedback on my ideas so that I can quickly provide an editor that people are satisfied with.  If you have any suggestions about how the editor can be improved please let know.  Thanks!

Add comment