%load_ext notexbook
%texify -v
2.0.1
).
Fira Code
font; 14px
; Material Theme.
Hack
font; 14px
; Material Theme.
First things first: Thank you so much for getting here (whatever is your
referral URL
)
Valerio 🤗
This notebook introduces the $\text{no}\TeX\text{book}$ Jupyter Notebooks theme.
In the next two sections, we will start with a quick overview spoiler of the theme's main typesetting features, then we will dive into all of its very nuts and bolts, including Editor Colour Themes, ad-hoc formattings, monospace fonts, and much more.
When I had to come up with a name for the theme, I aimed almost immediately at finding a single word that would convey the idea of integration of the Jupyter notebooks with $\LaTeX$ I had in mind. Indeed, no$\TeX$book seemed quite an obvious choice: this name is a unique portmanteau1 that blends together the words noTeXbook, and noTeXbook, that is the original name of Donald E. Knuth's book on $\TeX$.
That was the omen! One!... Two!... Five! 2
The $\text{no}\TeX\text{book}$ theme wishes to pay a tribute of gratitude to two of the technologies I do use and love the most as a researcher and a data scientist.
**[1]**: `port·man·teau | \ pȯrt-ˈman-(ˌ)tō` **[2]**: [The Holy Hand Granade](https://www.youtube.com/watch?v=xOrgLj9lOwk) - Monthy Python and the Holy Grail
%texify?
to see all available options)2.0x
);stderr
and pandas.DataFrame
;CSS
classes for additional LaTeX-ish formatting use cases (e.g. footnotes, dropcap).Moreover, the theme also includes a few tweaks to the general Notebook/Jupyterlab UI: the colours of all the icons and Kernel status indicators uses the theme's main palette, and a special emphasising effects is applied on active cell in either command or edit modes, as well as on multiple cells selections.
import numpy as np
import cv2
import matplotlib as mpl
import matplotlib.pyplot as plt
# Matplotlib Configuration Params
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
mpl.rcParams['figure.figsize'] = (18,1)
# Color Palette
colours = {"red": "#d43133",
"magenta" : "#D14187",
"torquoise" : "#009489",
"azure": "#00afde",
"blue": "#2875d9",
"light-grey": "#828282",
"dark-grey": "#383838",
"yellow": "#f9ab00",
"orange": "#e8710a",
}
def hex2rgb(h: str):
"""helper to convert hex colours into RGB tuple"""
h = h.lstrip('#')
return tuple(int(h[i:i+2], 16) for i in (0, 2, 4))
# Create a black image
image = np.full((1024,1024,3), 255, np.uint8)
def show_palette(colours):
n_cols = len(colours)
fig = plt.figure()
for i, (colour, hexcode) in enumerate(sorted(colours.items(), key=lambda e: hex2rgb(e[1]))):
axis = fig.add_subplot(1,n_cols,i+1)
rgb = hex2rgb(hexcode)
cv2.circle(image, (512, 512), 512, (rgb[0], rgb[1], rgb[2]), -1)
plt.title(colour, y=-0.5)
plt.axis('off')
plt.imshow(image);
show_palette(colours)
The theme main colour palette is based on these main 7
colours.
These colours can also be used in special formattings for text colouring using ad-hoc CSS
classes (all following the same naming rule): .texbook-<COLOUR NAME>
$\rightarrow$ Turquoise; Azure; Blue; Dark Grey; Light Grey; Magenta; Red; Orange; Yellow $\leftarrow$
All the fonts used in the $\text{no}\TeX\text{book}$ theme typeface design are open source, freely available on public font repositories (e.g., Google Fonts, CDN Fonts, FontSquirrel), and released under the OFL (Open Font License), and alike. Original reference and download links are provided below.
$\text{no}\TeX\text{book}$ typeface
The main goal of the $\text{no}\TeX\text{book}$ theme is to allow Jupyter notebooks to render like a
$\LaTeX$-generated article. Therefore, the (Markdown) text rendering adopts the good ol'
Computer Modern font family for both
serif and monospace
text (i.e. CMUSerif
and CMUTypewriter
fonts, respectively).
In edit mode, the Hack
font is used for Markdown editor, whereas Fira Code
font is used
for code editor. The former looks slightly better for text writing (imho), being also based on the Bitstream Vera
and the
DejaVu
fonts. Fira Code
on the other hand has been
specifically designed for source code, combining a clean and elegant style with ligratures support3.
**[3]**: Support for ligatures in the Markdown editor would be quite pointless, as the cell will be ultimately rendered in Computer Modern font.
Notebook UI
The font used for everything else in the Notebook UI and look-and-feel (e.g. header
, navbar
,
jupyter-server
home page (notebook list) uses the Roboto Slab
font.
(Miscellaneous of text formatting and emphasis - adapted from Markdown Cheatsheet) - License: CC-BY
Emphasis, aka italics, with asterisks or underscores.
Strong emphasis, aka bold, with asterisks or underscores.
Combined emphasis with asterisks and underscores, also for bold
italic
mono
Mono blocks are supported too.
Strikethrough uses two tildes, colored in red: Scratch this.
Headers
h1
)¶h2
)¶h3
)¶h4
)¶h5
)¶h6
)¶Lists
mono
Tables
Tables | Are | Cool |
---|---|---|
col 3 is | right-aligned | \$1600 |
col 2 is | centered | \$12 |
zebra stripes | are neat | \$1 |
Blockquotes and Monospace Paragraphs
Blockquotes are very handy in email to emulate reply text. This line is part of the same quote.
This paragraph will be using monospace font.
Special mention goes to code syntax highlighting support in Markdown cells: they will still be using the default CMUTypewriter
monospace font,
but they will also share the same colour scheme used for code cells (more on this in the Code Editor Section).
For example:
// Javascript Highlighting
var x = 3.14; // A number with decimals
var y = 3; // A number without decimals
# Python highlighting
import antigravity
from __future__ import barry_as_FLUFL # PEP401
echo "Shell syntaxt highlighting"
Math and $LaTeX$ text style integration is supported (via MathJax
) both in inline and block modes.
Inline math: $ X^2 + 1 = 1 $ works fine.
Math block:
$$ X^2 + 1 = 1 $$Some more Math examples taken from Latex/Advanced Mathematics:
$$ \begin{equation} f(x)=(x+a)(x+b) \end{equation} $$$$ \begin{equation} L' = {L}{\sqrt{1-\frac{v^2}{c^2}}} \end{equation} $$Maxwell's equations: $$ \begin{equation} \left.\begin{aligned} B'&=-\partial \times E,\\ E'&=\partial \times B - 4\pi j, \end{aligned} \right\} \qquad \text{Maxwell's equations} \end{equation} $$
Factorials and Binomials: $$ \frac{n!}{k!(n-k)!} = \binom{n}{k} $$
fraction within a fraction $$ \frac{\frac{1}{x}+\frac{1}{y}}{y-z} $$
Limits: $$ \begin{equation} \lim_{a\to \infty} \tfrac{1}{a} \end{equation} $$
Math formulas with comments:
$$ [ y = a + f(\underbrace{b x}_{ \ge 0 \text{ by assumption}}) = a + f(\underbrace{b x}_{ \ge 0 \text{ by assumption}}) ] $$gather
: Consecutive equations without alignment
$$
\begin{gather*}
a_0=\frac{1}{\pi}\int\limits_{-\pi}^{\pi}f(x)\,\mathrm{d}x\\[6pt]
\begin{split}
a_n=\frac{1}{\pi}\int\limits_{-\pi}^{\pi}f(x)\cos nx\,\mathrm{d}x=\\
=\frac{1}{\pi}\int\limits_{-\pi}^{\pi}x^2\cos nx\,\mathrm{d}x
\end{split}\\[6pt]
\begin{split}
b_n=\frac{1}{\pi}\int\limits_{-\pi}^{\pi}f(x)\sin nx\,\mathrm{d}x=\\
=\frac{1}{\pi}\int\limits_{-\pi}^{\pi}x^2\sin nx\,\mathrm{d}x
\end{split}\\[6pt]
\end{gather*}
$$
alignat
: Allows control of the horizontal space between equations.
$$
\begin{alignat}{2}
\sigma_1 &= x + y &\quad \sigma_2 &= \frac{x}{y} \\
\sigma_1' &= \frac{\partial x + y}{\partial x} & \sigma_2'
&= \frac{\partial \frac{x}{y}}{\partial x}
\end{alignat}
$$
In addition to standard Markdown integration, the $\text{no}\TeX\text{book}$ theme provides extra CSS
classes to allow for additional $\LaTeX$-ish formatting, and extra typesetting for notebooks:
Any HTML link targeting a bookmark or an anchor including fn
(as in footnote) in their name will be automatically interpreted as links to a footnote. For example:
[1](#fnlink)
The above link will be automatically rendered as superscript and within square-brackets1
To actually generate the footnote text, every HTML
tag mapped to an id
starting with fn
(or alternatively using the fn
class) will be automatically formatted as footnote text. Footnote symbol should be emphasised in bold:
<span id="fnlink"><b>[1]:</b> This is an example of a footnote</span>
[1]: This is an example of a footnote
As default, the max-width
of images (and SVG) is automatically capped at the 70%
to allow for a
proper rendering of large images, whilst avoiding any potential overflow.
Nonetheless, there may be cases in which it would be required to control the max-width
parameter in order to enlarge or
shrink an image. Special CSS
classes are available controlling the max-width
attribute of displaying images.
All this classes share the same name prefix (i.e. .maxw
) followed by the corresponding ma-width expressed as percentage value.
The list of available CSS Classes is:
>>> [f"maxw{i}" for i in range(5, 101, 5)]
['maxw10', 'maxw15', 'maxw20', 'maxw25', 'maxw30', 'maxw35', 'maxw40', 'maxw45', 'maxw50',
'maxw55', 'maxw60', 'maxw65', 'maxw70', 'maxw75', 'maxw80', 'maxw85', 'maxw90', 'maxw95',
'maxw100']
Examples:
<!-- max-width: 10% -->
<img [...] class="maxw10" />
<!-- max-width: 35% -->
<img [...] class="maxw35" />
The theme also defines special classes to include badges.
This may turn out to be particularly useful in notebooks to include links to external services like Google Colab, MyBinder, or NBViewer,
In order to do so, the theme provides the CSS
class .badges
that can be used in a Markdown cell:
<div class="badges"> ... </div>
Here is an example:
The inline-math
CSS
class forces to display inline
Math blocks. This may be particularly useful in cases we do want to use the $\LaTeX$ Math-block environment to write equation, but we do not want to have it displayed in a separate paragraph:
To do so, let's just wrap the equation with a span
HTML tag with class .inline-math
:
<span class="inline-math">... </span>
This equation will be displayed inline: $$ \sum_{i=1}^{N} x_i^2 $$
The default monospace
font used in Markdown Cell rendering is CMUTypewriter
, that is the monospace font of the Computer Modern Family.
However, the $\text{no}\TeX\text{book}$ theme also utilises two additional monospace fonts (for Code and Markdown editors), and sometimes it may also be required to use any of these fonts in rendered text.
To do so, the theme provides two special CSS
classes, namely .codemono
and .mdmono
that will serve exactly this purpose.
The example below demonstrates how to force the rendering of the following inline mono using code editor font
<span class="codemono">`Code Monospace Font` with Ligatures **support** `--> >= !=`</span>
`Code Monospace Font` with Ligatures **support** `--> >= !=`
class Dataset(object):
r"""An abstract class representing a :class:`Dataset`.
All datasets that represent a map from keys to data samples should subclass
it. All subclasses should overwrite :meth:`__getitem__`, supporting fetching a
data sample for a given key. Subclasses could also optionally overwrite
:meth:`__len__`, which is expected to return the size of the dataset by many
:class:`~torch.utils.data.Sampler` implementations and the default options
of :class:`~torch.utils.data.DataLoader`.
.. note::
:class:`~torch.utils.data.DataLoader` by default constructs a index
sampler that yields integral indices. To make it work with a map-style
dataset with non-integral indices/keys, a custom sampler must be provided.
"""
def __getitem__(self, index):
raise NotImplementedError
def __add__(self, other):
return ConcatDataset([self, other])
# No `def __len__(self)` default?
# See NOTE [ Lack of Default `__len__` in Python Abstract Base Classes ]
# in pytorch/torch/utils/data/sampler.py
The CSS style for code and markdown editor integrated in $\text{no}\TeX\text{book}$ adopts a strategy that aims at flexibility and extensibility.
The main style file for code editors is editors.css
. This file imports each theme for both code and
markdown editors. The themes for the two editors are defined in two different files, to allow for
maxmimum flexibility in the choice of the colours schemes to adopt.
In each theme file, the base colour palette is defined, along with the mapping of each of these colours to specific (editor) variables. These variables are then used to define the CSS style rules.
In this way, it is very easy to change or try multiple themes, or even defining custom new ones.
The default colour scheme used for code and markdown editor is based on the
Material Design Light Theme.
In addition, other editor themes are bundled with the $\text{no}\TeX\text{book}$ Jupyter theme, e.g. GitHub Light
for code, Typora
theme for markdown.
The base colour palettes for each of those themes are showed below.
material
)¶The default colour palette used for both Code and Markdown editors is inspired by the Material Design Light Theme.
The colour palette is declined on 12
colours, reported below:
material_code_colours = {
"light-white": "#FAFAFA",
"black": "#212121",
"dark-blue" : "#01579B11",
"dark-blue-2": "#01579B22",
"blue": "#1565C0",
"green": "#2E7D32",
"yellow": "#A8601A",
"cyan": "#00838f",
"magenta": "#9C00B0",
"red": "#C0392B",
"grey": "#9E9E9E",
"light-blue": "#78909c"
}
show_palette(material_code_colours)
The Markdown editor uses only a subset of those colours. In particular:
material_md_colours = {
"black": "#212121",
"dark-blue" : "#01579B11",
"blue": "#1565C0",
"yellow": "#A8601A",
"red": "#C0392B",
"grey": "#9E9E9E",
"light-blue": "#78909c"
}
show_palette(material_md_colours)
github
)¶This theme builds on the new code editor theme available on GitHub.
github_code_colours = {
"white": "#fafafa",
"red": "#d65b67",
"orange": "#df7b41",
"yellow": "#f5e17b",
"blue": "#0259be",
"dark-blue": "#053060",
"black": "#24292e",
"azure": "#c0d8f4",
"grey": "#868c94",
"light-grey": "#b3b4b6",
"purple": "#724abd",
}
show_palette(github_code_colours)
github-light
)¶The GitHub Light theme is an alternative theme inspired by the (previous) GitHub light theme.
Reference: Github Syntax Highlighting
github_code_colours = {
"dark-grey": "#505050",
"grey": "#b8b8b8",
"light-grey": "#6a737d",
"lighter-grey": "#e2e2e2",
"antrax": "#24292e",
"red": "#d73a49",
"orange": "#e36209",
"dark-orange": "#f14c00",
"purple": "#6f42c1",
"light-yellow": "#fff9eb",
"yellow": "#ffea7f",
"blue": "#005cc5",
"dark-blue": "#032f62",
"green": "#22863a"
}
show_palette(github_code_colours)
crisp
)¶The colour palette of the Crisp Light editor theme is inspired by the Crisp light theme included in the Rainglow collection of VSCode Themes
Reference: https://github.com/rainglow/vscode/
crisp_code_colours = {
"lilac": "#c6a7c6",
"black": "#221a22",
"grey": "#b8b8b8",
"yellow": "#fc9a0f",
"dark-orange": "#fc6a0f",
"purple": "#765478",
"dark-purple": "#4f3c4f",
"light-purple": "#99769b",
"red": "#cf433e"
}
show_palette(crisp_code_colours)
typora_md_colours = {
"pink": "#d14187",
"dark-grey": "#383838",
"darker-grey": "#333333",
"taupe": "#a99f9f",
"light-orange": "#be7716",
"light-red": "#a34343",
"grey-blue": "#48599b",
"dark-bg": "#252a2f",
"dirty-white": "#8d8e8f"
}
show_palette(typora_md_colours)
The look and feel of dataframes
(tables) is slightly changed.
I've chosen a post-it note color for the table background so that dataframe output standsout, especially when scrolling through a long notebook.
from sklearn.datasets import load_iris
import pandas as pd
iris = load_iris()
iris_df = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
columns= iris['feature_names'] + ['target'])
iris_df.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | target | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | 0.0 |
1 | 4.9 | 3.0 | 1.4 | 0.2 | 0.0 |
2 | 4.7 | 3.2 | 1.3 | 0.2 | 0.0 |
3 | 4.6 | 3.1 | 1.5 | 0.2 | 0.0 |
4 | 5.0 | 3.6 | 1.4 | 0.2 | 0.0 |
from wherever import non_existing_module
--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) <ipython-input-14-40a1e5a99230> in <module> ----> 1 from wherever import non_existing_module ModuleNotFoundError: No module named 'wherever'
from scipy import linalg
linalg.det(np.ones((3, 4)))
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-15-5162a496210c> in <module> 1 from scipy import linalg ----> 2 linalg.det(np.ones((3, 4))) ~/anaconda3/envs/notexbook-test/lib/python3.9/site-packages/scipy/linalg/basic.py in det(a, overwrite_a, check_finite) 1018 a1 = _asarray_validated(a, check_finite=check_finite) 1019 if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: -> 1020 raise ValueError('expected square matrix') 1021 overwrite_a = overwrite_a or _datacopied(a1, a) 1022 fdet, = get_flinalg_funcs(('det',), (a1,)) ValueError: expected square matrix
Jupyter Lab is fully supported!
Moreover: the latest versions of jupyter-nbconvert
apply the lab
template as default HTML template for export. This generates a DOM structure which is compliant with Jupyter Lab.
Here is an example of this notebook exported with lab
template $\Rightarrow$ Jupyter Lab Light
custom.css
Jupyter theme¶The $\text{no}\TeX\text{book}$ theme is also available as a full-fledged custom Jupyter notebook theme (HTML/CSS). This is useful in case one would prefer to enable the theme as the global custom default Jupyter theme.
The noTeXbook
theme package is available for download,
along with its corresponding documentation.
The documentation also contains details on the original CSS design, and instructions on how to define your own CSS Editor Colour theme.
The HTML of a Colaboratory notebook is nothing similar to the standard Jupyter notebook/lab HTML structure (so the custom-css
cannot work). In addition, every single Colaboratory notebook cell generates a new HTML iframe
, so making the texify
IPython magic pretty much useless too.
Therefore, the only solution I could resort to was using the Stylus) browser extension. Unfortunately this is not as customisable and portable as the IPython magic, but hey?! Better than nothing 🤓
All the instructions on how to install $\text{no}\TeX\text{book}$ for Google Colaboratory Notebooks are available $\Rightarrow$ here) on the branch specifically dedicated to the Colab
version of the theme.
Once you are done, try to open the sample notebook in Colab, and enjoy 🙌
spinzero
jupyter theme has been inspirational in the design of the early version of this theme;(Some links I found useful along the way):
setuptools
: Specify Dependenciessetup.py
commandspyproject.toml
pyproject.toml
Special thanks to cdesio, ninadicara, and alanderex for testing earlier versions of the theme!