Skip to content

Commit 2637c65

Browse files
committed
add some structure to the project
1 parent 587e818 commit 2637c65

32 files changed

+137
-94
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
__pycache__
22
.envrc
3+
parse_qwantz.egg-info

add_test_case.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
number="$1"
44

55
stdout_file=test/expected_outputs/$number.txt
6-
python parse_qwantz.py $COMIC_DIR/"${number}"* > "$stdout_file"
6+
parse-qwantz $COMIC_DIR/"${number}"* > "$stdout_file"
77
cp $COMIC_DIR/"${number}"* test/comics/$number.png

dev_requirements.txt

-1
This file was deleted.

parse_qwantz/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from parse_qwantz.cli import app
2+
from parse_qwantz.main import main

box.py parse_qwantz/box.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import NamedTuple
22

3-
from pixels import Pixel
3+
from parse_qwantz.pixels import Pixel
44

55

66
class Box(NamedTuple):

cli.py parse_qwantz/cli.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
import typer
44

5-
from parse_qwantz import main
5+
from parse_qwantz.main import main
66

7+
app = typer.Typer()
78

9+
10+
@app.command()
811
def cli(image_path: Path, debug: bool = typer.Option(False, help="Enable debug features.")):
912
"""Generate transcripts for Ryan North's Dinosaur Comics from https://qwantz.com"""
1013
main(image_path, debug=debug)
1114

1215

1316
if __name__ == '__main__':
14-
typer.run(cli)
17+
app()

colors.py parse_qwantz/colors.py

File renamed without changes.

detect_thought.py parse_qwantz/detect_thought.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from collections import deque
22
from itertools import product
33

4-
from box import Box
5-
from pixels import Pixel
6-
from simple_image import SimpleImage
7-
from shape import get_shape, get_adjacent_pixels, get_box
4+
from parse_qwantz.box import Box
5+
from parse_qwantz.pixels import Pixel
6+
from parse_qwantz.simple_image import SimpleImage
7+
from parse_qwantz.shape import get_shape, get_adjacent_pixels, get_box
88

99

1010
def get_thought(pixel: Pixel, image: SimpleImage) -> tuple[Box, list[Pixel]] | None:

elements.py parse_qwantz/elements.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from logging import getLogger
22

3-
from box import Box
4-
from fonts import ALL_FONTS
5-
from lines import Line, get_line
6-
from text_lines import TextLine, try_text_line
7-
from detect_thought import get_thought
8-
from pixels import Pixel
9-
from shape import get_shape
10-
from simple_image import SimpleImage
3+
from parse_qwantz.box import Box
4+
from parse_qwantz.fonts import ALL_FONTS
5+
from parse_qwantz.lines import Line, get_line
6+
from parse_qwantz.text_lines import TextLine, try_text_line
7+
from parse_qwantz.detect_thought import get_thought
8+
from parse_qwantz.pixels import Pixel
9+
from parse_qwantz.shape import get_shape
10+
from parse_qwantz.simple_image import SimpleImage
1111

1212
logger = getLogger()
1313

fonts.py parse_qwantz/fonts.py

+21-18
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
import string
22
from dataclasses import dataclass
3+
from importlib.resources import as_file
34
from itertools import product
4-
from typing import NamedTuple
5+
from pathlib import Path
6+
from typing import NamedTuple, ContextManager
57

68
from PIL import Image
79

8-
from box import Box
9-
from pixels import Pixel
10-
from simple_image import SimpleImage
10+
from parse_qwantz.box import Box
11+
from parse_qwantz.pixels import Pixel
12+
from parse_qwantz.simple_image import SimpleImage
1113

1214
PRINTABLE = string.printable.strip()
1315
FORBIDDEN_CHARS = '\\_`|~'
1416

15-
REGULAR13_SHAPE_FILE = 'img/regular13.png'
16-
REGULAR12_SHAPE_FILE = 'img/regular12.png'
17-
REGULAR11_SHAPE_FILE = 'img/regular11.png'
18-
REGULAR9_SHAPE_FILE = 'img/regular9.png'
19-
REGULAR8_SHAPE_FILE = 'img/regular8.png'
17+
FONT_SIZES = [(13, 'Regular'), (12, 'Condensed'), (11, 'Small'), (9, 'Mini'), (8, 'Tiny')]
18+
SHIFTED_VARIANTS = {
19+
13: {',': 1, ':': 1, '.': -1},
20+
}
2021

2122

2223
class CharBox(NamedTuple):
@@ -90,9 +91,10 @@ def __repr__(self):
9091

9192
@classmethod
9293
def from_file(
93-
cls, file_path: str, name: str, shifted_variants: dict[str, int] | None = None
94+
cls, file_path_context_manager: ContextManager[Path], name: str, shifted_variants: dict[str, int] | None = None
9495
) -> "Font":
95-
image = SimpleImage.from_image(Image.open(file_path))
96+
with file_path_context_manager as file_path:
97+
image = SimpleImage.from_image(Image.open(file_path))
9698
width = image.width // len(PRINTABLE)
9799
height = image.height
98100
shapes = {}
@@ -150,10 +152,11 @@ def get_bitmask(pixel: Pixel, image: SimpleImage, width: int, height: int) -> in
150152
return bitmask
151153

152154

153-
REGULAR_FONT = Font.from_file(REGULAR13_SHAPE_FILE, 'Regular', shifted_variants={',': 1, ':': 1, '.': -1})
154-
CONDENSED_FONT = Font.from_file(REGULAR12_SHAPE_FILE, 'Condensed')
155-
SMALL_FONT = Font.from_file(REGULAR11_SHAPE_FILE, 'Small')
156-
MINI_FONT = Font.from_file(REGULAR9_SHAPE_FILE, 'Mini')
157-
TINY_FONT = Font.from_file(REGULAR8_SHAPE_FILE, 'Tiny')
158-
159-
ALL_FONTS = [REGULAR_FONT, SMALL_FONT, TINY_FONT, CONDENSED_FONT, MINI_FONT]
155+
ALL_FONTS = [
156+
Font.from_file(
157+
file_path_context_manager=as_file(Path('parse_qwantz', 'img', f'regular{size}.png')),
158+
name=name,
159+
shifted_variants=SHIFTED_VARIANTS.get(size, {}),
160+
)
161+
for size, name in FONT_SIZES
162+
]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

lines.py parse_qwantz/lines.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from itertools import groupby, product
22

3-
from pixels import Pixel
4-
from simple_image import SimpleImage
5-
from shape import get_shape, get_box
3+
from parse_qwantz.pixels import Pixel
4+
from parse_qwantz.simple_image import SimpleImage
5+
from parse_qwantz.shape import get_shape, get_box
66

77
Line = tuple[Pixel, Pixel]
88

logger.py parse_qwantz/logger.py

File renamed without changes.

parse_qwantz.py parse_qwantz/main.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33

44
from PIL import Image, ImageDraw
55

6-
from box import Box, get_interval_distance
7-
from colors import Color
8-
from text_blocks import get_text_blocks, TextBlock
9-
from elements import get_elements
10-
from match_blocks import match_blocks, Character_s
11-
from match_lines import match_lines, Character, OFF_PANEL, UnmatchedLine
12-
from match_thought import match_thought
13-
from pixels import Pixel
14-
from shape import get_box
15-
from simple_image import SimpleImage
16-
from prepare_image import apply_mask
17-
from logger import get_logger
6+
from parse_qwantz.box import Box, get_interval_distance
7+
from parse_qwantz.colors import Color
8+
from parse_qwantz.text_blocks import get_text_blocks, TextBlock
9+
from parse_qwantz.elements import get_elements
10+
from parse_qwantz.match_blocks import match_blocks, Character_s
11+
from parse_qwantz.match_lines import match_lines, Character, OFF_PANEL, UnmatchedLine
12+
from parse_qwantz.match_thought import match_thought
13+
from parse_qwantz.pixels import Pixel
14+
from parse_qwantz.shape import get_box
15+
from parse_qwantz.simple_image import SimpleImage
16+
from parse_qwantz.prepare_image import apply_mask
17+
from parse_qwantz.logger import get_logger
1818

1919
logger = get_logger()
2020

match_blocks.py parse_qwantz/match_blocks.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Iterable
22

3-
from text_blocks import TextBlock
4-
from match_lines import Target, Character
5-
from text_lines import TextLine
3+
from parse_qwantz.text_blocks import TextBlock
4+
from parse_qwantz.match_lines import Target, Character
5+
from parse_qwantz.text_lines import TextLine
66

77
Character_s = Character | tuple[Character, Character]
88

match_lines.py parse_qwantz/match_lines.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
from dataclasses import dataclass
33
from typing import Iterable
44

5-
from box import Box
6-
from lines import Line
7-
from text_blocks import TextBlock
8-
from pixels import Pixel
9-
from simple_image import SimpleImage
10-
from text_lines import TextLine
5+
from parse_qwantz.box import Box
6+
from parse_qwantz.lines import Line
7+
from parse_qwantz.text_blocks import TextBlock
8+
from parse_qwantz.pixels import Pixel
9+
from parse_qwantz.simple_image import SimpleImage
10+
from parse_qwantz.text_lines import TextLine
1111

1212
logger = logging.getLogger()
1313

match_thought.py parse_qwantz/match_thought.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from typing import Iterable
22

3-
from box import Box
4-
from text_blocks import TextBlock
5-
from match_lines import Character
3+
from parse_qwantz.box import Box
4+
from parse_qwantz.text_blocks import TextBlock
5+
from parse_qwantz.match_lines import Character
66

77

88
def match_thought(

pixels.py parse_qwantz/pixels.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from PIL import Image
55

6-
from colors import Color
6+
from parse_qwantz.colors import Color
77

88

99
class Pixel(NamedTuple):

parse_qwantz/prepare_image.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from functools import cache
2+
from importlib.resources import as_file
3+
from pathlib import Path
4+
5+
from PIL import Image
6+
7+
DIM = (735, 500)
8+
9+
MASK_FILE_PATH = Path('parse_qwantz', 'img', 'mask.png')
10+
11+
12+
@cache
13+
def get_mask_image():
14+
with as_file(MASK_FILE_PATH) as image_path:
15+
return Image.open(image_path)
16+
17+
18+
def apply_mask(image: Image):
19+
all_white = Image.new(mode='RGB', size=DIM, color=(255, 255, 255))
20+
return Image.composite(image, all_white, get_mask_image())

shape.py parse_qwantz/shape.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from typing import Collection
22

3-
from box import Box
4-
from colors import Color
5-
from pixels import Pixel
6-
from simple_image import SimpleImage
3+
from parse_qwantz.box import Box
4+
from parse_qwantz.colors import Color
5+
from parse_qwantz.pixels import Pixel
6+
from parse_qwantz.simple_image import SimpleImage
77

88

99
def get_box(shape: Collection[Pixel], padding=0) -> Box:

simple_image.py parse_qwantz/simple_image.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
from PIL import Image
44

5-
from box import Box
6-
from colors import Color
7-
from pixels import Pixel, get_pixels
5+
from parse_qwantz.box import Box
6+
from parse_qwantz.colors import Color
7+
from parse_qwantz.pixels import Pixel, get_pixels
88

99

1010
@dataclass

text_blocks.py parse_qwantz/text_blocks.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from itertools import chain, groupby
22
from typing import Iterable, NamedTuple
33

4-
from box import Box, get_interval_distance
5-
from fonts import Font
6-
from colors import Color
7-
from text_lines import TextLine, try_text_line
8-
from pixels import Pixel
9-
from simple_image import SimpleImage
4+
from parse_qwantz.box import Box, get_interval_distance
5+
from parse_qwantz.fonts import Font
6+
from parse_qwantz.colors import Color
7+
from parse_qwantz.text_lines import TextLine, try_text_line
8+
from parse_qwantz.pixels import Pixel
9+
from parse_qwantz.simple_image import SimpleImage
1010

1111

1212
class TextBlock(NamedTuple):

text_lines.py parse_qwantz/text_lines.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
from dataclasses import dataclass
44

5-
from box import Box
6-
from fonts import Font, CharBox
7-
from pixels import Pixel
8-
from simple_image import SimpleImage
5+
from parse_qwantz.box import Box
6+
from parse_qwantz.fonts import Font, CharBox
7+
from parse_qwantz.pixels import Pixel
8+
from parse_qwantz.simple_image import SimpleImage
99

1010

1111
@dataclass

prepare_image.py

-12
This file was deleted.

py.typed

Whitespace-only changes.

pyproject.toml

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[project]
2+
name = "parse_qwantz"
3+
authors = [{name = "Jan Szejko", email = "[email protected]"}]
4+
version = "2023.1.26"
5+
description = "Transcript generator for Dinosaur Comics"
6+
requires-python = ">=3.10"
7+
classifiers = [
8+
"Development Status :: 3 - Alpha",
9+
"Programming Language :: Python :: 3.10",
10+
"Environment :: Console",
11+
"Intended Audience :: End Users/Desktop",
12+
# "License :: OSI Approved :: BSD License",
13+
"Natural Language :: English",
14+
"Operating System :: OS Independent",
15+
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
16+
"Scientific/Engineering :: Image Recognition",
17+
"Typing :: Typed",
18+
]
19+
dependencies = [
20+
"Pillow",
21+
"typer",
22+
]
23+
# TODO: readme, license
24+
25+
[project.optional-dependencies]
26+
dev = ["pytest"]
27+
28+
[project.scripts]
29+
parse-qwantz = "parse_qwantz:app"

requirements.txt

-2
This file was deleted.

0 commit comments

Comments
 (0)