Skip to content

Commit

Permalink
Move markdown helpers to Omd_util
Browse files Browse the repository at this point in the history
  • Loading branch information
antoniskalou committed Dec 17, 2023
1 parent 355674f commit 0303312
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 50 deletions.
52 changes: 2 additions & 50 deletions lib/issue_lib/cli.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,12 @@ let slug_title title =
in
safe_title ^ ".md"

let is_text_empty text = String.(equal empty (trim text))
let text_or_none text =
if is_text_empty text then None else Some text

let title_from_md doc =
let open Omd in
let rec finder = function
| Text (_, s) | Code (_, s) -> text_or_none s
| Link (_, link) -> finder link.label
| Strong (_, inline) | Emph (_, inline) -> finder inline
| Concat (_, xs) ->
List.filter_map finder xs
|> String.concat ""
|> text_or_none
| _ -> None
in
Omd_ext.inline_find_map ~concat:false ~f:finder doc

(* extract the title from the contents (first line) *)
let title path =
path
|> File_util.read_entire_file
|> Omd.of_string
|> title_from_md
|> Omd_util.title_of_doc

let category ~root path =
path
Expand All @@ -84,39 +66,9 @@ let issue_link title relative_path =

let wrap_in_article issue_html = "<article>" ^ issue_html ^ "</article>"

(* split a string, extracting a list of Omd.Link and Omd.Text *)
let split_links attr (tag, r) text =
Str.full_split r text
|> List.map (function
| Str.Delim (s) ->
let label = Omd.Text (attr, s) in
let title = Some ("Search " ^ tag ^ " " ^ s) in
Omd.Link (
[("class", "issue-" ^ tag)],
{ Omd.title; label; destination = "#" })
| Str.Text (s) -> Omd.Text (attr, s))

let mention_regexp = Str.regexp {|@\([A-Za-z0-9]+\)|}
let hashtag_regexp = Str.regexp {|#\([A-Za-z0-9]+\)|}

let extract_links attr text =
split_links attr ("mention", mention_regexp) text
|> List.concat_map (
function
| Omd.Text (attr, s) -> split_links attr ("hashtag", hashtag_regexp) s
| _ as x -> [x])

let replace_text_with_links = Omd_ext.inline_map ~f:(function
| Omd.Text (attr, s) as t ->
let links = extract_links attr s in
if List.is_empty links
then t
else Omd.Concat (attr, links)
| _ as x -> x)

let md_to_html ~root path =
let doc = Omd.of_string (File_util.read_entire_file path) in
let doc = replace_text_with_links doc in
let doc = Omd_util.replace_text_with_links doc in
let html = Omd.to_html doc in
let issue_link =
issue_link
Expand Down
47 changes: 47 additions & 0 deletions lib/issue_lib/omd_util.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
let is_text_empty text = String.(equal empty (trim text))
let text_or_none text =
if is_text_empty text then None else Some text

let title_of_doc doc =
let open Omd in
let rec finder = function
| Text (_, s) | Code (_, s) -> text_or_none s
| Link (_, link) -> finder link.label
| Strong (_, inline) | Emph (_, inline) -> finder inline
| Concat (_, xs) ->
List.filter_map finder xs
|> String.concat ""
|> text_or_none
| _ -> None
in
Omd_ext.inline_find_map ~concat:false ~f:finder doc

(* split a string, extracting a list of Omd.Link and Omd.Text *)
let split_links attr (tag, r) text =
Str.full_split r text
|> List.map (function
| Str.Delim (s) ->
let label = Omd.Text (attr, s) in
let title = Some ("Search " ^ tag ^ " " ^ s) in
Omd.Link (
[("class", "issue-" ^ tag)],
{ Omd.title; label; destination = "#" })
| Str.Text (s) -> Omd.Text (attr, s))

let mention_regexp = Str.regexp {|@\([A-Za-z0-9]+\)|}
let hashtag_regexp = Str.regexp {|#\([A-Za-z0-9]+\)|}

let extract_links attr text =
split_links attr ("mention", mention_regexp) text
|> List.concat_map (
function
| Omd.Text (attr, s) -> split_links attr ("hashtag", hashtag_regexp) s
| x -> [x])

let replace_text_with_links = Omd_ext.inline_map ~concat:true ~f:(function
| Omd.Text (attr, s) as t ->
let links = extract_links attr s in
if List.is_empty links
then t
else Omd.Concat (attr, links)
| x -> x)
10 changes: 10 additions & 0 deletions lib/issue_lib/omd_util.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
val title_of_doc : 'a Omd.block list -> string option

val extract_links
: (string * string) list
-> string
-> (string * string) list Omd.inline list

val replace_text_with_links
: (string * string) list Omd.block list
-> (string * string) list Omd.block list
53 changes: 53 additions & 0 deletions lib/issue_lib_test/omd_util_test.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
open Issue_lib;;

let%test_unit "title_of_doc various inlines" =
let tester test =
Printf.eprintf "\twith %s\n" test;
assert (
Omd.of_string test
|> Omd_util.title_of_doc
|> Option.fold ~none:false ~some:(String.equal "title"))
in
List.iter tester
[ {|title|}
; {| title |}
; {|# title|}
; {|[title](https://example.com)|}
; {|`title`|}
; {|_title_|}
; {|__title__|}
; {|[_title_](https://example.com)|}
; {|[__title__](https://example.com)|}
; {|[`title`](https://example.com)|}
]

let%test "title_of_doc handles empty links" =
Omd.of_string {|[](https://example.com)|}
|> Omd_util.title_of_doc
|> Option.is_none

let%test "title_of_doc handles empty headings" =
Omd.of_string {|# |}
|> Omd_util.title_of_doc
|> Option.is_none

let%test "title_of_doc handles empty code" =
Omd.of_string {|``|}
|> Omd_util.title_of_doc
(* will return ``, i'm ok with this case since the markdown parser
seems to think its just plain text. *)
|> Option.fold ~none:false ~some:(String.equal "``")

let%test "extract_links extracts @ from text" =
match Omd_util.extract_links [] "hello @joe" with
| [Omd.Text (_, text); Omd.Link (_, { label = Omd.Text (_, link); _ })] ->
String.equal "hello " text
&& String.equal "@joe" link
| _ -> false

let%test "extract_links extracts # from text" =
match Omd_util.extract_links [] "hello #mike" with
| [Omd.Text (_, text); Omd.Link (_, { label = Omd.Text (_, link); _ })] ->
String.equal "hello " text
&& String.equal "#mike" link
| _ -> false

0 comments on commit 0303312

Please sign in to comment.