Skip to content

Commit

Permalink
Fix rich rendering of panels
Browse files Browse the repository at this point in the history
We use a table with a single column, single header and/or single row that
contain the renderables.

The border color as well as the icon in title depends on the kind of
admonition (maybe we want to limit the kind of admonitions.

We cannot render only a header, so when the directive has no content, we
render only the body.
  • Loading branch information
Carreau committed Dec 24, 2023
1 parent b923122 commit d3936c9
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 42 deletions.
41 changes: 31 additions & 10 deletions papyri/rich_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,29 @@
Attempt to render using the rich protocol.
"""

from __future__ import annotations

from .myst_ast import MThematicBreak, MHeading
from dataclasses import dataclass
from rich.segment import Segment
from typing import Any, Optional
from rich.console import Console, ConsoleOptions, RenderResult, Group
from rich.panel import Panel, Box
from rich.panel import Panel
from rich.box import Box
from rich.padding import Padding
from rich import print
import rich
import json

from rich.table import Table

from typing import TYPE_CHECKING

from .myst_ast import MText

if TYPE_CHECKING:
from .myst_ast import MAdmonition, MAdmonitionTitle


def pad(arg):
return Padding(arg, (0, 0, 0, 2))
Expand Down Expand Up @@ -186,19 +198,28 @@ def visit_Directive(self, node):
def visit_MLink(self, node):
return self.generic_visit(node.children)

def visit_MAdmonitionTitle(self, node):
return [Panel(Unimp(str(node.to_dict())))]
def visit_MAdmonitionTitle(self, node: MAdmonitionTitle):
return self.generic_visit(node.children)

def visit_MAdmonition(self, node):
def visit_MAdmonition(self, node: MAdmonition):
COLOR = {"warning": "yellow", "deprecated": "red", "note": "blue"}
# TODO, there seem to be some error with the printing of wide characters
SYMBOL = {"warning": "⚠", "deprecated": "ⓧ ", "note": "ⓘ "}
SYMBOL = {"warning": "/!\\", "deprecated": "[x]", "note": "(i)"}
title, *other = node.children
assert title.type == "admonitionTitle"
acc = self.generic_visit([title])
table: Table
color = COLOR.get(node.kind, "purple")
symbol = SYMBOL.get(node.kind, "|?|")
if other:
rd = self.generic_visit(other)

acc.append(Panel(Group(*rd)))
return acc
table = Table(border_style=color)
table.add_column(
Group(*self.generic_visit([MText(symbol + ": ")] + [title]))
)
table.add_row(Group(*self.generic_visit(other)))
else:
table = Table(border_style=color, show_header=False)
table.add_row(Group(*self.generic_visit([MText(symbol + ": ")] + [title])))
return [table]

def visit_MHeading(self, node: MHeading):
cs = [RToken("#" * (node.depth + 1) + " ")] + self.generic_visit(node.children)
Expand Down
18 changes: 9 additions & 9 deletions papyri/tests/expected/numpy:einsum.expected
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ output : ndarray

## Notes

──────────────────────────────────────────────────────────────────────────────
{'type': 'admonitionTitle', 'children': [{'type': 'text', 'value': 'versiona
──────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────
(i): versionadded 1.6.0
──────────────────────────────────────────────────────────────────────────────
The Einstein summation convention can be used to compute many
multi-dimensional, linear algebraic array operations. `einsum` provides a
succinct way of representing these.
Expand Down Expand Up @@ -148,17 +148,17 @@ output shape is not provided in this format `einsum` will be calculated in
implicit mode, otherwise it will be performed explicitly. The examples below
have corresponding `einsum` calls with the two parameter methods.

──────────────────────────────────────────────────────────────────────────────
{'type': 'admonitionTitle', 'children': [{'type': 'text', 'value': 'versiona
──────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────
(i): versionadded 1.10.0
──────────────────────────────────────────────────────────────────────────────
Views returned from einsum are now writeable whenever the input array is
writeable. For example, np.einsum('ijk...->kji...', a) will now have the same
effect as np.swapaxes(a, 0, 2) <numpy.swapaxes> and np.einsum('ii->i', a) will
return a writeable view of the diagonal of a 2D array.

──────────────────────────────────────────────────────────────────────────────
{'type': 'admonitionTitle', 'children': [{'type': 'text', 'value': 'versiona
──────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────
(i): versionadded 1.12.0
──────────────────────────────────────────────────────────────────────────────
Added the optimize argument which will optimize the contraction order of an
einsum expression. For a contraction with three or more operands this can
greatly increase the computational efficiency at the cost of a larger memory
Expand Down
32 changes: 15 additions & 17 deletions papyri/tests/expected/numpy:linspace.expected
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,20 @@ Returns num evenly spaced samples, calculated over the interval [`start`, stop

The endpoint of the interval can optionally be excluded.

╭──────────────────────────────────────────────────────────────────────────────╮
│ {'type': 'admonitionTitle', 'children': [{'type': 'text', 'value': 'versionc │
╰──────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────╮
│ Non-scalar `start` and `stop` are now supported. │
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ (i): versionchanged 1.16.0 ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Non-scalar start and stop are now supported. │
│ │
╰──────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────╮
│ {'type': 'admonitionTitle', 'children': [{'type': 'text', 'value': 'versionc │
╰──────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────╮
└──────────────────────────────────────────────────────────────────────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ (i): versionchanged 1.20.0 ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Values are rounded towards -inf instead of 0 when an integer dtype is │
│ specified. The old behavior can still be obtained with np.linspace(start, │
│ stop, num).astype(int) │
│ │
──────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────
## Parameters

start : array_like
Expand All @@ -53,17 +51,17 @@ dtype : dtype, optional
inferred from start and stop. The inferred dtype will never be an integer;
`float` is chosen even if the arguments would produce an array of integers.

────────────────────────────────────────────────────────────────────────────
{'type': 'admonitionTitle', 'children': [{'type': 'text', 'value': 'versio
────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────
(i): versionadded 1.9.0
────────────────────────────────────────────────────────────────────────────
axis : int, optional
The axis in the result to store the samples. Relevant only if start or stop
are array-like. By default (0), the samples will be along a new axis
inserted at the beginning. Use -1 to get an axis at the end.

────────────────────────────────────────────────────────────────────────────
{'type': 'admonitionTitle', 'children': [{'type': 'text', 'value': 'versio
────────────────────────────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────
(i): versionadded 1.16.0
────────────────────────────────────────────────────────────────────────────
## Returns

samples : ndarray
Expand Down
9 changes: 4 additions & 5 deletions papyri/tests/expected/papyri.examples.expected
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,12 @@ Unordered list

## Admonitions

╭──────────────────────────────────────────────────────────────────────────────╮
│ {'type': 'admonitionTitle', 'children': [{'type': 'text', 'value': 'note '}] │
╰──────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────╮
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ (i): note ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ An admonition note ! │
│ │
──────────────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────────────
This is a link to `Jupyter website <jupyter.org>`

## Code (title 2)
Expand Down
3 changes: 2 additions & 1 deletion papyri/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,13 @@ def _admonition_handler_x(self, name, argument, options, content):
MAdmonition(
[MAdmonitionTitle([MText(f"{name} {argument}")])]
+ inner[0].children,
kind=name,
)
]
else:
return [
MAdmonition(
[MAdmonitionTitle([MText(f"{name} {argument}")])],
[MAdmonitionTitle([MText(f"{name} {argument}")])], kind=name
)
]

Expand Down

0 comments on commit d3936c9

Please sign in to comment.