@@ -86,7 +86,8 @@ impl<'s> ScriptSource<'s> {
8686 . push_visible_span ( open_start..open_end) ) ;
8787 } ;
8888 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) ;
9091 if !info. is_empty ( ) {
9192 let info_start = info. offset_from ( & raw ) ;
9293 let info_end = info_start + info. len ( ) ;
@@ -147,7 +148,8 @@ impl<'s> ScriptSource<'s> {
147148 )
148149 . push_visible_span ( open_start..open_end) ) ;
149150 } 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) ;
151153 if !after_closing_fence. is_empty ( ) {
152154 // extra characters beyond the original fence pattern
153155 let after_start = after_closing_fence. offset_from ( & raw ) ;
@@ -261,8 +263,6 @@ pub fn strip_ws_lines(input: &str) -> Option<usize> {
261263/// True if `c` is considered a whitespace according to Rust language definition.
262264/// See [Rust language reference](https://doc.rust-lang.org/reference/whitespace.html)
263265/// for definitions of these classes.
264- ///
265- /// See rust-lang/rust's compiler/rustc_lexer/src/lib.rs `is_whitespace`
266266fn is_whitespace ( c : char ) -> bool {
267267 // This is Pattern_White_Space.
268268 //
@@ -271,27 +271,46 @@ fn is_whitespace(c: char) -> bool {
271271
272272 matches ! (
273273 c,
274- // Usual ASCII suspects
275- '\u{0009}' // \t
276- | '\u{000A}' // \n
274+ // End-of-line characters
275+ | '\u{000A}' // line feed (\n)
277276 | '\u{000B}' // vertical tab
278277 | '\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
284282
285- // Bidi markers
283+ // `Default_Ignorable_Code_Point` characters
286284 | '\u{200E}' // LEFT-TO-RIGHT MARK
287285 | '\u{200F}' // RIGHT-TO-LEFT MARK
288286
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
292305 )
293306}
294307
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+
295314#[ derive( Debug ) ]
296315pub struct FrontmatterError {
297316 message : String ,
0 commit comments