Skip to content

Instantly share code, notes, and snippets.

@rtpg
Created September 26, 2016 01:00
Show Gist options
  • Save rtpg/4eb757c2c71ab20946bbd8156cd05332 to your computer and use it in GitHub Desktop.
Save rtpg/4eb757c2c71ab20946bbd8156cd05332 to your computer and use it in GitHub Desktop.
Carmack Plan File Generator
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Easy EPUB generation\n",
"=====================\n",
" \n",
" This is a quick script I use to build e-books for my Kindle based off of some content I have. Sometimes it's blogs, sometimes it's some text files I have lying about. It's usually simple HTML that I can easily throw into a book.\n",
" \n",
" Feel free to use this for your own needs! Some more explanation in this [blog post](http://127.0.0.1:4000/2016/09/17/make-an-ebook.html)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get the Content\n",
"=============\n",
"\n",
" Carmack's plan files can be found at [this Github repo](https://github.com/ESWAT/john-carmack-plan-archive). I use the `by_day` files, and will separate the e-book such that each day is its own chapter. I put those files into the `build/` directory"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Generate e-Book Content Blocks\n",
"========\n",
"\n",
"Using the wonderful [ebooklib](https://github.com/aerkalov/ebooklib/). \n",
"\n",
"Building a chapter per day of notes"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import os\n",
"\n",
"import markdown2\n",
"from ebooklib import epub\n",
"\n",
"build_dir = \"build/\"\n",
"\n",
"def make_chapter(filename):\n",
" # example filename : 'johnc_plan_19960218.txt'\n",
" date_str = filename.split('_')[2].split('.')[0]\n",
" # 19960218 -> 1996-02-18\n",
" date_str = date_str[:4] + \"-\" + date_str[4:6] + \"-\" + date_str[6:]\n",
" with open(build_dir + filename, 'r', errors='ignore') as f:\n",
" content = f.read()\n",
" \n",
" title = date_str\n",
" \n",
" chapter = epub.EpubHtml(\n",
" title=title, # this is what will show up in the TOC\n",
" file_name=filename, \n",
" lang='en'\n",
" )\n",
" chapter.content = '<body><h3>' + date_str +'</h3>' + markdown2.markdown(content) + '</body>'\n",
"\n",
" return chapter\n",
"\n",
"\n",
"chapters = [\n",
" make_chapter(filename) for filename in os.listdir(build_dir) if filename != '.DS_Store' # sigh\n",
"]\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Building the Book\n",
"========\n",
"\n",
"Now that you have the book chapters, time to bind them all together and produce the book!\n",
"\n",
"Here we're just setting up the metadata and the chapter ordering. If you're building something fancier, you'll also want to do something like create a cover or re-order chapters. Check the `ebooklib` documentation for some good ideas.\n"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# create book object\n",
"book = epub.EpubBook()\n",
"\n",
"# set metadata\n",
"book.set_identifier('carmack_plan_file')\n",
"book.set_title(\"John Carmack's Plan Files (1996-2010)\")\n",
"book.set_language('en')\n",
"book.add_author('John Carmack')\n",
"\n",
"# add the chapters themselve\n",
"for chapter in chapters:\n",
" book.add_item(chapter)\n",
" \n",
"# world's most basic CSS. Work's fine for Kindle\n",
"style = 'BODY {color: white;}'\n",
"nav_css = epub.EpubItem(uid=\"style_nav\", file_name=\"style/nav.css\", media_type=\"text/css\", content=style)\n",
"book.add_item(nav_css)\n",
"\n",
"# set the table of contents\n",
"book.toc = chapters\n",
"# the spine defines the reading order. Here we'll define it as the chapters from before\n",
"book.spine = ['nav'] + chapters\n",
"\n",
"# add default NCX and Nav file\n",
"book.add_item(epub.EpubNcx())\n",
"book.add_item(epub.EpubNav())\n",
"\n",
"# finally, write book to file\n",
"epub.write_epub('final.epub', book, {})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment