Textualize / rich

Rich is a Python library for rich text and beautiful formatting in the terminal.
https://rich.readthedocs.io/en/latest/
MIT License
48.1k stars 1.69k forks source link

Margins in text lines in Jupyter HTML template #3335

Open vladsavelyev opened 2 months ago

vladsavelyev commented 2 months ago

Hi!

We are using Rich for logging (from rich.logging import RichHandler), and I have a few questions about its text formatting in Jupyter notebooks. First, it seems to be adding a large spacing between lines.

import rich
import rich.progress
from rich.logging import RichHandler
import logging

log = logging.getLogger("rich")

console = rich.console.Console()
handler = RichHandler(
    console=console,
    show_time=False,
    show_level=False,
)
log.handlers = [handler]

log.info("|           multiqc | Loading data from /Users/vlad/git/MultiQC/multiqc_data/multiqc_data.json")
log.info("|           multiqc | Loaded module Salmon")
log.info("|           multiqc | Loaded plot salmon_plot")
log.info("|           multiqc | Loaded plot general_stats_table")

with rich.progress.Progress(console=console) as progress:
    task = progress.add_task("| searching", total=100)
    for i in range(100):
        progress.update(task, advance=1)
    progress.update(task)

log.info("|           multiqc | Loading data from /Users/vlad/git/MultiQC/multiqc_data/multiqc_data.json")
log.info("|           multiqc | Loaded module Salmon")
log.info("|           multiqc | Loaded plot salmon_plot")
log.info("|           multiqc | Loaded plot general_stats_table")

Notebook output:

CleanShot 2024-04-17 at 14 13 35@2x

With especially large spacing after the progress bar widget.

Compared that to a standard text output:

import logging
import sys
import tqdm

log = logging.getLogger("rich")
log.handlers = [logging.StreamHandler(sys.stdout)]
log.setLevel("INFO")

log.info("|           multiqc | Loading data from /Users/vlad/git/MultiQC/multiqc_data/multiqc_data.json")
log.info("|           multiqc | Loaded module Salmon")
log.info("|           multiqc | Loaded plot salmon_plot")
log.info("|           multiqc | Loaded plot general_stats_table")
with tqdm.tqdm(
    total=100,
    file=sys.stdout,
    bar_format=f"| {'searching':>17} | " + "{bar:50} {percentage:3.0f}% {n_fmt}/{total_fmt} {desc}",
) as pbar:
    for i in range(100):
        pbar.update(1)
    pbar.refresh()
log.info("|           multiqc | Loading data from /Users/vlad/git/MultiQC/multiqc_data/multiqc_data.json")
log.info("|           multiqc | Loaded module Salmon")
log.info("|           multiqc | Loaded plot salmon_plot")
log.info("|           multiqc | Loaded plot general_stats_table")

CleanShot 2024-04-17 at 14 12 00@2x

Looking at the HTML source code, Jupyter seems to be adding a margin-bottom to the child elements of .jp-RenderedHTMLCommon (in this case, each line is a single pre element inside the wrapper, so the .jp-RenderedHTMLCommon > *:last-child { margin-bottom: 0.5em } takes effect. I'm not sure if we have control over Jupyter CSS, but it seems like overriding the style of the pre element set in JUPYTER_HTML_FORMAT helps to remove the vertical spacing:

rich.jupyter.JUPYTER_HTML_FORMAT = """\
<pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace;margin-bottom:0px">{code}</pre>
"""

CleanShot 2024-04-17 at 14 11 30@2x

Let me know if that makes sense. Since users can override JUPYTER_HTML_FORMAT, there is no urgency in changing it in the code or making it explicitly user-configurable. But it probably would be nice to hardcode margin-bottom:0px there.

There is still an issue remaining with the widgets though. In my example, the searching line is not printed by the logging's RichHandler, but rather it's an instance of rich.progress.Progress. So in this case, the pre element is additionally wrapped in a .jupyter-widgets div that has { margin: var(--jp-widgets-margin) }, which adds an additional margin-left, making the progress bar unaligned with the log prints vertically. I wonder if you have ideas on how to fix that as well?

github-actions[bot] commented 2 months ago

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

vladsavelyev commented 2 months ago

Created a PR hardcoding the vertical margin: https://github.com/Textualize/rich/pull/3336