aboutsummaryrefslogtreecommitdiff
path: root/docs/src/app/ui/markdown.gleam
blob: 8bc00daef35a9d4f5e90cf5a3153df9a4907a9d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// IMPORTS ---------------------------------------------------------------------

import gleam/int
import gleam/list
import lustre/attribute
import lustre/element.{Element}
import lustre/element/html

// MARKDOWN ELEMENTS -----------------------------------------------------------

pub fn code(src: String) -> Element(msg) {
  html.pre([], [html.code([], [element.text(src)])])
}

pub fn emphasis(content: List(Element(msg))) {
  html.em([], content)
}

pub fn heading(
  depth: Int,
  title: String,
  tags: List(String),
  id: String,
) -> Element(msg) {
  let depth = int.min(depth, 3)
  let tags = list.map(tags, heading_tag)

  case depth {
    1 ->
      html.h1(
        [attribute.class("flex items-center justify-between"), attribute.id(id)],
        [
          heading_title(title, id),
          html.p([attribute.class("flex gap-4")], tags),
        ],
      )
    2 ->
      html.h2(
        [
          attribute.class("flex items-center justify-between border-t"),
          attribute.id(id),
        ],
        [
          heading_title(title, id),
          html.p([attribute.class("flex gap-4")], tags),
        ],
      )
    3 ->
      html.h3(
        [attribute.class("flex items-center justify-between"), attribute.id(id)],
        [
          heading_title(title, id),
          html.p([attribute.class("flex gap-2")], tags),
        ],
      )
  }
}

fn heading_title(title: String, href: String) -> Element(msg) {
  html.span(
    [attribute.class("group")],
    [
      element.text(title),
      html.a(
        [
          attribute.href("#" <> href),
          attribute.class("pl-2 text-gray-200 opacity-0 transition-opacity"),
          attribute.class("group-hover:underline group-hover:opacity-100"),
        ],
        [element.text("#")],
      ),
    ],
  )
}

fn heading_tag(tag: String) -> Element(msg) {
  html.span(
    [
      attribute.class(
        "px-2 py-1 text-xs text-gray-700 border border-gray-200 rounded",
      ),
    ],
    [element.text(tag)],
  )
}

pub fn inline_code(src: String) -> Element(msg) {
  html.code([], [element.text(src)])
}

pub fn link(href: String, content: List(Element(msg))) -> Element(msg) {
  html.a([attribute.href(href)], content)
}

pub fn list(ordered: Bool, items: List(Element(msg))) -> Element(msg) {
  case ordered {
    True -> html.ol([], items)
    False -> html.ul([], items)
  }
}

pub fn list_item(content: List(Element(msg))) -> Element(msg) {
  html.li([], content)
}

pub fn paragraph(content: List(Element(msg))) -> Element(msg) {
  html.p([], content)
}

pub fn strong(content: List(Element(msg))) -> Element(msg) {
  html.strong([], content)
}

pub fn text(content: String) -> Element(msg) {
  element.text(content)
}