Skip to content

Commit

Permalink
fix(templating): Fix whitespace/newlines around sections
Browse files Browse the repository at this point in the history
Every section is now preceeded by 2 empty lines.
Trailing newlines at the very end were removed.
Spacing was generally unified.
  • Loading branch information
alexpovel committed Sep 3, 2022
1 parent 7c95f76 commit 3e5b5c6
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 14 deletions.
43 changes: 29 additions & 14 deletions ancv/visualization/templates.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import json
from abc import ABC, abstractmethod
from contextlib import redirect_stdout
from functools import partial, singledispatchmethod
from functools import singledispatchmethod
from pathlib import Path
from tempfile import SpooledTemporaryFile
from typing import NamedTuple, Optional
from typing import MutableSequence, NamedTuple, Optional

from rich import box
from rich.align import Align
from rich.console import Console, ConsoleOptions, Group, NewLine, RenderableType, group
from rich.padding import Padding
from rich.panel import Panel
from rich.rule import Rule
from rich.style import Style
from rich.table import Column, Table
Expand Down Expand Up @@ -84,7 +82,7 @@ def render(self) -> str:

with console.capture() as capture:
console.print(self)
return capture.get()
return capture.get().strip()

@classmethod
# A property would be nicer but it's not supported from Python 3.11 on:
Expand Down Expand Up @@ -164,6 +162,25 @@ def horizontal_fill(left: RenderableType, right: RenderableType) -> RenderableGe
yield NewLine()


def ensure_single_trailing_newline(sequence: MutableSequence[RenderableType]) -> None:
"""Ensure that `sequence` ends w/ exactly one `NewLine`, removing if necessary.
This has to be done in-place (yuck) because `rich.console.Group.renderables` is a
read-only property. It can be modified in-place, but not assigned to again.
"""
while True:
match sequence:
case [*_, NewLine(), NewLine()]:
sequence.pop()
case [*_, last] if not isinstance(last, NewLine):
sequence.append(NewLine())
case []:
sequence.append(NewLine())
case _:
break
return None


class Sequential(Template):
def section(self, title: str) -> RenderableGenerator:
yield NewLine()
Expand Down Expand Up @@ -439,12 +456,6 @@ def _(item: Project, theme: Theme) -> RenderableGenerator:
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderableGenerator:
panel = partial(
Panel,
box=box.SIMPLE,
padding=PaddingLevels(top=0, right=0, bottom=0, left=0),
)

if basics := self.model.basics:
yield from self.format(basics, self.theme)

Expand All @@ -464,6 +475,8 @@ def __rich_console__(
yield NewLine()
yield from self.format(location, self.theme)

yield NewLine()

if skills := self.model.skills:
yield from self.section("Skills")
table = Table.grid(
Expand All @@ -477,7 +490,8 @@ def __rich_console__(
keywords = ", ".join(skill.keywords) if skill.keywords else ""
level = skill.level or ""
table.add_row(name, level, keywords)
yield panel(table)
yield table
yield NewLine()

container: ResumeItemContainer
title: str
Expand All @@ -496,6 +510,7 @@ def __rich_console__(
if container:
group = Group(
*self.section(title),
self.format_and_group_all_elements(container),
*self.format_and_group_all_elements(container).renderables,
)
yield panel(group)
ensure_single_trailing_newline(group.renderables)
yield group
28 changes: 28 additions & 0 deletions tests/visualization/test_templates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest
from rich.console import NewLine, RenderableType

from ancv.visualization.templates import ensure_single_trailing_newline


@pytest.mark.parametrize(
["input_sequence", "expected_sequence"],
[
([], [NewLine()]),
([1], [1, NewLine()]),
([1, 2], [1, 2, NewLine()]),
([1, 2, NewLine()], [1, 2, NewLine()]),
([1, 2, NewLine(), NewLine()], [1, 2, NewLine()]),
([1, NewLine(), NewLine(), NewLine(), NewLine()], [1, NewLine()]),
([NewLine(), NewLine(), NewLine(), NewLine()], [NewLine()]),
],
)
def test_ensure_single_trailing_newline(
input_sequence: list[RenderableType], expected_sequence: list[RenderableType]
) -> None:
ensure_single_trailing_newline(input_sequence)

for result, expected in zip(input_sequence, expected_sequence, strict=True):
if isinstance(result, NewLine): # Cannot compare for equality
assert isinstance(expected, NewLine)
else:
assert result == expected

0 comments on commit 3e5b5c6

Please sign in to comment.