Bug fixes and features #1

Merged
witten merged 12 commits from deroshkin/novel-stats-fork:deroshkin_branch into master 2021-10-22 20:05:18 +00:00
1 changed files with 18 additions and 17 deletions
Showing only changes of commit e3a47d7425 - Show all commits

View File

@ -3,13 +3,12 @@
import collections import collections
import sys import sys
import os
CHAPTER_MARKER = '## ' CHAPTER_MARKER = '## '
STATUS_MARKER = '[status]: # ' STATUS_MARKER = '[status]: # '
ACT_MARKER = '[act]: # ' ACT_MARKER = '[act]: # '
COMMENT_MARKER = '[//]: # ' COMMENT_MARKER = '[//]: # ' # Strandard markdown comment marker, supported by pandoc and calibre's ebook-convert
def count_words(line): def count_words(line):
@ -27,13 +26,17 @@ def count_words(line):
def main(): def main():
arguments = sys.argv[1:] arguments = sys.argv[1:]
filename = arguments[0] filename = arguments[0]
tmpfilename = None mdfile = None
if '-pp' in arguments: if '-pp' in arguments:
import MarkdownPP # -pp flag to allow Markdown Preprocessing primarily to allow multi-file novel formatting
tmpfilename = f'.tmp-{os.getpid}.md' # this is implemented using a temporary file created using python's buit-in tempfile library
MarkdownPP.MarkdownPP(input=open(filename), output=open(tmpfilename,'w'), modules=list(MarkdownPP.modules)) import MarkdownPP, tempfile
filename = tmpfilename mdfile = tempfile.TemporaryFile(mode='w+')
Review

Clever!

Clever!
MarkdownPP.MarkdownPP(input=open(filename), output=mdfile, modules=list(MarkdownPP.modules))
mdfile.seek(0)
else:
mdfile = open(filename)
chapter_heading = None chapter_heading = None
act_heading = None act_heading = None
@ -44,7 +47,7 @@ def main():
status_by_chapter = {} status_by_chapter = {}
current_status = None current_status = None
for line in open(filename).readlines(): for line in mdfile.readlines():
if line.startswith(CHAPTER_MARKER): if line.startswith(CHAPTER_MARKER):
word_count_by_act[act_heading] += word_count_by_chapter[chapter_heading] word_count_by_act[act_heading] += word_count_by_chapter[chapter_heading]
total_word_count += word_count_by_chapter[chapter_heading] total_word_count += word_count_by_chapter[chapter_heading]
@ -55,7 +58,7 @@ def main():
status_by_chapter[chapter_heading] = collections.defaultdict(int) status_by_chapter[chapter_heading] = collections.defaultdict(int)
current_status = None current_status = None
elif line.startswith(STATUS_MARKER): elif line.startswith(STATUS_MARKER): # Modified to allow multiple statuses in a single chapter, can swap back and forth.
if current_status == None: if current_status == None:
current_status = line[len(STATUS_MARKER):].strip('()\n') current_status = line[len(STATUS_MARKER):].strip('()\n')
status_by_chapter[chapter_heading][current_status] = count_words(chapter_heading) status_by_chapter[chapter_heading][current_status] = count_words(chapter_heading)
@ -65,7 +68,7 @@ def main():
elif line.startswith(ACT_MARKER): elif line.startswith(ACT_MARKER):
act_heading = line[len(ACT_MARKER):].strip('()\n') act_heading = line[len(ACT_MARKER):].strip('()\n')
word_count_by_act[act_heading] = count_words(act_heading) word_count_by_act[act_heading] = count_words(act_heading)
elif line.startswith(COMMENT_MARKER): elif line.startswith(COMMENT_MARKER): # don't count the words in a comment
pass pass
else: else:
line_word_count = count_words(line) line_word_count = count_words(line)
@ -79,8 +82,7 @@ def main():
word_count_by_act[act_heading] += word_count_by_chapter[chapter_heading] word_count_by_act[act_heading] += word_count_by_chapter[chapter_heading]
total_word_count += word_count_by_chapter[chapter_heading] total_word_count += word_count_by_chapter[chapter_heading]
if '-c' in arguments or '--chapter' in arguments: if '-c' in arguments or '--chapter' in arguments: # -c or --chapter to give a chapter-by-chapter word count summary
# Print out word counts.
for chapter_heading, chapter_word_count in word_count_by_chapter.items(): for chapter_heading, chapter_word_count in word_count_by_chapter.items():
if chapter_heading is None: if chapter_heading is None:
continue continue
@ -99,7 +101,7 @@ def main():
print() print()
if '-a' in arguments or '--act' in arguments: if '-a' in arguments or '--act' in arguments: # -a or --act to give an act-by-act word count summary
for act_heading, act_word_count in word_count_by_act.items(): for act_heading, act_word_count in word_count_by_act.items():
if act_heading is None: if act_heading is None:
continue continue
@ -109,12 +111,11 @@ def main():
print() print()
for status, status_word_count in word_count_by_status.items(): for status, status_word_count in word_count_by_status.items():
print('{}: {:,} words (~{}%)'.format(status, status_word_count, status_word_count * 100 // total_word_count)) print(f'{status}: {status_word_count:,} words (~{status_word_count * 100 // total_word_count}%)')
print('total: {:,} words'.format(total_word_count)) print(f'total: {total_word_count:,} words')
if tmpfilename: mdfile.close()
Review

Code changes look great! At some point it'd probably be good to switch to "formal" argument parsing (argparse, etc.), but certainly not needed now.

Code changes look great! At some point it'd probably be good to switch to "formal" argument parsing (`argparse`, etc.), but certainly not needed now.
os.remove(tmpfilename)
if __name__ == '__main__': if __name__ == '__main__':