113 lines
3.6 KiB
Python
113 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
# IMPORTS
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
from __future__ import annotations;
|
|
|
|
from src.thirdparty.types import *;
|
|
from src.thirdparty.maths import *;
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
# EXPORTS
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
__all__ = [
|
|
'Alignment',
|
|
'AlignmentBasic',
|
|
'AlignmentPair',
|
|
];
|
|
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
# Class Alignments
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
class Alignment():
|
|
@property
|
|
def parts1(self) -> List[str]:
|
|
if isinstance(self, AlignmentBasic):
|
|
return [self.word1];
|
|
elif isinstance(self, AlignmentPair):
|
|
return self.left.parts1 + self.right.parts1;
|
|
return [];
|
|
|
|
@property
|
|
def parts2(self) -> List[str]:
|
|
if isinstance(self, AlignmentBasic):
|
|
return [self.word2];
|
|
elif isinstance(self, AlignmentPair):
|
|
return self.left.parts2 + self.right.parts2;
|
|
return [];
|
|
|
|
def astree(
|
|
self,
|
|
indent: str = ' ',
|
|
prefix: str = '',
|
|
braces: bool = False,
|
|
branch: str = ' └──── ',
|
|
) -> str:
|
|
return '\n'.join(list(self._astree_recursion(indent=indent, prefix=prefix, braces=braces, branch=branch)));
|
|
|
|
def _astree_recursion(
|
|
self,
|
|
depth: int = 0,
|
|
indent: str = ' ',
|
|
prefix: str = '',
|
|
braces: bool = False,
|
|
branch: str = ' └──── ',
|
|
branch_atom: str = '˚└──── ',
|
|
) -> Generator[str, None, None]:
|
|
word1 = self.as_string1(braces=braces);
|
|
word2 = self.as_string2(braces=braces);
|
|
if isinstance(self, AlignmentBasic):
|
|
u = prefix + branch_atom if depth > 0 else prefix;
|
|
yield f'{u}{word2}';
|
|
if depth == 0:
|
|
yield f'{" "*len(u)}{"-"*len(word1)}';
|
|
yield f'{" "*len(u)}{word1}';
|
|
elif isinstance(self, AlignmentPair):
|
|
u = prefix + branch if depth > 0 else prefix;
|
|
yield f'{u}{word2}';
|
|
if depth == 0:
|
|
yield f'{" "*len(u)}{"-"*len(word1)}';
|
|
yield f'{" "*len(u)}{word1}';
|
|
yield f'{indent}{prefix} │';
|
|
yield from self.left._astree_recursion(
|
|
depth = depth + 1,
|
|
indent = indent,
|
|
prefix = indent + prefix,
|
|
braces = braces,
|
|
branch = branch,
|
|
);
|
|
yield f'{indent}{prefix} │';
|
|
yield from self.right._astree_recursion(
|
|
depth = depth + 1,
|
|
indent = indent,
|
|
prefix = indent + prefix,
|
|
braces = braces,
|
|
branch = branch,
|
|
);
|
|
return;
|
|
|
|
def as_string1(self, braces: bool = False) -> Tuple[str, str]:
|
|
if braces:
|
|
return f'({")(".join(self.parts1)})';
|
|
return ''.join(self.parts1);
|
|
|
|
def as_string2(self, braces: bool = False,) -> Tuple[str, str]:
|
|
if braces:
|
|
return f'({")(".join(self.parts2)})';
|
|
return ''.join(self.parts2);
|
|
|
|
@dataclass
|
|
class AlignmentBasic(Alignment):
|
|
word1: str = field();
|
|
word2: str = field();
|
|
|
|
@dataclass
|
|
class AlignmentPair(Alignment):
|
|
left: Alignment = field();
|
|
right: Alignment = field();
|