package mdx
Executable code blocks inside markdown files
Install
Dune Dependency
Authors
Maintainers
Sources
mdx-1.11.1.tbz
sha256=603990812efa7184d88a4896d7f9369b43d32e3dbdd26fe9cecb5a5f5f32c1e0
sha512=461bb3f2e25f8a2f869577ec8f95f731e0765a534043088fdc88ee9fabaa52926eb957124529ff889f1d698df594b235219c677521eebe01a5959c7db75131ea
doc/src/mdx/label.ml.html
Source file label.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
(* * Copyright (c) 2018 Thomas Gazagnaire <thomas@gazagnaire.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) open Compat open Result module Relation = struct type t = Eq | Neq | Le | Lt | Ge | Gt let pp ppf = function | Eq -> Fmt.string ppf "=" | Neq -> Fmt.string ppf "<>" | Gt -> Fmt.string ppf ">" | Ge -> Fmt.string ppf ">=" | Lt -> Fmt.string ppf "<" | Le -> Fmt.string ppf "<=" let compare = function | Eq -> ( = ) | Neq -> ( <> ) | Lt -> ( < ) | Le -> ( <= ) | Gt -> ( > ) | Ge -> ( >= ) let of_string = function | "<>" -> Neq | ">=" -> Ge | ">" -> Gt | "<=" -> Le | "<" -> Lt | "=" -> Eq | _ -> (* can not happen, filtered by the regexp *) assert false let re = let open Re in compile @@ seq [ bos; group (rep (alt [ alnum; char '-'; char '_' ])); group (alt [ str "<="; str ">="; str "<>"; str "<"; str ">"; str "=" ]); group (rep any); eos; ] let raw_parse s = match Re.exec_opt re s with | None -> (s, None) | Some g -> ( try let label = Re.Group.get g 1 in let op = of_string (Re.Group.get g 2) in let value = Re.Group.get g 3 in (label, Some (op, value)) with Not_found -> (s, None)) end type non_det = Nd_output | Nd_command let default_non_det = Nd_output type block_kind = OCaml | Cram | Toplevel | Include type t = | Dir of string | Source_tree of string | File of string | Part of string | Env of string | Skip | Non_det of non_det option | Version of Relation.t * Ocaml_version.t | Require_package of string | Set of string * string | Unset of string | Block_kind of block_kind let pp_block_kind ppf = function | OCaml -> Fmt.string ppf "ocaml" | Cram -> Fmt.string ppf "cram" | Toplevel -> Fmt.string ppf "toplevel" | Include -> Fmt.string ppf "include" let pp ppf = function | Dir d -> Fmt.pf ppf "dir=%s" d | Source_tree s -> Fmt.pf ppf "source-tree=%s" s | File f -> Fmt.pf ppf "file=%s" f | Part p -> Fmt.pf ppf "part=%s" p | Env e -> Fmt.pf ppf "env=%s" e | Skip -> Fmt.string ppf "skip" | Non_det None -> Fmt.string ppf "non-deterministic" | Non_det (Some Nd_output) -> Fmt.string ppf "non-deterministic=output" | Non_det (Some Nd_command) -> Fmt.string ppf "non-deterministic=command" | Version (op, v) -> Fmt.pf ppf "version%a%a" Relation.pp op Ocaml_version.pp v | Require_package p -> Fmt.pf ppf "require-package=%s" p | Set (v, x) -> Fmt.pf ppf "set-%s=%s" v x | Unset x -> Fmt.pf ppf "unset-%s" x | Block_kind bk -> pp_block_kind ppf bk let is_prefix ~prefix s = let len_prefix = String.length prefix in if String.length s > len_prefix then String.equal (String.sub s 0 len_prefix) prefix else false (* [is_prefix ~prefix s] is always checked before. *) let split_prefix ~prefix s = let len_prefix = String.length prefix in String.sub s len_prefix (String.length s - len_prefix) let non_eq_op ~label = Util.Result.errorf "Label `%s` requires assignment using the `=` operator." label let invalid_value ~label ~allowed_values value = Util.Result.errorf "%S is not a valid value for label `%s`. Valid values are %s." value label (Util.String.english_conjonction allowed_values) let doesnt_accept_value ~label ~value res = match value with | Some _ -> Util.Result.errorf "Label `%s` does not allow a value." label | None -> Ok res let requires_value ~label ~value f = match value with | Some (op, v) -> f op v | None -> Util.Result.errorf "Label `%s` requires a value." label let requires_eq_value ~label ~value f = requires_value ~label ~value (fun op value -> match op with Relation.Eq -> Ok (f value) | _ -> non_eq_op ~label) let interpret label value = match label with | "skip" -> doesnt_accept_value ~label ~value Skip | "ocaml" -> doesnt_accept_value ~label ~value (Block_kind OCaml) | "cram" -> doesnt_accept_value ~label ~value (Block_kind Cram) | "toplevel" -> doesnt_accept_value ~label ~value (Block_kind Toplevel) | "include" -> doesnt_accept_value ~label ~value (Block_kind Include) | v when is_prefix ~prefix:"unset-" v -> doesnt_accept_value ~label ~value (Unset (split_prefix ~prefix:"unset-" v)) | "version" -> requires_value ~label ~value (fun op v -> match Ocaml_version.of_string v with | Ok v -> Ok (Version (op, v)) | Error (`Msg e) -> Util.Result.errorf "Invalid `version` label value: %s." e) | "non-deterministic" -> ( match value with | None -> Ok (Non_det None) | Some (Relation.Eq, "output") -> Ok (Non_det (Some Nd_output)) | Some (Relation.Eq, "command") -> Ok (Non_det (Some Nd_command)) | Some (Relation.Eq, v) -> let allowed_values = [ "<none>"; {|"command"|}; {|"output"|} ] in invalid_value ~label ~allowed_values v | Some _ -> non_eq_op ~label) | "dir" -> requires_eq_value ~label ~value (fun x -> Dir x) | "source-tree" -> requires_eq_value ~label ~value (fun x -> Source_tree x) | "file" -> requires_eq_value ~label ~value (fun x -> File x) | "part" -> requires_eq_value ~label ~value (fun x -> Part x) | "env" -> requires_eq_value ~label ~value (fun x -> Env x) | "require-package" -> requires_eq_value ~label ~value (fun x -> Require_package x) | l when is_prefix ~prefix:"set-" l -> requires_eq_value ~label ~value (fun x -> Set (split_prefix ~prefix:"set-" l, x)) | l -> Error (`Msg (Format.sprintf "`%s` is not a valid label." l)) let of_string s = let f acc s = let label, value = Relation.raw_parse s in match (acc, interpret label value) with | Ok labels, Ok label -> Ok (label :: labels) | Error msgs, Ok _ -> Error msgs | Ok _, Error msg -> Error [ msg ] | Error msgs, Error msg -> Error (msg :: msgs) in match s with | "" -> Ok [] | s -> ( let split = String.split_on_char ',' s in match List.fold_left f (Ok []) split with | Ok labels -> Ok (List.rev labels) | Error msgs -> Error (List.rev msgs))
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>