Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#

A Code Project Article Editor with Live Preview

Rate me:
Please Sign up or sign in to vote.
4.84/5 (62 votes)
5 Aug 2009CPOL5 min read 112.8K   3.9K   148   32
A tool to help author articles at The Code Project
screenshot_small.png

Click image for full screenshot - 306 KB

Table of Contents

{ Automatically generated Table of Contents }

Introduction

This is a short article about an HTML editor I assembled with special support for writing articles at The Code Project.

Background

Office 2007 doesn't contain a version of Frontpage, which I used to use to write articles. I didn't want to install Frontpage 2003 over Office 2007 "just in case!" So, I had a look around for an HTML editor that can show a preview side-by-side with the raw HTML. Visual Studio was the best one I found, but the preview has to be below the HTML, which is not what I want on my widescreen monitors. So I decided to write one myself. Here it is and I hope you find it useful.

Note: As Derek Bartram pointed out in the message board below, Visual Studio 2008 can split the source and design views vertically. The setting is:

Tools | Options | HTML Designer | General | Split views vertically

Assembly Instructions

It's a basic Windows Forms application with Weifen Luo's DockPanel Suite [^], so you can arrange the panes just how you want them. The editor is part of #develop from the ic#code [^] people. I also used their #ziplib. The preview pane is a plain old WebBrowser control.

Using BobBuilder

Window Types

There are two types of windows in BobBuilder: editor and preview. You must have exactly one editor window open for each document, but you can have any number of preview windows open.

Editor Windows

The TextEditor control from #develop has lots of nice features, like undo/redo and syntax highlighting. It also has loads of options that I have surfaced in the Tools | Options dialog. I have added shortcuts for some HTML tags like <code> and <pre>, which are often found in articles at The Code Project. Also, when you are in an opening tag, pressing TAB will close the tag for you and put the caret in the middle.

Autocomplete

To help prevent illegal HTML being rendered, there are a few "autocompleted" characters. Firstly, if you type a <, you will get <>. Then if you are inside a tag, the quote, ", and single quote, ', characters will double up.

Preview Windows

The preview windows update continuously while you use the editor. If you have a system sound set for the "Navigation Started" event, you might like to disable it! The preview windows attempt to remember their scroll positions at each update, but this is not possible if illegal HTML is rendered.

Toolstrips

There are buttons for the standard formattings like bold and italic. There is also an Action to insert a clickety.

Table of Contents

There are a menu item and a toolstrip button to insert a Table of Contents. This command parses the HTML using Regexs for all <hN> tags and inserts anchors around them. It then adds unordered lists of links to make the table. If a table already exists, then it will be replaced. Otherwise, the new table is inserted at the current caret position.

Known Issues

Links

Any relative hyperlinks, for example to anchors, do not work in the preview windows. This is because the HTML is passed to the WebBrowser controls using their DocumentText property. When this happens, the WebBrowser sets the URI to about:blank and things stop working...

However, before the HTML is passed to the WebBrowser control, it is modified a bit. Some JavaScript is added to help maintain the scroll position and a <base> tag is added to make any inline references work, such as images. You can always save the document and use Tools | External Browser to quickly check that your relative links are working.

Note: when you upload your article, the HTML will be put in one of the main directories, but all other files (images, ZIPs, ... ) will be put in a subdirectory named the same as the basename of the article. For example, BobBuilder.aspx is in /KB/cs/ and all other files are in /KB/cs/BobBuilder/. You might like to replicate this structure locally when you are writing your article.

Points of Interest

There are a couple of points to highlight:

Design Patterns

I implemented the MVC pattern, but with a twist: I used the Observer pattern with the views subscribing to the (Singleton) controller as publisher. When an action is initiated, a command is sent to the controller using a normal method call. The controller does its work, firing events to communicate with any participating views.

A neat feature of the .NET event implementation of Observer is that the subscribers can alter the EventArgs derived parameter, so passing information back to the publisher. This is demonstrated in the implementation of the CurrentDocument property:

C#
partial class Controller
{
   public static Document CurrentDocument
   {
      get
      {
         return Instance
            .ExecuteCore( null, new Command.GetCurrentDocument() )
            .Document;
      }
   }
}

Instance gets the Singleton instance and ExecuteCore is a member method which returns its Command parameter. For the GetCurrentDocument command, all ExecuteCore does is raise the static Execute event. All the views have subscribed to this event and, when the currently active view handles it, it fills in the Document property of the command with its own (the current) document. So, when the event returns after calling all the views in its invocation list, the Document property has been set by the current view and is returned to whoever needs it.

This pattern made life easier than having the controller maintain a collection of some view interface. Now this is all taken care of by the built-in event handling, while reducing the coupling between the controller and the views.

System.Windows.Forms.Keys

I could not find a .NET way to determine the right member of this enumeration for a given char. In the end, I wrote this snippet:

C#
[System.Runtime.InteropServices.DllImport( "user32.dll" )]
static extern short VkKeyScan( char ch );
   
static Keys ConvertToKeys( char c )
{
   short vk = VkKeyScan( c );
   int key = vk & 0x00FF;
   int mod = vk & 0xFF00;
   int iKeys = ( mod << 8 ) | key;
   Keys eKeys = ( Keys ) iKeys;
   return eKeys;
}

TODO

This is a short list of possible future enhancements. Please leave a comment below if you have any opinions or ideas.

  • Spelling checker
  • More common formattings
  • Configurable shortcuts
  • Macro compiler
  • Remember toolstrip positions
  • Handle exceptions better

References

History

2008 Feb 01:

Initial release

2008 Feb 01:Removed smileys
2008 Feb 03:Added auto-generation of Table of Contents
2008 Feb 07:Fixed auto-generation of Table of Contents
2009 Aug 05: Fixed preview placement with new DOCTYPE in template

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
I discovered C# and .NET 1.0 Beta 1 in late 2000 and loved them immediately.
I have been writing software professionally in C# ever since

In real life, I have spent 3 years travelling abroad,
I have held a UK Private Pilots Licence for 20 years,
and I am a PADI Divemaster.

I now live near idyllic Bournemouth in England.

I can work 'virtually' anywhere!

Comments and Discussions

 
GeneralMy vote of 5 Pin
Mazen el Senih24-Sep-12 6:38
professionalMazen el Senih24-Sep-12 6:38 
GeneralRe: My vote of 5 Pin
Nicholas Butler24-Sep-12 7:55
sitebuilderNicholas Butler24-Sep-12 7:55 
GeneralMy vote of 5 Pin
adriancs20-Apr-12 18:10
mvaadriancs20-Apr-12 18:10 
GeneralMy vote of 5 Pin
ProEnggSoft7-Mar-12 18:40
ProEnggSoft7-Mar-12 18:40 
GeneralGreat App for Speed Pin
Jeff B. Cromwell7-Mar-12 11:55
Jeff B. Cromwell7-Mar-12 11:55 
GeneralQuestion about CSS Pin
damien025-May-10 4:12
damien025-May-10 4:12 
GeneralA Suggestion. Pin
Abhishek Shekhar27-Apr-10 2:26
Abhishek Shekhar27-Apr-10 2:26 
GeneralSo cool Pin
Marcelo Ricardo de Oliveira5-Aug-09 9:49
mvaMarcelo Ricardo de Oliveira5-Aug-09 9:49 
GeneralGreat tool Pin
David MacDermot12-Jun-09 16:18
David MacDermot12-Jun-09 16:18 
Generalprogrammming errer Pin
paballo12-Mar-08 0:51
paballo12-Mar-08 0:51 
GeneralRe: programmming errer PinPopular
Paul Conrad21-Sep-08 7:23
professionalPaul Conrad21-Sep-08 7:23 
GeneralPreview below html in Visual Studio Pin
Derek Bartram5-Feb-08 10:14
Derek Bartram5-Feb-08 10:14 
GeneralRe: Preview below html in Visual Studio Pin
Nicholas Butler6-Feb-08 2:46
sitebuilderNicholas Butler6-Feb-08 2:46 
GeneralBob the Builder is very nice Pin
Sue H5-Feb-08 4:31
Sue H5-Feb-08 4:31 
GeneralRe: Bob the Builder is very nice Pin
Nicholas Butler5-Feb-08 5:54
sitebuilderNicholas Butler5-Feb-08 5:54 
QuestionBug? Pin
georani1-Feb-08 7:42
georani1-Feb-08 7:42 
AnswerRe: Bug? Pin
Nicholas Butler1-Feb-08 8:01
sitebuilderNicholas Butler1-Feb-08 8:01 
Hi,

There is an option ( Tools | Options ) that allows you to try to download the template from www.codeproject.com when you open a new document. If the download fails, you can get this error. Either try again, or turn the option off.

Thanks for your feedback Smile | :) I know this could be handled better...

----------------------------------
Be excellent to each other Smile | :)

GeneralRe: Bug? Pin
georani2-Feb-08 2:00
georani2-Feb-08 2:00 
GeneralRe: Bug? Pin
Nicholas Butler2-Feb-08 3:30
sitebuilderNicholas Butler2-Feb-08 3:30 
GeneralRe: Bug? Pin
soho5-Feb-08 20:42
soho5-Feb-08 20:42 
GeneralRe: Bug? Pin
thund3rstruck6-Aug-09 7:44
thund3rstruck6-Aug-09 7:44 
AnswerRe: Bug? Pin
Nicholas Butler6-Aug-09 7:57
sitebuilderNicholas Butler6-Aug-09 7:57 
GeneralThis will save me a lot of headaches Pin
Bharat Mallapur1-Feb-08 4:18
Bharat Mallapur1-Feb-08 4:18 
GeneralRe: This will save me a lot of headaches Pin
Nicholas Butler1-Feb-08 5:01
sitebuilderNicholas Butler1-Feb-08 5:01 
GeneralRe: This will save me a lot of headaches Pin
Vertyg01-Feb-08 22:18
Vertyg01-Feb-08 22:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.