My agentic slop goes here. Not intended for anyone else!
at main 7.0 kB view raw
1(** OCaml implementation of the Kitty graphics protocol. 2 3 This library provides a clean API for generating escape sequences to display 4 images and animations in terminals that support the Kitty graphics protocol. 5 6 The protocol uses APC (Application Program Command) escape sequences to transmit 7 and display images with extensive control over placement, sizing, and composition. 8 9 See {{: https://sw.kovidgoyal.net/kitty/graphics-protocol/} Kitty Graphics Protocol} 10 for the complete specification. 11*) 12 13(** {1 Core Types} *) 14 15(** Image format for raw pixel data. *) 16type format = 17 | RGB (** 24-bit RGB (3 bytes per pixel) *) 18 | RGBA (** 32-bit RGBA (4 bytes per pixel) *) 19 | PNG (** PNG format *) 20 21(** Compression method for image data. *) 22type compression = 23 | No_compression 24 | Zlib 25 26(** Transmission medium. *) 27type transmission = 28 | Direct of { 29 format : format; 30 data : bytes; 31 width : int; (** Width in pixels *) 32 height : int; (** Height in pixels *) 33 compression : compression; 34 } 35 | File of { 36 path : string; 37 } 38 39(** Image identifier (number or string up to 24 chars). *) 40type image_id = private string 41 42(** Placement identifier. *) 43type placement_id = private int 44 45(** {1 Image Identifiers} *) 46 47(** [image_id_of_int n] creates an image ID from an integer. 48 @raise Invalid_argument if [n] is negative *) 49val image_id_of_int : int -> image_id 50 51(** [image_id_of_string s] creates an image ID from a string. 52 @raise Invalid_argument if [s] is empty or longer than 24 characters *) 53val image_id_of_string : string -> image_id 54 55(** [placement_id_of_int n] creates a placement ID from an integer. 56 @raise Invalid_argument if [n] is negative *) 57val placement_id_of_int : int -> placement_id 58 59(** {1 Placement Configuration} *) 60 61(** Placement configuration for displaying images. *) 62type placement 63 64(** [v ?image_id ?placement_id ?x ?y ?width ?height ?rows ?columns ?z_index 65 ?cursor_movement transmission ()] creates a placement configuration. 66 67 @param image_id Image identifier for reuse/deletion 68 @param placement_id Placement identifier for this specific display 69 @param x Left edge offset in pixels 70 @param y Top edge offset in pixels 71 @param width Width in pixels (scales image if different from source) 72 @param height Height in pixels (scales image if different from source) 73 @param rows Height in terminal cells 74 @param columns Width in terminal cells 75 @param z_index Z-order for layering (-2^31 to 2^31-1, default 0) 76 @param cursor_movement If false, cursor doesn't move after display (default true) 77 @param transmission The image data transmission method *) 78val v : 79 ?image_id:image_id -> 80 ?placement_id:placement_id -> 81 ?x:int -> 82 ?y:int -> 83 ?width:int -> 84 ?height:int -> 85 ?rows:int -> 86 ?columns:int -> 87 ?z_index:int -> 88 ?cursor_movement:bool -> 89 transmission -> 90 unit -> 91 placement 92 93(** {1 Rendering} *) 94 95(** [render placement] generates the complete escape sequence(s) for the placement. 96 For large images that require chunking, this returns a single string with all chunks. *) 97val render : placement -> string 98 99(** [render_chunked placement] generates escape sequences as a list of chunks. 100 Useful for streaming large images or interleaving with other output. *) 101val render_chunked : placement -> string list 102 103(** {1 Deletion} *) 104 105(** Delete images or placements. *) 106module Delete : sig 107 (** Deletion target. *) 108 type target = 109 | By_id of image_id 110 | By_image_id of image_id 111 | By_placement_id of placement_id 112 | At_cursor 113 | All 114 115 (** [render target] generates the escape sequence to delete images. *) 116 val render : target -> string 117end 118 119(** {1 Animation} *) 120 121(** Animation support for multi-frame images. *) 122module Animation : sig 123 (** Frame composition mode. *) 124 type composition = 125 | Blend (** Alpha blend with previous frame *) 126 | Overwrite (** Replace previous frame *) 127 128 (** Animation frame configuration. *) 129 type frame 130 131 (** [frame ?composition ?gap transmission frame_number] creates a frame configuration. 132 133 @param composition How to compose this frame with previous frames 134 @param gap Gap before next frame in milliseconds (0-65535) 135 @param transmission The frame image data 136 @param frame_number Frame index (1-based) *) 137 val frame : 138 ?composition:composition -> 139 ?gap:int -> 140 transmission -> 141 int -> 142 frame 143 144 (** Animation control. *) 145 type control = 146 | Set_gap of { 147 frame_number : int; (** Which frame to modify *) 148 gap : int; (** New gap in milliseconds *) 149 } 150 | Set_loop of int (** Number of loops (0 = infinite) *) 151 | Stop (** Stop animation *) 152 | Run (** Resume animation *) 153 154 (** [render_frame image_id frame] generates escape sequence for transmitting an animation frame. 155 156 @param image_id The animation's image identifier *) 157 val render_frame : image_id -> frame -> string 158 159 (** [render_control image_id control] generates escape sequence for animation control. *) 160 val render_control : image_id -> control -> string 161end 162 163(** {1 Fmt-style Formatters} *) 164 165(** [pp placement] creates a Fmt formatter that displays an image. 166 167 Example: 168 {[ 169 let img = Graphics.v (Graphics.File { path = "image.png" }) () in 170 Fmt.pr "Here's an image: %a" Graphics.pp img 171 ]} 172*) 173val pp : placement -> unit Fmt.t 174 175(** [pp_delete target] creates a Fmt formatter that deletes images. 176 177 Example: 178 {[ 179 Fmt.pr "Clearing screen: %a" Graphics.pp_delete Graphics.Delete.All 180 ]} 181*) 182val pp_delete : Delete.target -> unit Fmt.t 183 184(** [pp_animation_frame image_id frame] creates a Fmt formatter for animation frames. *) 185val pp_animation_frame : image_id -> Animation.frame -> unit Fmt.t 186 187(** [pp_animation_control image_id control] creates a Fmt formatter for animation control. *) 188val pp_animation_control : image_id -> Animation.control -> unit Fmt.t 189 190(** {1 Convenience Functions} *) 191 192(** [display_png_file ?x ?y ?width ?height ?rows ?columns path] displays a PNG file. 193 194 @param path Path to PNG file 195 @return Escape sequence string *) 196val display_png_file : 197 ?x:int -> 198 ?y:int -> 199 ?width:int -> 200 ?height:int -> 201 ?rows:int -> 202 ?columns:int -> 203 string -> 204 string 205 206(** [display_png_bytes ?x ?y ?width ?height ?rows ?columns ~width:w ~height:h data] 207 displays PNG data from bytes. 208 209 @param width Image width in pixels 210 @param height Image height in pixels 211 @param data PNG-encoded image data 212 @return Escape sequence string *) 213val display_png_bytes : 214 ?x:int -> 215 ?y:int -> 216 ?width:int -> 217 ?height:int -> 218 ?rows:int -> 219 ?columns:int -> 220 w:int -> 221 h:int -> 222 bytes -> 223 string 224 225(** [delete_all ()] generates escape sequence to delete all images. *) 226val delete_all : unit -> string 227 228(** [delete_by_id id] generates escape sequence to delete image by ID. *) 229val delete_by_id : image_id -> string