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

Add val_fmt_image() to enable image rendering in various components #451

Merged
merged 4 commits into from
Sep 30, 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
65 changes: 65 additions & 0 deletions great_tables/_formats_vals.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Any
from pathlib import Path

from great_tables import GT
from great_tables.gt import GT, _get_column_of_values
Expand Down Expand Up @@ -931,3 +932,67 @@ def val_fmt_markdown(
vals_fmt = _get_column_of_values(gt=gt_obj_fmt, column_name="x", context="html")

return vals_fmt


def val_fmt_image(
x: X,
height: str | int | None = None,
width: str | int | None = None,
sep: str = " ",
path: str | Path | None = None,
file_pattern: str = "{}",
encode: bool = True,
) -> list[str]:
"""Format image paths to generate images in cells.

To more easily insert graphics into body cells, we can use the `fmt_image()` method. This allows
for one or more images to be placed in the targeted cells. The cells need to contain some
reference to an image file, either: (1) complete http/https or local paths to the files; (2) the
file names, where a common path can be provided via `path=`; or (3) a fragment of the file name,
where the `file_pattern=` argument helps to compose the entire file name and `path=` provides
the path information. This should be expressly used on columns that contain *only* references to
image files (i.e., no image references as part of a larger block of text). Multiple images can
be included per cell by separating image references by commas. The `sep=` argument allows for a
common separator to be applied between images.

Parameters
----------
x
A list of values to be formatted.
height
The height of the rendered images.
width
The width of the rendered images.
sep
In the output of images within a body cell, `sep=` provides the separator between each
image.
path
An optional path to local image files (this is combined with all filenames).
file_pattern
The pattern to use for mapping input values in the body cells to the names of the graphics
files. The string supplied should use `"{}"` in the pattern to map filename fragments to
input strings.
encode
The option to always use Base64 encoding for image paths that are determined to be local. By
default, this is `True`.

Returns
-------
list[str]
A list of formatted values is returned.
"""
gt_obj: GTData = _make_one_col_table(vals=x)

gt_obj_fmt = gt_obj.fmt_image(
columns="x",
height=height,
width=width,
sep=sep,
path=path,
file_pattern=file_pattern,
encode=encode,
)

vals_fmt = _get_column_of_values(gt=gt_obj_fmt, column_name="x", context="html")

return vals_fmt
1 change: 1 addition & 0 deletions great_tables/vals.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
val_fmt_date as fmt_date,
val_fmt_time as fmt_time,
val_fmt_markdown as fmt_markdown,
val_fmt_image as fmt_image,
)
31 changes: 31 additions & 0 deletions tests/test_formats_vals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import base64
from pathlib import Path
from importlib_resources import files

import pytest
from great_tables import vals


@pytest.fixture
def img_paths():
return files("great_tables") / "data/metro_images"


def test_locate_val_fmt_image(img_paths: Path):
imgs = vals.fmt_image("1", path=img_paths, file_pattern="metro_{}.svg")
with open(img_paths / "metro_1.svg", "rb") as f:
encoded = base64.b64encode(f.read()).decode()

assert encoded in imgs[0]


def test_val_fmt_image_single(img_paths: Path):
imgs = vals.fmt_image("1", path=img_paths, file_pattern="metro_{}.svg")
assert 'img src="data:image/svg+xml;base64' in imgs[0]


def test_val_fmt_image_multiple(img_paths: Path):
img1, img2 = vals.fmt_image(["1", "2"], path=img_paths, file_pattern="metro_{}.svg")

assert 'img src="data:image/svg+xml;base64' in img1
assert 'img src="data:image/svg+xml;base64' in img2