1
+ #[ doc = "
2
+
3
+ Removes the common level of indention from description strings. For
4
+ instance, if an entire doc comment is indented 8 spaces we want to
5
+ remove those 8 spaces from every line.
6
+
7
+ The first line of a string is allowed to be intend less than
8
+ subsequent lines in the same paragraph in order to account for
9
+ instances where the string containing the doc comment is opened in the
10
+ middle of a line, and each of the following lines is indented.
11
+
12
+ " ] ;
13
+
14
+ export mk_pass;
15
+
16
+ fn mk_pass ( ) -> pass {
17
+ desc_pass:: mk_pass ( unindent)
18
+ }
19
+
20
+ fn unindent ( s : str ) -> str {
21
+ let lines = str:: lines_any ( s) ;
22
+ let saw_first_line = false ;
23
+ let saw_second_line = false ;
24
+ let min_indent = vec:: foldl ( uint:: max_value, lines) { |min_indent, line|
25
+
26
+ // After we see the first non-whitespace line, look at
27
+ // the line we have. If it is not whitespace, and therefore
28
+ // part of the first paragraph, then ignore the indentation
29
+ // level of the first line
30
+ let ignore_previous_indents =
31
+ saw_first_line &&
32
+ !saw_second_line &&
33
+ !str:: is_whitespace ( line) ;
34
+
35
+ let min_indent = if ignore_previous_indents {
36
+ uint:: max_value
37
+ } else {
38
+ min_indent
39
+ } ;
40
+
41
+ if saw_first_line {
42
+ saw_second_line = true ;
43
+ }
44
+
45
+ if str:: is_whitespace ( line) {
46
+ min_indent
47
+ } else {
48
+ saw_first_line = true ;
49
+ let spaces = 0 u;
50
+ str:: loop_chars ( line) { |char|
51
+ // Only comparing against space because I wouldn't
52
+ // know what to do with mixed whitespace chars
53
+ if char == ' ' {
54
+ spaces += 1 u;
55
+ true
56
+ } else {
57
+ false
58
+ }
59
+ } ;
60
+ math:: min ( min_indent, spaces)
61
+ }
62
+ } ;
63
+
64
+ if check vec:: is_not_empty ( lines) {
65
+ let unindented = [ str:: trim ( vec:: head ( lines) ) ]
66
+ + vec:: map ( vec:: tail ( lines) ) { |line|
67
+ if str:: is_whitespace ( line) {
68
+ line
69
+ } else {
70
+ assert str:: byte_len ( line) >= min_indent;
71
+ str:: char_slice ( line, min_indent, str:: char_len ( line) )
72
+ }
73
+ } ;
74
+ str:: connect ( unindented, "\n " )
75
+ } else {
76
+ s
77
+ }
78
+ }
79
+
80
+ #[ test]
81
+ fn should_unindent ( ) {
82
+ let s = " line1\n line2" ;
83
+ let r = unindent ( s) ;
84
+ assert r == "line1\n line2" ;
85
+ }
86
+
87
+ #[ test]
88
+ fn should_unindent_multiple_paragraphs ( ) {
89
+ let s = " line1\n \n line2" ;
90
+ let r = unindent ( s) ;
91
+ assert r == "line1\n \n line2" ;
92
+ }
93
+
94
+ #[ test]
95
+ fn should_leave_multiple_indent_levels ( ) {
96
+ // Line 2 is indented another level beyond the
97
+ // base indentation and should be preserved
98
+ let s = " line1\n \n line2" ;
99
+ let r = unindent ( s) ;
100
+ assert r == "line1\n \n line2" ;
101
+ }
102
+
103
+ #[ test]
104
+ fn should_ignore_first_line_indent ( ) {
105
+ // Thi first line of the first paragraph may not be indented as
106
+ // far due to the way the doc string was written:
107
+ //
108
+ // #[doc = "Start way over here
109
+ // and continue here"]
110
+ let s = "line1\n line2" ;
111
+ let r = unindent ( s) ;
112
+ assert r == "line1\n line2" ;
113
+ }
114
+
115
+ #[ test]
116
+ fn should_not_ignore_first_line_indent_in_a_single_line_para ( ) {
117
+ let s = "line1\n \n line2" ;
118
+ let r = unindent ( s) ;
119
+ assert r == "line1\n \n line2" ;
120
+ }
0 commit comments