rdiscount 2.1.7 → 2.2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 51677d6198a4b3fa64990fb931e5b68651e0abfdfa8c1afdb16713fa52c66d6b
4
+ data.tar.gz: a11a9a266cd0a749614ef2fb4ee02ddc6718f12b81902a2b0281688fb4acad6e
5
+ SHA512:
6
+ metadata.gz: 4f108c1762e520eb80b5b73585f01a4e8bd0317ecbcc6f62ac0ca80eeb4cce87a88c4861b2e0d762956e5d765b048e6e8e4621132511e33c811249888790876b
7
+ data.tar.gz: 68af4be8ec06761fb3d34a9c66bdd6105436d1249bc23653cc3781510ba0fb9ed4e50da6d8aa09ec0194abaa83311d5a620ec46a311c5ce4e4d933e7b6a37779
data/BUILDING CHANGED
@@ -20,7 +20,7 @@ the rake gather task to copy discount source files into the ext/ directory:
20
20
  Submodule 'discount' (git://github.com/davidfstr/discount.git) registered for path 'discount'
21
21
  Cloning into discount...
22
22
  $ cd discount
23
- $ ./configure.sh --with-fenced-code --with-github-tags --with-dl=both
23
+ $ ./configure.sh
24
24
  $ make # ensure it compiles
25
25
  $ cd ..
26
26
  $ rake gather
@@ -52,6 +52,9 @@ ext. This must be done manually. Here's a quick way to get the full list:
52
52
 
53
53
  $ echo ext/*.c ext/*.h ext/*.rb ext/blocktags ext/VERSION | tr ' ' "\n" | sort
54
54
 
55
+ (There is an old Rakefile target called "rdiscount.gemspec" that looks like it
56
+ is designed to perform an update of these files, however I haven't tested it.)
57
+
55
58
  Build the RDiscount gem. If you get errors related to missing files
56
59
  in ext, make sure you updated the gemspec correctly in the previous step.
57
60
 
@@ -76,10 +79,14 @@ Worked? Swell! The hard part is past.
76
79
 
77
80
  Check the Discount release notes to determine whether it has gained any new
78
81
  features that should be exposed through the RDiscount Ruby interface
79
- (lib/rdiscount.rb), such as new MKD_* flags. If so, update the
80
- Ruby interface.
82
+ (lib/rdiscount.rb), such as new MKD_* flags or configure flags.
83
+ If so, update the Ruby interface.
84
+
85
+ If the ./configure.sh line needs to be changed to support new features,
86
+ you will need to port some #defines from discount/config.h to ext/config.h
87
+ manually to get RDiscount's embedded Discount to use the same configure flags.
81
88
 
82
- For new Discount extensions, you will need to update:
89
+ For new Discount extensions via new MKD_* flags, you will need to update:
83
90
 
84
91
  * lib/rdiscount.rb with new accessors and
85
92
  * the rb_rdiscount__get_flags function in ext/rdiscount.c with new
@@ -88,8 +95,8 @@ For new Discount extensions, you will need to update:
88
95
  You should also look for RDiscount-specific bugs & feature requests in the
89
96
  GitHub tracker and fix a few.
90
97
 
91
- If any bugs were fixed or features added, be sure to rerun the
92
- release tests mentioned above. And don't forget to add new tests!
98
+ If any bugs were fixed or features added be sure to also add new tests!
99
+ And don't forget to rerun the preexisting tests.
93
100
 
94
101
  Update the CHANGELOG.
95
102
 
@@ -1,6 +1,7 @@
1
1
  Discount Markdown Processor for Ruby
2
2
  ====================================
3
- [![Build Status](https://travis-ci.org/davidfstr/rdiscount.png)](https://travis-ci.org/davidfstr/rdiscount)
3
+ [![Build Status](https://travis-ci.org/davidfstr/rdiscount.svg?branch=master)](https://travis-ci.org/davidfstr/rdiscount)
4
+ [![Build status](https://ci.appveyor.com/api/projects/status/47i0qxrnvjbg724f/branch/master?svg=true)](https://ci.appveyor.com/project/DavidFoster/rdiscount/branch/master)
4
5
 
5
6
  Discount is an implementation of John Gruber's Markdown markup language in C. It
6
7
  implements all of the language described in [the markdown syntax document][1] and
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ task :default => :test
8
8
  # Ruby Extension
9
9
  # ==========================================================
10
10
 
11
- DLEXT = Config::MAKEFILE_CONFIG['DLEXT']
11
+ DLEXT = RbConfig::MAKEFILE_CONFIG['DLEXT']
12
12
  RUBYDIGEST = Digest::MD5.hexdigest(`ruby --version`)
13
13
 
14
14
  file "ext/ruby-#{RUBYDIGEST}" do |f|
@@ -63,7 +63,9 @@ task 'test:conformance' => [:build] do |t|
63
63
  test_version = ENV['MARKDOWN_TEST_VER'] || '1.0.3'
64
64
  lib_dir = "#{pwd}/lib"
65
65
  chdir("test/MarkdownTest_#{test_version}") do
66
- sh "RUBYLIB=#{lib_dir} ./MarkdownTest.pl --script='#{script}' --tidy"
66
+ result = `RUBYLIB=#{lib_dir} ./MarkdownTest.pl --script='#{script}' --tidy`
67
+ print result
68
+ fail unless result.include? "; 0 failed."
67
69
  end
68
70
  end
69
71
 
@@ -1 +1 @@
1
- 2.1.7
1
+ 2.2.0
@@ -8,7 +8,7 @@
8
8
 
9
9
  #define MAGIC 0x1f2e3d4c
10
10
 
11
- struct alist { int magic, size; struct alist *next, *last; };
11
+ struct alist { int magic, size, index; int *end; struct alist *next, *last; };
12
12
 
13
13
  static struct alist list = { 0, 0, 0, 0 };
14
14
 
@@ -16,14 +16,32 @@ static int mallocs=0;
16
16
  static int reallocs=0;
17
17
  static int frees=0;
18
18
 
19
+ static int index = 0;
20
+
21
+ static void
22
+ die(char *msg, int index)
23
+ {
24
+ fprintf(stderr, msg, index);
25
+ abort();
26
+ }
27
+
28
+
19
29
  void *
20
- acalloc(int size, int count)
30
+ acalloc(int count, int size)
21
31
  {
22
- struct alist *ret = calloc(size + sizeof(struct alist), count);
32
+ struct alist *ret;
33
+
34
+ if ( size > 1 ) {
35
+ count *= size;
36
+ size = 1;
37
+ }
23
38
 
24
- if ( ret ) {
39
+ if ( ret = calloc(count + sizeof(struct alist) + sizeof(int), size) ) {
25
40
  ret->magic = MAGIC;
26
41
  ret->size = size * count;
42
+ ret->index = index ++;
43
+ ret->end = (int*)(count + (char*) (ret + 1));
44
+ *(ret->end) = ~MAGIC;
27
45
  if ( list.next ) {
28
46
  ret->next = list.next;
29
47
  ret->last = &list;
@@ -54,6 +72,8 @@ afree(void *ptr)
54
72
  struct alist *p2 = ((struct alist*)ptr)-1;
55
73
 
56
74
  if ( p2->magic == MAGIC ) {
75
+ if ( ! (p2->end && *(p2->end) == ~MAGIC) )
76
+ die("goddam: corrupted memory block %d in free()!\n", p2->index);
57
77
  p2->last->next = p2->next;
58
78
  p2->next->last = p2->last;
59
79
  ++frees;
@@ -71,12 +91,16 @@ arealloc(void *ptr, int size)
71
91
  struct alist save;
72
92
 
73
93
  if ( p2->magic == MAGIC ) {
94
+ if ( ! (p2->end && *(p2->end) == ~MAGIC) )
95
+ die("goddam: corrupted memory block %d in realloc()!\n", p2->index);
74
96
  save.next = p2->next;
75
97
  save.last = p2->last;
76
- p2 = realloc(p2, sizeof(*p2) + size);
98
+ p2 = realloc(p2, sizeof(int) + sizeof(*p2) + size);
77
99
 
78
100
  if ( p2 ) {
79
101
  p2->size = size;
102
+ p2->end = (int*)(size + (char*) (p2 + 1));
103
+ *(p2->end) = ~MAGIC;
80
104
  p2->next->last = p2;
81
105
  p2->last->next = p2;
82
106
  ++reallocs;
@@ -7,16 +7,6 @@
7
7
  /* tabs are four spaces */
8
8
  #define TABSTOP 4
9
9
 
10
- /* enable fenced code blocks */
11
- #define WITH_FENCED_CODE 1
12
-
13
- /* include - and _ as acceptable characters in HTML tag names */
14
- #define WITH_GITHUB_TAGS 1
15
-
16
- /* enable discount and PHP Markdown Extra definition lists */
17
- #define USE_EXTRA_DL 1
18
- #define USE_DISCOUNT_DL 1
19
-
20
10
  /* these are setup by extconf.rb */
21
11
  #if HAVE_RANDOM
22
12
  #define COINTOSS() (random()&1)
data/ext/css.c CHANGED
@@ -75,11 +75,13 @@ int
75
75
  mkd_generatecss(Document *d, FILE *f)
76
76
  {
77
77
  char *res;
78
- int written = EOF, size = mkd_css(d, &res);
78
+ int written;
79
+ int size = mkd_css(d, &res);
79
80
 
80
- if ( size > 0 )
81
- written = fwrite(res, 1, size, f);
81
+ written = (size > 0) ? fwrite(res,1,size,f) : 0;
82
+
82
83
  if ( res )
83
84
  free(res);
85
+
84
86
  return (written == size) ? size : EOF;
85
87
  }
@@ -145,7 +145,6 @@ mkd_dump(Document *doc, FILE *out, int flags, char *title)
145
145
  dumptree(doc->code, &stack, out);
146
146
  DELETE(stack);
147
147
 
148
- mkd_cleanup(doc);
149
148
  return 0;
150
149
  }
151
150
  return -1;
@@ -22,7 +22,7 @@
22
22
  * of html has been generated.
23
23
  *
24
24
  * It should create MarkdownTest_1.0 (and _1.0.3)
25
- * compatable emphasis for non-pathological cases
25
+ * compatible emphasis for non-pathological cases
26
26
  * and it should fail in a standards-compliant way
27
27
  * when someone attempts to feed it junk.
28
28
  *
@@ -8,7 +8,7 @@ HAVE_RAND = have_func('rand')
8
8
  HAVE_SRAND = have_func('srand')
9
9
 
10
10
  def sized_int(size, types)
11
- types.find { |type| check_sizeof(type) == 4 } ||
11
+ types.find { |type| check_sizeof(type) == size } ||
12
12
  abort("no int with size #{size}")
13
13
  end
14
14
 
@@ -34,4 +34,16 @@ end
34
34
 
35
35
  $defs.push("-DVERSION=\\\"#{VERSION}\\\"")
36
36
 
37
+ # Post XCode 5.1 the command line tools on OS X treat unrecognised
38
+ # command line options as errors and it's been seen that
39
+ # -multiply_definedsuppress can trickle from ruby build settings.
40
+ # Issue 115
41
+ if /darwin|mac os/.match RbConfig::CONFIG['host_os']
42
+ $DLDFLAGS.gsub!("-multiply_definedsuppress", "")
43
+ end
44
+
45
+ if /mswin/.match RbConfig::CONFIG['host_os']
46
+ $defs.push("-Dinline=__inline")
47
+ end
48
+
37
49
  create_makefile('rdiscount')
@@ -30,6 +30,12 @@ static struct flagnames flagnames[] = {
30
30
  { MKD_NODLIST, "!DLIST" },
31
31
  { MKD_EXTRA_FOOTNOTE, "FOOTNOTE" },
32
32
  { MKD_NOSTYLE, "!STYLE" },
33
+ { MKD_NODLDISCOUNT, "!DLDISCOUNT" },
34
+ { MKD_DLEXTRA, "DLEXTRA" },
35
+ { MKD_FENCEDCODE, "FENCEDCODE" },
36
+ { MKD_IDANCHOR, "IDANCHOR" },
37
+ { MKD_GITHUBTAGS, "GITHUBTAGS" },
38
+ { MKD_URLENCODEDANCHOR, "URLENCODEDANCHOR" },
33
39
  };
34
40
  #define NR(x) (sizeof x/sizeof x[0])
35
41
 
@@ -38,6 +38,16 @@ push(char *bfr, int size, MMIOT *f)
38
38
  }
39
39
 
40
40
 
41
+ /*
42
+ * push a character into the generator input buffer
43
+ */
44
+ static void
45
+ pushc(char c, MMIOT *f)
46
+ {
47
+ EXPAND(f->in) = c;
48
+ }
49
+
50
+
41
51
  /* look <i> characters ahead of the cursor.
42
52
  */
43
53
  static inline int
@@ -207,7 +217,7 @@ ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f, char *esc)
207
217
  sub.esc = f->esc;
208
218
 
209
219
  push(bfr, size, &sub);
210
- EXPAND(sub.in) = 0;
220
+ pushc(0, &sub);
211
221
  S(sub.in)--;
212
222
 
213
223
  text(&sub);
@@ -262,7 +272,7 @@ puturl(char *s, int size, MMIOT *f, int display)
262
272
  Qstring("%22", f);
263
273
  else if ( isalnum(c) || ispunct(c) || (display && isspace(c)) )
264
274
  Qchar(c, f);
265
- else if ( c == 003 ) /* untokenize ^C */
275
+ else if ( c == MKD_EOLN ) /* untokenize hard return */
266
276
  Qstring(" ", f);
267
277
  else
268
278
  Qprintf(f, "%%%02X", c);
@@ -618,7 +628,7 @@ extra_linky(MMIOT *f, Cstring text, Footnote *ref)
618
628
  ___mkd_reparse(T(text), S(text), linkt.flags, f, 0);
619
629
  else {
620
630
  ref->flags |= REFERENCED;
621
- ref->refnumber = ++ f->reference;
631
+ ref->refnumber = ++ f->footnotes->reference;
622
632
  Qprintf(f, "<sup id=\"%sref:%d\"><a href=\"#%s:%d\" rel=\"footnote\">%d</a></sup>",
623
633
  p_or_nothing(f), ref->refnumber,
624
634
  p_or_nothing(f), ref->refnumber, ref->refnumber);
@@ -731,8 +741,9 @@ linkylinky(int image, MMIOT *f)
731
741
  S(key.tag) = S(name);
732
742
  }
733
743
 
734
- if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
735
- sizeof key, (stfu)__mkd_footsort) ) {
744
+ if ( ref = bsearch(&key, T(f->footnotes->note),
745
+ S(f->footnotes->note),
746
+ sizeof key, (stfu)__mkd_footsort) ) {
736
747
  if ( extra_footnote )
737
748
  status = extra_linky(f,name,ref);
738
749
  else
@@ -774,8 +785,12 @@ static void
774
785
  mangle(char *s, int len, MMIOT *f)
775
786
  {
776
787
  while ( len-- > 0 ) {
788
+ #if DEBIAN_GLITCH
789
+ Qprintf(f, "&#%02d;", *((unsigned char*)(s++)) );
790
+ #else
777
791
  Qstring("&#", f);
778
792
  Qprintf(f, COINTOSS() ? "x%02x;" : "%02d;", *((unsigned char*)(s++)) );
793
+ #endif
779
794
  }
780
795
  }
781
796
 
@@ -837,7 +852,7 @@ code(MMIOT *f, char *s, int length)
837
852
  int i,c;
838
853
 
839
854
  for ( i=0; i < length; i++ )
840
- if ( (c = s[i]) == 003) /* ^C: expand back to 2 spaces */
855
+ if ( (c = s[i]) == MKD_EOLN) /* ^C: expand back to 2 spaces */
841
856
  Qstring(" ", f);
842
857
  else if ( c == '\\' && (i < length-1) && escaped(f, s[i+1]) )
843
858
  cputc(s[++i], f);
@@ -845,7 +860,6 @@ code(MMIOT *f, char *s, int length)
845
860
  cputc(c, f);
846
861
  } /* code */
847
862
 
848
-
849
863
  /* delspan() -- write out a chunk of text, blocking with <del>...</del>
850
864
  */
851
865
  static void
@@ -994,11 +1008,9 @@ maybe_tag_or_link(MMIOT *f)
994
1008
  }
995
1009
  else if ( isspace(c) )
996
1010
  break;
997
- #if WITH_GITHUB_TAGS
998
- else if ( ! (c == '/' || c == '-' || c == '_' || isalnum(c) ) )
999
- #else
1000
- else if ( ! (c == '/' || isalnum(c) ) )
1001
- #endif
1011
+ else if ( ! (c == '/'
1012
+ || (f->flags & MKD_GITHUBTAGS && (c == '-' || c == '_'))
1013
+ || isalnum(c) ) )
1002
1014
  maybetag=0;
1003
1015
  }
1004
1016
 
@@ -1044,13 +1056,16 @@ maybe_autolink(MMIOT *f)
1044
1056
 
1045
1057
  /* greedily scan forward for the end of a legitimate link.
1046
1058
  */
1047
- for ( size=0; (c=peek(f, size+1)) != EOF; size++ )
1059
+ for ( size=0; (c=peek(f, size+1)) != EOF; size++ ) {
1048
1060
  if ( c == '\\' ) {
1049
1061
  if ( peek(f, size+2) != EOF )
1050
1062
  ++size;
1051
1063
  }
1052
- else if ( isspace(c) || strchr("'\"()[]{}<>`", c) )
1064
+ else if ( c & 0x80 ) /* HACK: ignore utf-8 extended characters */
1065
+ continue;
1066
+ else if ( isspace(c) || strchr("'\"()[]{}<>`", c) || c == MKD_EOLN )
1053
1067
  break;
1068
+ }
1054
1069
 
1055
1070
  if ( (size > 1) && process_possible_link(f, size) ) {
1056
1071
  shift(f, size);
@@ -1192,6 +1207,29 @@ smartypants(int c, int *flags, MMIOT *f)
1192
1207
  } /* smartypants */
1193
1208
 
1194
1209
 
1210
+ #if WITH_LATEX
1211
+ /* process latex with arbitrary 2-character ( $$ .. $$, \[ .. \], \( .. \)
1212
+ * delimiters
1213
+ */
1214
+ static int
1215
+ mathhandler(MMIOT *f, int e1, int e2)
1216
+ {
1217
+ int i = 0;
1218
+
1219
+ while(peek(f, ++i) != EOF) {
1220
+ if (peek(f, i) == e1 && peek(f, i+1) == e2) {
1221
+ cputc(peek(f,-1), f);
1222
+ cputc(peek(f, 0), f);
1223
+ while ( i-- > -1 )
1224
+ cputc(pull(f), f);
1225
+ return 1;
1226
+ }
1227
+ }
1228
+ return 0;
1229
+ }
1230
+ #endif
1231
+
1232
+
1195
1233
  /* process a body of text encased in some sort of tick marks. If it
1196
1234
  * works, generate the output and return 1, otherwise just return 0 and
1197
1235
  * let the caller figure it out.
@@ -1243,7 +1281,8 @@ text(MMIOT *f)
1243
1281
  switch (c) {
1244
1282
  case 0: break;
1245
1283
 
1246
- case 3: Qstring(tag_text(f) ? " " : "<br/>", f);
1284
+ case MKD_EOLN:
1285
+ Qstring(tag_text(f) ? " " : "<br/>", f);
1247
1286
  break;
1248
1287
 
1249
1288
  case '>': if ( tag_text(f) )
@@ -1266,6 +1305,7 @@ text(MMIOT *f)
1266
1305
  else
1267
1306
  Qchar(c, f);
1268
1307
  break;
1308
+
1269
1309
  case '[': if ( tag_text(f) || !linkylinky(0, f) )
1270
1310
  Qchar(c, f);
1271
1311
  break;
@@ -1369,7 +1409,14 @@ text(MMIOT *f)
1369
1409
 
1370
1410
  case EOF: Qchar('\\', f);
1371
1411
  break;
1372
-
1412
+
1413
+ #if WITH_LATEX
1414
+ case '[':
1415
+ case '(': if ( mathhandler(f, '\\', (c =='(')?')':']') )
1416
+ break;
1417
+ /* else fall through to default */
1418
+ #endif
1419
+
1373
1420
  default: if ( escaped(f,c) ||
1374
1421
  strchr(">#.-+{}]![*_\\()`", c) )
1375
1422
  Qchar(c, f);
@@ -1395,6 +1442,16 @@ text(MMIOT *f)
1395
1442
  Qchar(c, f);
1396
1443
  break;
1397
1444
 
1445
+ #if WITH_LATEX
1446
+ case '$': if ( peek(f, 1) == '$' ) {
1447
+ pull(f);
1448
+ if ( mathhandler(f, '$', '$') )
1449
+ break;
1450
+ Qchar('$', f);
1451
+ }
1452
+ /* fall through to default */
1453
+ #endif
1454
+
1398
1455
  default: Qchar(c, f);
1399
1456
  break;
1400
1457
  }
@@ -1409,26 +1466,26 @@ text(MMIOT *f)
1409
1466
  static void
1410
1467
  printheader(Paragraph *pp, MMIOT *f)
1411
1468
  {
1412
- #if WITH_ID_ANCHOR
1413
- Qprintf(f, "<h%d", pp->hnumber);
1414
- if ( f->flags & MKD_TOC ) {
1415
- Qstring(" id=\"", f);
1416
- mkd_string_to_anchor(T(pp->text->text),
1417
- S(pp->text->text),
1418
- (mkd_sta_function_t)Qchar, f, 1);
1419
- Qchar('"', f);
1420
- }
1421
- Qchar('>', f);
1422
- #else
1423
- if ( f->flags & MKD_TOC ) {
1424
- Qstring("<a name=\"", f);
1425
- mkd_string_to_anchor(T(pp->text->text),
1426
- S(pp->text->text),
1427
- (mkd_sta_function_t)Qchar, f, 1);
1428
- Qstring("\"></a>\n", f);
1469
+ if ( f->flags & MKD_IDANCHOR ) {
1470
+ Qprintf(f, "<h%d", pp->hnumber);
1471
+ if ( f->flags & MKD_TOC ) {
1472
+ Qstring(" id=\"", f);
1473
+ mkd_string_to_anchor(T(pp->text->text),
1474
+ S(pp->text->text),
1475
+ (mkd_sta_function_t)Qchar, f, 1, f->flags);
1476
+ Qchar('"', f);
1477
+ }
1478
+ Qchar('>', f);
1479
+ } else {
1480
+ if ( f->flags & MKD_TOC ) {
1481
+ Qstring("<a name=\"", f);
1482
+ mkd_string_to_anchor(T(pp->text->text),
1483
+ S(pp->text->text),
1484
+ (mkd_sta_function_t)Qchar, f, 1, f->flags);
1485
+ Qstring("\"></a>\n", f);
1486
+ }
1487
+ Qprintf(f, "<h%d>", pp->hnumber);
1429
1488
  }
1430
- Qprintf(f, "<h%d>", pp->hnumber);
1431
- #endif
1432
1489
  push(T(pp->text->text), S(pp->text->text), f);
1433
1490
  text(f);
1434
1491
  Qprintf(f, "</h%d>", pp->hnumber);
@@ -1567,13 +1624,14 @@ printblock(Paragraph *pp, MMIOT *f)
1567
1624
  && T(t->text)[S(t->text)-2] == ' '
1568
1625
  && T(t->text)[S(t->text)-1] == ' ' ) {
1569
1626
  push(T(t->text), S(t->text)-2, f);
1570
- push("\003\n", 2, f);
1627
+ pushc(MKD_EOLN, f);
1628
+ pushc('\n', f);
1571
1629
  }
1572
1630
  else {
1573
1631
  ___mkd_tidy(&t->text);
1574
1632
  push(T(t->text), S(t->text), f);
1575
1633
  if ( t->next )
1576
- push("\n", 1, f);
1634
+ pushc('\n', f);
1577
1635
  }
1578
1636
  }
1579
1637
  t = t->next;
@@ -1758,14 +1816,14 @@ mkd_extra_footnotes(MMIOT *m)
1758
1816
  int j, i;
1759
1817
  Footnote *t;
1760
1818
 
1761
- if ( m->reference == 0 )
1819
+ if ( m->footnotes->reference == 0 )
1762
1820
  return;
1763
1821
 
1764
1822
  Csprintf(&m->out, "\n<div class=\"footnotes\">\n<hr/>\n<ol>\n");
1765
1823
 
1766
- for ( i=1; i <= m->reference; i++ ) {
1767
- for ( j=0; j < S(*m->footnotes); j++ ) {
1768
- t = &T(*m->footnotes)[j];
1824
+ for ( i=1; i <= m->footnotes->reference; i++ ) {
1825
+ for ( j=0; j < S(m->footnotes->note); j++ ) {
1826
+ t = &T(m->footnotes->note)[j];
1769
1827
  if ( (t->refnumber == i) && (t->flags & REFERENCED) ) {
1770
1828
  Csprintf(&m->out, "<li id=\"%s:%d\">\n<p>",
1771
1829
  p_or_nothing(m), t->refnumber);
@@ -1794,15 +1852,19 @@ mkd_document(Document *p, char **res)
1794
1852
  if ( p->ctx->flags & MKD_EXTRA_FOOTNOTE )
1795
1853
  mkd_extra_footnotes(p->ctx);
1796
1854
  p->html = 1;
1797
- }
1798
-
1799
- size = S(p->ctx->out);
1855
+ size = S(p->ctx->out);
1800
1856
 
1801
- if ( (size == 0) || T(p->ctx->out)[size-1] )
1802
- EXPAND(p->ctx->out) = 0;
1857
+ if ( (size == 0) || T(p->ctx->out)[size-1] ) {
1858
+ /* Add a null byte at the end of the generated html,
1859
+ * but pretend it doesn't exist.
1860
+ */
1861
+ EXPAND(p->ctx->out) = 0;
1862
+ --S(p->ctx->out);
1863
+ }
1864
+ }
1803
1865
 
1804
1866
  *res = T(p->ctx->out);
1805
- return size;
1867
+ return S(p->ctx->out);
1806
1868
  }
1807
1869
  return EOF;
1808
1870
  }