1  /  1  页   1 跳转 查看:808

.NET CodeToHTML

.NET CodeToHTML

author/Paschal L  from/dotnetslackers.com

This article shows you how to convert source code to HTML.

Introduction
The aim of this article is to share with you something I found was really challenging for me to build. I had to include some code in different articles (including this one) and I wanted to get the code colorized and properly formatted.

I was amazed by the lack of information on HTML syntax coloring in VB.NET.

If you are a PERL programmer then you are lucky as you have the Code2HTML library. My PERL skills being very poor, I decided to write something for the .NET platform. This example can be used with .NET 2.0 and above.

The only change needed for .NET 1.1 will be to change the FileUpload control on the .aspx page with an Input File web control.

You can also use this article as a way to learn more about regular expressions.

How it works
The code is pretty much self-explanatory, but the idea behind it is something like this:

Set the language
Find the number of visible lines
For each visible line, color it
Supported languages
This tool currently supports the main .NET languages: VB.NET, C# and JavaScript. It can also colorize .aspx and HTML pages.

There is a method which can be used to set up the language automatically according to the file extension. You can also of course use a dropdown to select a language.



引用:
Private Sub SetLanguageFromFileName(ByVal FilePath As String) 
        ' Find the current language from the file extension   
        If FilePath.Split(Convert.ToChar(".")).Length > 0 Then 
            Dim sFileExtension As String = FilePath.Substring( 
                              FilePath.LastIndexOf(Convert.ToChar(".")) + 1) 
            Select Case sFileExtension.ToLower().Trim() 
                Case ProgrammingLanguage.VB 
                    _Language = ProgrammingLanguage.VB 
                Case ProgrammingLanguage.CSharp 
                    _Language = ProgrammingLanguage.CSharp 
                Case ProgrammingLanguage.JavaScript 
                    _Language = ProgrammingLanguage.JavaScript 
            End Select 
        End If 
    End Sub 



Extending the languages support
To extend the list of languages, you need to add a new constant in the Language class:



引用:
Private Class ProgrammingLanguage 
    Public Const VB As String = "vb" 
    Public Const CSharp As String = "cs" 
    Public Const JavaScript As String = "js" 
End Class 
    Private Class ProgrammingLanguage
        Public Const VB As String = "vb"
        Public Const CSharp As String = "cs"
        Public Const JavaScript As String = "js"
    End Class


Now you have to write a function to define the list of keywords used by the language. A regular expression will then match those tags and add some HTML tags to colorize the lines.



引用:
Private Function FixVBLine(ByVal sInputLine As String) As String 
        Dim sOutput As String = sInputLine 
        If sInputLine.Length = 0 Then 
            Return sInputLine 
        End If 
        sOutput = Regex.Replace(sInputLine, "(?i)(\t)", " ") 
        sOutput = HttpUtility.HtmlEncode(sOutput) 
        Dim sKeywords() As String = { 
"AddressOf", "Delegate", "Optional", "ByVal", "ByRef", "Decimal", "Boolean", "Option", 
"Compare", "Binary", "Text", "On", "Off", "Explicit", "Strict", "Private",   
"Protected", "Public", "End Namespace", "Namespace", "End Class", "Exit", "Class",   
"Goto", "Try", "Catch", "End Try", "For", "End If", "If", "Else", "ElseIf", "Next",   
"While", "And", "Do", "Loop", "Dim", "As", "End Select", "Select", "Case", "Or",   
"Imports", "Then", "Integer", "Long", "String", "Overloads", "True", "Overrides", "End 
Property", "End Sub", "End Function", "Sub", "Me", "Function", "End Get", "End Set", 
"Get", "Friend", "Inherits", "Implements", "Return", "Not", "New", "Shared",   
"Nothing", "Finally", "False", "Me", "My", "MyBase", "End Enum", "Enum" } 
        Dim CombinedKeywords As String = "(?<keyword>" + String.Join("|", sKeywords)   
                                              + ")" 
        sOutput = Regex.Replace(sOutput, "(?i)\b" + CombinedKeywords + "\b(?<!'.*)", 
                                  TAG_FNTBLUE + "${keyword}" + TAG_EFONT) 
        sOutput = Regex.Replace(sOutput, "(?<comment>'(?![^']*").*$)", 
                                  TAG_FNTGRN + "${comment}" + TAG_EFONT) 
        Return sOutput 
    End Function


Scripts embedded in an ASP.NET page
So what about the conversion of scripts languages in an .aspx page? Easy, a method is used to identify the script tag and the language used (see below), then the script lines are converted in the same way as a separate code file.



引用:
Private Function GetLanguageFromLine(ByVal sInputLine As String, ByVal DefaultLanguage As String) As String 
 
        ' Returns name of the language   
        Dim sReturn As String = DefaultLanguage 
        If sInputLine.Length = 0 Then 
            Return sReturn 
        End If 
        Dim LanguageMatch As Match = RegularExpressions.Regex.Match(sInputLine, 
                          "(?i)<%@\s*Page\s*.*Language\s*=\s*""(?<lang>[^""]+)""") 
        If LanguageMatch.Success Then 
            sReturn = LanguageMatch.Groups("lang").ToString() 
        End If 
        LanguageMatch = RegularExpressions.Regex.Match(sInputLine,   
"(?i)(?=.*runat\s*=\s*""?server""?)<script.*language\s*=\s*""(?<lang>[^""]+)"".*>") 
        If LanguageMatch.Success Then 
            sReturn = LanguageMatch.Groups("lang").ToString() 
        End If 
        LanguageMatch = RegularExpressions.Regex.Match(sInputLine, 
"(?i)<%@\s*WebService\s*.*Language\s*=\s*""?(?<lang>[^""]+)""?") 
        If LanguageMatch.Success Then 
            sReturn = LanguageMatch.Groups("lang").ToString() 
        End If 
 
        ' "CS" instead of "C#" ?   
        If sReturn = "CS" Then 
            sReturn = ProgrammingLanguage.CSharp 
        End If 
        Return sReturn 
    End Function
 

Rendering the code source
CodeToHtml is capable of converting your code source from a file or from a string. A series of overload methods provide all the means for that.

For the File option, one method let's you pass a Filepath then render the file to the page. The other overload method writes the converted file to disk using an output path (on the server).



引用:
Public Overloads Function RenderFile(ByVal FilePath As String) As String 
        ' errors?   
        SetLanguageFromFileName(FilePath) 
        Return Render(IO.File.OpenText(FilePath)) 
    End Function 
 
    Public Overloads Sub RenderFile(ByVal FilePath As String,   
                                  ByVal OutputFilePath As String) 
        ' Render and throw error   
        SetLanguageFromFileName(FilePath) 
        Dim MyStreamWriter As New IO.StreamWriter(OutputFilePath) 
        MyStreamWriter.Write(Render(IO.File.OpenText(FilePath))) 
        MyStreamWriter.Flush() 
        MyStreamWriter.Close() 
    End Sub


 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [Visual Studio.NET] 的这些文章也感兴趣:

如何获取当前路径?
祝贺SharpDevelop中文站开通,让我们共同来挖掘#develop的强大功能吧!
BlogEngine.Net架构与源代码分析系列part6:开放API——MetaWeblog与BlogImporter
对于.NET程序员,这是否是XSLT的终结?
DotNet for Symbian平台 (Nokia,Sony,Motorola等手机)
绝佳创意:通过手机短信来控制电脑的“执行者”
Presentation: Windows as a Web Platform
VB 6 to VB.NET Migration Proceeds Ever So Slowly
为通过ClickOnce部署的应用程序配置文件类型
在Visual Studio 2005中打开Share Source CLI 2.0(Rotor)
 

回复:.NET CodeToHTML

Code
Now it's time to see the full code (VB.NET). The C# equivalent can be done easily from this source.

The example included here uses a FileUpload web control and a simple button to convert the selected file and return it through a Literal control.

For the purpose of this article, I have kept all the code in one place, but you can also create a separate class if you need too. Because the source code is converted in HTML, it should not interfere with anything on the web page, but just in case I use a <pre> tag to clearly identify the result.

When you click the button a click event is raised, the language property is set up according to the file extension. Then the file is read and the render method is called up on the string.

Listing 1: Full listing Default.aspx
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="CCodeToHTML._Default" %> 
 


引用:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";> 
<html xmlns="http://www.w3.org/1999/xhtml";> 
<head runat="server"> 
    <title>Untitled Page</title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div> 
        <asp:FileUpload ID="FileUpload1" runat="server" /> 
        <asp:Button ID="Button1" runat="server" 
            Text="Button" /> 
        <pre> 
    <asp:Literal ID="FileResult" runat="server" /> 
    </pre> 
    </div> 
    </form> 
</body> 
</html> 


Listing 2: Full listing Default.aspx.vb


引用:
Imports System.IO 
 
Partial Class _Default 
    Inherits System.Web.UI.Page 
 
 
    Protected Sub Button1_Click(ByVal sender As Object,   
                                ByVal e As System.EventArgs) Handles Button1.Click 
        If Not (FileUpload1.PostedFile Is Nothing) Then 
            Dim myFile As String = "" 
            Dim fileName As String = FileUpload1.PostedFile.FileName 
            SetLanguageFromFileName(fileName) 
            Dim srRead As StreamReader = File.OpenText(fileName) 
            FileResult.Text = Render(srRead) 
        End If 
    End Sub 
 
    Private _ShowFileName As Boolean = False 
    Private _FontSize As Integer = 3 
    Private _Language As String = "" 
    Private Const TAG_FNTRED As String = "<font color=""red"">" 
    Private Const TAG_FNTBLUE As String = "<font color=""blue"">" 
    Private Const TAG_FNTGRN As String = "<font color=""green"">" 
    Private Const TAG_FNTMRN As String = "<font color=""maroon"">" 
    Private Const TAG_EFONT As String = "</font>" 
 
    Public Property ShowFileName() As Boolean 
        Get 
            Return _ShowFileName 
        End Get 
        Set(ByVal Value As Boolean) 
            _ShowFileName = Value 
        End Set 
    End Property 
 
    Public Property FontSize() As Integer 
        Get 
            Return _FontSize 
        End Get 
        Set(ByVal Value As Integer) 
            _FontSize = Value 
        End Set 
    End Property 
 
    Public Property Language() As String 
        Get 
            Return _Language 
        End Get 
        Set(ByVal Value As String) 
            _Language = Value 
        End Set 
    End Property 
 
    Private Sub SetLanguageFromFileName(ByVal FilePath As String) 
        ' Find the current language from the file extension   
        If FilePath.Split(Convert.ToChar(".")).Length > 0 Then 
            Dim sFileExtension As String = FilePath.Substring(FilePath.LastIndexOf(Convert.ToChar(".")) + 1) 
            Select Case sFileExtension.ToLower().Trim() 
                Case ProgrammingLanguage.VB 
                    _Language = ProgrammingLanguage.VB 
                Case ProgrammingLanguage.CSharp 
                    _Language = ProgrammingLanguage.CSharp 
                Case ProgrammingLanguage.JavaScript 
                    _Language = ProgrammingLanguage.JavaScript 
            End Select 
        End If 
    End Sub 
 
    Public Overloads Function RenderFile(ByVal FilePath As String) As String 
        ' errors?   
        SetLanguageFromFileName(FilePath) 
        Return Render(IO.File.OpenText(FilePath)) 
    End Function 
 
    Public Overloads Sub RenderFile(ByVal FilePath As String,   
                                    ByVal OutputFilePath As String) 
        ' Render and throw error   
        SetLanguageFromFileName(FilePath) 
        Dim MyStreamWriter As New IO.StreamWriter(OutputFilePath) 
        MyStreamWriter.Write(Render(IO.File.OpenText(FilePath))) 
        MyStreamWriter.Flush() 
        MyStreamWriter.Close() 
    End Sub 
 
    Public Overloads Function Render(ByVal InputTextReader As IO.StreamReader) As String 
        Return Render(InputTextReader.ReadToEnd()) 
    End Function 
 
    Public Overloads Function Render(ByVal InputString As String) As String 
        Dim MyStringBuilder As New System.Text.StringBuilder() 
        Dim MyStringWriter As New System.IO.StringWriter(MyStringBuilder) 
 
        ' Split into a string array for processing 
        Dim InputLines() As String = InputString.Split(vbCrLf) 
        Dim sInputLine As String 
 
        ' Write out the font size   
        MyStringWriter.WriteLine("<font size=""" & _FontSize & """ \>") 
 
 
        ' Process the language   
        Select Case _Language.Trim.ToLower() 
 
            Case ProgrammingLanguage.CSharp 
                MyStringWriter.WriteLine("<pre>") 
                For Each sInputLine In InputLines 
                    MyStringWriter.Write(FixCSLine(sInputLine)) 
                Next 
                MyStringWriter.WriteLine("</pre>") 
            Case ProgrammingLanguage.JavaScript 
                MyStringWriter.WriteLine("<pre>") 
                For Each sInputLine In InputLines 
                    MyStringWriter.Write(FixJSLine(sInputLine)) 
                Next 
                MyStringWriter.WriteLine("</pre>") 
            Case ProgrammingLanguage.VB 
                MyStringWriter.WriteLine("<pre>") 
                For Each sInputLine In InputLines 
                    MyStringWriter.Write(FixVBLine(sInputLine)) 
                Next 
                MyStringWriter.WriteLine("</pre>") 
            Case Else 
                Dim bIsInScriptBlock As Boolean = False 
                Dim bIsInMultiLine As Boolean = False 
                MyStringWriter.WriteLine("<pre>") 
                For Each sInputLine In InputLines 
                    ' get the global language from a page directive   
                    _Language = GetLanguageFromLine(sInputLine, _Language) 
 
                    If IsScriptBlockTagStart(sInputLine) Then 
                        MyStringWriter.Write(FixASPXLine(sInputLine)) 
                        bIsInScriptBlock = True 
                    ElseIf IsScriptBlockTagEnd(sInputLine) Then 
                        MyStringWriter.Write(FixASPXLine(sInputLine)) 
                        bIsInScriptBlock = False 
                    ElseIf IsMultiLineTagStart(sInputLine) And bIsInMultiLine = False Then 
                        MyStringWriter.Write("<font color=blue><b>" + 
                                            HttpUtility.HtmlEncode(sInputLine)) 
                        bIsInMultiLine = True 
                    ElseIf IsMultiLineTagEnd(sInputLine) And bIsInMultiLine = True Then 
                        MyStringWriter.Write(HttpUtility.HtmlEncode(sInputLine) + 
                                            "</b></font>") 
                        bIsInMultiLine = False 
                    ElseIf bIsInMultiLine Then 
                        MyStringWriter.Write(HttpUtility.HtmlEncode(sInputLine)) 
                    Else 
                        If bIsInScriptBlock Then 
                            Select Case _Language.Trim.ToLower() 
                                Case ProgrammingLanguage.CSharp 
                                    MyStringWriter.Write(FixCSLine(sInputLine)) 
                                Case ProgrammingLanguage.JavaScript 
                                    MyStringWriter.Write(FixJSLine(sInputLine)) 
                                Case ProgrammingLanguage.VB 
                                    MyStringWriter.Write(FixVBLine(sInputLine)) 
                                Case Else 
                                    MyStringWriter.Write(FixVBLine(sInputLine)) 
                            End Select 
                        Else 
                            MyStringWriter.Write(FixASPXLine(sInputLine)) 
                        End If 
                    End If 
                Next 
                MyStringWriter.WriteLine("</pre>") 
                'aspx-page sorted out   
        End Select 
 
        MyStringWriter.WriteLine("</font>") 
        MyStringWriter.Flush() 
        Return MyStringBuilder.ToString() 
    End Function 
 
    Private Function GetLanguageFromLine(ByVal sInputLine As String,   
                                        ByVal DefaultLanguage As String) As String 
 
        ' Returns name of the language   
        Dim sReturn As String = DefaultLanguage 
        If sInputLine.Length = 0 Then 
            Return sReturn 
        End If 
        Dim LanguageMatch As Match = RegularExpressions.Regex.Match(sInputLine, 
"(?i)<%@\s*Page\s*.*Language\s*=\s*""(?<lang>[^""]+)""") 
        If LanguageMatch.Success Then 
            sReturn = LanguageMatch.Groups("lang").ToString() 
        End If 
        LanguageMatch = RegularExpressions.Regex.Match(sInputLine,   
"(?i)(?=.*runat\s*=\s*""?server""?)<script.*language\s*=\s*""(?<lang>[^""]+)"".*>") 
        If LanguageMatch.Success Then 
            sReturn = LanguageMatch.Groups("lang").ToString() 
        End If 
        LanguageMatch = RegularExpressions.Regex.Match(sInputLine,   
"(?i)<%@\s*WebService\s*.*Language\s*=\s*""?(?<lang>[^""]+)""?") 
        If LanguageMatch.Success Then 
            sReturn = LanguageMatch.Groups("lang").ToString() 
        End If 
 
        ' "CS" instead of "C#" ?   
        If sReturn = "CS" Then 
            sReturn = ProgrammingLanguage.CSharp 
        End If 
        Return sReturn 
    End Function 
 
    Private Function FixCSLine(ByVal sInputLine As String) As String 
        Dim sOutput As String = sInputLine 
        If sInputLine.Length = 0 Then 
            Return sInputLine 
        End If 
        sOutput = Regex.Replace(sInputLine, "(?i)(\t)", " ") 
 
        sOutput = HttpUtility.HtmlEncode(sOutput) 
        Dim sKeywords() As String = {"private", "protected", "public", "namespace",   
"class", "break", "for", "if", "else", "while", "switch", "case", "using", "return", 
"null", "void", "int", "bool", "string", "float", "this", "new", "true", "false",   
"const", "static", "base", "foreach", "in", "try", "catch", "get", "set", "char",   
"default"} 
        Dim sCombinedKeywords As String = "(?<keyword>" &   
                                            String.Join("|", sKeywords) & ")" 
        sOutput = Regex.Replace(sOutput, "\b" & sCombinedKeywords & "\b(?<!//.*)", 
                                TAG_FNTBLUE & "${keyword}" & TAG_EFONT) 
 
        sOutput = Regex.Replace(sOutput, "(?<comment>//.*$)", TAG_FNTGRN & "${comment}" & TAG_EFONT) 
 
        Return sOutput 
 
    End Function 
 
    Private Function FixJSLine(ByVal sInputLine As String) As String 
        Dim sOutput As String = sInputLine 
        If sInputLine.Length = 0 Then 
            Return sInputLine 
        End If 
        sOutput = Regex.Replace(sInputLine, "(?i)(\t)", " ") 
        sOutput = HttpUtility.HtmlEncode(sOutput) 
        Dim sKeywords() As String = {"private", "protected", "public", "namespace", 
"class", "var", "for", "if", "else", "while", "switch", "case", "using", "get",   
"return", "null", "void", "int", "string", "float", "this", "set", "new", "true",   
"false", "const", "static", "package", "function", "internal", "extends", "super",   
"import", "default", "break", "try", "catch", "finally"} 
 
        Dim sCombinedKeywords As String = "(?<keyword>" &   
                                String.Join("|", sKeywords) & ")" 
        sOutput = Regex.Replace(sOutput, "\b" + sCombinedKeywords + "\b(?<!//.*)", 
                                TAG_FNTBLUE + "${keyword}" + TAG_EFONT) 
        sOutput = Regex.Replace(sOutput, "(?<comment>//.*$)", TAG_FNTGRN +   
                                "${comment}" + TAG_EFONT) 
        Return sOutput 
    End Function 
 
    Private Function FixVBLine(ByVal sInputLine As String) As String 
        Dim sOutput As String = sInputLine 
        If sInputLine.Length = 0 Then 
            Return sInputLine 
        End If 
        sOutput = Regex.Replace(sInputLine, "(?i)(\t)", " ") 
        sOutput = HttpUtility.HtmlEncode(sOutput) 
        Dim sKeywords() As String = {"AddressOf", "Delegate", "Optional", "ByVal",   
"ByRef", "Decimal", "Boolean", "Option", "Compare", "Binary", "Text", "On", "Off",   
"Explicit", "Strict", "Private", "Protected", "Public", "End Namespace", "Namespace", 
"End Class", "Exit", "Class", "Goto", "Try", "Catch", "End Try", "For", "End If",   
"If", "Else", "ElseIf", "Next", "While", "And", "Do", "Loop", "Dim", "As", "End 
Select", "Select", "Case", "Or", "Imports", "Then", "Integer", "Long", "String",   
"Overloads", "True", "Overrides", "End Property", "End Sub", "End Function", "Sub",   
"Me", "Function", "End Get", "End Set", "Get", "Friend", "Inherits", "Implements",   
"Return", "Not", "New", "Shared", "Nothing", "Finally", "False", "Me", "My", "MyBase", 
"End Enum", "Enum"} 
        Dim CombinedKeywords As String = "(?<keyword>" + String.Join("|", sKeywords) + ")" 
        sOutput = Regex.Replace(sOutput, "(?i)\b" + CombinedKeywords + "\b(?<!'.*)", 
                                TAG_FNTBLUE + "${keyword}" + TAG_EFONT) 
        sOutput = Regex.Replace(sOutput, "(?<comment>'(?![^']*").*$)", 
                                TAG_FNTGRN + "${comment}" + TAG_EFONT) 
        Return sOutput 
    End Function 

    Private Function FixASPXLine(ByVal sInputLine As String) As String 

        Dim sOutput As String = sInputLine 
        Dim sSearchExpression As String 
        Dim sReplaceExpression As String 
        If sInputLine.Length = 0 Then 
            Return sInputLine 
        End If 
        ' Search for \t and replace it with 4 spaces 
        sOutput = Regex.Replace(sOutput, "(?i)(\t)", " ") 
        sOutput = HttpUtility.HtmlEncode(sOutput) 


        ' Single line comment or #include references. 
        sSearchExpression = "(?i)(?<a>(^.*))(?<b>(<!--))(?<c>(.*))(?<d>(-->))(?<e>(.*))" 
        sReplaceExpression = "${a}" & TAG_FNTGRN & "${b}${c}${d}" & TAG_EFONT & "${e}" 
        If Regex.IsMatch(sOutput, sSearchExpression) Then 
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression) 
        End If 

        ' Colorize <%@ <type> 
        sSearchExpression = "(?i)" + "(?<a>(<%@))" + "(?<b>(.*))" + "(?<c>(%>))" 
        sReplaceExpression = "<font color=blue><b>${a}${b}${c}</b></font>" 
        If (Regex.IsMatch(sOutput, sSearchExpression)) Then 
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression) 
        End If 

        ' Colorize <%# <type> 
        sSearchExpression = "(?i)" + "(?<a>(<%#))" + "(?<b>(.*))" + "(?<c>(%>))" 
        sReplaceExpression = "${a}" + "<font color=red><b>" + "${b}" + "</b></font>" + "${c}" 

        If (Regex.IsMatch(sOutput, sSearchExpression)) Then 
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression) 
        End If 

        ' Colorize tag <type> 
        sSearchExpression = "(?i)" + 
"(?<a>(<)(?!%)(?!/?asp:)(?!/?template)(?!/?property)(?!/?ibuyspy:)(/|!)?)" + 
"(?<b>[^;\s&]+)" + "(?<c>(\s|>|\Z))" 
        sReplaceExpression = "${a}" + TAG_FNTMRN + "${b}" + TAG_EFONT + "${c}" 

        If (Regex.IsMatch(sOutput, sSearchExpression)) Then 
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression) 
        End If 

        ' Colorize asp:|template for runat=server tags <type> 
        sSearchExpression = 
"(?i)(?<a></?)(?<b>(asp:|template|property|IBuySpy:).*)(?<c>>)?" 

        sReplaceExpression = "${a}" + TAG_FNTBLUE + "<b>${b}</b>" + TAG_EFONT + "${c}" 
        If (Regex.IsMatch(sOutput, sSearchExpression)) Then 
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression) 
        End If 

        ' Colourise begin of tag char(s) "<","</","<%" 
        sSearchExpression = "(?i)(?<a>(<)(/|!|%)?)" 
        sReplaceExpression = TAG_FNTBLUE + "${a}" + TAG_EFONT 

        If (Regex.IsMatch(sOutput, sSearchExpression)) Then 
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression) 

        End If 

        ' Colorize end of tag char(s) ">","/>" 
        sSearchExpression = "(?i)(?<a>(/|%)?(>))" 
        sReplaceExpression = TAG_FNTBLUE + "${a}" + TAG_EFONT 

        If (Regex.IsMatch(sOutput, sSearchExpression)) Then 
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression) 
        End If 
        Return sOutput 
    End Function 

    Private Function IsScriptBlockTagStart(ByVal sInputLine As String) As Boolean 
        Dim bReturn As Boolean = False 

        If Regex.IsMatch(sInputLine, "<script.*runat=""?server""?.*>") Then 
            bReturn = True 

        ElseIf Regex.IsMatch(sInputLine, "(?i)<%@\s*WebService") Then 
            bReturn = True 

        End If 
        Return bReturn 
    End Function 

    Private Function IsScriptBlockTagEnd(ByVal sInputLine As String) As Boolean 

        Dim bReturn As Boolean = False 
        If (Regex.IsMatch(sInputLine, "</script.*>")) Then 
            bReturn = True 
        End If 
        Return bReturn 
    End Function 

    Private Function IsMultiLineTagStart(ByVal sInputLine As String) As Boolean 
        Dim bReturn As Boolean = False 
        Dim sOutput As String 
        Dim sSearchExpression As String = 
"(?i)(?!.*>)(?<a></?)(?<b>(asp:|template|property|IBuySpy:).*)" 
        sOutput = HttpUtility.HtmlEncode(sInputLine) 
        If Regex.IsMatch(sOutput, sSearchExpression) Then 
            bReturn = True 
        End If 
        Return bReturn 
    End Function 

    Private Function IsMultiLineTagEnd(ByVal sInputLine As String) As Boolean 
        Dim bReturn As Boolean = False 
        Dim sOutput As String 
        Dim sSearchExpression As String = "(?i)>" 
        sOutput = HttpUtility.HtmlEncode(sInputLine) 
        If Regex.IsMatch(sOutput, sSearchExpression) Then 
            bReturn = True 
        End If 
        Return bReturn 
    End Function 

    Private Class ProgrammingLanguage 
        Public Const VB As String = "vb" 
        Public Const CSharp As String = "cs" 
        Public Const JavaScript As String = "js" 
    End Class 
 
End Class 
 
 
Imports System.IO

Partial Class _Default
    Inherits System.Web.UI.Page


    Protected Sub Button1_Click(ByVal sender As Object,
                                ByVal e As System.EventArgs) Handles Button1.Click
        If Not (FileUpload1.PostedFile Is Nothing) Then
            Dim myFile As String = ""
            Dim fileName As String = FileUpload1.PostedFile.FileName
            SetLanguageFromFileName(fileName)
            Dim srRead As StreamReader = File.OpenText(fileName)
            FileResult.Text = Render(srRead)
        End If
    End Sub

    Private _ShowFileName As Boolean = False
    Private _FontSize As Integer = 3
    Private _Language As String = ""
    Private Const TAG_FNTRED As String = "<font color=""red"">"
    Private Const TAG_FNTBLUE As String = "<font color=""blue"">"
    Private Const TAG_FNTGRN As String = "<font color=""green"">"
    Private Const TAG_FNTMRN As String = "<font color=""maroon"">"
    Private Const TAG_EFONT As String = "</font>"

    Public Property ShowFileName() As Boolean
        Get
            Return _ShowFileName
        End Get
        Set(ByVal Value As Boolean)
            _ShowFileName = Value
        End Set
    End Property

    Public Property FontSize() As Integer
        Get
            Return _FontSize
        End Get
        Set(ByVal Value As Integer)
            _FontSize = Value
        End Set
    End Property

    Public Property Language() As String
        Get
            Return _Language
        End Get
        Set(ByVal Value As String)
            _Language = Value
        End Set
    End Property

    Private Sub SetLanguageFromFileName(ByVal FilePath As String)
        ' Find the current language from the file extension
        If FilePath.Split(Convert.ToChar(".")).Length > 0 Then
            Dim sFileExtension As String = FilePath.Substring(FilePath.LastIndexOf(Convert.ToChar(".")) + 1)
            Select Case sFileExtension.ToLower().Trim()
                Case ProgrammingLanguage.VB
                    _Language = ProgrammingLanguage.VB
                Case ProgrammingLanguage.CSharp
                    _Language = ProgrammingLanguage.CSharp
                Case ProgrammingLanguage.JavaScript
                    _Language = ProgrammingLanguage.JavaScript
            End Select
        End If
    End Sub

    Public Overloads Function RenderFile(ByVal FilePath As String) As String
        ' errors?
        SetLanguageFromFileName(FilePath)
        Return Render(IO.File.OpenText(FilePath))
    End Function

    Public Overloads Sub RenderFile(ByVal FilePath As String,
                                    ByVal OutputFilePath As String)
        ' Render and throw error
        SetLanguageFromFileName(FilePath)
        Dim MyStreamWriter As New IO.StreamWriter(OutputFilePath)
        MyStreamWriter.Write(Render(IO.File.OpenText(FilePath)))
        MyStreamWriter.Flush()
        MyStreamWriter.Close()
    End Sub

    Public Overloads Function Render(ByVal InputTextReader As IO.StreamReader) As String
        Return Render(InputTextReader.ReadToEnd())
    End Function

    Public Overloads Function Render(ByVal InputString As String) As String
        Dim MyStringBuilder As New System.Text.StringBuilder()
        Dim MyStringWriter As New System.IO.StringWriter(MyStringBuilder)

        ' Split into a string array for processing
        Dim InputLines() As String = InputString.Split(vbCrLf)
        Dim sInputLine As String

        ' Write out the font size
        MyStringWriter.WriteLine("<font size=""" & _FontSize & """ \>")


        ' Process the language
        Select Case _Language.Trim.ToLower()

            Case ProgrammingLanguage.CSharp
                MyStringWriter.WriteLine("<pre>")
                For Each sInputLine In InputLines
                    MyStringWriter.Write(FixCSLine(sInputLine))
                Next
                MyStringWriter.WriteLine("</pre>")
            Case ProgrammingLanguage.JavaScript
                MyStringWriter.WriteLine("<pre>")
                For Each sInputLine In InputLines
                    MyStringWriter.Write(FixJSLine(sInputLine))
                Next
                MyStringWriter.WriteLine("</pre>")
            Case ProgrammingLanguage.VB
                MyStringWriter.WriteLine("<pre>")
                For Each sInputLine In InputLines
                    MyStringWriter.Write(FixVBLine(sInputLine))
                Next
                MyStringWriter.WriteLine("</pre>")
            Case Else
                Dim bIsInScriptBlock As Boolean = False
                Dim bIsInMultiLine As Boolean = False
                MyStringWriter.WriteLine("<pre>")
                For Each sInputLine In InputLines
                    ' get the global language from a page directive
                    _Language = GetLanguageFromLine(sInputLine, _Language)

                    If IsScriptBlockTagStart(sInputLine) Then
                        MyStringWriter.Write(FixASPXLine(sInputLine))
                        bIsInScriptBlock = True
                    ElseIf IsScriptBlockTagEnd(sInputLine) Then
                        MyStringWriter.Write(FixASPXLine(sInputLine))
                        bIsInScriptBlock = False
                    ElseIf IsMultiLineTagStart(sInputLine) And bIsInMultiLine = False Then
                        MyStringWriter.Write("<font color=blue><b>" +
                                            HttpUtility.HtmlEncode(sInputLine))
                        bIsInMultiLine = True
                    ElseIf IsMultiLineTagEnd(sInputLine) And bIsInMultiLine = True Then
                        MyStringWriter.Write(HttpUtility.HtmlEncode(sInputLine) +
                                            "</b></font>")
                        bIsInMultiLine = False
                    ElseIf bIsInMultiLine Then
                        MyStringWriter.Write(HttpUtility.HtmlEncode(sInputLine))
                    Else
                        If bIsInScriptBlock Then
                            Select Case _Language.Trim.ToLower()
                                Case ProgrammingLanguage.CSharp
                                    MyStringWriter.Write(FixCSLine(sInputLine))
                                Case ProgrammingLanguage.JavaScript
                                    MyStringWriter.Write(FixJSLine(sInputLine))
                                Case ProgrammingLanguage.VB
                                    MyStringWriter.Write(FixVBLine(sInputLine))
                                Case Else
                                    MyStringWriter.Write(FixVBLine(sInputLine))
                            End Select
                        Else
                            MyStringWriter.Write(FixASPXLine(sInputLine))
                        End If
                    End If
                Next
                MyStringWriter.WriteLine("</pre>")
                'aspx-page sorted out
        End Select

        MyStringWriter.WriteLine("</font>")
        MyStringWriter.Flush()
        Return MyStringBuilder.ToString()
    End Function

    Private Function GetLanguageFromLine(ByVal sInputLine As String,
                                        ByVal DefaultLanguage As String) As String

        ' Returns name of the language
        Dim sReturn As String = DefaultLanguage
        If sInputLine.Length = 0 Then
            Return sReturn
        End If
        Dim LanguageMatch As Match = RegularExpressions.Regex.Match(sInputLine,
"(?i)<%@\s*Page\s*.*Language\s*=\s*""(?<lang>[^""]+)""")
        If LanguageMatch.Success Then
            sReturn = LanguageMatch.Groups("lang").ToString()
        End If
        LanguageMatch = RegularExpressions.Regex.Match(sInputLine,
"(?i)(?=.*runat\s*=\s*""?server""?)<script.*language\s*=\s*""(?<lang>[^""]+)"".*>")
        If LanguageMatch.Success Then
            sReturn = LanguageMatch.Groups("lang").ToString()
        End If
        LanguageMatch = RegularExpressions.Regex.Match(sInputLine,
"(?i)<%@\s*WebService\s*.*Language\s*=\s*""?(?<lang>[^""]+)""?")
        If LanguageMatch.Success Then
            sReturn = LanguageMatch.Groups("lang").ToString()
        End If

        ' "CS" instead of "C#" ?
        If sReturn = "CS" Then
            sReturn = ProgrammingLanguage.CSharp
        End If
        Return sReturn
    End Function

    Private Function FixCSLine(ByVal sInputLine As String) As String
        Dim sOutput As String = sInputLine
        If sInputLine.Length = 0 Then
            Return sInputLine
        End If
        sOutput = Regex.Replace(sInputLine, "(?i)(\t)", " ")

        sOutput = HttpUtility.HtmlEncode(sOutput)
        Dim sKeywords() As String = {"private", "protected", "public", "namespace",
"class", "break", "for", "if", "else", "while", "switch", "case", "using", "return",
"null", "void", "int", "bool", "string", "float", "this", "new", "true", "false",
"const", "static", "base", "foreach", "in", "try", "catch", "get", "set", "char",
"default"}
        Dim sCombinedKeywords As String = "(?<keyword>" &
                                            String.Join("|", sKeywords) & ")"
        sOutput = Regex.Replace(sOutput, "\b" & sCombinedKeywords & "\b(?<!//.*)",
                                TAG_FNTBLUE & "${keyword}" & TAG_EFONT)

        sOutput = Regex.Replace(sOutput, "(?<comment>//.*$)", TAG_FNTGRN & "${comment}" & TAG_EFONT)

        Return sOutput

    End Function

    Private Function FixJSLine(ByVal sInputLine As String) As String
        Dim sOutput As String = sInputLine
        If sInputLine.Length = 0 Then
            Return sInputLine
        End If
        sOutput = Regex.Replace(sInputLine, "(?i)(\t)", " ")
        sOutput = HttpUtility.HtmlEncode(sOutput)
        Dim sKeywords() As String = {"private", "protected", "public", "namespace",
"class", "var", "for", "if", "else", "while", "switch", "case", "using", "get",
"return", "null", "void", "int", "string", "float", "this", "set", "new", "true",
"false", "const", "static", "package", "function", "internal", "extends", "super",
"import", "default", "break", "try", "catch", "finally"}

        Dim sCombinedKeywords As String = "(?<keyword>" &
                                String.Join("|", sKeywords) & ")"
        sOutput = Regex.Replace(sOutput, "\b" + sCombinedKeywords + "\b(?<!//.*)",
                                TAG_FNTBLUE + "${keyword}" + TAG_EFONT)
        sOutput = Regex.Replace(sOutput, "(?<comment>//.*$)", TAG_FNTGRN +
                                "${comment}" + TAG_EFONT)
        Return sOutput
    End Function

    Private Function FixVBLine(ByVal sInputLine As String) As String
        Dim sOutput As String = sInputLine
        If sInputLine.Length = 0 Then
            Return sInputLine
        End If
        sOutput = Regex.Replace(sInputLine, "(?i)(\t)", " ")
        sOutput = HttpUtility.HtmlEncode(sOutput)
        Dim sKeywords() As String = {"AddressOf", "Delegate", "Optional", "ByVal",
"ByRef", "Decimal", "Boolean", "Option", "Compare", "Binary", "Text", "On", "Off",
"Explicit", "Strict", "Private", "Protected", "Public", "End Namespace", "Namespace",
"End Class", "Exit", "Class", "Goto", "Try", "Catch", "End Try", "For", "End If",
"If", "Else", "ElseIf", "Next", "While", "And", "Do", "Loop", "Dim", "As", "End
Select", "Select", "Case", "Or", "Imports", "Then", "Integer", "Long", "String",
"Overloads", "True", "Overrides", "End Property", "End Sub", "End Function", "Sub",
"Me", "Function", "End Get", "End Set", "Get", "Friend", "Inherits", "Implements",
"Return", "Not", "New", "Shared", "Nothing", "Finally", "False", "Me", "My", "MyBase",
"End Enum", "Enum"}
        Dim CombinedKeywords As String = "(?<keyword>" + String.Join("|", sKeywords) + ")"
        sOutput = Regex.Replace(sOutput, "(?i)\b" + CombinedKeywords + "\b(?<!'.*)",
                                TAG_FNTBLUE + "${keyword}" + TAG_EFONT)
        sOutput = Regex.Replace(sOutput, "(?<comment>'(?![^']*").*$)",
                                TAG_FNTGRN + "${comment}" + TAG_EFONT)
        Return sOutput
    End Function

    Private Function FixASPXLine(ByVal sInputLine As String) As String

        Dim sOutput As String = sInputLine
        Dim sSearchExpression As String
        Dim sReplaceExpression As String
        If sInputLine.Length = 0 Then
            Return sInputLine
        End If
        ' Search for \t and replace it with 4 spaces
        sOutput = Regex.Replace(sOutput, "(?i)(\t)", " ")
        sOutput = HttpUtility.HtmlEncode(sOutput)


        ' Single line comment or #include references.
        sSearchExpression = "(?i)(?<a>(^.*))(?<b>(<!--))(?<c>(.*))(?<d>(-->))(?<e>(.*))"
        sReplaceExpression = "${a}" & TAG_FNTGRN & "${b}${c}${d}" & TAG_EFONT & "${e}"
        If Regex.IsMatch(sOutput, sSearchExpression) Then
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression)
        End If

        ' Colorize <%@ <type>
        sSearchExpression = "(?i)" + "(?<a>(<%@))" + "(?<b>(.*))" + "(?<c>(%>))"
        sReplaceExpression = "<font color=blue><b>${a}${b}${c}</b></font>"
        If (Regex.IsMatch(sOutput, sSearchExpression)) Then
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression)
        End If

        ' Colorize <%# <type>
        sSearchExpression = "(?i)" + "(?<a>(<%#))" + "(?<b>(.*))" + "(?<c>(%>))"
        sReplaceExpression = "${a}" + "<font color=red><b>" + "${b}" + "</b></font>" + "${c}"

        If (Regex.IsMatch(sOutput, sSearchExpression)) Then
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression)
        End If

        ' Colorize tag <type>
        sSearchExpression = "(?i)" +
"(?<a>(<)(?!%)(?!/?asp:)(?!/?template)(?!/?property)(?!/?ibuyspy:)(/|!)?)" +
"(?<b>[^;\s&]+)" + "(?<c>(\s|>|\Z))"
        sReplaceExpression = "${a}" + TAG_FNTMRN + "${b}" + TAG_EFONT + "${c}"

        If (Regex.IsMatch(sOutput, sSearchExpression)) Then
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression)
        End If

        ' Colorize asp:|template for runat=server tags <type>
        sSearchExpression =
"(?i)(?<a></?)(?<b>(asp:|template|property|IBuySpy:).*)(?<c>>)?"

        sReplaceExpression = "${a}" + TAG_FNTBLUE + "<b>${b}</b>" + TAG_EFONT + "${c}"
        If (Regex.IsMatch(sOutput, sSearchExpression)) Then
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression)
        End If

        ' Colourise begin of tag char(s) "<","</","<%"
        sSearchExpression = "(?i)(?<a>(<)(/|!|%)?)"
        sReplaceExpression = TAG_FNTBLUE + "${a}" + TAG_EFONT

        If (Regex.IsMatch(sOutput, sSearchExpression)) Then
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression)

        End If

        ' Colorize end of tag char(s) ">","/>"
        sSearchExpression = "(?i)(?<a>(/|%)?(>))"
        sReplaceExpression = TAG_FNTBLUE + "${a}" + TAG_EFONT

        If (Regex.IsMatch(sOutput, sSearchExpression)) Then
            sOutput = Regex.Replace(sOutput, sSearchExpression, sReplaceExpression)
        End If
        Return sOutput
    End Function

    Private Function IsScriptBlockTagStart(ByVal sInputLine As String) As Boolean
        Dim bReturn As Boolean = False

        If Regex.IsMatch(sInputLine, "<script.*runat=""?server""?.*>") Then
            bReturn = True

        ElseIf Regex.IsMatch(sInputLine, "(?i)<%@\s*WebService") Then
            bReturn = True

        End If
        Return bReturn
    End Function

    Private Function IsScriptBlockTagEnd(ByVal sInputLine As String) As Boolean

        Dim bReturn As Boolean = False
        If (Regex.IsMatch(sInputLine, "</script.*>")) Then
            bReturn = True
        End If
        Return bReturn
    End Function

    Private Function IsMultiLineTagStart(ByVal sInputLine As String) As Boolean
        Dim bReturn As Boolean = False
        Dim sOutput As String
        Dim sSearchExpression As String =
"(?i)(?!.*>)(?<a></?)(?<b>(asp:|template|property|IBuySpy:).*)"
        sOutput = HttpUtility.HtmlEncode(sInputLine)
        If Regex.IsMatch(sOutput, sSearchExpression) Then
            bReturn = True
        End If
        Return bReturn
    End Function

    Private Function IsMultiLineTagEnd(ByVal sInputLine As String) As Boolean
        Dim bReturn As Boolean = False
        Dim sOutput As String
        Dim sSearchExpression As String = "(?i)>"
        sOutput = HttpUtility.HtmlEncode(sInputLine)
        If Regex.IsMatch(sOutput, sSearchExpression) Then
            bReturn = True
        End If
        Return bReturn
    End Function

    Private Class ProgrammingLanguage
        Public Const VB As String = "vb"
        Public Const CSharp As String = "cs"
        Public Const JavaScript As String = "js"
    End Class

End Class



Summary
You've now learned how to convert and colorize a code source to HTML. Following the guidelines in this article, you might also look at extending the languages list or why not add more new keywords for C# 3.0 and above. I would be interested to know about any developments you can add from this example.

The generated HTML files can then be used for:

Printing with a browser: contrary to most browsers, java is known to have a very bad and buggy printing support
Documentation: syntax highlighted code always looks better
Web publication
 
1  /  1  页   1 跳转

快速回复帖子

标题
禁用 URL 识别
禁用表情
禁用 Discuz!NT 代码
使用个人签名
  [完成后可按 Ctrl+Enter 无刷新发布]  

版权所有 拼吾爱程序人生    Total Unique Visitors:

web counter

Powered by Discuz!NT 2.1.202   Copyright © 2001-2008 Comsenz Inc. 鄂ICP备07500843号
返顶部