From 65f1922ca5098444cc338c78653f538dfb4bf55c Mon Sep 17 00:00:00 2001 From: Egor Kraev Date: Thu, 2 Apr 2026 12:30:04 +0200 Subject: [PATCH] Add to_html method for TableData --- gslides_api/agnostic/element.py | 29 +++++++++++++- pyproject.toml | 2 +- tests/test_table_data_to_html.py | 69 ++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 tests/test_table_data_to_html.py diff --git a/gslides_api/agnostic/element.py b/gslides_api/agnostic/element.py index 163a93b..e0c7484 100644 --- a/gslides_api/agnostic/element.py +++ b/gslides_api/agnostic/element.py @@ -1,8 +1,9 @@ +import html import json import re from abc import ABC, abstractmethod from enum import Enum -from typing import Any, List, Literal +from typing import Any, List, Literal, Optional import marko from pydantic import BaseModel, Field, field_validator, model_validator @@ -53,6 +54,32 @@ def to_markdown(self) -> str: return "\n".join(lines) + def to_html(self, css_class: Optional[str] = None) -> str: + """Convert table data to an HTML element. + + Args: + css_class: Optional CSS class to apply to the
element. + + Returns: + HTML string with
, , and elements. + """ + if not self.headers: + return "" + + cls_attr = f' class="{html.escape(css_class)}"' if css_class else "" + parts = [f"", ""] + for header in self.headers: + parts.append(f"") + parts.append("") + for row in self.rows: + parts.append("") + for i in range(len(self.headers)): + cell = str(row[i]) if i < len(row) else "" + parts.append(f"") + parts.append("") + parts.append("
{html.escape(str(header))}
{html.escape(cell)}
") + return "".join(parts) + def to_dataframe(self): """Convert table data to pandas DataFrame. diff --git a/pyproject.toml b/pyproject.toml index 4d4b615..625cca7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "gslides-api" -version = "0.3.5" +version = "0.3.6" description = "A Python library for working with Google Slides API using Pydantic domain objects" authors = ["motley.ai "] license = "MIT" diff --git a/tests/test_table_data_to_html.py b/tests/test_table_data_to_html.py new file mode 100644 index 0000000..727dc10 --- /dev/null +++ b/tests/test_table_data_to_html.py @@ -0,0 +1,69 @@ +"""Tests for TableData.to_html() method.""" + +import pytest + +from gslides_api.agnostic.element import TableData + + +class TestTableDataToHtml: + def test_basic_table(self): + td = TableData(headers=["Name", "Value"], rows=[["Alice", "100"], ["Bob", "200"]]) + result = td.to_html() + assert "" in result + assert "" in result + assert "" in result + assert "" in result + assert "" in result + assert "" in result + assert "" in result + assert "" in result + assert "" in result + + def test_with_css_class(self): + td = TableData(headers=["A"], rows=[["1"]]) + result = td.to_html(css_class="dtbl") + assert '
NameValueAlice100Bob200
' in result + + def test_without_css_class(self): + td = TableData(headers=["A"], rows=[["1"]]) + result = td.to_html() + assert "
" in result + assert "class=" not in result + + def test_empty_headers(self): + td = TableData(headers=[], rows=[]) + assert td.to_html() == "" + + def test_html_escaping(self): + td = TableData( + headers=["