Skip to main content

A literate programming tool for Python that weaves code and documentation into scientific reports

Project description

Nhandu

PyPI version Python 3.10+ Tests License: MIT

Literate programming for Python: write executable documents in plain .py files.

Nhandu transforms Python files with markdown comments into beautiful, reproducible reports. It is lighter than Jupyter, simpler than Quarto, and perfectly git-friendly.

Nhandu (/ɲãndu/, approximately "NYAN-doo") means "spider" in many Tupi-Guarani languages, reflecting its role in weaving code and documentation together, much like Knuth's original vision of literate programming.

Installation

pip install nhandu

For Jupyter notebook conversion support:

pip install nhandu[jupyter]

Requirements: Python 3.10 or later.

Quick Start

Create a file called analysis.py:

#' # My First Analysis
#'
#' Lines starting with `#'` are markdown.
#' Everything else is regular Python code.

import math

#' ## Results

print(f"Pi is approximately {math.pi:.4f}")
print(f"Euler's number is approximately {math.e:.4f}")

#' Variables persist between code blocks:

radius = 5
area = math.pi * radius ** 2
print(f"Area of circle with radius {radius}: {area:.2f}")

Generate a report:

nhandu analysis.py                  # Markdown output → analysis.out.md
nhandu analysis.py --format html    # HTML output → analysis.html

Why Nhandu?

Python's literate programming tools each come with trade-offs:

  • Jupyter notebooks use JSON (messy git diffs), require a browser, and mix code with metadata
  • Quarto is powerful but complex, with a steep learning curve
  • Pweave is no longer maintained and incompatible with current Python versions

Nhandu offers a different approach:

Jupyter Quarto Nhandu
File format JSON (.ipynb) Markdown (.qmd) Python (.py)
Git diffs Noisy Clean Clean
Requires browser/server Yes No No
Configuration needed Kernels, metadata YAML headers, engines Nothing
Editor support Specialized Any + plugins Any Python editor
Learning curve Medium High Minimal

Features

Smart Output Capture

Nhandu automatically captures:

  • Print statements and stdout
  • Matplotlib figures (no plt.show() needed) — also works with seaborn, pandas .plot(), and other matplotlib-based libraries
  • Expression results (last expression in a block is displayed, like Jupyter)

Syntax Highlighting

Server-side syntax highlighting via Pygments with 49 built-in themes. Popular themes include github-dark (default), monokai, dracula, one-dark, and solarized-light.

List all available themes:

nhandu --list-themes

HTML Templates

Three built-in templates for HTML output:

  • default — clean sans-serif layout
  • academic — serif, paper-like styling for research reports
  • corporate — blue accents, professional look

Select via --template academic or template: frontmatter. Add custom CSS overrides with --template-css custom.css. List available templates:

nhandu --list-templates

Templates are orthogonal to --code-theme (Pygments syntax highlighting).

Output Formats

  • Markdown (default) — convertible to PDF, Word, or LaTeX via pandoc
  • HTML — self-contained files with embedded plots, syntax highlighting, and responsive styling

Inline Code

Embed Python expressions directly in markdown text:

total = 1500
target = 2000

#' We achieved <%= total %> in sales,
#' which is <%= (total/target)*100 %>% of our target.
  • <%= expression %> — evaluate and display the result
  • <% statement %> — execute without output

Inline code shares the same namespace as regular code blocks.

Hidden Code Blocks

Run setup code without cluttering the report:

#| hide
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('seaborn-v0_8')
#|

#' Now the analysis begins:
data = pd.read_csv("data.csv")

YAML Frontmatter

Configure reports via optional frontmatter:

#' ---
#' title: My Scientific Report
#' output: html
#' code_theme: dracula
#' template: academic
#' plot_dpi: 150
#' number_format: ".2f"
#' show_footer: false
#' ---
Option Default Description
title filename Document title (used in HTML <title>)
output markdown Output format: markdown or html
code_theme github-dark Pygments syntax highlighting theme
plot_dpi 100 DPI for saved matplotlib figures
number_format .4f Python format spec for inline float values
template default HTML template: default, academic, or corporate
template_css (none) Path to custom CSS file appended to template styles
show_footer true Show "Made with Nhandu" footer in HTML
working_dir (current) Working directory for code execution

Configuration can also be provided via a YAML file (--config config.yaml) or CLI arguments.

CLI Reference

Processing Documents

nhandu INPUT [OPTIONS]

# Examples:
nhandu analysis.py                        # → analysis.out.md (markdown)
nhandu analysis.py --format html          # → analysis.html
nhandu analysis.py -o report.html         # Specify output path
nhandu analysis.py --code-theme monokai   # Custom syntax theme
nhandu analysis.py --no-footer            # Disable HTML footer
nhandu analysis.py -v                     # Verbose with progress
nhandu analysis.py --parse-only           # Show structure, skip execution

Options

positional:
  INPUT                         Input file (.py literate Python)

options:
  -o, --output PATH             Output file path
  --format {html,md,markdown}   Output format (default: markdown)
  --config PATH                 Configuration file (YAML)
  --working-dir PATH            Working directory for code execution
  --code-theme THEME            Syntax highlighting theme
  --template TEMPLATE           HTML template (default, academic, corporate)
  --template-css PATH           Custom CSS file to append to template styles
  --no-footer                   Disable footer in HTML output
  --parse-only                  Parse and show structure without executing
  -v, --verbose                 Verbose output with progress
  --list-themes                 List all available syntax themes
  --list-templates              List all available HTML templates
  --version                     Show version and exit

Jupyter Notebook Conversion

Import from Jupyter:

nhandu import-notebook notebook.ipynb -o document.py

Export to Jupyter:

nhandu export-notebook document.py -o notebook.ipynb
nhandu export-notebook document.py -o notebook.ipynb --execute  # With outputs

Conversion preserves markdown cells, code cells, hidden cell tags, and metadata. Requires pip install nhandu[jupyter].

The Literate Python Format

The format is simple: lines starting with #' are markdown, everything else is Python code.

#' # Heading
#'
#' Markdown text with **bold**, *italic*, `code`,
#' [links](https://example.com), and tables.

# This is a regular Python comment (stays in the code block)
x = 42

#' Back to documentation. The variable `x` is still in scope:

print(f"x = {x}")  # Output captured automatically

Execution Model

  • Shared namespace — all code blocks share the same Python environment
  • Sequential execution — blocks run top to bottom, in document order
  • Automatic capture — stdout, expression results, and matplotlib figures are captured without any special syntax

Python API

Nhandu can also be used as a library:

from nhandu import parse, execute, render

content = open("document.py").read()
doc = parse(content, source_path="document.py")
executed = execute(doc)
html = render(executed, format="html")

Progress tracking is available via callback:

def on_progress(index, total, block):
    print(f"Block {index}/{total}: {'ERROR' if block.error else 'OK'}")

executed = execute(doc, on_progress=on_progress)

Available themes can be listed programmatically:

from nhandu.renderer import list_themes
print(list_themes())

Examples

The docs/ directory contains complete demonstrations:

Example Description Output
01_hello_world.py Basic syntax and concepts HTML
02_data_analysis.py Data analysis with the standard library HTML
03_plotting.py Matplotlib visualizations HTML
04_scientific_computation.py NumPy numerical computing HTML
05_advanced_report.py Pandas and multiple visualizations HTML
06_inline_code.py Inline code evaluation HTML

Project Information

Citation

If you use Nhandu in your research, please cite:

@software{tresoldi2025nhandu,
  author = {Tresoldi, Tiago},
  title = {Nhandu: Literate Programming for Python},
  year = {2025},
  publisher = {Department of Linguistics and Philology, Uppsala University},
  address = {Uppsala, Sweden},
  url = {https://github.com/tresoldi/nhandu},
  orcid = {0000-0002-2863-1467}
}

Acknowledgments

Nhandu is inspired by Donald Knuth's literate programming vision, knitr and R Markdown's approach to reproducible research, Jupyter's interactive computing paradigm, Quarto's scientific publishing tools, and Pweave's Python implementation.

The earliest stages of development took place within the Cultural Evolution of Texts project, with funding from the Riksbankens Jubileumsfond (grant agreement ID: MXM19-1087:1).

License

MIT License. See LICENSE for details.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nhandu-0.4.0.tar.gz (48.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nhandu-0.4.0-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

Details for the file nhandu-0.4.0.tar.gz.

File metadata

  • Download URL: nhandu-0.4.0.tar.gz
  • Upload date:
  • Size: 48.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nhandu-0.4.0.tar.gz
Algorithm Hash digest
SHA256 f1f52c881a2d1dd0244f35d8c9d9b4529a1148735d97d6c26adab27dcd3d2e66
MD5 f8cb50f23ec5934da23b69a29ab96d7a
BLAKE2b-256 23d68aa83f705a88a5f141d9bbb316d72e9d03ac0c6462e0f0e885d6c8c333f1

See more details on using hashes here.

File details

Details for the file nhandu-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: nhandu-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 30.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for nhandu-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 33e86333bfdea183b681383c657a71e5bde28727cc59dbc44fc2b811628f537d
MD5 b51c347dabb9c70e20bf1e6e66320db6
BLAKE2b-256 a385c66f59532a34862bcd448ddbcfbd9a1294969707f7e6d2fb088ba93f2f9a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page