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 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 stats(): """Gets statistics from the project (e.g., word count, etc.) :return: word_count, scene_count, sub_chapter_count, chapter_count, section_count :rtype: int Usage: >>> draft stats >>> Words: 54034 >>> Scenes: 67 >>> Sub-Chapters: 30 >>> Chapters: 10 >>> Sections: 3 """ generator = Generator() generator.confirm_project_layout() outliner = Outliner() word_count, scene_count, sub_chapter_count, chapter_count, section_count = outliner.get_statistics( ) click.secho("Words: " + str(word_count), fg="green") click.secho("Scenes: " + str(scene_count), fg="green") click.secho("Sub-Chapters: " + str(sub_chapter_count), fg="green") click.secho("Chapters: " + str(chapter_count), fg="green") click.secho("Sections: " + str(section_count), 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 test_generate_file_tree(self): generator = Generator() generator.generate_project("Gatsby") self.assertTrue(os.path.isdir("gatsby/project/Gatsby/")) self.assertTrue(os.path.isfile("gatsby/settings.yml")) self.assertTrue(os.path.isfile("gatsby/.gitignore")) rmtree("gatsby")
def test_generator_succeeds_with_dsstore(self): os.mkdir("project") dsstore = open("project/.DS_Store", "w") dsstore.write("whatever") dsstore.close() generator = Generator() generator.confirm_project_layout() rmtree("project")
def test_simple_name_removes_articles(self): titles = [("The Great Gatsby", "great-gatsby"), ("Catcher In The Rye", "catcher-rye"), ("A Light In August", "light-august"), ("On Writing", "writing"), ("Of Mice And Men", "mice-men"), ("Gatsby", "gatsby")] generator = Generator() for title in titles: shortened = generator._create_simple_name(title[0]) self.assertEqual(shortened, title[1])
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 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 create_project(title): """Generates a project structure. The root file name will be the title but: lower case, spaces replaced with dashes, and only the first two words (minus articles like 'and', 'of', etc.) :param str title: Title for the project. :return: None Usage: >>> draft generate-project 'Catcher In The Rye' """ generator = Generator() generator.generate_project(title) click.secho("Project " + title + " created.", fg="green")
def test_generate_file_tree_does_not_overwrite_existing_files(self): os.mkdir("gatsby") os.mkdir("gatsby/project") os.mkdir("gatsby/project/arbitrary") with open("gatsby/project/arbitrary/whatever.txt", "w") as test: test.write("whatever") generator = Generator() generator.generate_project("Gatsby2") self.assertTrue(os.path.isdir("gatsby/project/arbitrary/")) self.assertTrue( os.path.isfile("gatsby/project/arbitrary/whatever.txt")) with self.assertRaises(FileExistsError): generator.generate_project("Gatsby") rmtree("gatsby2")
def test_multiple_dirs_in_project_raises_error(self): os.mkdir("project") dsstore = open("project/.DS_Store", "w") dsstore.write("whatever") dsstore.close() whatever = open("project/whatever", "w") whatever.write("whatever") whatever.close() os.mkdir("project/jaunt") generator = Generator() with self.assertRaises(StructureError): generator.confirm_project_layout() rmtree("project")
def test_root_is_shortened_title(self): generator = Generator() generator.generate_project("The Great Gatsby") self.assertTrue( os.path.isdir("great-gatsby/project/The Great Gatsby/"))
def test_blank_project_raises_error_in_blank_project(self): generator = Generator() with self.assertRaises(StructureError): generator.confirm_project_layout()
def test_file_names_sanitized(self): generator = Generator() generator.generate_project("The Great Gatsby!") self.assertTrue( os.path.isdir("great-gatsby/project/The Great Gatsby/"))
def test_missing_project_returns_error(self): generator = Generator() with self.assertRaises(StructureError): generator.confirm_project_layout()