I decided to write a small script to make writing HTML interactive stories less tedious:
import doctest
import re
import sys
import tkinter
import tkinter.filedialog
HTML_START = """<!DOCTYPE html>
<html lang="en">
<div align="center">
<head>
<title>{}</title>
<h1>{}</h1>
</head>
<body>
"""
HTML_END = """
</div>
</body>
</html>"""
SEPARATOR = '\n---\n\n'
def link_to_self(word):
"""
Generates an html link to the given word.
>>> link_to_self("spam")
'<a href="Spam.html">spam</a>'
"""
return '<a href="{}.html">{}</a>'.format(word.capitalize(),word)
def inside_square_brackets(text):
"""
Returns all the text inside square brackets.
>>> inside_square_brackets('Some nice [brackets]')
['[brackets]']
"""
return re.findall('\[.*?\]',text)
def insert_links(text):
"""
Insert links from square brackets.
>>> insert_links("A [cake]?")
'A <a href="Cake.html">cake</a>?'
"""
for link in inside_square_brackets(text):
text = text.replace(link,link_to_self(link.replace('[','').replace(']','')))
return text
def html_page(title,page):
"""
Generates an html page with title and text.
"""
return HTML_START.format(title.capitalize(),title.capitalize()) + insert_links(page) + HTML_END
def create_html_file(filename,text):
with open(filename+'.html','w+') as f:
f.write(html_page(filename,text))
def gen_interactive_story(titles_and_texts):
for title,text in titles_and_texts:
create_html_file(title,text)
def parse_stories_and_titles(text):
"""
Spits out tuples (title,text) from a text containg paragraphs
separated by the SEPARATOR.
"""
chunks = text.split(SEPARATOR)
lines_from_chunks = [chunk.splitlines() for chunk in chunks]
return [(line[0].capitalize(),''.join(line[1:]))
for line in lines_from_chunks]
def find_txt_file(lst):
"""
Returns the first '.txt' file in a list.
>>> find_txt_file(['a.txt','b.foo','c.py'])
'a.txt'
"""
txts = [i for i in lst if '.txt' in i]
if txts: return txts[0]
def contains_txt_file(lst):
return bool(find_txt_file(lst))
def parse_and_generate_stories(filename):
with open(filename) as f:
titles_and_texts = parse_stories_and_titles(f.read())
gen_interactive_story(titles_and_texts)
def ask_filename():
root = tkinter.Tk()
root.withdraw()
return tkinter.filedialog.askopenfilenames()[0]
def _test():
doctest.testmod()
def main():
_test()
if contains_txt_file(sys.argv):
filename = find_txt_file(sys.argv)
else:
filename = ask_filename()
parse_and_generate_stories(filename)
if __name__ == "__main__":
main()
To simplify testing, I include a properly written story:
a scary choice
It was an extremely [dark] night and around me I could only
see a [cave] and a [wood].
---
dark
I mean, extremely dark, even without moon. But I could not lose time,
it was time to make [a scary choice].
---
cave
The cave was frightening, but I decided to go in nonetheless,
what is life without risk?
---
wood
The wood was emitting scary and creepy sounds but I decided
to enter it because it seemed less scary than the wood.