Skip to content

Commit 3c7630c

Browse files
committed
odoc-parser: strip stray CR from deindented code block lines
Splitting a code block on '\n' leaves a trailing '\r' on every line of CRLF input. count_leading_whitespace already discounts that '\r' when computing the indent, but drop didn't strip it from the line it returned, so the joined result still contained CRs. This made fmt_code on Windows fail with Lexer.Error (Illegal_character '\r') for any {@ocaml[...]} block, since the OCaml lexer's newline regex is '\r*\n' and rejects a bare CR. Strip the trailing '\r' in drop so the output uses LF only, matching what the rest of the pipeline expects.
1 parent 2d5d8c1 commit 3c7630c

2 files changed

Lines changed: 10 additions & 5 deletions

File tree

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ profile. This started with version 0.26.0.
1414
- Fix `match` in `if-then-else` branches expanding to vertical with
1515
`fit-or-vertical` (#2798, @MisterDA)
1616

17+
- Fix lexer error on Windows when an Odoc code block contains CRLF line
18+
endings (@hhugo)
19+
1720
## 0.29.0
1821

1922
### Highlight

vendor/odoc-parser/odoc_parser.ml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,13 @@ let deindent : what:string -> loc:Loc.span -> string -> string * Warning.t list
168168
else []
169169
in
170170
let drop n line =
171-
(* Since blank lines were ignored when calculating
172-
[least_amount_of_whitespace], their length might be less than the
173-
amount. *)
174-
if String.length line < n then ""
175-
else String.sub line n (String.length line - n)
171+
(* Strip a trailing '\r' left over from splitting CRLF input on '\n', so
172+
the joined output uses LF only and downstream consumers (e.g. the OCaml
173+
lexer, whose newline regex is '\r*\n') don't see a bare '\r'. Blank
174+
lines may also be shorter than [n], in which case the result is empty. *)
175+
let len = String.length line in
176+
let stop = if len > 0 && line.[len - 1] = '\r' then len - 1 else len in
177+
if n >= stop then "" else String.sub line n (stop - n)
176178
in
177179
let lines = List.map (drop least_amount_of_whitespace) lines in
178180
(String.concat "\n" lines, warning)

0 commit comments

Comments
 (0)