diff --git a/anton/core/artifacts/report_tools.py b/anton/core/artifacts/report_tools.py index e84651b5a..a882a9a12 100644 --- a/anton/core/artifacts/report_tools.py +++ b/anton/core/artifacts/report_tools.py @@ -14,6 +14,11 @@ They are imported from the installed package rather than copied into artifact folders, so a report made with one release opens and edits with the next. + +Block-level markup (sections, paragraphs, list items, table rows, chart bars) +ends with a line break, so line-based tools can read and diff a page part by +part. Line breaks go only between elements where the browser does not show +whitespace, never inside text. """ from __future__ import annotations @@ -86,36 +91,39 @@ def _slug(text: str) -> str: if(empty){empty.hidden=shown>0;}} sel.addEventListener('change',apply);apply();});})(); """ -_FILTER_SCRIPT = f"" +_FILTER_SCRIPT = f"\n" def page(title: str, *parts, lang: str = "en", theme: str = "light", subtitle: str | None = None) -> Html: """A complete document: lang, charset, viewport, inline CSS, light or dark theme.""" if theme not in ("light", "dark"): raise ValueError('theme must be "light" or "dark"') + # Parts are joined without separators: a line break between two inline + # parts (text and a link) would show as a space. Block parts end with one. body = "".join(_esc(p) for p in parts) script = _FILTER_SCRIPT if "data-rt-filter" in body else "" - sub = f'
{_esc(subtitle)}
' if subtitle else "" + sub = f'{_esc(subtitle)}
\n' if subtitle else "" return Html( - f'' - f'{_esc(t)}
" for t in texts)) + return Html("".join(f"{_esc(t)}
\n" for t in texts)) def bullets(items) -> Html: - return Html("{_esc(tl)}: {_esc(round(total, 6))}
' + total_html = f'{_esc(tl)}: {_esc(round(total, 6))}
\n' + # The label and the select are inline: a line break between them would show as a space. return Html( f'{_esc(empty_text)}
' - f'{_esc(empty_text)}
\n' + + _table_html(columns, numeric, trs) + "