From 3d67939c41e39e7eb493ef77a385cc290c1587c0 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 2 Mar 2012 15:17:13 -0800 Subject: [PATCH] rustdoc: Begin constructing indexes --- src/rustdoc/doc.rs | 2 - src/rustdoc/markdown_index_pass.rs | 92 ++++++++++++++++++++++++++++++ src/rustdoc/markdown_pass.rs | 57 +++++++++++------- src/rustdoc/rustdoc.rc | 1 + src/rustdoc/rustdoc.rs | 1 + 5 files changed, 130 insertions(+), 23 deletions(-) create mode 100644 src/rustdoc/markdown_index_pass.rs diff --git a/src/rustdoc/doc.rs b/src/rustdoc/doc.rs index aa1bca2eab9..ceca4cb5a72 100644 --- a/src/rustdoc/doc.rs +++ b/src/rustdoc/doc.rs @@ -122,14 +122,12 @@ Fields: * kind - The type of thing being indexed, e.g. 'Module' * name - The name of the thing -* brief - A description * link - A format-specific string representing the link target "] type index_entry = { kind: str, name: str, - brief: str, link: str }; diff --git a/src/rustdoc/markdown_index_pass.rs b/src/rustdoc/markdown_index_pass.rs new file mode 100644 index 00000000000..021274f6052 --- /dev/null +++ b/src/rustdoc/markdown_index_pass.rs @@ -0,0 +1,92 @@ +#[doc = "Build indexes as appropriate for the markdown pass"]; + +export mk_pass; + +fn mk_pass() -> pass { + { + name: "markdown_index", + f: run + } +} + +fn run(_srv: astsrv::srv, doc: doc::cratedoc) -> doc::cratedoc { + let fold = fold::fold({ + fold_mod: fold_mod + with *fold::default_any_fold(()) + }); + fold.fold_crate(fold, doc) +} + +fn fold_mod(fold: fold::fold<()>, doc: doc::moddoc) -> doc::moddoc { + + let doc = fold::default_any_fold_mod(fold, doc); + + { + index: some(build_index(doc)) + with doc + } +} + +fn build_index(doc: doc::moddoc) -> doc::index { + { + entries: par::anymap(doc.items, item_to_entry) + } +} + +fn item_to_entry(doc: doc::itemtag) -> doc::index_entry { + { + kind: markdown_pass::header_kind(doc), + name: markdown_pass::header_name(doc), + link: pandoc_header_id(markdown_pass::header_text(doc)) + } +} + +fn pandoc_header_id(header: str) -> str { + + // http://johnmacfarlane.net/pandoc/README.html#headers + + let header = remove_formatting(header); + let header = remove_punctuation(header); + let header = replace_with_hyphens(header); + let header = convert_to_lowercase(header); + let header = remove_up_to_first_letter(header); + let header = maybe_use_section_id(header); + ret header; + + fn remove_formatting(s: str) -> str { s } + fn remove_punctuation(s: str) -> str { + str::replace(s, "`", "") + } + fn replace_with_hyphens(s: str) -> str { + str::replace(s, " ", "-") + } + fn convert_to_lowercase(s: str) -> str { str::to_lower(s) } + fn remove_up_to_first_letter(s: str) -> str { s } + fn maybe_use_section_id(s: str) -> str { s } +} + +#[test] +fn should_index_mod_contents() { + let doc = test::mk_doc("mod a { } fn b() { }"); + assert option::get(doc.topmod.index).entries[0] == { + kind: "Module", + name: "a", + link: "module-a" + }; + assert option::get(doc.topmod.index).entries[1] == { + kind: "Function", + name: "b", + link: "function-b" + }; +} + +#[cfg(test)] +mod test { + fn mk_doc(source: str) -> doc::cratedoc { + astsrv::from_str(source) {|srv| + let doc = extract::from_srv(srv, ""); + let doc = path_pass::mk_pass().f(srv, doc); + run(srv, doc) + } + } +} diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs index 6a796e72525..42d0681c357 100644 --- a/src/rustdoc/markdown_pass.rs +++ b/src/rustdoc/markdown_pass.rs @@ -4,6 +4,7 @@ import markdown_writer::writer; import markdown_writer::writer_util; export mk_pass; +export header_kind, header_name, header_text; fn mk_pass(config: config::config) -> pass { mk_pass_(config, markdown_writer::make_writer(config)) @@ -116,59 +117,73 @@ fn write_header_(ctxt: ctxt, lvl: hlvl, title: str) { ctxt.w.write_line(""); } -fn header_text(doc: doc::itemtag) -> str { - let fullpath = str::connect(doc.path() + [doc.name()], "::"); +fn header_kind(doc: doc::itemtag) -> str { alt doc { doc::modtag(_) { if doc.id() == rustc::syntax::ast::crate_node_id { - header_text_("Crate", doc.name()) + "Crate" } else { - header_text_("Module", fullpath) + "Module" } } doc::nmodtag(_) { - header_text_("Native module", fullpath) + "Native module" } doc::fntag(_) { - header_text_("Function", doc.name()) + "Function" } doc::consttag(_) { - header_text_("Const", doc.name()) + "Const" } doc::enumtag(_) { - header_text_("Enum", doc.name()) + "Enum" } doc::restag(_) { - header_text_("Resource", doc.name()) + "Resource" } doc::ifacetag(_) { - header_text_("Interface", doc.name()) + "Interface" + } + doc::impltag(doc) { + "Implementation" + } + doc::tytag(_) { + "Type" + } + } +} + +fn header_name(doc: doc::itemtag) -> str { + let fullpath = str::connect(doc.path() + [doc.name()], "::"); + alt doc { + doc::modtag(_) if doc.id() != rustc::syntax::ast::crate_node_id { + fullpath + } + doc::nmodtag(_) { + fullpath } doc::impltag(doc) { assert option::is_some(doc.self_ty); let self_ty = option::get(doc.self_ty); alt doc.iface_ty { some(iface_ty) { - header_text_( - "Implementation", - #fmt("%s of %s for %s", - doc.name(), iface_ty, self_ty) - ) + #fmt("%s of %s for %s", doc.name(), iface_ty, self_ty) } none { - header_text_( - "Implementation", - #fmt("%s for %s", doc.name(), self_ty) - ) + #fmt("%s for %s", doc.name(), self_ty) } } } - doc::tytag(_) { - header_text_("Type", doc.name()) + _ { + doc.name() } } } +fn header_text(doc: doc::itemtag) -> str { + header_text_(header_kind(doc), header_name(doc)) +} + fn header_text_(kind: str, name: str) -> str { #fmt("%s `%s`", kind, name) } diff --git a/src/rustdoc/rustdoc.rc b/src/rustdoc/rustdoc.rc index 5f88ca4bdf9..69a95cfd24c 100644 --- a/src/rustdoc/rustdoc.rc +++ b/src/rustdoc/rustdoc.rc @@ -17,6 +17,7 @@ mod parse; mod extract; mod attr_parser; mod doc; +mod markdown_index_pass; mod markdown_pass; mod markdown_writer; mod fold; diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs index 86af77a687f..df0e014eb41 100755 --- a/src/rustdoc/rustdoc.rs +++ b/src/rustdoc/rustdoc.rs @@ -147,6 +147,7 @@ fn run(config: config::config) { unindent_pass::mk_pass(), sort_item_name_pass::mk_pass(), sort_item_type_pass::mk_pass(), + markdown_index_pass::mk_pass(), markdown_pass::mk_pass(config) ]); }