examples/custom_theme.livemd

<!-- livebook:{"persist_outputs":true} -->

# Custom Theme

```elixir
Mix.install([
  {:mdex, ">= 0.11.3"},
  {:kino, "~> 0.16"}
])
```

## Intro

MDEx uses [Lumis](https://hex.pm/packages/lumis) for syntax highlighting, which supports customizable themes. This example shows how to modify an existing theme by changing styles for specific syntax elements like function calls.

## Customization

Below we'll customize the `github_light` theme but you can work with any [%Lumis.Theme{}](https://hexdocs.pm/lumis/Lumis.Theme.html) or build one from scratch.

```elixir
theme = Lumis.Theme.get("github_light")

function_call_style =
  %Lumis.Theme.Style{
    fg: "#d1242f",
    bg: "#e4b7be",
    bold: true
  }

new_theme = put_in(
  theme,
  [Access.key!(:highlights), Access.key!("function.call")],
  function_call_style
)
```

<!-- livebook:{"output":true} -->

```
%Lumis.Theme{
  name: "github_light",
  appearance: :light,
  revision: "c106c9472154d6b2c74b74565616b877ae8ed31d",
  highlights: %{
    "function.macro" => %Lumis.Theme.Style{
      fg: "#6639ba",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "variable.builtin" => %Lumis.Theme.Style{
      fg: "#0550ae",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "markup.list.checked" => %Lumis.Theme.Style{
      fg: "#116329",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "character" => %Lumis.Theme.Style{
      fg: "#0a3069",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "string.special.symbol" => %Lumis.Theme.Style{
      fg: "#0550ae",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "markup.strong" => %Lumis.Theme.Style{
      fg: "#1f2328",
      bg: nil,
      bold: true,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "markup.list.unchecked" => %Lumis.Theme.Style{
      fg: "#57606a",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "variable.parameter.builtin" => %Lumis.Theme.Style{
      fg: "#0550ae",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "character.special" => %Lumis.Theme.Style{
      fg: "#1f2328",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "boolean" => %Lumis.Theme.Style{
      fg: "#0550ae",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "string.escape" => %Lumis.Theme.Style{
      fg: "#0a3069",
      bg: nil,
      bold: true,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    "keyword.exception" => %Lumis.Theme.Style{
      fg: "#0550ae",
      bg: nil,
      bold: false,
      italic: false,
      text_decoration: %Lumis.Theme.TextDecoration{underline: nil, strikethrough: false}
    },
    ...
  }
}
```

````elixir
options = [
  syntax_highlight: [formatter: {:html_inline, theme: new_theme}]
]

"""
# Elixir
```elixir
# elixir example

def fib(n), do: fib(n, 1, 1)

def fib(0, _a, _b), do: []

def fib(n, a, b) when n > 0 do
  [a | fib(n - 1, b, a + b)]
end
```

# Ruby
```ruby
# ruby example

def fibonacci(n)
  return n if (0..1).include?(n)
  (fibonacci(n - 1) + fibonacci(n - 2))
end
```

# Rust
```rust
// rust example

fn fibonacci(n: u32) -> u32 {
  match n {
    0 => 1,
    1 => 1,
    _ => fibonacci(n - 1) + fibonacci(n - 2),
  }
}
```
"""
|> MDEx.to_html!(options)
|> Kino.HTML.new()
````