Zmd is a Markdown parser and HTML translator written in 100% pure Zig with zero dependencies.
Zmd is used by the Jetzig web framework.
- Headers (H1->H6)
- bold
- italic
code
- Links
- Images
- Fenced code blocks (with info string)
- Ordered lists
- Unordered lists
const std = @import("std");
const Zmd = @import("zmd").Zmd;
const fragments = @import("zmd").html.DefaultFragments;
pub fn main() !void {
var zmd = Zmd.init(std.testing.allocator);
defer zmd.deinit();
try zmd.parse(
\\# Header
\\## Sub-header
\\### Sub-sub-header
\\
\\some text in **bold** and _italic_
\\
\\a paragraph
\\
\\```zig
\\some code
\\```
\\some more text with a `code` fragment
);
const html = try zmd.toHtml(fragments);
defer std.testing.allocator.free(html);
}
The default HTML formatter provides a set of fragments that can be overridden. Fragments can be either:
- A two-element tuple containing an open and close tag (e.g.
.{ "<div>", </div>" }
); - A function that receives
std.mem.Allocator
andzmd.Node
, returning![]const u8
.
Simply define a struct with the appropriate declarations of either type and Zmd will use the provided fragments, falling back to defaults for anything that is not defined.
Some node types provie special attributes such as:
meta
- provided onblock
elements. This is the language specifier (zig
) in this example:
```zig
if (true) std.debug.print("some zig code");
```
href
,title
- provided onimage
andlink
elements.
const MyFragments = struct {
pub const h1 = .{ "<h1 class='text-xl font-bold'>", "</h1>\n" };
pub fn block(allocator: std.mem.Allocator, node: Node) ![]const u8 {
const style = "font-family: Monospace;";
return if (node.meta) |meta|
std.fmt.allocPrint(allocator,
\\<pre class="language-{s}" style="{s}"><code>{s}</code></pre>
, .{ meta, style, node.content })
else
std.fmt.allocPrint(allocator,
\\<pre style="{s}"><code>{s}</code></pre>
, .{ style, node.content });
}
}
And then:
const html = try zmd.toHtml(MyFragments);
See src/zmd/html.zig for the full reference.
Zmd is MIT-licensed.