Skip to content

Commit

Permalink
resolves asciidoctor#47 stop requiring specific include file scheme
Browse files Browse the repository at this point in the history
support conversion of article documents to a single-chapter file
resolves asciidoctor#205 support special chapters like bibliography
resolves asciidoctor#190 `basedir` now points to spine document directory when processing chapter files
resolves asciidoctor#178 fix image and listing numbers being reset in each chapter
resolves asciidoctor#166 fix xref resolving between sub-includes of chapter files
resolves asciidoctor#151 add support for contentless include files
resolves asciidoctor#136 drop nonstandard `<<chapter#>>` xref syntax and instead support vanilla `<<anchor>>` or `<<file#anchor>>` syntax
require Asciidoctor 1.5.6+
  • Loading branch information
slonopotamus committed Feb 18, 2020
1 parent bfda20b commit 822c69f
Show file tree
Hide file tree
Showing 32 changed files with 1,027 additions and 1,343 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
matrix:
ruby: [jruby, 2.3, 2.4, 2.5, 2.6, 2.7]
platform: [ubuntu-latest, macos-latest, windows-latest]
asciidoctor: [1.5.3, '']
asciidoctor: [1.5.6, '']
exclude:
# kindlegen fails to install on 2.3 on Windows. See https://github.com/asciidoctor/asciidoctor-epub3/pull/213
- ruby: 2.3
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/master[

== Unreleased

* support conversion of article documents to a single-chapter file
* stop requiring specific include file scheme (#47)
* support special chapters like bibliography (#205)
* `basedir` now points to main document directory when processing chapter files (#190)
* fix image and listing numbers being reset in each chapter (#178)
* fix xref resolving between sub-includes of chapter files (#166)
* add support for contentless include files (#151)
* drop nonstandard `<<chapter#>>` xref syntax and instead support vanilla `<<anchor>>` or `<<file#anchor>>` syntax (#136)
* require Asciidoctor 1.5.6+
* do not include current date if `:reproducible:` attribute is set (#203)
* respect `SOURCE_DATE_EPOCH` environment variable for reproducible builds
* fix invalid markup produced for tables with footer (#295)
Expand Down
159 changes: 28 additions & 131 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -136,74 +136,22 @@ The EPUB3 publication, which can be thought of as the “digital master”, is a

An EPUB3 archive is composed of multiple files. The content of each “chapter” is typically stored in a dedicated XHTML file.
Therefore, the {project-name} converter “chunks” the AsciiDoc source document into multiple XHTML files to add to the EPUB3 archive.
While other converters handle this chunking task by automatically slicing up the XHTML output at predetermined heading levels, this converter takes a different approach, outlined next.

=== Composition Rules

There are several rules you must follow to successfully convert your AsciiDoc source documents into an EPUB3 publication archive.
These rules may be loosened in the future, but they are mandatory at the moment.

Rule 1::
Each chapter must begin in a dedicated file that resides at the root of the project.
It must be included into the main document using the AsciiDoc include directive.
The main document, which we call the “spine”, may only contain a document header and a sequence of include directives.
See <<Declaring the Spine>> for details.
+
TIP: The include directive may be used in the chapter files to include other files (even files in other folders).

Rule 2::
Each chapter must start with a document title (i.e., level-0 heading).
The document header must declare an ID that matches the chapter filename (minus its file extension).

Rule 3::
No sections in a chapter may have the same ID as the chapter ID.

Rule 4::
The cross reference (i.e., xref) from one chapter to another must be in the format `+xref:chapter-id#chapter-id[optional reftext]+` (or `+<<chapter-id#chapter-id,optional reftext>>+`).
If you want to reference a section in a chapter, update the fragment (i.e., the value that follows the hash) to match the target section ID.
The reftext is optional since the reftext of the target is used by default.
+
TIP: To assign reference text (i.e., reftext) for a chapter title, set the document attribute `docreftext` in the header for that chapter.
+
TIP: Rule 2 states that the chapter ID must match the basename of the chapter file.
In truth, the chapter ID can be a _derivative of_ the chapter filename.
In that case, an attribute reference can be used to prepend a prefix to an inter-document cross reference.
For example, if you want each chapter file to begin with `chapter-`, you'd write the xref as `+xref:{chapter-prefix}chapter-id#chapter-id[]+`.
You'd then assign an empty value to the `chapter-prefix` attribute when converting to an e-book and `chapter-` for all other formats.

The next section goes into more detail about how to set up the spine document and include the chapter files.

=== Declaring the Spine

The spine (or master document) must be well-formed.
Otherwise, {project-name} will not convert the document properly.
If your AsciiDoc documents are not structured as explained in this section, you'll need to change them.

Asciidoctor uses top-level include directives (i.e., include directives in the master document) to indicate where each chapter split should occur.
The chapter files should begin with an AsciiDoc document header, which consists of an ID, a document title (i.e., level-0 heading), an author name, and a set of attribute entries.
Only the document title is required.

The document title in the chapter file is used as the chapter title and the label for the chapter in the TOC.
The chapter ID, combined with the _.xhtml_ suffix, is used as the filename of the chapter inside the EPUB3 archive (though this could change in the future).
We recommend that you base the filename of the chapter on the chapter ID.

If you don't specify an ID for a chapter, one will be generated automatically from the document title.
The rules for generating a chapter ID from the document title are as follows:

* apply inline formatting, then remove XML elements
* remove the `\&#8217;` character reference (so `John\&#8217;s` becomes `Johns`)
* replace `\&amp;` with the word `and` (so `John \&amp; Jane` becomes `John and Jane`)
* expand all other character references
* lowercase all characters
* replace illegal ID characters with the character defined by the `idseparator` attribute
* prepend the value of the `idprefix` attribute
* prepend an underscore if the ID begins with a number

You can think of the master document as the spine of the book and the include directives the individual items being bound together.
The target of each include directive in the master document is parsed and converted as a separate AsciiDoc document, with certain options and attributes passed down from the master to ensure consistent behavior.
Each resulting XHTML document is then added to the EPUB3 archive as a chapter document and the master document becomes the navigation file (i.e, the table of contents).

Here's an example showing the structure of a spine document:
Like other converters, Asciidoctor EPUB3 handles this chunking task by automatically slicing up the XHTML output at predetermined heading levels.

When `doctype` attribute is set to `book`, each top-level section will become a separate ebook "chapter" file.
This includes preface, bibliography, appendix, etc.

Otherwise, whole document is converted to a single ebook chapter.

You may specify custom chapter filenames by assigning IDs to sections:

[source,asciidoc]
-----
[#custom-chapter-id]
= Chapter
-----

Here's an example showing the structure of a book:

[source,asciidoc]
----
Expand All @@ -214,43 +162,21 @@ Author Name
\ifndef::ebook-format[:leveloffset: 1]
//...and so on
\include::chapter-one.adoc[]
\include::chapter-two.adoc[]
\include::chapter-three.adoc[]
----

IMPORTANT: The spine document cannot contain any content other than include directives.

Here's an example showing the structure of a chapter document:

[source,asciidoc]
----
[#chapter-one]
= Chapter One
chapter content
----
== Chapter One
CAUTION: Although an explicit ID over the chapter title is not required, it's recommended for stability.
Some interesting text here.
If your chapter files start with a level-1 section instead of a level-2 section, you need to make the opposite adjustment in the header of the spine document:
== Chapter Two
[source,asciidoc]
----
\ifndef::ebook-format[:leveloffset: -1]
Even more exciting stuff.
----

If the master document does not contain any include directives, then the converter treats the document as the sole chapter in the EPUB3 archive and automatically produces a navigation file that references it.
(Currently broken. See issue {uri-issues}/47[#47]).

NOTE: Eventually, we envision introducing a dedicated block macro to represent a spine item so that we don't overload the meaning of the include directive.
However, for the time being, the include directive fills this role.
In older Asciidoctor EPUB3 versions, there were strict rules on document organization: 'spine' master document with chapter includes.
This is no longer the case. If you followed old rules, chances are your document will work with newer Asciidoctor EPUB3 either as-is or after minor adjustments.

== Prerequisites

All that's needed to use {project-name} is Ruby 2.3 or newer and a few Ruby gems (including at least Asciidoctor 1.5.3), which we'll explain how to install in the next section.
All that's needed to use {project-name} is Ruby 2.3 or newer and a few Ruby gems (including at least Asciidoctor 1.5.6), which we'll explain how to install in the next section.

To check if you have Ruby available, use the `ruby` command to query the installed version:

Expand Down Expand Up @@ -299,31 +225,6 @@ Assuming all the required gems install properly, verify you can run the `asciido
If you see the version of {project-name} printed, you're ready to use {project-name}.
Let's get an AsciiDoc document ready to convert to EPUB3.

=== Prepare an AsciiDoc Document

If you don't already have an AsciiDoc document, you can use the [file]_sample-book.adoc_ file and its chapters found in the [path]_data/samples_ directory of this project.

.Master file named sample-book.adoc
```asciidoc
= Asciidoctor EPUB3: Sample Book
Author Name
v1.0, 2014-04-15
:doctype: book
:creator: {author}
:producer: Asciidoctor
:keywords: Asciidoctor, samples, e-book, EPUB3, KF8, MOBI, Asciidoctor.js
:copyright: CC-BY-SA 3.0
:imagesdir: images

\include::asciidoctor-epub3-readme.adoc[]

\include::sample-content.adoc[]

\include::asciidoctor-js-introduction.adoc[]

\include::asciidoctor-js-extension.adoc[]
```

=== EPUB-related AsciiDoc Attributes

The metadata in the generated EPUB3 file is populated from attributes in the AsciiDoc document.
Expand Down Expand Up @@ -362,7 +263,7 @@ The title is added to the metadata in plain text format.
The authors in each chapter document are aggregated together with the authors in the master file.

|username
|Used to resolve an avatar for the author that is displayed in the header of a chapter when the `publication-type` is set to a value other than `book`.
|Used to resolve an avatar for the author that is displayed in the header of a chapter when the `doctype` is set to a value other than `book`.
The avatar image should be located at the path _\{imagesdir}/avatars/\{username}.jpg_, where `\{username}` is the value of this attribute.

|producer
Expand Down Expand Up @@ -400,13 +301,9 @@ _Only applies to a chapter document._
|The path to a directory that contains alternate epub3.css and epub3-css3-only.css files to customize the look and feel.

|doctype
|Effectively ignored.
The master document is assumed to be a book and each chapter an article.

|publication-type
|Used to control the inclusion of special content in the generated HTML.
If set to a value other than book, the byline information (author and avatar) is included below the chapter header and a typographic end mark is added at the end of the last paragraph.
Suggested values include: book (default), anthology, magazine, journal, article.
Suggested values include: book (default), article.
|===

When using the EPUB3 converter, the `ebook-format` attribute resolves to the name of the e-book format being generated (epub3 or kf8) and the corresponding attribute `ebook-format-<name>` is defined, where `<name>` is `epub3` or `kf8`.
Expand Down Expand Up @@ -618,9 +515,9 @@ mimetype

Images referenced in your AsciiDoc document must be stored in the images catalog.
The images catalog is defined by the `imagesdir` attribute.
If set, the value of this attribute is resolved relative to the spine document and must be at or below (i.e., within) the directory of that document.
If set, the value of this attribute is resolved relative to the document and must be at or below (i.e., within) the directory of that document.
(In other words, it cannot point to a location outside the document directory).
If this attribute is not set, the images catalog defaults to the directory of the spine document.
If this attribute is not set, the images catalog defaults to the directory of the document.
{project-name} will discover all local image references and insert those images into the EPUB3 archive at the same relative path.

=== Default Images
Expand All @@ -645,7 +542,7 @@ Once your image is ready, you can set the cover image by defining the `front-cov
:front-cover-image: image:cover.png[Front Cover,1050,1600]
----

The image is resolved relative to the directory specified in the `imagesdir` attribute, which defaults to the directory of the spine document.
The image is resolved relative to the directory specified in the `imagesdir` attribute, which defaults to the directory of the3 document.
The image can be in any format, though we recommend using PNG, JPG, or SVG as they are the most portable formats.

IMPORTANT: *You should always specify the dimensions of the cover image.*
Expand Down
3 changes: 0 additions & 3 deletions WORKLOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

== TODO

* remove conum patch for listing block (fixed in Asciidoctor 1.5.6)
* change has_role? to role?
* use empty string in place of nil in interpolated strings (few more still to check)
* add epub3width (or epubwidth) as alternative to scaledwidth for images
Expand All @@ -16,7 +15,6 @@
* don't add image from front matter if already referenced by chapter
* add document filename to warn messages (added for some)
* look for front-matter.html relative to docdir (or base_dir?); also allow front-matter.xhtml
* change references[:spine] to spine_document property
* reorder sections in README; needs to flow a bit better...Getting Started is too large & after Structuring your Manuscript
* add helper to resolve imagesdir
* support inline SVG
Expand Down Expand Up @@ -50,7 +48,6 @@
* CRITICAL: make generated file name strategy configurable (source file vs id)
* HIGH: revisit the headshot image logic
* HIGH: if running on a single article, then the document id has a conflicting purpose
* HIGH: require spine option on include directive in order to create a chapter file (requires change in Asciidoctor)
* HIGH: promote regexps to constants
* HIGH: put shy marks after dashes to allow wrapping to occur in text justification
* MEDIUM: add landmarks nav list to nav.xhtml; see https://github.com/IDPF/epub3-samples/blob/master/31/moby-dick-mo-xhtml/EPUB/toc.xhtml
Expand Down
2 changes: 1 addition & 1 deletion asciidoctor-epub3.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ An extension for Asciidoctor that converts AsciiDoc documents to EPUB3 and KF8/M
s.add_development_dependency 'rubocop', '~> 0.79.0'
s.add_development_dependency 'rubocop-rspec', '~> 1.38.0'

s.add_runtime_dependency 'asciidoctor', '>= 1.5.3', '< 3.0.0'
s.add_runtime_dependency 'asciidoctor', '>= 1.5.6', '< 3.0.0'
s.add_runtime_dependency 'gepub', '~> 1.0.0'
end
Loading

0 comments on commit 822c69f

Please sign in to comment.