Skip to main content

Write in Jupyter Notebooks. Publish anywhere.

Project description

nb2wb

Write in notebooks. Publish anywhere.

nb2wb turns notebook-native writing into paste-ready HTML for editors that do not understand Jupyter, Quarto, or LaTeX. Start from a notebook, a Markdown article, or a Quarto document, then target a neutral preview wrapper or a profile tuned for Substack, Medium, X Articles, LinkedIn, Dev.to, Hashnode, Ghost, or WordPress.

The project also ships a reverse scaffold. Use wb2nb or nb2wb.revert() to turn published HTML back into a Jupyter notebook when you need to recover prose, code blocks, and image-derived content.

Why People Reach for nb2wb

  • Render code cells as syntax-highlighted images so theme and spacing survive copy and paste.
  • Render display math as images and inline math as readable Unicode text.
  • Keep tables as native HTML or convert them to images when a platform editor is unreliable.
  • Wrap output for different publishing targets without rewriting article content.
  • Serve extracted images through --serve when editors reject embedded data URIs.
  • Reverse HTML posts back into notebook scaffolds, with OCR as an opt-in upgrade.
  • Apply safety limits and HTML/SVG sanitization by default for server-side use.

Supported Inputs

  • Jupyter notebooks: .ipynb
  • Quarto documents: .qmd
  • Markdown documents: .md
  • In-memory notebook payloads: dict / nbformat.NotebookNode
  • In-memory text payloads: raw strings or {"format": "...", "content": "..."}
  • Reverse conversion inputs: .html, .htm, and in-memory HTML payloads

Installation

Install the base package:

pip install nb2wb

Install extras only when you need them:

pip install "nb2wb[ocr]"     # local OCR for reverse conversion
pip install "nb2wb[openai]"  # OpenAI-backed OCR pipeline
pip install "nb2wb[gemini]"  # Google Gemini-backed OCR pipeline

For development:

git clone https://github.com/the-palindrome/nb2wb.git
cd nb2wb
pip install -e ".[dev]"

Quick Start

Convert a notebook to the default preview wrapper:

nb2wb notebook.ipynb

Target a platform profile:

nb2wb notebook.ipynb -t medium
nb2wb notebook.ipynb -t x
nb2wb notebook.ipynb -t linkedin

Use execution, raw mode, and wrapper overrides when you need them:

nb2wb report.qmd --execute
nb2wb report.ipynb --warnings
nb2wb report.ipynb --raw -o article_raw.html
nb2wb report.ipynb -t ghost --image-strategy embed --article-width 900
nb2wb report.ipynb --serve

Reverse an HTML article back into a notebook scaffold:

wb2nb article.html
wb2nb article.html -o recovered.ipynb
wb2nb article.html --ocr-pipeline local
OPENAI_API_KEY=... wb2nb article.html --ocr-pipeline openai --model your-model-name
GEMINI_API_KEY=... wb2nb article.html --ocr-pipeline gemini --model gemini-2.0-flash

Python API

nb2wb.convert() is content-only. Load files with helpers first, then pass the in-memory payload into the converter.

import nb2wb

payload = nb2wb.load_input_payload("notebook.ipynb")
html = nb2wb.convert(
    payload,
    target="substack",
    config={"latex": {"try_usetex": True}},
)

You can also pass text or notebook payloads directly:

import nb2wb

html = nb2wb.convert(
    {
        "format": "md",
        "content": "# Shipping Notes\n\n`nb2wb` handles this in memory.",
    },
    target="medium",
    raw_mode=True,
)

Reverse conversion follows the same pattern:

import nb2wb

payload = nb2wb.load_html_payload("article.html")
notebook = nb2wb.revert(payload)

Add OCR only when you want image-derived notebook cells:

from nb2wb.ocr.openai import OpenAIOCRPipeline

ocr_notebook = nb2wb.revert(
    payload,
    ocr_pipeline=OpenAIOCRPipeline(model="your-model-name"),
)

Examples

The examples/ directory now covers forward conversion, reverse conversion, API usage, Markdown directives, Quarto {output} chunks, visibility tags, rich HTML/SVG outputs, and target-specific publishing flows.

Useful entry points:

Security Model

nb2wb keeps the safe path on by default:

  • HTML and SVG fragments are sanitized.
  • CSS URLs are filtered.
  • Remote image fetching is SSRF-safe.
  • Local image handling blocks traversal and escape paths.
  • Notebook payloads are constrained by configurable size and workload limits.

Execution is different. If you enable --execute or execute=True, treat the notebook as untrusted code and isolate that runtime yourself.

Documentation

Development

Run the test suite:

pytest

Build docs locally:

pip install -e ".[docs]"
sphinx-build -b html docs docs/_build/html

The detailed test guide lives in tests/README.md.

License

MIT

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

nb2wb-0.3.0.tar.gz (89.1 kB view details)

Uploaded Source

Built Distribution

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

nb2wb-0.3.0-py3-none-any.whl (100.9 kB view details)

Uploaded Python 3

File details

Details for the file nb2wb-0.3.0.tar.gz.

File metadata

  • Download URL: nb2wb-0.3.0.tar.gz
  • Upload date:
  • Size: 89.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nb2wb-0.3.0.tar.gz
Algorithm Hash digest
SHA256 1a869ec8034342c1368b97deae06589572b9bf4ae35b572b47afea38dda0fdac
MD5 567f5d49baadd318b01bf6247b1a9d57
BLAKE2b-256 d1a9098c57b77d7a2ec7884d68afd34f0126b727e51e289ef2e6b9938f0df991

See more details on using hashes here.

Provenance

The following attestation bundles were made for nb2wb-0.3.0.tar.gz:

Publisher: publish.yml on the-palindrome/nb2wb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nb2wb-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: nb2wb-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 100.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nb2wb-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f258ac84af8cd238db3a142b80546fd2e534fd226a1e8fb02d27cb096482cc2e
MD5 5f5b2d702a6dd03342d76d3621a81c1f
BLAKE2b-256 f9c5b6db8711f8b1025e50a8214f9d4f5d75683c115ee1cda8e7bbff7d8abdb7

See more details on using hashes here.

Provenance

The following attestation bundles were made for nb2wb-0.3.0-py3-none-any.whl:

Publisher: publish.yml on the-palindrome/nb2wb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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