Simplifies CLI commands and streamlines build process

Refactors the CLI to streamline command usage, making it more intuitive.
It simplifies the build process by introducing default behaviors
and removing unnecessary format specifications. Also introduces 'pdf' command
to build the book in PDF format.
This change enhances the user experience and improves the overall workflow.
This commit is contained in:
Vijay Janapa Reddi
2025-08-26 00:47:47 +02:00
parent 39c58c30b6
commit 80ff71c9c2
2 changed files with 107 additions and 79 deletions

119
binder
View File

@@ -3024,16 +3024,18 @@ This is an ACADEMIC TEXTBOOK release. Please format as:
fast_table.add_column("Description", style="white", width=30)
fast_table.add_column("Example", style="dim", width=30)
fast_table.add_row("preview <chapter[,ch2,...]>", "Build and preview chapter(s)", "./binder preview intro,ops")
fast_table.add_row("build <format>", "Build complete book", "./binder build html")
fast_table.add_row("build [chapter[,ch2,...]]", "Build book or chapter(s) (HTML)", "./binder build intro,ops")
fast_table.add_row("preview [chapter[,ch2,...]]", "Preview book or chapter(s)", "./binder preview intro")
fast_table.add_row("pdf [chapter[,ch2,...]]", "Build book or chapter(s) (PDF)", "./binder pdf intro")
full_table = Table(show_header=True, header_style="bold blue", box=None)
full_table.add_column("Command", style="blue", width=35)
full_table.add_column("Description", style="white", width=30)
full_table.add_column("Example", style="dim", width=30)
full_table.add_row("build <html|pdf|epub|both>", "Build complete book", "./binder build pdf")
full_table.add_row("preview-full [format]", "Preview complete book", "./binder preview-full")
full_table.add_row("build", "Build entire book (HTML)", "./binder build")
full_table.add_row("preview", "Preview entire book", "./binder preview")
full_table.add_row("pdf", "Build entire book (PDF)", "./binder pdf")
full_table.add_row("publish", "Deploy website updates (no release)", "./binder publish")
full_table.add_row("release", "Create formal textbook release", "./binder release")
@@ -3063,7 +3065,7 @@ This is an ACADEMIC TEXTBOOK release. Please format as:
shortcuts_table.add_row("b", "build")
shortcuts_table.add_row("p", "preview")
shortcuts_table.add_row("pf", "preview-full")
shortcuts_table.add_row("pdf", "pdf")
shortcuts_table.add_row("c", "clean")
shortcuts_table.add_row("ch", "check")
shortcuts_table.add_row("s", "switch")
@@ -3086,12 +3088,14 @@ This is an ACADEMIC TEXTBOOK release. Please format as:
# Pro Tips
examples = Text()
examples.append("🎯 Power User Examples:\n", style="bold magenta")
examples.append(" ./binder p intro,ml_systems ", style="cyan")
examples.append("# Preview multiple chapters\n", style="dim")
examples.append(" ./binder b pdf ", style="cyan")
examples.append("# Build complete PDF book\n", style="dim")
examples.append(" ./binder b both ", style="cyan")
examples.append("# Build both HTML and PDF\n", style="dim")
examples.append(" ./binder build intro,ml_systems ", style="cyan")
examples.append("# Build multiple chapters (HTML)\n", style="dim")
examples.append(" ./binder pdf intro ", style="cyan")
examples.append("# Build single chapter as PDF\n", style="dim")
examples.append(" ./binder preview ", style="cyan")
examples.append("# Preview entire book\n", style="dim")
examples.append(" ./binder pdf ", style="cyan")
examples.append("# Build entire book as PDF\n", style="dim")
examples.append(" ./binder c ", style="cyan")
examples.append("# Clean all artifacts\n", style="dim")
examples.append(" ./binder st ", style="cyan")
@@ -3939,9 +3943,10 @@ def main():
# Enhanced command mapping with aliases
command_aliases = {
# New short aliases
'b': 'build',
'p': 'preview',
'pf': 'preview-full',
'p': 'preview',
'pdf': 'pdf',
'c': 'clean',
'ch': 'check',
's': 'switch',
@@ -3951,7 +3956,12 @@ def main():
'se': 'setup',
'pu': 'publish',
'r': 'release',
'h': 'help'
'h': 'help',
# Backward compatibility aliases
'build-full': 'build', # ./binder build-full -> ./binder build
'preview-full': 'preview', # ./binder preview-full -> ./binder preview
'pf': 'preview', # Keep existing pf shortcut
}
# Apply aliases
@@ -3961,49 +3971,60 @@ def main():
# Handle commands
try:
if command == "build":
if len(sys.argv) < 3:
console.print("[red]❌ Usage: ./binder build <html|pdf|epub|both>[/red]")
console.print("[dim]Examples: ./binder build html, ./binder build pdf[/dim]")
return
binder.show_symlink_status()
format_type = sys.argv[2]
if format_type not in ["html", "pdf", "epub", "both"]:
console.print("[red]❌ Format must be 'html', 'pdf', 'epub', or 'both'[/red]")
return
# Always build full book
binder.build_full(format_type)
if len(sys.argv) < 3:
# No target specified - build entire book in HTML
console.print("[green]🏗️ Building entire book (HTML)...[/green]")
binder.build_full("html")
else:
# Chapter specified - build specific chapter(s)
chapters = sys.argv[2]
console.print(f"[green]🏗️ Building chapter(s): {chapters}[/green]")
if ',' in chapters:
# Multiple chapters - build them together
chapter_list = [ch.strip() for ch in chapters.split(',')]
binder.build_multiple(chapter_list, "html")
else:
# Single chapter - build it
binder.build_multiple([chapters], "html")
elif command == "preview":
binder.show_symlink_status()
if len(sys.argv) < 3:
console.print("[red]❌ Usage: ./binder preview <chapter[,chapter2,...]>[/red]")
console.print("[dim]Examples: ./binder preview intro, ./binder preview intro,ml_systems[/dim]")
return
binder.show_symlink_status()
chapters = sys.argv[2]
if ',' in chapters:
# Multiple chapters - build them together
chapter_list = [ch.strip() for ch in chapters.split(',')]
binder.build_multiple(chapter_list, "html")
# No target specified - preview entire book
console.print("[blue]🌐 Previewing entire book...[/blue]")
binder.preview_full("html")
else:
# Single chapter - use existing preview
binder.preview(chapters)
# Chapter specified - preview specific chapter(s)
chapters = sys.argv[2]
console.print(f"[blue]🌐 Previewing chapter(s): {chapters}[/blue]")
if ',' in chapters:
# Multiple chapters - build them together then preview
chapter_list = [ch.strip() for ch in chapters.split(',')]
binder.build_multiple(chapter_list, "html")
else:
# Single chapter - use existing preview
binder.preview(chapters)
elif command == "build-full":
elif command == "pdf":
binder.show_symlink_status()
format_type = sys.argv[2] if len(sys.argv) > 2 else "html"
if format_type not in ["html", "pdf", "both"]:
console.print("[red]❌ Format must be 'html', 'pdf', or 'both'[/red]")
return
binder.build_full(format_type)
if len(sys.argv) < 3:
# No target specified - build entire book as PDF
console.print("[red]📄 Building entire book (PDF)...[/red]")
binder.build_full("pdf")
else:
# Chapter specified - build specific chapter(s) as PDF
chapters = sys.argv[2]
console.print(f"[red]📄 Building chapter(s) as PDF: {chapters}[/red]")
if ',' in chapters:
# Multiple chapters - build them together as PDF
chapter_list = [ch.strip() for ch in chapters.split(',')]
binder.build_multiple(chapter_list, "pdf")
else:
# Single chapter - build as PDF
binder.build_multiple([chapters], "pdf")
elif command == "preview-full":
binder.show_symlink_status()
format_type = sys.argv[2] if len(sys.argv) > 2 else "html"
if format_type not in ["html", "pdf", "both"]:
console.print("[red]❌ Format must be 'html', 'pdf', or 'both'[/red]")
return
binder.preview_full(format_type)
elif command == "clean":
binder.show_symlink_status()

View File

@@ -11,17 +11,23 @@ The **Book Binder** is a self-contained, lightning-fast development CLI for the
# Welcome and overview
./binder hello
# Build a single chapter
./binder build intro html
# Build a single chapter (HTML)
./binder build intro
# Build multiple chapters together
./binder build intro,ml_systems html
# Build multiple chapters together (HTML)
./binder build intro,ml_systems
# Preview a chapter (builds and opens in browser)
./binder preview intro
# Build the complete book
./binder build * pdf
# Build the complete book (HTML)
./binder build
# Build the complete book (PDF)
./binder pdf
# Build a single chapter (PDF)
./binder pdf intro
# Publish the book
./binder publish
@@ -42,25 +48,25 @@ chmod +x binder
## Command Reference
### ⚡ Fast Chapter Commands
### ⚡ Core Commands
Fast builds focus on individual chapters with minimal overhead, perfect for development and iteration.
Intuitive commands that work on both individual chapters and the entire book.
| Command | Description | Example |
|---------|-------------|---------|
| `build <chapter[,ch2,...]> <format>` | Build one or more chapters | `./binder build intro,ml_systems html` |
| `preview <chapter>` | Build and preview a chapter | `./binder preview ops` |
| `build [chapter[,ch2,...]]` | Build book or chapter(s) in HTML | `./binder build intro,ml_systems` |
| `preview [chapter[,ch2,...]]` | Preview book or chapter(s) | `./binder preview ops` |
| `pdf [chapter[,ch2,...]]` | Build book or chapter(s) in PDF | `./binder pdf intro` |
**Supported formats**: `html`, `pdf` (format is required)
**Smart defaults**: No target = entire book, with target = specific chapter(s)
### 📚 Full Book Commands
Full builds render the complete book with all chapters, parts, and cross-references.
### 📚 Full Book Examples
| Command | Description | Example |
|---------|-------------|---------|
| `build * <format>` | Build complete book | `./binder build * pdf` |
| `preview-full` | Preview complete book | `./binder preview-full` |
| `build` | Build complete book (HTML) | `./binder build` |
| `preview` | Preview complete book | `./binder preview` |
| `pdf` | Build complete book (PDF) | `./binder pdf` |
| `publish` | Build and publish book | `./binder publish` |
### 🔧 Management Commands
@@ -78,22 +84,21 @@ Full builds render the complete book with all chapters, parts, and cross-referen
### 🚀 Shortcuts
All commands have single-letter shortcuts:
All commands have convenient shortcuts:
| Shortcut | Command |
|----------|---------|
| `b` | `build` |
| `p` | `preview` |
| `pf` | `preview-full` |
| `pt` | `publish-trigger` |
| `pub` | `publish` |
| `se` | `setup` |
| `he` | `hello` |
| `pdf` | `pdf` |
| `c` | `clean` |
| `ch` | `check` |
| `s` | `switch` |
| `st` | `status` |
| `l` | `list` |
| `he` | `hello` |
| `se` | `setup` |
| `pu` | `publish` |
| `h` | `help` |
## Chapter Names
@@ -172,9 +177,9 @@ When called with arguments, `publish` triggers the GitHub Actions workflow direc
```bash
# Development workflow
./binder preview intro # Preview a chapter
./binder build - html # Build complete HTML
./binder build - pdf # Build complete PDF
./binder publish # Publish to the world
./binder build # Build complete HTML
./binder pdf # Build complete PDF
./binder publish # Publish to the world
```
### After Publishing:
@@ -196,12 +201,14 @@ When called with arguments, `publish` triggers the GitHub Actions workflow direc
The binder supports building multiple chapters together in a single Quarto render command:
```bash
# Old behavior: Sequential builds (slower)
# ./binder build intro # Build intro alone
# ./binder build ml_systems # Build ml_systems alone
# Build multiple chapters together (HTML)
./binder build intro,ml_systems
# New behavior: Unified build (faster)
./binder build intro,ml_systems html # Build both together
# Build multiple chapters together (PDF)
./binder pdf intro,ml_systems
# Preview multiple chapters together
./binder preview intro,ml_systems
```
**Benefits:**