All files / code / mod.ts

100.00% Branches 17/17
100.00% Lines 39/39
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
 
x8
x24
 
 
 
x8
x8
x32
x8
x8
 
 
x8
x8
x8
x8
x8
x8
x17
x18
x18
 
 
x75
x17
x17
x17
x18
x18
x18
 
 
x17
 
 
x17
x24
x24
x24
 
 
x75
x17
x24
x24
x25
 
 
x17
x24
x24
x17
x8
 
 
x8






















































// Imports
import { type Directive, Phase } from "@mizu/internal/engine"
import mapping from "./mapping.json" with { type: "json" }
export type * from "@mizu/internal/engine"

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

/** `*code` directive. */
export const _code = {
  name: "*code",
  phase: Phase.CONTENT,
  typings,
  default: "this.textContent",
  async execute(renderer, element, { attributes: [attribute], ...options }) {
    if (!renderer.isHtmlElement(element)) {
      return
    }

    // Load language syntax
    const parsed = renderer.parseAttribute(attribute, this.typings, { modifiers: true })
    const language = (mapping as Record<PropertyKey, string>)[parsed.tag] ?? "plaintext"
    const { default: hljs } = await import("highlight.js/lib/core")
    if (!hljs.getLanguage(language)) {
      const { default: syntax } = await import(`highlight.js/lib/languages/${language}`)
      hljs.registerLanguage(language, syntax)
    }

    // Retrieve code
    let code = `${await renderer.evaluate(element, attribute.value || this.default, options)}`

    // Trim indentation
    if (parsed.modifiers.trim) {
      const trim = code.match(/^[ \t]*\S/m)?.[0].match(/\S/)?.index ?? 0
      code = code.replaceAll(new RegExp(`^[ \\t]{${trim}}`, "gm"), "")
    }

    // Highlight code
    code = hljs.highlight(code, { language }).value
    if (parsed.modifiers.trim) {
      code = code.trim()
    }
    element.innerHTML = code

    // Trim parent
    if ((parsed.modifiers.trim) && (element.parentElement?.tagName === "PRE")) {
      element.parentElement.innerHTML = element.parentElement.innerHTML.trim()
    }
  },
} as Directive<null, typeof typings> & { default: NonNullable<Directive["default"]> }

/** Default exports. */
export default _code