Click here to Skip to main content
15,887,821 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi
I'm going to be creating a game soon and I've made a config file for the server. The server has a Configuration editor, which lets the user view and edit the config file in an easy-to-understand way.

It allows for the following tags:

$c[r,g,b] (changes the text colour)
$b (makes the text bold)
$i (makes the text italic)
$u (underlines the text)
$s (strikes the text out)

The parser works by pulling out any tags, changing the text format, then drawing it in the ListViewDrawSubItem event.

For example,
$bWelcome back, $c[128,255,255]$name
becomes
Welcome back, <name>
(where -name- is light blue).

As you can see in the images, any tag is allowed directly after $c[] or at the start of a word, but in no other configuration.

How could I modify my code to allow any number of tags anywhere in the string, as long as the syntax is correct? For example, "$c[0,255,0]H$bel$il$so" should become Hello

Relevant code:

VB
Private Sub configListView_DrawSubItem(sender As Object, e As DrawListViewSubItemEventArgs) Handles configListView.DrawSubItem

       If e.Item.Selected Then
           e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), e.Bounds)
       Else
           e.Graphics.FillRectangle(New SolidBrush(configListView.BackColor), e.Bounds)
       End If

       If e.ColumnIndex = 0 Then
           TextRenderer.DrawText(e.Graphics, e.SubItem.Text, New Font(Me.Font, Nothing), New Point(e.Bounds.Left + 3, e.Bounds.Top + 2), configListView.ForeColor)
           Return
       End If

       Dim textToDraw As Dictionary(Of Color, String) = Utils.getColorsFrom(e.SubItem.Text, configListView.ForeColor)

       Dim x As Integer = e.Bounds.Left + 3
       Dim y As Integer = e.Bounds.Top + 2

       For Each d As KeyValuePair(Of Color, String) In textToDraw

           Dim color As Color = d.Key
           Dim text As String = d.Value

           If text = "True" Then
               color = Color.FromArgb(128, 255, 128)
           ElseIf text = "False" Then
               color = Color.FromArgb(255, 128, 128)
           ElseIf Integer.TryParse(text, New Integer) Then
               color = Color.FromArgb(128, 128, 255)
           End If

           Dim font As Font = Me.Font

           If text.StartsWith("$b") Then
               font = New Font(Me.Font, FontStyle.Bold)
               text = text.Substring(2, text.Length - 2)
           ElseIf text.StartsWith("$i") Then
               font = New Font(Me.Font, FontStyle.Italic)
               text = text.Substring(2, text.Length - 2)
           ElseIf text.StartsWith("$u") Then
               font = New Font(Me.Font, FontStyle.Underline)
               text = text.Substring(2, text.Length - 2)
           ElseIf text.StartsWith("$s") Then
               font = New Font(Me.Font, FontStyle.Strikeout)
               text = text.Substring(2, text.Length - 2)
           End If

           text = text.Replace("$name", "<name>")

           TextRenderer.DrawText(e.Graphics, text, font, New Point(x, y), color)

           x += TextRenderer.MeasureText(text, Font).Width - 6

       Next

   End Sub


Utils.vb

VB
Shared Function splitByWord(str As String, delimeterWord As String, allowEmpties As Boolean) As String()
        Return str.Split(New String() {delimeterWord}, IIf(allowEmpties, StringSplitOptions.None, StringSplitOptions.RemoveEmptyEntries))
    End Function

    Shared Function countOf(c As String, str As String) As Integer

        Dim count As Integer = 0

        For Each ch In str
            If c = ch Then count += 1
        Next

        Return count

    End Function

    Shared Function getColorsFrom(str As String, defaultColor As Color) As Dictionary(Of Color, String)

        Dim result As New Dictionary(Of Color, String)

        For Each s As String In Utils.splitByWord(str, "$c", False)

            If Not (s.Substring(0, 1) = "[" AndAlso s.Contains("]")) Then
                result.Add(defaultColor, s)
                Continue For
            End If

            Dim rgb As String = s.Substring(1, s.Length - 1).Split("]")(0)

            If Not Utils.countOf(",", rgb) = 2 Then
                result.Add(defaultColor, s)
                Continue For
            End If

            Dim text As String = s.Substring(rgb.Length + 2, s.Length - rgb.Length - 2)
            Dim r As Integer = 0
            Dim g As Integer = 0
            Dim b As Integer = 0

            Try
                r = rgb.Split(",")(0)
                g = rgb.Split(",")(1)
                b = rgb.Split(",")(2)

                result.Add(Color.FromArgb(r, g, b), text)
            Catch
                result.Add(defaultColor, s)
                Continue For
            End Try

        Next

        Return result

    End Function


http://dc773.4shared.com/img/BtucjLtOce/s23/15666a14bf0/scr1[^]

http://dc773.4shared.com/img/y_v8KfcVce/s23/15666a14fd8/scr2[^]

What I have tried:

I've tried perfecting the above code for hours without help.
Posted
Comments
Member 11450536 8-Aug-16 12:28pm    
Bump. I've put a lot of time into this and can't figure it out.
Kschuler 10-Aug-16 16:08pm    
I can't answer this directly...but I'm pretty sure you should research regular expressions.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900