package quill

  1. Overview
  2. Docs

Source file view_debug.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
open Quill_markdown
open Vdom

let rec inline_to_debug_string (indent : int) (i : inline) : string =
  let indent_str = String.make (indent * 2) ' ' in
  let content =
    match i.inline_content with
    | Run s -> Printf.sprintf "%sRun \"%s\"" indent_str s
    | Emph inline' ->
        Printf.sprintf "%sEmph (\n%s\n%s)" indent_str
          (inline_to_debug_string (indent + 1) inline')
          indent_str
    | Strong inline' ->
        Printf.sprintf "%sStrong (\n%s\n%s)" indent_str
          (inline_to_debug_string (indent + 1) inline')
          indent_str
    | Code_span s -> Printf.sprintf "%sCode_span \"%s\"" indent_str s
    | Seq items ->
        let items_str =
          List.map (inline_to_debug_string (indent + 1)) items
          |> String.concat "\n"
        in
        Printf.sprintf "%sSeq [\n%s\n%s]" indent_str items_str indent_str
    | Break typ ->
        let typ_str = match typ with `Hard -> "Hard" | `Soft -> "Soft" in
        Printf.sprintf "%sBreak %s" indent_str typ_str
    | Image { alt; src } ->
        Printf.sprintf "%sImage { alt = (\n%s\n%s); src = \"%s\" }" indent_str
          (inline_to_debug_string (indent + 1) alt)
          indent_str src
    | Link { text; href } ->
        Printf.sprintf "%sLink { text = (\n%s\n%s); href = \"%s\" }" indent_str
          (inline_to_debug_string (indent + 1) text)
          indent_str href
    | Raw_html html -> Printf.sprintf "%sRaw_html \"%s\"" indent_str html
  in
  let focus_str = if i.focused then "[FOCUSED]" else "" in
  Printf.sprintf "%sid=%d %s%s" indent_str i.id content focus_str

let rec has_focused_inline (b : block) : bool =
  let rec check_inline (i : inline) : bool =
    i.focused
    ||
    match i.inline_content with
    | Run _ -> false
    | Emph inline' -> check_inline inline'
    | Strong inline' -> check_inline inline'
    | Code_span _ -> false
    | Seq items -> List.exists check_inline items
    | Break _ -> false
    | Image { alt; _ } -> check_inline alt
    | Link { text; _ } -> check_inline text
    | Raw_html _ -> false
  in
  match b.content with
  | Paragraph inline -> check_inline inline
  | Heading (_, inline) -> check_inline inline
  | Codeblock _ -> false
  | Blocks bs -> List.exists has_focused_inline bs
  | Block_quote bs -> List.exists has_focused_inline bs
  | List (_, _, items) ->
      List.exists (fun item -> List.exists has_focused_inline item) items
  | Blank_line () -> false
  | Thematic_break -> false
  | Html_block _ -> false
  | Link_reference_definition _ -> false

let rec block_to_debug_string (indent : int) (b : block) : string =
  let indent_str = String.make (indent * 2) ' ' in
  let content =
    match b.content with
    | Paragraph inline ->
        Printf.sprintf "%sParagraph (\n%s\n%s)" indent_str
          (inline_to_debug_string (indent + 1) inline)
          indent_str
    | Codeblock { code; output; info = _ } ->
        let inner_parts =
          [
            Printf.sprintf "%sCode: %s"
              (String.make ((indent + 1) * 2) ' ')
              code;
          ]
        in
        let inner_parts =
          match output with
          | None -> inner_parts
          | Some output_block ->
              inner_parts
              @ [
                  Printf.sprintf "%sOutput:"
                    (String.make ((indent + 1) * 2) ' ');
                  block_to_debug_string (indent + 2) output_block;
                ]
        in
        let inner_str = String.concat "\n" inner_parts in
        Printf.sprintf "%sCodeblock (\n%s\n%s)" indent_str inner_str indent_str
    | Heading (level, inline) ->
        Printf.sprintf "%sHeading %d (\n%s\n%s)" indent_str level
          (inline_to_debug_string (indent + 1) inline)
          indent_str
    | Blocks bs ->
        let bs_str =
          List.map (block_to_debug_string (indent + 1)) bs |> String.concat "\n"
        in
        Printf.sprintf "%sBlocks [\n%s\n%s]" indent_str bs_str indent_str
    | Blank_line () ->
        Printf.sprintf "%sBlank_line ()%s" indent_str
          (String.make ((indent + 1) * 2) ' ')
    | Thematic_break -> Printf.sprintf "%sThematic_break" indent_str
    | Block_quote blocks ->
        let blocks_str =
          List.map (block_to_debug_string (indent + 1)) blocks
          |> String.concat "\n"
        in
        Printf.sprintf "%sBlock_quote [\n%s\n%s]" indent_str blocks_str
          indent_str
    | List (list_type, spacing, items) ->
        let type_str =
          match list_type with
          | Unordered c -> Printf.sprintf "Unordered '%c'" c
          | Ordered (start, c) -> Printf.sprintf "Ordered (%d, '%c')" start c
        in
        let spacing_str =
          match spacing with Tight -> "Tight" | Loose -> "Loose"
        in
        let items_str =
          List.map
            (fun item ->
              let item_str =
                List.map (block_to_debug_string (indent + 2)) item
                |> String.concat "\n"
              in
              Printf.sprintf "%s[\n%s\n%s]"
                (String.make ((indent + 1) * 2) ' ')
                item_str
                (String.make ((indent + 1) * 2) ' '))
            items
          |> String.concat "\n"
        in
        Printf.sprintf "%sList (%s, %s) [\n%s\n%s]" indent_str type_str
          spacing_str items_str indent_str
    | Html_block html ->
        Printf.sprintf "%sHtml_block \"%s\"" indent_str (String.escaped html)
    | Link_reference_definition _ ->
        Printf.sprintf "%sLink_reference_definition" indent_str
  in
  let focus_str =
    if b.focused then " [FOCUSED]"
    else if has_focused_inline b then " [CONTAINS FOCUS]"
    else ""
  in
  Printf.sprintf "%sid=%d %s%s" indent_str b.id content focus_str

let document_to_debug_string (model : Model.t) : string =
  let doc_ast =
    List.map (block_to_debug_string 0) model.document |> String.concat "\n"
  in
  let doc_str = Quill_markdown.md_of_document model.document in
  Printf.sprintf "Document [\n%s\n]\n\n---\n\n%s" doc_ast doc_str

let view model =
  let debug_str = document_to_debug_string model in
  elt "pre" [ text debug_str ]
OCaml

Innovation. Community. Security.