Skip to content

feat(reader): add optional justified EPUB body text - #686

Merged
codedogQBY merged 3 commits into
codedogQBY:mainfrom
cha1latte:agent/justify-epub-body-text
Aug 17, 2026
Merged

codedogQBY merged 3 commits into
codedogQBY:mainfrom
cha1latte:agent/justify-epub-body-text

Conversation

@cha1latte

@cha1latte cha1latte commented Aug 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add a default-on Justify body text reader setting with translations for every supported locale
  • justify ordinary horizontal, reflowable EPUB paragraphs while preserving intentional centered/right-aligned text, poetry with line breaks, code, tables, captions, forms, vertical writing, and fixed-layout content
  • restore the EPUB's original formatting when the setting is disabled
  • inline the tested helper into the generated reader asset and keep initial/partial WebView settings payloads consistent

Why

Body alignment is currently controlled entirely by each EPUB, so readers cannot request consistent justified prose. This adds that control without overriding content whose layout or alignment is intentional.

Validation

  • pnpm --filter @readany/core test — 584 passed
  • pnpm --filter @readany/app-expo test — 9 passed
  • pnpm --filter @readany/app-expo exec tsc --noEmit
  • focused Biome lint on all feature-owned source files
  • pnpm --filter @readany/app-expo build:reader
  • node --check packages/app-expo/assets/reader/justified-text.js
  • git diff --check
  • physical Pixel 9a proof using a deliberately left-aligned EPUB: Disabled restored the ragged right edge; Enabled justified ordinary paragraphs to both edges; intentionally centered text stayed centered

The Android device proof used the Shlai integration APK built by GitHub Actions from commit da63ccd79fda3216b20caf7e15bed5408654f742 (run 31965394987), which contains this PR unchanged.

@cha1latte
cha1latte marked this pull request as ready for review August 16, 2026 19:28
@codedogQBY
codedogQBY merged commit 239f6f5 into codedogQBY:main Aug 17, 2026
k6G52m4Dz75W added a commit to k6G52m4Dz75W/ReadAny that referenced this pull request Sep 10, 2026
… br scan

Replace the DOM-scan justified-text.js (PR codedogQBY#686) with a light, cross-platform
strategy shared by mobile WebView and desktop foliate:

- CSS fallback in @layer readany-justify: body { text-align: justify } is the
  default, but unlayered book styles always win, so author alignment can never
  be overridden. :where() keeps specificity at 0.
- :where(*:has(> br)) { text-align: start } so direct-br poetry/lyrics lines
  are not stretched; using :has(> br) (direct child) avoids cascading start
  onto unrelated siblings of a br-bearing outer container.
- Code/tables/captions/forms excluded with text-align: start.
- A tiny JS pass reads the computed alignment of only br-bearing block-level
  elements and pins author-aligned ones (center/right/end, however expressed)
  inline, so the book's alignment survives our start rule. Pins are tagged and
  un-pinned on disable (clean undo) or on vertical/fixed layouts.
- Vertical/fixed documents are tagged data-readany-vertical (via getDirection
  on desktop, isVerticalDoc on mobile) so the justify CSS scopes to horizontal
  text.
- justifyBodyText setting retained (default on); when off the layer is not
  injected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants