Source code for derobertis_cv.pltemplates.skills.skill_dot

from typing import Sequence, Union

import pyexlatex as pl
from pyexlatex.typing import PyexlatexItems

partial_circle_def = pl.Raw(
    r"""
\tikzset{%
    pics/partialcircle/.style args={#1/#2/#3/#4}{code={%
        \ifstrequal{#2}{0}{%
            \node[circle,minimum width=1.35mm,draw=#4,fill=#1] {};
        }{%
            \tkzDefPoint(0,0){O}
            \tkzDrawSector[R,fill=#1,draw=#4](O,1.35mm)(90,90-#2)
            \tkzDrawSector[R,fill=#3,draw=#4](O,1.35mm)(90-#2,90-360)
    }
    }},
}
"""
)

GRAY_DARK = 130
GRAY_LIGHT = 220


[docs] class PartialCircle(pl.Template):
[docs] def __init__( self, fill: float = 0.5, bg_color: Union[str, pl.TextColor] = "white", fg_color: Union[str, pl.TextColor] = "black", line_color: Union[str, pl.TextColor] = "black", ): self.fill = fill self.bg_color = bg_color self.fg_color = fg_color self.line_color = line_color self.init_data() self.add_package("etoolbox") self.add_package("tkz-euclide") self.data.packages.extend( [ # pl.Raw(r'\usetkzobj{all}'), # required in overleaf but not with newer version of tkz-euclide partial_circle_def ] ) self.contents = self._get_contents() super().__init__()
def _validate_contents(self): if self.fill < 0 or self.fill > 1: raise ValueError(f"fill must be between 0 and 1, got {self.fill}") super()._validate_contents() @property def _circle_fill(self) -> int: full = 360 return int(full * self.fill) def _get_contents(self) -> PyexlatexItems: if self.fill == 1: fill_def = str(self.fg_color) + "/0//" + str(self.line_color) else: fill_def = ( str(self.bg_color) + "/" + str(self._circle_fill) + "/" + str(self.fg_color) + "/" + str(self.line_color) ) return [ pl.TextSize(-3), r"\tikz[baseline=-0.9ex]\pic{partialcircle=" + fill_def + "};", pl.TextSize(0), ]
[docs] class SkillDot(PartialCircle):
[docs] def __init__( self, level: int, max_level: int = 5, color_level: int = 1, color_choices: Sequence[Union[str, pl.TextColor]] = ("black",), ): fill = (level - 1) * 1 / (max_level - 1) try: color = color_choices[color_level - 1] except IndexError: raise ValueError( "Must pass a 1-based index for color_level which is valid for the length of color_choices" ) super().__init__(fill, fg_color=color, line_color=color)
[docs] class GrayscaleSkillDot(SkillDot):
[docs] def __init__(self, level: int, max_level: int = 5, color_level: int = 3): gray_dark = GRAY_DARK gray_light = GRAY_LIGHT gray_dark_def = pl.RGB( gray_dark, gray_dark, gray_dark, color_name=f"gray{gray_dark}" ) gray_light_def = pl.RGB( gray_light, gray_light, gray_light, color_name=f"gray{gray_light}" ) self.init_data() self.add_package("xcolor") self.data.packages.extend([gray_dark_def, gray_light_def]) colors = (f"gray{gray_light}", f"gray{gray_dark}", "black") super().__init__( level, max_level=max_level, color_level=color_level, color_choices=colors )