July 08, 2008

MAML Editor: Progress II

In a previous blog post I discussed my work on a WYSIWYG editor for authoring MAML topics, either inside or outside of DocProject.  This post is simply another quick update on my progress.

Preview Release Timeline

A few weeks ago I started a new job and they put me on a project with a tight deadline so I haven't had much time to do anything else.  Last weekend I was still too busy to do much with the editor (even on July 4th) so I missed my most recent target date: yesterday.

I'll probably have time to work on the editor each night this week though so I should be able to put a working preview out there soon.  Last night I was able to almost complete key input behavior processing, which I had actually planned to work on after the preview.  I was also able to complete a few controls; e.g., the alert control now has a drop down list in the header with icon-text pairs as list items (shown in the screenshot below).  It was so easy to implement too compared to having to owner draw items in WinForms apps - WPF is really cool.  The next control I'm going to write is for MAML linking, which should be fun :)


I still have to add the command buttons but I've been deferring that because it should be pretty easy to do with limited functionality for the initial release (e.g., the editor's not schema based yet so all buttons will always be enabled.)  Although, I'll probably only add a small subset of commands initially, which will save time.

One thing that I may do for the preview though is to add the ability to insert custom command buttons through a dialog and have them associated with custom MAML markup. Once the markup is inserted, it can be parsed as if it was being loaded from a MAML file using the existing factory/parser infrastructure - that should fill in the gap nicely for MAML elements that I won't be providing support for in the initial release.  (Note that this is entirely conceptual - I don't know if it'll actually be worth the effort for the preview release.)

The other major feature that the editor is currently lacking is the ability to parse the physical flow back into MAML for save operations (it currently saves as XAML, for testing purposes).  I don't see this being a difficult process though since every element in the document is currently tagged with a parser context object, which provides direct access to the particular parser that can transform the element into MAML, in much the same way that it parses MAML into elements when a topic is loaded.  (Load functionality works fine :)

Originally I was hoping to avoid having to parse the physical flow by simply saving the in-memory LINQ to XML document (this was working for a short while during development), however I discovered later that the only change event that gets raised is the FlowDocument's TextChanged event (IIRC), making it difficult to track the relationship between changes in the flow and the underlying XDocument structure.  Although, I do see an opportunity to implement change tracking like this in the future due to my parser context and parser input behavior designs, but for the sake of time I'll probably defer it until a subsequent beta release.

Screen Capture

The following is an updated image of the same MAML topic being edited as in my last post.  It might not look like much has changed, but functionally speaking, it's now actually becoming a useful app (barring the missing save functionality :).

This time all of the styles that you see are loaded dynamically from XAML style sheets (currently embedded resources, but eventually loose XAML as well) and, although it's not obvious from the image, the editor actually behaves much more like you'd expect from a schema-based editor.  For example, pressing the Delete key at the end of the MAML Introduction will no longer cause the first section's header to move up into the introduction's paragraph.  This behavior is controlled by each individual MAML element - they define their own key press behavior using a custom preview & bubble approach, just like real WPF controls, but they also inherit some default behavior that restricts the flow a bit.

I've also started using WPF annotations for debugging (not visible in the image below) and I also plan to use them to display a delete button near the currently selected block element.  So to delete an entire section from the editor you would click anywhere inside the section and the delete button will appear, perhaps floating at the top-right corner of the element.  That's the way I think it should work for all block elements, such as the MAML introduction, section, procedure, alert table and code block shown in the image below.

(Note: The document shown below was actually loaded from a real MAML topic file.  The red squiggles are real-time spell checking errors provided by WPF and each element's styles were applied dynamically using XAML style sheets.)


Add comment