Skip to content

Commit

Permalink
Documentation (readium#486)
Browse files Browse the repository at this point in the history
Co-authored-by: qnga <32197639+qnga@users.noreply.github.com>
  • Loading branch information
mickael-menu and qnga committed May 1, 2024
1 parent 374c9c3 commit ff983dc
Show file tree
Hide file tree
Showing 14 changed files with 909 additions and 35 deletions.
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Contributing to the Readium Kotlin Toolkit

First and foremost, thanks for your interest! 🙏 We need contributors like you to help bring this project to fruition.

We welcome many kind of contributions such as improving the documentation, submitting bug reports and feature requests, or writing code.

## Writing code

### Coding standard

We use [`ktlint`](https://github.com/pinterest/ktlint) to ensure code formatting and avoid bikeshedding.

Before submitting a PR, save yourself some trouble by automatically formatting the code with `make format` from the project's root directory.

### Modifying the EPUB Navigator's JavaScript layer

The EPUB navigator injects a set of JavaScript files into a publication's resources, exposing a JavaScript API to the `WebView` under the `readium` global namespace. The JavaScript source code is located under [`readium/navigator/src/main/assets/_scripts`](readium/navigator/src/main/assets/_scripts).

`index-reflowable.js` is the root of the bundle injected in a reflowable EPUB's resources, while `index-fixed.js` is used for a fixed-layout EPUB's resources.

If you make any changes to the JavaScript files, you must regenerate the bundles embedded in the application. First, make sure you have [`corepack` installed](https://pnpm.io/installation#using-corepack). Then, run `make scripts` from the project's root directory.

80 changes: 80 additions & 0 deletions MAINTAINING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Maintaining the Readium Kotlin toolkit

## Releasing a new version

You are ready to release a new version of the Kotlin toolkit? Great, follow these steps:

1. Figure out the next version using the [semantic versioning scheme](https://semver.org).
2. Test a migration from the last released version.
3. Update the [migration guide](docs/migration-guide.md) in case of breaking changes.
4. Issue the new release.
1. Create a branch with the same name as the future tag, from `develop`.
2. Bump the version numbers in:
* `README`
* `gradle.properties`
* `test-app/build.gradle.kts`
5. Close the version in the `CHANGELOG.md` and `docs/migration-guide.md`, [for example](https://github.com/readium/kotlin-toolkit/commit/011e0d74adc66ec2073f746d815310b838af4fbf).
6. Create a PR to merge in `develop` and verify the CI workflows.
7. Squash and merge the PR.
8. Tag the new version from `develop`.
```shell
git checkout develop
git pull
git tag -a 3.0.1 -m 3.0.1
git push --tags
```
5. Create a new release on GitHub.
* Add an APK to the release page **with LCP enabled**.
6. Publish to Maven Central.
1. Verify that the [`Publish` workflow](https://github.com/readium/kotlin-toolkit/actions/workflows/publish.yml) successfully pushed and closed the release to Maven Central.
2. Sign in to https://s01.oss.sonatype.org/
3. Verify the content of the staging repository.
4. Release the staging repository.
7. Check that the new modules can be imported in an Android project from Maven Central.
8. Merge `develop` into `main`.

### Publishing to Maven Central manually

If the `Publish` workflow fails, you may need to publish to Maven Central manually.

[The Sonatype issue for Readium is located here](https://issues.sonatype.org/browse/OSSRH-85964).

#### With the new vanniktech's Maven publish plugin

1. Make sure you have the secrets in `.envrc` and [direnv](https://direnv.net) installed.
2. Run:
```
./gradlew publishToMavenCentral --no-configuration-cache
```
3. Sign in to https://s01.oss.sonatype.org/
4. Publish manually the previously closed Staging repository

### (Deprecated) With the official Maven publish plugin

1. Make sure you have the secrets in `local.properties`.
2. Run:
```
./gradlew clean assembleRelease
./gradlew androidSourcesJar javadocJar
./gradlew publishReleasePublicationToSonatypeRepository closeSonatypeStagingRepository
```
3. Sign in to https://s01.oss.sonatype.org/
4. Publish manually the previously closed Staging repository

Note that [you can't run the gradlew commands separately](https://github.com/gradle-nexus/publish-plugin#publishing-and-closing-in-different-gradle-invocations), otherwise you get this error:

> No staging repository with name sonatype created
## Troubleshooting

### GitHub CI workflow is stuck

If a CI workflow is stuck with this message:

```
Requested labels: ubuntu-18.04
Job defined at: readium/kotlin-toolkit/.github/workflows/docs.yml@refs/heads/main
Waiting for a runner to pick up this job...
```

Try to update the version of the OS image in the workflow.
13 changes: 1 addition & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,7 @@

[Readium Mobile](https://github.com/readium/mobile) is a toolkit for ebooks, audiobooks and comics written in Swift & Kotlin.

This toolkit is a modular project, which follows the [Readium Architecture](https://github.com/readium/architecture). The different modules are found under [`readium/`](readium).

* [`shared`](readium/shared) – Shared `Publication` models and utilities
* [`streamer`](readium/streamer) – Publication parsers and local HTTP server
* [`navigator`](readium/navigator) – Plain `Fragment` and `Activity` classes rendering publications
* [`opds`](readium/opds) – Parsers for OPDS catalog feeds
* [`lcp`](readium/lcp) – Service and models for [Readium LCP](https://www.edrlab.org/readium-lcp/)
* [`adapters`](readium/adapters) – Adapters to use third-party libraries with Readium.
* [`adapters/pdfium`](readium/adapters/pdfium) – Parse and render PDFs using the open source library [PdfiumAndroid](https://github.com/barteksc/PdfiumAndroid).
* [`adapters/pspdfkit`](readium/adapters/pspdfkit) – Parse and render PDFs using the commercial library [PSPDFKit](https://pspdfkit.com/).

A [Test App](test-app) demonstrates how to integrate the Readium Kotlin toolkit in your own reading app.
:point_up: **Take a look at the [guide to get started](docs/guides/getting-started.md).** A [Test App](test-app) demonstrates how to integrate the Readium Kotlin toolkit in your own reading app.

:question: **Find documentation and API reference at [readium.org/kotlin-toolkit](https://readium.org/kotlin-toolkit)**.

Expand Down
12 changes: 12 additions & 0 deletions docs/guides/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# User guides

* [Getting started](getting-started.md)
* [Opening a publication](open-publication.md)
* [Extracting the content of a publication](content.md)
* [Supporting PDF documents](pdf.md)
* [Text-to-speech](tts.md)
* [Supporting Readium LCP](lcp.md)
* [Navigator](navigator/navigator.md)
* [Configuring the Navigator](navigator/preferences.md)
* [Font families in the EPUB navigator](navigator/epub-fonts.md)
* [Media Navigator](navigator/media-navigator.md)
153 changes: 153 additions & 0 deletions docs/guides/getting-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Getting started

The Readium Kotlin toolkit enables you to develop reading apps for Android and ChromeOS. It provides built-in support for multiple publication formats such as EPUB, PDF, audiobooks, and comics.

:warning: Readium offers only low-level tools. You are responsible for creating a user interface for reading and managing books, as well as a data layer to store the user's publications. The Test App is an example of such integration.

## Design principles

The toolkit has been designed following these core tenets:

* **Modular**: It is divided into separate modules that can be used independently.
* **Extensible**: Integrators should be able to support a custom DRM, publication format or inject their own stylesheets without modifying the toolkit itself.
* **Opiniated**: We adhere to open standards but sometimes interpret them for practicality.

## Modules

### Main modules

* `readium-shared` contains shared `Publication` models and utilities.
* `readium-streamer` parses publication files (e.g. an EPUB) into a `Publication` object.
* [`readium-navigator` renders the content of a publication](navigator/navigator.md).
* [`readium-navigator-media-audio` renders audiobooks](navigator/media-navigator.md)
* [`readium-navigator-media-tts` renders publication with a text-to-speech engine](tts.md)

### Specialized packages

* `readium-opds` parses [OPDS catalog feeds](https://opds.io) (both OPDS 1 and 2).
* [`readium-lcp` downloads and decrypts LCP-protected publications](lcp.md).

### Adapters to third-party dependencies

* `readium-adapter-exoplayer` provides an [ExoPlayer](https://exoplayer.dev) adapter for the [`AudioNavigator`](navigator/media-navigator.md).
* [`readium-adapter-pdfium`](../../readium/adapters/pdfium/README.md) provides a [Pdfium](https://github.com/barteksc/AndroidPdfViewer) adapter for the [PDF Navigator](pdf.md).
* [`readium-adapter-pspdfkit`](../../readium/adapters/pspdfkit/README.md) provides a [PSPDFKit](https://pspdfkit.com) adapter for the [PDF Navigator](pdf.md).

## Overview of the shared models (`readium-shared`)

The Readium toolkit provides models used as exchange types between packages.

### Publication models

#### Publication

`Publication` and its sub-components represent a single publication – ebook, audiobook or comic. It is loosely based on the [Readium Web Publication Manifest](https://readium.org/webpub-manifest/).

A `Publication` instance:

* holds the metadata of a publication, such as its author or table of contents,
* allows to read the contents of a publication, e.g. XHTML or audio resources,
* provides additional services, for example content extraction or text search.

#### Link

A [`Link` object](https://readium.org/webpub-manifest/#24-the-link-object) holds a pointer (URL) to a resource or service along with additional metadata, such as its media type or title.

The `Publication` contains several `Link` collections, for example:

* `readingOrder` lists the publication resources arranged in the order they should be read.
* `resources` contains secondary resources necessary for rendering the `readingOrder`, such as an image or a font file.
* `tableOfContents` represents the table of contents as a tree of `Link` objects.
* `links` exposes additional resources, such as a canonical link to the manifest or a search web service.

#### Locator

A [`Locator` object](https://readium.org/architecture/models/locators/) represents a precise location in a publication resource in a format that can be stored and shared across reading systems. It is more accurate than a `Link` and contains additional information about the location, e.g. progression percentage, position or textual context.

`Locator` objects are used for various features, including:

* reporting the current progression in the publication
* saving bookmarks, highlights and annotations
* navigating search results

### Data models

#### Asset

An `Asset` represents a single file or package and provides access to its content. There are two types of `Asset`:

* `ContainerAsset` for packages which contains several resources, such as a ZIP archive.
* `ResourceAsset` for accessing a single resource, such as a JSON or PDF file.

`Asset` instances are obtained through an `AssetRetriever`.

You can use the `asset.format` to identify the media type and capabilities of the asset.

```kotlin
if (asset.format.conformsTo(Specification.Lcp)) {
// The asset is protected with LCP.
}
if (asset.format.conformsTo(Specification.Epub)) {
// The asset represent an EPUB publication.
}
```

#### Resource

A `Resource` provides read access to a single resource, such as a file or an entry in an archive.

`Resource` instances are usually created by a `ResourceFactory`. The toolkit ships with various implementations supporting different data access protocols such as local files, HTTP, Android Content Providers, etc.

#### Container

A `Container<Resource>` provides read access to a collection of resources. `Container` instances representing an archive are usually created by an `ArchiveOpener`. The toolkit ships with a `ZipArchiveOpener` supporting local and remote ZIP files.

`Publication` objects internally use a `Container<Resource>` to expose its content.

## Opening a publication (`readium-streamer`)

To retrieve a `Publication` object from a publication file like an EPUB or audiobook, you can use an `AssetRetriever` and `PublicationOpener`.

```kotlin
// Instantiate the required components.
val httpClient = DefaultHttpClient()
val assetRetriever = AssetRetriever(
contentResolver = context.contentResolver,
httpClient = httpClient
)
val publicationOpener = PublicationOpener(
publicationParser = DefaultPublicationParser(
context,
httpClient = httpClient,
assetRetriever = assetRetriever,
pdfFactory = PdfiumDocumentFactory(context)
)
)

// Retrieve an `Asset` to access the file content.
val url = File("/path/to/book.epub").toUrl()
val asset = assetRetriever.retrieve(url)
.getOrElse { /* Failed to retrieve the Asset */ }

// Open a `Publication` from the `Asset`.
val publication = publicationOpener.open(asset, allowUserInteraction = true)
.getOrElse { /* Failed to access or parse the publication */ }

print("Opened ${publication.metadata.title}")
```

The `allowUserInteraction` parameter is useful when supporting a DRM like Readium LCP. It indicates if the toolkit can prompt the user for credentials when the publication is protected.

[See the dedicated user guide for more information](open-publication.md).

## Accessing the metadata of a publication

After opening a publication, you may want to read its metadata to insert a new entity into your bookshelf database, for instance. The `publication.metadata` object contains everything you need, including `title`, `authors` and the `published` date.

You can retrieve the publication cover using `publication.cover()`.

## Rendering the publication on the screen (`readium-navigator`)

You can use a Readium navigator to present the publication to the user. The `Navigator` renders resources on the screen and offers APIs and user interactions for navigating the contents.

Please refer to the [Navigator guide](navigator/navigator.md) for more information.
9 changes: 0 additions & 9 deletions docs/guides/index.md

This file was deleted.

Loading

0 comments on commit ff983dc

Please sign in to comment.