Fossil

Diff
Login

Differences From Artifact [2594903eec]:

To Artifact [15df91dc48]:


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);