Metadata-Version: 2.4
Name: nb2wb
Version: 0.2.1
Summary: Write in Jupyter Notebooks. Publish anywhere.
Author: Tivadar Danka
License: MIT
Project-URL: Homepage, https://github.com/the-palindrome/nb2wb
Project-URL: Repository, https://github.com/the-palindrome/nb2wb
Project-URL: Issues, https://github.com/the-palindrome/nb2wb/issues
Keywords: jupyter,substack,latex,converter,technical-writing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Text Processing :: Markup :: HTML
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: nbformat>=5.0
Requires-Dist: nbconvert>=6.0
Requires-Dist: ipykernel>=6.0
Requires-Dist: matplotlib>=3.5
Requires-Dist: Pillow>=9.0
Requires-Dist: Pygments>=2.10
Requires-Dist: PyYAML>=6.0
Requires-Dist: markdown>=3.4
Requires-Dist: unicodeit>=0.7
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: isort; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx>=7.4; extra == "docs"
Requires-Dist: myst-parser>=2.0; extra == "docs"
Requires-Dist: furo>=2024.8.6; extra == "docs"
Dynamic: license-file

# nb2wb

**Write in notebooks. Publish anywhere.**

`nb2wb` converts Jupyter Notebooks and other notebook-style content into publishable HTML for Substack, Medium, and X Articles.

Supported inputs:

- Jupyter notebooks (`.ipynb`)
- Quarto documents (`.qmd`)
- Markdown documents (`.md`)
- in-memory Jupyter notebook payloads (`dict` / `NotebookNode`)

## Documentation

- Detailed docs (Read the Docs): `https://nb2wb.readthedocs.io/`
- Docs source in this repo: `docs/index.md`

## Brief Feature Tour

1. **Load notebook content** from file or in-memory payload.
2. **Optionally execute code cells** (`--execute` / `execute=True`).
3. **Render markdown, math, code, and outputs** into platform-safe HTML fragments.
4. **Convert display math, code, and (optionally) tables to images** for high-fidelity publishing.
5. **Sanitize rich HTML/SVG output** and enforce server-side safety limits.
6. **Wrap output for your target platform** (`substack`, `medium`, `x`).

## Installation

```bash
pip install nb2wb
```

Development install:

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

## Quick Start (CLI)

```bash
nb2wb notebook.ipynb
nb2wb notebook.ipynb -t medium
nb2wb notebook.ipynb -t x
nb2wb notebook.ipynb -o article.html
nb2wb notebook.ipynb --open
nb2wb notebook.ipynb --serve
nb2wb notebook.ipynb --raw -o article_raw.html
nb2wb report.qmd --execute
```

## Quick Start (Python API)

```python
import nb2wb

# Path input via loader helper
payload = nb2wb.load_input_payload("notebook.ipynb")
html = nb2wb.convert(
    payload,
    target="substack",
    config={"latex": {"try_usetex": True}},
)

# In-memory payload input (JSON / JSONB parsed notebook)
html = nb2wb.convert(
    notebook_payload,
    target="substack",
    execute=False,
)

# Raw-mode output (no <head>, toolbar, or JavaScript)
html = nb2wb.convert(
    notebook_payload,
    target="medium",
    raw_mode=True,
)
```

`nb2wb.convert()` is content-only; use `load_input_payload()` (or typed loaders) for filesystem inputs.

## Security at a Glance

`nb2wb` uses a mandatory server-safe conversion pipeline:

- strict HTML/SVG sanitization
- CSS URL sanitization
- SSRF-safe image fetching
- path traversal protection for local files
- notebook size/resource safety limits
- fail-closed behavior for unsafe/unresolvable image sources

Important: enabling execution runs notebook code. Treat `execute=True` workloads as untrusted code and isolate them appropriately.

## Configuration

Use YAML file in CLI:

```bash
nb2wb notebook.ipynb -c config.yaml
```

Or pass dict/object/path in API:

```python
html = nb2wb.convert(notebook_payload, config={"safety": {"max_cells": 1500}})
```

## Read More

- [Feature Tour](docs/feature-tour.md)
- [Getting Started](docs/getting-started.md)
- [CLI Reference](docs/cli-reference.md)
- [Python API](docs/python-api.md)
- [Input Formats](docs/input-formats.md)
- [Configuration](docs/configuration.md)
- [Platforms](docs/platforms.md)
- [Security Model](docs/security.md)
- [FastAPI/API Integration](docs/server-integration.md)
- [Troubleshooting](docs/troubleshooting.md)
- [For Maintainers](docs/for-maintainers.md)

## Development

Run tests:

```bash
pytest
```

Build docs locally:

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

## License

MIT
