{{ message }}
mdhtml
Directory actions
More options
Directory actions
More options
mdhtml
Folders and files
"""Generate README.md from a notebook: `nbdev-readme` without quarto. The notebook's stored
outputs are used as found (nothing executes), `hide` cells drop, leading `#|` directive lines
strip, a leading raw frontmatter message is consumed, and images embedded in outputs or
attachments are extracted to a `{stem}_files/` directory the command owns and clears. A
do-not-edit comment goes on top unless `head` replaces or suppresses it."""
import sys, shutil, tomllib
from pathlib import Path
from fastcore.script import call_parse
from aidialog.dialog import Dialog, dlg2md, sraw
from aidialog.ipynb import read_ipynb
from .md import md2gfm
__all__ = ["main"]
_WARN = "<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->"
def _nbdev_cfg(start):
"Project root and `[tool.nbdev]` table of the nearest pyproject.toml carrying one, else `start` and empty"
for d in [start, *start.parents]:
f = d/"pyproject.toml"
if not f.exists(): continue
if (t := tomllib.loads(f.read_text(encoding="utf-8")).get("tool", {}).get("nbdev")) is not None: return d, t
return start, {}
def _strip_directives(s):
lines = s.split("\n")
n = 0
while n < len(lines) and lines[n].startswith("#|"): n += 1
return "\n".join(lines[n:]).lstrip("\n")
@call_parse(pos=["file"])
def main(
file: str = None, # Notebook to render (default: the configured `readme_nb` under `nbs_path`)
out: str = None, # Output path (default: README.md at the project root)
head: str = None, # Text placed above the output (default: a do-not-edit comment; pass '' for none)
):
"Create README.md, and a `{stem}_files/` directory of extracted images, from a notebook's stored outputs"
root, cfg = _nbdev_cfg(Path.cwd())
file = Path(file) if file else root/cfg.get("nbs_path", "nbs")/cfg.get("readme_nb", "index.ipynb")
out = Path(out) if out else root/"README.md"
ms = [m for m in read_ipynb(file).messages if not m.has_directive("hide")]
if ms and ms[0].msg_type == sraw and ms[0].content.startswith("---"): ms = ms[1:]
for m in ms: m.content = _strip_directives(m.content)
imgdir = out.parent/f"{out.stem}_files"
shutil.rmtree(imgdir, ignore_errors=True)
res = md2gfm(dlg2md(Dialog(ms)), dest=out, raw=("md", "html"), imgdir=imgdir)
if head is None: head = _WARN
if head: out.write_text(f"{head}\n\n{res}")
for w in res.warnings: print(w, file=sys.stderr)
