C# Wiki Markup

Star, asterisk character

Wiki markup uses symbols to format text. It uses star characters for bold tags. The same character delimits bold open and close tags in wiki syntax. It supports too italics and nesting. We develop a simple C# parser for this syntax.

Example syntax

This is some *wiki* syntax.

Example

Note

Here we have a really clean and modern implementation of the parser we need. The parser keeps track of depth. It uses Stack for this. The result is that the parser is accurate and extensible.

Stack

Tip:This approach can be used for many different parser implementations, not just wiki syntax.

Method that parses with Stack: C#

using System;
using System.Text;
using System.Collections.Generic;

/// <summary>
/// Custom static methods to be used site-wide.
/// </summary>
public static class SiteUtil
{
    /// <summary>
    /// Specifies the kind of blocks we are inside in the wiki markup.
    /// Note that we can be inside some markup within other markup.
    /// </summary>
    enum CurrentWikiTag
    {
	BoldTag,
	ItalicsTag,
	LinkTag
    };

    /// <summary>
    /// Convert some Wiki markup and syntax to HTML. This converts * and _
    /// to their equivalent HTML.
    /// </summary>
    public static string WikiMarkupToHtml(string textIn)
    {
	// Use a stack to keep track of our level.
	Stack<CurrentWikiTag> tagStack = new Stack<CurrentWikiTag>();

	// Store results in the StringBuilder.
	StringBuilder builder = new StringBuilder();

	// Examine each character in our string.
	foreach (char singleLetter in textIn)
	{
	    if (singleLetter == '*')
	    {
		// See if stack contains a star on the top.
		if (tagStack.Count > 0 && tagStack.Peek() == CurrentWikiTag.BoldTag)
		{
		    // Our top is a star. We are on the second star.
		    // So remove it and close the bold block.
		    tagStack.Pop();
		    builder.Append("</b>");
		}
		else
		{
		    // We are opening a new bold.
		    tagStack.Push(CurrentWikiTag.BoldTag);
		    builder.Append("<b>");
		}
	    }
	    else if (singleLetter == '_')
	    {
		// Same for italics tags. We use the underscore and a different enum.
		if (tagStack.Count > 0 && tagStack.Peek() == CurrentWikiTag.ItalicsTag)
		{
		    tagStack.Pop();
		    builder.Append("</i>");
		}
		else
		{
		    tagStack.Push(CurrentWikiTag.ItalicsTag);
		    builder.Append("<i>");
		}
	    }
	    else
	    {
		// Simply append any non-markup characters.
		builder.Append(singleLetter);
	    }
	}
	return builder.ToString();
    }
}
Enum type

The example uses an enumeration of tags. There is an enumeration that stores types of tags that we have encountered. The BoldTag tracks whether we are in a bold section in the markup, for example.

EnumStack

This is a Stack generic collection that stores the tags we have encountered. When we encounter a star, we add a BoldTag to the top of the Stack. The brunt of the method is running the foreach-loop over each character.

Foreach

More on Stack. Count returns the number of items in the Stack. You must check this (with an if-statement) before using Pop, which removes the top element. Push adds a new top element, and Peek lets you see what is on top of the Stack.

IfString type

The StringBuilder is converted to a string and then returned. The hardest part is the Stack methods and the object itself. If you are like me, you have plenty of stacks around your residence.

StringBuilder Secrets

Tip:Computer stacks are just like real-life stacks, except there are some different terms.

Discussion

I use it on parsing code on the strings in my XML files to convert simple wiki markup to HTML. It is easy to store wiki markup in XML, but HTML is hard because it uses the same basic bracket syntax as XML and would need escaping.

And:Wiki syntax provides an excellent compromise between the power of HTML and the simplicity of plain text.

HTMLXML

Many enhancements could be made, including adding hyperlink support or more various tags to detect. Also, you could refactor this code to use a lookup table or Dictionary. It would be shorter and probably faster.

Dictionary

Summary

The C# programming language

Stacks offer us a powerful and simple way to implement depth tracking in a parser. They are ideal for wiki syntax and HTML. Wiki syntax is wonderful to use with XML, but some C# code to parse it is necessary.

Review:We use Stack and StringBuilder to make wiki syntax and HTML play nice together.


C#: Method: Algorithm