Skip to content

Instantly share code, notes, and snippets.

@qsun
Created February 6, 2012 05:40
Show Gist options
  • Save qsun/1749965 to your computer and use it in GitHub Desktop.
Save qsun/1749965 to your computer and use it in GitHub Desktop.
Parse and spin spin-formatted article
import random
# Usage: parse(text).spin()
class Node:
def __init__(self):
None
def spin(self):
raise Exception('Not implemented')
class ListNode(Node):
def __init__(self, nodes=[]):
self.nodes = nodes
def spin(self):
text = ''
for node in self.nodes:
text = text + node.spin()
return text
def append_node(self, node):
if isinstance(node, ListNode):
for n in node.nodes:
self.nodes = [n] + self.nodes
else:
self.nodes = [node] + self.nodes
def __repr__(self):
return '[' + ','.join([
str(n) for n in self.nodes
]) + ']'
class ChoiceNode(Node):
def __init__(self, choices=[]):
self.choices = choices
def choose(self):
if len(self.choices) > 0:
return random.choice(self.choices)
else:
return None
def spin(self):
choice = self.choose()
if choice is not None:
return choice.spin()
else:
return ''
def add_choice(self, choice):
self.choices.append(choice)
def __repr__(self):
return '{' + '|'.join([
str(c) for c in self.choices
]) + '}'
class TextNode(Node):
def __init__(self, text=''):
self.text = text
def spin(self):
return self.text
def add_char(self, c):
self.text = self.text + c
def __repr__(self):
return '(' + self.text + ')'
def parse(text):
stack = []
for c in text:
if c == '{':
start_choice(stack)
elif c == '|':
add_choice(stack)
elif c == '}':
end_choices(stack)
else:
# normal char
push_text(stack, c)
return ListNode(nodes=stack)
def start_choice(stack):
stack.append('{')
def add_choice(stack):
stack.append('|')
def end_choices(stack):
branch = ListNode(nodes=[])
choices = ChoiceNode(choices=[])
while True:
top = stack.pop()
if top == '|':
choices.add_choice(branch)
branch = ListNode(nodes=[])
elif top == '{':
choices.add_choice(branch)
stack.append(choices)
return
else:
branch.append_node(top)
def push_text(stack, c):
if len(stack) > 0:
if isinstance(stack[-1], TextNode):
stack[-1].add_char(c)
return
stack.append(TextNode(c))
def test():
f = open('sample.txt', 'r')
text = f.read()
print parse(text).spin()
# text = '''{{a|b}|c}'''
# sa = parse(text)
# article = sample()
# print article.spin()
parse_article = parse
if __name__ == '__main__':
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment