Skip to content

Commit

Permalink
Some more changes
Browse files Browse the repository at this point in the history
  • Loading branch information
schorrm committed Apr 7, 2023
1 parent e49c894 commit 43e822d
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 75 deletions.
30 changes: 15 additions & 15 deletions src/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# * is /TS:style/ tag only shorthand for /F:::style/?
# * is it toggle bitfield or overwrite?
# * what happens if calling /END:TS/ after /F/ or vice versa? (Do we need a 4th Style object?)


class FormatManager:
class FormatContext:
def __init__(self, def_font=Font(), def_align=Alignment(), def_color=Color()):
Expand Down Expand Up @@ -51,36 +53,35 @@ def update_context(self, tag):
elif tag.type == TagType.TEXTSTYLE:
self.TS_tag(tag)
elif tag.type == TagType.POP:
warnings.warn("Got POP tag in update_context(). pop_tag() should be called explicitly", SyntaxWarning)
warnings.warn(
"Got POP tag in update_context(). pop_tag() should be called explicitly", SyntaxWarning)
self.pop_tag(tag)
else:
# TODO: Usefuller error messages. Own error type(s)?
raise RuntimeError("Got bad tag type")

def pop_tag(self, tag):
""" Handles a pop tag """
if tag == TagType.FONT:
target_array = self.fonts
elif tag == TagType.ALIGNMENT:
target_array = self.aligns
elif tag == TagType.COLOR:
target_array = self.colors
elif tag == TagType.TEXTSTYLE:
target_array = self.fonts
else:
raise RuntimeError("Invalid pop tag data")
match tag:
case TagType.FONT | TagType.TEXTSTYLE:
target_array = self.fonts
case TagType.ALIGNMENT:
target_array = self.aligns
case TagType.COLOR:
target_array = self.colors
case _:
raise RuntimeError("Invalid pop tag data")

if len(target_array) > 1:
target_array.pop()
else:
raise SyntaxError("Can't pop default formatting specifier")

def _flatten(self):
self.fonts = [self.current_font]
self.aligns = [self.current_align]
self.colors = [self.current_color]


@property
def _current_context(self):
return self.contexts[-1]
Expand All @@ -95,7 +96,7 @@ def push_context(self, scoped_tags):
self.current_color))
for tag in scoped_tags:
self.update_context(tag)

self._current_context._flatten()

def pop_context(self):
Expand All @@ -111,4 +112,3 @@ def scoped_context(self, scoped_tags):
context = self._current_context
self.pop_context()
return context

41 changes: 24 additions & 17 deletions src/format_types.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
#!/usr/bin/python3

from dataclasses import dataclass, field
from PIL import ImageFont
from PIL.ImageFont import FreeTypeFont
from .defines import TagType, DEFAULT_FONT_SIZE


def _STATIC(tag: TagType) -> TagType:
return field(init=False, default=tag)


@dataclass
class Font:
def __init__(self, font_face='Impact', font_size=DEFAULT_FONT_SIZE, outline_size=0, text_style='r'):
self.font_face = font_face
self.font_size = font_size
self.outline_size = outline_size
self.text_style = text_style
self._cached_font = None
self.type = TagType.FONT
font_face: str = 'Impact'
font_size: int = DEFAULT_FONT_SIZE
outline_size: int = 0
text_style: str = 'r'
type: TagType = _STATIC(TagType.FONT)
_cached_font: FreeTypeFont | None = field(init=False, default=None)

@property
def PIL_font(self):
Expand All @@ -21,7 +27,8 @@ def PIL_font(self):
self._cached_font = ImageFont.truetype(
font=self.font_face, size=self.font_size)
except OSError:
raise RuntimeError(f"Couldn't find font {self.font_face}")
# re-raise with a diagnostic so you can find the missing font..
raise OSError(f"Couldn't find font '{self.font_face}'")
return self._cached_font

def inherit_from(self, update_font):
Expand All @@ -36,11 +43,11 @@ def __repr__(self):
return f'<Font: {self.font_face} {self.font_size}{self.text_style}, {self.outline_size}>'


@dataclass
class Alignment:
def __init__(self, halign: str = 'center', valign: str = 'center'):
self.halign = halign
self.valign = valign
self.type = TagType.ALIGNMENT
halign: str = 'center'
valign: str = 'center'
type: TagType = _STATIC(TagType.ALIGNMENT)

def inherit_from(self, update_alignment):
self.halign = self.halign or update_alignment.halign
Expand All @@ -51,12 +58,12 @@ def __repr__(self):
return f'<Align {self.halign}, {self.valign}>'


@dataclass
class Color:
def __init__(self, foreground: str = "black", background: str = None, outline: str = "white"):
self.foreground = foreground
self.background = background
self.outline = outline
self.type = TagType.COLOR
foreground: str = "black"
background: str | None = None
outline: str = "white"
type: TagType = _STATIC(TagType.COLOR)

def inherit_from(self, update_color):
self.foreground = self.foreground or update_color.foreground
Expand Down
38 changes: 16 additions & 22 deletions src/layout_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,22 @@
from dataclasses import dataclass


class Pop:
def __init__(self, tag: TagType):
self.type = TagType.POP
self.target = tag
# Represents the interface for grouping the structural objects
class LPTag:
pass


@dataclass
class Pop(LPTag):
target: TagType
type: TagType = TagType.POP

def __repr__(self):
return f'<Pop {self.target}>'


@dataclass
class LPMeme:
class LPMeme(LPTag):
image: str | None = None
size: tuple[int | None, int | None] = (None, None)
fillcolor: str = 'white'
Expand All @@ -34,7 +39,7 @@ def __repr__(self):


@dataclass
class LPText:
class LPText(LPTag):
text: str
position: str | None = None
rotation: int = 0
Expand All @@ -45,7 +50,7 @@ def __repr__(self):


@dataclass
class LPComposite:
class LPComposite(LPTag):
gridsize: Any | None = None # TODO(schorrm): fix with correct types
gridposition: Any | None = None # TODO(schorrm): fix with correct type
type: TagType | None = TagType.COMPOSITE
Expand All @@ -54,21 +59,10 @@ def __repr__(self):
return f'<LPComposite: {self.gridsize} @{self.gridposition}>'


class LPWhitespacePrefix:
def __init__(self, text):
self.text = text
self.type = TagType.WHITESPACE
@dataclass
class LPWhitespacePrefix(LPTag):
text: str
type: TagType = TagType.WHITESPACE

def __repr__(self):
return f'<WP: {self.text}>'

# class LPOutput:
# def __init__(self, tagtype: TagType, data: Dict):
# self.type = tagtype
# self.data = data

# def __getattr__(self, attr):
# if attr in self.data.keys():
# return self.data[attr]
# else:
# raise ???
38 changes: 17 additions & 21 deletions src/stack_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,23 @@ def parse(self, tag_list: List[List]) -> List:

self.lookaheads = 0
for tag, *scoped_tags in tag_list:
if is_layout_obj(tag): # create new scope for layout object
match tag:
case LPText():
self.current_scope.children.append(
Scope(tag, scoped_tags))
case LPWhitespacePrefix():
self.add_scope(LPMeme(image=None, size=(
"lookahead", None), fillcolor='white'), list())
self.current_scope.children.append(Scope(LPText(tag.text, position='all'), [Alignment("left", "top"), Font(
WP_DEFAULT_FONT, WP_DEFAULT_FONTSIZE, WP_DEFAULT_OL_SIZE), *scoped_tags]))
case LPMeme() | LPComposite():
self.add_scope(tag, scoped_tags)

else: # format tags
match tag:
case Pop(target=TagType.MEME):
self.pop_meme()
case Pop(target=TagType.COMPOSITE):
self.pop_composite()
case _:
self.current_scope.children.append(tag)
match tag:
case LPText():
self.current_scope.children.append(
Scope(tag, scoped_tags))
case LPWhitespacePrefix():
self.add_scope(LPMeme(image=None, size=(
"lookahead", None), fillcolor='white'), list())
self.current_scope.children.append(Scope(LPText(tag.text, position='all'), [Alignment("left", "top"), Font(
WP_DEFAULT_FONT, WP_DEFAULT_FONTSIZE, WP_DEFAULT_OL_SIZE), *scoped_tags]))
case LPMeme() | LPComposite():
self.add_scope(tag, scoped_tags)
case Pop(target=TagType.MEME):
self.pop_meme()
case Pop(target=TagType.COMPOSITE):
self.pop_composite()
case _:
self.current_scope.children.append(tag)

# implictly popping the meme caused non-existant scope errors
if self.current_scope_tag == TagType.MEME:
Expand Down

0 comments on commit 43e822d

Please sign in to comment.