from execnb.nbio import * from fastcore.all import * from fasthtml.common import * from fasthtml.jupyter import * from IPython.display import HTML, Markdown from mistletoe import markdown, HTMLRenderer from mistletoe.contrib.pygments_renderer import PygmentsRenderer from nb2fasthtml.core import * from pathlib import Path import pygments from pygments import highlight from pygments.lexers import PythonLexer from pygments.formatters import HtmlFormatter from random import choice
audrey.feldroy.com
The experimental notebooks of Audrey M. Roy Greenfeld. This website and all its notebooks are open-source at github.com/audreyfeldroy/audrey.feldroy.com
# Converting Jupyter Notebook Cells to Pygments Syntax-Highlighted HTML
by Audrey M. Roy Greenfeld | Wed, Dec 25, 2024
## Understand the Problem Can a Jupyter notebook be converted to syntax-highlighted HTML easily with Pygments? Side note: Highlight.js is what Danny and Isaac use for syntax highlighting in FastHTML apps. I'll try that in another notebook later. I started this on a plane where I only had Pygments installed.
Devise a Plan
- Get the code cells of a sample notebook
- Convert one to syntax-highlighted HTML
- View it
- Convert all to syntax-highlighted HTML
Carry Out Plan
nb = read_nb(Path("../nbs/2024-12-24-deck-the-halls.ipynb")) nb.metadata
nb.cells
sources = L(nb.cells).itemgot('source') sources
sources.map(Div)
code_cells = L(nb.cells).filter(lambda x: x.cell_type == 'code') code_cells[:4]
code_cells[2]
Code Highlighting With Pygments
fm = HtmlFormatter(style='colorful') pl = PythonLexer()
highlight("print('Hi')", lexer=pl, formatter=fm)
highlight(code_cells[2].source, lexer=pl, formatter=fm)
HTML(highlight(code_cells[2].source, lexer=pl, formatter=fm))
The previous cell should show colors but doesn't. Not sure how to show them here in this notebook.
def colorize(c): return highlight(c.source, lexer=pl, formatter=fm)
colorized = code_cells.map(colorize).map(NotStr) colorized[:2]
def colorized_cells(cells): return cells.map(colorize).map(NotStr)
Formatter Styles
L(pygments.styles.STYLES.items())
L(pygments.styles.STYLES.items()).itemgot(1)
styles = L(pygments.styles.STYLES.items()).itemgot(1).itemgot(1) styles
%%aip Get a random style from that list
style = choice(styles) style
CSS Styles
fm = HtmlFormatter(style='stata-dark')
fm.get_style_defs()[:100]
FastHTML app
app,rt = fast_app()
server = JupyUvi(app)
@rt def index(): nb = read_nb(Path("../nbs/2024-12-24-deck-the-halls.ipynb")) code_cells = L(nb.cells).filter(lambda x: x.cell_type == 'code') style = choice(styles) fm = HtmlFormatter(style=style) return ( H1(f"Random style: {style}"), P("This page gets a random ", A("Pygments", href="https://pygments.org/"), " HtmlFormatter style and applies it to ", A("my Deck the Halls Jupyter notebook", href="https://nbsanity.com/static/a426287f3fbfc5a38c99291beadc77d3/2024-12-24-deck-the-halls.html")), Style(fm.get_style_defs()), Style(".highlight{border:1px solid gray;margin:10px;}"), Div(*colorized_cells(code_cells)) )
Stopping the Server
if 'server' in globals(): server.stop()
© 2024-2025 Audrey M. Roy Greenfeld