WardrikDaemon.Console.Markdown (wardrik_daemon v0.1.0-rc.1)

Copy Markdown

Renders streamed markdown a line at a time.

Text arrives a token at a time and must reach the screen before the document is finished, so this renders lines, not documents. push/2 takes what arrived and returns the lines now complete. It keeps the rest:

{lines, buffer} = WardrikDaemon.Console.Markdown.push(WardrikDaemon.Console.Markdown.new(), "# Title\nsome ")
{lines, buffer} = WardrikDaemon.Console.Markdown.push(buffer, "prose\n")
{lines, _buffer} = WardrikDaemon.Console.Markdown.flush(buffer)

A line is Owl.Data. Two constructs span lines:

  • a fenced code block - the buffer tracks whether it's inside one.
  • a table - its rows are held back until the line after it arrives. They come back together as one WardrikDaemon.Console.Table, which whoever draws it lays out at its own width.

tail/1 returns the unfinished line, for a screen that shows text before its line is complete.

Nothing here wraps. Whoever draws a line wraps it at its own width, so a resized screen can wrap it again.

Summary

Types

What one complete line renders to: styled text, or a table.

t()

Text not yet a complete line, whether it sits inside a fence, and the table rows held back.

Functions

Returns the contents of each fenced code block in text, in order, without the fences or a trailing newline.

Renders whatever is left, for the end of a stream.

Renders one complete line of markdown, outside any fence.

Returns an empty buffer.

Adds text and returns the lines it completed: rendered, in order, without their newlines.

Returns the unfinished line, rendered as if the stream ended here, or nil if nothing is pending.

Types

line()

What one complete line renders to: styled text, or a table.

t()

@type t() :: %WardrikDaemon.Console.Markdown{
  fenced?: boolean(),
  pending: String.t(),
  table: [String.t()]
}

Text not yet a complete line, whether it sits inside a fence, and the table rows held back.

Functions

code_blocks(text)

@spec code_blocks(String.t()) :: [String.t()]

Returns the contents of each fenced code block in text, in order, without the fences or a trailing newline.

flush(buffer)

@spec flush(t()) :: {[line()], t()}

Renders whatever is left, for the end of a stream.

line(text)

@spec line(String.t()) :: Owl.Data.t()

Renders one complete line of markdown, outside any fence.

new()

@spec new() :: t()

Returns an empty buffer.

push(buffer, text)

@spec push(t(), String.t()) :: {[line()], t()}

Adds text and returns the lines it completed: rendered, in order, without their newlines.

tail(markdown)

@spec tail(t()) :: Owl.Data.t() | nil

Returns the unfinished line, rendered as if the stream ended here, or nil if nothing is pending.

It's provisional: the same text is rendered again, as a line, once its newline arrives.