Move colorization to the display layer
Color output isn't necessarily always going to be a terminal output thing, and terminals don't always support the same escape codes (e.g. on Windows). Thus, all colorization efforts are done in the Display rather than in the Game. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -2,10 +2,11 @@ import argparse
|
|||||||
import importlib.util
|
import importlib.util
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
from agame.color import colorize
|
|
||||||
from agame.display import ANSIDisplay
|
|
||||||
from agame.game import Game
|
from agame.game import Game
|
||||||
|
|
||||||
|
# TODO - conditional import for this based on OS
|
||||||
|
from agame.display import ANSIDisplay
|
||||||
|
|
||||||
|
|
||||||
# Parse args
|
# Parse args
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ("colorize",)
|
|
||||||
|
|
||||||
BOLD_PAT = re.compile(r"\*\*(.+?)\*\*", re.MULTILINE)
|
|
||||||
ITALIC_PAT = re.compile(r"//(.+?)//", re.MULTILINE)
|
|
||||||
INTEREST_PAT = re.compile(r"\(\((.+?)\)\)", re.MULTILINE)
|
|
||||||
SHADOW_PAT = re.compile(r"\{\{(.+?)\}\}", re.MULTILINE)
|
|
||||||
|
|
||||||
BOLD_COL = "\u001b[1m"
|
|
||||||
ITALIC_COL = "\u001b[3m"
|
|
||||||
INTEREST_COL = "\u001b[34;1m"
|
|
||||||
SHADOW_COL = "\u001b[30;1m"
|
|
||||||
RESET_COL = "\u001b[0m"
|
|
||||||
|
|
||||||
|
|
||||||
def colorize(text: str) -> str:
|
|
||||||
"""
|
|
||||||
Colorizes text for output on an ANSI terminal.
|
|
||||||
|
|
||||||
This will use escape codes to replace things.
|
|
||||||
|
|
||||||
Style guide:
|
|
||||||
((This)) is "interest" styling. This will make the text blue.
|
|
||||||
{{This}} is "shadow" styling. This will make the text a dark grey (or at
|
|
||||||
least, more subtle.)
|
|
||||||
"""
|
|
||||||
replacements = [
|
|
||||||
(INTEREST_PAT, INTEREST_COL),
|
|
||||||
(SHADOW_PAT, SHADOW_COL),
|
|
||||||
(BOLD_PAT, BOLD_COL),
|
|
||||||
(ITALIC_PAT, ITALIC_COL),
|
|
||||||
]
|
|
||||||
|
|
||||||
for (pat, col) in replacements:
|
|
||||||
text = pat.sub(col + r"\1" + RESET_COL, text)
|
|
||||||
|
|
||||||
return text
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import termios
|
import termios
|
||||||
from typing import Optional, Sequence, TextIO, Tuple, TYPE_CHECKING
|
from typing import Optional, Sequence, TextIO, Tuple, TYPE_CHECKING
|
||||||
from agame.color import colorize
|
|
||||||
from agame.action import Action
|
from agame.action import Action
|
||||||
from agame.dialog import DialogOption
|
from agame.dialog import DialogOption
|
||||||
from .display import Display
|
from .display import Display
|
||||||
@@ -9,8 +9,44 @@ from .display import Display
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from agame.game import Game
|
from agame.game import Game
|
||||||
|
|
||||||
|
__all__ = ("ANSIDisplay",)
|
||||||
|
|
||||||
ESC = "\u001b"
|
ESC = "\u001b"
|
||||||
ANSI_MOVE_BOTTOM = f"{ESC}[999;0f"
|
ANSI_MOVE_BOTTOM = f"{ESC}[999;0f"
|
||||||
|
ANSI_BOLD_COL = f"{ESC}[1m"
|
||||||
|
ANSI_ITALIC_COL = f"{ESC}[3m"
|
||||||
|
ANSI_INTEREST_COL = f"{ESC}[34;1m"
|
||||||
|
ANSI_SHADOW_COL = f"{ESC}[30;1m"
|
||||||
|
ANSI_RESET_COL = f"{ESC}[0m"
|
||||||
|
|
||||||
|
BOLD_PAT = re.compile(r"\*\*(.+?)\*\*", re.MULTILINE)
|
||||||
|
ITALIC_PAT = re.compile(r"//(.+?)//", re.MULTILINE)
|
||||||
|
INTEREST_PAT = re.compile(r"\(\((.+?)\)\)", re.MULTILINE)
|
||||||
|
SHADOW_PAT = re.compile(r"\{\{(.+?)\}\}", re.MULTILINE)
|
||||||
|
|
||||||
|
|
||||||
|
def colorize(text: str) -> str:
|
||||||
|
"""
|
||||||
|
Colorizes text for output on an ANSI terminal.
|
||||||
|
|
||||||
|
This will use escape codes to replace things.
|
||||||
|
|
||||||
|
Style guide:
|
||||||
|
((This)) is "interest" styling. This will make the text blue.
|
||||||
|
{{This}} is "shadow" styling. This will make the text a dark grey (or at
|
||||||
|
least, more subtle.)
|
||||||
|
"""
|
||||||
|
replacements = [
|
||||||
|
(INTEREST_PAT, ANSI_INTEREST_COL),
|
||||||
|
(SHADOW_PAT, ANSI_SHADOW_COL),
|
||||||
|
(BOLD_PAT, ANSI_BOLD_COL),
|
||||||
|
(ITALIC_PAT, ANSI_ITALIC_COL),
|
||||||
|
]
|
||||||
|
|
||||||
|
for (pat, col) in replacements:
|
||||||
|
text = pat.sub(col + r"\1" + ANSI_RESET_COL, text)
|
||||||
|
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
class ANSIDisplay(Display):
|
class ANSIDisplay(Display):
|
||||||
@@ -47,6 +83,7 @@ class ANSIDisplay(Display):
|
|||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
def line(self, line: str = ""):
|
def line(self, line: str = ""):
|
||||||
|
line = colorize(line)
|
||||||
self.stdout.write(line)
|
self.stdout.write(line)
|
||||||
self.stdout.write("\n")
|
self.stdout.write("\n")
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import dataclasses
|
|||||||
import textwrap
|
import textwrap
|
||||||
from typing import Any, MutableMapping, List, Match, Optional, Sequence, Union
|
from typing import Any, MutableMapping, List, Match, Optional, Sequence, Union
|
||||||
from agame.action import Action
|
from agame.action import Action
|
||||||
from agame.color import colorize
|
|
||||||
from agame.display import Display
|
from agame.display import Display
|
||||||
from agame.item import Item, ItemInst
|
from agame.item import Item, ItemInst
|
||||||
from agame.room import Room
|
from agame.room import Room
|
||||||
@@ -141,12 +140,11 @@ class Game:
|
|||||||
"Format, colorize, wrap, and print the message."
|
"Format, colorize, wrap, and print the message."
|
||||||
if lines:
|
if lines:
|
||||||
head = textwrap.fill(lines[0])
|
head = textwrap.fill(lines[0])
|
||||||
# TODO - move colorize to Display
|
self.display.line(head)
|
||||||
self.display.line(colorize(head))
|
|
||||||
for line in lines[1:]:
|
for line in lines[1:]:
|
||||||
message = textwrap.fill(line)
|
message = textwrap.fill(line)
|
||||||
self.display.line()
|
self.display.line()
|
||||||
self.display.line(colorize(message))
|
self.display.line(message)
|
||||||
else:
|
else:
|
||||||
self.display.line()
|
self.display.line()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user