Categories: development, applications

Escaping Code for posting on the WebSite, and removing indent

In my postings, I now tend to use Code Snippets more. Along with the new Blog Theme, I also added Syntax Highlightinh using google-code-prettify, which produces really nice results, but has 2 drawbacks.

The first one is a drawback of the script itself: < has to be replaced with &lt; in all cases. The second problem is a problem with copy/pasting snippets: They tend to have an indent on the left that makes them unneccessarily wide. If I copy/paste something 4 levels deep, I have 16 spaces on the left.

I wrote myself a simple tool that essentially does two things: It replaces all opening brackets with HTML &lt;, and it removes the left indent without breaking any further indentation.

The function is really simple, maybe not the most efficient but good enough:

private void btnEscape_Click(object sender, EventArgs e)
{
    string classname = "prettyprint";
    if (cbLang.Checked)
    {
        classname += " lang-" + cbLangSelection.SelectedItem.ToString();
    }

    if (cbIndent.Checked)
    {
        int removeIndent = 0;
        foreach (string s in tbCode.Lines)
        {
            if (string.IsNullOrEmpty(s)) continue;
            int tmp = 0;
            foreach (char c in s)
            {
                if (c != ' ')
                {
                    break;
                }
                else
                {
                    tmp++;
                }
            }
            if (removeIndent == 0 || tmp < removeIndent)
            {
                removeIndent = tmp;
            }
        }
        StringBuilder sb = new StringBuilder();
        foreach (string s in tbCode.Lines)
        {
            sb.AppendLine(s.Length >= removeIndent ? s.Remove(0, removeIndent) : s);
        }
        tbCode.Text = sb.ToString();
    }

    tbCode.Text = string.Format("<pre class=\"{0}\">{1}{2}</pre>", classname, Environment.NewLine, tbCode.Text.Replace("<", "&amp;lt;"));
}

The application has a Button (btnEscape) and a Multiline Textbox (tbCode). Also, there is a Checkbox cbLang with a ComboBox cbLangSelection, and finally a second CheckBox cbIndent.

Now, the cbLang stuff is just for explicitely specifying the language the code is in for prettify.js to work. Usually, it tries to guess the language and does that quite good, but sometimes you may want to be explicit about it. Have a look at the FAQ for valid languages. The check is simple: If Checkbox clicked, append "lang-{0}" to classname.

Then, we got the indent-function. This checks every line and then every char in every line to find the length of the shortest indentation. Then, it builds a new string where it replaces the first characters up to removeIndent characters. Note that it ignores empty strings to not break on empty lines in the code.

The last function then just replaces the code in the Textbox with a pre-tag. Notice the tbCode.Text.Replace bit.

PS: If you want to add support for CTRL+A to select all text in the TextBox, use the KeyDown Event:

private void tbCode_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.KeyCode == Keys.A)
    {
        tbCode.SelectAll();
        e.Handled = true;
        e.SuppressKeyPress = true;
    }
}