react-native-codepad-lang-markdown 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CodepadLangMarkdown.podspec +28 -0
- package/README.md +50 -2
- package/android/CMakeLists.txt +19 -0
- package/android/build.gradle +61 -0
- package/android/consumer-rules.pro +2 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/assets/codepad-languages/markdown +1 -0
- package/android/src/main/assets/codepad-languages/markdown_inline +1 -0
- package/android/src/main/cpp/lang.c +17 -0
- package/android/src/main/java/me/sectiontn/codepad/lang/markdown/CodepadLangMarkdownPackage.kt +13 -0
- package/android/src/main/java/me/sectiontn/codepad/lang/markdown/MarkdownLanguage.kt +169 -0
- package/android/src/main/java/me/sectiontn/codepad/lang/markdown_inline/MarkdownInlineLanguage.kt +156 -0
- package/grammar/LICENSE +21 -0
- package/grammar/tree-sitter-markdown/src/parser.c +59787 -0
- package/grammar/tree-sitter-markdown/src/scanner.c +1602 -0
- package/grammar/tree-sitter-markdown/src/tree_sitter/alloc.h +54 -0
- package/grammar/tree-sitter-markdown/src/tree_sitter/array.h +330 -0
- package/grammar/tree-sitter-markdown/src/tree_sitter/parser.h +286 -0
- package/grammar/tree-sitter-markdown-inline/src/parser.c +75709 -0
- package/grammar/tree-sitter-markdown-inline/src/scanner.c +397 -0
- package/grammar/tree-sitter-markdown-inline/src/tree_sitter/alloc.h +54 -0
- package/grammar/tree-sitter-markdown-inline/src/tree_sitter/array.h +330 -0
- package/grammar/tree-sitter-markdown-inline/src/tree_sitter/parser.h +286 -0
- package/ios/CPLangMarkdown.h +11 -0
- package/ios/CPLangMarkdown.swift +162 -0
- package/ios/CPLangMarkdownInline.h +11 -0
- package/ios/CPLangMarkdownInline.swift +149 -0
- package/package.json +40 -4
- package/queries/markdown/highlights.scm +123 -0
- package/queries/markdown/indents.scm +1 -0
- package/queries/markdown/injections.scm +25 -0
- package/queries/markdown_inline/highlights.scm +128 -0
- package/queries/markdown_inline/injections.scm +7 -0
- package/src/index.ts +2 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
#include "tree_sitter/parser.h"
|
|
2
|
+
|
|
3
|
+
#ifdef _MSC_VER
|
|
4
|
+
#define UNUSED __pragma(warning(suppress : 4101))
|
|
5
|
+
#else
|
|
6
|
+
#define UNUSED __attribute__((unused))
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
// For explanation of the tokens see grammar.js
|
|
10
|
+
typedef enum {
|
|
11
|
+
ERROR,
|
|
12
|
+
TRIGGER_ERROR,
|
|
13
|
+
CODE_SPAN_START,
|
|
14
|
+
CODE_SPAN_CLOSE,
|
|
15
|
+
EMPHASIS_OPEN_STAR,
|
|
16
|
+
EMPHASIS_OPEN_UNDERSCORE,
|
|
17
|
+
EMPHASIS_CLOSE_STAR,
|
|
18
|
+
EMPHASIS_CLOSE_UNDERSCORE,
|
|
19
|
+
LAST_TOKEN_WHITESPACE,
|
|
20
|
+
LAST_TOKEN_PUNCTUATION,
|
|
21
|
+
STRIKETHROUGH_OPEN,
|
|
22
|
+
STRIKETHROUGH_CLOSE,
|
|
23
|
+
LATEX_SPAN_START,
|
|
24
|
+
LATEX_SPAN_CLOSE,
|
|
25
|
+
UNCLOSED_SPAN
|
|
26
|
+
} TokenType;
|
|
27
|
+
|
|
28
|
+
// Determines if a character is punctuation as defined by the markdown spec.
|
|
29
|
+
static bool is_punctuation(int32_t chr) {
|
|
30
|
+
return (chr >= '!' && chr <= '/') || (chr >= ':' && chr <= '@') ||
|
|
31
|
+
(chr >= '[' && chr <= '`') || (chr >= '{' && chr <= '~');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// State bitflags used with `Scanner.state`
|
|
35
|
+
|
|
36
|
+
// TODO
|
|
37
|
+
static UNUSED const uint8_t STATE_EMPHASIS_DELIMITER_MOD_3 = 0x3;
|
|
38
|
+
// Current delimiter run is opening
|
|
39
|
+
static const uint8_t STATE_EMPHASIS_DELIMITER_IS_OPEN = 0x1 << 2;
|
|
40
|
+
|
|
41
|
+
// Convenience function to emit the error token. This is done to stop invalid
|
|
42
|
+
// parse branches. Specifically:
|
|
43
|
+
// 1. When encountering a newline after a line break that ended a paragraph, and
|
|
44
|
+
// no new block
|
|
45
|
+
// has been opened.
|
|
46
|
+
// 2. When encountering a new block after a soft line break.
|
|
47
|
+
// 3. When a `$._trigger_error` token is valid, which is used to stop parse
|
|
48
|
+
// branches through
|
|
49
|
+
// normal tree-sitter grammar rules.
|
|
50
|
+
//
|
|
51
|
+
// See also the `$._soft_line_break` and `$._paragraph_end_newline` tokens in
|
|
52
|
+
// grammar.js
|
|
53
|
+
static bool error(TSLexer *lexer) {
|
|
54
|
+
lexer->result_symbol = ERROR;
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
typedef struct {
|
|
59
|
+
// Parser state flags
|
|
60
|
+
uint8_t state;
|
|
61
|
+
uint8_t code_span_delimiter_length;
|
|
62
|
+
uint8_t latex_span_delimiter_length;
|
|
63
|
+
// The number of characters remaining in the currrent emphasis delimiter
|
|
64
|
+
// run.
|
|
65
|
+
uint8_t num_emphasis_delimiters_left;
|
|
66
|
+
|
|
67
|
+
} Scanner;
|
|
68
|
+
|
|
69
|
+
// Write the whole state of a Scanner to a byte buffer
|
|
70
|
+
static unsigned serialize(Scanner *s, char *buffer) {
|
|
71
|
+
unsigned size = 0;
|
|
72
|
+
buffer[size++] = (char)s->state;
|
|
73
|
+
buffer[size++] = (char)s->code_span_delimiter_length;
|
|
74
|
+
buffer[size++] = (char)s->latex_span_delimiter_length;
|
|
75
|
+
buffer[size++] = (char)s->num_emphasis_delimiters_left;
|
|
76
|
+
return size;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Read the whole state of a Scanner from a byte buffer
|
|
80
|
+
// `serizalize` and `deserialize` should be fully symmetric.
|
|
81
|
+
static void deserialize(Scanner *s, const char *buffer, unsigned length) {
|
|
82
|
+
s->state = 0;
|
|
83
|
+
s->code_span_delimiter_length = 0;
|
|
84
|
+
s->latex_span_delimiter_length = 0;
|
|
85
|
+
s->num_emphasis_delimiters_left = 0;
|
|
86
|
+
if (length > 0) {
|
|
87
|
+
size_t size = 0;
|
|
88
|
+
s->state = (uint8_t)buffer[size++];
|
|
89
|
+
s->code_span_delimiter_length = (uint8_t)buffer[size++];
|
|
90
|
+
s->latex_span_delimiter_length = (uint8_t)buffer[size++];
|
|
91
|
+
s->num_emphasis_delimiters_left = (uint8_t)buffer[size++];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static bool parse_leaf_delimiter(TSLexer *lexer, uint8_t *delimiter_length,
|
|
96
|
+
const bool *valid_symbols,
|
|
97
|
+
const char delimiter,
|
|
98
|
+
const TokenType open_token,
|
|
99
|
+
const TokenType close_token) {
|
|
100
|
+
uint8_t level = 0;
|
|
101
|
+
while (lexer->lookahead == delimiter) {
|
|
102
|
+
lexer->advance(lexer, false);
|
|
103
|
+
level++;
|
|
104
|
+
}
|
|
105
|
+
lexer->mark_end(lexer);
|
|
106
|
+
if (level == *delimiter_length && valid_symbols[close_token]) {
|
|
107
|
+
*delimiter_length = 0;
|
|
108
|
+
lexer->result_symbol = close_token;
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
if (valid_symbols[open_token]) {
|
|
112
|
+
// Parse ahead to check if there is a closing delimiter
|
|
113
|
+
size_t close_level = 0;
|
|
114
|
+
while (!lexer->eof(lexer)) {
|
|
115
|
+
if (lexer->lookahead == delimiter) {
|
|
116
|
+
close_level++;
|
|
117
|
+
} else {
|
|
118
|
+
if (close_level == level) {
|
|
119
|
+
// Found a matching delimiter
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
close_level = 0;
|
|
123
|
+
}
|
|
124
|
+
lexer->advance(lexer, false);
|
|
125
|
+
}
|
|
126
|
+
if (close_level == level) {
|
|
127
|
+
*delimiter_length = level;
|
|
128
|
+
lexer->result_symbol = open_token;
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
if (valid_symbols[UNCLOSED_SPAN]) {
|
|
132
|
+
lexer->result_symbol = UNCLOSED_SPAN;
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static bool parse_backtick(Scanner *s, TSLexer *lexer,
|
|
140
|
+
const bool *valid_symbols) {
|
|
141
|
+
return parse_leaf_delimiter(lexer, &s->code_span_delimiter_length,
|
|
142
|
+
valid_symbols, '`', CODE_SPAN_START,
|
|
143
|
+
CODE_SPAN_CLOSE);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
static bool parse_dollar(Scanner *s, TSLexer *lexer,
|
|
147
|
+
const bool *valid_symbols) {
|
|
148
|
+
return parse_leaf_delimiter(lexer, &s->latex_span_delimiter_length,
|
|
149
|
+
valid_symbols, '$', LATEX_SPAN_START,
|
|
150
|
+
LATEX_SPAN_CLOSE);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static bool parse_star(Scanner *s, TSLexer *lexer, const bool *valid_symbols) {
|
|
154
|
+
lexer->advance(lexer, false);
|
|
155
|
+
// If `num_emphasis_delimiters_left` is not zero then we already decided
|
|
156
|
+
// that this should be part of an emphasis delimiter run, so interpret it as
|
|
157
|
+
// such.
|
|
158
|
+
if (s->num_emphasis_delimiters_left > 0) {
|
|
159
|
+
// The `STATE_EMPHASIS_DELIMITER_IS_OPEN` state flag tells us wether it
|
|
160
|
+
// should be open or close.
|
|
161
|
+
if ((s->state & STATE_EMPHASIS_DELIMITER_IS_OPEN) &&
|
|
162
|
+
valid_symbols[EMPHASIS_OPEN_STAR]) {
|
|
163
|
+
s->state &= (~STATE_EMPHASIS_DELIMITER_IS_OPEN);
|
|
164
|
+
lexer->result_symbol = EMPHASIS_OPEN_STAR;
|
|
165
|
+
s->num_emphasis_delimiters_left--;
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
if (valid_symbols[EMPHASIS_CLOSE_STAR]) {
|
|
169
|
+
lexer->result_symbol = EMPHASIS_CLOSE_STAR;
|
|
170
|
+
s->num_emphasis_delimiters_left--;
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
lexer->mark_end(lexer);
|
|
175
|
+
// Otherwise count the number of stars
|
|
176
|
+
uint8_t star_count = 1;
|
|
177
|
+
while (lexer->lookahead == '*') {
|
|
178
|
+
star_count++;
|
|
179
|
+
lexer->advance(lexer, false);
|
|
180
|
+
}
|
|
181
|
+
bool line_end = lexer->lookahead == '\n' || lexer->lookahead == '\r' ||
|
|
182
|
+
lexer->eof(lexer);
|
|
183
|
+
if (valid_symbols[EMPHASIS_OPEN_STAR] ||
|
|
184
|
+
valid_symbols[EMPHASIS_CLOSE_STAR]) {
|
|
185
|
+
// The desicion made for the first star also counts for all the
|
|
186
|
+
// following stars in the delimiter run. Rembemer how many there are.
|
|
187
|
+
s->num_emphasis_delimiters_left = star_count - 1;
|
|
188
|
+
// Look ahead to the next symbol (after the last star) to find out if it
|
|
189
|
+
// is whitespace punctuation or other.
|
|
190
|
+
bool next_symbol_whitespace =
|
|
191
|
+
line_end || lexer->lookahead == ' ' || lexer->lookahead == '\t';
|
|
192
|
+
bool next_symbol_punctuation = is_punctuation(lexer->lookahead);
|
|
193
|
+
// Information about the last token is in valid_symbols. See grammar.js
|
|
194
|
+
// for these tokens for how this is done.
|
|
195
|
+
if (valid_symbols[EMPHASIS_CLOSE_STAR] &&
|
|
196
|
+
!valid_symbols[LAST_TOKEN_WHITESPACE] &&
|
|
197
|
+
(!valid_symbols[LAST_TOKEN_PUNCTUATION] ||
|
|
198
|
+
next_symbol_punctuation || next_symbol_whitespace)) {
|
|
199
|
+
// Closing delimiters take precedence
|
|
200
|
+
s->state &= ~STATE_EMPHASIS_DELIMITER_IS_OPEN;
|
|
201
|
+
lexer->result_symbol = EMPHASIS_CLOSE_STAR;
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
if (!next_symbol_whitespace && (!next_symbol_punctuation ||
|
|
205
|
+
valid_symbols[LAST_TOKEN_PUNCTUATION] ||
|
|
206
|
+
valid_symbols[LAST_TOKEN_WHITESPACE])) {
|
|
207
|
+
s->state |= STATE_EMPHASIS_DELIMITER_IS_OPEN;
|
|
208
|
+
lexer->result_symbol = EMPHASIS_OPEN_STAR;
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
static bool parse_tilde(Scanner *s, TSLexer *lexer, const bool *valid_symbols) {
|
|
216
|
+
lexer->advance(lexer, false);
|
|
217
|
+
// If `num_emphasis_delimiters_left` is not zero then we already decided
|
|
218
|
+
// that this should be part of an emphasis delimiter run, so interpret it as
|
|
219
|
+
// such.
|
|
220
|
+
if (s->num_emphasis_delimiters_left > 0) {
|
|
221
|
+
// The `STATE_EMPHASIS_DELIMITER_IS_OPEN` state flag tells us wether it
|
|
222
|
+
// should be open or close.
|
|
223
|
+
if ((s->state & STATE_EMPHASIS_DELIMITER_IS_OPEN) &&
|
|
224
|
+
valid_symbols[STRIKETHROUGH_OPEN]) {
|
|
225
|
+
s->state &= (~STATE_EMPHASIS_DELIMITER_IS_OPEN);
|
|
226
|
+
lexer->result_symbol = STRIKETHROUGH_OPEN;
|
|
227
|
+
s->num_emphasis_delimiters_left--;
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
if (valid_symbols[STRIKETHROUGH_CLOSE]) {
|
|
231
|
+
lexer->result_symbol = STRIKETHROUGH_CLOSE;
|
|
232
|
+
s->num_emphasis_delimiters_left--;
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
lexer->mark_end(lexer);
|
|
237
|
+
// Otherwise count the number of tildes
|
|
238
|
+
uint8_t star_count = 1;
|
|
239
|
+
while (lexer->lookahead == '~') {
|
|
240
|
+
star_count++;
|
|
241
|
+
lexer->advance(lexer, false);
|
|
242
|
+
}
|
|
243
|
+
bool line_end = lexer->lookahead == '\n' || lexer->lookahead == '\r' ||
|
|
244
|
+
lexer->eof(lexer);
|
|
245
|
+
if (valid_symbols[STRIKETHROUGH_OPEN] ||
|
|
246
|
+
valid_symbols[STRIKETHROUGH_CLOSE]) {
|
|
247
|
+
// The desicion made for the first star also counts for all the
|
|
248
|
+
// following stars in the delimiter run. Rembemer how many there are.
|
|
249
|
+
s->num_emphasis_delimiters_left = star_count - 1;
|
|
250
|
+
// Look ahead to the next symbol (after the last star) to find out if it
|
|
251
|
+
// is whitespace punctuation or other.
|
|
252
|
+
bool next_symbol_whitespace =
|
|
253
|
+
line_end || lexer->lookahead == ' ' || lexer->lookahead == '\t';
|
|
254
|
+
bool next_symbol_punctuation = is_punctuation(lexer->lookahead);
|
|
255
|
+
// Information about the last token is in valid_symbols. See grammar.js
|
|
256
|
+
// for these tokens for how this is done.
|
|
257
|
+
if (valid_symbols[STRIKETHROUGH_CLOSE] &&
|
|
258
|
+
!valid_symbols[LAST_TOKEN_WHITESPACE] &&
|
|
259
|
+
(!valid_symbols[LAST_TOKEN_PUNCTUATION] ||
|
|
260
|
+
next_symbol_punctuation || next_symbol_whitespace)) {
|
|
261
|
+
// Closing delimiters take precedence
|
|
262
|
+
s->state &= ~STATE_EMPHASIS_DELIMITER_IS_OPEN;
|
|
263
|
+
lexer->result_symbol = STRIKETHROUGH_CLOSE;
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
if (!next_symbol_whitespace && (!next_symbol_punctuation ||
|
|
267
|
+
valid_symbols[LAST_TOKEN_PUNCTUATION] ||
|
|
268
|
+
valid_symbols[LAST_TOKEN_WHITESPACE])) {
|
|
269
|
+
s->state |= STATE_EMPHASIS_DELIMITER_IS_OPEN;
|
|
270
|
+
lexer->result_symbol = STRIKETHROUGH_OPEN;
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
static bool parse_underscore(Scanner *s, TSLexer *lexer,
|
|
278
|
+
const bool *valid_symbols) {
|
|
279
|
+
lexer->advance(lexer, false);
|
|
280
|
+
// If `num_emphasis_delimiters_left` is not zero then we already decided
|
|
281
|
+
// that this should be part of an emphasis delimiter run, so interpret it as
|
|
282
|
+
// such.
|
|
283
|
+
if (s->num_emphasis_delimiters_left > 0) {
|
|
284
|
+
// The `STATE_EMPHASIS_DELIMITER_IS_OPEN` state flag tells us wether it
|
|
285
|
+
// should be open or close.
|
|
286
|
+
if ((s->state & STATE_EMPHASIS_DELIMITER_IS_OPEN) &&
|
|
287
|
+
valid_symbols[EMPHASIS_OPEN_UNDERSCORE]) {
|
|
288
|
+
s->state &= (~STATE_EMPHASIS_DELIMITER_IS_OPEN);
|
|
289
|
+
lexer->result_symbol = EMPHASIS_OPEN_UNDERSCORE;
|
|
290
|
+
s->num_emphasis_delimiters_left--;
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
if (valid_symbols[EMPHASIS_CLOSE_UNDERSCORE]) {
|
|
294
|
+
lexer->result_symbol = EMPHASIS_CLOSE_UNDERSCORE;
|
|
295
|
+
s->num_emphasis_delimiters_left--;
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
lexer->mark_end(lexer);
|
|
300
|
+
// Otherwise count the number of stars
|
|
301
|
+
uint8_t underscore_count = 1;
|
|
302
|
+
while (lexer->lookahead == '_') {
|
|
303
|
+
underscore_count++;
|
|
304
|
+
lexer->advance(lexer, false);
|
|
305
|
+
}
|
|
306
|
+
bool line_end = lexer->lookahead == '\n' || lexer->lookahead == '\r' ||
|
|
307
|
+
lexer->eof(lexer);
|
|
308
|
+
if (valid_symbols[EMPHASIS_OPEN_UNDERSCORE] ||
|
|
309
|
+
valid_symbols[EMPHASIS_CLOSE_UNDERSCORE]) {
|
|
310
|
+
// The desicion made for the first underscore also counts for all the
|
|
311
|
+
// following underscores in the delimiter run. Rembemer how many there are.
|
|
312
|
+
s->num_emphasis_delimiters_left = underscore_count - 1;
|
|
313
|
+
// Look ahead to the next symbol (after the last underscore) to find out if it
|
|
314
|
+
// is whitespace punctuation or other.
|
|
315
|
+
bool next_symbol_whitespace =
|
|
316
|
+
line_end || lexer->lookahead == ' ' || lexer->lookahead == '\t';
|
|
317
|
+
bool next_symbol_punctuation = is_punctuation(lexer->lookahead);
|
|
318
|
+
// Information about the last token is in valid_symbols. See grammar.js
|
|
319
|
+
// for these tokens for how this is done.
|
|
320
|
+
if (valid_symbols[EMPHASIS_CLOSE_UNDERSCORE] &&
|
|
321
|
+
!valid_symbols[LAST_TOKEN_WHITESPACE] &&
|
|
322
|
+
(!valid_symbols[LAST_TOKEN_PUNCTUATION] ||
|
|
323
|
+
next_symbol_punctuation || next_symbol_whitespace)) {
|
|
324
|
+
// Closing delimiters take precedence
|
|
325
|
+
s->state &= ~STATE_EMPHASIS_DELIMITER_IS_OPEN;
|
|
326
|
+
lexer->result_symbol = EMPHASIS_CLOSE_UNDERSCORE;
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
if (!next_symbol_whitespace && (!next_symbol_punctuation ||
|
|
330
|
+
valid_symbols[LAST_TOKEN_PUNCTUATION] ||
|
|
331
|
+
valid_symbols[LAST_TOKEN_WHITESPACE])) {
|
|
332
|
+
s->state |= STATE_EMPHASIS_DELIMITER_IS_OPEN;
|
|
333
|
+
lexer->result_symbol = EMPHASIS_OPEN_UNDERSCORE;
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
static bool scan(Scanner *s, TSLexer *lexer, const bool *valid_symbols) {
|
|
341
|
+
// A normal tree-sitter rule decided that the current branch is invalid and
|
|
342
|
+
// now "requests" an error to stop the branch
|
|
343
|
+
if (valid_symbols[TRIGGER_ERROR]) {
|
|
344
|
+
return error(lexer);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Decide which tokens to consider based on the first non-whitespace
|
|
348
|
+
// character
|
|
349
|
+
switch (lexer->lookahead) {
|
|
350
|
+
case '`':
|
|
351
|
+
// A backtick could mark the beginning or ending of a code span or a
|
|
352
|
+
// fenced code block.
|
|
353
|
+
return parse_backtick(s, lexer, valid_symbols);
|
|
354
|
+
case '$':
|
|
355
|
+
return parse_dollar(s, lexer, valid_symbols);
|
|
356
|
+
case '*':
|
|
357
|
+
// A star could either mark the beginning or ending of emphasis, a
|
|
358
|
+
// list item or thematic break. This code is similar to the code for
|
|
359
|
+
// '_' and '+'.
|
|
360
|
+
return parse_star(s, lexer, valid_symbols);
|
|
361
|
+
case '_':
|
|
362
|
+
return parse_underscore(s, lexer, valid_symbols);
|
|
363
|
+
case '~':
|
|
364
|
+
return parse_tilde(s, lexer, valid_symbols);
|
|
365
|
+
}
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
void *tree_sitter_markdown_inline_external_scanner_create() {
|
|
370
|
+
Scanner *s = (Scanner *)malloc(sizeof(Scanner));
|
|
371
|
+
deserialize(s, NULL, 0);
|
|
372
|
+
return s;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
bool tree_sitter_markdown_inline_external_scanner_scan(
|
|
376
|
+
void *payload, TSLexer *lexer, const bool *valid_symbols) {
|
|
377
|
+
Scanner *scanner = (Scanner *)payload;
|
|
378
|
+
return scan(scanner, lexer, valid_symbols);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
unsigned tree_sitter_markdown_inline_external_scanner_serialize(void *payload,
|
|
382
|
+
char *buffer) {
|
|
383
|
+
Scanner *scanner = (Scanner *)payload;
|
|
384
|
+
return serialize(scanner, buffer);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
void tree_sitter_markdown_inline_external_scanner_deserialize(void *payload,
|
|
388
|
+
const char *buffer,
|
|
389
|
+
unsigned length) {
|
|
390
|
+
Scanner *scanner = (Scanner *)payload;
|
|
391
|
+
deserialize(scanner, buffer, length);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
void tree_sitter_markdown_inline_external_scanner_destroy(void *payload) {
|
|
395
|
+
Scanner *scanner = (Scanner *)payload;
|
|
396
|
+
free(scanner);
|
|
397
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#ifndef TREE_SITTER_ALLOC_H_
|
|
2
|
+
#define TREE_SITTER_ALLOC_H_
|
|
3
|
+
|
|
4
|
+
#ifdef __cplusplus
|
|
5
|
+
extern "C" {
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
#include <stdbool.h>
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <stdlib.h>
|
|
11
|
+
|
|
12
|
+
// Allow clients to override allocation functions
|
|
13
|
+
#ifdef TREE_SITTER_REUSE_ALLOCATOR
|
|
14
|
+
|
|
15
|
+
extern void *(*ts_current_malloc)(size_t size);
|
|
16
|
+
extern void *(*ts_current_calloc)(size_t count, size_t size);
|
|
17
|
+
extern void *(*ts_current_realloc)(void *ptr, size_t size);
|
|
18
|
+
extern void (*ts_current_free)(void *ptr);
|
|
19
|
+
|
|
20
|
+
#ifndef ts_malloc
|
|
21
|
+
#define ts_malloc ts_current_malloc
|
|
22
|
+
#endif
|
|
23
|
+
#ifndef ts_calloc
|
|
24
|
+
#define ts_calloc ts_current_calloc
|
|
25
|
+
#endif
|
|
26
|
+
#ifndef ts_realloc
|
|
27
|
+
#define ts_realloc ts_current_realloc
|
|
28
|
+
#endif
|
|
29
|
+
#ifndef ts_free
|
|
30
|
+
#define ts_free ts_current_free
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
#else
|
|
34
|
+
|
|
35
|
+
#ifndef ts_malloc
|
|
36
|
+
#define ts_malloc malloc
|
|
37
|
+
#endif
|
|
38
|
+
#ifndef ts_calloc
|
|
39
|
+
#define ts_calloc calloc
|
|
40
|
+
#endif
|
|
41
|
+
#ifndef ts_realloc
|
|
42
|
+
#define ts_realloc realloc
|
|
43
|
+
#endif
|
|
44
|
+
#ifndef ts_free
|
|
45
|
+
#define ts_free free
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
#endif
|
|
49
|
+
|
|
50
|
+
#ifdef __cplusplus
|
|
51
|
+
}
|
|
52
|
+
#endif
|
|
53
|
+
|
|
54
|
+
#endif // TREE_SITTER_ALLOC_H_
|