package forester
A tool for tending mathematical forests
Install
Dune Dependency
Authors
Maintainers
Sources
5.0.tar.gz
md5=24f4aed96a8b8af33aba13fba66f1b37
sha512=d36b896aca11858bb4a00fc704c16cc27a1f197bdb3e479d6132fd70f70d67d7158096285cb0b6fb00db14417f0f822cc27fe65d82f0971e42378fd8271ce573
doc/src/forester.compiler/Forest.ml.html
Source file Forest.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 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
(* * SPDX-FileCopyrightText: 2024 The Forester Project Contributors * * SPDX-License-Identifier: GPL-3.0-or-later *) open Forester_prelude open Forester_core open struct module T = Types module Dx = Datalog_expr end include URI.Tbl type article = T.content T.article type env = (module Forest_graphs.S) let execute_datalog_script graphs script = let module Graphs = (val graphs : Forest_graphs.S) in let@ sequent = List.iter @~ script in Datalog_engine.db_add Graphs.dl_db (Datalog_eval.eval_sequent sequent) (* TODO: Why is this not run at the top level? *) (* let () = execute_datalog_script Builtin_relation.axioms *) let run_datalog_query (graphs : env) (q : (string, Vertex.t) Dx.query) : Vertex_set.t = let@ () = Reporter.trace "when running query" in (* TODO: See above *) let () = execute_datalog_script graphs Builtin_relation.axioms in let module Graphs = (val graphs) in Datalog_eval.run_query Graphs.dl_db q let add_edge graphs rel ~source ~target = let module Graphs = (val graphs : Forest_graphs.S) in let premises = [] in let conclusion = let args = [Dx.Const source; Dx.Const target] in Dx.{rel; args} in execute_datalog_script graphs [{conclusion; premises}] let add_fact graphs rel node = let module Graphs = (val graphs : Forest_graphs.S) in let premises = [] in let conclusion = let args = [Dx.Const node] in Dx.{rel; args} in execute_datalog_script graphs [{conclusion; premises}] let rec analyse_content_node graphs (scope : URI.t) (node : 'a T.content_node) : unit = match node with | Text _ | CDATA _ | Route_of_uri _ | Uri _ | Results_of_datalog_query _ | Contextual_number _ -> () | Transclude transclusion -> analyse_transclusion graphs scope transclusion | Xml_elt elt -> begin let@ attr = List.iter @~ elt.attrs in analyse_content graphs scope attr.value end; analyse_content graphs scope elt.content | Section section -> analyse_section graphs scope section | Link link -> add_edge graphs Builtin_relation.links_to ~source: (Uri_vertex scope) ~target: (Uri_vertex link.href); analyse_content graphs scope link.content | KaTeX (_, content) -> analyse_content graphs scope content | Artefact artefact -> analyse_artefact graphs scope artefact | Datalog_script script -> execute_datalog_script graphs script and analyse_artefact graphs scope artefact = analyse_content graphs scope artefact.content and analyse_transclusion graphs (scope : URI.t) (transclusion : T.transclusion) : unit = match transclusion.target with | Full _ | Mainmatter -> add_edge graphs Builtin_relation.transcludes ~source: (Uri_vertex scope) ~target: (Uri_vertex transclusion.href) | Title _ | Taxon -> () and analyse_content (graphs : env) (scope : URI.t) (content : T.content) : unit = T.extract_content content |> List.iter @@ analyse_content_node graphs scope and analyse_attribution graphs (scope : URI.t) (attr : _ T.attribution) = let rel = match attr.role with | Author -> Builtin_relation.has_author | Contributor -> Builtin_relation.has_direct_contributor in add_edge graphs rel ~source: (Uri_vertex scope) ~target: attr.vertex; analyse_vertex graphs scope attr.vertex and analyse_vertex graphs scope vtx = match vtx with | Uri_vertex _ -> () | Content_vertex content -> analyse_content graphs scope content and analyse_tag graphs (scope : URI.t) (tag : _ T.vertex) = analyse_vertex graphs scope tag; add_edge graphs Builtin_relation.has_tag ~source: (Uri_vertex scope) ~target: tag and analyse_taxon graphs (scope : URI.t) (taxon_opt : T.content option) = let@ taxon = Option.iter @~ taxon_opt in analyse_content graphs scope taxon; add_edge graphs Builtin_relation.has_taxon ~source: (Uri_vertex scope) ~target: (Content_vertex taxon) and analyse_attributions graphs (scope : URI.t) = List.iter @@ analyse_attribution graphs scope and graphs (scope : URI.t) = List.iter @@ analyse_tag graphs scope and analyse_frontmatter graphs (scope : URI.t) (fm : T.content T.frontmatter) : unit = Option.iter (analyse_content graphs scope) fm.title; analyse_taxon graphs scope fm.taxon; analyse_attributions graphs scope fm.attributions; analyse_tags graphs scope fm.tags; analyse_metas graphs scope fm.metas and analyse_metas graphs (scope : URI.t) = List.iter @@ analyse_meta graphs scope and analyse_meta graphs (scope : URI.t) (_, content) : unit = analyse_content graphs scope content and analyse_section graphs (scope : URI.t) (section : T.content T.section) : unit = begin let@ target = Option.iter @~ section.frontmatter.uri in add_edge graphs Builtin_relation.transcludes ~source: (Uri_vertex scope) ~target: (Uri_vertex target) end; let scope = Option.value ~default: scope section.frontmatter.uri in analyse_frontmatter graphs scope section.frontmatter; analyse_content graphs scope section.mainmatter let analyse_article graphs (article : article) : unit = let@ scope = Option.iter @~ article.frontmatter.uri in add_fact graphs Builtin_relation.is_article (T.Uri_vertex scope); analyse_frontmatter graphs scope article.frontmatter; analyse_content graphs scope article.mainmatter; analyse_content graphs scope article.backmatter let analyse_asset graphs (asset : T.asset) : unit = add_fact graphs Builtin_relation.is_asset (T.Uri_vertex asset.uri) let analyse_resource graphs = function | T.Article article -> analyse_article graphs article | T.Asset asset -> analyse_asset graphs asset | _ -> () let get_article : URI.t -> _ t -> T.content T.article option = fun uri forest -> match find_opt forest uri with | None -> None | Some (T.Asset _) -> Logs.debug (fun m -> m "%a is an asset, not an article" URI.pp uri); None | Some (T.Syndication _) -> Logs.debug (fun m -> m "%a is a syndication, not an article" URI.pp uri); None | Some (T.Article article) -> Some article let rec get_expanded_title ?scope ?(flags = T.{empty_when_untitled = false}) (frontmatter : _ T.frontmatter) forest = let short_title = match frontmatter.title with | Some content -> content | None when not flags.empty_when_untitled -> begin match frontmatter.uri with | Some uri -> T.Content [T.Uri uri] | _ -> T.Content [T.Text "Untitled"] end | _ -> T.Content [] in Option.value ~default: short_title @@ match frontmatter.designated_parent with | Some parent_uri when not (Option.equal URI.equal scope frontmatter.designated_parent) -> let@ parent = Option.map @~ get_article parent_uri forest in let parent_title = get_expanded_title parent.frontmatter forest in let parent_link = T.Link {href = parent_uri; content = parent_title} in let chevron = T.Text " › " in T.map_content (fun xs -> parent_link :: chevron :: xs) short_title | _ -> None let section_symbol = "§" let get_content_of_transclusion (transclusion : T.transclusion) forest = match transclusion.target with | Full flags -> let@ article = Option.map @~ get_article transclusion.href forest in T.Content [T.Section (T.article_to_section article ~flags)] | Mainmatter -> let@ article = Option.map @~ get_article transclusion.href forest in article.mainmatter | Title flags -> Option.some @@ begin match get_article transclusion.href forest with | None -> T.Content [T.Uri transclusion.href] | Some article -> get_expanded_title ~flags article.frontmatter forest end | Taxon -> let@ article = Option.map @~ get_article transclusion.href forest in let default = T.Content [T.Text section_symbol] in Option.value ~default article.frontmatter.taxon let get_title_or_content_of_vertex ?(not_found = fun _ -> None) vertex forest = match vertex with | T.Content_vertex content -> Some content | T.Uri_vertex uri -> begin match get_article uri forest with | Some article -> article.frontmatter.title | None -> not_found uri end let get_all_articles resources = let extract_article = function | T.Article a -> Some a | _ -> None in resources |> to_seq_values |> Seq.filter_map extract_article |> List.of_seq let get_all_assets resources = let extract_asset = function | T.Asset a -> Some a | _ -> None in resources |> to_seq_values |> Seq.filter_map extract_asset |> List.of_seq let get_all_resources resources = resources |> to_seq_values |> List.of_seq
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>