LyX to Kindle Converter
Version 0.0.2, updated infra-alpha
By Steve Litt


Table of Contents for this Documentation

License

The LyX to Kindle Converter software is licensed with the Open Source MIT license. This documentation is licensed with the same license. Here's the license:

Copyright (C) 2011 by Steve Litt

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Warning: Use the Star Environments

Warning: In your LyX file you MUST use Chapter*, Section*, Subsection*, etc. If you try to use the forms without the stars, it will currently error out. Consider this a bug that will be fixed in a later version. Sorry.

Package Contents

This software comes in three parts:
  1. lyx2kindle.py
  2. metadata.kindle.skeleton
  3. CSS file
  4. Sample initial HTML file for front matter
  5. HTML documentation

System Requirements

**: The LyX to Kindle converter was written on a Linux system and tested only on Linux. Given the portable nature of Python, I have no reason to believe that it wouldn't also work on Windows or OS/x. Slight modifications might (or might not) be needed.

Purpose

The LyX to Kindle converter is designed to convert a LyX authored book into a Kindle flowing-text book, acceptable by Amazon as a Kindle book. This means the finished product has exactly one Cover page, accessible with Kindle's title button or Goto->Cover, a table of contents accessible within the book or TOC view button, and an NCX view. It's built to be a one command total converter.

As a practical matter this infra-alpha quality software has two purposes:
  1. Produce files close enough that with some hand tweaking you can easily turn them into a Kindle book.
  2. Serve as a platform for discussions on the LyX to Kindle conversion process in order to produce better conversion software.

Quality

This is infra-alpha quality code. It's throwaway code. It was produced as a second stab at the LyX to Kindle conversion. It's been improved since version 0.0.1 My time prioritization was 95% learning Kindle and writing the code, and 5% software engineering standards. That's just fine because at 523 lines of code, including comments, it can be totally rewritten or refactored in a couple days. In the meantime, it serves as a platform for discussions on what's really needed, and it can help people create simple Kindle books, either all by itself, or with some manual tweaking of its output and rerunning kindlegen.

Version 0.0.2 has one huge kludge: The  putlabelsfirst() subroutine puts <a> type labels ahead of the <h?> headlines they represent. This is a good thing because this complies with the Kindle specs, as opposed to putting them between <h?> and </h?>, which is against Kindle standards and creates a bug where a page looks different depending on whether you page forward to it or jump to it via the TOC. So this is a good thing. However, publabelsfirst() was written in 20 minutes as a simple line-rearranger that depends on the line breaks issued by eLyXer, so it weds lyx2kindle.py to eLyXer, and also means lyx2kindle.py will break if eLyXer changes its linefeeds, even if its HTML remains functionally identical. It is intended that in a later version putlabelsfirst() will be rewritten as an HTML tag parser, at which time it will depend on the meaning of the HTML, not the linefeed structure.

No discussion of quality is complete without mentioning Amazon's admonition that the only guaranteed way of creating a Kindle MOBI file is with kindlegen. There are plenty of other ways to do it, but kindlegen is the official method.

How It Works

It's amusing that this "LyX to Kindle Converter" is a 523 line program (comments included) calling the 11K line eLyXer LyX to HTML converter and the who knows how complex kindlegen HTML+NCX+OPF to MOBI converter. The LyX to Kindle Converter is primarily a postprocessor for HTML produced by eLyXer, in order to make that HTML acceptable to kindlegen, and to produce NCX and OPF files. However, because the LyX to Kindle Converter also runs eLyXer and kindlegen, it's a one-command complete LyX to Kindle Converter, and to the casual eye it might look like the whole thing. But it just looks that way :-)

The following diagram illustrates the high level conversion of a LyX document to a Kindle-valid MOBI:
lyx2kindle process diagram

In order to use this program, the program spawns elyxer as:
elyxer --nofooter --css whatever.css myfile.lyx temp1.html
That means that on your machine, the eLyXer program must be called as elyxer, not elyxer.py nor /home/myuid/elyxer-1.2.3/elyxer.py, and it must be on the executable path. In Linux or BSD (OS/x) the simplest way to do that is with a symlink. For Windows, I leave it as an exercise for the reader.

The same is true of kindlegen. If the Windows version is called kindlegen.exe, it should still work, although as I mentioned the LyX to Kindle converter has never been run or tested on Windows.

The CSS File

Whatever paragraph environments you use in your LyX documents must be defined in your CSS file. The CSS file defines the appearance of your Kindle eBook. A sample CSS file has been included with your download.

Changes in 0.0.2

This section lists the changes in 0.0.2. The preceding version was 0.0.1.

How YOU Run the Program

NOTE: "directory" means the same thing as "folder" on a computer. They're interchangeable terms.
Here's the process for running the program:
  1. Copy metadata.to_kindle.skeleton to some other name (this example assumes you named it metadata.to_kindle) in the same directory as the LyX document.
  2. Go to the directory with the LyX document.
  3. Fill out all relevent data in metadata.to_kindle
  4. Fill out the initial HTML file, with the name identified in the metadata files. This HTML file contains only the interior of <body></body>, without the <body></body> tags. This HTML will be prepended onto the HTML converted from LyX, and its use is to form your eBook's title page and maybe more, as you choose.
  5. Execute this command:
On my 11K word document the conversion takes less than 2 seconds to run. When it finishes, it tells you the name of the MOBI file. Basically, it will be the same as the OPF file, but with .mobi substituted for .opf.

Of the four steps detailed above, only 3, filling out the relevent data in metadata.to_kindle requires any thought. Read on...

How To Fill In the Metadata File

The metadata file, which for the purposes of this document I call metadata.to_kindle, must be in the same directory as the LyX file. Each book you convert must have a separate metadata file. The metadata file is where you define three types of information:
  1. Metadata available in the Kindle book
  2. Info necessary for the conversion
  3. Info about labels in the LyX source document
The following is the skeleton file for 0.0.2:

<wholething>
<!-- metadata.kindle 0.0.2 -->
<!-- User defined Kindle conversion constants -->
<!-- Intended to be maintained by the human user -->
<!-- Each book must have its own metadata.kindle -->


<!-- Title, Author and Date -->
<!-- Replace tokens with real metadata to override LyX provided metadata -->
<!-- As of 0.0.2, these cannot be set within LyX -->
<title>Your Books Title</title>
<author>Yourlastname, Yourfirstname</author>
<date>mm/dd/yyyy</date>

<!-- Insert metadata between open and close tags -->
<!--  or comment out the open/close pair. -->
<publisher></publisher>
<subject>A short description or list of keywords </subject>
<description>Longer description, several sentences to several paragraphs. All on one line unless you really want linebreaks in the book description.</description>

<!-- UID necessary for Kindle acceptance. Use ISBN if you have one -->
<!-- Otherwise use something unique within all books -->
<uid>ISBN or other unique book identifier</uid>

<!-- Following filenames are necessary for conversion. -->
<!-- Conversion will fail without them. -->
<!-- Or at least the book won't be acceptable -->
<!-- Fill in each filename between the start and end tags -->
<!-- They don't have to be similarly named,
<!--  but it's easier to remember if they are. -->
<!-- Comment out any that aren't used -->
<lyxfile>mybook.lyx</lyxfile>
<cssfile>mybook.css</cssfile>
<htmlfile>mybook.html</htmlfile>
<coverfile>mybook_cover.jpg</coverfile>
<opffile>mybook.opf</opffile>
<ncxfile>mybook.ncx</ncxfile>

<!-- Following labels must match labels for -->
<!--  Startup Page, TOC Page and Beginning Page -->
<!--  The postprocessor puts thes in the <guide> section of the opf -->
<!--  These must match the labels in the LyX file -->
<!--  See http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.6 -->
<!--  Note this converter has no hyphen in "guidecopyrightpage" -->
<!-- Comment out any you don't use. -->
<guide opftype="toc" lyxlabel="guidetoc" kindlegotoname="Table of Contents"/>
<guide opftype="start" lyxlabel="guidestart" kindlegotoname="Startup Page"/>
<guide opftype="text" lyxlabel="guidetext" kindlegotoname="Beginning of actual story"/>

<guide opftype="copyright-page" lyxlabel="guidecopyrightpage" kindlegotoname="Copyright"/>
<guide opftype="preface" lyxlabel="guidepreface" kindlegotoname="The Troubleshooters.Com Way"/>
<!-- <guide opftype="dedication" lyxlabel="guidededication" kindlegotoname="Dedication"/> -->
<!-- <guide opftype="title-page" lyxlabel="guidetitlepage" kindlegotoname="Title Page"/> -->



<!-- Following flags control conversion. -->
<!-- These are currently (0.0.2) untested and might not work. Leave them at yes. -->
<makehtml>yes</makehtml>
<postprocesshtml>yes</postprocesshtml>
<makencx>yes</makencx>
<makeopf>yes</makeopf>
<dokindlegen>yes</dokindlegen>

<!-- Filename of html code that gets prepended onto the LyX converted HTML -->
<inithtml>inithtml.htinit</inithtml>

<!-- Label in LyX file where conversion begins -->
<!-- Everything in the LyX file before label doesnt go in .mobi -->
<!-- Not yet implemented in 0.0.2, but on todo list -->
<startlabel>startlabel<startlabel>

</wholething>

In the preceding, tags <title>, <author> and <date>  are the book's Title, Author and Date environments respectively. Unlike 0.0.1, in 0.0.2 this data cannot be set within the LyX file.

Other book metadata follows -- the publisher, subject, description, unique ID (use your ISBN if you have one). After that other metadata comes filenames required to create the book: <lyxfile>, <cssfile>, <htmlfile>, <coverfile>, <opffile> and <ncxfile>. In each case, insert the filename between the respective begin and end tags.

Next comes the metadata for guides. Guides are the facility by which you can click the Goto button on your kindle and get a list of locations. Guides are by far the most complex part of filling out the metadata file, and you must fill out at least opftypes toc and start or Amazon will not accept your book for sale. In order to have a half a chance to understand guides, please take a look at this document now:

http://idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.6

The referenced document lists all the types that can go in a guide: cover, title-page, toc, index, glossary, acknowledgements, bibliography, colophon, copyright-page, dedication, epigraph, foreword, loi, lot, notes, preface, and text. In addition to those,  Kindle seems to support one called "start". Cover is definitely required, and I think start and text might be required also. The rest can be used as desired.

Here's one from my metadata file:
<guide opftype="text" lyxlabel="guidetext" kindlegotoname="Beginning of actual story"/>
Here's the explanation:
I recommend you change only the kindlegotoname attribute, leaving the others as they are (and using the lyxlabel attribute as this item's location label in LyX).

You must delete or comment out the guide items that you don't use. Comments for your metadata file are the same as any HTML/XML comments, begin the comment with <!-- and end it with -->.

You may need to use other types than are in the skeleton metadata file. That will not work in the current lyx2kindle. Note that this is a feature defect in the lyx2kindle program and will be fixed on later versions. Later versions will allow you to insert any valid guide type.

After the list of <guide> tags in the metadata file comes the final section, which turns on and off various processes in lyx2kindle.py. This feature has not been tested, and for the time being I'd leave them all at "yes". But if you want to turn one off, change it to "no".

New to 0.0.2 are <inithtml> and <startlabel>. <inithtml> names the file containing HTML for the title page and perhaps other frontmatter that will be bolted onto the front of the book. <startlabel>, which does nothing in 0.0.2, will, in later versions, names a LyX document label that defines how much of the front of the LyX document is not transferred to the book, so you can replace LyX frontmatter with the HTML named by <inithtml>

Program Limitations

This program was built as a proof of concept to engender conversations about the kind of LyX to Kindle conversion we want. It works in only a limited set of circumstances:
The good news is, with the possible exception of master/child documents, none of these would be difficult to fix. Most are a matter of modifying lyx2kindle.py, and I can do those time permitting. Some might involve changes to eLyXer, and the eLyXer project headed by Alex Fernandez.

Improvements

While this software is young I'd prefer small improvements be submitted to me, in order to keep one version of the software for the time being. Large improvements should be made by you and then maybe we can merge the two together. At some point, when the software's a little more stable, I anticipate better programmers than me taking over this project.