Fossil SCM

Make parsing slightly faster and fix a comment. No changes in functionality.

george 2022-02-16 23:08 markdown-footnotes
Commit a36dd09d17f3057f077c46be9c4b1a9f26e0f053bb640698eab474cd3c9599f9
1 file changed +88 -92
+88 -92
--- src/markdown.c
+++ src/markdown.c
@@ -1168,20 +1168,19 @@
11681168
static size_t char_link(
11691169
struct Blob *ob,
11701170
struct render *rndr,
11711171
char *data,
11721172
size_t offset,
1173
- size_t size
1173
+ size_t size /* parse_inline() ensures that size > 0 */
11741174
){
11751175
const int is_img = (offset && data[-1] == '!');
11761176
size_t i = 1, txt_e;
11771177
struct Blob *content = 0;
11781178
struct Blob *link = 0;
11791179
struct Blob *title = 0;
11801180
const struct footnote *fn = 0;
11811181
int ret;
1182
- /* ? FIXME: assert( size>0 ); */
11831182
11841183
/* checking whether the correct renderer exists */
11851184
if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
11861185
return 0;
11871186
}
@@ -1188,104 +1187,101 @@
11881187
11891188
/* looking for the matching closing bracket */
11901189
txt_e = matching_bracket_offset(data, data+size);
11911190
if( !txt_e ) return 0;
11921191
i = txt_e + 1;
1193
-
1194
- /* skip any amount of whitespace or newline */
1195
- /* (this is much more laxist than original markdown syntax) */
1196
- while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1197
-
1198
- /* allocate temporary buffers to store content, link and title */
1199
- title = new_work_buffer(rndr);
1200
- content = new_work_buffer(rndr);
1201
- link = new_work_buffer(rndr);
12021192
ret = 0; /* error if we don't get to the callback */
12031193
12041194
/* free-standing footnote refernece */
12051195
if(!is_img && size>3 && data[1]=='^'){
1206
- /* free-standing footnote reference */
1207
- fn = get_footnote(rndr, data+2, txt_e-2);
1208
- if( !fn ) {
1209
- rndr->notes.misref.nUsed++;
1210
- fn = &rndr->notes.misref;
1211
- }
1212
- release_work_buffer(rndr, content);
1213
- content = 0;
1214
- i = txt_e+1; /* rewinding a closing square bracket */
1215
-
1216
- }else if( i<size && data[i]=='(' ){
1217
-
1218
- if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
1219
-
1220
- const size_t k = matching_bracket_offset(data+i, data+size);
1221
- if( !k ) goto char_link_cleanup;
1222
- fn = add_inline_footnote(rndr, data+(i+2), k-2);
1223
- i += k+1;
1224
- }else{ /* inline style link */
1225
- size_t span_end = i;
1226
- while( span_end<size
1227
- && !(data[span_end]==')' && (span_end==i || data[span_end-1]!='\\'))
1228
- ){
1229
- span_end++;
1230
- }
1231
-
1232
- if( span_end>=size
1233
- || get_link_inline(link, title, data+i+1, span_end-(i+1))<0
1234
- ){
1235
- goto char_link_cleanup;
1236
- }
1237
-
1238
- i = span_end+1;
1239
- }
1240
-
1241
- /* reference style link or span-bounded footnote reference */
1242
- }else if( i<size && data[i]=='[' ){
1243
- char *id_data;
1244
- size_t id_size, id_end = i;
1245
- int bFootnote;
1246
-
1247
- while( id_end<size && data[id_end]!=']' ){ id_end++; }
1248
-
1249
- if( id_end>=size ) goto char_link_cleanup;
1250
- bFootnote = data[i+1]=='^';
1251
-
1252
- if( i+1==id_end || (bFootnote && i+2==id_end) ){
1253
- /* implicit id - use the contents */
1254
- id_data = data+1;
1255
- id_size = txt_e-1;
1256
- }else{
1257
- /* explicit id - between brackets */
1258
- id_data = data+i+1;
1259
- id_size = id_end-(i+1);
1260
- if( bFootnote ){
1261
- id_data++;
1262
- id_size--;
1263
- }
1264
- }
1265
-
1266
- if( bFootnote ){
1267
- fn = get_footnote(rndr, id_data, id_size);
1268
- if( !fn ) {
1269
- rndr->notes.misref.nUsed++;
1270
- fn = &rndr->notes.misref;
1271
- }
1272
- }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1273
- goto char_link_cleanup;
1274
- }
1275
-
1276
- i = id_end+1;
1277
-
1278
- /* shortcut reference style link */
1279
- }else{
1280
- if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1281
- goto char_link_cleanup;
1282
- }
1283
- /* rewinding a closing square bracket */
1284
- i = txt_e+1;
1285
- }
1286
-
1196
+ fn = get_footnote(rndr, data+2, txt_e-2);
1197
+ if( !fn ) {
1198
+ rndr->notes.misref.nUsed++;
1199
+ fn = &rndr->notes.misref;
1200
+ }
1201
+ }else{
1202
+
1203
+ /* skip "inter-bracket-whitespace" - any amount of whitespace or newline */
1204
+ /* (this is much more laxist than original markdown syntax) */
1205
+ while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1206
+
1207
+ /* allocate temporary buffers to store content, link and title */
1208
+ title = new_work_buffer(rndr);
1209
+ content = new_work_buffer(rndr);
1210
+ link = new_work_buffer(rndr);
1211
+
1212
+ if( i<size && data[i]=='(' ){
1213
+
1214
+ if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
1215
+
1216
+ const size_t k = matching_bracket_offset(data+i, data+size);
1217
+ if( !k ) goto char_link_cleanup;
1218
+ fn = add_inline_footnote(rndr, data+(i+2), k-2);
1219
+ i += k+1;
1220
+ }else{ /* inline style link */
1221
+ size_t span_end = i;
1222
+ while( span_end<size
1223
+ && !(data[span_end]==')' && (span_end==i || data[span_end-1]!='\\'))
1224
+ ){
1225
+ span_end++;
1226
+ }
1227
+
1228
+ if( span_end>=size
1229
+ || get_link_inline(link, title, data+i+1, span_end-(i+1))<0
1230
+ ){
1231
+ goto char_link_cleanup;
1232
+ }
1233
+
1234
+ i = span_end+1;
1235
+ }
1236
+
1237
+ /* reference style link or span-bounded footnote reference */
1238
+ }else if( i<size && data[i]=='[' ){
1239
+ char *id_data;
1240
+ size_t id_size, id_end = i;
1241
+ int bFootnote;
1242
+
1243
+ while( id_end<size && data[id_end]!=']' ){ id_end++; }
1244
+
1245
+ if( id_end>=size ) goto char_link_cleanup;
1246
+ bFootnote = data[i+1]=='^';
1247
+
1248
+ if( i+1==id_end || (bFootnote && i+2==id_end) ){
1249
+ /* implicit id - use the contents */
1250
+ id_data = data+1;
1251
+ id_size = txt_e-1;
1252
+ }else{
1253
+ /* explicit id - between brackets */
1254
+ id_data = data+i+1;
1255
+ id_size = id_end-(i+1);
1256
+ if( bFootnote ){
1257
+ id_data++;
1258
+ id_size--;
1259
+ }
1260
+ }
1261
+
1262
+ if( bFootnote ){
1263
+ fn = get_footnote(rndr, id_data, id_size);
1264
+ if( !fn ) {
1265
+ rndr->notes.misref.nUsed++;
1266
+ fn = &rndr->notes.misref;
1267
+ }
1268
+ }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1269
+ goto char_link_cleanup;
1270
+ }
1271
+
1272
+ i = id_end+1;
1273
+
1274
+ /* shortcut reference style link */
1275
+ }else{
1276
+ if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1277
+ goto char_link_cleanup;
1278
+ }
1279
+ /* rewinding an "inter-bracket-whitespace" */
1280
+ i = txt_e+1;
1281
+ }
1282
+ }
12871283
/* building content: img alt is escaped, link content is parsed */
12881284
if( txt_e>1 && content ){
12891285
if( is_img ) blob_append(content, data+1, txt_e-1);
12901286
else parse_inline(content, rndr, data+1, txt_e-1);
12911287
}
12921288
--- src/markdown.c
+++ src/markdown.c
@@ -1168,20 +1168,19 @@
1168 static size_t char_link(
1169 struct Blob *ob,
1170 struct render *rndr,
1171 char *data,
1172 size_t offset,
1173 size_t size
1174 ){
1175 const int is_img = (offset && data[-1] == '!');
1176 size_t i = 1, txt_e;
1177 struct Blob *content = 0;
1178 struct Blob *link = 0;
1179 struct Blob *title = 0;
1180 const struct footnote *fn = 0;
1181 int ret;
1182 /* ? FIXME: assert( size>0 ); */
1183
1184 /* checking whether the correct renderer exists */
1185 if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
1186 return 0;
1187 }
@@ -1188,104 +1187,101 @@
1188
1189 /* looking for the matching closing bracket */
1190 txt_e = matching_bracket_offset(data, data+size);
1191 if( !txt_e ) return 0;
1192 i = txt_e + 1;
1193
1194 /* skip any amount of whitespace or newline */
1195 /* (this is much more laxist than original markdown syntax) */
1196 while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1197
1198 /* allocate temporary buffers to store content, link and title */
1199 title = new_work_buffer(rndr);
1200 content = new_work_buffer(rndr);
1201 link = new_work_buffer(rndr);
1202 ret = 0; /* error if we don't get to the callback */
1203
1204 /* free-standing footnote refernece */
1205 if(!is_img && size>3 && data[1]=='^'){
1206 /* free-standing footnote reference */
1207 fn = get_footnote(rndr, data+2, txt_e-2);
1208 if( !fn ) {
1209 rndr->notes.misref.nUsed++;
1210 fn = &rndr->notes.misref;
1211 }
1212 release_work_buffer(rndr, content);
1213 content = 0;
1214 i = txt_e+1; /* rewinding a closing square bracket */
1215
1216 }else if( i<size && data[i]=='(' ){
1217
1218 if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
1219
1220 const size_t k = matching_bracket_offset(data+i, data+size);
1221 if( !k ) goto char_link_cleanup;
1222 fn = add_inline_footnote(rndr, data+(i+2), k-2);
1223 i += k+1;
1224 }else{ /* inline style link */
1225 size_t span_end = i;
1226 while( span_end<size
1227 && !(data[span_end]==')' && (span_end==i || data[span_end-1]!='\\'))
1228 ){
1229 span_end++;
1230 }
1231
1232 if( span_end>=size
1233 || get_link_inline(link, title, data+i+1, span_end-(i+1))<0
1234 ){
1235 goto char_link_cleanup;
1236 }
1237
1238 i = span_end+1;
1239 }
1240
1241 /* reference style link or span-bounded footnote reference */
1242 }else if( i<size && data[i]=='[' ){
1243 char *id_data;
1244 size_t id_size, id_end = i;
1245 int bFootnote;
1246
1247 while( id_end<size && data[id_end]!=']' ){ id_end++; }
1248
1249 if( id_end>=size ) goto char_link_cleanup;
1250 bFootnote = data[i+1]=='^';
1251
1252 if( i+1==id_end || (bFootnote && i+2==id_end) ){
1253 /* implicit id - use the contents */
1254 id_data = data+1;
1255 id_size = txt_e-1;
1256 }else{
1257 /* explicit id - between brackets */
1258 id_data = data+i+1;
1259 id_size = id_end-(i+1);
1260 if( bFootnote ){
1261 id_data++;
1262 id_size--;
1263 }
1264 }
1265
1266 if( bFootnote ){
1267 fn = get_footnote(rndr, id_data, id_size);
1268 if( !fn ) {
1269 rndr->notes.misref.nUsed++;
1270 fn = &rndr->notes.misref;
1271 }
1272 }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1273 goto char_link_cleanup;
1274 }
1275
1276 i = id_end+1;
1277
1278 /* shortcut reference style link */
1279 }else{
1280 if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1281 goto char_link_cleanup;
1282 }
1283 /* rewinding a closing square bracket */
1284 i = txt_e+1;
1285 }
1286
 
 
 
 
 
 
1287 /* building content: img alt is escaped, link content is parsed */
1288 if( txt_e>1 && content ){
1289 if( is_img ) blob_append(content, data+1, txt_e-1);
1290 else parse_inline(content, rndr, data+1, txt_e-1);
1291 }
1292
--- src/markdown.c
+++ src/markdown.c
@@ -1168,20 +1168,19 @@
1168 static size_t char_link(
1169 struct Blob *ob,
1170 struct render *rndr,
1171 char *data,
1172 size_t offset,
1173 size_t size /* parse_inline() ensures that size > 0 */
1174 ){
1175 const int is_img = (offset && data[-1] == '!');
1176 size_t i = 1, txt_e;
1177 struct Blob *content = 0;
1178 struct Blob *link = 0;
1179 struct Blob *title = 0;
1180 const struct footnote *fn = 0;
1181 int ret;
 
1182
1183 /* checking whether the correct renderer exists */
1184 if( (is_img && !rndr->make.image) || (!is_img && !rndr->make.link) ){
1185 return 0;
1186 }
@@ -1188,104 +1187,101 @@
1187
1188 /* looking for the matching closing bracket */
1189 txt_e = matching_bracket_offset(data, data+size);
1190 if( !txt_e ) return 0;
1191 i = txt_e + 1;
 
 
 
 
 
 
 
 
 
1192 ret = 0; /* error if we don't get to the callback */
1193
1194 /* free-standing footnote refernece */
1195 if(!is_img && size>3 && data[1]=='^'){
1196 fn = get_footnote(rndr, data+2, txt_e-2);
1197 if( !fn ) {
1198 rndr->notes.misref.nUsed++;
1199 fn = &rndr->notes.misref;
1200 }
1201 }else{
1202
1203 /* skip "inter-bracket-whitespace" - any amount of whitespace or newline */
1204 /* (this is much more laxist than original markdown syntax) */
1205 while( i<size && (data[i]==' ' || data[i]=='\t' || data[i]=='\n') ){ i++; }
1206
1207 /* allocate temporary buffers to store content, link and title */
1208 title = new_work_buffer(rndr);
1209 content = new_work_buffer(rndr);
1210 link = new_work_buffer(rndr);
1211
1212 if( i<size && data[i]=='(' ){
1213
1214 if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
1215
1216 const size_t k = matching_bracket_offset(data+i, data+size);
1217 if( !k ) goto char_link_cleanup;
1218 fn = add_inline_footnote(rndr, data+(i+2), k-2);
1219 i += k+1;
1220 }else{ /* inline style link */
1221 size_t span_end = i;
1222 while( span_end<size
1223 && !(data[span_end]==')' && (span_end==i || data[span_end-1]!='\\'))
1224 ){
1225 span_end++;
1226 }
1227
1228 if( span_end>=size
1229 || get_link_inline(link, title, data+i+1, span_end-(i+1))<0
1230 ){
1231 goto char_link_cleanup;
1232 }
1233
1234 i = span_end+1;
1235 }
1236
1237 /* reference style link or span-bounded footnote reference */
1238 }else if( i<size && data[i]=='[' ){
1239 char *id_data;
1240 size_t id_size, id_end = i;
1241 int bFootnote;
1242
1243 while( id_end<size && data[id_end]!=']' ){ id_end++; }
1244
1245 if( id_end>=size ) goto char_link_cleanup;
1246 bFootnote = data[i+1]=='^';
1247
1248 if( i+1==id_end || (bFootnote && i+2==id_end) ){
1249 /* implicit id - use the contents */
1250 id_data = data+1;
1251 id_size = txt_e-1;
1252 }else{
1253 /* explicit id - between brackets */
1254 id_data = data+i+1;
1255 id_size = id_end-(i+1);
1256 if( bFootnote ){
1257 id_data++;
1258 id_size--;
1259 }
1260 }
1261
1262 if( bFootnote ){
1263 fn = get_footnote(rndr, id_data, id_size);
1264 if( !fn ) {
1265 rndr->notes.misref.nUsed++;
1266 fn = &rndr->notes.misref;
1267 }
1268 }else if( get_link_ref(rndr, link, title, id_data, id_size)<0 ){
1269 goto char_link_cleanup;
1270 }
1271
1272 i = id_end+1;
1273
1274 /* shortcut reference style link */
1275 }else{
1276 if( get_link_ref(rndr, link, title, data+1, txt_e-1)<0 ){
1277 goto char_link_cleanup;
1278 }
1279 /* rewinding an "inter-bracket-whitespace" */
1280 i = txt_e+1;
1281 }
1282 }
1283 /* building content: img alt is escaped, link content is parsed */
1284 if( txt_e>1 && content ){
1285 if( is_img ) blob_append(content, data+1, txt_e-1);
1286 else parse_inline(content, rndr, data+1, txt_e-1);
1287 }
1288

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button