| ︙ | | |
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
-
+
+
|
struct Blob refs;
char_trigger active_char[256];
int iDepth; /* Depth of recursion */
int nBlobCache; /* Number of entries in aBlobCache */
struct Blob *aBlobCache[20]; /* Cache of Blobs available for reuse */
struct {
Blob all; /* array of footnotes */
Blob all; /* Buffer that holds array of footnotes. Its underline
memory may be reallocated when a new footnote is added. */
int nLbled; /* number of labeled footnotes found during the first pass */
int nMarks; /* counts distinct indices found during the second pass */
struct footnote misref; /* nUsed counts misreferences, iMark must be -1 */
} notes;
};
/* html_tag -- structure for quick HTML tag search (inspired from discount) */
|
| ︙ | | |
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
|
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
|
-
+
|
|| data[link_e-1]=='\n')
){
link_e--;
}
/* remove optional angle brackets around the link */
if( data[link_b]=='<' ) link_b += 1;
if( data[link_e-1]=='>' ) link_e -= 1; /* TODO: handle link_e == 0 */
if( link_e && data[link_e-1]=='>' ) link_e -= 1;
/* escape backslashed character from link */
blob_reset(link);
i = link_b;
while( i<link_e ){
mark = i;
while( i<link_e && data[i]!='\\' ){ i++; }
|
| ︙ | | |
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
|
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
|
-
-
-
+
+
+
-
-
+
-
+
+
-
+
|
}
if( *p!='.' ) break;
}
return 0;
}
/*
** Adds unlabeled footnote to the rndr. If text is blank then returns
** 0, otherwise returns the address of the added footnote, which lives
** in rndr->notes, noting that the pointer may be invalidated via
** Adds unlabeled footnote to the rndr->notes.all.
** On success puts a shallow copy of the constructed footnote into pFN
** and returns 1, otherwise pFN is unchanged and 0 is returned.
** reallocation the next time a footnote is added to that member.
*/
static inline const struct footnote* add_inline_footnote(
static inline int add_inline_footnote(
struct render *rndr,
const char *text,
size_t size
size_t size,
struct footnote* pFN
){
struct footnote fn = FOOTNOTE_INITIALIZER;
struct footnote fn = FOOTNOTE_INITIALIZER, *last;
const char *zUPC = 0;
size_t nUPC = 0, n = sizeof_blank_prefix(text, size, 3);
if( n >= size ) return 0;
text += n;
size -= n;
nUPC = is_footnote_classlist(text, size, 1);
if( nUPC ){
|
| ︙ | | |
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
|
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
|
-
+
+
+
+
|
fn.iMark = ++(rndr->notes.nMarks);
fn.nUsed = 1;
fn.index = COUNT_FOOTNOTES(&rndr->notes.all);
assert( fn.iMark > 0 );
blob_append(&fn.text, text, size);
if(nUPC) blob_append(&fn.upc, zUPC, nUPC);
blob_append(&rndr->notes.all, (char *)&fn, sizeof fn);
return (struct footnote*)( blob_buffer(&rndr->notes.all)
last = (struct footnote*)( blob_buffer(&rndr->notes.all)
+( blob_size(&rndr->notes.all)-sizeof fn ));
assert( pFN );
memcpy( pFN, last, sizeof fn );
return 1;
}
/*
** Return the byte offset of the matching closing bracket or 0 if not
** found. begin[0] must be either '[' or '('.
**
** TODO: It seems that things like "\\(" are not handled correctly.
|
| ︙ | | |
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
|
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
|
-
+
-
+
-
-
+
|
struct Blob *ob,
struct render *rndr,
char *data,
size_t offset,
size_t size
){
size_t end;
const struct footnote* fn;
struct footnote fn;
if( size<4 || data[1]!='^' ) return 0;
end = matching_bracket_offset(data, data+size);
if( !end ) return 0;
fn = add_inline_footnote(rndr, data+2, end-2);
if( !add_inline_footnote(rndr, data+2, end-2, &fn) ) return 0;
if( !fn ) return 0;
if( rndr->make.footnote_ref ){
rndr->make.footnote_ref(ob,0,&fn->upc,fn->iMark,1,rndr->make.opaque);
rndr->make.footnote_ref(ob,0,&fn.upc,fn.iMark,1,rndr->make.opaque);
}
return end+1;
}
/*
** char_link -- '[': parsing a link or an image.
*/
|
| ︙ | | |
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
|
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
|
-
-
+
-
|
link = new_work_buffer(rndr);
if( i<size && data[i]=='(' ){
if( i+2<size && data[i+1]=='^' ){ /* span-bounded inline footnote */
const size_t k = matching_bracket_offset(data+i, data+size);
const struct footnote *x;
if( !k ) goto char_link_cleanup;
x = add_inline_footnote(rndr, data+(i+2), k-2);
add_inline_footnote(rndr, data+(i+2), k-2, &fn);
if( x ) fn = *x;
i += k+1;
}else{ /* inline style link */
size_t span_end = i;
while( span_end<size
&& !(data[span_end]==')'
&& (span_end==i || data[span_end-1]!='\\')) ){
span_end++;
|
| ︙ | | |
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
|
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
|
+
+
-
+
-
+
|
struct Blob *ob, /* output blob */
struct render *rndr, /* renderer internal state */
char *data, /* input text */
size_t size /* input text size */
){
size_t beg, end, i;
char *txt_data;
int has_table;
if( !size ) return;
int has_table = (rndr->make.table
has_table = (rndr->make.table
&& rndr->make.table_row
&& rndr->make.table_cell
&& memchr(data, '|', size)!=0); /* TODO: handle data == 0 */
&& memchr(data, '|', size)!=0);
beg = 0;
while( beg<size ){
txt_data = data+beg;
end = size-beg;
if( data[beg]=='#' ){
beg += parse_atxheader(ob, rndr, txt_data, end);
|
| ︙ | | |