hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

html.ha (67907B)


      1 // License: GPL-3.0
      2 // (c) 2021-2022 Alexey Yerin <yyp@disroot.org>
      3 // (c) 2022 Byron Torres <b@torresjrjr.com>
      4 // (c) 2021-2022 Drew DeVault <sir@cmpwn.com>
      5 // (c) 2021 Eyal Sawady <ecs@d2evs.net>
      6 // (c) 2021 Thomas Bracht Laumann Jespersen <t@laumann.xyz>
      7 // (c) 2022 Umar Getagazov <umar@handlerug.me>
      8 
      9 // Note: ast::ident should never have to be escaped
     10 use bufio;
     11 use encoding::utf8;
     12 use fmt;
     13 use hare::ast;
     14 use hare::ast::{variadism};
     15 use hare::lex;
     16 use hare::module;
     17 use hare::unparse;
     18 use io;
     19 use net::ip;
     20 use net::uri;
     21 use os;
     22 use path;
     23 use strings;
     24 use strio;
     25 
     26 // Prints a string to an output handle, escaping any of HTML's reserved
     27 // characters.
     28 fn html_escape(out: io::handle, in: str) (size | io::error) = {
     29 	let z = 0z;
     30 	let iter = strings::iter(in);
     31 	for (true) {
     32 		match (strings::next(&iter)) {
     33 		case void => break;
     34 		case let rn: rune =>
     35 			z += fmt::fprint(out, switch (rn) {
     36 			case '&' =>
     37 				yield "&amp;";
     38 			case '<' =>
     39 				yield "&lt;";
     40 			case '>' =>
     41 				yield "&gt;";
     42 			case '"' =>
     43 				yield "&quot;";
     44 			case '\'' =>
     45 				yield "&apos;";
     46 			case =>
     47 				yield strings::fromutf8(utf8::encoderune(rn));
     48 			})?;
     49 		};
     50 	};
     51 	return z;
     52 };
     53 
     54 @test fn html_escape() void = {
     55        let sink = strio::dynamic();
     56        defer io::close(&sink)!;
     57        html_escape(&sink, "hello world!")!;
     58        assert(strio::string(&sink) == "hello world!");
     59 
     60        let sink = strio::dynamic();
     61        defer io::close(&sink)!;
     62        html_escape(&sink, "\"hello world!\"")!;
     63        assert(strio::string(&sink) == "&quot;hello world!&quot;");
     64 
     65        let sink = strio::dynamic();
     66        defer io::close(&sink)!;
     67        html_escape(&sink, "<hello & 'world'!>")!;
     68        assert(strio::string(&sink) == "&lt;hello &amp; &apos;world&apos;!&gt;");
     69 };
     70 
     71 // Formats output as HTML
     72 fn emit_html(ctx: *context) (void | error) = {
     73 	const decls = ctx.summary;
     74 	const ident = unparse::identstr(ctx.ident);
     75 	defer free(ident);
     76 
     77 	if (ctx.template) head(ctx.ident)?;
     78 
     79 	if (len(ident) == 0) {
     80 		fmt::fprintf(ctx.out, "<h2>The Hare standard library <span class='heading-extra'>")?;
     81 	} else {
     82 		fmt::fprintf(ctx.out, "<h2>{} <span class='heading-extra'>", ident)?;
     83 	};
     84 	for (let i = 0z; i < len(ctx.tags); i += 1) {
     85 		const mode = switch (ctx.tags[i].mode) {
     86 		case module::tag_mode::INCLUSIVE =>
     87 			yield '+';
     88 		case module::tag_mode::EXCLUSIVE =>
     89 			yield '-';
     90 		};
     91 		fmt::fprintf(ctx.out, "{}{} ", mode, ctx.tags[i].name)?;
     92 	};
     93 	fmt::fprintln(ctx.out, "</span></h2>")?;
     94 
     95 	match (ctx.readme) {
     96 	case void => void;
     97 	case let f: io::file =>
     98 		fmt::fprintln(ctx.out, "<div class='readme'>")?;
     99 		markup_html(ctx, f)?;
    100 		fmt::fprintln(ctx.out, "</div>")?;
    101 	};
    102 
    103 	let identpath = module::identpath(ctx.ident);
    104 	defer free(identpath);
    105 
    106 	let submodules: []str = [];
    107 	defer free(submodules);
    108 
    109 	for (let i = 0z; i < len(ctx.version.subdirs); i += 1) {
    110 		let dir = ctx.version.subdirs[i];
    111 		// XXX: the list of reserved directory names is not yet
    112 		// finalized. See https://todo.sr.ht/~sircmpwn/hare/516
    113 		if (dir == "contrib") continue;
    114 		if (dir == "cmd") continue;
    115 		if (dir == "docs") continue;
    116 		if (dir == "ext") continue;
    117 		if (dir == "vendor") continue;
    118 		if (dir == "scripts") continue;
    119 
    120 		let submod = [identpath, dir]: ast::ident;
    121 		if (module::lookup(ctx.mctx, submod) is module::error) {
    122 			continue;
    123 		};
    124 
    125 		append(submodules, dir);
    126 	};
    127 
    128 	if (len(submodules) != 0) {
    129 		if (len(ctx.ident) == 0) {
    130 			fmt::fprintln(ctx.out, "<h3>Modules</h3>")?;
    131 		} else {
    132 			fmt::fprintln(ctx.out, "<h3>Submodules</h3>")?;
    133 		};
    134 		fmt::fprintln(ctx.out, "<ul class='submodules'>")?;
    135 		for (let i = 0z; i < len(submodules); i += 1) {
    136 			let submodule = submodules[i];
    137 			let path = path::join("/", identpath, submodule);
    138 			defer free(path);
    139 
    140 			fmt::fprintf(ctx.out, "<li><a href='")?;
    141 			html_escape(ctx.out, path)?;
    142 			fmt::fprintf(ctx.out, "'>")?;
    143 			html_escape(ctx.out, submodule)?;
    144 			fmt::fprintfln(ctx.out, "</a></li>")?;
    145 		};
    146 		fmt::fprintln(ctx.out, "</ul>")?;
    147 	};
    148 
    149 	if (len(decls.types) == 0
    150 			&& len(decls.errors) == 0
    151 			&& len(decls.constants) == 0
    152 			&& len(decls.globals) == 0
    153 			&& len(decls.funcs) == 0) {
    154 		return;
    155 	};
    156 
    157 	fmt::fprintln(ctx.out, "<h3>Index</h3>")?;
    158 	tocentries(ctx.out, decls.types, "Types", "types")?;
    159 	tocentries(ctx.out, decls.errors, "Errors", "Errors")?;
    160 	tocentries(ctx.out, decls.constants, "Constants", "constants")?;
    161 	tocentries(ctx.out, decls.globals, "Globals", "globals")?;
    162 	tocentries(ctx.out, decls.funcs, "Functions", "functions")?;
    163 
    164 	if (len(decls.types) != 0) {
    165 		fmt::fprintln(ctx.out, "<h3>Types</h3>")?;
    166 		for (let i = 0z; i < len(decls.types); i += 1) {
    167 			details(ctx, decls.types[i])?;
    168 		};
    169 	};
    170 
    171 	if (len(decls.errors) != 0) {
    172 		fmt::fprintln(ctx.out, "<h3>Errors</h3>")?;
    173 		for (let i = 0z; i < len(decls.errors); i += 1) {
    174 			details(ctx, decls.errors[i])?;
    175 		};
    176 	};
    177 
    178 	if (len(decls.constants) != 0) {
    179 		fmt::fprintln(ctx.out, "<h3>Constants</h3>")?;
    180 		for (let i = 0z; i < len(decls.constants); i += 1) {
    181 			details(ctx, decls.constants[i])?;
    182 		};
    183 	};
    184 
    185 	if (len(decls.globals) != 0) {
    186 		fmt::fprintln(ctx.out, "<h3>Globals</h3>")?;
    187 		for (let i = 0z; i < len(decls.globals); i += 1) {
    188 			details(ctx, decls.globals[i])?;
    189 		};
    190 	};
    191 
    192 	if (len(decls.funcs) != 0) {
    193 		fmt::fprintln(ctx.out, "<h3>Functions</h3>")?;
    194 		for (let i = 0z; i < len(decls.funcs); i += 1) {
    195 			details(ctx, decls.funcs[i])?;
    196 		};
    197 	};
    198 };
    199 
    200 fn comment_html(out: io::handle, s: str) (size | io::error) = {
    201 	// TODO: handle [[references]]
    202 	let z = fmt::fprint(out, "<span class='comment'>//")?;
    203 	z += html_escape(out, s)?;
    204 	z += fmt::fprint(out, "</span><br>")?;
    205 	return z;
    206 };
    207 
    208 fn docs_html(out: io::handle, s: str, indent: size) (size | io::error) = {
    209 	const iter = strings::tokenize(s, "\n");
    210 	let z = 0z;
    211 	for (true) match (strings::next_token(&iter)) {
    212 	case let s: str =>
    213 		if (!(strings::peek_token(&iter) is void)) {
    214 			z += comment_html(out, s)?;
    215 			for (let i = 0z; i < indent; i += 1) {
    216 				z += fmt::fprint(out, "\t")?;
    217 			};
    218 		};
    219 	case void => break;
    220 	};
    221 
    222 	return z;
    223 };
    224 
    225 fn tocentries(
    226 	out: io::handle,
    227 	decls: []ast::decl,
    228 	name: str,
    229 	lname: str,
    230 ) (void | error) = {
    231 	if (len(decls) == 0) {
    232 		return;
    233 	};
    234 	fmt::fprintfln(out, "<h4>{}</h4>", name)?;
    235 	fmt::fprintln(out, "<pre>")?;
    236 	let undoc = false;
    237 	for (let i = 0z; i < len(decls); i += 1) {
    238 		if (!undoc && decls[i].docs == "") {
    239 			fmt::fprintfln(
    240 				out,
    241 				"{}<span class='comment'>// Undocumented {}:</span>",
    242 				if (i == 0) "" else "\n",
    243 				lname)?;
    244 			undoc = true;
    245 		};
    246 		tocentry(out, decls[i])?;
    247 	};
    248 	fmt::fprint(out, "</pre>")?;
    249 	return;
    250 };
    251 
    252 fn tocentry(out: io::handle, decl: ast::decl) (void | error) = {
    253 	fmt::fprintf(out, "{} ",
    254 		match (decl.decl) {
    255 		case ast::decl_func =>
    256 			yield "fn";
    257 		case []ast::decl_type =>
    258 			yield "type";
    259 		case []ast::decl_const =>
    260 			yield "const";
    261 		case []ast::decl_global =>
    262 			yield "let";
    263 		})?;
    264 	fmt::fprintf(out, "<a href='#")?;
    265 	unparse::ident(out, decl_ident(decl))?;
    266 	fmt::fprintf(out, "'>")?;
    267 	unparse::ident(out, decl_ident(decl))?;
    268 	fmt::fprint(out, "</a>")?;
    269 
    270 	match (decl.decl) {
    271 	case let t: []ast::decl_type => void;
    272 	case let g: []ast::decl_global =>
    273 		let g = g[0];
    274 		fmt::fprint(out, ": ")?;
    275 		type_html(out, 0, g._type, true)?;
    276 	case let c: []ast::decl_const =>
    277 		let c = c[0];
    278 		fmt::fprint(out, ": ")?;
    279 		type_html(out, 0, c._type, true)?;
    280 	case let f: ast::decl_func =>
    281 		prototype_html(out, 0,
    282 			f.prototype.repr as ast::func_type,
    283 			true)?;
    284 	};
    285 	fmt::fprintln(out, ";")?;
    286 	return;
    287 };
    288 
    289 fn details(ctx: *context, decl: ast::decl) (void | error) = {
    290 	fmt::fprintln(ctx.out, "<section class='member'>")?;
    291 	fmt::fprint(ctx.out, "<h4 id='")?;
    292 	unparse::ident(ctx.out, decl_ident(decl))?;
    293 	fmt::fprint(ctx.out, "'>")?;
    294 	fmt::fprintf(ctx.out, "{} ", match (decl.decl) {
    295 		case ast::decl_func =>
    296 			yield "fn";
    297 		case []ast::decl_type =>
    298 			yield "type";
    299 		case []ast::decl_const =>
    300 			yield "def";
    301 		case []ast::decl_global =>
    302 			yield "let";
    303 		})?;
    304 	unparse::ident(ctx.out, decl_ident(decl))?;
    305 	// TODO: Add source URL
    306 	fmt::fprint(ctx.out, "<span class='heading-extra'><a href='#")?;
    307 	unparse::ident(ctx.out, decl_ident(decl))?;
    308 	fmt::fprint(ctx.out, "'>[link]</a>
    309 	</span>")?;
    310 	fmt::fprintln(ctx.out, "</h4>")?;
    311 
    312 	if (len(decl.docs) == 0) {
    313 		fmt::fprintln(ctx.out, "<details>")?;
    314 		fmt::fprintln(ctx.out, "<summary>Show undocumented member</summary>")?;
    315 	};
    316 
    317 	fmt::fprintln(ctx.out, "<pre class='decl'>")?;
    318 	unparse_html(ctx.out, decl)?;
    319 	fmt::fprintln(ctx.out, "</pre>")?;
    320 
    321 	if (len(decl.docs) != 0) {
    322 		const trimmed = trim_comment(decl.docs);
    323 		defer free(trimmed);
    324 		const buf = strings::toutf8(trimmed);
    325 		markup_html(ctx, &bufio::fixed(buf, io::mode::READ))?;
    326 	} else {
    327 		fmt::fprintln(ctx.out, "</details>")?;
    328 	};
    329 
    330 	fmt::fprintln(ctx.out, "</section>")?;
    331 	return;
    332 };
    333 
    334 fn htmlref(ctx: *context, ref: ast::ident) (void | io::error) = {
    335 	const ik =
    336 		match (resolve(ctx, ref)) {
    337 		case let ik: (ast::ident, symkind) =>
    338 			yield ik;
    339 		case void =>
    340 			const ident = unparse::identstr(ref);
    341 			fmt::errorfln("Warning: Unresolved reference: {}", ident)?;
    342 			fmt::fprintf(ctx.out, "<a href='#' "
    343 				"class='ref invalid' "
    344 				"title='This reference could not be found'>{}</a>",
    345 				ident)?;
    346 			free(ident);
    347 			return;
    348 		};
    349 
    350 	// TODO: The reference is not necessarily in the stdlib
    351 	const kind = ik.1, id = ik.0;
    352 	const ident = unparse::identstr(id);
    353 	switch (kind) {
    354 	case symkind::LOCAL =>
    355 		fmt::fprintf(ctx.out, "<a href='#{0}' class='ref'>{0}</a>", ident)?;
    356 	case symkind::MODULE =>
    357 		let ipath = module::identpath(id);
    358 		defer free(ipath);
    359 		fmt::fprintf(ctx.out, "<a href='/{}' class='ref'>{}</a>",
    360 			ipath, ident)?;
    361 	case symkind::SYMBOL =>
    362 		let ipath = module::identpath(id[..len(id) - 1]);
    363 		defer free(ipath);
    364 		fmt::fprintf(ctx.out, "<a href='/{}#{}' class='ref'>{}</a>",
    365 			ipath, id[len(id) - 1], ident)?;
    366 	case symkind::ENUM_LOCAL =>
    367 		fmt::fprintf(ctx.out, "<a href='#{}' class='ref'>{}</a>",
    368 			id[len(id) - 2], ident)?;
    369 	case symkind::ENUM_REMOTE =>
    370 		let ipath = module::identpath(id[..len(id) - 2]);
    371 		defer free(ipath);
    372 		fmt::fprintf(ctx.out, "<a href='/{}#{}' class='ref'>{}</a>",
    373 			ipath, id[len(id) - 2], ident)?;
    374 	};
    375 	free(ident);
    376 };
    377 
    378 fn markup_html(ctx: *context, in: io::handle) (void | io::error) = {
    379 	let parser = parsedoc(in);
    380 	let waslist = false;
    381 	for (true) {
    382 		const tok = match (scandoc(&parser)) {
    383 			case void =>
    384 				if (waslist) {
    385 					fmt::fprintln(ctx.out, "</ul>")?;
    386 				};
    387 				break;
    388 			case let tok: token =>
    389 				yield tok;
    390 			};
    391 		match (tok) {
    392 		case paragraph =>
    393 			if (waslist) {
    394 				fmt::fprintln(ctx.out, "</ul>")?;
    395 				waslist = false;
    396 			};
    397 			fmt::fprintln(ctx.out)?;
    398 			fmt::fprint(ctx.out, "<p>")?;
    399 		case let tx: text =>
    400 			defer free(tx);
    401 			match (uri::parse(strings::trim(tx))) {
    402 			case let uri: uri::uri =>
    403 				defer uri::finish(&uri);
    404 				if (uri.host is net::ip::addr || len(uri.host as str) > 0) {
    405 					fmt::fprint(ctx.out, "<a rel='nofollow noopener' href='")?;
    406 					uri::fmt(ctx.out, &uri)?;
    407 					fmt::fprint(ctx.out, "'>")?;
    408 					html_escape(ctx.out, tx)?;
    409 					fmt::fprint(ctx.out, "</a>")?;
    410 				} else {
    411 					html_escape(ctx.out, tx)?;
    412 				};
    413 			case uri::invalid =>
    414 				html_escape(ctx.out, tx)?;
    415 			};
    416 		case let re: reference =>
    417 			htmlref(ctx, re)?;
    418 		case let sa: sample =>
    419 			if (waslist) {
    420 				fmt::fprintln(ctx.out, "</ul>")?;
    421 				waslist = false;
    422 			};
    423 			fmt::fprint(ctx.out, "<pre class='sample'>")?;
    424 			html_escape(ctx.out, sa)?;
    425 			fmt::fprint(ctx.out, "</pre>")?;
    426 			free(sa);
    427 		case listitem =>
    428 			if (!waslist) {
    429 				fmt::fprintln(ctx.out, "<ul>")?;
    430 				waslist = true;
    431 			};
    432 			fmt::fprint(ctx.out, "<li>")?;
    433 		};
    434 	};
    435 	fmt::fprintln(ctx.out)?;
    436 	return;
    437 };
    438 
    439 // Forked from [[hare::unparse]]
    440 fn unparse_html(out: io::handle, d: ast::decl) (size | io::error) = {
    441 	let n = 0z;
    442 	match (d.decl) {
    443 	case let c: []ast::decl_const =>
    444 		n += fmt::fprintf(out, "<span class='keyword'>def</span> ")?;
    445 		for (let i = 0z; i < len(c); i += 1) {
    446 			n += unparse::ident(out, c[i].ident)?;
    447 			n += fmt::fprint(out, ": ")?;
    448 			n += type_html(out, 0, c[i]._type, false)?;
    449 			if (i + 1 < len(c)) {
    450 				n += fmt::fprint(out, ", ")?;
    451 			};
    452 		};
    453 	case let g: []ast::decl_global =>
    454 		n += fmt::fprintf(out, "<span class='keyword'>{}</span>",
    455 			if (g[0].is_const) "const " else "let ")?;
    456 		for (let i = 0z; i < len(g); i += 1) {
    457 			n += unparse::ident(out, g[i].ident)?;
    458 			n += fmt::fprint(out, ": ")?;
    459 			n += type_html(out, 0, g[i]._type, false)?;
    460 			if (i + 1 < len(g)) {
    461 				n += fmt::fprint(out, ", ")?;
    462 			};
    463 		};
    464 	case let t: []ast::decl_type =>
    465 		n += fmt::fprint(out, "<span class='keyword'>type</span> ")?;
    466 		for (let i = 0z; i < len(t); i += 1) {
    467 			n += unparse::ident(out, t[i].ident)?;
    468 			n += fmt::fprint(out, " = ")?;
    469 			n += type_html(out, 0, t[i]._type, false)?;
    470 			if (i + 1 < len(t)) {
    471 				n += fmt::fprint(out, ", ")?;
    472 			};
    473 		};
    474 	case let f: ast::decl_func =>
    475 		n += fmt::fprint(out, switch (f.attrs) {
    476 		case ast::fndecl_attrs::NONE =>
    477 			yield "";
    478 		case ast::fndecl_attrs::FINI =>
    479 			yield "@fini ";
    480 		case ast::fndecl_attrs::INIT =>
    481 			yield "@init ";
    482 		case ast::fndecl_attrs::TEST =>
    483 			yield "@test ";
    484 		})?;
    485 		let p = f.prototype.repr as ast::func_type;
    486 		if (p.attrs & ast::func_attrs::NORETURN != 0) {
    487 			n += fmt::fprint(out, "@noreturn ")?;
    488 		};
    489 		n += fmt::fprint(out, "<span class='keyword'>fn</span> ")?;
    490 		n += unparse::ident(out, f.ident)?;
    491 		n += prototype_html(out, 0,
    492 			f.prototype.repr as ast::func_type,
    493 			false)?;
    494 	};
    495 	n += fmt::fprint(out, ";")?;
    496 	return n;
    497 };
    498 
    499 fn enum_html(
    500 	out: io::handle,
    501 	indent: size,
    502 	t: ast::enum_type
    503 ) (size | io::error) = {
    504 	let z = 0z;
    505 
    506 	z += fmt::fprint(out, "<span class='type'>enum</span> ")?;
    507 	if (t.storage != ast::builtin_type::INT) {
    508 		z += fmt::fprintf(out, "<span class='type'>{}</span> ",
    509 			unparse::builtin_type(t.storage))?;
    510 	};
    511 	z += fmt::fprintln(out, "{")?;
    512 	indent += 1;
    513 	for (let i = 0z; i < len(t.values); i += 1) {
    514 		for (let i = 0z; i < indent; i += 1) {
    515 			z += fmt::fprint(out, "\t")?;
    516 		};
    517 		const val = t.values[i];
    518 		let wrotedocs = false;
    519 		if (val.docs != "") {
    520 			// Check if comment should go above or next to field
    521 			if (multiline_comment(val.docs)) {
    522 				z += docs_html(out, val.docs, indent)?;
    523 				wrotedocs = true;
    524 			};
    525 		};
    526 
    527 		z += fmt::fprint(out, val.name)?;
    528 
    529 		match (val.value) {
    530 		case null => void;
    531 		case let expr: *ast::expr =>
    532 			z += fmt::fprint(out, " = ")?;
    533 			z += unparse::expr(out, indent, *expr)?;
    534 		};
    535 
    536 		z += fmt::fprint(out, ",")?;
    537 
    538 		if (val.docs != "" && !wrotedocs) {
    539 			z += fmt::fprint(out, " ")?;
    540 			z += docs_html(out, val.docs, 0)?;
    541 		} else {
    542 			z += fmt::fprintln(out)?;
    543 		};
    544 	};
    545 	indent -= 1;
    546 	for (let i = 0z; i < indent; i += 1) {
    547 		z += fmt::fprint(out, "\t")?;
    548 	};
    549 	z += newline(out, indent)?;
    550 	z += fmt::fprint(out, "}")?;
    551 	return z;
    552 };
    553 
    554 fn struct_union_html(
    555 	out: io::handle,
    556 	indent: size,
    557 	t: ast::_type,
    558 	brief: bool,
    559 ) (size | io::error) = {
    560 	let z = 0z;
    561 	let members = match (t.repr) {
    562 	case let t: ast::struct_type =>
    563 		z += fmt::fprint(out, "<span class='keyword'>struct</span> {")?;
    564 		yield t: []ast::struct_member;
    565 	case let t: ast::union_type =>
    566 		z += fmt::fprint(out, "<span class='keyword'>union</span> {")?;
    567 		yield t: []ast::struct_member;
    568 	};
    569 
    570 	indent += 1;
    571 	for (let i = 0z; i < len(members); i += 1) {
    572 		const member = members[i];
    573 
    574 		z += newline(out, indent)?;
    575 		if (member.docs != "" && !brief) {
    576 			z += docs_html(out, member.docs, indent)?;
    577 		};
    578 		match (member._offset) {
    579 		case null => void;
    580 		case let expr: *ast::expr =>
    581 			z += fmt::fprint(out, "@offset(")?;
    582 			z += unparse::expr(out, indent, *expr)?;
    583 			z += fmt::fprint(out, ") ")?;
    584 		};
    585 
    586 		match (member.member) {
    587 		case let f: ast::struct_field =>
    588 			z += fmt::fprintf(out, "{}: ", f.name)?;
    589 			z += type_html(out, indent, *f._type, brief)?;
    590 		case let embed: ast::struct_embedded =>
    591 			z += type_html(out, indent, *embed, brief)?;
    592 		case let indent: ast::struct_alias =>
    593 			z += unparse::ident(out, indent)?;
    594 		};
    595 		z += fmt::fprint(out, ",")?;
    596 	};
    597 
    598 	indent -= 1;
    599 	z += newline(out, indent)?;
    600 	z += fmt::fprint(out, "}")?;
    601 
    602 	return z;
    603 };
    604 
    605 fn type_html(
    606 	out: io::handle,
    607 	indent: size,
    608 	_type: ast::_type,
    609 	brief: bool,
    610 ) (size | io::error) = {
    611 	if (brief) {
    612 		let buf = strio::dynamic();
    613 		defer io::close(&buf)!;
    614 		unparse::_type(&buf, indent, _type)?;
    615 		return html_escape(out, strio::string(&buf))?;
    616 	};
    617 
    618 	// TODO: More detailed formatter which can find aliases nested deeper in
    619 	// other types and highlight more keywords, like const
    620 	let z = 0z;
    621 
    622 	if (_type.flags & ast::type_flags::CONST != 0
    623 			&& !(_type.repr is ast::func_type)) {
    624 		z += fmt::fprint(out, "<span class='keyword'>const</span> ")?;
    625 	};
    626 
    627 	if (_type.flags & ast::type_flags::ERROR != 0) {
    628 		if (_type.repr is ast::builtin_type) {
    629 			z += fmt::fprint(out, "<span class='type'>!</span>")?;
    630 		} else {
    631 			z += fmt::fprint(out, "!")?;
    632 		};
    633 	};
    634 
    635 	match (_type.repr) {
    636 	case let a: ast::alias_type =>
    637 		if (a.unwrap) {
    638 			z += fmt::fprint(out, "...")?;
    639 		};
    640 		z += unparse::ident(out, a.ident)?;
    641 	case let t: ast::builtin_type =>
    642 		z += fmt::fprintf(out, "<span class='type'>{}</span>",
    643 			unparse::builtin_type(t))?;
    644 	case let t: ast::tagged_type =>
    645 		// rough estimate of current line length
    646 		let linelen: size = z + (indent + 1) * 8;
    647 		z = 0;
    648 		linelen += fmt::fprint(out, "(")?;
    649 		for (let i = 0z; i < len(t); i += 1) {
    650 			linelen += type_html(out, indent, *t[i], brief)?;
    651 			if (i + 1 == len(t)) break;
    652 			linelen += fmt::fprint(out, " |")?;
    653 			// use 72 instead of 80 to give a bit of leeway for long
    654 			// type names
    655 			if (linelen > 72) {
    656 				z += linelen;
    657 				linelen = (indent + 1) * 8;
    658 				z += fmt::fprintln(out)?;
    659 				for (let i = 0z; i < indent; i += 1) {
    660 					z += fmt::fprint(out, "\t")?;
    661 				};
    662 			} else {
    663 				linelen += fmt::fprint(out, " ")?;
    664 			};
    665 		};
    666 		z += linelen;
    667 		z += fmt::fprint(out, ")")?;
    668 	case let t: ast::tuple_type =>
    669 		// rough estimate of current line length
    670 		let linelen: size = z + (indent + 1) * 8;
    671 		z = 0;
    672 		linelen += fmt::fprint(out, "(")?;
    673 		for (let i = 0z; i < len(t); i += 1) {
    674 			linelen += type_html(out, indent, *t[i], brief)?;
    675 			if (i + 1 == len(t)) break;
    676 			linelen += fmt::fprint(out, ",")?;
    677 			// use 72 instead of 80 to give a bit of leeway for long
    678 			// type names
    679 			if (linelen > 72) {
    680 				z += linelen;
    681 				linelen = (indent + 1) * 8;
    682 				z += fmt::fprintln(out)?;
    683 				for (let i = 0z; i < indent; i += 1) {
    684 					z += fmt::fprint(out, "\t")?;
    685 				};
    686 			} else {
    687 				linelen += fmt::fprint(out, " ")?;
    688 			};
    689 		};
    690 		z += linelen;
    691 		z += fmt::fprint(out, ")")?;
    692 	case let t: ast::pointer_type =>
    693 		if (t.flags & ast::pointer_flags::NULLABLE != 0) {
    694 			z += fmt::fprint(out, "<span class='type'>nullable</span> ")?;
    695 		};
    696 		z += fmt::fprint(out, "*")?;
    697 		z += type_html(out, indent, *t.referent, brief)?;
    698 	case let t: ast::func_type =>
    699 		if (t.attrs & ast::func_attrs::NORETURN == ast::func_attrs::NORETURN) {
    700 			z += fmt::fprint(out, "@noreturn ")?;
    701 		};
    702 
    703 		z += fmt::fprint(out, "<span class='keyword'>fn</span>(")?;
    704 		for (let i = 0z; i < len(t.params); i += 1) {
    705 			const param = t.params[i];
    706 			z += fmt::fprintf(out, "{}: ",
    707 				if (len(param.name) == 0) "_" else param.name)?;
    708 			z += type_html(out, indent, *param._type, brief)?;
    709 
    710 			if (i + 1 == len(t.params)
    711 					&& t.variadism == ast::variadism::HARE) {
    712 				// TODO: Highlight that as well
    713 				z += fmt::fprint(out, "...")?;
    714 			};
    715 			if (i + 1 < len(t.params)) {
    716 				z += fmt::fprint(out, ", ")?;
    717 			};
    718 		};
    719 		if (t.variadism == ast::variadism::C) {
    720 			z += fmt::fprint(out, ", ...")?;
    721 		};
    722 		z += fmt::fprint(out, ") ")?;
    723 		z += type_html(out, indent, *t.result, brief)?;
    724 	case let t: ast::enum_type =>
    725 		z += enum_html(out, indent, t)?;
    726 	case let t: ast::list_type =>
    727 		z += fmt::fprint(out, "[")?;
    728 		match (t.length) {
    729 		case let expr: *ast::expr =>
    730 			z += unparse::expr(out, indent, *expr)?;
    731 		case ast::len_slice =>
    732 			z += 0;
    733 		case ast::len_unbounded =>
    734 			z += fmt::fprintf(out, "*")?;
    735 		case ast::len_contextual =>
    736 			z += fmt::fprintf(out, "_")?;
    737 		};
    738 		z += fmt::fprint(out, "]")?;
    739 
    740 		z += type_html(out, indent, *t.members, brief)?;
    741 	case let t: ast::struct_type =>
    742 		z += struct_union_html(out, indent, _type, brief)?;
    743 	case let t: ast::union_type =>
    744 		z += struct_union_html(out, indent, _type, brief)?;
    745 	};
    746 
    747 	return z;
    748 };
    749 
    750 fn prototype_html(
    751 	out: io::handle,
    752 	indent: size,
    753 	t: ast::func_type,
    754 	brief: bool,
    755 ) (size | io::error) = {
    756 	let n = 0z;
    757 	n += fmt::fprint(out, "(")?;
    758 
    759 	// estimate length of prototype to determine if it should span multiple
    760 	// lines
    761 	const linelen = if (len(t.params) == 0 || brief) {
    762 		yield 0z; // If no parameters or brief, only use one line.
    763 	} else {
    764 		let linelen = indent * 8 + 5;
    765 		linelen += if (len(t.params) != 0) len(t.params) * 3 - 1 else 0;
    766 		for (let i = 0z; i < len(t.params); i += 1) {
    767 			const param = t.params[i];
    768 			linelen += unparse::_type(io::empty, indent,
    769 				*param._type)?;
    770 			linelen += if (param.name == "") 1 else len(param.name);
    771 		};
    772 		switch (t.variadism) {
    773 		case variadism::NONE => void;
    774 		case variadism::HARE =>
    775 			linelen += 3;
    776 		case variadism::C =>
    777 			linelen += 5;
    778 		};
    779 		linelen += unparse::_type(io::empty, indent, *t.result)?;
    780 		yield linelen;
    781 	};
    782 
    783 	// use 72 instead of 80 to give a bit of leeway for preceding text
    784 	if (linelen > 72) {
    785 		indent += 1;
    786 		for (let i = 0z; i < len(t.params); i += 1) {
    787 			const param = t.params[i];
    788 			n += newline(out, indent)?;
    789 			n += fmt::fprintf(out, "{}: ",
    790 				if (param.name == "") "_" else param.name)?;
    791 			n += type_html(out, indent, *param._type, brief)?;
    792 			if (i + 1 == len(t.params)
    793 					&& t.variadism == variadism::HARE) {
    794 				n += fmt::fprint(out, "...")?;
    795 			} else {
    796 				n += fmt::fprint(out, ",")?;
    797 			};
    798 		};
    799 		if (t.variadism == variadism::C) {
    800 			n += newline(out, indent)?;
    801 			n += fmt::fprint(out, "...")?;
    802 		};
    803 		indent -= 1;
    804 		n += newline(out, indent)?;
    805 	} else for (let i = 0z; i < len(t.params); i += 1) {
    806 		const param = t.params[i];
    807 		if (!brief) {
    808 			n += fmt::fprintf(out, "{}: ",
    809 				if (param.name == "") "_" else param.name)?;
    810 		};
    811 		n += type_html(out, indent, *param._type, brief)?;
    812 		if (i + 1 == len(t.params)) {
    813 			switch (t.variadism) {
    814 			case variadism::NONE => void;
    815 			case variadism::HARE =>
    816 				n += fmt::fprint(out, "...")?;
    817 			case variadism::C =>
    818 				n += fmt::fprint(out, ", ...")?;
    819 			};
    820 		} else {
    821 			n += fmt::fprint(out, ", ")?;
    822 		};
    823 	};
    824 
    825 	n += fmt::fprint(out, ") ")?;
    826 	n += type_html(out, indent, *t.result, brief)?;
    827 	return n;
    828 };
    829 
    830 fn breadcrumb(ident: ast::ident) str = {
    831 	if (len(ident) == 0) {
    832 		return "";
    833 	};
    834 	let buf = strio::dynamic();
    835 	fmt::fprintf(&buf, "<a href='/'>stdlib</a> » ")!;
    836 	for (let i = 0z; i < len(ident) - 1; i += 1) {
    837 		let ipath = module::identpath(ident[..i+1]);
    838 		defer free(ipath);
    839 		fmt::fprintf(&buf, "<a href='/{}'>{}</a>::", ipath, ident[i])!;
    840 	};
    841 	fmt::fprint(&buf, ident[len(ident) - 1])!;
    842 	return strio::string(&buf);
    843 };
    844 
    845 fn head(ident: ast::ident) (void | error) = {
    846 	const id = unparse::identstr(ident);
    847 	defer free(id);
    848 
    849 	let breadcrumb = breadcrumb(ident);
    850 	defer free(breadcrumb);
    851 
    852 	const title =
    853 		if (len(id) == 0)
    854 			fmt::asprintf("Hare documentation")
    855 		else
    856 			fmt::asprintf("{} — Hare documentation", id);
    857 	defer free(title);
    858 
    859 	// TODO: Move bits to +embed?
    860 	fmt::printfln("<!doctype html>
    861 <html lang='en'>
    862 <meta charset='utf-8' />
    863 <meta name='viewport' content='width=device-width, initial-scale=1' />
    864 <title>{}</title>", title)?;
    865 	fmt::println("<style>
    866 body {
    867 	font-family: sans-serif;
    868 	line-height: 1.3;
    869 	margin: 0 auto;
    870 	padding: 0 1rem;
    871 }
    872 
    873 nav:not(#TableOfContents) {
    874 	max-width: calc(800px + 128px + 128px);
    875 	margin: 1rem auto 0;
    876 	display: grid;
    877 	grid-template-rows: auto auto 1fr;
    878 	grid-template-columns: auto 1fr;
    879 	grid-template-areas:
    880 		'logo header'
    881 		'logo nav'
    882 		'logo none';
    883 }
    884 
    885 nav:not(#TableOfContents) img {
    886 	grid-area: logo;
    887 }
    888 
    889 nav:not(#TableOfContents) h1 {
    890 	grid-area: header;
    891 	margin: 0;
    892 	padding: 0;
    893 }
    894 
    895 nav:not(#TableOfContents) ul {
    896 	grid-area: nav;
    897 	margin: 0.5rem 0 0 0;
    898 	padding: 0;
    899 	list-style: none;
    900 	display: flex;
    901 	flex-direction: row;
    902 	justify-content: left;
    903 	flex-wrap: wrap;
    904 }
    905 
    906 nav:not(#TableOfContents) li:not(:first-child) {
    907 	margin-left: 2rem;
    908 }
    909 
    910 #TableOfContents {
    911 	font-size: 1.1rem;
    912 }
    913 
    914 main {
    915 	padding: 0 128px;
    916 	max-width: 800px;
    917 	margin: 0 auto;
    918 
    919 }
    920 
    921 pre {
    922 	background-color: #eee;
    923 	padding: 0.25rem 1rem;
    924 	margin: 0 -1rem 1rem;
    925 	font-size: 1.2rem;
    926 	max-width: calc(100% + 1rem);
    927 	overflow-x: auto;
    928 }
    929 
    930 pre .keyword {
    931     color: #008;
    932 }
    933 
    934 pre .type {
    935 	color: #44F;
    936 }
    937 
    938 ol {
    939 	padding-left: 0;
    940 	list-style: none;
    941 }
    942 
    943 ol li {
    944 	padding-left: 0;
    945 }
    946 
    947 h2, h3, h4 {
    948 	display: flex;
    949 }
    950 
    951 h3 {
    952 	border-bottom: 1px solid #ccc;
    953 	padding-bottom: 0.25rem;
    954 }
    955 
    956 .invalid {
    957 	color: red;
    958 }
    959 
    960 .heading-extra {
    961 	align-self: flex-end;
    962 	flex-grow: 1;
    963 	text-align: right;
    964 	font-size: 0.8rem;
    965 	color: #444;
    966 }
    967 
    968 h4:target + pre {
    969 	background: #ddf;
    970 }
    971 
    972 details {
    973 	background: #eee;
    974 	margin: 1rem -1rem 1rem;
    975 }
    976 
    977 summary {
    978 	cursor: pointer;
    979 	padding: 0.5rem 1rem;
    980 }
    981 
    982 details pre {
    983 	margin: 0;
    984 }
    985 
    986 .comment {
    987 	color: #000;
    988 	font-weight: bold;
    989 }
    990 
    991 @media(max-width: 1000px) {
    992 	main {
    993 		padding: 0;
    994 	}
    995 }
    996 
    997 @media(prefers-color-scheme: dark) {
    998 	body {
    999 		background: #121415;
   1000 		color: #e1dfdc;
   1001 	}
   1002 
   1003 	img.mascot {
   1004 		filter: invert(.92);
   1005 	}
   1006 
   1007 	a {
   1008 		color: #78bef8;
   1009 	}
   1010 
   1011 	a:visited {
   1012 		color: #48a7f5;
   1013 	}
   1014 
   1015 	summary {
   1016 		background: #16191c;
   1017 	}
   1018 
   1019 	h3 {
   1020 		border-bottom: solid #16191c;
   1021 	}
   1022 
   1023 	h4:target + pre {
   1024 		background: #162329;
   1025 	}
   1026 
   1027 	pre {
   1028 		background-color: #16191c;
   1029 	}
   1030 
   1031 	pre .keyword {
   1032 		color: #69f;
   1033 	}
   1034 
   1035 	pre .type {
   1036 		color: #3cf;
   1037 	}
   1038 
   1039 	.comment {
   1040 		color: #fff;
   1041 	}
   1042 
   1043 	.heading-extra {
   1044 		color: #9b9997;
   1045 	}
   1046 }
   1047 </style>
   1048 <nav>
   1049 	<img
   1050 		src='data:image/png;base64,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'
   1051 		class='mascot'
   1052 		alt='An inked drawing of the Hare mascot, a fuzzy rabbit'
   1053 		width='128' height='128' />
   1054 	<h1>Hare documentation</h1>
   1055 	<ul>
   1056 		<li>
   1057 			<a href='https://harelang.org'>Home</a>
   1058 		</li>")?;
   1059 	fmt::printf("<li>{}</li>", breadcrumb)?;
   1060 	fmt::print("</ul>
   1061 </nav>
   1062 <main>")?;
   1063 	return;
   1064 };