apex-ruby 1.0.43 → 1.0.45
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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 55f46b5882430ec3db488a30a91c1e026cb10af55a44e05765be695542268584
|
|
4
|
+
data.tar.gz: 5234aea6b39f08fb6398b49f6beb6e91c3c8e6d5c701cbf4d6ade0a58dffc61c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2feca8bc1497bf459cdbf2b772dc8657df94a2930f601038803fcff68da31a416378aa02ea5f04fac869acbcb466f8b32b8fc090ed1757612c2fa4f4c5862098
|
|
7
|
+
data.tar.gz: 1d81a7a77ec9e915a7203ba100a94c539d1008435dec05308f6a62e5064b5ad4e779f96d451d5325146e9f15002693a825e745908ff3cb0cf710a8e6dd3e8cea
|
|
@@ -21,8 +21,8 @@ typedef struct cmark_node cmark_node;
|
|
|
21
21
|
|
|
22
22
|
#define APEX_VERSION_MAJOR 1
|
|
23
23
|
#define APEX_VERSION_MINOR 1
|
|
24
|
-
#define APEX_VERSION_PATCH
|
|
25
|
-
#define APEX_VERSION_STRING "1.1.
|
|
24
|
+
#define APEX_VERSION_PATCH 51
|
|
25
|
+
#define APEX_VERSION_STRING "1.1.51"
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Processor compatibility modes
|
|
@@ -9,6 +9,58 @@
|
|
|
9
9
|
#include <stdbool.h>
|
|
10
10
|
#include <ctype.h>
|
|
11
11
|
|
|
12
|
+
/* Just past the closing ')' of a markdown link or image destination.
|
|
13
|
+
* Quotes hide parentheses. A newline means the destination is unclosed. */
|
|
14
|
+
static const char *markdown_destination_end(const char *after_open_paren) {
|
|
15
|
+
int depth = 1;
|
|
16
|
+
bool in_quote = false;
|
|
17
|
+
char quote = 0;
|
|
18
|
+
const char *p = after_open_paren;
|
|
19
|
+
|
|
20
|
+
if (!p) return NULL;
|
|
21
|
+
while (*p && *p != '\n' && *p != '\r') {
|
|
22
|
+
if (in_quote) {
|
|
23
|
+
if (*p == '\\' && p[1]) {
|
|
24
|
+
p += 2;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (*p == quote) in_quote = false;
|
|
28
|
+
p++;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (*p == '"' || *p == '\'') {
|
|
32
|
+
in_quote = true;
|
|
33
|
+
quote = *p++;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (*p == '(') {
|
|
37
|
+
depth++;
|
|
38
|
+
} else if (*p == ')') {
|
|
39
|
+
depth--;
|
|
40
|
+
if (depth == 0) return p + 1;
|
|
41
|
+
}
|
|
42
|
+
p++;
|
|
43
|
+
}
|
|
44
|
+
return NULL;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static bool append_verbatim(char **output, char **write, size_t *remaining,
|
|
48
|
+
size_t *capacity, const char *src, size_t len) {
|
|
49
|
+
if (len >= *remaining) {
|
|
50
|
+
size_t written = (size_t)(*write - *output);
|
|
51
|
+
*capacity = (written + len + 1) * 2;
|
|
52
|
+
char *grown = realloc(*output, *capacity);
|
|
53
|
+
if (!grown) return false;
|
|
54
|
+
*output = grown;
|
|
55
|
+
*write = grown + written;
|
|
56
|
+
*remaining = *capacity - written;
|
|
57
|
+
}
|
|
58
|
+
memcpy(*write, src, len);
|
|
59
|
+
*write += len;
|
|
60
|
+
*remaining -= len;
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
12
64
|
/** True if content at p looks like a list marker (- , * , + , or digit+. ) */
|
|
13
65
|
static bool looks_like_list_marker(const char *p) {
|
|
14
66
|
if (*p == '-' || *p == '*' || *p == '+')
|
|
@@ -60,6 +112,22 @@ char *apex_process_highlights(const char *text) {
|
|
|
60
112
|
in_indented_code_block = line_is_indented_code_block(read);
|
|
61
113
|
}
|
|
62
114
|
|
|
115
|
+
/* Copy markdown link/image destinations verbatim. Base64 padding
|
|
116
|
+
* is ==, which is not a highlight. */
|
|
117
|
+
if (!in_code_block && !in_inline_code && !in_indented_code_block &&
|
|
118
|
+
*read == ']' && read[1] == '(') {
|
|
119
|
+
const char *dest_end = markdown_destination_end(read + 2);
|
|
120
|
+
if (dest_end) {
|
|
121
|
+
size_t dest_len = (size_t)(dest_end - read);
|
|
122
|
+
if (!append_verbatim(&output, &write, &remaining, &capacity, read, dest_len)) {
|
|
123
|
+
free(output);
|
|
124
|
+
return NULL;
|
|
125
|
+
}
|
|
126
|
+
read = dest_end;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
63
131
|
/* Track fenced and inline code (skip highlighting inside them) */
|
|
64
132
|
if (*read == '`') {
|
|
65
133
|
if (read[1] == '`' && read[2] == '`') {
|
|
@@ -40,6 +40,58 @@ static const char *find_ial_after(const char *text, const char **ial_end) {
|
|
|
40
40
|
return NULL;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/* Just past the closing ')' of a markdown link or image destination.
|
|
44
|
+
* Quotes hide parentheses. A newline means the destination is unclosed. */
|
|
45
|
+
static const char *markdown_destination_end(const char *after_open_paren) {
|
|
46
|
+
int depth = 1;
|
|
47
|
+
bool in_quote = false;
|
|
48
|
+
char quote = 0;
|
|
49
|
+
const char *p = after_open_paren;
|
|
50
|
+
|
|
51
|
+
if (!p) return NULL;
|
|
52
|
+
while (*p && *p != '\n' && *p != '\r') {
|
|
53
|
+
if (in_quote) {
|
|
54
|
+
if (*p == '\\' && p[1]) {
|
|
55
|
+
p += 2;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (*p == quote) in_quote = false;
|
|
59
|
+
p++;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (*p == '"' || *p == '\'') {
|
|
63
|
+
in_quote = true;
|
|
64
|
+
quote = *p++;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (*p == '(') {
|
|
68
|
+
depth++;
|
|
69
|
+
} else if (*p == ')') {
|
|
70
|
+
depth--;
|
|
71
|
+
if (depth == 0) return p + 1;
|
|
72
|
+
}
|
|
73
|
+
p++;
|
|
74
|
+
}
|
|
75
|
+
return NULL;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static bool append_verbatim(char **output, char **write, size_t *remaining,
|
|
79
|
+
size_t *capacity, const char *src, size_t len) {
|
|
80
|
+
if (len >= *remaining) {
|
|
81
|
+
size_t written = (size_t)(*write - *output);
|
|
82
|
+
*capacity = (written + len + 1) * 2;
|
|
83
|
+
char *grown = realloc(*output, *capacity);
|
|
84
|
+
if (!grown) return false;
|
|
85
|
+
*output = grown;
|
|
86
|
+
*write = grown + written;
|
|
87
|
+
*remaining = *capacity - written;
|
|
88
|
+
}
|
|
89
|
+
memcpy(*write, src, len);
|
|
90
|
+
*write += len;
|
|
91
|
+
*remaining -= len;
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
43
95
|
/**
|
|
44
96
|
* If text starts an HTML tag (<name or </name), return a pointer just past its
|
|
45
97
|
* closing '>' (quote-aware), or NULL. Gives up at a blank line outside quotes
|
|
@@ -87,6 +139,19 @@ char *apex_process_inserts(const char *text) {
|
|
|
87
139
|
bool in_inline_code = false;
|
|
88
140
|
|
|
89
141
|
while (*read) {
|
|
142
|
+
/* Copy markdown link/image destinations verbatim. A data URI's
|
|
143
|
+
* base64 contains ++, which is not an insert. */
|
|
144
|
+
if (!in_code_block && !in_inline_code && *read == ']' && read[1] == '(') {
|
|
145
|
+
const char *dest_end = markdown_destination_end(read + 2);
|
|
146
|
+
if (dest_end) {
|
|
147
|
+
size_t dest_len = (size_t)(dest_end - read);
|
|
148
|
+
if (!append_verbatim(&output, &write, &remaining, &capacity, read, dest_len))
|
|
149
|
+
goto cleanup;
|
|
150
|
+
read = dest_end;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
90
155
|
/* Copy HTML tags verbatim so ++ inside attribute values (e.g. base64
|
|
91
156
|
* data: URIs) is not converted */
|
|
92
157
|
if (!in_code_block && !in_inline_code && *read == '<') {
|
|
@@ -81,6 +81,31 @@ static int scan_dollar_math(const char *input, int len, bool *is_display) {
|
|
|
81
81
|
return 0;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* True when display-math content has a letter, digit, or operator.
|
|
86
|
+
* Emphasis stars, commas, and spaces do not qualify on their own, so
|
|
87
|
+
* **\[**, **\]** stays escaped brackets instead of an equation.
|
|
88
|
+
*/
|
|
89
|
+
static bool display_math_content(const char *s, int len) {
|
|
90
|
+
for (int i = 0; i < len; i++) {
|
|
91
|
+
unsigned char c = (unsigned char)s[i];
|
|
92
|
+
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
|
93
|
+
(c >= '0' && c <= '9') || c >= 128) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
switch (c) {
|
|
97
|
+
case '+': case '-': case '/': case '=':
|
|
98
|
+
case '^': case '_': case '\\': case '.':
|
|
99
|
+
case '<': case '>': case '|': case '~':
|
|
100
|
+
case '{': case '}':
|
|
101
|
+
return true;
|
|
102
|
+
default:
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
84
109
|
/**
|
|
85
110
|
* Scan for \(...\) or \[...\] LaTeX-style math
|
|
86
111
|
* Returns length if found, 0 otherwise
|
|
@@ -94,6 +119,9 @@ static int scan_latex_math(const char *input, int len, bool *is_display) {
|
|
|
94
119
|
/* Find closing \] */
|
|
95
120
|
for (int i = 2; i < len - 1; i++) {
|
|
96
121
|
if (input[i] == '\\' && input[i + 1] == ']') {
|
|
122
|
+
if (!display_math_content(input + 2, i - 2)) {
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
97
125
|
return i + 2;
|
|
98
126
|
}
|
|
99
127
|
}
|
data/lib/apex/version.rb
CHANGED