Code

Documentation for a library is mostly code. chimera highlights Luwu, Luau and Lua while it builds the page. Readers download no highlighting script, and the colors follow whichever theme they picked. Squiggles and hovers then explain the code the way an editor would.

Code blocks

const function greet(name: string, greeting = "Hello")
    print(`{greeting}, {name}!`)
end
const greet = CodeBlock([==[
    const function greet(name: string, greeting = "Hello")
        print(`{greeting}, {name}!`)
    end
]==])
    :line_numbers()
    :copyable()

copyable() adds the copy button in the corner, and line_numbers() adds the gutter. Selecting the code never picks up the numbers.

Inline code

Call site:build("out") to write every page.

const tip = Paragraph({ "Call ", Code("site:build(\"out\")"), " to write every page." })

Every <code> tag is a Code, highlighted as Luwu unless you name another language.

Languages

The language is the second argument: CodeBlock("cargo build", "bash"). Other languages are highlighted in the browser by highlight.js, and a page only loads it when it has code that needs it. "plaintext" isn't highlighted at all, and plain() turns the colors off for a single block.

Squiggles

A Squiggle underlines a span of code the way an editor marks an error and shows its message when the reader points at it:

local name = "Ada"
print(nmae)
const typo = CodeBlock("local name = \"Ada\"\nprint(nmae)")
    :line_numbers()
    :squiggle(
        Squiggle.error(SourceSpan.on_line(2, 7, 10), "Unknown global 'nmae'"),
        Squiggle.info(SourceSpan.on_line(1, 7, 10), "'name' is only used once")
    )

Squiggle.error, Squiggle.warning and Squiggle.info use the theme's editor colors. For any other color, use Squiggle(spans, color, message).

Each span is a SourceSpan: a start and an end, both a line and a column. SourceSpan.on_line(2, 7, 10) covers columns 7 to 10 of line 2, and SourceSpan.from_string("2.7-2.10") reads the spans that luwu-analyze --formatter=gnu prints.

Hovers

A Hover shows content when the reader points at part of the code. A dotted underline tells them what to try. On a phone, tap it:

const cat = Cat("Nyla")
cat:feed(2)
const hovered = CodeBlock("const cat = Cat(\"Nyla\")\ncat:feed(2)")
    :hover(
        Hover(SourceSpan.on_line(1, 7, 9), CodeBlock("const cat: Cat")),
        Hover(SourceSpan.on_line(2, 5, 8), {
            CodeBlock("function Cat:feed(amount: number): Cat"),
            Paragraph("Feeds the cat, so it's less hungry."),
        })
    )

A hover can hold anything, from plain text to code or your own components, and one over a squiggle shows both. The Better Hovers page uses them to show real hovers from Luwu's language server.

Hover nyla to meet her.

const nyla = Code("nyla"):hover(Hover(
    SourceSpan.on_line(1, 1, 4),
    Card("Nyla", Paragraph("A small, opinionated cat."))
))
const fancy = Paragraph({ "Hover ", nyla, " to meet her." })

Your own code elements

To show code your own way, with a file name above it for example, implement SourceCode. Your class gets highlighting, squiggles and hovers too. Call render_source(out) where the code goes:

class FileSnippet implements SourceCode
    function tag(): string
        return "figure"
    end
    function __init(self, file: string?, source: string?, language: Language?)
        self.source = source or ""
        self
            :attr("data-file", file)
            :attr("data-language", language or "luwu")
    end
    function render(self, out: Writer)
        self:render_open(out)
        out:write(`<figcaption>{Text.escape(tostring(self:get_attr("data-file")))}</figcaption>`)
        out:write(`<pre><code class="language-{self:language()}">`)
        self:render_source(out)
        out:write("</code></pre></figure>")
    end
end