Created
February 6, 2012 05:40
-
-
Save qsun/1749965 to your computer and use it in GitHub Desktop.
Parse and spin spin-formatted article
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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