Skip to content

Merge the two entry points behind auto-detected input handling #1

Description

@interworks-morr

narraoke has two entry points, split by how the source is rendered:

Input Rendering
narraoke structured markdown styled HTML, screenshotted by a headless browser — keeps code blocks, tables, typography
narraoke-article a URL, text file, or pasted prose text drawn onto generated frames with PIL — no browser, no structure assumed

They share utils, tts_engine, and timing. What differs is the front end (fetch + extract vs. read a local file) and the renderer, and the renderers are genuinely incompatible: one needs a DOM to screenshot, the other needs no structure at all.

Today the user picks by choosing a command. That is a decision they should not have to make — the input usually implies the answer.

Proposal

One narraoke entry point that inspects the input and dispatches, with an override for when the guess is wrong.

Detection, in order

  1. Looks like a URL (http://, https://) → fetch, extract, plain renderer.
  2. HTML — by extension, or by content sniffing → extract, plain renderer. article_to_video._looks_like_html already does this and can move somewhere shared.
  3. Markdown with structure.md and the parse finds headings, code blocks, or tables → rich renderer.
  4. Anything else.txt, bare prose, a .md with no structure → plain renderer.

Step 3 is the interesting one: extension alone is not enough, because a .md file that is one long paragraph gains nothing from a browser screenshot and costs a Chromium round trip to find that out. The existing load_narration_blocks already classifies blocks by kind, so the signal is available before any rendering happens.

Override

--renderer rich|plain forces the choice. Needed for two reasons: a wrong guess should be recoverable without restructuring the document, and a user comparing the two renderers on the same input should be able to.

Behaviour to preserve

  • narraoke-article keeps working, or is aliased, so existing invocations do not break.
  • The article extra stays optional. A rich-renderer run must not require the extraction stack; detection has to fail gracefully when it is absent — if a URL is passed without the extra installed, say so rather than raising an ImportError.
  • Both renderers stay. This is a dispatch change, not a consolidation of rendering code.

Open questions

  • Should detection be reported in the run summary? Probably yes — "why did it pick the plain renderer?" is the obvious first support question.
  • What happens with a structured markdown file passed to the plain renderer via --renderer plain? Presumably strip the markup and narrate the text, but the fenced-code handling needs thought.
  • Is there a case for a third mode where a URL is fetched and then rendered richly? The extracted HTML could in principle be screenshotted. Out of scope here, but worth not designing it out.

Not doing

Merging the renderers themselves. They solve different problems and both are needed regardless.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions