def parse(filename): """Generates a project tree based on a Markdown formatted file. Useful for generating project trees based on legacy projects or an outline file. Will automatically strip punctuation out of Markdown headers for folder names, but will preserve them in the 'overrides' section of settings.yml for use in compiling. :param str filename: Filename (i.e., not the full path) to be parsed (must include extension). :return: None Usage: >>> draft parse mobydick.md """ settings = get_settings() present_warning = settings["warnings"]["parse"] answer = False if present_warning: answer = click.confirm( click.style( "Highly recommend changes are COMMITed before proceeding. Continue?", fg="red", bold=True)) if answer or not present_warning: generator = Generator() generator.confirm_project_layout() outliner = Outliner() filepath = _get_filepath(filename) outliner.generate_file_tree(filepath) click.secho("Tree generated.", fg="green")
def sequence(): """Resets indices in folders and files and resolves duplicates. Usage: >>> draft sequence """ settings = get_settings() present_warning = settings["warnings"]["sequence"] answer = False if present_warning: answer = click.confirm( click.style( "Highly recommend changes are COMMITed before proceeding. Continue?", fg="red", bold=True)) if answer or not present_warning: generator = Generator() generator.confirm_project_layout() outliner = Outliner() outliner.update_file_sequence() click.secho("Files resequenced.", fg="green")
def trim(filename=None): """Removes all duplicate spaces from text. Acts on every file in project unless filepath argument passed. :param str filepath: (optional) Filename (i.e., not the full path) to be parsed (must include extension). :return: None Usage: >>> draft trim '01-Meeting Ishmael.md' """ settings = get_settings() present_warning = settings["warnings"]["trim"] answer = False if present_warning: answer = click.confirm( click.style( "Highly recommend changes are COMMITed before proceeding. Continue?", fg="red", bold=True)) if answer or not present_warning: generator = Generator() generator.confirm_project_layout() if filename: filename = _get_filepath(filename) formatter = Formatter(filename) formatter.remove_duplicate_spaces() click.secho("Duplicate spaces removed.", fg="green")
def split(filename=None): """Splits multi-line sentences into separate lines. Affects all project files unless filepath is passed as an argument. :param str filename: (optional) Filename (i.e., not the full path) to be parsed (must include extension). :return: None Usage: >>> draft split '01-Meeting Ishmael.md' """ settings = get_settings() present_warning = settings["warnings"]["split"] answer = False if present_warning: if not filename: click.secho( "WARNING: You are about to split sentences across the " + "entire project tree.", fg="red", bold=True) answer = click.confirm( click.style( "Highly recommend changes are COMMITed before proceeding. Continue?", fg="red", bold=True)) if answer or not present_warning: if filename: filename = _get_filepath(filename) formatter = Formatter(filename) formatter.split_sentences() click.secho("Sentence split complete.", fg="green")
def generate_project(self, title): root = self._create_simple_name(title) title = clean_filename(title) os.mkdir(root) os.mkdir(root + "/project") os.mkdir(root + "/project/" + title) with open(root + "/settings.yml", "w+") as settings_file: settings_file.write(yaml.dump(get_settings())) with open(root + "/.gitignore", "w+") as gitignore: gitignore.write(GITIGNORE)
def test_existing_settings_not_overwritten(self): fp = open("legacy.txt", "w+") fp.write("# Gatsby\n") fp.write("\n") fp.write("## Part 1: The Reckoning\n") fp.write("\n") fp.write("### Chapter 1: The Promise\n") fp.write("\n") fp.write("#### New York, 1942\n") fp.write("##### The Bar\n") fp.write("\n") fp.write("It was a fall day.\n") fp.write("It was cold.\n") fp.close() with open("settings.yml", "w+") as settings_file: settings_file.write(yaml.dump(get_settings())) outliner = Outliner() outliner.generate_file_tree("legacy.txt") with open("settings.yml", "r") as settings_file: settings = yaml.safe_load(settings_file) self.assertEqual( settings, { "author": None, "headers": { "chapter": True, "section": True, "sub_chapter": True }, "overrides": { "Chapter 1 The Promise": "Chapter 1: The Promise", "New York 1942": "New York, 1942", "Part 1 The Reckoning": "Part 1: The Reckoning" }, "warnings": { "parse": True, "sequence": True, "split": True, "trim": True } }) os.remove("settings.yml")
def compile_project(self, draft=False): outline = self._get_file_tree() settings = get_settings() headers = settings["headers"] overrides = settings["overrides"] author = settings["author"] SECTION_BREAK = "\n\n<br>\n\n" title = os.listdir("project")[0] try: override = overrides[title] title = override except (KeyError, TypeError): pass page = "# " + title + "\n\n" if author: page = page + "##### " + author + "\n\n" for branch in outline: if os.path.isfile(branch): with open(branch, "r") as sc: text = sc.read().strip() text = self._get_text_element(text, draft) # i.e., if we're making an outline and there is some outline text if text and not draft: text = ": " + text if draft: page = page + text.strip() + SECTION_BREAK else: split_branch = branch.split("/") branch_end = split_branch[-1] extension_index = branch_end.rindex(".") _, sequence_index = self._get_sequence_index( branch_end) scene_name = "**" + branch_end[ sequence_index + 1:extension_index] + "**" page = page + scene_name + text + "\n\n" elif os.path.isdir(branch): split_branch = branch.split("/") branch_end = split_branch[-1] _, sequence_index = self._get_sequence_index(branch_end) try: title = overrides[branch_end[sequence_index + 1:]] except (KeyError, TypeError): title = branch_end[sequence_index + 1:] if len(split_branch) == 3: if headers["section"] or not draft: section = "## " + title + "\n\n" else: section = SECTION_BREAK elif len(split_branch) == 4: if headers["chapter"] or not draft: section = "### " + title + "\n\n" else: section = SECTION_BREAK elif len(split_branch) == 5: if headers["sub_chapter"] or not draft: section = "#### " + title + "\n\n" else: section = SECTION_BREAK elif len(split_branch) == 2: continue page = page + section if draft: title = os.listdir("project")[0] file_name = title + ".md" html_name = title + ".html" else: file_name = "outline.md" html_name = "outline.html" file_name = self._create_next_filename(file_name) with open(file_name, "w") as fp: page = re.sub("\\n{3,}", "\\n\\n", page) fp.write(page) with open(html_name, "w") as ht: renderer = mistune.Renderer(escape=False, hard_wrap=False) # use this renderer instance markdown = mistune.Markdown(renderer=renderer) html = markdown(page) ht.write(html) return file_name