about it"))
return md.to_html("bare https://example.com links too")
```
### Backslash escapes
A backslash before any of \ ` * _ { } [ ] ( ) # + - . ! : | & < > ^ ~ renders the character literally; before anything else the backslash itself stays in the output.
```lua
local md = require("santoku.markdown")
print(md.to_html("\\*not emphasized\\* but *emphasized*"))
print(md.to_html("\\# not a heading"))
return md.to_html("\\q is not in the escape set")
```
### Entities and ampersands
Anything matching the entity syntax (ampersand, optional hash, alphanumerics, semicolon) passes through untouched; a lone ampersand is escaped to amp.
```lua
local md = require("santoku.markdown")
print(md.to_html("& and © pass through"))
print(md.to_html("AT&T gets its ampersand escaped"))
return md.to_html("¬anentity because no semicolon")
```
### HTML escaping
Special characters in plain text and code spans are entity-escaped: angle brackets, ampersands, double quotes, and single quotes.
```lua
local md = require("santoku.markdown")
print(md.to_html("a < b & c"))
print(md.to_html("`5 > 4` is true"))
print(md.to_html("it's got 'singles'"))
return md.to_html('say "hello"')
```
### Raw HTML passes through
With all render flags at zero, inline tags and block-level HTML are emitted verbatim, not escaped. Useful for trusted prose, and a reason to sanitize or pre-escape untrusted input before rendering.
```lua
local md = require("santoku.markdown")
print(md.to_html("inline spans survive"))
return md.to_html("\nA whole block, kept as is.\n
")
```
### Fenced code, pipe tables and strikethrough
The binding enables the fenced_code, tables and strikethrough extensions: triple backticks open a code block, pipe rows with a dashed separator render a table, and double tildes render del. Indented code blocks still work.
```lua
local md = require("santoku.markdown")
print(md.to_html("```\na code block\n```"))
print(md.to_html("| a | b |\n|---|---|\n| 1 | 2 |"))
return md.to_html("~~struck~~")
```
### Argument handling and edge cases
The binding takes exactly one argument through luaL_checklstring: extra arguments are dropped, numbers coerce through Lua's standard string conversion, non-strings like nil raise, and empty input renders to the empty string.
```lua
local md = require("santoku.markdown")
print(md.to_html("first", "ignored", "also ignored"))
print(md.to_html(42))
print("empty in, empty out:", "[" .. md.to_html("") .. "]")
local ok, err = pcall(md.to_html, nil)
print(ok, err)
return ok
```
### Composing with santoku.string
Interpolate a Markdown template with the base library, then render it.
```lua
local md = require("santoku.markdown")
local str = require("santoku.string")
local doc = str.interp("# %name\n\nThe %name rock wraps %impl and returns HTML.", {
name = "santoku-markdown",
impl = "Sundown",
})
print(doc)
return md.to_html(doc)
```
### Data to page with santoku.mustache
The two renderers chain: mustache turns a table into Markdown source, to_html turns that into markup. A changelog or notes pipeline works this way.
```lua
local md = require("santoku.markdown")
local mch = require("santoku.mustache")
local tpl = mch("# {{title}}\n\n{{#items}}- {{.}}\n{{/items}}")
local doc = tpl({
title = "Release notes",
items = { "faster parse", "smaller wasm", "same one-function API" },
})
print(doc)
return md.to_html(doc)
```