"""Provides operations related to the HTML table stored in `.metadata.text_as_html`. Used during partitioning as well as chunking. """ from __future__ import annotations import html from functools import cached_property from typing import TYPE_CHECKING, Iterator, Sequence, cast from lxml import etree from lxml.html import fragment_fromstring if TYPE_CHECKING: from lxml.html import HtmlElement def htmlify_matrix_of_cell_texts(matrix: Sequence[Sequence[str]]) -> str: """Form an HTML table from "rows" and "columns" of `matrix`. Character overhead is minimized: - No whitespace padding is added for human readability - No newlines ("\n") are added - No ``, `
`, or `` elements are used; we can't tell where those might be semantically appropriate anyway so at best they would consume unnecessary space and at worst would be misleading. """ def iter_trs(rows_of_cell_strs: Sequence[Sequence[str]]) -> Iterator[str]: for row_cell_strs in rows_of_cell_strs: # -- suppress emission of rows with no cells -- if not row_cell_strs: continue yield f"| ` elements to ` | ` so all cells have the same tag --
if e.tag == "th":
e.tag = "td"
# -- normalize whitespace in element text; this removes indent whitespace before nested
# -- elements and reduces whitespace between words to a single space.
if e.text:
e.text = " ".join(e.text.split())
# -- normalize tails. A tail is the text between an element's closing tag and the
# -- start of the next sibling. Pure-whitespace tails are pretty-printing noise and
# -- can be dropped, but tails can also carry real content (e.g. mixed inline
# -- markup like `foo bar baz` or text between ` ` tags), which # -- must be preserved. if e.tail: parts = e.tail.split() if not parts: e.tail = None else: prefix = " " if e.tail[0].isspace() else "" suffix = " " if e.tail[-1].isspace() else "" e.tail = prefix + " ".join(parts) + suffix return cls(table, header_row_idxs=header_row_idxs, source_row_htmls=source_row_htmls) @cached_property def html(self) -> str: """The HTML-fragment for this `
foo | bar | ` cells."""
return self._is_header
@property
def source_html(self) -> str | None:
"""Original source ` | ` element."""
def __init__(self, td: HtmlElement):
self._td = td
@cached_property
def html(self) -> str:
"""Like " | foo bar baz | "."""
return etree.tostring(self._td, encoding=str) if self.text else ""
@cached_property
def text(self) -> str:
"""Text inside ` | ` element, empty string when no text."""
return " ".join(self._td.text_content().split())
| |
|---|