This commit is contained in:
@@ -1,87 +1,132 @@
|
||||
# pyWebLayout-ereader
|
||||
# DReader Application
|
||||
|
||||
A complete ebook reader application built with [pyWebLayout](https://github.com/yourusername/pyWebLayout).
|
||||
## Project Status
|
||||
|
||||
This project demonstrates how to build a full-featured ebook reader using pyWebLayout's layout engine. It serves as both a reference implementation and a ready-to-use ereader library.
|
||||
| Badge | Description |
|
||||
|-------|-------------|
|
||||
|  | **Test Coverage** - Percentage of code covered by unit tests |
|
||||
|  | **Documentation Coverage** - Percentage of code with docstrings |
|
||||
|  | **License** - Project licensing information |
|
||||
|
||||
## Features
|
||||
> 📋 **Note**: Badges show results from the commit referenced in the URLs. Red "error" badges indicate build failures for that specific step.
|
||||
|
||||
- 📖 **EPUB Support** - Load and read EPUB files
|
||||
- 📄 **Page Navigation** - Forward/backward navigation with smooth rendering
|
||||
- 🔖 **Bookmarks** - Save and restore reading positions
|
||||
- 🎨 **Text Highlighting** - Highlight words and selections with notes
|
||||
- 🔍 **Text Selection** - Select and query text via touch/click
|
||||
- ⚙️ **Customization** - Font size, line spacing, colors
|
||||
- 📑 **Chapter Navigation** - Jump to chapters via table of contents
|
||||
- 👆 **Gesture Support** - Tap, swipe, pinch, long-press handling
|
||||
## Description
|
||||
|
||||
DReader Application is a complete, production-ready ebook reader built on [pyWebLayout](https://gitea.tourolle.paris/dtourolle/pyWebLayout). It demonstrates how to build a full-featured ebook reader with text highlighting, bookmarks, gesture support, and position persistence.
|
||||
|
||||
This project serves as both a reference implementation and a ready-to-use ereader library for building desktop, web-based, or embedded reading applications.
|
||||
|
||||
## Key Features
|
||||
|
||||
### Core Reading Features
|
||||
- 📖 **EPUB Support** - Load and render EPUB files with full text extraction
|
||||
- 📄 **Page Rendering** - Render pages as PIL Images optimized for any display
|
||||
- ⬅️➡️ **Navigation** - Smooth forward and backward page navigation
|
||||
- 🔖 **Bookmarks** - Save and restore reading positions with persistence
|
||||
- 📑 **Chapter Navigation** - Jump to chapters by title or index via TOC
|
||||
- 📊 **Progress Tracking** - Real-time reading progress percentage
|
||||
|
||||
### Text Interaction
|
||||
- 🎨 **Text Highlighting** - Highlight words and text selections with custom colors
|
||||
- 💡 **Highlight Notes** - Attach notes and annotations to highlights
|
||||
- 🔍 **Text Selection** - Select words or ranges via pixel coordinates
|
||||
- 👆 **Gesture Support** - Handle tap, swipe, pinch, long-press events
|
||||
- 🎯 **Pixel Queries** - Query text content at any screen position
|
||||
|
||||
### Customization & Display
|
||||
- 🔤 **Font Control** - Dynamically adjust font size with live preview
|
||||
- 📏 **Spacing Control** - Customize line and paragraph spacing
|
||||
- 💾 **Position Persistence** - Stable positions across style changes
|
||||
- ⚡ **Smart Reflow** - Automatic text reflow on font/spacing changes
|
||||
- 🎨 **Custom Styling** - Full control over colors, fonts, and layout
|
||||
|
||||
## Installation
|
||||
|
||||
### From Source
|
||||
|
||||
```bash
|
||||
# Install pyWebLayout first if not already installed
|
||||
cd /path/to/pyWebLayout
|
||||
# Clone the repository
|
||||
git clone https://gitea.tourolle.paris/dtourolle/dreader-application.git
|
||||
cd dreader-application
|
||||
|
||||
# Install in development mode
|
||||
pip install -e .
|
||||
|
||||
# Install pyWebLayout-ereader
|
||||
cd /path/to/pyWebLayout-ereader
|
||||
pip install -e .
|
||||
# Or install with dev dependencies
|
||||
pip install -e ".[dev]"
|
||||
```
|
||||
|
||||
### As a Dependency
|
||||
The pyWebLayout dependency will be automatically installed from the git repository.
|
||||
|
||||
```bash
|
||||
pip install pyweblayout-ereader
|
||||
```
|
||||
## DReader in Action
|
||||
|
||||
Here are animated demonstrations of the key features:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<b>Page Navigation</b><br>
|
||||
<img src="docs/images/ereader_page_navigation.gif" width="300" alt="Page Navigation"><br>
|
||||
<em>Forward and backward navigation through pages</em>
|
||||
</td>
|
||||
<td align="center">
|
||||
<b>Font Size Adjustment</b><br>
|
||||
<img src="docs/images/ereader_font_size.gif" width="300" alt="Font Size"><br>
|
||||
<em>Dynamic font size scaling with position preservation</em>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<b>Chapter Navigation</b><br>
|
||||
<img src="docs/images/ereader_chapter_navigation.gif" width="300" alt="Chapter Navigation"><br>
|
||||
<em>Jump directly to chapters by title or index</em>
|
||||
</td>
|
||||
<td align="center">
|
||||
<b>Bookmarks & Positions</b><br>
|
||||
<img src="docs/images/ereader_bookmarks.gif" width="300" alt="Bookmarks"><br>
|
||||
<em>Save and restore reading positions anywhere in the book</em>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" colspan="2">
|
||||
<b>Text Highlighting</b><br>
|
||||
<img src="docs/images/ereader_highlighting.gif" width="300" alt="Highlighting"><br>
|
||||
<em>Highlight words and selections with custom colors and notes</em>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Quick Start
|
||||
|
||||
```python
|
||||
from pyweblayout_ereader import EbookReader
|
||||
from dreader.application import EbookReader
|
||||
|
||||
# Create reader
|
||||
reader = EbookReader(page_size=(800, 1000))
|
||||
# Create an ebook reader
|
||||
with EbookReader(page_size=(800, 1000)) as reader:
|
||||
# Load an EPUB file
|
||||
reader.load_epub("mybook.epub")
|
||||
|
||||
# Load an EPUB
|
||||
reader.load_epub("mybook.epub")
|
||||
# Get current page as PIL Image
|
||||
page = reader.get_current_page()
|
||||
page.save("page_001.png")
|
||||
|
||||
# Get current page as image
|
||||
page = reader.get_current_page()
|
||||
page.save("current_page.png")
|
||||
# Navigate through pages
|
||||
reader.next_page()
|
||||
reader.previous_page()
|
||||
|
||||
# Navigate
|
||||
reader.next_page()
|
||||
reader.previous_page()
|
||||
# Save reading position
|
||||
reader.save_position("chapter_3")
|
||||
|
||||
# Save position
|
||||
reader.save_position("bookmark1")
|
||||
# Jump to a chapter
|
||||
reader.jump_to_chapter("Chapter 5")
|
||||
|
||||
# Later, restore position
|
||||
reader.load_position("bookmark1")
|
||||
```
|
||||
# Adjust font size
|
||||
reader.increase_font_size()
|
||||
|
||||
## Examples
|
||||
# Highlight text at coordinates
|
||||
highlight_id = reader.highlight_word(x=200, y=300, note="Important!")
|
||||
|
||||
See the `examples/` directory for complete examples:
|
||||
|
||||
- **simple_ereader_example.py** - Basic ereader usage
|
||||
- **ereader_demo.py** - Full-featured demo with all capabilities
|
||||
- **word_selection_highlighting.py** - Text selection and highlighting
|
||||
- **generate_ereader_gifs.py** - Generate animated demos
|
||||
|
||||
## Architecture
|
||||
|
||||
This project is a **high-level application layer** that combines pyWebLayout components:
|
||||
|
||||
```
|
||||
pyweblayout_ereader.EbookReader
|
||||
↓
|
||||
├── pyWebLayout.layout.EreaderLayoutManager # Layout & pagination
|
||||
├── pyWebLayout.core.HighlightManager # Highlighting system
|
||||
├── pyWebLayout.io.gesture # Touch/gesture handling
|
||||
└── pyWebLayout.io.readers # EPUB parsing
|
||||
# Get progress
|
||||
progress = reader.get_reading_progress()
|
||||
print(f"Progress: {progress*100:.1f}%")
|
||||
```
|
||||
|
||||
## API Overview
|
||||
@@ -91,7 +136,7 @@ pyweblayout_ereader.EbookReader
|
||||
```python
|
||||
reader.load_epub("book.epub")
|
||||
reader.is_loaded() # Check if book loaded
|
||||
reader.get_book_info() # Get metadata
|
||||
reader.get_book_info() # Get metadata (title, author, etc.)
|
||||
```
|
||||
|
||||
### Navigation
|
||||
@@ -99,21 +144,26 @@ reader.get_book_info() # Get metadata
|
||||
```python
|
||||
reader.next_page()
|
||||
reader.previous_page()
|
||||
reader.jump_to_chapter("Chapter 1")
|
||||
reader.get_reading_progress() # 0.0 to 1.0
|
||||
reader.jump_to_chapter("Chapter 1") # By title
|
||||
reader.jump_to_chapter(0) # By index
|
||||
reader.get_chapters() # List all chapters
|
||||
reader.get_current_chapter_info()
|
||||
reader.get_reading_progress() # Returns 0.0 to 1.0
|
||||
```
|
||||
|
||||
### Styling
|
||||
### Styling & Display
|
||||
|
||||
```python
|
||||
reader.increase_font_size()
|
||||
reader.decrease_font_size()
|
||||
reader.set_font_size(1.5) # 150% scale
|
||||
reader.get_font_size()
|
||||
|
||||
reader.set_line_spacing(8)
|
||||
reader.set_inter_block_spacing(20)
|
||||
```
|
||||
|
||||
### Bookmarks
|
||||
### Bookmarks & Position Management
|
||||
|
||||
```python
|
||||
reader.save_position("my_bookmark")
|
||||
@@ -122,23 +172,36 @@ reader.list_saved_positions()
|
||||
reader.delete_position("my_bookmark")
|
||||
```
|
||||
|
||||
### Highlighting
|
||||
### Text Highlighting
|
||||
|
||||
```python
|
||||
# Highlight a word at pixel coordinates
|
||||
highlight_id = reader.highlight_word(x=100, y=200, note="Important!")
|
||||
from pyWebLayout.core.highlight import HighlightColor
|
||||
|
||||
# Highlight a selection
|
||||
# Highlight a word at pixel coordinates
|
||||
highlight_id = reader.highlight_word(
|
||||
x=100,
|
||||
y=200,
|
||||
color=HighlightColor.YELLOW,
|
||||
note="Important concept!"
|
||||
)
|
||||
|
||||
# Highlight a text selection
|
||||
highlight_id = reader.highlight_selection(
|
||||
start=(100, 200),
|
||||
end=(300, 250),
|
||||
color=(255, 255, 0, 128) # Yellow
|
||||
color=(255, 255, 0, 128) # RGBA
|
||||
)
|
||||
|
||||
# Query word at position
|
||||
result = reader.query_pixel(x=200, y=300)
|
||||
if result:
|
||||
print(f"Word: {result.word.text}")
|
||||
|
||||
# Manage highlights
|
||||
reader.list_highlights()
|
||||
highlights = reader.list_highlights()
|
||||
reader.remove_highlight(highlight_id)
|
||||
reader.clear_highlights()
|
||||
reader.get_highlights_for_current_page()
|
||||
```
|
||||
|
||||
### Gesture Handling
|
||||
@@ -153,32 +216,73 @@ response = reader.handle_touch(event)
|
||||
# Response contains action type and data
|
||||
if response.action == ActionType.PAGE_TURN:
|
||||
print(f"Page turned: {response.data['direction']}")
|
||||
elif response.action == ActionType.WORD_SELECTED:
|
||||
print(f"Word selected: {response.data['word']}")
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
### File Operations
|
||||
|
||||
- **Desktop Ereader Applications** - Build native ereader apps
|
||||
- **Web-based Readers** - Serve rendered pages via Flask/FastAPI
|
||||
- **E-ink Device Firmware** - Optimized for e-ink displays
|
||||
- **Reading Analytics** - Track reading patterns and highlights
|
||||
- **Educational Tools** - Annotated reading with highlights and notes
|
||||
```python
|
||||
# Save current page to file
|
||||
reader.render_to_file("current_page.png")
|
||||
|
||||
## Relationship to pyWebLayout
|
||||
# Context manager (auto-saves position on close)
|
||||
with EbookReader(page_size=(800, 1000)) as reader:
|
||||
reader.load_epub("book.epub")
|
||||
# ... use reader ...
|
||||
# Position automatically saved on exit
|
||||
```
|
||||
|
||||
**pyWebLayout** is a layout engine library providing low-level primitives for:
|
||||
- Text rendering and layout
|
||||
## Examples
|
||||
|
||||
Check out the `examples/` directory for complete working examples:
|
||||
|
||||
- **[simple_ereader_example.py](examples/simple_ereader_example.py)** - Basic ereader usage with EPUB loading and navigation
|
||||
- **[ereader_demo.py](examples/ereader_demo.py)** - Comprehensive demo showcasing all features
|
||||
- **[word_selection_highlighting.py](examples/word_selection_highlighting.py)** - Text selection and highlighting
|
||||
- **[simple_word_highlight.py](examples/simple_word_highlight.py)** - Minimal highlighting example
|
||||
- **[generate_ereader_gifs.py](examples/generate_ereader_gifs.py)** - Generate animated GIF demonstrations
|
||||
|
||||
## Architecture
|
||||
|
||||
DReader Application is a **high-level application layer** that combines pyWebLayout's low-level components:
|
||||
|
||||
```
|
||||
dreader.application.EbookReader (High-Level API)
|
||||
↓
|
||||
├── pyWebLayout.layout.EreaderLayoutManager # Layout engine & pagination
|
||||
├── pyWebLayout.layout.EreaderLayout # Bidirectional layout
|
||||
├── pyWebLayout.core.HighlightManager # Highlighting system
|
||||
├── pyWebLayout.io.gesture # Touch/gesture handling
|
||||
└── pyWebLayout.io.readers.epub_reader # EPUB parsing
|
||||
```
|
||||
|
||||
### Relationship to pyWebLayout
|
||||
|
||||
**pyWebLayout** is a layout engine library providing low-level primitives:
|
||||
- Text rendering and layout algorithms
|
||||
- Document structure and pagination
|
||||
- Query systems for interactive content
|
||||
- Core rendering infrastructure
|
||||
|
||||
**pyWebLayout-ereader** is an application framework that:
|
||||
**DReader Application** is an application framework that:
|
||||
- Combines pyWebLayout components into a complete reader
|
||||
- Provides user-friendly APIs for common ereader tasks
|
||||
- Manages application state (bookmarks, highlights, etc.)
|
||||
- Manages application state (bookmarks, highlights, positions)
|
||||
- Handles business logic for gestures and interactions
|
||||
|
||||
Think of it like this:
|
||||
- pyWebLayout = React (library)
|
||||
- pyWebLayout-ereader = Next.js (framework)
|
||||
- **pyWebLayout** = React (library)
|
||||
- **DReader Application** = Next.js (framework)
|
||||
|
||||
## Use Cases
|
||||
|
||||
- 📱 **Desktop Ereader Applications** - Build native ereader apps with Python
|
||||
- 🌐 **Web-based Readers** - Serve rendered pages via Flask/FastAPI
|
||||
- 📟 **E-ink Device Firmware** - Optimized rendering for e-ink displays
|
||||
- 📊 **Reading Analytics** - Track reading patterns, highlights, and engagement
|
||||
- 🎓 **Educational Tools** - Create annotated reading experiences with highlights and notes
|
||||
- 🔬 **Research Applications** - Build specialized reading tools for academic work
|
||||
|
||||
## Development
|
||||
|
||||
@@ -189,22 +293,83 @@ pip install -e ".[dev]"
|
||||
# Run tests
|
||||
pytest
|
||||
|
||||
# Run tests with coverage
|
||||
pytest --cov=dreader --cov-report=html
|
||||
|
||||
# Format code
|
||||
black pyweblayout_ereader/
|
||||
black dreader/ tests/
|
||||
|
||||
# Type checking
|
||||
mypy pyweblayout_ereader/
|
||||
mypy dreader/
|
||||
|
||||
# Linting
|
||||
flake8 dreader/ tests/
|
||||
```
|
||||
|
||||
### Running Examples
|
||||
|
||||
```bash
|
||||
# Ensure you have an EPUB file for testing
|
||||
cd examples
|
||||
|
||||
# Run simple example
|
||||
python simple_ereader_example.py /path/to/book.epub
|
||||
|
||||
# Run comprehensive demo
|
||||
python ereader_demo.py /path/to/book.epub
|
||||
|
||||
# Generate animated GIFs
|
||||
python generate_ereader_gifs.py /path/to/book.epub
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
The project includes comprehensive tests covering:
|
||||
|
||||
- **Application API** - All EbookReader methods and workflows
|
||||
- **System Integration** - Layout manager, bookmarks, and state management
|
||||
- **Highlighting** - Word and selection highlighting with persistence
|
||||
- **Edge Cases** - Error handling, boundary conditions, and recovery
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
pytest
|
||||
|
||||
# Run specific test file
|
||||
pytest tests/test_ereader_application.py
|
||||
|
||||
# Run with verbose output
|
||||
pytest -v
|
||||
|
||||
# Run with coverage report
|
||||
pytest --cov=dreader --cov-report=term-missing
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions welcome! This project demonstrates what's possible with pyWebLayout. If you build something cool or find ways to improve the reader, please share!
|
||||
|
||||
### How to Contribute
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
||||
3. Make your changes with tests
|
||||
4. Run tests and ensure coverage stays high
|
||||
5. Format code with black
|
||||
6. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see LICENSE file for details
|
||||
MIT License - see [LICENSE](LICENSE) file for details
|
||||
|
||||
## Author
|
||||
|
||||
Duncan Tourolle - duncan@tourolle.paris
|
||||
|
||||
## Related Projects
|
||||
|
||||
- [pyWebLayout](https://github.com/yourusername/pyWebLayout) - The underlying layout engine
|
||||
- Add your projects here!
|
||||
- [pyWebLayout](https://gitea.tourolle.paris/dtourolle/pyWebLayout) - The underlying layout engine library
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Built with [pyWebLayout](https://gitea.tourolle.paris/dtourolle/pyWebLayout) - A powerful Python library for HTML-like layout and rendering.
|
||||
|
||||
Reference in New Issue
Block a user