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
nb2wb report.ipynb --verbose

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
GEMINI_API_KEY=... wb2nb article.html --ocr-pipeline gemini --model gemini-2.5-flash --verbose

OpenAIOCRPipeline and GeminiOCRPipeline fetch public remote http/https image URLs.

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}},
    verbose=True,
)

You can also enable package logging explicitly:

import nb2wb

nb2wb.configure_logging(verbose=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.2.tar.gz (93.4 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.2-py3-none-any.whl (106.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nb2wb-0.3.2.tar.gz
  • Upload date:
  • Size: 93.4 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.2.tar.gz
Algorithm Hash digest
SHA256 5cffb81bb8c2ab7f5ab44cf1fc2d82f647ed2767807fed3f0f97025ca610e7fd
MD5 17690c04a90f3547c6562cfa5cd96b26
BLAKE2b-256 83818d7dd28c0bab55c597a82f95ad7db0b98fb3bbd1773a43cf5cd4fff7c5ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for nb2wb-0.3.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: nb2wb-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 106.0 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 424a2892868aa870695aca0a01040586864871a7cde603d60038f0241627a119
MD5 113f379f3b379250274732d960266b60
BLAKE2b-256 13d800b8802da049814e01658f9df1f40f148605405db5391028d483dd4e0ca8

See more details on using hashes here.

Provenance

The following attestation bundles were made for nb2wb-0.3.2-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