Skip to content

rustdoc: insert blank lines between consecutive doc comment blocks #6757

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions src/librustdoc/attr_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ pub struct CrateAttrs {

fn doc_metas(
attrs: ~[ast::attribute]
) -> ~[@ast::meta_item] {
) -> ~[(@ast::meta_item, attr::doc_style)] {

let doc_attrs = attr::find_attrs_by_name(attrs, "doc");
let doc_metas = do doc_attrs.map |attr| {
attr::attr_meta(attr::desugar_doc_attr(attr))
let (attr, style) = attr::desugar_doc_attr(attr);
(attr::attr_meta(attr), style)
};

return doc_metas;
Expand All @@ -46,9 +47,27 @@ pub fn parse_crate(attrs: ~[ast::attribute]) -> CrateAttrs {
}

pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> {
let doc_strs = do doc_metas(attrs).filter_mapped |meta| {
attr::get_meta_item_value_str(*meta).map(|s| copy **s)
};
let mut doc_strs = ~[];
let mut last_doc_style: Option<attr::doc_style> = None;

for doc_metas(attrs).each |&(meta, style)| {
for attr::get_meta_item_value_str(meta).each |s| {
// consecutive line comments of the same (inner/outer) style must
// be emitted without spacing inbetween so that they can form
// multi-line markdown constructs (like long paragraphs), but
// for everything else we need a blank line to prevent multiple
// comments from merging into a single paragraph.
match (style, last_doc_style) {
(attr::doc_line_inner, Some(attr::doc_line_inner))
| (attr::doc_line_outer, Some(attr::doc_line_outer))
| (_, None) => {}
_ => { doc_strs.push(~"") }
}
last_doc_style = Some(style);

doc_strs.push(copy **s);
}
}
if doc_strs.is_empty() {
None
} else {
Expand All @@ -57,8 +76,8 @@ pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> {
}

pub fn parse_hidden(attrs: ~[ast::attribute]) -> bool {
do doc_metas(attrs).find |meta| {
match attr::get_meta_item_list(*meta) {
do doc_metas(attrs).find |&(meta, _style)| {
match attr::get_meta_item_list(meta) {
Some(metas) => {
let hiddens = attr::find_meta_items_by_name(metas, "hidden");
!hiddens.is_empty()
Expand Down Expand Up @@ -155,4 +174,11 @@ mod test {
let desc = parse_desc(parse_attributes(source));
assert!(desc == Some(~"foo\nbar"));
}
#[test]
fn should_space_out_doc_comments() {
let source = ~"/** c1*//// c2\n/** c3*/\n/// c4\n/// c5\n/** c6*/";
let desc = parse_desc(parse_attributes(source));
println(fmt!("%?", desc));
assert!(desc == Some(~"c1\n\nc2\n\nc3\n\nc4\nc5\n\nc6"));
}
}
23 changes: 18 additions & 5 deletions src/libsyntax/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ use parse::comments::{doc_comment_style, strip_doc_comment_decoration};
use core::hashmap::HashSet;
use extra;

pub enum doc_style {
doc_block_outer,
doc_block_inner,
doc_line_outer,
doc_line_inner,
doc_attr_outer,
doc_attr_inner,
}

/* Constructors */

pub fn mk_name_value_item_str(name: @~str, value: @~str)
Expand Down Expand Up @@ -73,14 +82,18 @@ pub fn attr_metas(attrs: &[ast::attribute]) -> ~[@ast::meta_item] {
do attrs.map |a| { attr_meta(*a) }
}

pub fn desugar_doc_attr(attr: &ast::attribute) -> ast::attribute {
pub fn desugar_doc_attr(attr: &ast::attribute) -> (ast::attribute, doc_style) {
if attr.node.is_sugared_doc {
let comment = get_meta_item_value_str(attr.node.value).get();
let meta = mk_name_value_item_str(@~"doc",
@strip_doc_comment_decoration(*comment));
mk_attr(meta)
let (content, style) = strip_doc_comment_decoration(*comment);
let meta = mk_name_value_item_str(@~"doc", @content);
(mk_attr(meta), style)
} else {
*attr
let style = match attr.node.style {
ast::attr_inner => doc_attr_inner,
ast::attr_outer => doc_attr_outer,
};
(*attr, style)
}
}

Expand Down
22 changes: 18 additions & 4 deletions src/libsyntax/parse/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use core::prelude::*;

use ast;
use attr;
use codemap::{BytePos, CharPos, CodeMap, Pos};
use diagnostic;
use parse::lexer::{is_whitespace, get_str_from, reader};
Expand Down Expand Up @@ -50,7 +51,7 @@ pub fn doc_comment_style(comment: &str) -> ast::attr_style {
}
}

pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
pub fn strip_doc_comment_decoration(comment: &str) -> (~str, attr::doc_style) {

/// remove whitespace-only lines from the start/end of lines
fn vertical_trim(lines: ~[~str]) -> ~[~str] {
Expand Down Expand Up @@ -94,10 +95,18 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
};
}

assert!(comment.len() >= 3);

if comment.starts_with("//") {
let style = if comment.char_at(2) == '!' {
attr::doc_line_inner
} else {
attr::doc_line_outer
};
// FIXME #5475:
// return comment.slice(3u, comment.len()).trim().to_owned();
let r = comment.slice(3u, comment.len()); return r.trim().to_owned();
// return (comment.slice(3u, comment.len()).trim().to_owned(), style);
let r = comment.slice(3u, comment.len());
return (r.trim().to_owned(), style);

}

Expand All @@ -110,7 +119,12 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
let lines = block_trim(lines, ~"\t ", None);
let lines = block_trim(lines, ~"*", Some(1u));
let lines = block_trim(lines, ~"\t ", None);
return str::connect(lines, "\n");
let style = if comment.char_at(2) == '!' {
attr::doc_block_inner
} else {
attr::doc_block_outer
};
return (str::connect(lines, "\n"), style);
}

fail!("not a doc-comment: %s", comment);
Expand Down