2012-01-17 19:44:32 -06:00
|
|
|
#[doc = "Generate markdown from a document tree"];
|
|
|
|
|
2012-01-16 15:22:25 -06:00
|
|
|
import std::io;
|
|
|
|
import std::io::writer_util;
|
|
|
|
|
2012-01-17 18:12:50 -06:00
|
|
|
export mk_pass;
|
|
|
|
|
|
|
|
fn mk_pass(
|
|
|
|
writer: fn~() -> io::writer
|
|
|
|
) -> pass {
|
|
|
|
ret fn~(
|
|
|
|
_srv: astsrv::srv,
|
|
|
|
doc: doc::cratedoc
|
|
|
|
) -> doc::cratedoc {
|
|
|
|
write_markdown(doc, writer());
|
|
|
|
doc
|
|
|
|
};
|
|
|
|
}
|
2012-01-16 15:23:42 -06:00
|
|
|
|
2012-01-16 01:01:05 -06:00
|
|
|
type ctxt = {
|
2012-01-19 01:54:56 -06:00
|
|
|
w: io::writer
|
2012-01-16 00:58:57 -06:00
|
|
|
};
|
|
|
|
|
2012-01-16 02:33:36 -06:00
|
|
|
fn write_markdown(
|
|
|
|
doc: doc::cratedoc,
|
|
|
|
writer: io::writer
|
|
|
|
) {
|
|
|
|
let ctxt = {
|
2012-01-19 01:54:56 -06:00
|
|
|
w: writer
|
2012-01-16 02:33:36 -06:00
|
|
|
};
|
|
|
|
|
2012-01-16 23:37:29 -06:00
|
|
|
write_crate(ctxt, doc);
|
|
|
|
}
|
|
|
|
|
2012-01-19 18:21:33 -06:00
|
|
|
enum hlvl {
|
2012-01-19 21:29:21 -06:00
|
|
|
h1 = 1,
|
|
|
|
h2 = 2,
|
|
|
|
h3 = 3
|
2012-01-16 02:59:18 -06:00
|
|
|
}
|
|
|
|
|
2012-01-19 01:54:56 -06:00
|
|
|
fn write_header(ctxt: ctxt, lvl: hlvl, title: str) {
|
2012-01-18 15:02:29 -06:00
|
|
|
let hashes = str::from_chars(vec::init_elt(lvl as uint, '#'));
|
2012-01-19 01:54:56 -06:00
|
|
|
ctxt.w.write_line(#fmt("%s %s", hashes, title));
|
|
|
|
ctxt.w.write_line("");
|
2012-01-17 00:01:25 -06:00
|
|
|
}
|
|
|
|
|
2012-01-16 23:37:29 -06:00
|
|
|
fn write_crate(
|
|
|
|
ctxt: ctxt,
|
|
|
|
doc: doc::cratedoc
|
|
|
|
) {
|
2012-01-19 01:54:56 -06:00
|
|
|
write_header(ctxt, h1, #fmt("Crate %s", doc.topmod.name));
|
2012-01-16 23:37:29 -06:00
|
|
|
write_top_module(ctxt, doc.topmod);
|
2012-01-16 17:44:10 -06:00
|
|
|
}
|
|
|
|
|
2012-01-16 02:59:18 -06:00
|
|
|
fn write_top_module(
|
|
|
|
ctxt: ctxt,
|
|
|
|
moddoc: doc::moddoc
|
|
|
|
) {
|
2012-01-16 17:38:40 -06:00
|
|
|
write_mod_contents(ctxt, moddoc);
|
2012-01-16 02:59:18 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn write_mod(
|
|
|
|
ctxt: ctxt,
|
|
|
|
moddoc: doc::moddoc
|
|
|
|
) {
|
2012-01-19 02:03:45 -06:00
|
|
|
let fullpath = str::connect(moddoc.path + [moddoc.name], "::");
|
|
|
|
write_header(ctxt, h2, #fmt("Module `%s`", fullpath));
|
2012-01-16 17:38:40 -06:00
|
|
|
write_mod_contents(ctxt, moddoc);
|
2012-01-16 02:59:18 -06:00
|
|
|
}
|
|
|
|
|
2012-01-19 02:03:45 -06:00
|
|
|
#[test]
|
|
|
|
fn should_write_full_path_to_mod() {
|
|
|
|
let markdown = test::render("mod a { mod b { mod c { } } }");
|
|
|
|
assert str::contains(markdown, "## Module `a::b::c`");
|
|
|
|
}
|
|
|
|
|
2012-01-16 02:59:18 -06:00
|
|
|
fn write_mod_contents(
|
|
|
|
ctxt: ctxt,
|
2012-01-18 23:33:37 -06:00
|
|
|
doc: doc::moddoc
|
2012-01-16 02:59:18 -06:00
|
|
|
) {
|
2012-01-18 23:33:37 -06:00
|
|
|
write_brief(ctxt, doc.brief);
|
|
|
|
write_desc(ctxt, doc.desc);
|
|
|
|
|
2012-01-24 02:51:19 -06:00
|
|
|
for constdoc in *doc.consts {
|
|
|
|
write_const(ctxt, constdoc);
|
|
|
|
}
|
|
|
|
|
2012-01-25 22:55:55 -06:00
|
|
|
for enumdoc in *doc.enums {
|
|
|
|
write_enum(ctxt, enumdoc);
|
|
|
|
}
|
|
|
|
|
2012-01-18 23:33:37 -06:00
|
|
|
for fndoc in *doc.fns {
|
2012-01-19 01:54:56 -06:00
|
|
|
write_fn(ctxt, fndoc);
|
2012-01-16 02:59:18 -06:00
|
|
|
}
|
|
|
|
|
2012-01-18 23:33:37 -06:00
|
|
|
for moddoc in *doc.mods {
|
2012-01-19 01:54:56 -06:00
|
|
|
write_mod(ctxt, moddoc);
|
2012-01-16 02:59:18 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-18 23:33:37 -06:00
|
|
|
#[test]
|
|
|
|
fn should_write_crate_brief_description() {
|
|
|
|
let markdown = test::render("#[doc(brief = \"this is the crate\")];");
|
|
|
|
assert str::contains(markdown, "this is the crate");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_crate_description() {
|
|
|
|
let markdown = test::render("#[doc = \"this is the crate\"];");
|
|
|
|
assert str::contains(markdown, "this is the crate");
|
|
|
|
}
|
|
|
|
|
2012-01-16 02:59:18 -06:00
|
|
|
fn write_fn(
|
|
|
|
ctxt: ctxt,
|
2012-01-16 17:44:10 -06:00
|
|
|
doc: doc::fndoc
|
2012-01-16 02:59:18 -06:00
|
|
|
) {
|
2012-01-19 01:54:56 -06:00
|
|
|
write_header(ctxt, h3, #fmt("Function `%s`", doc.name));
|
2012-01-19 20:58:44 -06:00
|
|
|
write_sig(ctxt, doc.sig);
|
2012-01-18 01:39:22 -06:00
|
|
|
write_brief(ctxt, doc.brief);
|
|
|
|
write_desc(ctxt, doc.desc);
|
|
|
|
write_args(ctxt, doc.args);
|
|
|
|
write_return(ctxt, doc.return);
|
2012-01-24 20:17:06 -06:00
|
|
|
write_failure(ctxt, doc.failure);
|
2012-01-18 01:39:22 -06:00
|
|
|
}
|
|
|
|
|
2012-01-19 20:58:44 -06:00
|
|
|
fn write_sig(ctxt: ctxt, sig: option<str>) {
|
|
|
|
alt sig {
|
|
|
|
some(sig) {
|
2012-01-23 19:58:40 -06:00
|
|
|
ctxt.w.write_line(code_block_indent(sig));
|
2012-01-19 20:58:44 -06:00
|
|
|
ctxt.w.write_line("");
|
|
|
|
}
|
|
|
|
none { fail "unimplemented" }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-23 19:58:40 -06:00
|
|
|
fn code_block_indent(s: str) -> str {
|
|
|
|
let lines = str::lines_any(s);
|
|
|
|
let indented = vec::map(lines, { |line| #fmt(" %s", line) });
|
|
|
|
str::connect(indented, "\n")
|
|
|
|
}
|
|
|
|
|
2012-01-19 20:58:44 -06:00
|
|
|
#[test]
|
|
|
|
fn should_write_the_function_signature() {
|
|
|
|
let markdown = test::render("#[doc = \"f\"] fn a() { }");
|
2012-01-23 19:14:55 -06:00
|
|
|
assert str::contains(markdown, "\n fn a()\n");
|
2012-01-19 20:58:44 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_insert_blank_line_after_fn_signature() {
|
|
|
|
let markdown = test::render("#[doc = \"f\"] fn a() { }");
|
2012-01-23 19:14:55 -06:00
|
|
|
assert str::contains(markdown, "fn a()\n\n");
|
2012-01-19 20:58:44 -06:00
|
|
|
}
|
|
|
|
|
2012-01-23 19:58:40 -06:00
|
|
|
#[test]
|
|
|
|
fn should_correctly_indent_fn_signature() {
|
|
|
|
let doc = test::create_doc("fn a() { }");
|
|
|
|
let doc = ~{
|
|
|
|
topmod: ~{
|
|
|
|
fns: doc::fnlist([~{
|
|
|
|
sig: some("line 1\nline 2")
|
|
|
|
with *doc.topmod.fns[0]
|
|
|
|
}])
|
|
|
|
with *doc.topmod
|
|
|
|
}
|
|
|
|
with *doc
|
|
|
|
};
|
|
|
|
let markdown = test::write_markdown_str(doc);
|
|
|
|
assert str::contains(markdown, " line 1\n line 2");
|
|
|
|
}
|
|
|
|
|
2012-01-18 01:39:22 -06:00
|
|
|
fn write_brief(
|
|
|
|
ctxt: ctxt,
|
|
|
|
brief: option<str>
|
|
|
|
) {
|
|
|
|
alt brief {
|
2012-01-16 18:01:33 -06:00
|
|
|
some(brief) {
|
|
|
|
ctxt.w.write_line(brief);
|
2012-01-18 01:29:23 -06:00
|
|
|
ctxt.w.write_line("");
|
2012-01-16 18:01:33 -06:00
|
|
|
}
|
2012-01-19 00:37:22 -06:00
|
|
|
none { }
|
2012-01-16 18:01:33 -06:00
|
|
|
}
|
2012-01-18 01:39:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn write_desc(
|
|
|
|
ctxt: ctxt,
|
|
|
|
desc: option<str>
|
|
|
|
) {
|
|
|
|
alt desc {
|
2012-01-18 01:42:26 -06:00
|
|
|
some(desc) {
|
|
|
|
ctxt.w.write_line(desc);
|
2012-01-16 01:01:05 -06:00
|
|
|
ctxt.w.write_line("");
|
2012-01-15 17:23:07 -06:00
|
|
|
}
|
2012-01-19 00:37:22 -06:00
|
|
|
none { }
|
2012-01-15 17:23:07 -06:00
|
|
|
}
|
2012-01-18 01:39:22 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn write_args(
|
|
|
|
ctxt: ctxt,
|
2012-01-18 16:47:18 -06:00
|
|
|
args: [doc::argdoc]
|
2012-01-18 01:39:22 -06:00
|
|
|
) {
|
2012-01-18 17:02:23 -06:00
|
|
|
if vec::is_not_empty(args) {
|
|
|
|
ctxt.w.write_line("Arguments:");
|
|
|
|
ctxt.w.write_line("");
|
|
|
|
vec::iter(args) {|arg| write_arg(ctxt, arg) };
|
|
|
|
ctxt.w.write_line("");
|
2012-01-15 17:23:07 -06:00
|
|
|
}
|
2012-01-18 01:39:22 -06:00
|
|
|
}
|
|
|
|
|
2012-01-18 17:02:23 -06:00
|
|
|
fn write_arg(ctxt: ctxt, arg: doc::argdoc) {
|
2012-01-18 19:10:04 -06:00
|
|
|
assert option::is_some(arg.ty);
|
2012-01-19 00:40:06 -06:00
|
|
|
ctxt.w.write_str(#fmt(
|
2012-01-18 19:11:58 -06:00
|
|
|
"* `%s`: `%s`",
|
2012-01-18 19:10:04 -06:00
|
|
|
arg.name,
|
|
|
|
option::get(arg.ty)
|
|
|
|
));
|
2012-01-19 00:40:06 -06:00
|
|
|
alt arg.desc {
|
|
|
|
some(desc) {
|
|
|
|
ctxt.w.write_str(#fmt(" - %s", desc));
|
|
|
|
}
|
2012-01-19 02:08:51 -06:00
|
|
|
none { }
|
2012-01-19 00:40:06 -06:00
|
|
|
}
|
|
|
|
ctxt.w.write_line("");
|
2012-01-18 17:02:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_argument_list() {
|
|
|
|
let source = "fn a(b: int, c: int) { }";
|
|
|
|
let markdown = test::render(source);
|
|
|
|
assert str::contains(
|
|
|
|
markdown,
|
|
|
|
"Arguments:\n\
|
|
|
|
\n\
|
2012-01-18 19:11:58 -06:00
|
|
|
* `b`: `int`\n\
|
|
|
|
* `c`: `int`\n\
|
2012-01-18 17:02:23 -06:00
|
|
|
\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_not_write_arguments_if_none() {
|
|
|
|
let source = "fn a() { } fn b() { }";
|
|
|
|
let markdown = test::render(source);
|
|
|
|
assert !str::contains(markdown, "Arguments");
|
|
|
|
}
|
|
|
|
|
2012-01-19 00:40:06 -06:00
|
|
|
#[test]
|
|
|
|
fn should_write_argument_description() {
|
|
|
|
let source = "#[doc(args(a = \"milk\"))] fn f(a: bool) { }";
|
|
|
|
let markdown = test::render(source);
|
|
|
|
assert str::contains(markdown, "`a`: `bool` - milk");
|
|
|
|
}
|
|
|
|
|
2012-01-18 01:39:22 -06:00
|
|
|
fn write_return(
|
|
|
|
ctxt: ctxt,
|
2012-01-19 21:14:12 -06:00
|
|
|
doc: doc::retdoc
|
2012-01-18 01:39:22 -06:00
|
|
|
) {
|
2012-01-19 21:14:12 -06:00
|
|
|
alt doc.ty {
|
|
|
|
some(ty) {
|
2012-01-23 18:17:46 -06:00
|
|
|
ctxt.w.write_str(#fmt("Returns `%s`", ty));
|
2012-01-19 21:14:12 -06:00
|
|
|
alt doc.desc {
|
|
|
|
some(d) {
|
2012-01-23 18:17:46 -06:00
|
|
|
ctxt.w.write_line(#fmt(" - %s", d));
|
|
|
|
ctxt.w.write_line("");
|
|
|
|
}
|
|
|
|
none {
|
|
|
|
ctxt.w.write_line("");
|
2012-01-18 01:53:24 -06:00
|
|
|
ctxt.w.write_line("");
|
2012-01-16 17:38:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-01-19 00:37:22 -06:00
|
|
|
none { }
|
2012-01-15 17:23:07 -06:00
|
|
|
}
|
|
|
|
}
|
2012-01-16 02:33:36 -06:00
|
|
|
|
2012-01-18 23:50:35 -06:00
|
|
|
#[test]
|
|
|
|
fn should_write_return_type_on_new_line() {
|
|
|
|
let markdown = test::render("fn a() -> int { }");
|
|
|
|
assert str::contains(markdown, "\nReturns `int`");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_blank_line_between_return_type_and_next_header() {
|
|
|
|
let markdown = test::render(
|
|
|
|
"fn a() -> int { } \
|
|
|
|
fn b() -> int { }"
|
|
|
|
);
|
|
|
|
assert str::contains(markdown, "Returns `int`\n\n##");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_not_write_return_type_when_there_is_none() {
|
|
|
|
let markdown = test::render("fn a() { }");
|
|
|
|
assert !str::contains(markdown, "Returns");
|
|
|
|
}
|
|
|
|
|
2012-01-19 16:29:45 -06:00
|
|
|
#[test]
|
|
|
|
fn should_write_blank_line_after_return_description() {
|
|
|
|
let markdown = test::render(
|
|
|
|
"#[doc(return = \"blorp\")] fn a() -> int { }"
|
|
|
|
);
|
|
|
|
assert str::contains(markdown, "blorp\n\n");
|
|
|
|
}
|
|
|
|
|
2012-01-23 18:17:46 -06:00
|
|
|
#[test]
|
|
|
|
fn should_write_return_description_on_same_line_as_type() {
|
|
|
|
let markdown = test::render(
|
|
|
|
"#[doc(return = \"blorp\")] fn a() -> int { }"
|
|
|
|
);
|
|
|
|
assert str::contains(markdown, "Returns `int` - blorp");
|
|
|
|
}
|
|
|
|
|
2012-01-24 20:17:06 -06:00
|
|
|
fn write_failure(ctxt: ctxt, str: option<str>) {
|
|
|
|
alt str {
|
|
|
|
some(str) {
|
|
|
|
ctxt.w.write_line(#fmt("Failure conditions: %s", str));
|
|
|
|
ctxt.w.write_line("");
|
|
|
|
}
|
|
|
|
none { }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_failure_conditions() {
|
|
|
|
let markdown = test::render(
|
|
|
|
"#[doc(failure = \"it's the fail\")] fn a () { }");
|
|
|
|
assert str::contains(
|
|
|
|
markdown,
|
|
|
|
"\n\nFailure conditions: it's the fail\n\n");
|
|
|
|
}
|
|
|
|
|
2012-01-24 02:51:19 -06:00
|
|
|
fn write_const(
|
|
|
|
ctxt: ctxt,
|
|
|
|
doc: doc::constdoc
|
|
|
|
) {
|
|
|
|
write_header(ctxt, h3, #fmt("Const `%s`", doc.name));
|
|
|
|
write_sig(ctxt, doc.ty);
|
|
|
|
write_brief(ctxt, doc.brief);
|
|
|
|
write_desc(ctxt, doc.desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_const_header() {
|
|
|
|
let markdown = test::render("const a: bool = true;");
|
|
|
|
assert str::contains(markdown, "### Const `a`\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_const_description() {
|
|
|
|
let markdown = test::render(
|
|
|
|
"#[doc(brief = \"a\", desc = \"b\")]\
|
|
|
|
const a: bool = true;");
|
|
|
|
assert str::contains(markdown, "\n\na\n\nb\n\n");
|
|
|
|
}
|
|
|
|
|
2012-01-25 22:55:55 -06:00
|
|
|
fn write_enum(
|
|
|
|
ctxt: ctxt,
|
|
|
|
doc: doc::enumdoc
|
|
|
|
) {
|
|
|
|
write_header(ctxt, h3, #fmt("Enum `%s`", doc.name));
|
|
|
|
write_brief(ctxt, doc.brief);
|
|
|
|
write_desc(ctxt, doc.desc);
|
|
|
|
write_variants(ctxt, doc.variants);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_enum_header() {
|
|
|
|
let markdown = test::render("enum a { b }");
|
|
|
|
assert str::contains(markdown, "### Enum `a`\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_enum_description() {
|
|
|
|
let markdown = test::render(
|
|
|
|
"#[doc(brief = \"a\", desc = \"b\")] enum a { b }");
|
|
|
|
assert str::contains(markdown, "\n\na\n\nb\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_variants(
|
|
|
|
ctxt: ctxt,
|
|
|
|
docs: [doc::variantdoc]
|
|
|
|
) {
|
|
|
|
if vec::is_empty(docs) {
|
|
|
|
ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctxt.w.write_line("Variants:");
|
|
|
|
ctxt.w.write_line("");
|
|
|
|
|
|
|
|
vec::iter(docs, {|variant| write_variant(ctxt, variant) });
|
|
|
|
|
|
|
|
ctxt.w.write_line("");
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_variant(ctxt: ctxt, doc: doc::variantdoc) {
|
|
|
|
assert option::is_some(doc.sig);
|
|
|
|
let sig = option::get(doc.sig);
|
|
|
|
alt doc.desc {
|
|
|
|
some(desc) {
|
|
|
|
ctxt.w.write_line(#fmt("* `%s` - %s", sig, desc));
|
|
|
|
}
|
|
|
|
none {
|
|
|
|
ctxt.w.write_line(#fmt("* `%s`", sig));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_variant_list() {
|
|
|
|
let markdown = test::render(
|
|
|
|
"enum a { \
|
|
|
|
#[doc = \"test\"] b, \
|
|
|
|
#[doc = \"test\"] c }");
|
|
|
|
assert str::contains(
|
|
|
|
markdown,
|
|
|
|
"\n\nVariants:\n\
|
|
|
|
\n* `b` - test\
|
|
|
|
\n* `c` - test\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_variant_list_without_descs() {
|
|
|
|
let markdown = test::render("enum a { b, c }");
|
|
|
|
assert str::contains(
|
|
|
|
markdown,
|
|
|
|
"\n\nVariants:\n\
|
|
|
|
\n* `b`\
|
|
|
|
\n* `c`\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_write_variant_list_with_signatures() {
|
|
|
|
let markdown = test::render("enum a { b(int), #[doc = \"a\"] c(int) }");
|
|
|
|
assert str::contains(
|
|
|
|
markdown,
|
|
|
|
"\n\nVariants:\n\
|
|
|
|
\n* `b(int)`\
|
|
|
|
\n* `c(int)` - a\n\n");
|
|
|
|
}
|
|
|
|
|
2012-01-16 02:33:36 -06:00
|
|
|
#[cfg(test)]
|
2012-01-18 17:02:23 -06:00
|
|
|
mod test {
|
2012-01-18 01:33:11 -06:00
|
|
|
fn render(source: str) -> str {
|
2012-01-23 19:58:40 -06:00
|
|
|
let doc = create_doc(source);
|
|
|
|
let markdown = write_markdown_str(doc);
|
|
|
|
#debug("markdown: %s", markdown);
|
|
|
|
markdown
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_doc(source: str) -> doc::cratedoc {
|
2012-01-18 01:33:11 -06:00
|
|
|
let srv = astsrv::mk_srv_from_str(source);
|
|
|
|
let doc = extract::from_srv(srv, "");
|
2012-01-19 20:58:44 -06:00
|
|
|
#debug("doc (extract): %?", doc);
|
2012-01-19 16:12:40 -06:00
|
|
|
let doc = tystr_pass::mk_pass()(srv, doc);
|
2012-01-19 20:58:44 -06:00
|
|
|
#debug("doc (tystr): %?", doc);
|
2012-01-19 02:03:45 -06:00
|
|
|
let doc = path_pass::mk_pass()(srv, doc);
|
2012-01-19 20:58:44 -06:00
|
|
|
#debug("doc (path): %?", doc);
|
2012-01-18 01:33:11 -06:00
|
|
|
let doc = attr_pass::mk_pass()(srv, doc);
|
2012-01-19 20:58:44 -06:00
|
|
|
#debug("doc (attr): %?", doc);
|
2012-01-23 19:58:40 -06:00
|
|
|
doc
|
2012-01-18 01:33:11 -06:00
|
|
|
}
|
|
|
|
|
2012-01-16 02:33:36 -06:00
|
|
|
fn write_markdown_str(
|
2012-01-16 17:38:40 -06:00
|
|
|
doc: doc::cratedoc
|
2012-01-16 02:33:36 -06:00
|
|
|
) -> str {
|
|
|
|
let buffer = io::mk_mem_buffer();
|
|
|
|
let writer = io::mem_buffer_writer(buffer);
|
2012-01-16 17:38:40 -06:00
|
|
|
write_markdown(doc, writer);
|
2012-01-16 02:33:36 -06:00
|
|
|
ret io::mem_buffer_str(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn write_markdown_should_write_crate_header() {
|
2012-01-18 01:33:11 -06:00
|
|
|
let srv = astsrv::mk_srv_from_str("");
|
|
|
|
let doc = extract::from_srv(srv, "belch");
|
|
|
|
let doc = attr_pass::mk_pass()(srv, doc);
|
2012-01-16 17:38:40 -06:00
|
|
|
let markdown = write_markdown_str(doc);
|
2012-01-18 01:29:23 -06:00
|
|
|
assert str::contains(markdown, "# Crate belch");
|
2012-01-16 02:33:36 -06:00
|
|
|
}
|
2012-01-16 02:59:18 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn write_markdown_should_write_function_header() {
|
2012-01-18 01:33:11 -06:00
|
|
|
let markdown = render("fn func() { }");
|
2012-01-24 02:51:54 -06:00
|
|
|
assert str::contains(markdown, "### Function `func`");
|
2012-01-16 02:59:18 -06:00
|
|
|
}
|
2012-01-17 01:10:25 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn write_markdown_should_write_mod_headers() {
|
2012-01-18 01:33:11 -06:00
|
|
|
let markdown = render("mod moo { }");
|
2012-01-17 01:10:25 -06:00
|
|
|
assert str::contains(markdown, "## Module `moo`");
|
|
|
|
}
|
2012-01-17 18:30:53 -06:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_leave_blank_line_after_header() {
|
2012-01-18 01:33:11 -06:00
|
|
|
let markdown = render("mod morp { }");
|
2012-01-18 01:29:23 -06:00
|
|
|
assert str::contains(markdown, "Module `morp`\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-01-19 20:58:44 -06:00
|
|
|
fn should_leave_blank_line_between_fn_header_and_sig() {
|
2012-01-18 01:33:11 -06:00
|
|
|
let markdown = render("#[doc(brief = \"brief\")] fn a() { }");
|
2012-01-23 19:14:55 -06:00
|
|
|
assert str::contains(markdown, "Function `a`\n\n fn a()");
|
2012-01-18 01:29:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2012-01-18 01:53:24 -06:00
|
|
|
fn should_leave_blank_line_after_brief() {
|
2012-01-18 01:33:11 -06:00
|
|
|
let markdown = render("#[doc(brief = \"brief\")] fn a() { }");
|
2012-01-18 01:29:23 -06:00
|
|
|
assert str::contains(markdown, "brief\n\n");
|
2012-01-17 18:30:53 -06:00
|
|
|
}
|
2012-01-18 01:42:26 -06:00
|
|
|
|
|
|
|
#[test]
|
2012-01-18 01:53:24 -06:00
|
|
|
fn should_leave_blank_line_between_brief_and_desc() {
|
2012-01-18 01:42:26 -06:00
|
|
|
let markdown = render(
|
|
|
|
"#[doc(brief = \"brief\", desc = \"desc\")] fn a() { }"
|
|
|
|
);
|
|
|
|
assert str::contains(markdown, "brief\n\ndesc");
|
|
|
|
}
|
2012-01-18 01:53:24 -06:00
|
|
|
|
2012-01-16 02:33:36 -06:00
|
|
|
}
|