Marcli.Theme (Marcli v0.3.1)

View Source

Theme configuration for terminal Markdown rendering.

Every visual aspect of the rendered output is controlled by fields in this struct: ANSI escape sequences, marker characters, glyphs, box-drawing characters, and sizing.

Color values

All fields that accept ANSI escape sequences (headings, inline styles, code blocks, etc.) can be given in two forms:

  • Binary -- a raw ANSI escape string such as "\e[1;33m", exactly as before.

  • {Color.input(), keyword()} -- a tuple where the first element is anything Color.new/1 accepts (a hex string like "#ff9900", a CSS named colour like "red", an atom like :rebeccapurple, or a Color.* struct) and the second element is an options keyword passed to Color.ANSI.to_string/2. Supported options are :mode (:truecolor, :ansi256, :ansi16) and :layer (:foreground, :background).

The tuple form is resolved eagerly when the theme is constructed via merge/1 or load/1, so there is no runtime overhead.

Requires the optional :color dependency:

{:color, "~> 0.3", optional: true}

Examples

Marcli.Theme.merge(h1: {"#ff9900", mode: :truecolor})
Marcli.Theme.merge(h1: {"red", mode: :ansi256})
Marcli.Theme.merge(h1: {"red", mode: :ansi16, layer: :foreground})

Loading from file

theme = Marcli.Theme.load(".marcli.exs")
Marcli.render(markdown, theme: theme)

The file must evaluate to a keyword list whose keys match struct fields. Unknown keys are silently ignored.

Defaults

Calling Marcli.Theme.default() returns the built-in theme that matches the hardcoded rendering from Marcli v0.1.

Summary

Types

A colour value accepted by theme fields.

t()

Functions

Returns the built-in default theme.

Returns the default syntax highlighting color map.

Loads a theme from the given file path.

Merges a keyword list of overrides into the default theme.

Resolves a colour value to an ANSI escape binary.

Types

color_input()

@type color_input() :: String.t() | {term(), keyword()}

A colour value accepted by theme fields.

Either a ready-made ANSI escape binary or a {Color.input(), keyword()} tuple that will be resolved via Color.ANSI.to_string/2 at theme construction time.

t()

@type t() :: %Marcli.Theme{
  block_quote: String.t(),
  block_quote_prefix: String.t(),
  bold: String.t(),
  bullet_marker: String.t(),
  code_border: String.t(),
  code_bottom: String.t(),
  code_left: String.t(),
  code_text: String.t(),
  code_top: String.t(),
  h1: String.t(),
  h2: String.t(),
  h3: String.t(),
  html_block: String.t(),
  image_prefix: String.t(),
  image_suffix: String.t(),
  image_text: String.t(),
  image_url: String.t(),
  inline_code: String.t(),
  italic: String.t(),
  link_text: String.t(),
  link_url: String.t(),
  list_continuation: String.t(),
  ordered_glyphs: [String.t()],
  ordered_indent: String.t(),
  reset: String.t(),
  strikethrough: String.t(),
  syntax: %{required(atom()) => String.t()},
  syntax_highlight: boolean(),
  table_border: String.t(),
  table_chars: %{required(atom()) => String.t()},
  table_header: String.t(),
  task_checked: String.t(),
  task_unchecked: String.t(),
  thematic_break: String.t(),
  thematic_break_char: String.t(),
  thematic_break_width: non_neg_integer()
}

Functions

default()

@spec default() :: t()

Returns the built-in default theme.

default_syntax()

@spec default_syntax() :: %{required(atom()) => String.t()}

Returns the default syntax highlighting color map.

load(path \\ ".marcli.exs")

@spec load(Path.t()) :: t()

Loads a theme from the given file path.

The file must evaluate to a keyword list. Keys that match struct fields override the defaults; unknown keys are ignored.

Returns default() when the file does not exist.

merge(overrides)

@spec merge(keyword()) :: t()

Merges a keyword list of overrides into the default theme.

Colour values may be given as raw ANSI escape binaries or as {Color.input(), keyword()} tuples that will be resolved via Color.ANSI.to_string/2. Map-valued fields (:syntax, :table_chars) have their individual values resolved recursively.

Marcli.Theme.merge(h1: "\e[1;31m")
#=> %Marcli.Theme{h1: "\e[1;31m", ...defaults...}

Marcli.Theme.merge(h1: {"red", mode: :truecolor})
#=> %Marcli.Theme{h1: "\e[38;2;255;0;0m", ...defaults...}

resolve_color(value)

@spec resolve_color(color_input()) :: String.t()

Resolves a colour value to an ANSI escape binary.

Returns binaries unchanged. For {Color.input(), keyword()} tuples, delegates to Color.ANSI.to_string/2 (requires the optional :color dependency).

Examples

iex> Marcli.Theme.resolve_color("\e[31m")
"\e[31m"

iex> Marcli.Theme.resolve_color({"red", []})
"\e[38;2;255;0;0m"

iex> Marcli.Theme.resolve_color({"#00ff00", mode: :ansi256})
"\e[38;5;46m"