{"id":35272573,"url":"https://github.com/bigbag/papyrix-reader","last_synced_at":"2026-05-20T06:01:37.976Z","repository":{"id":333827181,"uuid":"1135096130","full_name":"bigbag/papyrix-reader","owner":"bigbag","description":"Lightweight open-source firmware for Xteink X4 e-paper reader • EPUB/TXT support • WiFi transfers • Custom themes \u0026 fonts","archived":false,"fork":false,"pushed_at":"2026-01-28T13:14:26.000Z","size":34191,"stargazers_count":47,"open_issues_count":3,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-29T01:51:36.595Z","etag":null,"topics":["eink","eink-devices","esp32","papyrix","xteink","xteink-x4"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bigbag.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["bigbag"],"ko_fi":"bigbag"}},"created_at":"2026-01-15T16:23:57.000Z","updated_at":"2026-01-28T22:34:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bigbag/papyrix-reader","commit_stats":null,"previous_names":["bigbag/papyrix-reader"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/bigbag/papyrix-reader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigbag%2Fpapyrix-reader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigbag%2Fpapyrix-reader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigbag%2Fpapyrix-reader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigbag%2Fpapyrix-reader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bigbag","download_url":"https://codeload.github.com/bigbag/papyrix-reader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bigbag%2Fpapyrix-reader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28882644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-29T16:41:59.663Z","status":"ssl_error","status_checked_at":"2026-01-29T16:39:39.641Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eink","eink-devices","esp32","papyrix","xteink","xteink-x4"],"created_at":"2025-12-30T12:59:00.090Z","updated_at":"2026-05-20T06:01:37.966Z","avatar_url":"https://github.com/bigbag.png","language":"C","funding_links":["https://github.com/sponsors/bigbag","https://ko-fi.com/bigbag"],"categories":[],"sub_categories":[],"readme":"# Papyrix\n\n[![Changelog](https://img.shields.io/badge/changelog-CHANGELOG.md-blue)](CHANGELOG.md)\n[![User Guide](https://img.shields.io/badge/docs-User_Guide-green)](docs/user_guide.md)\n[![Customization](https://img.shields.io/badge/docs-Customization-green)](docs/customization.md)\n[![Fonts](https://img.shields.io/badge/docs-Fonts-green)](docs/fonts.md)\n[![Architecture](https://img.shields.io/badge/docs-Architecture-green)](docs/architecture.md)\n[![Device Specs](https://img.shields.io/badge/docs-Device_Specs-green)](docs/device-specifications.md)\n[![X4 Specs](https://img.shields.io/badge/docs-X4_Specs-green)](docs/x4-specifications.md)\n[![X3 Specs](https://img.shields.io/badge/docs-X3_Specs-green)](docs/x3-specifications.md)\n[![File Formats](https://img.shields.io/badge/docs-File_Formats-green)](docs/file-formats.md)\n[![Images](https://img.shields.io/badge/docs-Images-green)](docs/images.md)\n[![SSD1677 Driver](https://img.shields.io/badge/docs-SSD1677_Driver-green)](docs/ssd1677-driver.md)\n[![Webserver](https://img.shields.io/badge/docs-Webserver-green)](docs/webserver.md)\n[![Calibre](https://img.shields.io/badge/docs-Calibre_Wireless-green)](docs/calibre.md)\n\n\nA lightweight, user-friendly firmware for the **Xteink X4** and **Xteink X3** e-paper display readers.\nBuilt using **PlatformIO** and targeting the **ESP32-C3** microcontroller. A single firmware\nauto-detects the panel variant at boot via I²C signature scan (BQ27220 fuel gauge, DS3231 RTC, QMI8658 IMU).\n\n\u003e **Warning:** Papyrix does not support OTA updates. Some Xteink units (e.g. from AliExpress)\n\u003e ship with USB flashing locked — if you flash Papyrix on a locked device by OTA, you will\n\u003e have no way to update or recover over USB. Firmware updates and [emergency recovery](#emergency-recovery)\n\u003e are still possible from SD card. Only flash Papyrix on devices with unlocked USB.\n\n![Home screen](./docs/images/device.jpg)\n\n## Motivation\n\nE-paper devices are fantastic for reading, but most commercially available readers are closed systems with limited customisation. The **Xteink X4** and **Xteink X3** are affordable e-paper devices, however the official firmware remains closed.\n\nPapyrix aims to:\n* Provide a **lightweight, open-source alternative** to the official firmware.\n* Offer a **document reader** capable of handling EPUB content on constrained hardware.\n* Support **customisable font, layout, and display** options.\n* Run purely on the **Xteink X3 / X4 hardware** from a single auto-detecting firmware.\n\nThis project is **not affiliated with Xteink**; it's built as a community project.\n\n## Supported devices\n\n| Device | Panel | Portrait viewport | Notes |\n|---|---|---|---|\n| Xteink X4 | 800×480 SSD1677 | 480×800 | Original target — full feature set |\n| Xteink X3 | 792×528 SSD1677 | 528×792 | Detected at boot via I²C probe (BQ27220, DS3231, QMI8658). DS3231 RTC and QMI8658 IMU are detected but not yet used. |\n\nPage caches are stored in device-specific subdirectories (`/.papyrix/cache/` for X4,\n`/.papyrix/cache/x3/` for X3) so an SD card moved between devices renders correctly\non each panel.\n\n## Features\n\n### Reading \u0026 Format Support\n- [x] EPUB 2 and EPUB 3 parsing (nav.xhtml with NCX fallback)\n- [x] CSS stylesheet parsing (text-align, font-style, font-weight, text-indent, margins, direction)\n- [x] Preformatted text (`\u003cpre\u003e`) and inline code (`\u003ccode\u003e`, `\u003ctt\u003e`, `\u003ckbd\u003e`, `\u003csamp\u003e`) rendered as italic (no monospace font bundled)\n- [x] FB2 (FictionBook 2.0) support with metadata, TOC navigation, and metadata caching (no inline images)\n- [x] HTML (.html, .htm) file support (standalone HTML documents)\n- [x] XTC/XTCH native format support\n- [x] Markdown (.md, .markdown) file support with formatting\n- [x] Plain text (.txt, .text) file support\n- [x] Saved reading position\n- [x] Bookmarks (up to 20 per book, persisted to SD card)\n- [x] Book cover display (JPG/JPEG/PNG/BMP, case-insensitive)\n- [x] Table of contents navigation\n- [x] Image support within EPUB (JPEG/PNG/BMP, baseline JPEG only, max 2048×3072)\n\n### Text \u0026 Display\n- [x] Configurable font sizes (XSmall/Small/Normal/Large)\n- [x] Paragraph alignment (Justified/Left/Center/Right)\n- [x] Text layout presets (Compact/Standard/Large) for indentation and spacing\n- [x] Soft hyphen support for text layout\n- [x] Liang-pattern hyphenation with language detection from EPUB metadata (de, en, es, fr, it, ru, uk)\n- [x] Native Vietnamese, Thai, Greek, and Arabic support in builtin fonts\n- [x] CJK (Chinese/Japanese/Korean) text layout (book text only, not UI)\n- [x] Thai text rendering with proper mark positioning\n- [x] Arabic text shaping - contextual forms, Lam-Alef ligatures with RTL layout\n- [x] Knuth-Plass line breaking algorithm (TeX-quality justified text)\n- [x] Text anti-aliasing toggle (grayscale text rendering for builtin and custom fonts)\n- [x] Pages per refresh setting (1/5/10/15/30)\n- [x] Sunlight fading fix (powers down display after refresh to prevent UV fading)\n- [x] Turbo LUTs with LUT caching for faster X3 page turns\n- [x] 4 screen orientations\n\n### Customization\n- [x] Custom themes from SD card (`/config/themes/`)\n- [x] Custom fonts from SD card (`/config/fonts/`, .epdfont format)\n- [x] Custom sleep screens (Dark/Light/Custom/Cover modes)\n- [x] Button remapping (side and front buttons)\n- [x] Power button actions (page turn, bookmark, or sleep on short press)\n\n### Network \u0026 Connectivity\n- [x] WiFi file transfer (web server)\n- [x] Calibre Wireless Device - Send books from Calibre desktop\n\n### Maintenance\n- [x] Cleanup menu (clear caches, fonts, factory reset)\n- [x] Firmware updates from SD card\n- [x] System info (version, uptime, memory, storage)\n\n### File System\n- [x] exFAT and FAT32 SD card support\n- [x] UTF-8 filenames (Cyrillic, etc.)\n- [x] File explorer with nested folders\n- [x] Hidden system folders filtering (LOST.DIR, $RECYCLE.BIN, etc.)\n\n\u003e **Tip:** If you organise your library into deeply nested folders with Cyrillic or CJK names, format the SD card as **exFAT** rather than FAT32. Non-Latin characters use 2-4 bytes each in UTF-8, so deep folder paths can exceed FAT32's path length limit.\n\nSee [the user guide](docs/user_guide.md) for operating instructions, and the [customization guide](docs/customization.md) for themes and fonts. Example theme and font files are available in [`docs/examples/`](docs/examples/).\n\n### Installing \u0026 Firmware Updates\n\n\u003e Need to recover a bricked device? [Jump to emergency recovery](#emergency-recovery).\n\nThe recommended way to install or update Papyrix is\n**[papyrix-flasher](https://github.com/bigbag/papyrix-flasher)** — a cross-platform\nCLI tool with auto-detection and embedded bootloader. Download the latest release for\nyour platform and run:\n\n```bash\npapyrix-flasher flash firmware.bin\n```\n\n**From SD card:** You can also install or update using an SD card:\n\n1. Copy the firmware file as `/firmware.bin` to the root of your SD card.\n2. Insert the SD card into the device.\n3. Go to **Settings \u003e Firmware Update** and press **Run**.\n\nThe device flashes the firmware from SD card and reboots automatically.\n\n#### Emergency Recovery\n\nIf the device will not boot, copy the firmware as `/force_update.bin` to the SD card.\nOn next boot, the device flashes it automatically before starting the UI — no\ninteraction needed.\n\nSee the [customization guide](docs/customization.md) for details.\n\n## Development\n\n### Prerequisites\n\n* **PlatformIO Core** (`pio`) or **VS Code + PlatformIO IDE**\n* Python 3.12+ with [uv](https://docs.astral.sh/uv/) (for font conversion)\n* Node.js 18+ (for sleep screen and logo scripts)\n* USB-C cable for flashing the ESP32-C3\n* Xteink X4\n\nInstall Node.js dependencies (for sleep screen and logo scripts):\n```bash\ncd scripts \u0026\u0026 npm install\n```\n\n### Using Nix (Recommended)\n\nIf you have [Nix](https://nixos.org/) installed, all dependencies are provided via `shell.nix`:\n\n```bash\n# Enter development environment\nnix-shell\n\n# Or run commands directly\nnix-shell --run \"make build\"\nnix-shell --run \"make check\"\n```\n\nFirst-time Nix setup:\n```bash\n# Install Nix (if not installed)\nsh \u003c(curl -L https://nixos.org/nix/install) --daemon\n\n# Add nixpkgs channel\nnix-channel --add https://nixos.org/channels/nixos-unstable nixpkgs\nnix-channel --update\n```\n\n### Checking out the code\n\nPapyrix uses PlatformIO for building and flashing the firmware. To get started, clone the repository:\n\n```\ngit clone --recursive https://github.com/pliashkou/papyrix\n\n# Or, if you've already cloned without --recursive:\ngit submodule update --init --recursive\n```\n\n### Building\n\n```sh\n# Build firmware\nmake build\n\n# Build release firmware\nmake release\n\n# Or using PlatformIO directly\npio run\n```\n\n### Flashing your device\n\nConnect your Xteink X4 to your computer via USB-C and run the following command.\n\n```sh\nmake flash\n\n# Or using PlatformIO directly\npio run --target upload\n```\n\nYou can also flash using esptool directly (useful if you have a pre-built firmware binary):\n\n```sh\nesptool.py --chip esp32c3 --port /dev/ttyACM0 --baud 460800 \\\n  write_flash -z 0x0 firmware.bin\n```\n\nReplace `/dev/ttyACM0` with your device port (e.g., `COM3` on Windows, `/dev/tty.usbmodem*` on macOS).\n\n### Build Scripts\n\nBuild scripts are in the `scripts/` directory.\n\n#### Converting fonts\n\nConvert TTF/OTF fonts to Papyrix `.epdfont` format using Python (requires [uv](https://docs.astral.sh/uv/)):\n\n```bash\n# Basic conversion (outputs to current directory)\nuv run scripts/fontconvert.py my-font -r MyFont-Regular.ttf --2bit\n\n# Full font family with all reader sizes (14, 16, 18pt)\nuv run scripts/fontconvert.py my-font -r Regular.ttf -b Bold.ttf --2bit --all-sizes -o /tmp/fonts/\n\n# With Thai script support\nuv run scripts/fontconvert.py my-font -r Regular.ttf --2bit --thai -o /tmp/fonts/\n\n# With Arabic script support\nuv run scripts/fontconvert.py my-font -r Regular.ttf --2bit --arabic -o /tmp/fonts/\n\n# Generate C header instead of binary (for builtin fonts)\nuv run scripts/fontconvert.py my_font 16 Regular.ttf --2bit \u003e my_font_16_2b.h\n```\n\nOptions: `-r/--regular`, `-b/--bold`, `-i/--italic`, `-o/--output`, `-s/--size`, `--2bit`, `--all-sizes`, `--header`, `--thai`, `--arabic`\n\nSee [customization guide](docs/customization.md) for detailed font conversion instructions.\n\n#### Creating sleep screen images\n\nConvert any image to sleep screen BMP format (requires `cd scripts \u0026\u0026 npm install`):\n\n```bash\n# Via Makefile\nmake sleep-screen INPUT=photo.jpg OUTPUT=sleep.bmp\nmake sleep-screen INPUT=photo.jpg OUTPUT=sleep.bmp ARGS='--dither --bits 8'\n\n# Or directly\ncd scripts \u0026\u0026 node create-sleep-screen.mjs photo.jpg sleep.bmp --dither --bits 8\n```\n\nOptions:\n- `--orientation portrait|landscape` - Screen orientation (default: portrait)\n- `--bits 2|4|8` - Output bit depth (default: 4)\n- `--dither` - Enable Floyd-Steinberg dithering\n- `--fit contain|cover|stretch` - Resize mode (default: contain)\n\nCopy the output BMP to `/sleep/` directory or as `/sleep.bmp` on the SD card.\n\n#### Converting logo\n\nConvert image to C header for firmware logo (128x128 monochrome):\n\n```bash\ncd scripts \u0026\u0026 node convert-logo.mjs logo.png ../src/images/PapyrixLogo.h\n```\n\nOptions: `--invert`, `--threshold \u003c0-255\u003e`, `--rotate \u003c0|90|180|270\u003e`\n\n#### Calibre simulators (development/testing)\n\nTwo simulators are provided for testing the Calibre Wireless Device feature without real hardware:\n\n```bash\ncd scripts\n\n# Simulate a Papyrix device (for testing Calibre desktop connection)\nnode device-simulator.mjs\n\n# Simulate Calibre desktop (for testing device firmware)\nnode calibre-simulator.mjs\n```\n\nThe device simulator listens for Calibre broadcasts and can receive books (saved to `scripts/received_books/`). The Calibre simulator broadcasts discovery packets and sends test books to connected devices.\n\n#### Serial monitor\n\nA standalone Go binary for reading device logs without PlatformIO. Pre-built binaries are available on the [releases page](https://github.com/pliashkou/papyrix/releases), or build from source:\n\n```bash\ncd tools/monitor \u0026\u0026 go build -o monitor .\n```\n\nUsage:\n```bash\n./monitor                                  # Auto-detect port\n./monitor -port /dev/ttyACM0               # Explicit port\n./monitor -port /dev/ttyACM0 -log out.txt  # Also save to file\n./monitor -speed 921600                    # Custom baud rate (default: 115200)\n```\n\n#### Reader test (desktop)\n\nA desktop tool for testing the content parsing pipeline (EPUB, FB2, HTML, TXT, Markdown) without flashing to hardware. Useful for catching parsing bugs, layout issues, or crashes.\n\n```bash\n# Build only\nmake reader-test\n\n# Build and process a book\nmake reader-test FILE=book.epub OUTPUT=/tmp/cache\n\n# Dump parsed text content of each page\ntools/reader-test/build/reader-test --dump book.epub /tmp/cache\n```\n\nOptions:\n- `--dump` — Print the parsed text content of each page (useful for verifying entity resolution, text extraction, and layout)\n\n### Creating a GitHub release\n\n```sh\n# With auto-generated notes from commits\nmake gh-release VERSION=0.1.1\n\n# With custom notes\nmake gh-release VERSION=0.1.1 NOTES=\"Release notes here\"\n```\n\n### Generating changelog\n\nGenerate `CHANGELOG.md` from git tags and commit history:\n\n```sh\nmake changelog\n```\n\nThis creates a changelog grouped by version tags, with commit messages and author information.\n\n## Internals\n\nPapyrix is designed for the ESP32-C3's ~380KB RAM constraint. See [docs/architecture.md](docs/architecture.md) for detailed architecture documentation.\n\n### Data caching\n\nThe first time chapters of a book are loaded, they are cached to the SD card. Subsequent loads are served from the cache. This cache directory exists at `.papyrix` on the SD card. The structure is as follows:\n\n\n```\n.papyrix/\n├── epub_12471232/       # Each EPUB is cached to a subdirectory named `epub_\u003chash\u003e`\n│   ├── progress.bin     # Stores reading progress (chapter, page, etc.)\n│   ├── bookmarks.bin    # Saved bookmarks (up to 20 per book)\n│   ├── bookmarks.txt    # Human-readable bookmark list (companion to bookmarks.bin)\n│   ├── cover.bmp        # Book cover image (once generated)\n│   ├── book.bin         # Book metadata (title, author, spine, table of contents, etc.)\n│   ├── sections/        # All chapter data is stored in the sections subdirectory\n│   │   ├── 0.bin        # Chapter data (screen count, all text layout info, etc.)\n│   │   ├── 1.bin        #     files are named by their index in the spine\n│   │   └── ...\n│   └── images/          # Cached inline images (converted to 2-bit BMP)\n│       ├── 123456.bmp   # Images named by hash of source path\n│       └── ...\n│\n├── fb2_55667788/        # Each FB2 file is cached to a subdirectory named `fb2_\u003chash\u003e`\n│   ├── meta.bin         # Cached metadata (title, author, TOC) for faster reloads\n│   ├── progress.bin     # Stores reading progress\n│   ├── cover.bmp        # Cover image (converted from adjacent image file)\n│   ├── sections/        # Cached chapter pages (same format as EPUB sections)\n│   │   ├── 0.bin\n│   │   └── ...\n│\n│\n├── txt_98765432/        # Each TXT file is cached to a subdirectory named `txt_\u003chash\u003e`\n│   ├── progress.bin     # Stores current page number (4-byte uint32)\n│   ├── index.bin        # Page index (byte offsets for each page start)\n│   └── cover.bmp        # Cover image (converted from book.jpg/png/bmp or cover.jpg/png/bmp)\n│\n├── md_12345678/         # Each Markdown file is cached to a subdirectory named `md_\u003chash\u003e`\n│   ├── progress.bin     # Stores current page number (2-byte uint16)\n│   ├── section.bin      # Parsed pages (same format as EPUB sections)\n│   └── cover.bmp        # Cover image (converted from README.jpg/png/bmp or cover.jpg/png/bmp)\n│\n├── html_12345678/       # Each HTML file is cached to a subdirectory named `html_\u003chash\u003e`\n│   ├── progress.bin     # Stores current page number (4-byte, same as TXT/Markdown)\n│   ├── pages_\u003cfontId\u003e.bin  # Parsed pages (same format as Markdown/FB2 sections)\n│   └── cover.bmp        # Cover image (converted from adjacent image file)\n│\n└── epub_189013891/\n```\n\nTo clear cached data, use **Settings \u003e Cleanup** (see [User Guide](docs/user_guide.md)). Alternatively, delete the `.papyrix` directory manually.\n\nDue the way it's currently implemented, the cache is not automatically cleared when a book is deleted and moving a book file will use a new cache directory, resetting the reading progress.\n\nFor more details on the internal file structures, see the [file formats document](./docs/file-formats.md). For how the cache is built (chunked partial caching, on-demand extension, foreground vs. background, ownership model) see [Rendering Pipeline § Page Caching](./docs/rendering-pipeline.md#page-caching).\n\n## Related Tools\n\n### EPUB to XTC Converter (Web)\n\n[epub-to-xtc-converter](https://github.com/bigbag/epub-to-xtc-converter) — browser-based converter from EPUB to Xteink's native XTC/XTCH format. Uses CREngine WASM for accurate rendering.\n\n- Device presets for Xteink X4/X3 (480x800)\n- Font selection from Google Fonts or custom TTF/OTF\n- Configurable margins, line height, hyphenation (42 languages)\n- Dark mode and dithering options\n- Batch processing and ZIP export\n\n**Live version:** [liashkov.site/epub-to-xtc-converter](https://liashkov.site/epub-to-xtc-converter/)\n\n### EPUB Optimizer (CLI)\n\n[xteink-epub-optimizer](https://github.com/bigbag/xteink-epub-optimizer) — command-line tool to optimize EPUB files for the Xteink X4's constraints (480×800 display, limited RAM):\n\n- **CSS Sanitization** - Removes complex layouts (floats, flexbox, grid)\n- **Font Removal** - Strips embedded fonts to reduce file size\n- **Image Optimization** - Grayscale conversion, resizing to 480px max width\n- **XTC/XTCH Conversion** - Convert EPUBs to Xteink's native format\n\n```bash\n# Optimize EPUB\npython src/optimizer.py ./ebooks ./optimized\n\n# Convert to XTCH format\npython src/converter.py book.epub book.xtch --font fonts/MyFont.ttf\n```\n\n## Contributing\n\nContributions are very welcome!\n\n### To submit a contribution:\n\n1. Fork the repo\n2. Create a branch (`feature/your-feature`)\n3. Make changes\n4. Submit a PR\n\n---\n\nPapyrix is a fork of [CrossPoint Reader](https://github.com/daveallie/crosspoint-reader) by Dave Allie.\n\nX4 hardware insights from [bb_epaper](https://github.com/bitbank2/bb_epaper) by Larry Bank.\n\nMarkdown parsing using [MD4C](https://github.com/mity/md4c) by Martin Mitáš.\n\nCSS parser adapted from [microreader](https://github.com/CidVonHighwind/microreader) by CidVonHighwind.\n\n**Not affiliated with Xteink or any manufacturer of the X4 hardware**.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigbag%2Fpapyrix-reader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbigbag%2Fpapyrix-reader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbigbag%2Fpapyrix-reader/lists"}