tinypublisher 0.3.2
A tool to make a simple EPUB package.
Requires Python: >=3.9

# tinypublisher

A tool to make a simple epub package easily.

## Installation

```
pip install tinypublisher
```

## Usage

### Quick-Usage

In the following, the `tinypublish` command makes the `test.epub` file from the jpeg file list.

```
% ls examples/foo/*.jpg
examples/foo/00 a.jpg	examples/foo/02 c.jpg	examples/foo/04 e.jpg
examples/foo/01 b.jpg	examples/foo/03 d.jpg

% ls -1 examples/foo/*.jpg | tinypublish test
tinypublisher.builder.INFO: making a build dir
  -- build
tinypublisher.builder.INFO: making a Package Document
  -- build/test/book/package.opf
tinypublisher.builder.INFO: making a Navigation Document
  -- build/test/book/navigation.xhtml
tinypublisher.builder.INFO: copying "examples/foo/00 a.jpg" to
  -- build/test/book/items/examples/foo/00 a.jpg
tinypublisher.builder.INFO: making a page
  -- build/test/book/items/examples/foo/00 a.jpg.xhtml
tinypublisher.builder.INFO: copying "examples/foo/01 b.jpg" to
  -- build/test/book/items/examples/foo/01 b.jpg
tinypublisher.builder.INFO: making a page
  -- build/test/book/items/examples/foo/01 b.jpg.xhtml
tinypublisher.builder.INFO: copying "examples/foo/02 c.jpg" to
  -- build/test/book/items/examples/foo/02 c.jpg
tinypublisher.builder.INFO: making a page
  -- build/test/book/items/examples/foo/02 c.jpg.xhtml
tinypublisher.builder.INFO: copying "examples/foo/03 d.jpg" to
  -- build/test/book/items/examples/foo/03 d.jpg
tinypublisher.builder.INFO: making a page
  -- build/test/book/items/examples/foo/03 d.jpg.xhtml
tinypublisher.builder.INFO: copying "examples/foo/04 e.jpg" to
  -- build/test/book/items/examples/foo/04 e.jpg
tinypublisher.builder.INFO: making a page
  -- build/test/book/items/examples/foo/04 e.jpg.xhtml
tinypublisher.builder.INFO: making a EPUB package
  -- build/test.epub
```

### tinypublish --help

```
usage: tinypublish [-h] [--unzipped] [-c cover-image] [-t title]
                   [-l language-tag] [-a author-name] [--id identifier]
				   [--uuid dns-name] [-s file-list]
                   package-name

A tool to buid a EPUB package easily.

positional arguments:
  package-name          EPUB Package directory and make the file
                        <package-name>.epub

optional arguments:
  -h, --help            show this help message and exit
  --unzipped            make the package unzipped
  -c cover-image, --cover cover-image
                        used for <item properties="cover-image"
						href="<cover-image>"/>
  -t title, --title title
                        if not, <package-name> is used for the book title
  -l language-tag, --language language-tag
                        if not, use the `lang` attribute of the content
						documents. if there is no `lang` attribute, use the
						`os.environ["LANG"]`
  -a author-name, --author author-name
                        used for <dc:creator> element of the package document
  --id identifier       used for <dc:identifier> element of the package document
  --uuid dns-name       if the <identifier> is not specified, use this value for
	                    generate the package unique identifier with
						`uuid5(NAMESPACE_DNS, <dns-name>)`. if both are not
						specified, generated by `uuid4()`
  -s file-list, --spine file-list
                        a tab-separated-values file that each line is the spine
						element for the package. you can also read this list
						from the standard input

File-list format:
    <file-list>  ::= <entry>+
    <entry> ::= <path> [ "\t" <use-nav> [ "\t" <caption> ] ] "\n"
    <use-nav> ::= <index-title> | "-" | ""
    <caption>  ::= <content-caption> | "-"

    <path>
        A path to XHTML, SVG, or image file. The path should be relative to this
        file list.
        That XHTML and SVG files are used as content documents (EPUB 3.2). Other
        media files are embedded in a XHTML file for each. If you want to embed
        that SVG into XHTML, you should add a <content-caption>.
    <index-title>
        Indicates that document linked from a table of contents.
        If it is specified to "-", the title of content document, text contents,
        or the basename of the file is used as the index title.
    <content-caption>
        When the <path>'s media type is image type, this value used as a content
        of figcaption tag of the wrapping XHTML.
        if the <path> points to an SVG and this cell is specified, the SVG is
        embedded in a XHTML file. Then, if it is "-", this value is the SVG's
        title data or the basename of the file.
```

### Example of a file-list format

The following example is a tab-separated-values file (a tab is expressed `[_TAB_]` for visibility):

```
01.png[_TAB_]The first page
02.xhtml
03.svg[_TAB_]-
04.svg[_TAB_][_______TAB________]-
05.jpg[_TAB_]The last page[_TAB_]Goodbye<br/>Sayoonara
```

The first column is the path of the spine content, the second is the title used for the table of content, and the third is the caption for the image content.

This file exists at [tests/assets/spine.tsv](tests/assets/spine.tsv). And you can build this as the following:

```
% tinypublish test -t "my test" -c tests/assets/cover.png -s tests/assets/spine.tsv
```

then the EPUB Package will be made at `tests/assets/build/test.epub`.

#### Package Document

The package document is made at `tests/assets/build/test/book/package.opf`. Its content is the following:

``` xml
  ...
  <manifest>
    <item href="navigation.xhtml" id="navigation" media-type="application/xhtml+xml" properties="nav"/>
    <item href="items/01.png" id="item1" media-type="image/png"/>
    <item href="items/01.png.xhtml" id="item3" media-type="application/xhtml+xml"/>
    <item href="items/02.xhtml" id="item4" media-type="application/xhtml+xml"/>
    <item href="items/03.svg" id="item5" media-type="image/svg+xml"/>
    <item href="items/04.svg.xhtml" id="item7" media-type="application/xhtml+xml"/>
    <item href="items/05.jpg" id="item8" media-type="image/jpeg"/>
    <item href="items/05.jpg.xhtml" id="item10" media-type="application/xhtml+xml"/>
    <item href="items/02.js" id="item11" media-type="application/javascript"/>
    <item href="items/mark3.svg" id="item12" media-type="image/svg+xml"/>
    <item href="items/style.css" id="item13" media-type="text/css"/>
    <item href="items/star2.gif" id="item14" media-type="image/gif"/>
    <item href="items/star1.gif" id="item15" media-type="image/gif"/>
    <item href="items/cover.png" id="item16" media-type="image/png" properties="cover-image"/>
  </manifest>
  <spine>
    <itemref idref="item3"/>
    <itemref idref="item4"/>
    <itemref idref="item5"/>
    <itemref idref="item7"/>
    <itemref idref="item10"/>
  </spine>
  ...
```

Since the third entry (`03.svg`) of the file list doesn't have a caption, `03.svg` is used to the content document. On the other hand the fourth entry (`04.svg`) has a caption (`-`), so `04.svg` is embedded in the spine item `04.svg.xhtml`.

#### Navigation Document

The navigation document is made at `tests/assets/build/test/book/navigation.xhtml`. Its content is the following:

``` html
    ...
    <nav epub:type="toc" id="toc">
      <ol>
        <li><a href="items/01.png.xhtml">The first page</a></li>
        <li><a href="items/03.svg">03.svg: This is a co…</a></li>
        <li><a href="items/05.jpg.xhtml">The last page</a></li>
      </ol>
    </nav>
    ...
```

In the file list, the three entries (`01.png, 03.svg, 05.jpg`) have a index title, so the table of contents have three links to each content document (`01.png.xhtml, 03.svg, 05.jpg.xhtml`). But if no spine content has a index title, like the above quick usage example, then every spine content document will be listed and labeled its filename.

## Future considered

- Make the image layout looks good
  - Using an svg for wrapping an image
- Specify the reading direction
- What to do about handling foreign resources