Skip to content

Instantly share code, notes, and snippets.

@zuedev
Created October 7, 2025 23:07
Show Gist options
  • Select an option

  • Save zuedev/ca86d93110079730f46ce2fe7b286430 to your computer and use it in GitHub Desktop.

Select an option

Save zuedev/ca86d93110079730f46ce2fe7b286430 to your computer and use it in GitHub Desktop.
Bulk download all D&D 5e books as Markdown files from 5etools. Automatically fetches the book index, loads the Markdown renderer, converts all chapters to .md format, and downloads each book individually. Run in browser console on books.html page.
// Mass Book Markdown Downloader for 5etools
//
// This script automatically downloads all books from the 5etools data directory
// as Markdown files. It loads the necessary rendering library, fetches each book's
// data, converts all chapters to Markdown format, and triggers individual file
// downloads. Each book is saved with its original name as a .md file.
//
// Usage: Paste this script into the browser console on books.html
//
// Mass download all books as Markdown
(async () => {
// Load the RendererMarkdown script if not already loaded
if (typeof RendererMarkdown === 'undefined') {
console.log('Loading RendererMarkdown...');
await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'js/render-markdown.js';
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
// Fetch the books index
const response = await fetch('data/books.json');
const booksData = await response.json();
// Function to download a single book
async function downloadBook(bookInfo) {
try {
console.log(`Downloading: ${bookInfo.name}`);
// Fetch the book data
const bookResponse = await fetch(`data/book/book-${bookInfo.id.toLowerCase()}.json`);
const bookData = await bookResponse.json();
// Convert all chapters to markdown
const markdownContent = bookData.data
.map(chapter => RendererMarkdown.get().render(chapter))
.join("\n\n------\n\n");
// Create and trigger download
const blob = new Blob([markdownContent], { type: 'text/markdown' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${bookInfo.name}.md`;
a.click();
URL.revokeObjectURL(url);
console.log(`✓ Downloaded: ${bookInfo.name}`);
// Small delay to avoid overwhelming the browser
await new Promise(resolve => setTimeout(resolve, 500));
} catch (error) {
console.error(`✗ Failed to download ${bookInfo.name}:`, error);
}
}
// Download all books
for (const book of booksData.book) {
await downloadBook(book);
}
console.log('All downloads complete!');
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment