Skip to content

Commit

Permalink
Add the inline_css= option to as_raw_html()
Browse files Browse the repository at this point in the history
  • Loading branch information
rich-iannone committed Dec 10, 2024
1 parent c2acdbe commit c3a8aaa
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 15 deletions.
99 changes: 90 additions & 9 deletions great_tables/_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
from pathlib import Path
from typing import TYPE_CHECKING, Literal

from css_inline import inline, inline_fragment
from typing_extensions import TypeAlias

from ._helpers import random_id
from ._utils import _try_import
from ._utils_render_latex import _render_as_latex

Expand Down Expand Up @@ -111,7 +113,7 @@ def show(
html, raw=True, metadata={"text/html": {"isolated": True}}
)
elif target == "browser":
html = self.as_raw_html(make_page=True)
html = self.as_raw_html(inline_css=False, make_page=True)

Check warning on line 116 in great_tables/_export.py

View check run for this annotation

Codecov / codecov/patch

great_tables/_export.py#L116

Added line #L116 was not covered by tests
with tempfile.TemporaryDirectory() as tmp_dir:
f_path = Path(tmp_dir) / "index.html"
f_path.write_text(html, encoding="utf-8")
Expand All @@ -126,19 +128,29 @@ def show(

def as_raw_html(
self: GT,
inline_css: bool = True,
make_page: bool = False,
all_important: bool = False,
) -> str:
"""
Get the HTML content of a GT object.
Get the HTML content from a GT object as a string. This function is useful for obtaining the
HTML content of a GT object for use in other contexts.
Get the HTML content from a GT object as a string. By default, the generated HTML will have
inlined styles, where CSS styles (that were previously contained in CSS rule sets external to
the `<table>` element are included as style attributes in the HTML table's tags. This option is
preferable when using the output HTML table in an emailing context.
Parameters
----------
gt
A GT object.
inline_css
An option to supply styles to table elements as inlined CSS styles. This is useful when
including the table HTML as part of an HTML email message body, since inlined styles are
largely supported in email clients over using CSS in a `<style>` block.
make_page
An option to wrap the table in a complete HTML page. This is useful when you want to display
the table in a web browser.
Returns
-------
Expand All @@ -147,24 +159,93 @@ def as_raw_html(
Examples:
------
Let's use the `row` column of `exibble` dataset to create a table. With the `as_raw_html()`
method, we're able to output the HTML content.
Let's use a subset of the `gtcars` dataset to create a new table.
```{python}
from great_tables import GT, exibble
from great_tables import GT, md, style, loc
from great_tables.data import gtcars
import polars as pl
gtcars_mini = (
pl.from_pandas(gtcars)
.select(["mfr", "model", "msrp"])
.head(5)
)
gt_tbl = (
GT(gtcars_mini)
.tab_header(
title=md("Data listing from **gtcars**"),
subtitle=md("gtcars is an R dataset")
)
.tab_style(
style=style.fill(color="LightCyan"),
locations=loc.body(columns="mfr")
)
.fmt_currency(columns="msrp")
.tab_options(
heading_background_color="Azure",
table_body_hlines_color="Lavender",
table_body_hlines_width="2px"
)
.opt_horizontal_padding(scale=2)
)
GT(exibble[["row"]]).as_raw_html()
gt_tbl
```
Now we can return the table as an HTML string with inlined CSS styles using the `as_raw_html()`
method.
```{python}
gt_tbl.as_raw_html()
```
The HTML string contains the HTML for the table. It has only the `<table>...</table>` part so
it's not a complete HTML document but rather an HTML fragment. While this useful for embedding
a table in an existing HTML document, you could also use the `make_page=True` argument to get a
complete HTML page with the table embedded in it. And if that's the case you might also want to
suppress the inlining of CSS styles by setting `inline_css=False`.
```{python}
gt_tbl.as_raw_html(inline_css=False, make_page=True)
```
"""
built_table = self._build_data(context="html")

html_table = built_table._render_as_html(
if not inline_css:
html_table = built_table._render_as_html(
make_page=make_page,
all_important=all_important,
)

return html_table

table_html = built_table._render_as_html(
make_page=make_page,
all_important=all_important,
)

return html_table
if make_page:
inlined = inline(html=table_html)

Check warning on line 230 in great_tables/_export.py

View check run for this annotation

Codecov / codecov/patch

great_tables/_export.py#L230

Added line #L230 was not covered by tests

else:
# Obtain the `table_id` value from the Options (might be set, might be None)
table_id = self._options.table_id.value

if table_id is None:
id = random_id()

Check warning on line 237 in great_tables/_export.py

View check run for this annotation

Codecov / codecov/patch

great_tables/_export.py#L237

Added line #L237 was not covered by tests
else:
id = table_id

# Compile the SCSS as CSS
from ._scss import compile_scss

table_css = str(compile_scss(self, id=id, compress=False, all_important=all_important))

inlined = inline_fragment(html=table_html, css=table_css)

return inlined


def as_latex(self: GT, use_longtable: bool = False, tbl_pos: str | None = None) -> str:
Expand Down
1 change: 1 addition & 0 deletions great_tables/gt.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ def _repr_html_(self):
all_important = defaults["all_important"]

rendered = self.as_raw_html(
inline_css=False,
make_page=make_page,
all_important=all_important,
)
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ classifiers = [
]
dependencies = [
"commonmark>=0.9.1",
"css-inline>=0.14.1",
"faicons>=0.2.2",
"htmltools>=0.4.1",
"importlib-metadata",
Expand Down
2 changes: 1 addition & 1 deletion tests/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def gt_tbl():


def test_html_string_generated(gt_tbl: GT, snapshot: str):
assert snapshot == gt_tbl.as_raw_html()
assert snapshot == gt_tbl.as_raw_html(inline_css=False)


@pytest.mark.skipif(sys.platform == "win32", reason="chrome might not be installed.")
Expand Down
2 changes: 1 addition & 1 deletion tests/test_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ def test_opt_table_font_use_stack_and_system_font():
def test_opt_table_font_google_font():
gt_tbl = GT(exibble).opt_table_font(font=google_font(name="IBM Plex Mono"))

rendered_html = gt_tbl.as_raw_html()
rendered_html = gt_tbl.as_raw_html(inline_css=False)

assert rendered_html.find(
"@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');"
Expand Down
6 changes: 3 additions & 3 deletions tests/test_tab_create_modify.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_tab_style_google_font(gt: GT):
locations=loc.body(columns="x"),
)

rendered_html = new_gt.as_raw_html()
rendered_html = new_gt.as_raw_html(inline_css=False)

assert rendered_html.find(
"@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');"
Expand All @@ -55,7 +55,7 @@ def test_tab_style_font_local(gt: GT):
locations=loc.body(columns="x"),
)

rendered_html = new_gt.as_raw_html()
rendered_html = new_gt.as_raw_html(inline_css=False)

assert rendered_html.find('<td style="font-family: Courier;" class="gt_row gt_right">1</td>')

Expand All @@ -67,7 +67,7 @@ def test_tab_style_font_from_column():
style=style.text(font=from_column(column="font")), locations=loc.body(columns="x")
)

rendered_html = gt_tbl.as_raw_html()
rendered_html = gt_tbl.as_raw_html(inline_css=False)

assert rendered_html.find('<td style="font-family: Helvetica;" class="gt_row gt_right">1</td>')
assert rendered_html.find('<td style="font-family: Courier;" class="gt_row gt_right">2</td>')
2 changes: 1 addition & 1 deletion tests/test_utils_render_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,6 @@ def test_loc_kitchen_sink(snapshot):
.tab_style(style.css("STUBHEAD"), loc.stubhead())
)

html = new_gt.as_raw_html()
html = new_gt.as_raw_html(inline_css=False)
cleaned = html[html.index("<table") :]
assert cleaned == snapshot

0 comments on commit c3a8aaa

Please sign in to comment.