Skip to content

Output Formats

Inkfeed can produce output in multiple formats simultaneously. Each format is handled by a dedicated writer class.

Writer Base Class

All writers implement the FormatWriter interface from output/base.py:

class FormatWriter:
    name: str  # e.g., "html", "md"

    def __init__(self, config: GeneralConfig): ...
    def setup(self) -> None: ...
    def write_source(self, result: ArchiveResult, output_dir: Path, date_str: str) -> list[IndexEntry]: ...
    def write_source_index(self, source_dir: Path, display_name: str, date_str: str, entries: list[IndexEntry]) -> None: ...
    def write_date_index(self, date_dir: Path, date_str: str, entries: list[IndexEntry]) -> None: ...
    def teardown(self) -> None: ...

Lifecycle

  1. setup() — Called once before any writing. Initialize resources here (e.g., start a browser for Sleepscreen).
  2. write_source() — Called for each source. Write individual article files and return index entries.
  3. write_source_index() — Write an index page for one source on one date.
  4. write_date_index() — Write the top-level index page for a date.
  5. teardown() — Called once after all writing. Clean up resources here.

Available Formats

HTML (html)

Rich, self-contained HTML pages with embedded CSS and images.

  • Uses Jinja2 templates from templates/
  • Generates per-article pages, source indices, and date indices
  • Supports embedded base64 images for full offline reading

Markdown (md)

Clean Markdown output using markdownify for HTML-to-Markdown conversion.

  • Produces .md files that render well on GitHub, Obsidian, etc.
  • Includes frontmatter-style headers
  • Image references use local paths

Gemtext (gemtext)

Output in the Gemini protocol's native text format.

  • Minimalist, link-line-based format
  • No inline formatting — links are on their own lines
  • Ideal for Gemini capsule hosting

EPUB (epub)

E-book format readable by most e-readers.

  • Uses ebooklib to generate standards-compliant EPUB files
  • One EPUB per source per day
  • Includes a table of contents

Sleepscreen (sleepscreen)

Specialized format for the Xteink X4 e-ink display's sleep screen. May also work with other e-ink devices that support cycling through sleep screen image files and 8-bit grayscale with more than 4 gray levels.

  • Renders HTML pages in a headless browser via Playwright
  • Generates 8-bit grayscale screenshot images at configured dimensions
  • Features spotlight articles and headline cards
  • Screen LUT configuration is not yet supported (text-only output works fine with default LUT)
  • Requires the sleepscreen optional dependency

Writer Registration

Writers are registered in main.py:

WRITER_MAP: dict[str, type[FormatWriter]] = {
    "html": HtmlWriter,
    "md": MarkdownWriter,
    "gemtext": GemtextWriter,
    "epub": EpubWriter,
    "sleepscreen": SleepscreenWriter,
}

Adding a New Format

  1. Create a new file in inkfeed/output/ (e.g., pdf.py)
  2. Implement a class inheriting from FormatWriter
  3. Register it in WRITER_MAP in main.py
  4. Add the format name to the output_formats list in your config