Skip to main content

C# and wiki markup parsing

Wiki Markup is the syntax or keyword used by wiki websites to format a webpage. You can use *asterisks* around a word for bold and _underscore_ for italic and this is common and easy to adopt.

Examples:

  • _italic_ or {{italic}}
  • *bold* or ((bold))


Wikipedia is using a different style of wiki markup and Google project hosting (as well as Google+) is using the same wiki markup I demonstrated above.

Implementation in C#
I am using Regex to implement wiki markup in C#.

And here is the method that does the entire job required for parsing any kind of wiki markup.

private static string ReplaceWikiMarkup(this string inputString, IList<string> pairs,
                                        IList<string> startTag, IList<string> endTag)
{
    for (var i = 0; i < pairs.Count; i++)
    {
        var r = new Regex(pairs[i] + "(.*?)" + pairs[i]);
        var matches = r.Matches(inputString);
        for (var j = 0; j < matches.Count; j++)
        {
            inputString = inputString.Replace(matches[j].Groups[0].Value,
                                                      startTag[i] +
                                                            matches[j].Groups[1].Value.Trim() +
                                                      endTag[i]);
        }
    }
    return inputString;
}

Using (calling) above method:



public static string ReplaceWikiMarkup(this string inputString)
{
    inputString = inputString.Replace("*", "-b-"); /* becasue asterisk(*) is a reserved word in Regex */
    return inputString.ReplaceWikiMarkup(
                new[] { "-b-", "_" },
                new[] { "<b>", "<i>" },        /* SEO: use <strong> instead */
                new[] { "</b>", "</i>" });
}

Understanding the method 
There are 4 arguments we are passing to the method:
  • inputString - Input in any format
  • pairs - Wiki Markup syntax or keywords: *Asterisk*, _underscore_ or anything else you use
  • startTag - This can be HTML element’s empty starting tag or stating tag with any number of attributes Examples: <b><i><strong><h2 class="something"><pre style="something: something ;">
  • endTag - This is the ending tag of HTML element Examples: </b></i></strong></h2></pre>
You must be careful for the ordering of HTML elements for startTag and endTag parameters. I mean that if startTag’s first element is <b> then endTag’s first element must be </b> and so on. Heading: Extending the method Let us assume that you want to use {{{ }}} or <code></code> as wiki markup for letting end-user inject the code.
  • Code: {{{ --- }}} or <code> --- </code>
  • Heading: [[ Heading ]]
  • Bold: (( Bold ))
public static string ReplaceWikiMarkup(this string inputString, 
                                IList<string> startKeywords, /* {{{ or <code> or <h> */
                                IList<string> endKeywords,   /* }}} or </code> or </h> */
                                IList<string> startTag,      /* HTML equivalent starting tag */
                                IList<string> endTag)        /* HTML equivalent ending tag */
{
    for (var i = 0; i < startKeywords.Count; i++)
    {
        var r = new Regex(startKeywords[i] + "(.*?)" + endKeywords[i]);
        var matches = r.Matches(inputString);
        for (var j = 0; j < matches.Count; j++)
        {
            inputString = inputString.Replace(matches[j].Groups[0].Value,
                                                      startTag[i] + matches[j].Groups[1].Value.Trim() +
                                                      endTag[i]);
        }
    }
    return inputString;
}

And now we are ready to call above (changed) method:


public static string ReplaceWikiMarkup(this string inputString)
{
    inputString = inputString.Replace("*", "-b-");
    return inputString.Replace(
                new[] { "-b-", "_", "<h>", "<code>" },
                new[] { "-b-", "_", "</h>", "</code>" },
                new[] { "<b>", "<i>", "<h2>", "<pre>" },
                new[] { "</b>", "</i>", "</h2>", "</pre>" });
}

Popular posts from this blog

Save files on disk using JavaScript or JQuery!

You can save any file, or DataURL, or Blob on disk using HTML5's newly introduced "download" attribute.

Use cases:

1. Force browser to download/save files like PDF/HTML/PHP/ASPX/JS/CSS/etc. on disk
2. Concatenate all transmitted blobs and save them as file on disk - it is useful in file sharing applications

Microsoft Edge? (msSaveBlob/msSaveOrOpenBlob)https://msdn.microsoft.com/en-us/library/hh779016(v=vs.85).aspx

/** * @param {Blob} file - File or Blob object. This parameter is required. * @param {string} fileName - Optional file name e.g. "image.png" */functioninvokeSaveAsDialog(file, fileName){if(!file){throw'Blob object is required.'; }if(!file.type){ file.type ='video/webm'; }var fileExtension = file.type.split('/')[1]; if(fileName && fileName.indexOf('.')!==-1){var splitted = fileName.split('.'); fileName = splitted[0]; fileExtension = splitted[1]; }var fileFullName …

Disable ICE Trickling

ICE trickling is a process where candidate-pairs are shared as soon as gathered by the ICEAgent.

Its true that, there is NO JavaScript API "currently" available in RTCWeb drafts to disable ICE-trickling process however, there is a trick that can be used to merge all candidate pairs in the session-description, and then you merely need to share that "single" SDP only.

The trick is simple: Wait until "end-of-candidate" signal is fired.

Usually "onicecandidate" event returns "NULL" entry for "event.candidate" object.

In "old-good" days, we were watching for "oniceconnectionstatechange" event, and checking for "peer.iceGatheringState === 'complete'" to return the SDP.

BTW, you can still listen for both "end-of-candidate" NULL value, as well as "peer.iceGatheringState === 'complete'".

peer.oniceconnectionstatechange =function(event){if(peer.iceGatheringState ==='…

WebRTC Tips & Tricks

This blog post is added for WebRTC newbies and beginners who wanna learn key-ideas; get code snippets and enjoy WebRTC life!

1. How to mute/unmute media streams?Remember, mute/unmute isn't implemented as a default/native features in either media capturing draft i.e. getUserMedia API also in WebRTC draft i.e. RTCPeerConnection API.

Also, there is no "onmuted" and "onunmuted" event defined or fired in the WebRTC native implementations.

Usually, as per chromium team's suggestions, media-tracks are enabled/disabled to mute/unmute the streams.

Remember, "MediaStreamTrack.enabled=false" NEVER sends silence audio or blank/black video; it doesn't stop packet transmission. Although when you set "MediaStreamTracks.enabled=false", packets are devoid of meaningful data. A solution for this approach is to hold/unhold tracks from SDP and renegotiate the connections. See next section for more information.

MediaStream object is just a synchronous conta…