Friday, February 4, 2011

Is there a lang-vb or lang-basic option for prettify.js from Google?

Visual Basic code does not render correctly with prettify.js from Google.

on Stack Overflow:

Partial Public Class WebForm1
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'set page title
        Page.Title = "Something"
    End Sub

End Class

in Visual Studio...

Visual Basic in Visual Studio

I found this in the README document:

How do I specify which language my code is in?

You don't need to specify the language since prettyprint() will guess. You can specify a language by specifying the language extension along with the prettyprint class like so:

<pre class="prettyprint lang-html">
  The lang-* class specifies the language file extensions.
  Supported file extensions include
    "c", "cc", "cpp", "cs", "cyc", "java", "bsh", "csh", "sh",
    "cv", "py", "perl", "pl", "pm", "rb", "js",
    "html", "html", "xhtml", "xml", "xsl".
</pre>

I see no lang-vb or lang-basic option. Does anyone know if one exists as an add-in?


Note: This is related to the VB.NET code blocks suggestion for Stack Overflow.

  • So your asking us if we know more than the actual README issued with it, even though there is a clear "supported file extensions"??

    PS: I like your bio :D Aren't we all man :)

    Zack Peterson : I've added an "as an add-in" qualifier to my question
    From Rob Cooper
  • Awesome ;)

    From what I can see, there is no real alternative due to the fundamental way that prettify deals with newlines etc..

    Man that may be an issue for SO considering it needs to be language-agnostic :S

    +1'ed ;)

    From Rob Cooper
  • /EDIT: I've rewritten the whole posting.

    Below is a pretty complete solution to the VB highlighting problem. If SO has got nothing better, please use it. VB syntax highlighting is definitely wanted.

    I've also added a code example with some complex code literals that gets highlighted correctly. However, I haven't even tried to get XLinq right. Might still work, though. The keywords list is taken from the MSDN. Contextual keywords are not included. Did you know the GetXmlNamespace operator?

    The algorithm knows literal type characters. It should also be able to handle identifier type characters but I haven't tested these. Note that the code works on HTML. As a consequence, &, < and > are required to be read as named (!) entities, not single characters.

    Sorry for the long regex.

    var highlightVB = function(code) {
        var regex = /("(?:""|[^"])+"c?)|('.*$)|#.+?#|(&amp;[HO])?\d+(\.\d*)?(e[+-]?\d+)?U?([SILDFR%@!#]|&amp;)?|\.\d+[FR!#]?|\s+|\w+|&amp;|&lt;|&gt;|([-+*/\\^$@!#%&<>()\[\]{}.,:=]+)/gi;
    
        var lines = code.split("\n");
        for (var i = 0; i < lines.length; i++) {
            var line = lines[i];
    
            var tokens;
            var result = "";
    
            while (tokens = regex.exec(line)) {
                var tok = getToken(tokens);
                switch (tok.charAt(0)) {
                    case '"':
                        if (tok.charAt(tok.length - 1) == "c")
                            result += span("char", tok);
                        else
                            result += span("string", tok);
                        break;
                    case "'":
                        result += span("comment", tok);
                        break;
                    case '#':
                        result += span("date", tok);
                        break;
                    default:
                        var c1 = tok.charAt(0);
    
                        if (isDigit(c1) ||
                            tok.length > 1 && c1 == '.' && isDigit(tok.charAt(1)) ||
                            tok.length > 5 && (tok.indexOf("&amp;") == 0 &&
                            tok.charAt(5) == 'H' || tok.charAt(5) == 'O')
                        )
                            result += span("number", tok);
                        else if (isKeyword(tok))
                            result += span("keyword", tok);
                        else
                            result += tok;
                        break;
                }
            }
    
            lines[i] = result;
        }
    
        return lines.join("\n");
    }
    
    var keywords = [
        "addhandler", "addressof", "alias", "and", "andalso", "as", "boolean", "byref",
        "byte", "byval", "call", "case", "catch", "cbool", "cbyte", "cchar", "cdate",
        "cdec", "cdbl", "char", "cint", "class", "clng", "cobj", "const", "continue",
        "csbyte", "cshort", "csng", "cstr", "ctype", "cuint", "culng", "cushort", "date",
        "decimal", "declare", "default", "delegate", "dim", "directcast", "do", "double",
        "each", "else", "elseif", "end", "endif", "enum", "erase", "error", "event",
        "exit", "false", "finally", "for", "friend", "function", "get", "gettype",
        "getxmlnamespace", "global", "gosub", "goto", "handles", "if", "if",
        "implements", "imports", "in", "inherits", "integer", "interface", "is", "isnot",
        "let", "lib", "like", "long", "loop", "me", "mod", "module", "mustinherit",
        "mustoverride", "mybase", "myclass", "namespace", "narrowing", "new", "next",
        "not", "nothing", "notinheritable", "notoverridable", "object", "of", "on",
        "operator", "option", "optional", "or", "orelse", "overloads", "overridable",
        "overrides", "paramarray", "partial", "private", "property", "protected",
        "public", "raiseevent", "readonly", "redim", "rem", "removehandler", "resume",
        "return", "sbyte", "select", "set", "shadows", "shared", "short", "single",
        "static", "step", "stop", "string", "structure", "sub", "synclock", "then",
        "throw", "to", "true", "try", "trycast", "typeof", "variant", "wend", "uinteger",
        "ulong", "ushort", "using", "when", "while", "widening", "with", "withevents",
        "writeonly", "xor", "#const", "#else", "#elseif", "#end", "#if"
    ]
    
    var isKeyword = function(token) {
        return keywords.indexOf(token.toLowerCase()) != -1;
    }
    
    var isDigit = function(c) {
        return c >= '0' && c <= '9';
    }
    
    var getToken = function(tokens) {
        for (var i = 0; i < tokens.length; i++)
            if (tokens[i] != undefined)
                return tokens[i];
        return null;
    }
    
    var span = function(class, text) {
        return "<span class=\"" + class + "\">" + text + "</span>";
    }
    

    Code for testing:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        'set page title'
        Page.Title = "Something"
        Dim r As String = "Say ""Hello"""
        Dim i As Integer = 1234
        Dim d As Double = 1.23
        Dim s As Single = .123F
        Dim l As Long = 123L
        Dim ul As ULong = 123UL
        Dim c As Char = "x"c
        Dim h As Integer = &amp;H0
        Dim t As Date = #5/31/1993 1:15:30 PM#
        Dim f As Single = 1.32e-5F
    End Sub
    
    Mark Nold : Konrad, this issue is now fixed in Prettify itself, though not implemented on SO.
    Konrad Rudolph : @Mark: Yes, I'm aware of this … see the Uservoice discussion. But as you said, SO unfortunately still doesn't implement it, and the Uservoice report has been declined.
  • In the meantime, you can put an extra comment character at the end of your comments to get it to look okay. For example:

    Sub TestMethod()
        'Method body goes here'
    End Sub
    

    You also need to escape internal comment characters in the normal vb-fashion:

    Sub TestMethod2()
        'Here''s another comment'
    End Sub
    

    Prettify still treats it as a string literal rather than a comment, but at least it looks okay.

    Another method I've seen is to start comments with an extra '//, like this:

    Sub TestMethod3()
        ''// one final comment
    End Sub
    

    Then it's handled like a comment, but you have to deal with C-style comment markers

    EndangeredMassa : Yes, but in that case you could simply use "//". The reason that people use "''//" is that it looks like a comment AND it compiles in VB as a comment.
    Joel Coehoorn : Since we're talking about vb snippets, its probably a good idea to make sure that they will at least compile when copy/pasted into the IDE.
  • Prettify does support VB comments as of the 8th of January 2009.

    To get vb syntax highlighting working correctly you need three things;

    <script type="text/javascript" src="/External/css/prettify/prettify.js"></script>
    <script type="text/javascript" src="/External/css/prettify/lang-vb.js"></script>
    

    and a PRE block around your code eg:

    <PRE class="prettyprint lang-vb">
     Function SomeVB() as string
       ' do stuff
       i = i + 1
     End Function
    </PRE>
    

    Stackoverflow is missing the lang-vb.js inclusion, and the ability to specify which language via Markdown, ie: class="prettyprint lang-vb" which is why it doesn't work here.

    for details on the issue: see the Prettify issues log

    From Mark Nold

0 comments:

Post a Comment