From 404f4a88d02e76a7acb80b9fb3f97154ee80dfa4 Mon Sep 17 00:00:00 2001 From: Alex Warren Date: Sat, 11 Oct 2014 20:43:48 +0100 Subject: [PATCH] Remove Squiffy 1 Python script --- .gitignore | 41 ------ squiffy.py | 407 ----------------------------------------------------- 2 files changed, 448 deletions(-) delete mode 100644 squiffy.py diff --git a/.gitignore b/.gitignore index 1d12cc0..686e536 100644 --- a/.gitignore +++ b/.gitignore @@ -1,51 +1,10 @@ index.html story.js style.css -squiffy.spec examples/*/jquery*.js _site -### .gitgnore for Python ################################################################################## - -*.py[cod] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 -__pycache__ - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.tox -nosetests.xml - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - - ### .gitgnore for node.js ################################################################################## # Logs diff --git a/squiffy.py b/squiffy.py deleted file mode 100644 index 2324894..0000000 --- a/squiffy.py +++ /dev/null @@ -1,407 +0,0 @@ -import os -import sys -import re -from collections import OrderedDict -import json -import glob -import markdown -import uuid -import hashlib -import shutil - -squiffy_version = "1.0" - -def process(input_filename, source_path, options): - output_path = os.path.abspath(os.path.dirname(input_filename)) - - story = Story() - story.set_id(os.path.abspath(input_filename)) - success = process_file(story, os.path.abspath(input_filename), True) - - if not success: - print ("Failed.") - return - - print ("Writing story.js") - - js_template_file = open(os.path.join(source_path, "squiffy.template.js")) - js_data = "// Created with Squiffy {0}\n// https://github.com/textadventures/squiffy\n\n".format(squiffy_version) + js_template_file.read() - output_js_file = open(os.path.join(output_path, "story.js"), 'w') - output_js_file.write(js_data) - output_js_file.write("\n\n") - if len(story.start) == 0: - story.start = list(story.sections.keys())[0] - output_js_file.write("squiffy.story.start = \"" + story.start + "\";\n") - output_js_file.write("squiffy.story.id = \"{0}\";\n".format(story.id)) - output_js_file.write("squiffy.story.sections = {\n") - - for section_name in story.sections: - section = story.sections[section_name] - - output_js_file.write("\t\"{0}\": {{\n".format(section_name)) - if section.clear: - output_js_file.write("\t\t\"clear\": true,\n") - output_js_file.write("\t\t\"text\": {0},\n".format(json.dumps(process_text("\n".join(section.text), story, section, None)))) - if len(section.attributes) > 0: - output_js_file.write("\t\t\"attributes\": {0},\n".format(json.dumps(section.attributes))) - if len(section.js) > 0: - write_js(output_js_file, 2, section.js) - - output_js_file.write("\t\t\"passages\": {\n") - for passage_name in section.passages: - passage = section.passages[passage_name] - - output_js_file.write("\t\t\t\"{0}\": {{\n".format(passage_name)) - if passage.clear: - output_js_file.write("\t\t\t\t\"clear\": true,\n") - output_js_file.write("\t\t\t\t\"text\": {0},\n".format(json.dumps(process_text("\n".join(passage.text), story, section, passage)))) - if len(passage.attributes) > 0: - output_js_file.write("\t\t\t\t\"attributes\": {0},\n".format(json.dumps(passage.attributes))) - if len(passage.js) > 0: - write_js(output_js_file, 4, passage.js) - output_js_file.write("\t\t\t},\n") - - output_js_file.write("\t\t},\n") - output_js_file.write("\t},\n") - - output_js_file.write("}\n") - - print ("Writing index.html") - - html_template_file = open(find_file("index.template.html", output_path, source_path)) - html_data = html_template_file.read() - html_data = html_data.replace("", "".format(squiffy_version)) - html_data = html_data.replace("", story.title) - jquery_js = "jquery.min.js" - jqueryui_js = "jquery-ui.min.js" - - if options.use_cdn: - jquery_js = "http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.10.2.min.js" - jqueryui_js = "http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/jquery-ui.min.js" - else: - shutil.copy2(os.path.join(source_path, "jquery.min.js"), output_path) - shutil.copy2(os.path.join(source_path, "jquery-ui.min.js"), output_path) - - html_data = html_data.replace("", jquery_js) - html_data = html_data.replace("", jqueryui_js) - - script_data = "\n".join(map(lambda script: "".format(script), story.scripts)) - html_data = html_data.replace("", script_data) - output_html_file = open(os.path.join(output_path, "index.html"), 'w') - output_html_file.write(html_data) - - print ("Writing style.css") - - css_template_file = open(find_file("style.template.css", output_path, source_path)) - css_data = css_template_file.read() - output_css_file = open(os.path.join(output_path, "style.css"), 'w') - output_css_file.write(css_data) - - print("Done.") - -def find_file(filename, output_path, source_path): - output_path_file = os.path.join(output_path, filename) - if os.path.exists(output_path_file): - return output_path_file - return os.path.join(source_path, filename) - -def process_file(story, input_filename, is_first): - if input_filename in story.files: - return True - story.files.append(input_filename) - print ("Loading " + input_filename) - input_file = open(input_filename) - line_count = 0 - auto_section_count = 0 - - section_regex = re.compile(r"^\[\[(.*)\]\]:$") - passage_regex = re.compile(r"^\[(.*)\]:$") - title_regex = re.compile(r"^@title (.*)$") - import_regex = re.compile(r"^@import (.*)$") - start_regex = re.compile(r"^@start (.*)$") - attributes_regex = re.compile(r"^@set (.*)$") - unset_regex = re.compile(r"^@unset (.*)$") - inc_regex = re.compile(r"^@inc (.*)$") - dec_regex = re.compile(r"^@dec (.*)$") - replace_regex = re.compile(r"^@replace (.*$)") - js_regex = re.compile(r"^(\t| {4})(.*)$") - continue_regex = re.compile(r"^\+\+\+(.*)$") - - section = None - passage = None - text_started = False - - input_data = input_file.read() - input_lines = input_data.splitlines() - - for line in input_lines: - stripline = line.strip() - line_count += 1 - section_match = section_regex.match(stripline) - passage_match = passage_regex.match(stripline) - continue_match = continue_regex.match(stripline) - js_match = js_regex.match(line) - if section_match: - section = story.addSection(section_match.group(1), input_filename, line_count) - passage = None - text_started = False - elif passage_match: - if section is None: - print("ERROR: {0} line {1}: Can't add passage '{2}' as no section has been created.".format( - input_filename, line_count, passage_match.group(1))) - return False - passage = section.addPassage(passage_match.group(1), line_count) - text_started = False - elif continue_match: - section = ensure_section_exists(story, section, is_first, input_filename, line_count) - auto_section_count += 1 - auto_section_name = "_continue{0}".format(auto_section_count) - section.addText("[[{0}]]({1})".format(continue_match.group(1), auto_section_name)) - section = story.addSection(auto_section_name, input_filename, line_count) - passage = None - text_started = False - elif stripline.startswith("@"): - title_match = title_regex.match(stripline) - start_match = start_regex.match(stripline) - import_match = import_regex.match(stripline) - attributes_match = attributes_regex.match(stripline) - unset_match = unset_regex.match(stripline) - inc_match = inc_regex.match(stripline) - dec_match = dec_regex.match(stripline) - replace_match = replace_regex.match(stripline) - if stripline == "@clear": - if passage is None: - section = ensure_section_exists(story, section, is_first, input_filename, line_count) - section.clear = True - else: - passage.clear = True - elif title_match: - story.title = title_match.group(1) - elif start_match: - story.start = start_match.group(1) - elif import_match: - base_path = os.path.abspath(os.path.dirname(input_filename)) - new_filenames = os.path.join(base_path, import_match.group(1)) - import_filenames = glob.glob(new_filenames) - for import_filename in import_filenames: - if import_filename.endswith(".squiffy"): - success = process_file(story, import_filename, False) - if not success: - return False - elif import_filename.endswith(".js"): - story.scripts.append(os.path.relpath(import_filename, base_path)) - elif attributes_match: - section = add_attribute(attributes_match.group(1), story, section, passage, is_first, input_filename, line_count) - elif unset_match: - section = add_attribute("not " + unset_match.group(1), story, section, passage, is_first, input_filename, line_count) - elif inc_match: - section = add_attribute(inc_match.group(1) + "+=1", story, section, passage, is_first, input_filename, line_count) - elif dec_match: - section = add_attribute(dec_match.group(1) + "-=1", story, section, passage, is_first, input_filename, line_count) - elif replace_match: - replace_attribute = replace_match.group(1) - attribute_match = re.match(r"^(.*?)=(.*)$", replace_attribute) - if attribute_match: - replace_attribute = attribute_match.group(1) + "=" + process_text(attribute_match.group(2), None, None, None) - section = add_attribute("@replace " + replace_attribute, story, section, passage, is_first, input_filename, line_count) - - elif not text_started and js_match: - if passage is None: - section = ensure_section_exists(story, section, is_first, input_filename, line_count) - section.addJS(js_match.group(2)) - else: - passage.addJS(js_match.group(2)) - else: - if not text_started and len(stripline) == 0: - continue - if passage is None: - section = ensure_section_exists(story, section, is_first, input_filename, line_count) - if not section is None: - section.addText(line) - text_started = True - else: - passage.addText(line) - text_started = True - - return True - -def ensure_section_exists(story, section, is_first, input_filename, line_count): - if section is None and is_first: - section = story.addSection("_default", input_filename, line_count) - return section - -def add_attribute(attribute, story, section, passage, is_first, input_filename, line_count): - if passage is None: - section = ensure_section_exists(story, section, is_first, input_filename, line_count) - section.addAttribute(attribute) - else: - passage.addAttribute(attribute) - return section - -def process_text(input, story, section, passage): - # named_section_link_regex matches: - # open [[ - # any text - the link text - # closing ]] - # open bracket - # any text - the name of the section - # closing bracket - named_section_link_regex = re.compile(r"\[\[(.*?)\]\]\((.*?)\)") - - links = map(lambda m: m.group(2), named_section_link_regex.finditer(input)) - check_section_links(story, links, section, passage) - - input = named_section_link_regex.sub(r"\1", input) - - # named_passage_link_regex matches: - # open [ - # any text - the link text - # closing ] - # open bracket, but not http(s):// after it - # any text - the name of the passage - # closing bracket - named_passage_link_regex = re.compile(r"\[(.*?)\]\(((?!https?://).*?)\)") - - links = map(lambda m: m.group(2), named_passage_link_regex.finditer(input)) - check_passage_links(story, links, section, passage) - - input = named_passage_link_regex.sub(r"\1", input) - - # unnamed_section_link_regex matches: - # open [[ - # any text - the link text - # closing ]] - unnamed_section_link_regex = re.compile(r"\[\[(.*?)\]\]") - - links = map(lambda m: m.group(1), unnamed_section_link_regex.finditer(input)) - check_section_links(story, links, section, passage) - - input = unnamed_section_link_regex.sub(r"\1", input) - - # unnamed_passage_link_regex matches: - # open [ - # any text - the link text - # closing ] - # no bracket after - unnamed_passage_link_regex = re.compile(r"\[(.*?)\]([^\(]|$)") - - links = map(lambda m: m.group(1), unnamed_passage_link_regex.finditer(input)) - check_passage_links(story, links, section, passage) - - input = unnamed_passage_link_regex.sub(r"\1\2", input) - - return markdown.markdown(input) - -def check_section_links(story, links, section, passage): - if story: - bad_links = filter(lambda m: not link_destination_exists(m, story.sections), links) - show_bad_links_warning(bad_links, "section", "[[", "]]", section, passage) - -def check_passage_links(story, links, section, passage): - if story: - bad_links = filter(lambda m: not link_destination_exists(m, section.passages), links) - show_bad_links_warning(bad_links, "passage", "[", "]", section, passage) - -def link_destination_exists(link, keys): - # Link destination data may look like: - # passageName - # passageName, my_attribute=2 - # passageName, @replace 1=new text, some_attribute=5 - # @replace 2=some words - # We're only interested in checking if the named passage or section exists. - - link_destination = link.split(",")[0] - if link_destination[0] == "@": - return True - return link_destination in keys - -def show_bad_links_warning(bad_links, link_to, before, after, section, passage): - for bad_link in bad_links: - - if passage is None: - warning = "{0} line {1}: In section \"{2}\"".format(section.filename, section.line, section.name) - else: - warning = "{0} line {1}: In section \"{2}\", passage \"{3}\"".format( - section.filename, passage.line, section.name, passage.name) - print("WARNING: {0} there is a link to a {1} called {2}{3}{4}, which doesn't exist".format(warning, link_to, before, bad_link, after)) - -def write_js(output_js_file, tab_count, js): - tabs = "\t" * tab_count - output_js_file.write("{0}\"js\": function() {{\n".format(tabs)) - for js_line in js: - output_js_file.write("{0}\t{1}\n".format(tabs, js_line)) - output_js_file.write("{0}}},\n".format(tabs)) - -class Story: - def __init__(self): - self.sections = OrderedDict() - self.title = "" - self.scripts = [] - self.files = [] - self.start = "" - - def addSection(self, name, filename, line): - section = Section(name, filename, line) - self.sections[name] = section - return section - - def set_id(self, filename): - file_id = str(uuid.getnode()) + filename - self.id = hashlib.sha1(file_id.encode('utf-8')).hexdigest()[0:10] - -class Section: - def __init__(self, name, filename, line): - self.name = name - self.filename = filename - self.line = line - self.text = [] - self.passages = OrderedDict() - self.js = [] - self.clear = False - self.attributes = [] - - def addPassage(self, name, line): - passage = Passage(name, line) - self.passages[name] = passage - return passage - - def addText(self, text): - self.text.append(text) - - def addJS(self, text): - self.js.append(text) - - def addAttribute(self, text): - self.attributes.append(text) - -class Passage: - def __init__(self, name, line): - self.name = name - self.line = line - self.text = [] - self.js = [] - self.clear = False - self.attributes = [] - - def addText(self, text): - self.text.append(text) - - def addJS(self, text): - self.js.append(text) - - def addAttribute(self, text): - self.attributes.append(text) - -class Options: - def __init__(self, args): - self.use_cdn = "-c" in args - -if __name__ == "__main__": - print("Squiffy " + squiffy_version) - if len(sys.argv) < 2: - print("Syntax: input.squiffy [-c]") - print("Options:") - print(" -c Use CDN for jQuery") - else: - options = Options(sys.argv[1:]) - process(sys.argv[1], os.path.abspath(os.path.dirname(sys.argv[0])), options)