Compare commits
2 Commits
master
...
deroshkin_
Author | SHA1 | Date |
---|---|---|
deroshkin | 357eceabad | |
Dmytro Yeroshkin | 1c53c94b9c |
31
.drone.yml
31
.drone.yml
|
@ -1,12 +1,39 @@
|
|||
---
|
||||
kind: pipeline
|
||||
name: python-3-11-alpine-3-18
|
||||
name: python-3-6-alpine-3-9
|
||||
|
||||
clone:
|
||||
skip_verify: true
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: alpine:3.18
|
||||
image: alpine:3.9
|
||||
pull: always
|
||||
commands:
|
||||
- tests/run-ci-tests
|
||||
---
|
||||
kind: pipeline
|
||||
name: python-3-7-alpine-3-10
|
||||
|
||||
clone:
|
||||
skip_verify: true
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: alpine:3.10
|
||||
pull: always
|
||||
commands:
|
||||
- tests/run-ci-tests
|
||||
---
|
||||
kind: pipeline
|
||||
name: python-3-8-alpine-3-13
|
||||
|
||||
clone:
|
||||
skip_verify: true
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: alpine:3.13
|
||||
pull: always
|
||||
commands:
|
||||
- tests/run-ci-tests
|
||||
|
|
18
README.md
18
README.md
|
@ -57,11 +57,11 @@ total: 946 words
|
|||
|
||||
## Installation
|
||||
|
||||
Start by cloning the project with git. Then install it with
|
||||
[pipx](https://pypa.github.io/pipx/). Example:
|
||||
Start by cloning the project with git. Then install it with Python's `pip`.
|
||||
Example:
|
||||
|
||||
```bash
|
||||
pipx install /path/to/novel-stats
|
||||
pip3 install /path/to/novel-stats
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
@ -226,9 +226,17 @@ make sure your changes work.
|
|||
|
||||
```bash
|
||||
cd novel-stats/
|
||||
pipx install --editable .
|
||||
pip3 install --editable --user .
|
||||
```
|
||||
|
||||
Note that this will typically install the novel-stats commands into
|
||||
`~/.local/bin`, which may or may not be on your PATH. There are other ways to
|
||||
install novel-stats editable as well, for instance into the system Python
|
||||
install (so without `--user`, as root), or even into a
|
||||
[virtualenv](https://virtualenv.pypa.io/en/stable/). How or where you install
|
||||
novel-stats is up to you, but generally an editable install makes development
|
||||
and testing easier.
|
||||
|
||||
|
||||
### Automated tests
|
||||
|
||||
|
@ -237,7 +245,7 @@ you're in the `novel-stats/` working copy, install tox, which is used for
|
|||
setting up testing environments:
|
||||
|
||||
```bash
|
||||
pipx install tox
|
||||
pip3 install --user tox
|
||||
```
|
||||
|
||||
Finally, to actually run tests, run:
|
||||
|
|
|
@ -4,18 +4,21 @@
|
|||
import argparse
|
||||
import collections
|
||||
import tempfile
|
||||
import re
|
||||
|
||||
CHAPTER_MARKER = '## '
|
||||
STATUS_MARKER = '[status]: # '
|
||||
ACT_MARKER = '[act]: # '
|
||||
# Standard markdown comment marker, supported by Pandoc and Calibre's ebook-convert.
|
||||
COMMENT_MARKER = '[//]: # '
|
||||
TITLE_MARKER = '# '
|
||||
WORD_SEPS = [' ','—']
|
||||
|
||||
|
||||
def count_words(line):
|
||||
count = 0
|
||||
|
||||
for word in line.strip().split(' '):
|
||||
for word in re.split('|'.join(WORD_SEPS), line.strip()):
|
||||
if not word.strip() or word == '*' or word.startswith('#'):
|
||||
continue
|
||||
|
||||
|
@ -72,8 +75,9 @@ def main():
|
|||
word_count_by_chapter = collections.defaultdict(int)
|
||||
word_count_by_status = collections.defaultdict(int)
|
||||
word_count_by_act = collections.defaultdict(int)
|
||||
status_by_chapter = collections.defaultdict(lambda: collections.defaultdict(int))
|
||||
status_by_chapter = {}
|
||||
current_status = None
|
||||
title = None
|
||||
|
||||
for line in mdfile.readlines():
|
||||
if line.startswith(CHAPTER_MARKER):
|
||||
|
@ -83,22 +87,24 @@ def main():
|
|||
chapter_heading = line[len(CHAPTER_MARKER) :].strip('()\n')
|
||||
|
||||
# Count the words in chapter heading, because the chapter number and title count as words.
|
||||
if chapter_heading:
|
||||
word_count_by_chapter[chapter_heading] = count_words(chapter_heading)
|
||||
current_status = None
|
||||
word_count_by_chapter[chapter_heading] = count_words(chapter_heading)
|
||||
|
||||
status_by_chapter[chapter_heading] = collections.defaultdict(int)
|
||||
current_status = None
|
||||
# Modified to allow multiple statuses in a single chapter, can swap back and forth.
|
||||
elif line.startswith(STATUS_MARKER):
|
||||
if current_status is None:
|
||||
current_status = line[len(STATUS_MARKER) :].strip('()\n')
|
||||
if chapter_heading:
|
||||
status_by_chapter[chapter_heading][current_status] = count_words(
|
||||
chapter_heading
|
||||
)
|
||||
status_by_chapter[chapter_heading][current_status] = count_words(chapter_heading)
|
||||
else:
|
||||
current_status = line[len(STATUS_MARKER) :].strip('()\n')
|
||||
elif line.startswith(ACT_MARKER):
|
||||
act_heading = line[len(ACT_MARKER) :].strip('()\n')
|
||||
word_count_by_act[act_heading] = count_words(act_heading)
|
||||
elif line.startswith(TITLE_MARKER):
|
||||
title = line[len(TITLE_MARKER):].strip()
|
||||
line_word_count = count_words(line)
|
||||
word_count_by_chapter[chapter_heading] += line_word_count
|
||||
elif line.startswith(COMMENT_MARKER): # Don't count the words in a comment.
|
||||
pass
|
||||
else:
|
||||
|
@ -115,6 +121,9 @@ def main():
|
|||
word_count_by_act[act_heading] += word_count_by_chapter[chapter_heading]
|
||||
total_word_count += word_count_by_chapter[chapter_heading]
|
||||
|
||||
if title:
|
||||
print(f'Novel Stats for {title.upper()}')
|
||||
|
||||
# -c or --chapter to give a chapter-by-chapter word count summary.
|
||||
if arguments.chapter:
|
||||
for chapter_heading, chapter_word_count in word_count_by_chapter.items():
|
||||
|
|
11
setup.py
11
setup.py
|
@ -20,15 +20,8 @@ setup(
|
|||
"Topic :: Text Processing :: Markup",
|
||||
],
|
||||
packages=find_packages(exclude=["tests*"]),
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"novel-stats = novel_stats.novel_stats:main",
|
||||
]
|
||||
},
|
||||
entry_points={"console_scripts": ["novel-stats = novel_stats.novel_stats:main",]},
|
||||
install_requires=(),
|
||||
extras_require={
|
||||
"multi_file": ["MarkdownPP"],
|
||||
},
|
||||
extras_require={"multi_file": ["MarkdownPP"],},
|
||||
include_package_data=True,
|
||||
python_requires='>3.7.0',
|
||||
)
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
appdirs==1.4.4
|
||||
attrs==23.1.0
|
||||
black==23.10.1
|
||||
click==8.1.7
|
||||
coverage==7.3.2
|
||||
flake8==6.1.0
|
||||
flexmock==0.11.3
|
||||
isort==5.12.0
|
||||
mccabe==0.7.0
|
||||
pluggy==1.3.0
|
||||
pathspec==0.11.2
|
||||
py==1.11.0
|
||||
pycodestyle==2.11.1
|
||||
pyflakes==3.1.0
|
||||
pytest==7.4.2
|
||||
pytest-cov==4.1.0
|
||||
regex
|
||||
typed-ast
|
||||
appdirs==1.4.4; python_version >= '3.8'
|
||||
attrs==20.3.0; python_version >= '3.8'
|
||||
black==19.10b0; python_version >= '3.8'
|
||||
click==7.1.2; python_version >= '3.8'
|
||||
coverage==5.3
|
||||
flake8==3.8.4
|
||||
flexmock==0.10.4
|
||||
isort==5.9.1
|
||||
mccabe==0.6.1
|
||||
pluggy==0.13.1
|
||||
pathspec==0.8.1; python_version >= '3.8'
|
||||
py==1.10.0
|
||||
pycodestyle==2.6.0
|
||||
pyflakes==2.2.0
|
||||
pytest==6.1.2
|
||||
pytest-cov==2.10.1
|
||||
regex; python_version >= '3.8'
|
||||
typed-ast==1.4.2; python_version >= '3.8'
|
||||
|
|
|
@ -9,6 +9,7 @@ set -e
|
|||
apk add --no-cache python3 py3-pip
|
||||
# If certain dependencies of black are available in this version of Alpine, install them.
|
||||
apk add --no-cache py3-typed-ast py3-regex || true
|
||||
pip3 install tox==4.11.3
|
||||
python3 -m pip install --upgrade pip==21.3.1 setuptools==58.2.0
|
||||
pip3 install tox==3.24.4
|
||||
export COVERAGE_FILE=/tmp/.coverage
|
||||
tox --workdir /tmp/.tox --sitepackages
|
||||
|
|
17
tox.ini
17
tox.ini
|
@ -1,16 +1,16 @@
|
|||
[tox]
|
||||
env_list = py38,py39,py310,py311
|
||||
envlist = py36,py37,py38,py39
|
||||
skip_missing_interpreters = True
|
||||
package = editable
|
||||
minversion = 4.0
|
||||
skipsdist = True
|
||||
minversion = 3.14.1
|
||||
|
||||
[testenv]
|
||||
deps =
|
||||
-r test_requirements.txt
|
||||
pass_env = COVERAGE_FILE
|
||||
usedevelop = True
|
||||
deps = -rtest_requirements.txt
|
||||
passenv = COVERAGE_FILE
|
||||
commands =
|
||||
pytest {posargs}
|
||||
black --check .
|
||||
py38,py39: black --check .
|
||||
isort --check-only --settings-path setup.cfg .
|
||||
flake8 novel_stats tests
|
||||
|
||||
|
@ -23,7 +23,6 @@ commands =
|
|||
pytest {posargs}
|
||||
|
||||
[testenv:isort]
|
||||
deps =
|
||||
{[testenv]deps}
|
||||
deps = {[testenv]deps}
|
||||
commands =
|
||||
isort --settings-path setup.cfg .
|
||||
|
|
Loading…
Reference in New Issue