···11+{0 Forester developer docs}
22+33+Forester is a compiled markup language for authoring scientific hypertext. This documentation is intended to give an overview of forester internals for people interested in contributing to the project.
44+55+{1 Questions}
66+77+If you have questions, feel free to write an email to [https://lists.sr.ht/~jonsterling/forester-discuss]. Please employ {{: https://useplaintext.email/#etiquette} plaintext email etiquette}, including line wrapping.
88+99+{1 Getting started}
1010+1111+Forester is implementend in the {{: https://ocaml.org/}OCaml programming language}, so you will need to have the OCaml toolchain installed. You can find instructions {{: https://ocaml.org/install#linux_mac_bsd}here}. Alternatively, you can get access to the toolchain using the {{: https://nixos.org/}Nix package manager}.
1212+1313+{2 Building the project}
1414+1515+[dune build]
1616+1717+{2 Testing}
1818+1919+[dune runtest]
2020+2121+{2 Sending a patch}
2222+2323+Once your changes are ready, follow {{: https://lists.sr.ht/~jonsterling/forester-devel}these instructions} to submit them for review.
2424+2525+{1 Codebase overview}
2626+2727+The code is organized into several libraries:
2828+2929+{!modules:
3030+ Forester_core
3131+ Forester_compiler
3232+ Forester_frontend
3333+ Forester_lsp}
3434+3535+{{!test} Test}
+62
lib/compiler/Code.mli
···11+type node =
22+ Text of string
33+ | Verbatim of string
44+ | Group of Forester_core.delim * t
55+ | Math of Forester_core.math_mode * t
66+ | Ident of Forester_core.Trie.path
77+ | Hash_ident of string
88+ | Xml_ident of string option * string
99+ | Subtree of string option * t
1010+ | Let of Forester_core.Trie.path *
1111+ Forester_core.Trie.path Forester_core.binding list * t
1212+ | Open of Forester_core.Trie.path
1313+ | Scope of t
1414+ | Put of Forester_core.Trie.path * t
1515+ | Default of Forester_core.Trie.path * t
1616+ | Get of Forester_core.Trie.path
1717+ | Fun of Forester_core.Trie.path Forester_core.binding list * t
1818+ | Object of t _object
1919+ | Patch of t patch
2020+ | Call of t * string
2121+ | Import of Forester_core.visibility * string
2222+ | Def of Forester_core.Trie.path *
2323+ Forester_core.Trie.path Forester_core.binding list * t
2424+ | Decl_xmlns of string * string
2525+ | Alloc of Forester_core.Trie.path
2626+ | Namespace of Forester_core.Trie.path * t
2727+ | Dx_sequent of t * t list
2828+ | Dx_query of string * t list * t list
2929+ | Dx_prop of t * t list
3030+ | Dx_var of string
3131+ | Dx_const_content of t
3232+ | Dx_const_iri of t
3333+ | Comment of string
3434+ | Error of string
3535+3636+and t = node Forester_core.Range.located list
3737+3838+and 'a _object = {
3939+ self : Forester_core.Trie.path option;
4040+ methods : (string * 'a) list;
4141+}
4242+4343+and 'a patch = {
4444+ obj : 'a;
4545+ self : Forester_core.Trie.path option;
4646+ methods : (string * 'a) list;
4747+}
4848+4949+val t : t Repr.t
5050+val pp : Format.formatter -> t -> unit
5151+5252+type tree = { source_path : string option; addr : string option; code : t; }
5353+5454+val parens : t -> node
5555+val squares : t -> node
5656+val braces : t -> node
5757+5858+val import_private : string -> node
5959+val import_public : string -> node
6060+val inline_math : t -> node
6161+val display_math : t -> node
6262+
+4-4
lib/compiler/Forest.mli
···1818(**/**)
19192020val analyse_resource : (module Forest_graphs.S) -> T.content T.resource -> unit
2121-(** [analyse_resource graphs resource] traverses {{!Forester_core.Types.resource}[resource]}, recording facts about it in {{!Forest_graphs.S}[graphs]}.
2121+(** [analyse_resource graphs resource] traverses {{!Forester_core.Types.resource}[resource]}, recording facts about it in {{!Forester_core.Forest_graphs.S}[graphs]}.
22222323- - When encountering a {{!Forester_core.Types.Link}[Link]}, it adds an edge to the {{!Forester_core.Builtin_relation.links_to}[links_to]} relation in {{!Forest_graphs.S}[graphs]}.
2323+ - When encountering a {{!Forester_core.Types.Link}[Link]}, it adds an edge to the {{!Forester_core.Builtin_relation.links_to}[links_to]} relation in {{!Forester_core.Forest_graphs.S}[graphs]}.
24242525- - When encountering a {{!Forester_core.Types.Transclude}[Transclude]}, it adds an edge to the {{!Forester_core.Builtin_relation.transcludes}[transcludes]} relation in {{!Forest_graphs.S}[graphs]}.
2525+ - When encountering a {{!Forester_core.Types.Transclude}[Transclude]}, it adds an edge to the {{!Forester_core.Builtin_relation.transcludes}[transcludes]} relation in {{!Forester_core.Forest_graphs.S}[graphs]}.
26262727- - When encountering a {{!Forester_core.Types.Datalog_script}[Datalog_script script]}, it runs the script and records the results in {{!Forest_graphs.S}[graphs]}.
2727+ - When encountering a {{!Forester_core.Types.Datalog_script}[Datalog_script script]}, it runs the script and records the results in {{!Forester_core.Forest_graphs.S}[graphs]}.
2828 *)
29293030val iri_for_resource : 'a T.resource -> Forester_core__.Base.iri option
···44 * SPDX-License-Identifier: GPL-3.0-or-later
55 *)
6677-open Forester_core
77+(** A simple graph database. Used to record the {{!Forester_core.Builtin_relation}relations} that exist between trees.*)
8899module type S = sig
1010- (** A simple graph database. Used to record the {{!Forester_core.Builtin_relation}relations} that exist between trees.*)
1111-1210 val dl_db : Datalog_engine.db
1311 val register_iri : Iri.t -> unit
1412 val get_all_vertices : unit -> Vertex_set.t
+38-17
lib/compiler/Forester_compiler.ml
···44 * SPDX-License-Identifier: GPL-3.0-or-later
55 *)
6677-(** This library implements the compiler for Forester.
88- *)
77+(** This library implements the compiler for Forester. *)
88+99+(** {1 Base types }*)
9101011module Code = Code
1112(** Abstract syntax *)
···14151516module Symbol = Symbol
16171717-(***)
1818+module Xml_forester = Xml_forester
1919+(** Definition of the forester XML schema. This is the compilation target.*)
2020+2121+(** {1 Compilation phases}*)
2222+2323+(** {2 Parsing}
2424+2525+ The lexer and parser are implemented with {{: https://ocaml.org/manual/5.3/lexyacc.html} ocamllex} and {{: https://gallium.inria.fr/~fpottier/menhir/} menhir}*)
2626+2727+module Lexer = Lexer
2828+2929+module Parse = Parse
18301931module Resolver = Resolver
3232+3333+module Imports = Imports
3434+(** Create {{!Forester_core.Forest_graph.t}import and dependency graphs}.
3535+ *)
3636+2037module Expand = Expand
3838+(** Transform {!Code.tree}s into {!Syn.tree}s by {{!Forester_core.Forest_graph.topo_fold}folding} over the {{!Forester_core.Forest_graph}import graph.}*)
3939+2140module Eval = Eval
2222-module Parse = Parse
2323-module Lexer = Lexer
4141+(** Transform {!Syn.tree}s into {{!Forester_core.Types.article}[articles]}.*)
4242+4343+module Legacy_query_engine = Legacy_query_engine
4444+(* [@@ocaml.deprecated "Use Datalog_query_engine instead"] *)
24452525-module Xml_forester = Xml_forester
2626-(** Definition of the forester XML schema*)
4646+(** {1 High-level architecture}
27472828-module Forest_graph = Forest_graph
2929-(** The graph type used by the datalog database *)
4848+ The compiler needs to support both batch-style and incremental compilation. To this end, we define a {{!State.t}state type} and {{!Phases}transition functions} that act on this state.
30493131-module Forest_graphs = Forest_graphs
5050+ In the future, we want to record more knowledge in {{!field:State.graphs}[graphs]} of the {{!State.t}state} and derive the information we need for the language server via the query system.
32513333-module Imports = Imports
3434-(** Analysis of the abstract syntax to create import and dependency graphs *)
5252+ *)
35533654module Config = Config
3755(** Configuration*)
38563957module Forest = Forest
4040-(**)
5858+(** Augmented hash table used throughout compilation phases.*)
41594260module State = State
4361module Phases = Phases
4462module Asset_router = Asset_router
4545-module Legacy_query_engine = Legacy_query_engine
4646-(* [@@ocaml.deprecated "Use Datalog_query_engine instead"] *)
47634864module Iri_resolver = Iri_resolver
6565+(** Maps URIs and IRIs to paths, documents or code*)
6666+4967module Iri_util = Iri_util
50685169module Diagnostic_store = Diagnostic_store
52705353-module Job = Job
5454-(** Definition of LaTeX jobs*)
7171+(** {1 IO}*)
7272+7373+(** {2 LaTeX pipeline}*)
55745675module LaTeX_pipeline = LaTeX_pipeline
5776module LaTeX_template = LaTeX_template
7777+module Job = Job
7878+(** Definition of LaTeX jobs*)
58795980module Export_for_test = Export_for_test
+5-4
lib/compiler/Phases.ml
···88open Forester_prelude
99open Forester_core
10101111+(**/**)
1112module T = Types
1212-module EP = Eio.Path
13131414type state = State.t
1515+(**/**)
15161617type transition = state -> state
1718···4041 }
41424243let load
4343- : Eio.Fs.dir_ty EP.t list -> transition
4444+ : Eio.Fs.dir_ty Eio.Path.t list -> transition
4445 = fun tree_dirs forest ->
4546 Logs.debug (fun m -> m "loading trees from file system");
4647 tree_dirs
···5152 (* WARNING: using realpath. This is necessary because later on,
5253 the lsp client will send notifications using the absolute path of
5354 a file.*)
5454- let source_path = EP.native_exn path |> Unix.realpath in
5555- let content = EP.load path in
5555+ let source_path = Eio.Path.native_exn path |> Unix.realpath in
5656+ let content = Eio.Path.load path in
5657 let uri = source_path |> Lsp.Uri.of_path in
5758 let tree =
5859 Lsp.Text_document.make
···44 * SPDX-License-Identifier: GPL-3.0-or-later
55 *)
6677+(** Core types
88+ *)
99+710include Base
811912module Iri_scheme = Iri_scheme
10131414+(** {1 Vertices}
1515+1616+ The type of vertices used by the {{!Forester_core.Forest_graphs}graph database}
1717+1818+ *)
1919+1120module Vertex = Vertex
1221module Vertex_set = Vertex_set
2222+2323+(** {1 Error handling}*)
2424+2525+(** Definition of compiler diagnostics and other errors.*)
2626+module Reporter = Reporter
2727+2828+(** Source locations. Among other things these are used by compiler diagnostics and the language server.*)
2929+module Range = Range
3030+3131+(** {1 Query system}
3232+ *)
13331434module Query = Query
3535+3636+(** {2 Builtins}*)
1537module Builtin_relation = Builtin_relation
1638module Builtin_queries = Builtin_queries
17391818-module Reporter = Reporter
1919-module Range = Range
4040+module Forest_graph = Forest_graph
4141+(** The graph type used by the datalog database. Used in particular to track imports, links and transclusions. *)
4242+4343+module Forest_graphs = Forest_graphs
4444+(** The graph database*)
4545+4646+(** {2 Datalog bindings}*)
4747+4848+module Datalog_engine = Datalog_engine
4949+module Datalog_expr = Datalog_expr
5050+module Datalog_eval = Datalog_eval
5151+2052module Prim = Prim
21532254module TeX_cs = TeX_cs
···2456module Types = Types
25572658module Trie = Trie
2727-2828-module Datalog_engine = Datalog_engine
2929-module Datalog_expr = Datalog_expr
3030-module Datalog_eval = Datalog_eval
+2
lib/core/Iri_scheme.mli
···6677open Base
8899+(** Forester uses an IRI scheme that incorporates a host that demarcates the current forest. A typical tree has have an address like this: [forest://host/xxx-NNNN]. Resources such as PDFs or images will be referred to by their hash.*)
1010+911val scheme : string
10121113val base_iri :
···11(*
22- * SPDX-FileCopyrightText: 2024 The Forester Project Contributors AND The RedPRL Development Team
22+ * SPDX-FileCopyrightText: 2024 The Forester Project Contributors
33 *
44 * SPDX-License-Identifier: GPL-3.0-or-later OR Apache-2.0 WITH LLVM-exception
55 *
···7788open Forester_compiler
991010-(** An implementation of the {{: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/} Microsoft Language Server Protocol } for forester. See {!Server.Handlers} for an overview of which methods are currently supported.*)
1010+(** An implementation of the {{: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/} Microsoft Language Server Protocol } for forester. *)
11111212-(** The compiler infrastructure used by the language server*)
1212+(** Analysis of the {{!type:Forester_compiler.Code.t}concrete syntax}*)
1313module Analysis = Analysis
14141515(** The event loop implementation and request handlers*)