Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat(plugins): add FIGlet plugin #12

Merged
merged 20 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions doteki/plugins/figlet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import logging
import pyfiglet # type: ignore
from typing import Any


def run(settings: dict[str, Any]) -> str | None:
if not validate_settings(settings):
return None

text = str(settings.get("ascii_text"))
font = settings.get("font", "standard")

try:
result = pyfiglet.figlet_format(text, font)
except pyfiglet.FontNotFound:
logging.error("Invalid font for the FIGlet plugin")
return None

result_lines = result.splitlines()
trimmed_result_lines = trim_leading_and_trailing_empty_lines(result_lines)
result = "\n".join(trimmed_result_lines)

pre_text = "```text\n"
post_text = "\n```"
result = pre_text + result.rstrip() + post_text
return str(result)


def validate_settings(settings: dict[str, Any]) -> bool:
if "ascii_text" not in settings:
logging.error("No text provided for the FIGlet plugin")
return False

return True


def trim_leading_and_trailing_empty_lines(lines: list[str]) -> list[str]:
# Leading lines.
while lines and lines[0].strip() == "":
lines.pop(0)

# Trailing lines.
while lines and lines[-1].strip() == "":
lines.pop()

return lines
16 changes: 14 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,19 @@ python = "^3.11"
# Optional dependencies for plugins.
feedparser = { version = "^6.0", optional = true }
requests = { version = "^2.28", optional = true }
pyfiglet = { version = "^1.0.2", optional = true}


[tool.poetry.extras]
# Plugin dependencies.
all = [ # This enables `pip install doteki[all]`. Should contain all dependencies below.
"requests",
"feedparser",
"pyfiglet",
]
lastfm = ["requests"]
feed = ["requests", "feedparser"]
figlet = ["pyfiglet"]

[build-system]
requires = ["poetry-core"]
Expand Down
60 changes: 60 additions & 0 deletions tests/plugins/test_figlet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import logging
import pytest
from doteki.plugins.figlet import run, trim_leading_and_trailing_empty_lines


def test_default_font():
settings = {"ascii_text": "hola"}
expected = r""" _ _
| |__ ___ | | __ _
| '_ \ / _ \| |/ _` |
| | | | (_) | | (_| |
|_| |_|\___/|_|\__,_|"""
result = run(settings)
assert expected in str(result)


def test_empty_text(caplog):
settings = {"font": "standard"}
with caplog.at_level(logging.ERROR):
result = run(settings)
assert result is None
assert "No text provided for the FIGlet plugin" in caplog.text


def test_invalid_font_returns_none(caplog):
settings = {"ascii_text": "hola", "font": "invalid_font"}
with caplog.at_level(logging.ERROR):
result = run(settings)
assert result is None
assert "Invalid font for the FIGlet plugin" in caplog.text


def test_int_text():
settings = {"ascii_text": 42, "font": "standard"}
expected = r""" _ _ ____
| || ||___ \
| || |_ __) |
|__ _/ __/
|_||_____|"""
result = run(settings)
assert expected in str(result)


@pytest.mark.parametrize(
"lines, expected",
[
# Removes leading and trailing empty lines.
(["", " ", "Hello", "World", "", " "], ["Hello", "World"]),
# Do not remove empty lines in the middle.
(["Hello", "", " ", "World"], ["Hello", "", " ", "World"]),
# Leave non-empty lines as is.
(["Hello", "World"], ["Hello", "World"]),
# If there are only empty lines, return an empty list.
(["", " ", " "], []),
# If no lines are provided, return an empty list.
([], []),
],
)
def test_trim_leading_and_trailing_empty_lines(lines, expected):
assert trim_leading_and_trailing_empty_lines(lines) == expected
43 changes: 43 additions & 0 deletions website/docs/plugins/figlet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# FIGlet Plugin

Display text with customizable ASCII art using FIGlet fonts.

## Configuration

The FIGlet plugin can be configured with the following parameters:

- `text`: Text to be rendered in ASCII font.
- `font`: FIGlet font to use. Defaults to `standard`.

## Usage

Here's an example configuration:

```toml title="doteki.toml"
[sections.ascii_art]
plugin = "figlet"
ascii_text = "hello"
font = "isometric1"
```

This will render the following:

```text
___ ___ ___ ___ ___
/\__\ /\ \ /\__\ /\__\ /\ \
/:/ / /::\ \ /:/ / /:/ / /::\ \
/:/__/ /:/\:\ \ /:/ / /:/ / /:/\:\ \
/::\ \ ___ /::\~\:\ \ /:/ / /:/ / /:/ \:\ \
/:/\:\ /\__\ /:/\:\ \:\__\ /:/__/ /:/__/ /:/__/ \:\__\
\/__\:\/:/ / \:\~\:\ \/__/ \:\ \ \:\ \ \:\ \ /:/ /
\::/ / \:\ \:\__\ \:\ \ \:\ \ \:\ /:/ /
/:/ / \:\ \/__/ \:\ \ \:\ \ \:\/:/ /
/:/ / \:\__\ \:\__\ \:\__\ \::/ /
\/__/ \/__/ \/__/ \/__/ \/__/
```

## Frequently Asked Questions

### Where can I find a list of available fonts?

Check the [FIGlet official site](http://www.figlet.org/examples.html) to explore the available fonts.