Wenn man seinen Code im Internet präsentieren möchte, hat man immer das Problem, dass der Code farblos ist. Größeren Code "per Hand" umzuwandeln ist viel zu aufwendig. Mit dieser Klasse ist es möglich bequem seinen Code in HTML-Code zu konvertieren. Die Umwandlung selbst basiert auf einem rekursiven Algorithmus. Dabei wird der Code zuerst bei Zeilenumbrüchen aufgesplittet und Zeile für Zeile konvertiert. Jede einzelne Zeile wird solange aufgeteilt, bis weder Komentare noch Text in Anführungszeichen vorhanden sind. Als nächstes werden die Schlüsselwörte rausgesucht. Wurde eins gefunden, werden die Zeichen vor und hinter den Schlüsselwort überprüft. Sind diese korrekt, wird vor und nach dem Schlüsselwort der entsprechende HTML-Tag eingefügt. Die Schlüsselwörter (in der MSDN aufgelistet) lädt das Programm aus einer XML-Datei, die in einen Stream geladen wird. Hierzu dient die GetStream-Funktion. Sie sollte an das Programm angepast werden, da es mehrere Möglichkeiten gibt, die Daten zu speichern. Die HTML-Tags, welche vor und nach Schlüsselwörtern bzw. Kommentaren stehen können durch die CommentTags bzw. KeywordTags Eigenschaft angegeben werden. Dabei handelt es sich um ein String-Array mit zwei Elementen, dem öffnenden (Index: 0) und den schließenden (Index: 1) Tag. Sollte die Länge nicht zwei betragen wird eine Ausnahme ausgelöst. Vier Dinge noch:
Erstellen der XML-Datei mit den Keywords <?xml version="1.0" encoding="utf-8" ?> <MainTag> <Keywords> <Keyword>AddHandler</Keyword> <Keyword>AddressOf</Keyword> <Keyword>Alias</Keyword> <Keyword>And</Keyword> <Keyword>AndAlso</Keyword> <Keyword>Ansi</Keyword> <Keyword>As</Keyword> <Keyword>Assembly</Keyword> <Keyword>Auto</Keyword> <Keyword>Boolean</Keyword> <Keyword>ByRef</Keyword> <Keyword>Byte</Keyword> <Keyword>ByVal</Keyword> <Keyword>Call</Keyword> <Keyword>Case</Keyword> <Keyword>Catch</Keyword> <Keyword>CBool</Keyword> <Keyword>CByte</Keyword> <Keyword>CChar</Keyword> <Keyword>CDate</Keyword> <Keyword>CDec</Keyword> <Keyword>CDbl</Keyword> <Keyword>Char</Keyword> <Keyword>CInt</Keyword> <Keyword>Class</Keyword> <Keyword>CLong</Keyword> <Keyword>CObj</Keyword> <Keyword>Compare</Keyword> <Keyword>Const</Keyword> <Keyword>CShort</Keyword> <Keyword>CSng</Keyword> <Keyword>CStr</Keyword> <Keyword>CType</Keyword> <Keyword>Date</Keyword> <Keyword>Decimal</Keyword> <Keyword>Declare</Keyword> <Keyword>Default</Keyword> <Keyword>Delegate</Keyword> <Keyword>Dim</Keyword> <Keyword>DirectCast</Keyword> <Keyword>Do</Keyword> <Keyword>Double</Keyword> <Keyword>Each</Keyword> <Keyword>Else</Keyword> <Keyword>ElseIf</Keyword> <Keyword>End</Keyword> <Keyword>Enum</Keyword> <Keyword>Erase</Keyword> <Keyword>Error</Keyword> <Keyword>Event</Keyword> <Keyword>Exit</Keyword> <Keyword>Explicit</Keyword> <Keyword>ExternalSource</Keyword> <Keyword>False</Keyword> <Keyword>Finally</Keyword> <Keyword>For</Keyword> <Keyword>Friend</Keyword> <Keyword>Function</Keyword> <Keyword>Get</Keyword> <Keyword>GetType</Keyword> <Keyword>GoTo</Keyword> <Keyword>Handles</Keyword> <Keyword>If</Keyword> <Keyword>Implements</Keyword> <Keyword>Imports</Keyword> <Keyword>In</Keyword> <Keyword>Inherits</Keyword> <Keyword>Integer</Keyword> <Keyword>Interface</Keyword> <Keyword>Is</Keyword> <Keyword>Let</Keyword> <Keyword>Lib</Keyword> <Keyword>Like</Keyword> <Keyword>Long</Keyword> <Keyword>Loop</Keyword> <Keyword>Me</Keyword> <Keyword>Mod</Keyword> <Keyword>Module</Keyword> <Keyword>MustInherit</Keyword> <Keyword>MustOverride</Keyword> <Keyword>MyBase</Keyword> <Keyword>MyClass</Keyword> <Keyword>Namespace</Keyword> <Keyword>New</Keyword> <Keyword>Next</Keyword> <Keyword>Not</Keyword> <Keyword>Nothing</Keyword> <Keyword>NotInheritable</Keyword> <Keyword>NotOverridable</Keyword> <Keyword>Object</Keyword> <Keyword>On</Keyword> <Keyword>Option</Keyword> <Keyword>Optional</Keyword> <Keyword>Or</Keyword> <Keyword>OrElse</Keyword> <Keyword>Overloads</Keyword> <Keyword>Overridable</Keyword> <Keyword>Overrides</Keyword> <Keyword>ParamArray</Keyword> <Keyword>Preserve</Keyword> <Keyword>Private</Keyword> <Keyword>Property</Keyword> <Keyword>Protected</Keyword> <Keyword>Public</Keyword> <Keyword>RaiseEvent</Keyword> <Keyword>ReadOnly</Keyword> <Keyword>ReDim</Keyword> <Keyword>Region</Keyword> <Keyword>RemoveHandler</Keyword> <Keyword>Resume</Keyword> <Keyword>Return</Keyword> <Keyword>Select</Keyword> <Keyword>Set</Keyword> <Keyword>Shadows</Keyword> <Keyword>Shared</Keyword> <Keyword>Short</Keyword> <Keyword>Single</Keyword> <Keyword>Static</Keyword> <Keyword>Step</Keyword> <Keyword>Stop</Keyword> <Keyword>Strict</Keyword> <Keyword>String</Keyword> <Keyword>Structure</Keyword> <Keyword>Sub</Keyword> <Keyword>SyncLock</Keyword> <Keyword>Then</Keyword> <Keyword>Throw</Keyword> <Keyword>To</Keyword> <Keyword>True</Keyword> <Keyword>Try</Keyword> <Keyword>TypeOf</Keyword> <Keyword>Unicode</Keyword> <Keyword>Until</Keyword> <Keyword>Variant</Keyword> <Keyword>When</Keyword> <Keyword>While</Keyword> <Keyword>With</Keyword> <Keyword>WithEvents</Keyword> <Keyword>WriteOnly</Keyword> </Keywords> <Chars> <CharBefor><NewLine></CharBefor> <CharBefor><Space></CharBefor> <CharBefor>></CharBefor> <CharBefor><</CharBefor> <CharBefor>#</CharBefor> <CharBefor>(</CharBefor> <CharBefor>)</CharBefor> <CharBefor>,</CharBefor> <CharAfter>(</CharAfter> <CharAfter>)</CharAfter> <CharAfter>,</CharAfter> <CharAfter>.</CharAfter> <CharAfter>:</CharAfter> <CharAfter><NewLine></CharAfter> <CharAfter><Space></CharAfter> </Chars> </MainTag> Die CodeConvert-Klasse Imports System Imports System.Collections Imports System.Environment Imports System.IO Imports System.Reflection Imports System.Text Imports System.Xml ' Wandelt Visual Basic .NET Code in HTML-Code um. Public Class CodeConverter #Region " Deklaration " ' Konstante für einen Leerstring. Private Const NullString As String = "" ' Anführungszeichen. Private Const QuotationMark As String = """" ' Der orginal Quellcode. Private sbOrginalCode As StringBuilder ' Die HTML-Befehle für Kommentare Private strCommentTags As String() ' Die HTML-Befehler für Schlüsselwörter. Private strKeywordTags As String() ' Die Liste der Schlüsselwörter Private strKeywords As String() ' Die Zeichen, oder Strings, die vor einem Wort sein dürfen, ' damit es als Schlüsselwort erkannt wird. Private strCharsBefor As String() ' Die Zeichen, oder Strings, die nach einem Wort sein dürfen, ' damit es als Schlüsselwort erkannt wird. Private strCharsAfter As String() #End Region #Region " New-Funktionen " ' Initialisiert die Klasse. Public Sub New() ' Lädt die Schlüsselwörter. LoadKeywords() ' Setzt leere Strings für die Tags ein. Me.CommentTags = New String() {NullString, NullString} Me.KeywordTags = New String() {NullString, NullString} End Sub ' Initialisiert die Klasse Public Sub New(ByVal Path As String) Me.New() ' Ließt die Code-Datei. Dim SR As New StreamReader(Path, Encoding.Default) sbOrginalCode = New StringBuilder(SR.ReadToEnd) SR.Close() End Sub #End Region #Region " Eigenschaften " ' Der Orginal Quellcode Public Property OrginalCode() As String Get Return sbOrginalCode.ToString End Get Set(ByVal Value As String) sbOrginalCode = New StringBuilder(Value) End Set End Property ' Der HTML-Code Public ReadOnly Property HTMLCode() As String Get Return ConvertCode.ToString End Get End Property ' Die HTML-Befehle für Kommentare Public Property CommentTags() As String() Get Return strCommentTags End Get Set(ByVal Value As String()) If Value.Length <> 2 Then ' Fehler auslösen. Throw New WrongNumberOfTagsException() Exit Property End If strCommentTags = Value End Set End Property ' Die HTML-Befehler für Schlüsselwörter. Public Property KeywordTags() As String() Get Return strKeywordTags End Get Set(ByVal Value As String()) If Value.Length <> 2 Then ' Fehler auslösen. Throw New WrongNumberOfTagsException() Exit Property End If strKeywordTags = Value End Set End Property #End Region ' Lädt die Schlüsselwörter. Private Sub LoadKeywords() Dim xmlDoc As New XmlDocument() Dim Node As XmlNode Dim Keywords As New ArrayList() xmlDoc.Load(GetStream("Keywords.xml")) ' Schlüsselwörter auslesen With xmlDoc.SelectSingleNode("descendant::Keywords") For Each Node In .SelectNodes("descendant::Keyword") Keywords.Add(Node.InnerText) Next End With ' "Speichert" die Schlüsselwörter. Keywords.Sort() strKeywords = Keywords.ToArray(GetType(String)) ' Löscht die Liste Keywords.Clear() ' Zeichen vor einem Schlüssselwort With xmlDoc.SelectSingleNode("descendant::Chars") For Each Node In .SelectNodes("descendant::CharBefor") Dim Chr As String = Node.InnerText If Chr = "<NewLine>" Then Chr = NewLine ElseIf Chr = "<Space>" Then Chr = " " End If Keywords.Add(Chr) Next End With ' "Speichert" die Schlüsselwörter. Keywords.Sort() strCharsBefor = Keywords.ToArray(GetType(String)) ' Löscht die Liste Keywords.Clear() ' Zeichen nach einem Schlüssselwort auslesen With xmlDoc.SelectSingleNode("descendant::Chars") For Each Node In .SelectNodes("descendant::CharAfter") Dim Chr As String = Node.InnerText If Chr = "<NewLine>" Then Chr = NewLine ElseIf Chr = "<Space>" Then Chr = " " End If Keywords.Add(Chr) Next End With ' "Speichert" die Schlüsselwörter. Keywords.Sort() strCharsAfter = Keywords.ToArray(GetType(String)) End Sub ' Lädt die XML-Datei mit den Schlüsselwörtern in einen Stream. Private Function GetStream(ByVal Name As String) As Stream ' Diese Funktion muss an das Programm angepasst werden. ' Möglich sind u.a. ... ' ... das laden aus den Ressourcen: ' ---------------------------------- ' ' Dim A As [Assembly] = [Assembly].GetExecutingAssembly ' Return A.GetManifestResourceStream(Name) ' ... das laden aus einer Datei: ' ------------------------------- ' Dim FS As New FileStream(Application.StartupPath & _ "keywords.xml", FileMode.Open) Return FS End Function ' Konvertiert den Code in HTML-Code. Private Function ConvertCode() As StringBuilder ' Überprüft, ob Code übergen wurde. If sbOrginalCode.Length = 0 Then Return New StringBuilder(NullString) End If Dim Line As String Dim Lines As String() Dim sbHTMLCode As New StringBuilder(OrginalCode) ' Ersetzt Zeichen, die mit dem HTML-Code in Konflikt kommen können. sbHTMLCode.Replace("&", "&") sbHTMLCode.Replace("<", "<") sbHTMLCode.Replace(">", ">") Lines = sbHTMLCode.ToString.Split(NewLine) sbHTMLCode = New StringBuilder() For Each Line In Lines If Line.Substring(0, 1) = NewLine.Substring(1, 1) Then sbHTMLCode.Append(ConvertLine(Line.Substring(1)) & "<br>" & NewLine) Else sbHTMLCode.Append(ConvertLine(Line) & "<br>" & NewLine) End If Next sbHTMLCode.Replace(" ", " ") sbHTMLCode.Replace(" ", " ") sbHTMLCode.Replace(" ", " ") Return sbHTMLCode End Function ' Konvertiert eine Zeile Private Function ConvertLine(ByVal Line As String) As String Dim L As New StringBuilder() Dim Ls As String() Dim REMPosition As Integer Dim StrPosition As Integer REMPosition = Line.IndexOf("'") StrPosition = Line.IndexOf(QuotationMark) ' Sowohl Anführungszeichen als auch Komentare in der Zeile. If (StrPosition <> -1) AndAlso (REMPosition <> -1) Then Dim i As Integer ' Der Komentar beginnt vor den Anführungszeichen If REMPosition < StrPosition Then L.Append(Line) L.Replace("'", strCommentTags(0) & "'", REMPosition, 1) L.Append(strCommentTags(1)) Return L.ToString Else Dim Length As Integer Ls = Line.Split(QuotationMark) For i = 0 To Ls.Length - 1 Step 2 Dim RP As Integer = Ls(i).IndexOf("'") ' Komentar beginnt in diesem Abschnitt If RP >= 0 Then ' Fügt konvertierten Code bis zum Komentar hinzu L.Append(ConvertLine(Ls(i).Substring(0, RP))) ' Fügt Kommentar-Tag ein. L.Append(strCommentTags(0)) ' Fügt Rest des Abschnittes hinzu. L.Append(Ls(i).Substring(RP)) Dim j As Integer ' Fügt die restlichen Abschnitte der Zeile hinzu. For j = i + 1 To Ls.Length - 1 L.Append(QuotationMark & Ls(j)) Next ' Fügt den Tab zum Beenden des Komentars hinzu L.Append(strCommentTags(1)) Else ' Fügt den Convertierten Abschnitt hinzu. L.Append(ConvertLine(Ls(i))) ' Fügt den String hinzu If i + 1 < Ls.Length Then L.Append(QuotationMark & Ls(i + 1)) End If End If L.Append(QuotationMark) Next Return L.ToString(0, L.Length - QuotationMark.Length) End If End If ' Nur Anführungszeichen enthalten If (StrPosition <> -1) AndAlso (REMPosition = -1) Then Dim i As Integer Ls = Line.Split(QuotationMark) For i = 0 To Ls.Length - 1 Step 2 L.Append(ConvertLine(Ls(i))) ' Fügt den String hinzu. If i + 1 < Ls.Length Then L.Append(QuotationMark & Ls(i + 1)) End If L.Append(QuotationMark) Next Return L.ToString(0, L.Length - QuotationMark.Length) End If ' Keine Strings, nur ein Komentar enthalten. If (StrPosition = -1) AndAlso (REMPosition <> -1) Then ' Fügt konvertierten Code bis zum Komentar hinzu L.Append(ConvertLine(Line.Substring(0, REMPosition))) ' Fügt Kommentar-Tag ein. L.Append(strCommentTags(0)) ' Fügt Rest des Abschnittes hinzu. L.Append(Line.Substring(REMPosition)) ' Schließt den Kommentar-Tag. L.Append(strCommentTags(1)) Return L.ToString End If ' Weder Strings noch Komentare If (StrPosition = -1) AndAlso (REMPosition = -1) Then Dim KW As String Dim KeywordIndex As Integer L.Append(Line) For Each KW In strKeywords KeywordIndex = -1 Do KeywordIndex = L.ToString.IndexOf(KW, KeywordIndex + 1) ' Wenn kein Schlüsselwort vorhanden: Schleife verlassen If KeywordIndex = -1 Then Exit Do End If Dim Chr As String Dim ChrB, ChrA As Boolean ChrB = False ChrA = False ' Überprüft, ob das Zeichen davor übereinstimmt. For Each Chr In strCharsBefor If KeywordIndex - Chr.Length < 0 Then ChrB = ChrB OrElse (KeywordIndex = 0) Else ChrB = ChrB OrElse (L.ToString.Substring(KeywordIndex - _ Chr.Length, Chr.Length) = Chr) End If Next ' Überprüft, ob das Zeichen danach übereinstimmt. For Each Chr In strCharsAfter If KeywordIndex + KW.Length + Chr.Length > L.Length Then ChrA = ChrA Or (KeywordIndex + KW.Length = L.Length) Else ChrA = ChrA Or (L.ToString.Substring(KeywordIndex + KW.Length, _ Chr.Length) = Chr) End If Next ' Wenn beide Zeichen über einstimmen. If ChrB And ChrA Then L.Replace(KW, strKeywordTags(0) & KW & strKeywordTags(1), _ KeywordIndex, KW.Length) KeywordIndex += strKeywordTags(0).Length + strKeywordTags(1).Length End If Loop Next Return L.ToString End If End Function End Class ' Wird ausgelößt, wenn die Anzahl der übergebenen Tags nicht stimmt. Public Class WrongNumberOfTagsException Inherits Exception Public Sub New() MyBase.New("Die Anzahl der Tags muss 2 sein.") End Sub Public Sub New(ByVal Message As String) MyBase.New(Message) End Sub End Class Beispiel für den Einsatz der neuen CodeConverter-Klasse Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click Dim oConvert As New CodeConverter With oConvert ' VB.NET Code .OrginalCode = TextBox1.Text ' HTML-Tags für Kommentare .CommentTags = Split("<font color=green>;</font>", ";") ' HTML-Tag für Schlüsselwörter .KeywordTags = Split("<font color=blue>;</font>", ";") End With ' HTML-Code erzeugen... Dim sHTML As String = oConvert.HTMLCode ' ... temporär abspeichern... Dim oStream As New IO.StreamWriter(Application.StartupPath & "\vbcode.htm") oStream.Write(sHTML) oStream.Close() ' ... und im Standard-Browser anzeigen System.Diagnostics.Process.Start(Application.StartupPath & "\vbcode.htm") End Sub Dieser Tipp wurde bereits 20.362 mal aufgerufen. Voriger Tipp | Zufälliger Tipp | Nächster Tipp
Anzeige
Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv Vol.6 (einschl. Beispielprojekt!) Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
vb@rchiv CD Vol.6 Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! Online-Update-Funktion Entwickler-Vollversionen u.v.m. Tipp des Monats April 2024 Skyfloy Chart von Microsoft und dazu noch gratis Tutorial für Microsoft Chart Controls für Microsoft .NET Framework 3.5 sevZIP40 Pro DLL Zippen und Unzippen wie die Profis! Mit nur wenigen Zeilen Code statten Sie Ihre Anwendungen ab sofort mit schnellen Zip- und Unzip-Funktionen aus. Hierbei lassen sich entweder einzelnen Dateien oder auch gesamte Ordner zippen bzw. entpacken. |
||||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |