@@ -84,84 +84,44 @@ pub enum MalformedGenerics {
8484
8585/// Removes excess indentation on comments in order for the Markdown
8686/// to be parsed correctly. This is necessary because the convention for
87- /// writing documentation is to provide a space between the /// or //! marker
87+ /// writing documentation is to provide a space between the ` ///` or ` //!` marker
8888/// and the doc text, but Markdown is whitespace-sensitive. For example,
8989/// a block of text with four-space indentation is parsed as a code block,
9090/// so if we didn't unindent comments, these list items
9191///
92+ /// ```
9293/// /// A list:
9394/// ///
9495/// /// - Foo
9596/// /// - Bar
97+ /// # fn foo() {}
98+ /// ```
9699///
97100/// would be parsed as if they were in a code block, which is likely not what the user intended.
98101pub fn unindent_doc_fragments ( docs : & mut [ DocFragment ] ) {
99- // `add` is used in case the most common sugared doc syntax is used ("/// "). The other
100- // fragments kind's lines are never starting with a whitespace unless they are using some
101- // markdown formatting requiring it. Therefore, if the doc block have a mix between the two,
102- // we need to take into account the fact that the minimum indent minus one (to take this
103- // whitespace into account).
104- //
105- // For example:
106- //
107- // /// hello!
108- // #[doc = "another"]
109- //
110- // In this case, you want "hello! another" and not "hello! another".
111- let add = if docs. windows ( 2 ) . any ( |arr| arr[ 0 ] . kind != arr[ 1 ] . kind )
112- && docs. iter ( ) . any ( |d| d. kind == DocFragmentKind :: SugaredDoc )
113- {
114- // In case we have a mix of sugared doc comments and "raw" ones, we want the sugared one to
115- // "decide" how much the minimum indent will be.
116- 1
117- } else {
118- 0
119- } ;
120-
121- // `min_indent` is used to know how much whitespaces from the start of each lines must be
122- // removed. Example:
123- //
124- // /// hello!
125- // #[doc = "another"]
126- //
127- // In here, the `min_indent` is 1 (because non-sugared fragment are always counted with minimum
128- // 1 whitespace), meaning that "hello!" will be considered a codeblock because it starts with 4
129- // (5 - 1) whitespaces.
130- let Some ( min_indent) = docs
102+ // Only sugared docs have the concept of indentation.
103+ // We assume the docs overall are indented by the amount that the least-indented line is indented.
104+ // Raw docs are taken literally.
105+ let min_indent = docs
131106 . iter ( )
132- . map ( |fragment| {
133- fragment
134- . doc
135- . as_str ( )
136- . lines ( )
137- . filter ( |line| line. chars ( ) . any ( |c| !c. is_whitespace ( ) ) )
138- . map ( |line| {
139- // Compare against either space or tab, ignoring whether they are
140- // mixed or not.
141- let whitespace = line. chars ( ) . take_while ( |c| * c == ' ' || * c == '\t' ) . count ( ) ;
142- whitespace
143- + ( if fragment. kind == DocFragmentKind :: SugaredDoc { 0 } else { add } )
144- } )
145- . min ( )
146- . unwrap_or ( usize:: MAX )
147- } )
107+ . filter ( |frag| frag. kind == DocFragmentKind :: SugaredDoc )
108+ . flat_map ( |frag| frag. doc . as_str ( ) . lines ( ) )
109+ . filter ( |line| line. chars ( ) . any ( |c| !c. is_whitespace ( ) ) )
110+ // FIXME: we should be more careful when spaces and tabs are mixed
111+ . map ( |line| line. chars ( ) . take_while ( |c| * c == ' ' || * c == '\t' ) . count ( ) )
148112 . min ( )
149- else {
150- return ;
151- } ;
113+ . unwrap_or ( 0 ) ;
152114
153115 for fragment in docs {
154116 if fragment. doc == kw:: Empty {
155117 continue ;
156118 }
157119
158- let indent = if fragment. kind != DocFragmentKind :: SugaredDoc && min_indent > 0 {
159- min_indent - add
160- } else {
161- min_indent
120+ fragment . indent = match fragment. kind {
121+ // Raw docs are taken literally.
122+ DocFragmentKind :: RawDoc => 0 ,
123+ DocFragmentKind :: SugaredDoc => min_indent,
162124 } ;
163-
164- fragment. indent = indent;
165125 }
166126}
167127
@@ -171,6 +131,7 @@ pub fn unindent_doc_fragments(docs: &mut [DocFragment]) {
171131///
172132/// Note: remove the trailing newline where appropriate
173133pub fn add_doc_fragment ( out : & mut String , frag : & DocFragment ) {
134+ debug ! ( "add_doc_fragment: {:?}" , frag) ;
174135 if frag. doc == kw:: Empty {
175136 out. push ( '\n' ) ;
176137 return ;
0 commit comments