Markdown
markdown renders a Markdown document as a Div of elements,
which goes anywhere an element does.
It handles GitHub Flavored Markdown,
and YAML front matter at the top of a document.
Peaks
The fourteen peaks above 8000 m are all in Asia; see the
list.
│ Because it's there.
• Himalayas
◦ Everest
◦ Kangchenjunga
• Karakoram
◦ K2
┌─────────┬────────────┐
│ Peak │ Height (m) │
├─────────┼────────────┤
│ Everest │ 8849 │
├─────────┼────────────┤
│ K2 │ 8611 │
└─────────┴────────────┘
tallest = max(peaks, key=lambda p: p.height)
- Links, bare URLs, and images are hyperlinks to their destinations. An image is shown as its alt text, since a terminal can't show the image.
- Fenced code blocks are highlighted as the language their info string names, or shown as written if it names none, or one Pygments doesn't know.
- Math, between
$s within a line or$$s on lines of their own, is shown as written, since a terminal can't typeset it. A dollar sign starts math only by Pandoc's rule, with no space just inside it and no digit right after the closing one, so$5 and $10stays text. - Raw HTML is shown as written.
GitHub's extensions to CommonMark draw like this:
- Front matter is shown dimmed and highlighted as YAML.
Pass
MarkdownStyles(front_matter=display_none)to hide it. - A task list item's box takes the place of its bullet, or follows its number.
- An alert is a block quote with a title, colored by its kind.
- Footnotes are numbered in the order they're referenced, and their definitions follow the rest of the document.
Rendering is cached by the source and the styles, so a component can render the same document on every render without parsing it again.
Scrolling
A document is as tall as its content, so one longer than the space it's given runs past the bottom of it.
Put it in a scroll container, as a browser puts a page in a scrolling viewport,
with scroll_on_keys and scroll_on_wheel to scroll it:
╭──────────────────────────────────────────────────────────╮
│ ◦ Everest │
│ ◦ Kangchenjunga │
│ • Karakoram │
│ ◦ K2 │
│ │
│ ┌─────────┬────────────┐ │
│ │ Peak │ Height (m) │ │
│ ├─────────┼────────────┤ │
│ │ Everest │ 8849 │ │
│ ├─────────┼────────────┤ │
╰──────────────────────────────────────────────────────────╯
The Markdown viewer example puts a tree of a directory's Markdown files beside the one it's showing, each in a pane that scrolls, and the Markdown gallery example shows the source of each kind of block and span beside how it renders.
Styles
MarkdownStyles holds a Style for each kind of block and a CellStyle for each kind of inline span.
Pass the fields you want to change, and the rest keep their defaults:
markdown(source, MarkdownStyles(heading_1=text_color("amber", 300), code_theme="monokai", block_gap=0))
API
counterweight.markdown.markdown
cached
markdown(
source: str, styles: MarkdownStyles = MarkdownStyles()
) -> Div
source, a Markdown document, as a Div of its blocks, drawn with styles.
Links, bare URLs, and images are hyperlinks to their destinations. Fenced code blocks are highlighted as the language their info string names, or shown as written if it names none or one Pygments doesn't know. Math and raw HTML are shown as written, too.
counterweight.markdown.MarkdownStyles
dataclass
MarkdownStyles(
*,
document: Style = Style(),
block_gap: int = 1,
paragraph: Style = text_wrap_stable,
heading_1: Style = text_wrap_stable
| Style(text_style=BOLD)
| text_color("sky", 300),
heading_2: Style = text_wrap_stable
| Style(text_style=BOLD)
| text_color("sky", 400),
heading_3: Style = text_wrap_stable
| Style(text_style=BOLD)
| text_color("sky", 500),
heading_4: Style = text_wrap_stable
| Style(text_style=BOLD),
heading_5: Style = text_wrap_stable
| Style(text_style=BOLD),
heading_6: Style = text_wrap_stable
| Style(text_style=BOLD | CellStyle(dim=True)),
block_quote: Style = border_light
| border_left
| border_color("slate", 500)
| pad_left(1),
block_quote_text: CellStyle = CellStyle(italic=True)
| text_style,
list_marker: Style = text_color("slate", 400),
bullets: tuple[str, ...] = ("•", "◦", "▪"),
unchecked_task: str = "☐",
checked_task: str = "☑",
checked_task_marker: Style = text_color("emerald", 400),
alert: Style = border_light | border_left | pad_left(1),
alert_title: Style = text_wrap_stable
| Style(text_style=BOLD),
alert_note: Style = border_color("blue", 400)
| text_color("blue", 400),
alert_tip: Style = border_color("green", 400)
| text_color("green", 400),
alert_important: Style = border_color("violet", 400)
| text_color("violet", 400),
alert_warning: Style = border_color("amber", 400)
| text_color("amber", 400),
alert_caution: Style = border_color("red", 400)
| text_color("red", 400),
code_block: Style = pad_x(1),
code_theme: CodeTheme = DEFAULT_CODE_THEME,
front_matter: Style = Style(
text_style=CellStyle(dim=True)
),
thematic_break: Style = border_light
| border_top
| border_color("slate", 600),
math_block: Style = text_wrap_stable
| text_justify_center
| text_color("violet", 300),
math_label: Style = text_color("slate", 400),
html_block: Style = Style(
text_style=CellStyle(dim=True)
),
table: Style = align_self_start,
table_cell: Style = border_light
| border
| border_color("slate", 600),
table_cell_text: Style = pad_x(1) | text_wrap_stable,
table_header: Style = Style(text_style=BOLD),
emphasis: CellStyle = CellStyle(italic=True),
strong: CellStyle = BOLD,
strikethrough: CellStyle = CellStyle(
strikethrough=True
),
code_inline: CellStyle = text_style | text_style,
math_inline: CellStyle = text_style,
link: CellStyle = CellStyle(underline=True)
| text_style,
image: CellStyle = CellStyle(italic=True) | text_style,
footnote_ref: CellStyle = text_style,
footnotes: Style = border_light
| border_top
| border_color("slate", 600)
)
How markdown draws each kind of Markdown block and inline span.
Each block becomes an element styled by its Style here, merged over the layout markdown gives it.
Each inline span's CellStyle is merged over the text around it, so ***both*** is bold and italic.
Pass the fields you want to change: MarkdownStyles(paragraph=text_wrap_pretty).
document
class-attribute
instance-attribute
The Div holding the document's blocks.
block_gap
class-attribute
instance-attribute
block_gap: int = 1
Rows between blocks: in the document, a block quote, and a loose list and its items.
heading_1
class-attribute
instance-attribute
heading_2
class-attribute
instance-attribute
heading_3
class-attribute
instance-attribute
heading_4
class-attribute
instance-attribute
heading_5
class-attribute
instance-attribute
heading_6
class-attribute
instance-attribute
block_quote
class-attribute
instance-attribute
block_quote: Style = (
border_light
| border_left
| border_color("slate", 500)
| pad_left(1)
)
block_quote_text
class-attribute
instance-attribute
Merged over the text of everything inside a block quote.
bullets
class-attribute
instance-attribute
The bullet for each depth of nested bullet lists, starting again from the first past the last.
unchecked_task
class-attribute
instance-attribute
unchecked_task: str = '☐'
The box of a task list item that isn't done, which takes the place of its bullet, or follows its number.
checked_task
class-attribute
instance-attribute
checked_task: str = '☑'
The box of a task list item that is done.
checked_task_marker
class-attribute
instance-attribute
checked_task_marker: Style = text_color('emerald', 400)
Merged over list_marker for the box of a task list item that is done.
alert
class-attribute
instance-attribute
alert: Style = border_light | border_left | pad_left(1)
A GitHub alert (> [!NOTE]), which is a block quote with a title.
alert_title
class-attribute
instance-attribute
alert_note
class-attribute
instance-attribute
alert_note: Style = border_color("blue", 400) | text_color(
"blue", 400
)
Merged over alert for a NOTE alert, and over alert_title for its title,
so its border color colors the alert's bar and its text color the title.
alert_tip
class-attribute
instance-attribute
alert_tip: Style = border_color("green", 400) | text_color(
"green", 400
)
Merged over alert and alert_title for a TIP alert, like alert_note.
alert_important
class-attribute
instance-attribute
alert_important: Style = border_color(
"violet", 400
) | text_color("violet", 400)
Merged over alert and alert_title for an IMPORTANT alert, like alert_note.
alert_warning
class-attribute
instance-attribute
alert_warning: Style = border_color(
"amber", 400
) | text_color("amber", 400)
Merged over alert and alert_title for a WARNING alert, like alert_note.
alert_caution
class-attribute
instance-attribute
alert_caution: Style = border_color(
"red", 400
) | text_color("red", 400)
Merged over alert and alert_title for a CAUTION alert, like alert_note.
code_block
class-attribute
instance-attribute
code_block: Style = pad_x(1)
Merged over the code theme's background, from code_style.
code_theme
class-attribute
instance-attribute
code_theme: CodeTheme = DEFAULT_CODE_THEME
The theme fenced code blocks are highlighted with, when their info string names a language Pygments knows.
front_matter
class-attribute
instance-attribute
Merged over code_block for the document's YAML front matter, which is highlighted as YAML.
Pass display_none to hide it.
thematic_break
class-attribute
instance-attribute
thematic_break: Style = (
border_light | border_top | border_color("slate", 600)
)
math_block
class-attribute
instance-attribute
math_block: Style = (
text_wrap_stable
| text_justify_center
| text_color("violet", 300)
)
Display math, between $$ lines, which is shown as written, since a terminal can't typeset it.
math_label
class-attribute
instance-attribute
math_label: Style = text_color('slate', 400)
The label of display math written $$...$$ (label), shown as (label) to its right.
html_block
class-attribute
instance-attribute
Raw HTML blocks, which are shown as written.
table_cell
class-attribute
instance-attribute
table_cell: Style = (
border_light | border | border_color("slate", 600)
)
The Div around each cell's text, which draws its border.
table_cell_text
class-attribute
instance-attribute
table_cell_text: Style = pad_x(1) | text_wrap_stable
table_header
class-attribute
instance-attribute
Merged over table_cell_text for the header row's cells.
strikethrough
class-attribute
instance-attribute
code_inline
class-attribute
instance-attribute
code_inline: CellStyle = (
text_color("rose", 300).text_style
| text_bg("slate", 800).text_style
)
math_inline
class-attribute
instance-attribute
math_inline: CellStyle = text_color(
"violet", 300
).text_style
Math within a line, between $s or $$s, which is shown as written.
link
class-attribute
instance-attribute
Merged under the CellStyle(link=...) that makes a link's text a hyperlink to its destination.
image
class-attribute
instance-attribute
An image's alt text, which links to the image, since a terminal can't show it.
footnote_ref
class-attribute
instance-attribute
footnote_ref: CellStyle = text_color('sky', 300).text_style
A footnote's number, [1], where it's referenced and beside its definition.
footnotes
class-attribute
instance-attribute
footnotes: Style = (
border_light | border_top | border_color("slate", 600)
)
The footnotes' definitions, which follow the rest of the document, numbered in the order they're referenced.