Created
October 7, 2025 23:07
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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