Skip to content

Instantly share code, notes, and snippets.

@keedi
Forked from eddwo/gist:5423102
Created April 25, 2013 15:48
Show Gist options
  • Save keedi/5460786 to your computer and use it in GitHub Desktop.
Save keedi/5460786 to your computer and use it in GitHub Desktop.
abstract class Comment
{
public abstract void Generate(StringBuilder builder);
public string Generate()
{
StringBuilder builder = new StringBuilder();
this.Generate(builder);
return builder.ToString();
}
}
class Choice : Comment
{
private readonly string[] _words;
private Random _random;
public Choice(TemplateParser parser)
{
_words = parser.ParseChoice();
_random = new Random();
}
public override void Generate(StringBuilder builder)
{
builder.Append(_words[_random.Next(_words.Length - 1)]);
}
public override string ToString()
{
string choiceWords = "{";
for (int i = 0; i < _words.Length; i++)
{
if (i > 0) choiceWords += '|';
choiceWords += _words[i];
}
choiceWords += '}';
return choiceWords;
}
}
class Sequence : Comment
{
private readonly Comment[] _sequence;
public Sequence(TemplateParser parser)
{
_sequence = parser.ParseSequence();
}
public override void Generate(StringBuilder builder)
{
foreach (Comment comm in _sequence)
{
comm.Generate(builder);
}
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
foreach (Comment comm in _sequence)
{
builder.Append(comm.ToString());
}
return builder.ToString();
}
}
class Words : Comment
{
private readonly string _words;
public Words(TemplateParser parser)
{
_words = parser.ParseWords();
}
public override void Generate(StringBuilder builder)
{
builder.Append(_words);
}
public override string ToString()
{
return _words;
}
}
class TemplateParser
{
const char _startChoice = '{';
const char _choiceOption = '|';
const char _endSequence = '|';
const char _endChoice = '}';
private readonly char[] _buffer;
private int _charPos;
public TemplateParser(string templateFile)
{
using (TextReader reader = new StreamReader(templateFile))
{
_buffer = reader.ReadToEnd().ToCharArray();
}
}
public IEnumerable<Comment> ParseTemplate()
{
_charPos = 1;
while (_charPos < _buffer.Length)
{
yield return new Sequence(this);
}
}
public Comment[] ParseSequence()
{
List<Comment> parts = new List<Comment>();
for (; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _startChoice:
_charPos++;
parts.Add(new Choice(this));
_charPos--;
break;
case _endSequence:
_charPos++;
return parts.ToArray();
default:
parts.Add(new Words(this));
_charPos--;
break;
}
}
return parts.ToArray();
}
public string[] ParseChoice()
{
int fromPos = _charPos;
List<string> words = new List<string>();
for (_charPos = fromPos; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _choiceOption:
words.Add(new String(_buffer, fromPos, _charPos - fromPos));
fromPos = _charPos + 1;
break;
case _endChoice:
words.Add(new String(_buffer, fromPos, _charPos - fromPos));
_charPos++;
return words.ToArray();
}
}
return words.ToArray();
}
public string ParseWords()
{
int fromPos = _charPos;
string words = String.Empty;
for (_charPos = fromPos; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _startChoice:
case _endSequence:
words = new String(_buffer, fromPos, _charPos - fromPos);
return words;
}
}
return words;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment