def compile(): """Compiles the project into markdown and HTML documents. Usage: >>> draft compile """ generator = Generator() generator.confirm_project_layout() outliner = Outliner() filename = outliner.compile_project(draft=True) click.secho("Project compiled at " + filename + ".", fg="green")
def test_compiles_project(self): outliner = Outliner() outliner.compile_project(draft=True) gatsby = open("Gatsby.md", "r") text = gatsby.read() gatsby.close() os.remove("Gatsby.md") os.remove("Gatsby.html") self.assertEqual( text, "# Gatsby\n\n## Part 1\n\n## Part 2\n\n### Chapter 1\n\n#### SubChapter 1\n\n**01-Scene 1.md**: the _world_ beckons!\n\n<br>\n\n**02-Scene 2.md**: the _world_ beckons!\n\n<br>\n\n### Chapter 2\n\n" )
def outline(): """Generates a new project outline. Usage: >>> draft outline """ generator = Generator() generator.confirm_project_layout() outliner = Outliner() filename = outliner.compile_project() click.secho("Project outlined at " + filename + ".", fg="green")
def test_skips_files_with_right_sequence(self): os.mkdir("project/") os.mkdir("project/Gatsby/") os.mkdir("project/Gatsby/1-Whatever/") os.mkdir("project/Gatsby/4-Other/") list = [(1, "project/Gatsby/1-Whatever/", 3), (2, "project/Gatsby/4-Other/", 3)] outliner = Outliner() outliner._rename_files(list, {3: 2}) self.assertTrue(os.path.isdir("project/Gatsby/1-Whatever")) self.assertTrue(os.path.isdir("project/Gatsby/2-Other")) rmtree('project')
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 test_returns_error_if_no_title(self): fp = open("legacy.txt", "w+") 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("\n") fp.write("## Part 2: The Whatever\n") fp.write("\n") fp.close() outliner = Outliner() with self.assertRaises(StructureError): outliner.generate_file_tree("legacy.txt")
def test_creates_outline(self): outliner = Outliner() outliner.compile_project(draft=False) gatsby = open("outline.md", "r") text = gatsby.read() gatsby.close() os.remove("outline.md") self.assertEqual( text, "# Gatsby\n\n## Part 1\n\n## Part 2\n\n### Chapter 1\n\n#### SubChapter 1\n\n**Scene 1**: This is an outline\n\n**Scene 2**\n\n### Chapter 2\n\n" ) gatsby = open("outline.html", "r") text = gatsby.read() gatsby.close() os.remove("outline.html")
def test_includes_author(self): with open("settings.yml", "w+") as settings_file: settings = {"author": "Garrett Edel"} settings_file.write(yaml.dump(settings)) outliner = Outliner() outliner.compile_project(draft=True) gatsby = open("Gatsby.md", "r") text = gatsby.read() gatsby.close() os.remove("Gatsby.md") os.remove("Gatsby.html") os.remove("settings.yml") self.assertEqual( text, "# Gatsby\n\n##### Garrett Edel\n\n## Part 1\n\n## Part 2\n\n### Chapter 1\n\n#### SubChapter 1\n\n**01-Scene 1.md**: the _world_ beckons!\n\n<br>\n\n**02-Scene 2.md**: the _world_ beckons!\n\n<br>\n\n### Chapter 2\n\n" )
def test_get_filepaths_returns_file_if_single(self): os.mkdir("project") file = open("project/whatever.md", "w") file.close() outliner = Outliner() file = cli._get_filepath("whatever.md") rmtree("project") self.assertEqual(file, "project/whatever.md")
def test_get_filepaths_raises_error_if_none(self): os.mkdir("project") file = open("project/whatever.md", "w") file.close() outliner = Outliner() with self.assertRaises(click.ClickException): files = cli._get_filepath("whatevers.md") rmtree("project")
def _get_filepath(filename): outliner = Outliner() project_outline = outliner._get_file_tree() root_files = os.listdir(".") filepaths = [ file for file in project_outline if file.split("/")[-1] == filename ] filepaths += [file for file in root_files if file == filename] if len(filepaths) == 1: return filepaths[0] elif len(filepaths) == 0: raise click.ClickException("No files matching " + filename + " found.") else: error_msg = "Multiple files matching " + filename + " found:" for filepath in filepaths: error_msg += "\n" + filepath raise click.ClickException(error_msg)
def remove_duplicate_spaces(self): pattern = " {2,}" if self.filepath: paths = [self.filepath] else: outliner = Outliner() files = outliner._get_file_tree() paths = [ file for file in files if os.path.isfile(file) and file[-3:] == ".md" ] for path in paths: with open(path, "r+") as file: text = file.read() text = re.sub(pattern, " ", text) file.truncate(0) file.seek(0) file.write(text)
def test_increments_outline_if_exists(self): with open("outline.md", "w") as outline: outline.write("whatever") with open("2-outline.md", "w") as outline: outline.write("whatever") outliner = Outliner() outliner.compile_project(draft=False) gatsby = open("3-outline.md", "r") text = gatsby.read() gatsby.close() self.assertTrue(os.path.exists("2-outline.md")) self.assertEqual( text, "# Gatsby\n\n## Part 1\n\n## Part 2\n\n### Chapter 1\n\n#### SubChapter 1\n\n**Scene 1**: This is an outline\n\n**Scene 2**\n\n### Chapter 2\n\n" ) os.remove("2-outline.md") os.remove("3-outline.md") os.remove("outline.md") os.remove("outline.html")
def test_headers_overridden(self): with open("settings.yml", "w+") as settings_file: settings = { "overrides": { "Gatsby": "The Great Gatsby", "Chapter 1": "Chapter 1: Word", } } settings_file.write(yaml.dump(settings)) outliner = Outliner() outliner.compile_project(draft=True) gatsby = open("Gatsby.md", "r") text = gatsby.read() gatsby.close() os.remove("Gatsby.md") os.remove("Gatsby.html") os.remove("settings.yml") self.assertEqual( text, "# The Great Gatsby\n\n## Part 1\n\n## Part 2\n\n### Chapter 1: Word\n\n#### SubChapter 1\n\n**01-Scene 1.md**: the _world_ beckons!\n\n<br>\n\n**02-Scene 2.md**: the _world_ beckons!\n\n<br>\n\n### Chapter 2\n\n" )
def test_non_mdtxt_raises_error(self): outliner = Outliner() with self.assertRaises(Exception): outliner.generate_file_tree("legacy.doc")
def split_sentences(self): pattern = '([\"\“]?[A-Z][^\.!?]*[\.!?][\"\”]?) {1,2}' abbreviations = ["etc.", "Mrs.", "Mr.", "Dr.", "Ms."] if self.filepath: paths = [self.filepath] else: outliner = Outliner() files = outliner._get_file_tree() paths = [ file for file in files if os.path.isfile(file) and file[-3:] == ".md" ] skipped_files = [] for path in paths: with open(path, "r+") as file: text = file.read() # If more than half of the lines in a file is already on new lines # then skip it unless it was explicitly called on that file if self._get_split_ratio(text) > .5 and not self.filepath: split_path = path.split("/") name = split_path[-1] skipped_files.append(name) continue text = text.replace("\t", "") text = text.replace("\n", "\n\n") lines = re.split(pattern, text) lines = [line for line in lines if line] skip = False kill_index = [] for index, line in enumerate(lines): if skip: skip = False kill_index.append(index) continue for abbreviation in abbreviations: if line.endswith(abbreviation): line = line + " " + lines[index + 1] lines[index] = line skip = True break try: if lines[index + 1][0].islower(): line = line + " " + lines[index + 1] lines[index] = line skip = True except IndexError: pass lines = [ line for index, line in enumerate(lines) if index not in kill_index ] text = "\n".join(lines) text = re.sub("\\n{3,}", "\\n\\n", text) text = text.replace(" \n", "\n") file.truncate(0) file.seek(0) file.write(text) for file in skipped_files: click.secho(file, fg="red") if skipped_files: click.secho( "Above files skipped since >50% of lines are already separated", fg="red") click.secho("You can force by running `draft trim filepath`", fg="red")
def test_generate_file_tree(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("\n") fp.write("## Part 2: The Whatever\n") fp.write("\n") fp.write("##### The Bar\n") fp.write("\n") fp.write("It was a fall day.\n") fp.write("It was cold.\n") fp.write("## Part 3: Tomorrow\n") fp.write("\n") fp.write("##### The Next Day\n") fp.write("\n") fp.write("Now it's tomorrow.\n") fp.write("It's still cold.\n") fp.write("## Part 4 Test\n") fp.close() outliner = Outliner() outliner.generate_file_tree("legacy.txt") self.assertEqual(len(os.listdir("project/Gatsby/")), 4) self.assertTrue(os.path.isdir("project/Gatsby/1-Part 1 The Reckoning")) self.assertTrue( os.path.isdir( "project/Gatsby/1-Part 1 The Reckoning/1-Chapter 1 The Promise" )) self.assertTrue( os.path.isdir( "project/Gatsby/1-Part 1 The Reckoning/1-Chapter 1 The Promise/1-New York 1942" )) self.assertTrue(os.path.isdir("project/Gatsby/2-Part 2 The Whatever")) self.assertTrue(os.path.isdir("project/Gatsby/3-Part 3 Tomorrow")) self.assertTrue( os.path.isfile( "project/Gatsby/2-Part 2 The Whatever/1-The Bar.md")) with open("project/Gatsby/2-Part 2 The Whatever/1-The Bar.md", "r") as fp: lines = fp.readlines() self.assertEqual(lines[0], "It was a fall day.\n") self.assertEqual(lines[1], "It was cold.\n") self.assertEqual(len(lines), 2) with open("settings.yml", "r") as settings_file: settings = yaml.safe_load(settings_file) self.assertEqual( settings, { "overrides": { "Chapter 1 The Promise": "Chapter 1: The Promise", "New York 1942": "New York, 1942", "Part 1 The Reckoning": "Part 1: The Reckoning", "Part 2 The Whatever": "Part 2: The Whatever", "Part 3 Tomorrow": "Part 3: Tomorrow" } }) os.remove("settings.yml")