RosettaCodeData/Task/Mad-Libs/Visual-Basic-.NET/mad-libs.visual

70 lines
2.4 KiB
Plaintext

Imports System.Text
Module Program
Private Function GetStory() As String
Dim input As New StringBuilder()
Do
Dim nextLine = Console.ReadLine()
If String.IsNullOrEmpty(nextLine) Then Exit Do
input.AppendLine(nextLine)
Loop
Dim story = input.ToString()
Return story
End Function
Sub Main()
Dim input As String = GetStory()
Dim result As New StringBuilder()
Dim replacements As New Dictionary(Of String, String)
For i = 0 To input.Length - 1
Dim curChar = input(i)
' For all characters but '<', append it and move on.
If curChar <> "<"c Then
result.Append(curChar)
Else
' If the character before was a backslash, then replace the backslash in the result with a '<' and move on.
If i > 0 AndAlso input(i - 1) = "\"c Then
result(result.Length - 1) = "<"c
Continue For
End If
' Search for the first '>' that isn't preceded by a backslash.
Dim closeBracketPos = -1
For ind = i To input.Length - 1
If input(ind) = ">"c AndAlso input(ind - 1) <> "\"c Then
closeBracketPos = ind
Exit For
End If
Next
' The search failed to find a '>'.
If closeBracketPos < 0 Then
Console.WriteLine($"ERROR: Template starting at position {i} is not closed.")
Environment.Exit(-1)
End If
' The text between the current character and the found '>' character, with escape sequences simplified.
Dim key As String = input.Substring(i + 1, closeBracketPos - i - 1).Replace("\>", ">", StringComparison.Ordinal)
Dim subst As String = Nothing
' Ask for and store a replacement value if there isn't already one for the key.
If Not replacements.TryGetValue(key, subst) Then
Console.Write($"Enter a {key}: ")
subst = Console.ReadLine()
replacements.Add(key, subst)
End If
result.Append(subst)
i = closeBracketPos
End If
Next
Console.WriteLine()
Console.Write(result)
End Sub
End Module