let trim_jsx_text =
let prefix_trim =
let rec trimmer str len idx =
if idx >= len then
""
else if str.[idx] = ' ' then
trimmer str len (idx + 1)
else
String.sub str idx (len - idx)
in
(fun str -> trimmer str (String.length str) 0)
in
let suffix_trim =
let rec trimmer str idx =
if idx < 0 then
""
else if str.[idx] = ' ' then
trimmer str (idx - 1)
else
String.sub str 0 (idx + 1)
in
(fun str -> trimmer str (String.length str - 1))
in
fun loc value ->
let value = String_utils.replace_char '\t' ' ' value in
let lines = String_utils.split_into_lines value in
let last_line = List.length lines - 1 in
let trimmed_lines =
Base.List.mapi
~f:(fun idx line ->
let line =
if idx <> 0 then
prefix_trim line
else
line
in
if idx <> last_line then
suffix_trim line
else
line)
lines
in
let (_, first_and_last_non_empty) =
List.fold_left
(fun (idx, first_and_last) line ->
let first_and_last =
if line <> "" then
match first_and_last with
| None -> Some (idx, idx)
| Some (first, _) -> Some (first, idx)
else
first_and_last
in
(idx + 1, first_and_last))
(0, None)
trimmed_lines
in
match first_and_last_non_empty with
| None -> None
| Some (first_line, last_line) ->
let trimmed = trimmed_lines |> List.filter (fun line -> line <> "") |> String.concat " " in
Loc.(
let start_line = loc.start.line + first_line in
let end_line = loc.start.line + last_line in
let first_trimmed_line = List.nth trimmed_lines first_line in
let last_trimmed_line = List.nth trimmed_lines last_line in
let first_char = first_trimmed_line.[0] in
let last_char = last_trimmed_line.[String.length last_trimmed_line - 1] in
let start_column = String.index (List.nth lines first_line) first_char in
let end_column = String.rindex (List.nth lines last_line) last_char + 1 in
let start_column =
if first_line = 0 then
start_column + loc.start.column
else
start_column
in
let end_column =
if last_line = 0 then
end_column + loc.start.column
else
end_column
in
let loc =
{
loc with
start = { line = start_line; column = start_column };
_end = { line = end_line; column = end_column };
}
in
Some (loc, trimmed))