Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
AAriam committed Sep 10, 2024
1 parent 4389188 commit c12b58b
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 23 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespaces = true

# ----------------------------------------- Project Metadata -------------------------------------
[project]
version = "0.0.0.dev5"
version = "0.0.0.dev6"
name = "ANSI-SGR"
requires-python = ">=3.10"
dependencies = [
Expand Down
180 changes: 158 additions & 22 deletions src/ansi_sgr/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,134 @@
from pyprotocol import Stringable


def code_block(
code: Stringable,
title: Stringable = "Code",
emoji: Stringable | None = "💻",
line_num: bool = True,
line_num_start: int = 1,
emphasize_lines: list[int] | None = None,
title_styles: int | str | list[int | str] = "bold",
title_color: int | str | tuple = (255, 255, 255),
title_bg_color: int | str | tuple = (70, 0, 0),
title_margin_top: int | None = None,
title_margin_bottom: int | None = None,
title_align: Literal["left", "right", "center"] = "left",
code_margin_top: int | None = 1,
code_margin_bottom: int | None = 1,
line_num_styles: int | str | list[int | str] = "bold",
line_num_color: int | str | tuple = (255, 255, 255),
line_num_bg_color: int | str | tuple = (30, 30, 30),
line_styles: int | str | list[int | str] = None,
line_color: int | str | tuple = (255, 255, 255),
line_bg_color: int | str | tuple = (100, 0, 0),
margin_left: int | None = 1,
margin_right: int | None = 1,
char_top: Stringable | None = "",
char_bottom: Stringable | None = "━",
char_left: Stringable | None = "┃",
char_right: Stringable | None = "┃",
char_top_left: Stringable | None = "┏",
char_top_right: Stringable | None = "┓",
char_bottom_left: Stringable | None = "┗",
char_bottom_right: Stringable | None = "┛",
line_width: int = 70,
):
title = str(title)
if emoji:
title = f"{emoji}{title}"
title_section = block(
text=title,
text_styles=title_styles,
text_color=title_color,
bg_color=title_bg_color,
char_top=char_top,
char_bottom="",
char_left=char_left,
char_right=char_right,
char_top_left=char_top_left,
char_top_right=char_top_right,
margin_top=title_margin_top,
margin_bottom=title_margin_bottom,
margin_left=margin_left,
margin_right=margin_right,
line_width=line_width,
align=title_align,
)
code = str(code)
line_count = len(code.splitlines())
number_width = len(str(line_num_start + line_count - 1))
if margin_left is None:
margin_left = margin_right
if margin_right is None:
margin_right = margin_left
if margin_left is None:
margin_left = margin_right
if margin_right is None:
margin_right = margin_left
line_width_adjusted = line_width - (margin_left or 0) - (margin_right or 0) - _wcwidth.wcswidth(
str(char_left)) - _wcwidth.wcswidth(str(char_right))
lines = _textwrap.fill(
text=code,
width=line_width_adjusted - ((number_width + 2) if line_num else 0),
expand_tabs=True,
tabsize=4,
replace_whitespace=False,
drop_whitespace=False,
).splitlines()
code_start_idx = 0
if char_left is None:
char_left = char_right or ""
if char_right is None:
char_right = char_left or ""
if code_margin_top is None:
code_margin_top = code_margin_bottom
if code_margin_bottom is None:
code_margin_bottom = code_margin_top
formatted_lines = []
for line_idx, line in enumerate(lines):
screen_width = _wcwidth.wcswidth(line)
char_width = len(line)
extra_padding = char_width - screen_width
width = line_width_adjusted + extra_padding - (number_width + 2 if line_num else 0)
line = line.ljust(width)
if emphasize_lines and line_idx - code_start_idx + 1 in emphasize_lines:
sequence = _sgr.create_sequence(line_styles, line_color, line_bg_color)
line = _sgr.apply_sequence(line, sequence, reset=True)
if line_num:
sequence = _sgr.create_sequence(line_num_styles, line_num_color, line_num_bg_color)
line_num_sgr = _sgr.apply_sequence(f"{line_num_start + line_idx:>{number_width}}", sequence, reset=True)
line = f"{line_num_sgr} {line}"
if margin_left:
line = " " * margin_left + line
if margin_right:
line = line + " " * margin_right
formatted_lines.append(f"{char_left}{line}{char_right}")
margin_line_content = " " * (line_width_adjusted + (margin_left or 0) + (margin_right or 0))
if code_margin_top:
formatted_lines = [f"{char_left}{margin_line_content}{char_right}"] * code_margin_top + formatted_lines
code_start_idx = code_margin_top
if code_margin_bottom:
formatted_lines = formatted_lines + [f"{char_left}{margin_line_content}{char_right}"] * code_margin_bottom
if char_top is None:
char_top = char_bottom or ""
if char_bottom is None:
char_bottom = char_top or ""
if char_top:
total_line_width = line_width - _wcwidth.wcswidth(
str(char_top_left)) - _wcwidth.wcswidth(str(char_top_right))
line_top = f"{char_top_left}{char_top * total_line_width}{char_top_right}"
formatted_lines.insert(0, line_top)
if char_bottom:
total_line_width = line_width - _wcwidth.wcswidth(
str(char_bottom_left)) - _wcwidth.wcswidth(str(char_bottom_right))
line_bottom = f"{char_bottom_left}{char_bottom * total_line_width}{char_bottom_right}"
formatted_lines.append(line_bottom)
body_section = "\n".join(formatted_lines)
return f"{title_section}\n{body_section}"



def admonition(
title: Stringable,
text: Stringable,
Expand All @@ -20,18 +148,16 @@ def admonition(
title_bg_color: int | str | tuple = (70, 0, 0),
title_margin_top: int | None = None,
title_margin_bottom: int | None = None,
title_margin_left: int | None = None,
title_margin_right: int | None = None,
title_align: Literal["left", "right", "center"] = "left",
text_styles: int | str | list[int | str] = None,
text_color: int | str | tuple = None,
text_bg_color: int | str | tuple = None,
text_margin_top: int | None = None,
text_margin_bottom: int | None = None,
text_margin_left: int | None = None,
text_margin_right: int | None = None,
text_margin_top: int | None = 1,
text_margin_bottom: int | None = 1,
text_align: Literal["left", "right", "center"] = "left",
char_top: Stringable | None = None,
margin_left: int | None = 1,
margin_right: int | None = 1,
char_top: Stringable | None = "",
char_bottom: Stringable | None = "━",
char_left: Stringable | None = "┃",
char_right: Stringable | None = "┃",
Expand All @@ -57,8 +183,8 @@ def admonition(
char_top_right=char_top_right,
margin_top=title_margin_top,
margin_bottom=title_margin_bottom,
margin_left=title_margin_left or text_margin_left,
margin_right=title_margin_right or text_margin_right,
margin_left=margin_left,
margin_right=margin_right,
line_width=line_width,
align=title_align,
)
Expand All @@ -75,8 +201,8 @@ def admonition(
char_bottom_right=char_bottom_right,
margin_top=text_margin_top,
margin_bottom=text_margin_bottom,
margin_left=text_margin_left or title_margin_left,
margin_right=text_margin_right or title_margin_right,
margin_left=margin_left,
margin_right=margin_right,
line_width=line_width,
align=text_align,
)
Expand All @@ -103,32 +229,38 @@ def block(
line_width: int = 50,
align: Literal["left", "right", "center"] = "left",
):
lines = _textwrap.wrap(
if margin_left is None:
margin_left = margin_right
if margin_right is None:
margin_right = margin_left
if char_left is None:
char_left = char_right or ""
if char_right is None:
char_right = char_left or ""
line_width_adjusted = line_width - (margin_left or 0) - (margin_right or 0) - _wcwidth.wcswidth(str(char_left)) - _wcwidth.wcswidth(str(char_right))
lines = _textwrap.fill(
text=str(text),
width=line_width,
width=line_width_adjusted,
expand_tabs=True,
tabsize=4,
replace_whitespace=False,
drop_whitespace=False,
)
if margin_left is None:
margin_left = margin_right
if margin_right is None:
margin_right = margin_left
).splitlines()

if margin_top is None:
margin_top = margin_bottom
if margin_bottom is None:
margin_bottom = margin_top
if margin_top:
lines = [" " * line_width] * margin_top + lines
lines = [" " * line_width_adjusted] * margin_top + lines
if margin_bottom:
lines = lines + [" " * line_width] * margin_bottom
lines = lines + [" " * line_width_adjusted] * margin_bottom
formatted_lines = []
for line in lines:
screen_width = _wcwidth.wcswidth(line)
char_width = len(line)
extra_padding = char_width - screen_width
width = line_width + extra_padding
width = line_width_adjusted + extra_padding
if align == "left":
line = line.ljust(width)
elif align == "right":
Expand All @@ -151,11 +283,15 @@ def block(
char_top = char_bottom or ""
if char_bottom is None:
char_bottom = char_top or ""
total_line_width = line_width + (margin_left or 0) + (margin_right or 0)

if char_top:
total_line_width = line_width - _wcwidth.wcswidth(
str(char_top_left)) - _wcwidth.wcswidth(str(char_top_right))
line_top = f"{char_top_left}{char_top * total_line_width}{char_top_right}"
formatted_lines.insert(0, line_top)
if char_bottom:
total_line_width = line_width - _wcwidth.wcswidth(
str(char_bottom_left)) - _wcwidth.wcswidth(str(char_bottom_right))
line_bottom = f"{char_bottom_left}{char_bottom * total_line_width}{char_bottom_right}"
formatted_lines.append(line_bottom)
return "\n".join(formatted_lines)
Expand Down

0 comments on commit c12b58b

Please sign in to comment.