diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-01-24 22:02:36 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-01-24 23:24:54 -0800 |
| commit | b779277daecb81efc0d6b0d9920c35d283e10530 (patch) | |
| tree | bcb07595afe2f097bba3b085f1dee1e4fb10c2ca /src/rustdoc | |
| parent | e8694589143830f1eff367016a3bb72c124345a5 (diff) | |
rustdoc: Add a pass to normalize indentation levels in doc comments
Diffstat (limited to 'src/rustdoc')
| -rw-r--r-- | src/rustdoc/rustdoc.rc | 1 | ||||
| -rwxr-xr-x | src/rustdoc/rustdoc.rs | 1 | ||||
| -rw-r--r-- | src/rustdoc/unindent_pass.rs | 120 |
3 files changed, 122 insertions, 0 deletions
diff --git a/src/rustdoc/rustdoc.rc b/src/rustdoc/rustdoc.rc index 15083e569b9..055ce07209f 100644 --- a/src/rustdoc/rustdoc.rc +++ b/src/rustdoc/rustdoc.rc @@ -25,6 +25,7 @@ mod prune_undoc_pass; mod prune_unexported_pass; mod desc_to_brief_pass; mod desc_pass; +mod unindent_pass; mod trim_pass; mod astsrv; mod demo; diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs index 4a0332eede6..45b20aefc6c 100755 --- a/src/rustdoc/rustdoc.rs +++ b/src/rustdoc/rustdoc.rs @@ -102,6 +102,7 @@ fn run(source_file: str) { prune_undoc_pass::mk_pass(), desc_to_brief_pass::mk_pass(), trim_pass::mk_pass(), + unindent_pass::mk_pass(), markdown_pass::mk_pass {|| std::io:: stdout()} ]); } \ No newline at end of file diff --git a/src/rustdoc/unindent_pass.rs b/src/rustdoc/unindent_pass.rs new file mode 100644 index 00000000000..ea439fd94c4 --- /dev/null +++ b/src/rustdoc/unindent_pass.rs @@ -0,0 +1,120 @@ +#[doc = " + +Removes the common level of indention from description strings. For +instance, if an entire doc comment is indented 8 spaces we want to +remove those 8 spaces from every line. + +The first line of a string is allowed to be intend less than +subsequent lines in the same paragraph in order to account for +instances where the string containing the doc comment is opened in the +middle of a line, and each of the following lines is indented. + +"]; + +export mk_pass; + +fn mk_pass() -> pass { + desc_pass::mk_pass(unindent) +} + +fn unindent(s: str) -> str { + let lines = str::lines_any(s); + let saw_first_line = false; + let saw_second_line = false; + let min_indent = vec::foldl(uint::max_value, lines) {|min_indent, line| + + // After we see the first non-whitespace line, look at + // the line we have. If it is not whitespace, and therefore + // part of the first paragraph, then ignore the indentation + // level of the first line + let ignore_previous_indents = + saw_first_line && + !saw_second_line && + !str::is_whitespace(line); + + let min_indent = if ignore_previous_indents { + uint::max_value + } else { + min_indent + }; + + if saw_first_line { + saw_second_line = true; + } + + if str::is_whitespace(line) { + min_indent + } else { + saw_first_line = true; + let spaces = 0u; + str::loop_chars(line) {|char| + // Only comparing against space because I wouldn't + // know what to do with mixed whitespace chars + if char == ' ' { + spaces += 1u; + true + } else { + false + } + }; + math::min(min_indent, spaces) + } + }; + + if check vec::is_not_empty(lines) { + let unindented = [str::trim(vec::head(lines))] + + vec::map(vec::tail(lines)) {|line| + if str::is_whitespace(line) { + line + } else { + assert str::byte_len(line) >= min_indent; + str::char_slice(line, min_indent, str::char_len(line)) + } + }; + str::connect(unindented, "\n") + } else { + s + } +} + +#[test] +fn should_unindent() { + let s = " line1\n line2"; + let r = unindent(s); + assert r == "line1\nline2"; +} + +#[test] +fn should_unindent_multiple_paragraphs() { + let s = " line1\n\n line2"; + let r = unindent(s); + assert r == "line1\n\nline2"; +} + +#[test] +fn should_leave_multiple_indent_levels() { + // Line 2 is indented another level beyond the + // base indentation and should be preserved + let s = " line1\n\n line2"; + let r = unindent(s); + assert r == "line1\n\n line2"; +} + +#[test] +fn should_ignore_first_line_indent() { + // Thi first line of the first paragraph may not be indented as + // far due to the way the doc string was written: + // + // #[doc = "Start way over here + // and continue here"] + let s = "line1\n line2"; + let r = unindent(s); + assert r == "line1\nline2"; +} + +#[test] +fn should_not_ignore_first_line_indent_in_a_single_line_para() { + let s = "line1\n\n line2"; + let r = unindent(s); + assert r == "line1\n\n line2"; +} \ No newline at end of file |
