{"id":1975,"date":"2018-04-05T17:13:39","date_gmt":"2018-04-05T16:13:39","guid":{"rendered":"https:\/\/www.andyjohnson.uk\/?p=1975"},"modified":"2018-04-05T17:13:39","modified_gmt":"2018-04-05T16:13:39","slug":"notes-on-generating-printable-keras-documentation","status":"publish","type":"post","link":"https:\/\/andyjohnson.uk\/blog\/2018\/04\/05\/notes-on-generating-printable-keras-documentation\/","title":{"rendered":"Notes on generating printable Keras documentation"},"content":{"rendered":"<p>It started when I wanted to print the documentation for <a href=\"https:\/\/keras.io\/\">Keras<\/a> so that I could peruse it on a train journey. Obviously this is a weird thing to want to do in at least two different ways, but sometimes you&#8217;ve just got to have ink on paper.<\/p>\n<p>The online HTML documentation for Keras is built from extended <a href=\"https:\/\/en.wikipedia.org\/wiki\/Markdown\">markdown<\/a> files, and can (in theory &#8211; hence this post) also be used to generate a PDF file. However, when I tried it there turned out to be a few &#8220;issues&#8221;, so I thought I&#8217;d document this in case anyone (including future-me) wants to go on the same journey. I&#8217;m not going to document the process of discovery I went though, just what seems to be the easiest route to getting a printable PDF. Note that these instructions are for Windows.<\/p>\n<p>Ready? Lets go.<\/p>\n<h2>Part 1: Install the prerequisites.<\/h2>\n<p>1. Install <a href=\"https:\/\/www.python.org\/\">Python 3.6<\/a> if you don&#8217;t already have it.<\/p>\n<p>2. Download and install <a href=\"http:\/\/www.mkdocs.org\/#installation\">mkdocs<\/a>. I used pip3 to do this. It will install itself into &lt;user&gt;\\AppData\\Local\\Pandoc and you&#8217;ll need to add this to your path.<\/p>\n<p>3. Download and install\u00a0<a href=\"https:\/\/github.com\/jgrassler\/mkdocs-pandoc\">mkdocs-pandoc<\/a>.<\/p>\n<p>4. Download and install <a href=\"https:\/\/miktex.org\/\">MiKTeX<\/a>. mkdocs-pandoc emits LaTeX and expects you to have a way to convert this to PDFusing <span style=\"font-family: 'courier new', courier, monospace;\">pdflatex.exe<\/span>, which is included in MiKTeX (and probably other TeX distributions). Choosing the option to automatically install missing packages will save time later. Add\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64<\/span> to your path.<\/p>\n<p>5. Download the <a href=\"https:\/\/github.com\/keras-team\/keras\">Keras repo<\/a> from Github and unzip <span style=\"font-family: 'courier new', courier, monospace;\">keras-master.zip<\/span>. You&#8217;ll need this because it includes the documentation source files.<\/p>\n<h2>Part 2: Generate the PDF<\/h2>\n<p>1. In an command window, go to <span style=\"font-family: 'courier new', courier, monospace;\">keras-master\/docs<\/span>. You&#8217;ll see a <span style=\"font-family: 'courier new', courier, monospace;\">readme.md<\/span> file containing instructions for building the docs. We&#8217;ll be following this outline but adding some workarounds.<\/p>\n<p>2. Run\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">python autogen.py<\/span> and wait for errors to occur:<\/p>\n<blockquote>\n<p style=\"text-align: left;\"><span style=\"font-family: 'courier new', courier, monospace; font-size: 10pt;\">Traceback (most recent call last):<\/span><br \/>\n<span style=\"font-family: 'courier new', courier, monospace; font-size: 10pt;\">File &#8220;autogen.py&#8221;, line 559, in &lt;module&gt; readme = read_file(&#8216;..\/README.md&#8217;) File &#8220;autogen.py&#8221;, line 532, in read_file return f.read() File &#8220;C:\\Program Files\\Python36\\lib\\encodings\\cp1252.py&#8221;, line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: &#8216;charmap&#8217; codec can&#8217;t decode byte 0x81 in position 7411: character maps to &lt;undefined&gt;<\/span><\/p>\n<\/blockquote>\n<p>This is happening because <span style=\"font-family: 'courier new', courier, monospace;\">autogen.py<\/span> is trying to read files that don&#8217;t match the default file encoding. We&#8217;ll need to hack <span style=\"font-family: 'courier new', courier, monospace;\">autogen.py<\/span>, so open it in an editor ando to the first place that <span style=\"font-family: 'courier new', courier, monospace;\">f.read()<\/span> is called, which for me was line 532. Change the <em>previous<\/em> line from<\/p>\n<blockquote><p><span style=\"font-family: 'courier new', courier, monospace; font-size: 10pt;\">with open(path) as f:<\/span><\/p><\/blockquote>\n<p>to<\/p>\n<blockquote><p><span style=\"font-family: 'courier new', courier, monospace; font-size: 10pt;\">with open(path<strong>, encoding=&#8221;latin1&#8243;<\/strong>) as f:<\/span><\/p><\/blockquote>\n<p>Save <span style=\"font-family: 'courier new', courier, monospace;\">autogen.py<\/span> and run the command again. You should get a similar error on a different line (it was line 563 for me) so fix it the same way. Save <span style=\"font-family: 'courier new', courier, monospace;\">autogen.py<\/span> and run the command yet again. This time it should complete successfully and generate a bunch of markdown files in the <span style=\"font-family: 'courier new', courier, monospace;\">sources<\/span> directory.<\/p>\n<p>3. Run the <span style=\"font-family: 'courier new', courier, monospace;\">mkdocs serve<\/span> command. This does some stuff and starts a local web server. Since this blocks the command window, you&#8217;ll need to start another command window and go to the <span style=\"font-family: 'courier new', courier, monospace;\">docs<\/span> directory.<\/p>\n<p>4. In the new command window, run\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">mkdocs build<\/span>. This generates an html web site in the <span style=\"font-family: 'courier new', courier, monospace;\">site<\/span> directory. This may not be strictly necessary, but its a useful check that things are working.<\/p>\n<p>5. At this point we leave the instructions in <span style=\"font-family: 'courier new', courier, monospace;\">readme.md<\/span> behind. Run the command <span style=\"font-family: 'courier new', courier, monospace;\">mkdocs2pandoc &gt; keras.pd<\/span>. This creates a single large markdown file (<span style=\"font-family: 'courier new', courier, monospace;\">keras.pd<\/span>) that is optimised for generating PDFs.<\/p>\n<p>6. The markdown document has a few problems at this point, which we can rectify by hand-editing it. I used <a href=\"https:\/\/notepad-plus-plus.org\/\">notepad++<\/a> for this.<\/p>\n<ul>\n<li>Change the top-level heading on the first line from <span style=\"font-family: 'courier new', courier, monospace;\">#Home<\/span> to <span style=\"font-family: 'courier new', courier, monospace;\">#Introduction<\/span>.<\/li>\n<li>The markdown document contains a number of HTML\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">&lt;span&gt;<\/span> tags with level five headings on the next line. This causes <span style=\"font-family: 'courier new', courier, monospace;\">pandoc\u00a0<\/span>(see step 7 below) to output the tag&#8217;s alt-text but fail to render the heading correctly. The solution is to add a line between them by using search and replace to replace <span style=\"font-family: 'courier new', courier, monospace;\">&lt;\/span&gt;\\r\\n#####<\/span> with\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">&lt;\/span&gt;\\r\\n\\r\\n#####<\/span>.<\/li>\n<li>The markdown contains HTML <span style=\"font-family: 'courier new', courier, monospace;\">&lt;img&gt;<\/span> tags that <span style=\"font-family: 'courier new', courier, monospace;\">pandoc<\/span>\u00a0won&#8217;t handle. Either remove these manually or (as I did) leave them in and <span style=\"font-family: 'courier new', courier, monospace;\">pandoc<\/span> will render the alt text. Annoying but I can live with it.<\/li>\n<\/ul>\n<p>7. Run the command\u00a0<span style=\"font-family: 'courier new', courier, monospace;\">pandoc &#8211;toc -f markdown+grid_tables+table_captions -V geometry:margin=2.5cm &#8211;pdf-engine=xelatex -o keras.pdf keras.pd<span style=\"font-family: georgia, palatino, serif;\"> .\u00a0<\/span><\/span>You&#8217;ll probably see some warnings: just ignore them. If you chose not to allow MiKTeX to automatically install missing packages then you be asked for permission to install various things as they are needed. The default LaTeX stylesheet renders pages with large margins, so I overrode this by setting them to 2.5 cm (about one inch) &#8211; tweak this according to preference. I also specified <span style=\"font-family: 'courier new', courier, monospace;\">xelatex<\/span> as the PDF engine because the default engine had fatal problems with some Unicode characters in the document. The table of contents defaults to three levels: if you want more detail then add <span style=\"font-family: 'courier new', courier, monospace;\">&#8211;toc-depth=4<\/span> to the command.<\/p>\n<p>At the end of all this, you&#8217;ll see you have a <span style=\"font-family: 'courier new', courier, monospace;\">keras.pdf<\/span> file. Load this into your favourite PDF viewer or print it out according to your preference.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It started when I wanted to print the documentation for Keras so that I could peruse it on a train journey. Obviously this is a weird thing to want to do in at least two different ways, but sometimes you&#8217;ve just got to have ink on paper. The online HTML documentation for Keras is built &hellip; <a href=\"https:\/\/andyjohnson.uk\/blog\/2018\/04\/05\/notes-on-generating-printable-keras-documentation\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Notes on generating printable Keras documentation&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[20,21],"class_list":["post-1975","post","type-post","status-publish","format-standard","hentry","category-development","tag-howto","tag-keras"],"_links":{"self":[{"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/posts\/1975","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/comments?post=1975"}],"version-history":[{"count":0,"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/posts\/1975\/revisions"}],"wp:attachment":[{"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/media?parent=1975"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/categories?post=1975"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andyjohnson.uk\/blog\/wp-json\/wp\/v2\/tags?post=1975"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}