Fossil

Diff
Login

Differences From Artifact [968d831b72]:

To Artifact [5d8d9fe4c4]:


140
141
142
143
144
145
146



147
148
149
150
151
152
153
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156







+
+
+







/* link_ref -- reference to a link */
struct link_ref {
  struct Blob id;     /* must be the first field as in footnote struct */
  struct Blob link;
  struct Blob title;
};

/* A footnote's data.
** id, text, and upc fields must be in that particular order.
*/
struct footnote {
  struct Blob id;      /* must be the first field as in link_ref struct  */
  struct Blob text;    /* footnote's content that is rendered at the end */
  struct Blob upc;     /* user-provided classes  .ASCII-alnum.or-hypen:  */
  int bRndred;         /* indicates if `text` holds a rendered content   */

  int defno;  /* serial number of definition, set during the first pass  */
2503
2504
2505
2506
2507
2508
2509
2510
2511


2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531



2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549


2550
2551
2552
2553
2554
2555
2556
2506
2507
2508
2509
2510
2511
2512


2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531



2532
2533
2534

2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549


2550
2551
2552
2553
2554
2555
2556
2557
2558







-
-
+
+

















-
-
-
+
+
+
-















-
-
+
+







  upc_offset = upc_size = 0;
  if( data[i]!='\n' && data[i]!='\r' ){
    size_t j;
    upc_size = is_footnote_classlist(data+i, end-i, 1);
    upc_offset = i; /* prevent further checks for a classlist */
    i += upc_size;
    j = i;
    do i++; while( i<end && data[i]!='\n' && data[i]!='\r' );
    blob_append(&fn.text, data+j, i-j);
    while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; };
    if( i!=j )blob_append(&fn.text, data+j, i-j);
    if( i<end ){
      blob_append_char(&fn.text, data[i]);
      i++;
      if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
        blob_append_char(&fn.text, data[i]);
        i++;
      }
    }
  }else{
    i++;
    if( i<end && data[i]=='\n' && data[i-1]=='\r' ) i++;
  }
  if( i<end ){

    /* compute the indentation from the 2nd line  */
    size_t indent = i;
    const char *spaces = data+i;
    while( i<end && data[i]==' ' ){ i++; }
    if( i>=end )   goto footnote_finish;
    indent = i - indent;
    while( indent<end && data[indent]==' ' ){ indent++; }
    if( indent>=end ) goto footnote_finish;
    indent -= i;
    i -= indent;
    if( indent<2 ) goto footnote_finish;

    /* process the 2nd and the following lines */
    while( i+indent<end && memcmp(data+i,spaces,indent)==0 ){
      size_t j;
      i += indent;
      if( !upc_offset ){
        /* a classlist must be provided no later than at the 2nd line */
        upc_offset = i + sizeof_blank_prefix(data+i, end-i, 1);
        upc_size = is_footnote_classlist(data+upc_offset, end-upc_offset, 1);
        if( upc_size ){
          i = upc_offset + upc_size;
        }
      }
      j = i;
      while( i<end && data[i]!='\n' && data[i]!='\r' ) i++;
      blob_append(&fn.text, data+j, i-j);
      while( i<end && data[i]!='\n' && data[i]!='\r' ){ i++; }
      if( i!=j ) blob_append(&fn.text, data+j, i-j);
      if( i>=end ) break;
      blob_append_char(&fn.text, data[i]);
      i++;
      if( i<end && data[i]=='\n' && data[i-1]=='\r' ){
        blob_append_char(&fn.text, data[i]);
        i++;
      }
2673
2674
2675
2676
2677
2678
2679
2680

2681
2682

2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693




2694
2695
2696
2697
2698
2699
2700
2675
2676
2677
2678
2679
2680
2681

2682
2683

2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706







-
+

-
+











+
+
+
+







    int nDups = 0;
    fn = CAST_AS_FOOTNOTES( allNotes );
    qsort(fn, rndr.notes.nLbled, sizeof(struct footnote), cmp_footnote_id);

    /* concatenate footnotes with equal labels */
    for(i=0; i<rndr.notes.nLbled ;){
      struct footnote *x = fn + i;
      size_t j = i+1, k = blob_size(&x->text) + 64;
      size_t j = i+1, k = blob_size(&x->text) + 64 + blob_size(&x->upc);
      while(j<rndr.notes.nLbled && !blob_compare(&x->id, &fn[j].id)){
        k += blob_size(&fn[j].text) + 10;
        k += blob_size(&fn[j].text) + 10 + blob_size(&fn[j].upc);
        j++;
        nDups++;
      }
      if( i+1<j ){
        Blob list = empty_blob;
        blob_reserve(&list, k);
        /* must match _joined_footnote_indicator in html_footnote_item() */
        blob_append_string(&list, "<ul class='fn-joined'>\n");
        for(k=i; k<j; k++){
          struct footnote *y = fn + k;
          blob_append_string(&list, "<li>");
          if( blob_size(&y->upc) ){
            blob_append(&list, blob_buffer(&y->upc), blob_size(&y->upc));
            blob_reset(&y->upc);
          }
          blob_append(&list, blob_buffer(&y->text), blob_size(&y->text));
          blob_append_string(&list, "</li>\n");

          /* free memory buffer */
          blob_reset(&y->text);
          if( k!=i ) blob_reset(&y->id);
        }
2769
2770
2771
2772
2773
2774
2775









2776
2777
2778
2779
2780
2781





2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792

2793
2794

2795
2796
2797
2798
2799
2800
2801
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792




2793
2794
2795
2796
2797

2798
2799
2800
2801
2802
2803
2804
2805
2806

2807


2808
2809
2810
2811
2812
2813
2814
2815







+
+
+
+
+
+
+
+
+


-
-
-
-
+
+
+
+
+
-









-
+
-
-
+







    }
    release_work_buffer(&rndr,tmp);

    /* footnotes rendering */
    if( rndr.make.footnote_item && rndr.make.footnotes ){
      Blob *all_items = new_work_buffer(&rndr);
      int j = -1;

      /* Assert that the in-memory layout of id, text and upc within
      ** footnote struct matches the expectations of html_footnote_item()
      ** If it doesn't then a compiler has done something very weird.
      */
      const struct footnote *dummy = 0;
      assert( &(dummy->id)  == &(dummy->text) - 1 );
      assert( &(dummy->upc) == &(dummy->text) + 1 );

      for(i=0; i<COUNT_FOOTNOTES(notes); i++){
        const struct footnote* x = CAST_AS_FOOTNOTES(notes) + i;
        if( x->iMark ){
          rndr.make.footnote_item(all_items, &x->text, x->iMark,
                   x->bRndred ? x->nUsed : 0, rndr.make.opaque);
          j = i;
        if( !x->iMark ) break;
        assert( x->nUsed );
        rndr.make.footnote_item(all_items, &x->text, x->iMark,
                 x->bRndred ? x->nUsed : 0, rndr.make.opaque);
        j = i;
        }
      }
      if( rndr.notes.misref.nUsed ){
        rndr.make.footnote_item(all_items, 0, -1,
                    rndr.notes.misref.nUsed, rndr.make.opaque);
        g.ftntsIssues[0] += rndr.notes.misref.nUsed;
      }
      while( ++j < COUNT_FOOTNOTES(notes) ){
        const struct footnote* x = CAST_AS_FOOTNOTES(notes) + j;
        assert( !x->iMark );
        assert( !x->bRndred );
        assert( !x->nUsed );
        assert( (&x->id) + 1 == &x->text ); /* see html_footnote_item() */
        assert( (&x->upc)- 1 == &x->text );
        assert( !x->bRndred );
        rndr.make.footnote_item(all_items,&x->text,0,0,rndr.make.opaque);
        g.ftntsIssues[1]++;
      }
      rndr.make.footnotes(ob, all_items, rndr.make.opaque);
      release_work_buffer(&rndr, all_items);
    }
    release_work_buffer(&rndr, notes);