From 361f90e618c081afe2fa8b0a67370610781e413e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 29 Jan 2012 14:51:09 -0800 Subject: [PATCH] rustdoc: Sort the items so modules are printed last --- src/rustdoc/markdown_pass.rs | 88 ++++++++++++++++++++++++++++++++---- src/rustdoc/rustdoc.rs | 2 +- 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs index 8c53ad75a1b..a67e43525a4 100644 --- a/src/rustdoc/markdown_pass.rs +++ b/src/rustdoc/markdown_pass.rs @@ -5,16 +5,65 @@ import std::io::writer_util; export mk_pass; +// FIXME: This is a really convoluted interface to work around trying +// to get a writer into a unique closure and then being able to test +// what was written afterward fn mk_pass( - writer: fn~() -> io::writer + give_writer: fn~(fn(io::writer)) ) -> pass { - ret fn~( - _srv: astsrv::srv, + fn~( + srv: astsrv::srv, doc: doc::cratedoc ) -> doc::cratedoc { - write_markdown(doc, writer()); + + fn mods_last(item1: doc::itemtag, item2: doc::itemtag) -> bool { + fn is_mod(item: doc::itemtag) -> bool { + alt item { + doc::modtag(_) { true } + _ { false } + } + } + + let lteq = !is_mod(item1) || is_mod(item2); + lteq + } + + give_writer {|writer| + // Sort the items so mods come last. All mods will be + // output at the same header level so sorting mods last + // makes the headers come out nested correctly. + let sorted_doc = sort_pass::mk_pass(mods_last)(srv, doc); + + write_markdown(sorted_doc, writer); + } doc - }; + } +} + +#[test] +fn should_write_modules_last() { + /* + Because the markdown pass writes all modules at the same level of + indentation (it doesn't 'nest' them), we need to make sure that we + write all of the modules contained in each module after all other + types of items, or else the header nesting will end up wrong, with + modules appearing to contain items that they do not. + */ + let markdown = test::render( + "mod a { }\ + fn b() { }\ + mod c { }\ + fn d() { }" + ); + + let idx_a = str::find(markdown, "# Module `a`"); + let idx_b = str::find(markdown, "## Function `b`"); + let idx_c = str::find(markdown, "# Module `c`"); + let idx_d = str::find(markdown, "## Function `d`"); + + assert idx_b < idx_d; + assert idx_d < idx_a; + assert idx_a < idx_c; } type ctxt = { @@ -487,13 +536,13 @@ fn should_write_resource_args() { #[cfg(test)] mod test { fn render(source: str) -> str { - let doc = create_doc(source); - let markdown = write_markdown_str(doc); + let (srv, doc) = create_doc_srv(source); + let markdown = write_markdown_str_srv(srv, doc); #debug("markdown: %s", markdown); markdown } - fn create_doc(source: str) -> doc::cratedoc { + fn create_doc_srv(source: str) -> (astsrv::srv, doc::cratedoc) { let srv = astsrv::mk_srv_from_str(source); let doc = extract::from_srv(srv, ""); #debug("doc (extract): %?", doc); @@ -503,6 +552,11 @@ mod test { #debug("doc (path): %?", doc); let doc = attr_pass::mk_pass()(srv, doc); #debug("doc (attr): %?", doc); + (srv, doc) + } + + fn create_doc(source: str) -> doc::cratedoc { + let (_, doc) = create_doc_srv(source); doc } @@ -515,6 +569,24 @@ mod test { ret io::mem_buffer_str(buffer); } + fn write_markdown_str_srv( + srv: astsrv::srv, + doc: doc::cratedoc + ) -> str { + let port = comm::port(); + let chan = comm::chan(port); + + let pass = mk_pass {|f| + let buffer = io::mk_mem_buffer(); + let writer = io::mem_buffer_writer(buffer); + f(writer); + let result = io::mem_buffer_str(buffer); + comm::send(chan, result); + }; + pass(srv, doc); + ret comm::recv(port); + } + #[test] fn write_markdown_should_write_crate_header() { let srv = astsrv::mk_srv_from_str(""); diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs index 6374860573d..a27cd674863 100755 --- a/src/rustdoc/rustdoc.rs +++ b/src/rustdoc/rustdoc.rs @@ -105,6 +105,6 @@ fn run(source_file: str) { desc_to_brief_pass::mk_pass(), trim_pass::mk_pass(), unindent_pass::mk_pass(), - markdown_pass::mk_pass {|| std::io:: stdout()} + markdown_pass::mk_pass {|f| f(std::io:: stdout()) } ]); } \ No newline at end of file