Model for the Publication's format/type
mickael-menu opened this issue · 9 comments
The way we handle Publication formats is not unified across platforms.
- We don't have a specified strategy to determine the format of a file (media type, file extension, etc.). So we might see differences across platforms.
- We have different enums with different cases, presenting a number of issues.
Swift
enum Publication.Format {
/// Formats natively supported by Readium.
case cbz, epub, pdf, webpub
/// Default value when the format is not specified.
case unknown
}
It's not clear what this represents:
- PDF is used for both LCPDF and PDF (because they are presented with
PDFNavigator
) - EPUB and WEBPUB are separate but they use the same navigator
Kotlin
enum class Publication.TYPE {
EPUB, CBZ, FXL, WEBPUB, AUDIO, DiViNa
}
Note that it's very different from the Swift version.
There's also some issues:
- FXL is separate from EPUB, because they use different navigators
- EPUB and WEBPUB are separate but they use the same navigator
- There's no
UNKNOWN
value for publications without a specified format (eg. parsed from OPDS)
Technically, we shouldn't need the format of the Publication, because in our model a Publication is not limited to one type of document in the readingOrder
. For example, we could have a Publication containing a PDF, and then an HTML page.
However, currently the format is needed for several reasons:
- Despite the fact that a Publication can contain several media types, the current navigator implementation requires a single format throughout the
readingOrder
. - The test-app is deciding which Navigator to create according to the Publication format/type.
- The format is needed when downloading a publication to set the file extension.
- The format might be of interest for the test-app (to display it in the user library).
Proposed Solution
- I think we should remove the format/type from the
Publication
model:
- As we've seen, it contradicts the flexibility of the model
- In some cases, it doesn't make sense to have a format (e.g. parsing an OPDS entry)
-
However, and since we still need the format in the test-app, we could move it to the more relevant
Container
object. It makes sense because the Container represents the Publication file. It could also be useful because if we know the Container's format, we can infer some available files in it (e.g. an EPUB Container has aMETA-INF/container.xml
resource). -
Instead of using a Format or Type enum as seen above, we should be very specific and introduce a
MediaType
enum (so LCPDF could be differentiated from PDF). This enum could centralize all the logics around media types and a specified strategy to determine a media type from a string and/or extension.
EDIT: I don't think thatMediaType
should be an enum anymore, see #116 (comment) -
We should remove the navigator creation logic from the test-app. For that, we could expose a unique Navigator facade in the navigator repo that would internally wrap the specific navigators. This would be simpler in the test-app, and we would be able to change the implementation without breaking the apps, for example to support multiple formats in a single navigator.
A challenge is that Publication.type/format
is used a lot throughout the test-app, so it will be a breaking change. Maybe there're some ways to ease the migration. For example keeping the format in the Publication for some time, with a deprecation warning.
@danielweck Do you have any insights from the JS implementation?
@danielweck Do you have any insights from the JS implementation?
There is currently only one "navigator" implementation, which renders readingOrder
HTML documents of EPUB reflowable and fixed-layout publications. There is currently no support for PDF, audio books, image books (CBZ), etc. Therefore, the current implementation is quite naive, and does not need to discriminate different kinds of publication.
This is a complex matter and I don't think that a single solution will help us achieve our goals.
IMO we would need at least:
- to preserve the info communicated in JSON-LD (
@type
) when we parse a RWPM or a W3C Audiobook - to preserve the media type of the package or manifest that we're using to initialize a
Publication
- a helper that can look into the resources expressed in the
readingOrder
and indicated if a publication is entirely based on: HTML, audio, images, video or a mixed use case
- to preserve the info communicated in JSON-LD (
@type
) when we parse a RWPM or a W3C Audiobook
It's currently available under publication.metadata.type
. However, it is not used by the EPUB, CBZ and PDF parsers. Should they add the media type there? The parser is the best place to know the file format.
- to preserve the media type of the package or manifest that we're using to initialize a
Publication
Is it the one provided by the test-app? Or resolved from the file by the parser? I think this is the thing that should be in Container
and not Publication
(except for @type
).
- a helper that can look into the resources expressed in the
readingOrder
and indicated if a publication is entirely based on: HTML, audio, images, video or a mixed use case
Definitely, this could be useful for the navigator. Incidentally, this could be based on the @type
as well.
Though all of this doesn't help to figure out the format of a file to be imported, hence the MediaType
helper.
However, it is not used by the EPUB, CBZ and PDF parsers. Should they add the media type there?
We could provide a default value for EPUB (https://schema.org/Book
), PDF (https://schema.org/DigitalDocument
) and CBZ (https://schema.org/ComicIssue
?).
Definitely, this could be useful for the navigator. Incidentally, this could be based on the
@type
as well.
Ideally I think this should be separate from the other two. There's a difference between what's advertised by a file and what's truly in its readingOrder
.
Also, something else that we want to keep in mind: using the HTML navigator won't always be the optimal choice.
EPUB 3 comics could benefit from our ability to:
- create an
alternate
pointing to an image directly instead of HTML - "guess" that these publications should default to an image navigator instead
This would require inspecting the HTML files of an FXL publication, which is probably beyond the scope of this discussion though.
Kobo supports something like this (thanks @JayPanoz for the reference): https://github.com/kobolabs/epub-spec#image-based-fxl-reader
Interesting! That goes definitely in the direction of letting the navigator decide which internal viewer to use.
Should we create a model with one Navigator and N specialized viewers, or an Navigator factory and N specialized Navigators?
I think that if we want to be able to support publications with multiple kind of contents down the line, it would make more sense to have one Navigator with N viewers.
An extension point could be added here to allow custom Viewers seamlessly.
But to start, the apps don't need to be aware of the Viewers. It should stay an implementation detail until we need the extensibility.
I submitted a full proposal for this in this PR: #127