All files / markdown / mod.ts

100.00% Branches 11/11
100.00% Lines 31/31
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
 
x5
 
 
 
x5
x5
x20
x5
x5
 
 
x5
x5
x5
x5
x5
x5
x13
x14
x14
x60
x20
x20
x13
x15
x45
x15
x13
x13
x19
x19
x19
x20
x13
x5
 
 
x5




































// Imports
import { type Directive, Phase } from "@mizu/internal/engine"
export type * from "@mizu/internal/engine"

/** Typings. */
export const typings = {
  modifiers: {
    trim: { type: Boolean, enforce: true },
  },
} as const

/** `*markdown` directive. */
export const _markdown = {
  name: "*markdown",
  phase: Phase.CONTENT,
  default: "this.textContent",
  typings,
  async execute(renderer, element, { attributes: [attribute], ...options }) {
    if (!renderer.isHtmlElement(element)) {
      return
    }
    const parsed = renderer.parseAttribute(attribute, typings, { modifiers: true })
    const { Renderer } = await import("./import/markdown/renderer.ts")
    let markdown = Renderer
    if (parsed.tag) {
      const plugins = await Promise.all(parsed.tag.split(",").map(async (name) => (await import(`./import/markdown/plugins/${name}.ts`)).default))
      markdown = await Renderer.with({ plugins }) as unknown as typeof markdown
    }
    let content = `${await renderer.evaluate(element, attribute.value || this.default, options)}`
    if (parsed.modifiers.trim) {
      const trim = content.match(/^[ \t]*\S/m)?.[0].match(/\S/)?.index ?? 0
      content = content.replaceAll(new RegExp(`^[ \\t]{${trim}}`, "gm"), "")
    }
    element.innerHTML = await markdown.render(content)
  },
} as Directive<null, typeof typings> & { default: NonNullable<Directive["default"]> }

/** Default exports. */
export default _markdown