package ppx_demo
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
PPX that exposes the source code string of an expression/module structure.
Install
dune-project
Dependency
Authors
Maintainers
Sources
v0.17.0.tar.gz
sha256=eaff90e151e326e7b6dbe163bfa976005944612e1ca146344733a7ed034ec988
doc/src/ppx_demo/ppx_demo.ml.html
Source file ppx_demo.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 88open! Core open Ppxlib open Ast_builder.Default let ppx_name = "demo" let files = String.Table.create () let read_file filename = match Hashtbl.find files filename with | Some file_contents -> file_contents | None -> let file_contents = In_channel.read_all filename in Hashtbl.add_exn files ~key:filename ~data:file_contents; file_contents ;; let create_demo_string ~loc_start ~loc_end = (* We start the substring a little further into the string so that we can strip off the leading "[%demo" of the expression. *) let start_index = loc_start.pos_cnum + String.length ppx_name + 2 in (* We end the substring one character earlier to strip off the trailing "]" from the ppx. *) let end_index = loc_end.pos_cnum - 1 in let file_contents = read_file loc_start.pos_fname in let () = let sanity_check_substring = String.sub file_contents ~pos:loc_start.pos_cnum ~len:(String.length ppx_name + 2) in if not (String.equal sanity_check_substring "[%demo") then failwith "ppx_demo requires that extension node be of the form [%demo ...]" in let substring_length = end_index - start_index in let pad_length = start_index - loc_start.pos_bol in let buffer = Buffer.create (substring_length + pad_length) in for _ = 0 to pad_length - 1 do Buffer.add_char buffer ' ' done; Buffer.add_substring buffer file_contents ~pos:start_index ~len:substring_length; Buffer.contents buffer |> Dedent.string ;; let expand_expr ~loc:{ loc_start; loc_end; _ } ~path:_ expr = let string = create_demo_string ~loc_start ~loc_end in let loc = { loc_start; loc_end; loc_ghost = true } in pexp_tuple ~loc [ expr; estring ~loc string ] ;; let expand_str ~loc:{ loc_start; loc_end; _ } ~path:_ (structure : structure) = let string = create_demo_string ~loc_start ~loc_end in let loc = { loc_start; loc_end; loc_ghost = true } in (* let ppx_demo_string = (* demo string of structure *) *) let demo = pstr_value ~loc Nonrecursive [ value_binding ~loc ~pat:(ppat_var ~loc { txt = "ppx_demo_string"; loc }) ~expr:(estring ~loc string) ] in (* {[ struct (* original structure *) let ppx_demo_string = (* demo string of structure *) end ]} *) pmod_structure ~loc (structure @ [ demo ]) ;; let () = Driver.register_transformation ppx_name ~extensions: [ Extension.declare ppx_name Extension.Context.expression Ast_pattern.(single_expr_payload __) expand_expr ; Extension.declare ppx_name Extension.Context.module_expr Ast_pattern.(pstr __) expand_str ] ;;
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>