···11-(*
22- * SPDX-FileCopyrightText: 2024 The Forester Project Contributors
33- *
44- * SPDX-License-Identifier: GPL-3.0-or-later
55- *)
66-77-open Forester_prelude
88-open Forester_compiler
99-open Forester_core
1010-1111-exception Todo of string
1212-1313-module T = Types
1414-module P = Pure_html
1515-1616-type _ renderable =
1717- | Content : T.content -> T.content renderable
1818- | Article : T.content T.article -> T.content T.article renderable
1919- | Frontmatter : T.content T.frontmatter -> T.content T.frontmatter renderable
2020-2121-type xml = P.node
2222-type json = Yojson.Safe.t
2323-type html = P.node
2424-2525-type _ target =
2626- | XML : xml target
2727- | JSON : json target
2828- | HTML : html target
2929- | STRING : string target
3030-[@@deriving show]
3131-3232-let render
3333- : type a b. dev: bool -> State.t -> a target -> b renderable -> a
3434-= fun
3535- ~dev
3636- forest
3737- tgt
3838- renderable
3939- ->
4040- let renderable =
4141- match renderable with
4242- | Content _ -> renderable
4343- | Article a ->
4444- if dev then
4545- renderable
4646- else
4747- Article {a with frontmatter = {a.frontmatter with source_path = None}}
4848- | Frontmatter fm ->
4949- if dev then
5050- renderable
5151- else
5252- Frontmatter {fm with source_path = None}
5353- in
5454- match tgt with
5555- | JSON ->
5656- begin
5757- match renderable with
5858- | Content content ->
5959- `String
6060- (Plain_text_client.string_of_content ~forest: forest.resources ~router: Iri.to_uri content)
6161- | Article article ->
6262- begin
6363- match (Json_manifest_client.render_tree ~dev ~forest article) with
6464- | Some (r, t) -> `Assoc [r, t]
6565- | None -> `Null
6666- end
6767- | Frontmatter _ -> raise (Todo "")
6868- end
6969- | HTML ->
7070- begin
7171- match renderable with
7272- | Content content -> P.HTML.div [] @@ Htmx_client.render_content forest content
7373- | Article article -> Htmx_client.render_article forest article
7474- | Frontmatter _ -> P.HTML.null []
7575- end
7676- | XML ->
7777- begin
7878- match renderable with
7979- | Content content ->
8080- P.HTML.null @@ Legacy_xml_client.render_content forest content
8181- | Article article ->
8282- Legacy_xml_client.render_article forest article
8383- | Frontmatter _ ->
8484- raise (Todo "render frontmatter to xml")
8585- end
8686- | STRING ->
8787- begin
8888- match renderable with
8989- | Content content -> Plain_text_client.string_of_content ~forest: forest.resources ~router: Iri.to_uri content
9090- | Article _ -> raise (Todo "render article to string")
9191- | Frontmatter _ -> raise (Todo "render frontmatter to string")
9292- end
9393-9494-let pp
9595- : type a b. dev: bool -> State.t -> a target -> Format.formatter -> b renderable -> unit
9696-= fun ~dev forest target fmt renderable ->
9797- let stuff =
9898- render ~dev forest target renderable
9999- in
100100- match target with
101101- | XML -> P.pp_xml fmt stuff
102102- | HTML -> P.pp fmt stuff
103103- | JSON -> Yojson.Safe.pp fmt stuff
104104- | STRING -> Format.pp_print_string fmt stuff
105105-106106-let pp_xml ?stylesheet ~forest ~dev fmt article =
107107- Format.fprintf fmt {|<?xml version="1.0" encoding="UTF-8"?>|};
108108- Format.pp_print_newline fmt ();
109109- begin
110110- let@ uri = Option.iter @~ stylesheet in
111111- Format.fprintf fmt "<?xml-stylesheet type=\"text/xsl\" href=\"%s\"?>" uri
112112- end;
113113- Format.pp_print_newline fmt ();
114114- P.pp_xml fmt @@ render ~dev forest XML (Article article)
+13-16
lib/frontend/State_machine.ml
···88open Forester_compiler
99open Forester_search
10101111+type target = HTML | JSON | XML | STRING
1212+1113module T = Types
12141315type state = State.t
···2628 | Expand_only of iri
2729 | Eval_only of iri
2830 | Parse of iri
2929- | Get of (('a Render.target [@opaque]) * iri)
3131+ | Get of iri
3032 | Query of (string, Vertex.t) Datalog_expr.query
3133 | Cache_results of (Vertex_set.t [@opaque])
3234 | Index
···3537type ('r, 'e) result =
3638 | Nothing
3739 | Vertex_set of Vertex_set.t
3838- | Render_result of 'r
4040+ | Got of T.content T.article
3941 | Error of 'e
40424143let update
···5254 | Query q ->
5355 let r = Forest.run_datalog_query state.graphs q in
5456 (Cache_results r, state, Vertex_set r)
5555- | Get (target, iri) ->
5757+ | Get iri ->
5658 begin
5759 match Forest.get_article iri state.resources with
5860 | Some article ->
5959- let result =
6060- Render_result
6161- (
6262- Render.render
6363- ~dev: true
6464- state
6565- target
6666- (Article article)
6767- )
6868- in
6969- (Done, state, result)
7070- | None -> (Done, state, Error (`Not_found iri))
6161+ Done, state, Got article
6262+ | None -> Done, state, Error (`Not_found iri)
7163 end
7264 | Quit -> exit 0
7365 | Load_all_configured_dirs ->
···186178 match Forest.get_article iri forest.resources with
187179 | None -> assert false
188180 | Some article ->
189189- Format.asprintf "%a" Render.(pp ~dev forest target) (Article article)
181181+ match target with
182182+ | HTML -> Pure_html.to_string @@ Htmx_client.render_article forest article
183183+ | XML ->
184184+ Format.asprintf "%a" Legacy_xml_client.(pp_xml ~forest ?stylesheet: None) article
185185+ | JSON -> Yojson.Safe.to_string @@ snd @@ Option.get @@ Json_manifest_client.render_tree ~dev ~forest article
186186+ | STRING -> "TODO"
+8-4
lib/language_server/Completion.ml
···116116 let* iri = tree.iri in
117117 let* {frontmatter; mainmatter; _} = Forest.get_article iri forest.resources in
118118 let documentation =
119119- let render = Render.render ~dev: true forest STRING in
119119+ let render =
120120+ Plain_text_client.string_of_content
121121+ ~forest: forest.resources
122122+ ~router: (Legacy_xml_client.route forest)
123123+ in
120124 let title = frontmatter.title in
121125 let taxon = frontmatter.taxon in
122126 let content =
123127 Format.asprintf
124128 {|%s\n %s\n %s\n |}
125125- (Option.fold ~none: "" ~some: (fun s -> Format.asprintf "# %s" (render (Content s))) title)
126126- (Option.fold ~none: "" ~some: (fun s -> Format.asprintf "taxon: %s" (render (Content s))) taxon)
127127- (render (Content mainmatter))
129129+ (Option.fold ~none: "" ~some: (fun s -> Format.asprintf "# %s" (render s)) title)
130130+ (Option.fold ~none: "" ~some: (fun s -> Format.asprintf "taxon: %s" (render s)) taxon)
131131+ (render mainmatter)
128132 in
129133 Some (`String content)
130134 in
+6-2
lib/language_server/Document_link.ml
···1616(* TODO: handle external links as well? *)
1717let compute (params : L.DocumentLinkParams.t) =
1818 let Lsp_state.{forest; _} = Lsp_state.get () in
1919- let render = Render.render ~dev: true forest STRING in
1919+ let render =
2020+ Plain_text_client.string_of_content
2121+ ~forest: forest.resources
2222+ ~router: (Legacy_xml_client.route forest)
2323+ in
2024 let config = State.config forest in
2125 match params with
2226 | {textDocument; _} ->
···3943 let iri = (Iri_scheme.user_iri ~host: config.host addr) in
4044 let* target = Option.map Lsp.Uri.of_path @@ Iri_tbl.find_opt forest.resolver iri in
4145 let* {frontmatter; _} = Forest.get_article iri forest.resources in
4242- let* tooltip = Option.map (fun c -> render (Content c)) frontmatter.title in
4646+ let* tooltip = Option.map (fun c -> render c) frontmatter.title in
4347 let link =
4448 L.DocumentLink.create
4549 ~range
···7788open Forester_compiler
991010+(**/**)
1111+module State = Lsp_state
1212+module LspEio = LspEio
1313+(**/**)
1414+1015(** An implementation of the {{: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/} Microsoft Language Server Protocol } for forester. *)
11161217(** Analysis of the {{!type:Forester_compiler.Code.t}concrete syntax}*)
+6-2
lib/language_server/Hover.ml
···2424 : L.Hover.t option
2525 =
2626 let Lsp_state.{forest; _} = Lsp_state.get () in
2727- let render = Render.render ~dev: true forest STRING in
2727+ let render =
2828+ Plain_text_client.string_of_content
2929+ ~forest: forest.resources
3030+ ~router: (Legacy_xml_client.route forest)
3131+ in
2832 let config = State.config forest in
2933 let host = config.host in
3034 let content =
···4246 | None ->
4347 Format.asprintf "Could not get article %a." pp_iri iri_under_cursor
4448 | Some {mainmatter; frontmatter; _} ->
4545- let main = render (Content mainmatter) in
4949+ let main = render mainmatter in
4650 if main = "" then (Format.asprintf "%a" T.(pp_frontmatter pp_content) frontmatter)
4751 else main
4852 in
+8-7
lib/language_server/Inlay_hint.ml
···1919 _;
2020 } ->
2121 let Lsp_state.{forest; _} = Lsp_state.get () in
2222- let render = Render.render forest STRING in
2222+ (* let render = Render.render forest STRING in *)
2323 let config = State.config forest in
2424 let host = config.host in
2525 match Forest.find_opt (State.parsed forest) (Iri_scheme.uri_to_iri ~host textDocument.uri) with
···4848 match Analysis.extract_addr node with
4949 | None -> None
5050 | Some str ->
5151- (* Eio.traceln "got addr"; *)
5251 let iri = Iri_scheme.user_iri ~host str in
5352 match Forest.get_article iri forest.resources with
5453 | None ->
5555- (* Eio.traceln "article %a not found" pp_iri iri; *)
5654 None
5755 | Some {frontmatter; _} ->
5858- (* Eio.traceln "got article"; *)
5956 match frontmatter.title with
6057 | None -> None
6158 | Some title ->
6262- (* Eio.traceln "got title"; *)
6363- let content = " " ^ render ~dev: true (Content title) in
6464- (* Eio.traceln "made content title"; *)
5959+ let content =
6060+ " " ^
6161+ Plain_text_client.string_of_content
6262+ ~forest: forest.resources
6363+ ~router: (Legacy_xml_client.route forest)
6464+ title
6565+ in
6566 Some
6667 (
6768 L.InlayHint.create
+8-3
lib/language_server/Workspace_symbols.ml
···1717 ({query = _; _}: L.WorkspaceSymbolParams.t)
1818 =
1919 let Lsp_state.{forest; _} = Lsp_state.get () in
2020- let render = Render.render ~dev: true forest STRING in
2121- let trees =
2020+ let render =
2121+ Plain_text_client.string_of_content
2222+ ~forest: forest.resources
2323+ ~router: (Legacy_xml_client.route forest)
2424+ in
2525+ let trees
2626+ =
2227 forest
2328 |> State.parsed
2429 |> Forest.to_seq_keys
···3136 begin
3237 match frontmatter.title with
3338 | None -> "untitled"
3434- | Some content -> render (Content content)
3939+ | Some content -> render content
3540 end
3641 in
3742 let uri =