Renderers#

A renderer decides what a calculation looks like. handcalcs parses your code once, and the renderer turns the parsed calculation into Markdown, LaTeX, HTML, plain text, an Excel workbook, a Word document, or anything else you write a renderer for.

Choosing a renderer#

Renderer

Name

Produces

Use it for

MarkdownRenderer

markdown

Markdown text with $$ LaTeX math

Jupyter (the default), MyST/Sphinx, Quarto, any Markdown + MathJax/KaTeX site

LatexRenderer

latex

A LaTeX fragment

.tex reports, PDF through LaTeX, Jupyter’s LaTeX display

HTMLRenderer

html

An HTML fragment with a scoped stylesheet, no math engine needed

Web apps, emails, HTML reports, Jupyter

ASCIIRenderer

ascii

Unicode text

Terminals, logs, test snapshots, plain-text reports

ExcelRenderer

excel

A live .xlsx worksheet

Handing a calculation to someone who works in Excel

WordRenderer

word

A .docx document with editable Word equations

Reports in Word (or Google Docs), from a script or a notebook

BaseRenderer

base

A nested Python list

Building your own renderer, debugging

Using one#

Every renderer is a class in handcalcs.renderers. Pass an instance to an interface:

from handcalcs import HandCalcs
from handcalcs.renderers import HTMLRenderer

html = HandCalcs(renderer=HTMLRenderer())(source)

In Jupyter, choose by name:

%hc_default_renderer html

Or set the default for each interface in the configuration: default_renderer for a bare HandCalcs() and @handcalc() (default ascii), jupyter_renderer for %%render.

The same calculation, five ways#

Output (MarkdownRenderer)

Roots

\[\begin{aligned} a &= 2 \; &b &= -7 \; &c_{0} &= 3 \; \end{aligned}\]
\[\begin{aligned} x_{1} &= \frac{-b + \sqrt{b^{2} - 4 \cdot a \cdot c_{0}}}{2 \cdot a} = \frac{-\left(-7\right) + \sqrt{\left(-7\right)^{2} - 4 \cdot 2 \cdot 3}}{2 \cdot 2} = 3 \\ &\quad\text{(Larger root)} \end{aligned}\]
# Roots

$$\begin{aligned} a &= 2 \; &b &= -7 \; &c_{0} &= 3 \; \end{aligned}$$

$$\begin{aligned} x_{1} &= \frac{-b + \sqrt{b^{2} - 4 \cdot a \cdot c_{0}}}{2 \cdot a} = \frac{-\left(-7\right) + \sqrt{\left(-7\right)^{2} - 4 \cdot 2 \cdot 3}}{2 \cdot 2} = 3 \\ &\quad\text{(Larger root)} \end{aligned}$$
Output (HTMLRenderer)

Roots

a=2b=-7c0=3
x1 = (-b + √(b2 - 4 · a · c0)) / (2 · a) = (-(-7) + √((-7)2 - 4 · 2 · 3)) / (2 · 2) = 3 (Larger root)
<div class="handcalcs"><style>.handcalcs{--hc-accent:#0B5F66;--hc-accent-dark:#91CFD4;--hc-guide-1:#85B8BD;--hc-guide-2:#D5B386;--hc-guide-3:#A8B0C7;}:is([data-jp-theme-light="false"],.vscode-dark,.vscode-high-contrast,[data-theme="dark"]) .handcalcs{--hc-accent-text:var(--hc-accent-dark);--hc-tint:color-mix(in srgb,var(--hc-accent) 30%,transparent);--hc-highlight:color-mix(in srgb,var(--hc-accent) 38%,transparent);}.handcalcs{--hc-gap:0.35em;--hc-indent:1.5em;--hc-param-gap:2em;--hc-eq-gap:0.3em;--hc-accent-text:var(--hc-accent);--hc-tint:color-mix(in srgb,var(--hc-accent) 9%,transparent);--hc-highlight:color-mix(in srgb,var(--hc-accent) 12%,transparent);--hc-muted:color-mix(in srgb,currentColor 60%,transparent);--hc-chip:color-mix(in srgb,currentColor 6%,transparent);display:flex;flex-direction:column;gap:var(--hc-gap);line-height:1.6;font-variant-numeric:tabular-nums;}.handcalcs :where(.hc-block,.hc-body){display:flex;flex-direction:column;gap:var(--hc-gap);}.handcalcs :where(.hc-body){margin-inline-start:0.55em;padding-inline-start:calc(var(--hc-indent) - 0.55em);border-inline-start:2px solid var(--hc-guide);--hc-guide:var(--hc-guide-1);}.handcalcs :where(.hc-body .hc-body){--hc-guide:var(--hc-guide-2);}.handcalcs :where(.hc-body .hc-body .hc-body){--hc-guide:var(--hc-guide-3);}.handcalcs :where(.hc-body .hc-body .hc-body .hc-body){--hc-guide:var(--hc-guide-1);}.handcalcs :where(.hc-body .hc-body .hc-body .hc-body .hc-body){--hc-guide:var(--hc-guide-2);}.handcalcs :where(.hc-line,.hc-header,.hc-comment){margin-block:0;}.handcalcs :where(.hc-header){background:var(--hc-tint);border-radius:4px;padding:0.1em 0.5em;}.handcalcs :where(.hc-header)::before{content:"\25B8";color:var(--hc-accent-text);margin-inline-end:0.4em;}.handcalcs :where(.hc-kw){color:var(--hc-accent-text);}.handcalcs :where(.hc-result){color:var(--hc-accent-text);background:var(--hc-highlight);font-weight:600;padding:0 0.25em;border-radius:3px;-webkit-box-decoration-break:clone;box-decoration-break:clone;}.handcalcs :where(.hc-note){color:var(--hc-muted);}.handcalcs :where(.hc-check){font-weight:700;}.handcalcs :where(.hc-pass){color:#1A7F37;}.handcalcs :where(.hc-fail){color:#CF222E;}.handcalcs :where(.hc-import){align-self:start;font-family:var(--jp-code-font-family,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);font-size:0.85em;color:var(--hc-muted);background:var(--hc-chip);padding:0.05em 0.5em;border-radius:3px;}.handcalcs :where(.hc-comment,.hc-note) :where(code){font-size:0.9em;background:var(--hc-chip);padding:0 0.25em;border-radius:3px;}.handcalcs table.hc-params{margin:0;border:0;border-collapse:separate;border-spacing:0;table-layout:auto;width:auto;align-self:center;font-size:inherit;color:inherit;font-variant-numeric:tabular-nums;background:var(--hc-tint);border-radius:4px;padding:0.1em 0.6em;}.handcalcs table.hc-params.hc-multiline{align-self:start;background:none;border-radius:0;padding:0 0 0 0.5em;border-inline-start:2px solid var(--hc-accent-text);}.handcalcs table.hc-params tr:nth-child(n){background:none;}.handcalcs table.hc-params td{padding:0;border:0;vertical-align:baseline;line-height:inherit;white-space:normal;max-width:none;}.handcalcs table.hc-params td.hc-param-id{text-align:right;padding-inline-end:var(--hc-eq-gap);}.handcalcs table.hc-params td.hc-param-eq{text-align:center;}.handcalcs table.hc-params td.hc-param-val{text-align:left;padding-inline-start:var(--hc-eq-gap);}.handcalcs table.hc-params td.hc-param-gap{width:var(--hc-param-gap);}.handcalcs table.hc-params td.hc-param-comment{text-align:left;padding-inline-start:var(--hc-eq-gap);}.handcalcs :where(.hc-pre){white-space:pre;}.handcalcs :where(.hc-matrix){display:inline-table;vertical-align:middle;border-inline:1px solid currentColor;border-radius:0.2em;padding:0 0.15em;}.handcalcs :where(.hc-matrix-row){display:table-row;}.handcalcs :where(.hc-matrix-cell){display:table-cell;text-align:right;padding:0 0.3em;line-height:1.2;}</style><h1>Roots</h1><table class="hc-params"><tr><td class="hc-param-id">a</td><td class="hc-param-eq">=</td><td class="hc-param-val">2</td><td class="hc-param-comment"></td><td class="hc-param-gap"></td><td class="hc-param-id">b</td><td class="hc-param-eq">=</td><td class="hc-param-val">-7</td><td class="hc-param-comment"></td><td class="hc-param-gap"></td><td class="hc-param-id">c<sub>0</sub></td><td class="hc-param-eq">=</td><td class="hc-param-val">3</td><td class="hc-param-comment"></td></tr></table><div class="hc-line">x<sub>1</sub> = (-b + √(b<sup>2</sup> - 4 · a · c<sub>0</sub>)) / (2 · a) = (-(-7) + √((-7)<sup>2</sup> - 4 · 2 · 3)) / (2 · 2) = <span class="hc-result">3</span> <span class="hc-note">(Larger root)</span></div></div>
Output (LatexRenderer)

Roots

\[\begin{aligned} a &= 2 \; &b &= -7 \; &c_{0} &= 3 \; \end{aligned}\]
\[\begin{aligned} x_{1} &= \frac{-b + \sqrt{b^{2} - 4 \cdot a \cdot c_{0}}}{2 \cdot a} = \frac{-\left(-7\right) + \sqrt{\left(-7\right)^{2} - 4 \cdot 2 \cdot 3}}{2 \cdot 2} = 3 \\ &\quad\text{(Larger root)} \end{aligned}\]
\section*{Roots}

\medskip
\noindent$\displaystyle
\begin{aligned}[t]
a &= 2 \; &b &= -7 \; &c_{0} &= 3 \;
\end{aligned}$

\medskip

\medskip
\noindent$\displaystyle
\begin{aligned}[t]
x_{1} &= \frac{-b + \sqrt{b^{2} - 4 \cdot a \cdot c_{0}}}{2 \cdot a} = \frac{-\left(-7\right) + \sqrt{\left(-7\right)^{2} - 4 \cdot 2 \cdot 3}}{2 \cdot 2} = 3 \\
&\quad\text{(Larger root)}
\end{aligned}$

\medskip
Output (ASCIIRenderer)
=====
Roots
=====

  a = 2    b = -7    c_0 = 3
x_1 = (-b + √(b² - 4 * a * c_0)) / (2 * a) = (-(-7) + √((-7)² - 4 * 2 * 3)) / (2 * 2) = 3 (Larger root)
Output (BaseRenderer)
['# Roots',
 'a = 2    b = -7    c_0 = 3',
 ['',
  [['x_1',
    '=',
    '(-b + sqrt(b ** 2 - 4 * a * c_0)) / (2 * a)',
    '=',
    '(-(-7) + sqrt((-7) ** 2 - 4 * 2 * 3)) / (2 * 2)',
    '=',
    '3',
    '(Larger root)']]]]

The source for all five:

## Roots
a = 2; b = -7; c_0 = 3
x_1 = (-b + sqrt(b**2 - 4*a*c_0)) / (2*a)  # Larger root

Going further#