@@ -1363,6 +1363,7 @@ object Parsers {
13631363
13641364 // Find the last line (should be just whitespace before closing delimiter)
13651365 val lastNewlineIdx = str.lastIndexOf('\n ' )
1366+
13661367 if (lastNewlineIdx < 0 ) {
13671368 syntaxError(
13681369 em " dedented string literal must start with newline after opening quotes " ,
@@ -1392,11 +1393,12 @@ object Parsers {
13921393 }
13931394
13941395 // Split into lines
1395- val lines = str.linesIterator.toSeq
1396+ val linesAndWithSeps = ( str.linesIterator.zip(str.linesWithSeparators)) .toSeq
13961397
1397- // Process all lines except the last (which is just the closing indentation)
1398+ // Process all lines except the first (which is empty before the first newline)
1399+ // and the last (which is just the closing indentation)
13981400 var lineOffset = offset
1399- val dedented = lines. dropRight(1 ).map { line =>
1401+ val dedented = linesAndWithSeps.drop( 1 ). dropRight(1 ).map { case ( line, lineWithSep) =>
14001402 val result =
14011403 if (line.startsWith(closingIndent)) line.substring(closingIndent.length)
14021404 else if (line.trim.isEmpty) " " // Empty or whitespace-only lines
@@ -1418,14 +1420,11 @@ object Parsers {
14181420 }
14191421 line
14201422 }
1421- lineOffset += line .length + 1 // +1 for the newline
1423+ lineOffset += lineWithSep .length // Make sure to include any \n, \r, \r\n, or \n\r
14221424 result
14231425 }
14241426
1425- // Drop the first line if it's empty (the newline after opening delimiter)
1426- val result = if (dedented.headOption.contains(" " )) dedented.drop(1 ) else dedented
1427-
1428- result.mkString(" \n " )
1427+ dedented.mkString(" \n " )
14291428 }
14301429
14311430 /** Literal ::= SimpleLiteral
0 commit comments