@@ -86,7 +86,8 @@ impl<'s> ScriptSource<'s> {
86
86
. push_visible_span ( open_start..open_end) ) ;
87
87
} ;
88
88
let info = input. next_slice ( info_nl. start ) ;
89
- let info = info. trim_matches ( is_whitespace) ;
89
+ let info = info. strip_suffix ( '\r' ) . unwrap_or ( info) ; // already excludes `\n`
90
+ let info = info. trim_matches ( is_horizontal_whitespace) ;
90
91
if !info. is_empty ( ) {
91
92
let info_start = info. offset_from ( & raw ) ;
92
93
let info_end = info_start + info. len ( ) ;
@@ -147,7 +148,8 @@ impl<'s> ScriptSource<'s> {
147
148
)
148
149
. push_visible_span ( open_start..open_end) ) ;
149
150
} else {
150
- let after_closing_fence = after_closing_fence. trim_matches ( is_whitespace) ;
151
+ let after_closing_fence = strip_newline ( after_closing_fence) ;
152
+ let after_closing_fence = after_closing_fence. trim_matches ( is_horizontal_whitespace) ;
151
153
if !after_closing_fence. is_empty ( ) {
152
154
// extra characters beyond the original fence pattern
153
155
let after_start = after_closing_fence. offset_from ( & raw ) ;
@@ -261,8 +263,6 @@ pub fn strip_ws_lines(input: &str) -> Option<usize> {
261
263
/// True if `c` is considered a whitespace according to Rust language definition.
262
264
/// See [Rust language reference](https://doc.rust-lang.org/reference/whitespace.html)
263
265
/// for definitions of these classes.
264
- ///
265
- /// See rust-lang/rust's compiler/rustc_lexer/src/lib.rs `is_whitespace`
266
266
fn is_whitespace ( c : char ) -> bool {
267
267
// This is Pattern_White_Space.
268
268
//
@@ -271,27 +271,46 @@ fn is_whitespace(c: char) -> bool {
271
271
272
272
matches ! (
273
273
c,
274
- // Usual ASCII suspects
275
- '\u{0009}' // \t
276
- | '\u{000A}' // \n
274
+ // End-of-line characters
275
+ | '\u{000A}' // line feed (\n)
277
276
| '\u{000B}' // vertical tab
278
277
| '\u{000C}' // form feed
279
- | '\u{000D}' // \r
280
- | '\u{0020}' // space
281
-
282
- // NEXT LINE from latin1
283
- | '\u{0085}'
278
+ | '\u{000D}' // carriage return (\r)
279
+ | '\u{0085}' // next line (from latin1)
280
+ | '\u{2028}' // LINE SEPARATOR
281
+ | '\u{2029}' // PARAGRAPH SEPARATOR
284
282
285
- // Bidi markers
283
+ // `Default_Ignorable_Code_Point` characters
286
284
| '\u{200E}' // LEFT-TO-RIGHT MARK
287
285
| '\u{200F}' // RIGHT-TO-LEFT MARK
288
286
289
- // Dedicated whitespace characters from Unicode
290
- | '\u{2028}' // LINE SEPARATOR
291
- | '\u{2029}' // PARAGRAPH SEPARATOR
287
+ // Horizontal space characters
288
+ | '\u{0009}' // tab (\t)
289
+ | '\u{0020}' // space
290
+ )
291
+ }
292
+
293
+ /// True if `c` is considered horizontal whitespace according to Rust language definition.
294
+ fn is_horizontal_whitespace ( c : char ) -> bool {
295
+ // This is Pattern_White_Space.
296
+ //
297
+ // Note that this set is stable (ie, it doesn't change with different
298
+ // Unicode versions), so it's ok to just hard-code the values.
299
+
300
+ matches ! (
301
+ c,
302
+ // Horizontal space characters
303
+ '\u{0009}' // tab (\t)
304
+ | '\u{0020}' // space
292
305
)
293
306
}
294
307
308
+ fn strip_newline ( text : & str ) -> & str {
309
+ text. strip_suffix ( "\r \n " )
310
+ . or_else ( || text. strip_suffix ( '\n' ) )
311
+ . unwrap_or ( text)
312
+ }
313
+
295
314
#[ derive( Debug ) ]
296
315
pub struct FrontmatterError {
297
316
message : String ,
0 commit comments