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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
use core:io;
use markdown;
// Load a markdown document and add post-processing as required.
Document loadDocument(Node node, Url file) {
try {
Document doc = parse(file.readAllText());
// Add post-processing.
doc.visit(DocVisitor(node, file));
return doc;
} catch (core:lang:CompilerError error) {
// Don't wrap compiler errors.
throw error;
} catch (DocError error) {
throw error;
} catch (Exception error) {
throw DocError(file, error.message);
}
}
/**
* Visitor to transform the markdown document to be more suitable for documentation.
*/
class DocVisitor extends markdown:Visitor {
// Path inside the tree.
Node node;
// File.
Url file;
// Create.
init(Node node, Url file) {
init { node = node; file = file; }
}
// Transform elements:
Element visit(Element element) {
if (element as CodeBlock) {
if (element.language == "inlinehtml") {
return CustomHtml((StrBuf() << join(element.code, "\n")).toS);
} else {
// Apply syntax highlighting!
}
}
element;
}
// Find and resolve markdown links:
TextSpan visit(TextSpan span) {
if (span as Link)
span.target = resolveLink(span.target);
span;
}
// Resolve a link.
Str resolveLink(Str link) {
if (link.startsWith("md:")) {
Url url = parseMdUrl(link.cut(link.begin + 3));
unless (target = node.resolveLink(url)) {
print("WARNING: ${file}: Broken markdown link: ${link}");
return link;
// throw DocError(file, "Unable to resolve the markdown link: ${link}");
}
return target.relativeOutputPath(node).format();
}
link;
}
}
|