Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 25 additions & 14 deletions lib/syntax/md_outline.ml
Original file line number Diff line number Diff line change
Expand Up @@ -763,22 +763,33 @@ let rec parse_list_items config lines i min_indent =

let parse config input =
let raw_lines = String.split_on_char '\n' input in
let lines = Array.of_list (List.map rstrip_cr raw_lines) in
let lines = Array.of_list raw_lines in
(* [split_on_char] has already allocated every line. Reuse those strings
for the overwhelmingly common LF input rather than allocating an
intermediate mapped list; only replace CRLF lines in place. *)
Array.iteri
(fun i line ->
let stripped = rstrip_cr line in
if stripped != line then lines.(i) <- stripped)
lines;
let n = Array.length lines in
let line_starts =
let arr = Array.make (max n 1) 0 in
let pos = ref 0 in
for idx = 0 to n - 1 do
arr.(idx) <- !pos;
let nl =
if idx + 1 < n then
1
else
0
in
pos := !pos + String.length lines.(idx) + nl
done;
arr
if config.parse_outline_only then
[||]
else
let arr = Array.make (max n 1) 0 in
let pos = ref 0 in
for idx = 0 to n - 1 do
arr.(idx) <- !pos;
let nl =
if idx + 1 < n then
1
else
0
in
pos := !pos + String.length lines.(idx) + nl
done;
arr
in
let src_end_pos body_i =
let rec find j =
Expand Down
22 changes: 21 additions & 1 deletion lib/syntax/property.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,31 @@ open Conf

let property_references config s =
let config = { config with inline_skip_macro = true } in
(* Most Logseq properties are scalar values (ids, dates, booleans, and so
on). Running the complete inline grammar for all of them dominates an
outline parse even though only tags and links survive the filter below.
Every syntax accepted by that filter starts with one of these bytes, so
cheaply reject scalar values before constructing an Angstrom parser. *)
let may_have_reference =
let length = String.length s in
let rec loop i =
if i = length then
false
else
match s.[i] with
| '#'
| '['
| '(' ->
true
| _ -> loop (i + 1)
in
loop 0
in
let end_quoted =
match last_char s with
| Some '"' -> true
| _ -> false in
if s = "" || (s.[0] == '"' && end_quoted) then
if (not may_have_reference) || (s.[0] == '"' && end_quoted) then
[]
else
match parse_string ~consume:All (Inline.parse config) s with
Expand Down
Loading