1/**
2 * @file formatter.h
3 *
4 * Format terminal content as plain text, VT sequences, or HTML.
5 */
6
7#ifndef GHOSTTY_VT_FORMATTER_H
8#define GHOSTTY_VT_FORMATTER_H
9
10#include <stdbool.h>
11#include <stddef.h>
12#include <stdint.h>
13#include <ghostty/vt/allocator.h>
14#include <ghostty/vt/selection.h>
15#include <ghostty/vt/types.h>
16#include <ghostty/vt/terminal.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
22/** @defgroup formatter Formatter
23 *
24 * Format terminal content as plain text, VT sequences, or HTML.
25 *
26 * A formatter captures a reference to a terminal and formatting options.
27 * It can be used repeatedly to produce output that reflects the current
28 * terminal state at the time of each format call.
29 *
30 * The terminal must outlive the formatter.
31 *
32 * @{
33 */
34
35/**
36 * Extra screen state to include in styled output.
37 *
38 * @ingroup formatter
39 */
40typedef struct {
41 /** Size of this struct in bytes. Must be set to sizeof(GhosttyFormatterScreenExtra). */
42 size_t size;
43
44 /** Emit cursor position using CUP (CSI H). */
45 bool cursor;
46
47 /** Emit current SGR style state based on the cursor's active style_id. */
48 bool style;
49
50 /** Emit current hyperlink state using OSC 8 sequences. */
51 bool hyperlink;
52
53 /** Emit character protection mode using DECSCA. */
54 bool protection;
55
56 /** Emit Kitty keyboard protocol state using CSI > u and CSI = sequences. */
57 bool kitty_keyboard;
58
59 /** Emit character set designations and invocations. */
60 bool charsets;
61} GhosttyFormatterScreenExtra;
62
63/**
64 * Extra terminal state to include in styled output.
65 *
66 * @ingroup formatter
67 */
68typedef struct {
69 /** Size of this struct in bytes. Must be set to sizeof(GhosttyFormatterTerminalExtra). */
70 size_t size;
71
72 /** Emit the palette using OSC 4 sequences. */
73 bool palette;
74
75 /** Emit terminal modes that differ from their defaults using CSI h/l. */
76 bool modes;
77
78 /** Emit scrolling region state using DECSTBM and DECSLRM sequences. */
79 bool scrolling_region;
80
81 /** Emit tabstop positions by clearing all tabs and setting each one. */
82 bool tabstops;
83
84 /** Emit the present working directory using OSC 7. */
85 bool pwd;
86
87 /** Emit keyboard modes such as ModifyOtherKeys. */
88 bool keyboard;
89
90 /** Screen-level extras. */
91 GhosttyFormatterScreenExtra screen;
92} GhosttyFormatterTerminalExtra;
93
94/**
95 * Options for creating a terminal formatter.
96 *
97 * @ingroup formatter
98 */
99typedef struct {
100 /** Size of this struct in bytes. Must be set to sizeof(GhosttyFormatterTerminalOptions). */
101 size_t size;
102
103 /** Output format to emit. */
104 GhosttyFormatterFormat emit;
105
106 /** Whether to unwrap soft-wrapped lines. */
107 bool unwrap;
108
109 /** Whether to trim trailing whitespace on non-blank lines. */
110 bool trim;
111
112 /** Extra terminal state to include in styled output. */
113 GhosttyFormatterTerminalExtra extra;
114
115 /** Optional selection to restrict output to a range.
116 * If NULL, the entire screen is formatted. */
117 const GhosttySelection *selection;
118} GhosttyFormatterTerminalOptions;
119
120/**
121 * Create a formatter for a terminal's active screen.
122 *
123 * The terminal must outlive the formatter. The formatter stores a borrowed
124 * reference to the terminal and reads its current state on each format call.
125 *
126 * @param allocator Pointer to allocator, or NULL to use the default allocator
127 * @param formatter Pointer to store the created formatter handle
128 * @param terminal The terminal to format (must not be NULL)
129 * @param options Formatting options
130 * @return GHOSTTY_SUCCESS on success, or an error code on failure
131 *
132 * @ingroup formatter
133 */
134GHOSTTY_API GhosttyResult ghostty_formatter_terminal_new(
135 const GhosttyAllocator* allocator,
136 GhosttyFormatter* formatter,
137 GhosttyTerminal terminal,
138 GhosttyFormatterTerminalOptions options);
139
140/**
141 * Run the formatter and produce output into the caller-provided buffer.
142 *
143 * Each call formats the current terminal state. Pass NULL for buf to
144 * query the required buffer size without writing any output; in that case
145 * out_written receives the required size and the return value is
146 * GHOSTTY_OUT_OF_SPACE.
147 *
148 * If the buffer is too small, returns GHOSTTY_OUT_OF_SPACE and sets
149 * out_written to the required size. The caller can then retry with a
150 * larger buffer.
151 *
152 * @param formatter The formatter handle (must not be NULL)
153 * @param buf Pointer to the output buffer, or NULL to query size
154 * @param buf_len Length of the output buffer in bytes
155 * @param out_written Pointer to receive the number of bytes written,
156 * or the required size on failure
157 * @return GHOSTTY_SUCCESS on success, or an error code on failure
158 *
159 * @ingroup formatter
160 */
161GHOSTTY_API GhosttyResult ghostty_formatter_format_buf(GhosttyFormatter formatter,
162 uint8_t* buf,
163 size_t buf_len,
164 size_t* out_written);
165
166/**
167 * Run the formatter and return an allocated buffer with the output.
168 *
169 * Each call formats the current terminal state. The buffer is allocated
170 * using the provided allocator (or the default allocator if NULL).
171 * The caller is responsible for freeing the returned buffer with
172 * ghostty_free(), passing the same allocator (or NULL for the default)
173 * that was used for the allocation.
174 *
175 * @param formatter The formatter handle (must not be NULL)
176 * @param allocator Pointer to allocator, or NULL to use the default allocator
177 * @param out_ptr Pointer to receive the allocated buffer
178 * @param out_len Pointer to receive the length of the output in bytes
179 * @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation
180 * failure
181 *
182 * @ingroup formatter
183 */
184GHOSTTY_API GhosttyResult ghostty_formatter_format_alloc(GhosttyFormatter formatter,
185 const GhosttyAllocator* allocator,
186 uint8_t** out_ptr,
187 size_t* out_len);
188
189/**
190 * Free a formatter instance.
191 *
192 * Releases all resources associated with the formatter. After this call,
193 * the formatter handle becomes invalid.
194 *
195 * @param formatter The formatter handle to free (may be NULL)
196 *
197 * @ingroup formatter
198 */
199GHOSTTY_API void ghostty_formatter_free(GhosttyFormatter formatter);
200
201/** @} */
202
203#ifdef __cplusplus
204}
205#endif
206
207#endif /* GHOSTTY_VT_FORMATTER_H */