2012-01-24 17:19:27 -08:00
|
|
|
#[doc = "
|
|
|
|
|
|
|
|
Pulls a brief description out of a long description.
|
|
|
|
|
|
|
|
If the first paragraph of a long description is short enough then it
|
|
|
|
is interpreted as the brief description.
|
|
|
|
|
|
|
|
"];
|
|
|
|
|
|
|
|
export mk_pass;
|
|
|
|
|
|
|
|
fn mk_pass() -> pass {
|
2012-02-27 18:07:16 -08:00
|
|
|
{
|
|
|
|
name: "desc_to_brief",
|
|
|
|
f: run
|
|
|
|
}
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn run(
|
|
|
|
_srv: astsrv::srv,
|
2012-03-02 18:33:25 -08:00
|
|
|
doc: doc::doc
|
|
|
|
) -> doc::doc {
|
2012-01-24 17:19:27 -08:00
|
|
|
let fold = fold::fold({
|
2012-02-17 15:55:30 -08:00
|
|
|
fold_item: fold_item,
|
2012-01-31 20:31:52 -08:00
|
|
|
fold_iface: fold_iface,
|
2012-02-17 15:55:30 -08:00
|
|
|
fold_impl: fold_impl
|
2012-02-20 22:24:59 -08:00
|
|
|
with *fold::default_any_fold(())
|
2012-01-24 17:19:27 -08:00
|
|
|
});
|
2012-03-02 18:33:25 -08:00
|
|
|
fold.fold_doc(fold, doc)
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
|
|
|
|
2012-02-17 15:55:30 -08:00
|
|
|
fn fold_item(fold: fold::fold<()>, doc: doc::itemdoc) -> doc::itemdoc {
|
|
|
|
let doc = fold::default_seq_fold_item(fold, doc);
|
2012-01-24 17:19:27 -08:00
|
|
|
|
2012-01-30 13:05:25 -08:00
|
|
|
{
|
2012-03-09 17:40:40 -08:00
|
|
|
brief: extract(doc.desc)
|
2012-01-30 13:05:25 -08:00
|
|
|
with doc
|
2012-01-26 22:19:47 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-30 19:24:06 -08:00
|
|
|
fn fold_iface(fold: fold::fold<()>, doc: doc::ifacedoc) -> doc::ifacedoc {
|
|
|
|
let doc =fold::default_seq_fold_iface(fold, doc);
|
|
|
|
|
|
|
|
{
|
2012-06-30 16:19:07 -07:00
|
|
|
methods: par::anymap(doc.methods, |doc| {
|
|
|
|
brief: extract(doc.desc)
|
|
|
|
with doc
|
2012-06-26 13:55:56 -07:00
|
|
|
})
|
2012-01-30 19:24:06 -08:00
|
|
|
with doc
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-31 20:31:52 -08:00
|
|
|
fn fold_impl(fold: fold::fold<()>, doc: doc::impldoc) -> doc::impldoc {
|
|
|
|
let doc =fold::default_seq_fold_impl(fold, doc);
|
|
|
|
|
|
|
|
{
|
2012-06-30 16:19:07 -07:00
|
|
|
methods: par::anymap(doc.methods, |doc| {
|
|
|
|
brief: extract(doc.desc)
|
|
|
|
with doc
|
2012-06-26 13:55:56 -07:00
|
|
|
})
|
2012-01-31 20:31:52 -08:00
|
|
|
with doc
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-24 17:19:27 -08:00
|
|
|
#[test]
|
2012-03-09 17:40:40 -08:00
|
|
|
fn should_promote_desc() {
|
|
|
|
let doc = test::mk_doc("#[doc = \"desc\"] mod m { }");
|
2012-03-02 18:33:25 -08:00
|
|
|
assert doc.cratemod().mods()[0].brief() == some("desc");
|
2012-01-30 19:24:06 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_promote_iface_method_desc() {
|
2012-03-09 17:40:40 -08:00
|
|
|
let doc = test::mk_doc("iface i { #[doc = \"desc\"] fn a(); }");
|
2012-03-02 18:33:25 -08:00
|
|
|
assert doc.cratemod().ifaces()[0].methods[0].brief == some("desc");
|
2012-01-31 20:31:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_promote_impl_method_desc() {
|
|
|
|
let doc = test::mk_doc(
|
2012-03-09 17:40:40 -08:00
|
|
|
"impl i for int { #[doc = \"desc\"] fn a() { } }");
|
2012-03-02 18:33:25 -08:00
|
|
|
assert doc.cratemod().impls()[0].methods[0].brief == some("desc");
|
2012-02-01 22:41:41 -08:00
|
|
|
}
|
|
|
|
|
2012-01-31 18:32:37 -08:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2012-03-02 18:33:25 -08:00
|
|
|
fn mk_doc(source: str) -> doc::doc {
|
2012-06-30 16:19:07 -07:00
|
|
|
do astsrv::from_str(source) |srv| {
|
2012-02-20 21:08:19 -08:00
|
|
|
let doc = extract::from_srv(srv, "");
|
2012-02-27 18:07:16 -08:00
|
|
|
let doc = attr_pass::mk_pass().f(srv, doc);
|
2012-02-20 21:08:19 -08:00
|
|
|
run(srv, doc)
|
|
|
|
}
|
2012-01-31 18:32:37 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-09 17:40:40 -08:00
|
|
|
fn extract(desc: option<str>) -> option<str> {
|
|
|
|
if option::is_none(desc) {
|
|
|
|
ret none
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
parse_desc(option::get(desc))
|
|
|
|
}
|
|
|
|
|
2012-03-09 17:40:40 -08:00
|
|
|
fn parse_desc(desc: str) -> option<str> {
|
2012-01-24 17:19:27 -08:00
|
|
|
|
|
|
|
const max_brief_len: uint = 120u;
|
|
|
|
|
2012-03-09 17:52:06 -08:00
|
|
|
alt first_sentence(desc) {
|
|
|
|
some(first_sentence) {
|
|
|
|
if str::len(first_sentence) <= max_brief_len {
|
|
|
|
some(first_sentence)
|
2012-01-24 17:19:27 -08:00
|
|
|
} else {
|
2012-03-09 17:40:40 -08:00
|
|
|
none
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
2012-03-09 17:52:06 -08:00
|
|
|
}
|
|
|
|
none { none }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn first_sentence(s: str) -> option<str> {
|
|
|
|
let paras = paragraphs(s);
|
|
|
|
if vec::is_not_empty(paras) {
|
2012-03-16 14:50:15 -07:00
|
|
|
let first_para = vec::head(paras);
|
|
|
|
some(str::replace(first_sentence_(first_para), "\n", " "))
|
2012-01-24 17:19:27 -08:00
|
|
|
} else {
|
2012-03-09 17:40:40 -08:00
|
|
|
none
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-16 14:50:15 -07:00
|
|
|
fn first_sentence_(s: str) -> str {
|
2012-03-22 08:39:41 -07:00
|
|
|
let mut dotcount = 0;
|
2012-03-16 14:50:15 -07:00
|
|
|
// The index of the character following a single dot. This allows
|
|
|
|
// Things like [0..1) to appear in the brief description
|
2012-06-30 16:19:07 -07:00
|
|
|
let idx = do str::find(s) |ch| {
|
2012-03-16 14:50:15 -07:00
|
|
|
if ch == '.' {
|
|
|
|
dotcount += 1;
|
|
|
|
false
|
|
|
|
} else {
|
|
|
|
if dotcount == 1 {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
dotcount = 0;
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
alt idx {
|
|
|
|
some(idx) if idx > 2u {
|
|
|
|
str::slice(s, 0u, idx - 1u)
|
|
|
|
}
|
|
|
|
_ {
|
|
|
|
if str::ends_with(s, ".") {
|
|
|
|
str::slice(s, 0u, str::len(s))
|
|
|
|
} else {
|
|
|
|
s
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-03-09 17:52:06 -08:00
|
|
|
}
|
|
|
|
|
2012-06-29 16:26:56 -07:00
|
|
|
fn paragraphs(s: str) -> ~[str] {
|
2012-01-24 17:19:27 -08:00
|
|
|
let lines = str::lines_any(s);
|
2012-03-22 08:39:41 -07:00
|
|
|
let mut whitespace_lines = 0;
|
|
|
|
let mut accum = "";
|
2012-06-30 16:19:07 -07:00
|
|
|
let paras = do vec::foldl(~[], lines) |paras, line| {
|
2012-03-22 08:39:41 -07:00
|
|
|
let mut res = paras;
|
2012-01-24 17:19:27 -08:00
|
|
|
|
|
|
|
if str::is_whitespace(line) {
|
|
|
|
whitespace_lines += 1;
|
|
|
|
} else {
|
|
|
|
if whitespace_lines > 0 {
|
|
|
|
if str::is_not_empty(accum) {
|
2012-06-29 16:26:56 -07:00
|
|
|
res += ~[accum];
|
2012-01-24 17:19:27 -08:00
|
|
|
accum = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
whitespace_lines = 0;
|
|
|
|
|
|
|
|
accum = if str::is_empty(accum) {
|
|
|
|
line
|
|
|
|
} else {
|
|
|
|
accum + "\n" + line
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
|
|
|
};
|
|
|
|
|
|
|
|
if str::is_not_empty(accum) {
|
2012-06-29 16:26:56 -07:00
|
|
|
paras + ~[accum]
|
2012-01-24 17:19:27 -08:00
|
|
|
} else {
|
|
|
|
paras
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_paragraphs_1() {
|
|
|
|
let paras = paragraphs("1\n\n2");
|
2012-06-29 16:26:56 -07:00
|
|
|
assert paras == ~["1", "2"];
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_paragraphs_2() {
|
|
|
|
let paras = paragraphs("\n\n1\n1\n\n2\n\n");
|
2012-06-29 16:26:56 -07:00
|
|
|
assert paras == ~["1\n1", "2"];
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_promote_short_descs() {
|
|
|
|
let desc = some("desc");
|
2012-03-09 17:40:40 -08:00
|
|
|
let brief = extract(desc);
|
|
|
|
assert brief == desc;
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_not_promote_long_descs() {
|
|
|
|
let desc = some("Warkworth Castle is a ruined medieval building
|
2012-03-09 17:52:06 -08:00
|
|
|
in the town of the same name in the English county of Northumberland,
|
|
|
|
and the town and castle occupy a loop of the River Coquet, less than a mile
|
2012-01-24 17:19:27 -08:00
|
|
|
from England's north-east coast. When the castle was founded is uncertain,
|
|
|
|
but traditionally its construction has been ascribed to Prince Henry of
|
|
|
|
Scotland in the mid 12th century, although it may have been built by
|
|
|
|
King Henry II of England when he took control of England'snorthern
|
|
|
|
counties.");
|
2012-03-09 17:40:40 -08:00
|
|
|
let brief = extract(desc);
|
|
|
|
assert brief == none;
|
2012-01-24 17:19:27 -08:00
|
|
|
}
|
2012-03-09 17:52:06 -08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_promote_first_sentence() {
|
|
|
|
let desc = some("Warkworth Castle is a ruined medieval building
|
|
|
|
in the town. of the same name in the English county of Northumberland,
|
|
|
|
and the town and castle occupy a loop of the River Coquet, less than a mile
|
|
|
|
from England's north-east coast. When the castle was founded is uncertain,
|
|
|
|
but traditionally its construction has been ascribed to Prince Henry of
|
|
|
|
Scotland in the mid 12th century, although it may have been built by
|
|
|
|
King Henry II of England when he took control of England'snorthern
|
|
|
|
counties.");
|
|
|
|
let brief = extract(desc);
|
|
|
|
assert brief == some(
|
|
|
|
"Warkworth Castle is a ruined medieval building in the town");
|
2012-03-16 14:50:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_not_consider_double_period_to_end_sentence() {
|
|
|
|
let desc = some("Warkworth..Castle is a ruined medieval building
|
|
|
|
in the town. of the same name in the English county of Northumberland,
|
|
|
|
and the town and castle occupy a loop of the River Coquet, less than a mile
|
|
|
|
from England's north-east coast. When the castle was founded is uncertain,
|
|
|
|
but traditionally its construction has been ascribed to Prince Henry of
|
|
|
|
Scotland in the mid 12th century, although it may have been built by
|
|
|
|
King Henry II of England when he took control of England'snorthern
|
|
|
|
counties.");
|
|
|
|
let brief = extract(desc);
|
|
|
|
assert brief == some(
|
|
|
|
"Warkworth..Castle is a ruined medieval building in the town");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_not_consider_triple_period_to_end_sentence() {
|
|
|
|
let desc = some("Warkworth... Castle is a ruined medieval building
|
|
|
|
in the town. of the same name in the English county of Northumberland,
|
|
|
|
and the town and castle occupy a loop of the River Coquet, less than a mile
|
|
|
|
from England's north-east coast. When the castle was founded is uncertain,
|
|
|
|
but traditionally its construction has been ascribed to Prince Henry of
|
|
|
|
Scotland in the mid 12th century, although it may have been built by
|
|
|
|
King Henry II of England when he took control of England'snorthern
|
|
|
|
counties.");
|
|
|
|
let brief = extract(desc);
|
|
|
|
assert brief == some(
|
|
|
|
"Warkworth... Castle is a ruined medieval building in the town");
|
|
|
|
}
|