rmultimarkdown 6.4.0.3 → 6.7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +5 -5
  2. data/Rakefile +7 -13
  3. data/ext/Makefile +67 -55
  4. data/ext/extconf.rb +8 -6
  5. data/ext/mmd/aho-corasick.c +8 -8
  6. data/ext/mmd/aho-corasick.h +3 -3
  7. data/ext/mmd/argtable3.c +6537 -0
  8. data/ext/mmd/argtable3.h +273 -0
  9. data/ext/mmd/beamer.c +12 -1
  10. data/ext/mmd/char.c +120 -27
  11. data/ext/mmd/char.h +23 -23
  12. data/ext/mmd/critic_markup.c +7 -6
  13. data/ext/mmd/d_string.c +88 -32
  14. data/ext/mmd/{include/d_string.h → d_string.h} +50 -38
  15. data/ext/mmd/epub.c +36 -12
  16. data/ext/mmd/epub.h +2 -2
  17. data/ext/mmd/file.c +50 -40
  18. data/ext/mmd/file.h +2 -2
  19. data/ext/mmd/html.c +164 -99
  20. data/ext/mmd/html.h +3 -2
  21. data/ext/mmd/i18n.h +15 -11
  22. data/ext/mmd/itmz-lexer.c +16978 -0
  23. data/ext/mmd/itmz-lexer.h +132 -0
  24. data/ext/mmd/itmz-parser.c +1189 -0
  25. data/ext/mmd/itmz-parser.h +11 -0
  26. data/ext/mmd/itmz-reader.c +388 -0
  27. data/ext/mmd/itmz-reader.h +111 -0
  28. data/ext/mmd/itmz.c +567 -0
  29. data/ext/mmd/itmz.h +117 -0
  30. data/ext/mmd/latex.c +93 -41
  31. data/ext/mmd/lexer.c +3506 -2774
  32. data/ext/mmd/{include/libMultiMarkdown.h → libMultiMarkdown.h} +49 -2
  33. data/ext/mmd/main.c +612 -0
  34. data/ext/mmd/memoir.c +4 -1
  35. data/ext/mmd/miniz.c +6905 -6680
  36. data/ext/mmd/miniz.h +456 -476
  37. data/ext/mmd/mmd.c +399 -94
  38. data/ext/mmd/mmd.h +25 -25
  39. data/ext/mmd/object_pool.h +3 -3
  40. data/ext/mmd/opendocument-content.c +137 -69
  41. data/ext/mmd/opendocument-content.h +2 -2
  42. data/ext/mmd/opendocument.c +35 -14
  43. data/ext/mmd/opendocument.h +2 -2
  44. data/ext/mmd/opml-lexer.c +259 -637
  45. data/ext/mmd/opml-lexer.h +1 -17
  46. data/ext/mmd/opml-parser.c +194 -188
  47. data/ext/mmd/opml-reader.c +72 -142
  48. data/ext/mmd/opml-reader.h +1 -1
  49. data/ext/mmd/opml.c +13 -13
  50. data/ext/mmd/opml.h +1 -1
  51. data/ext/mmd/parser.c +1623 -1244
  52. data/ext/mmd/rng.c +8 -3
  53. data/ext/mmd/scanners.c +66625 -103198
  54. data/ext/mmd/scanners.h +1 -0
  55. data/ext/mmd/stack.c +62 -20
  56. data/ext/mmd/stack.h +10 -21
  57. data/ext/mmd/textbundle.c +23 -7
  58. data/ext/mmd/textbundle.h +2 -2
  59. data/ext/mmd/token.c +42 -16
  60. data/ext/mmd/{include/token.h → token.h} +22 -8
  61. data/ext/mmd/token_pairs.c +0 -16
  62. data/ext/mmd/transclude.c +6 -2
  63. data/ext/mmd/uthash.h +745 -745
  64. data/ext/mmd/version.h +8 -8
  65. data/ext/mmd/writer.c +225 -63
  66. data/ext/mmd/writer.h +50 -36
  67. data/ext/mmd/xml.c +855 -0
  68. data/ext/mmd/xml.h +134 -0
  69. data/ext/mmd/zip.c +71 -4
  70. data/ext/mmd/zip.h +7 -1
  71. data/ext/ruby_multi_markdown.c +9 -18
  72. data/lib/multi_markdown/version.rb +1 -1
  73. data/lib/multi_markdown.bundle +0 -0
  74. data/rmultimarkdown.gemspec +0 -2
  75. metadata +22 -28
  76. data/ext/mmd/char_lookup.c +0 -212
data/ext/mmd/html.c CHANGED
@@ -62,9 +62,11 @@
62
62
  #include "html.h"
63
63
  #include "i18n.h"
64
64
  #include "libMultiMarkdown.h"
65
+ #include "mmd.h"
65
66
  #include "parser.h"
66
67
  #include "token.h"
67
68
  #include "scanners.h"
69
+ #include "stack.h"
68
70
  #include "writer.h"
69
71
 
70
72
 
@@ -93,9 +95,9 @@ static char * my_strdup(const char * source) {
93
95
 
94
96
 
95
97
  // Use Knuth's pseudo random generator to obfuscate email addresses predictably
96
- long ran_num_next();
98
+ long ran_num_next(void);
97
99
 
98
- void mmd_print_char_html(DString * out, char c, bool obfuscate) {
100
+ void mmd_print_char_html(DString * out, char c, bool obfuscate, bool line_breaks) {
99
101
  switch (c) {
100
102
  case '"':
101
103
  print_const(""");
@@ -115,7 +117,12 @@ void mmd_print_char_html(DString * out, char c, bool obfuscate) {
115
117
 
116
118
  case '\n':
117
119
  case '\r':
118
- print_const("<br/>\n");
120
+ if (line_breaks) {
121
+ print_const("<br/>\n");
122
+ } else {
123
+ print_char(c);
124
+ }
125
+
119
126
  break;
120
127
 
121
128
  default:
@@ -134,10 +141,11 @@ void mmd_print_char_html(DString * out, char c, bool obfuscate) {
134
141
  }
135
142
 
136
143
 
137
- void mmd_print_string_html(DString * out, const char * str, bool obfuscate) {
144
+ void mmd_print_string_html(DString * out, const char * str, bool obfuscate, bool line_breaks) {
138
145
  if (str) {
139
146
  while (*str != '\0') {
140
- mmd_print_char_html(out, *str, obfuscate);
147
+ mmd_print_char_html(out, *str, obfuscate, line_breaks);
148
+
141
149
  str++;
142
150
  }
143
151
  }
@@ -254,8 +262,8 @@ void mmd_print_localized_char_html(DString * out, unsigned short type, scratch_p
254
262
  }
255
263
 
256
264
 
257
- static char * strip_dimension_units(char *original) {
258
- char *result;
265
+ static char * strip_dimension_units(char * original) {
266
+ char * result;
259
267
  int i;
260
268
 
261
269
  result = my_strdup(original);
@@ -281,7 +289,7 @@ void mmd_export_link_html(DString * out, const char * source, token * text, link
281
289
 
282
290
  if (link->url) {
283
291
  print_const("<a href=\"");
284
- mmd_print_string_html(out, link->url, false);
292
+ mmd_print_string_html(out, link->url, false, false);
285
293
  print_const("\"");
286
294
  } else {
287
295
  print_const("<a href=\"\"");
@@ -289,7 +297,7 @@ void mmd_export_link_html(DString * out, const char * source, token * text, link
289
297
 
290
298
  if (link->title && link->title[0] != '\0') {
291
299
  print_const(" title=\"");
292
- mmd_print_string_html(out, link->title, false);
300
+ mmd_print_string_html(out, link->title, false, false);
293
301
  print_const("\"");
294
302
  }
295
303
 
@@ -440,7 +448,7 @@ void mmd_export_image_html(DString * out, const char * source, token * text, lin
440
448
  print_const(" />");
441
449
 
442
450
  if (is_figure) {
443
- if (text) {
451
+ if (text && text->len > 3) {
444
452
  print_const("\n<figcaption>");
445
453
  mmd_export_token_tree_html(out, source, text->child, scratch);
446
454
  print_const("</figcaption>");
@@ -451,7 +459,7 @@ void mmd_export_image_html(DString * out, const char * source, token * text, lin
451
459
  }
452
460
 
453
461
 
454
- void mmd_export_toc_entry_html(DString * out, const char * source, scratch_pad * scratch, size_t * counter, short level) {
462
+ void mmd_export_toc_entry_html(DString * out, const char * source, scratch_pad * scratch, size_t * counter, short level, short min, short max) {
455
463
  token * entry, * next;
456
464
  short entry_level, next_level;
457
465
  char * temp_char;
@@ -464,31 +472,38 @@ void mmd_export_toc_entry_html(DString * out, const char * source, scratch_pad *
464
472
  entry = stack_peek_index(scratch->header_stack, *counter);
465
473
  entry_level = raw_level_for_header(entry);
466
474
 
467
- if (entry_level >= level) {
468
- // This entry is a direct descendant of the parent
469
- temp_char = label_from_header(source, entry);
470
- printf("<li><a href=\"#%s\">", temp_char);
471
- mmd_export_token_tree_html(out, source, entry->child, scratch);
472
- print_const("</a>");
473
-
474
- if (*counter < scratch->header_stack->size - 1) {
475
- next = stack_peek_index(scratch->header_stack, *counter + 1);
476
- next_level = next->type - BLOCK_H1 + 1;
477
-
478
- if (next_level > entry_level) {
479
- // This entry has children
480
- (*counter)++;
481
- mmd_export_toc_entry_html(out, source, scratch, counter, entry_level + 1);
475
+ if (entry_level < min || entry_level > max) {
476
+ // Ignore this one
477
+ } else {
478
+ if (entry_level >= level) {
479
+ // This entry is a direct descendant of the parent
480
+ scratch->label_counter = (int) * counter;
481
+ temp_char = label_from_header(source, entry, scratch);
482
+ printf("<li><a href=\"#%s\">", temp_char);
483
+ mmd_export_token_tree_html(out, source, entry->child, scratch);
484
+ trim_trailing_whitespace_d_string(out);
485
+ print_const("</a>");
486
+
487
+ if (*counter < scratch->header_stack->size - 1) {
488
+ next = stack_peek_index(scratch->header_stack, *counter + 1);
489
+ next_level = next->type - BLOCK_H1 + 1;
490
+
491
+ if (next_level > entry_level) {
492
+ // This entry has children
493
+ (*counter)++;
494
+ mmd_export_toc_entry_html(out, source, scratch, counter, entry_level + 1, min, max);
495
+ trim_trailing_whitespace_d_string(out);
496
+ }
482
497
  }
483
- }
484
498
 
485
- print_const("</li>\n");
486
- free(temp_char);
487
- } else if (entry_level < level ) {
488
- // If entry < level, exit this level
489
- // Decrement counter first, so that we can test it again later
490
- (*counter)--;
491
- break;
499
+ print_const("</li>\n");
500
+ free(temp_char);
501
+ } else if (entry_level < level ) {
502
+ // If entry < level, exit this level
503
+ // Decrement counter first, so that we can test it again later
504
+ (*counter)--;
505
+ break;
506
+ }
492
507
  }
493
508
 
494
509
  // Increment counter
@@ -499,10 +514,14 @@ void mmd_export_toc_entry_html(DString * out, const char * source, scratch_pad *
499
514
  }
500
515
 
501
516
 
502
- void mmd_export_toc_html(DString * out, const char * source, scratch_pad * scratch) {
517
+ void mmd_export_toc_html(DString * out, const char * source, scratch_pad * scratch, short min, short max) {
503
518
  size_t counter = 0;
504
519
 
505
- mmd_export_toc_entry_html(out, source, scratch, &counter, 0);
520
+ int old_label_counter = scratch->label_counter;
521
+
522
+ mmd_export_toc_entry_html(out, source, scratch, &counter, 0, min, max);
523
+
524
+ scratch->label_counter = old_label_counter;
506
525
  }
507
526
 
508
527
 
@@ -521,6 +540,8 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
521
540
  token * temp_token = NULL;
522
541
  footnote * temp_note = NULL;
523
542
 
543
+ t->out_start = out->currentStringLength;
544
+
524
545
  switch (t->type) {
525
546
  case AMPERSAND:
526
547
  case AMPERSAND_LONG:
@@ -612,6 +633,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
612
633
  scratch->padded = 1;
613
634
  break;
614
635
 
636
+ case MARKER_DEFLIST_COLON:
637
+ break;
638
+
615
639
  case BLOCK_CODE_FENCED:
616
640
  pad(out, 2, scratch);
617
641
 
@@ -622,6 +646,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
622
646
  // Raw source
623
647
  if (raw_filter_text_matches(temp_char, FORMAT_HTML)) {
624
648
  switch (t->child->tail->type) {
649
+ case CODE_FENCE_LINE:
625
650
  case LINE_FENCE_BACKTICK_3:
626
651
  case LINE_FENCE_BACKTICK_4:
627
652
  case LINE_FENCE_BACKTICK_5:
@@ -636,7 +661,10 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
636
661
  d_string_append_c_array(out, &source[t->child->next->start], temp_token->start - t->child->next->start);
637
662
  scratch->padded = 1;
638
663
  } else {
639
- d_string_append_c_array(out, &source[t->child->start + t->child->len], t->start + t->len - t->child->next->start);
664
+ if (t->child->next) {
665
+ d_string_append_c_array(out, &source[t->child->start + t->child->len], t->start + t->len - t->child->next->start);
666
+ }
667
+
640
668
  scratch->padded = 0;
641
669
  }
642
670
  }
@@ -681,13 +709,13 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
681
709
  if (scratch->extensions & EXT_NO_LABELS) {
682
710
  printf("<h%1d>", temp_short + scratch->base_header_level - 1);
683
711
  } else {
684
- temp_char = label_from_header(source, t);
712
+ temp_char = label_from_header(source, t, scratch);
685
713
  printf("<h%1d id=\"%s\">", temp_short + scratch->base_header_level - 1, temp_char);
686
714
  free(temp_char);
687
715
  }
688
716
 
717
+ header_clean_trailing_whitespace(t->child, source);
689
718
  mmd_export_token_tree_html(out, source, t->child, scratch);
690
- trim_trailing_whitespace_d_string(out);
691
719
 
692
720
  printf("</h%1d>", temp_short + scratch->base_header_level - 1);
693
721
  scratch->padded = 0;
@@ -767,7 +795,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
767
795
  print_const("<li>");
768
796
 
769
797
  if (!scratch->list_is_tight) {
770
- print_const("<p>");
798
+ if (t->child->type != BLOCK_PARA) {
799
+ print_const("<p>");
800
+ }
771
801
  }
772
802
 
773
803
  scratch->padded = 2;
@@ -775,7 +805,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
775
805
 
776
806
  if (scratch->close_para) {
777
807
  if (!scratch->list_is_tight) {
778
- print_const("</p>");
808
+ if (t->child->type != BLOCK_PARA) {
809
+ print_const("</p>");
810
+ }
779
811
  }
780
812
  } else {
781
813
  scratch->close_para = true;
@@ -795,7 +827,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
795
827
  pad(out, 2, scratch);
796
828
 
797
829
  if (!scratch->list_is_tight) {
798
- print_const("<p>");
830
+ if (t->child->type != BLOCK_PARA) {
831
+ print_const("<p>");
832
+ }
799
833
  }
800
834
 
801
835
  mmd_export_token_tree_html(out, source, t->child, scratch);
@@ -804,7 +838,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
804
838
  scratch->footnote_para_counter--;
805
839
 
806
840
  if (scratch->footnote_para_counter == 0) {
807
- printf(" <a href=\"#cnref:%d\" title=\"%s\" class=\"reversecitation\">&#160;&#8617;</a>", scratch->citation_being_printed, LC("return to body"));
841
+ printf(" <a href=\"#cnref:%d\" title=\"%s\" class=\"reversecitation\">&#160;&#8617;&#xfe0e;</a>", scratch->citation_being_printed, LC("return to body"));
808
842
  }
809
843
  }
810
844
 
@@ -819,7 +853,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
819
853
  temp_short = rand() % 32000 + 1;
820
854
  }
821
855
 
822
- printf(" <a href=\"#fnref:%d\" title=\"%s\" class=\"reversefootnote\">&#160;&#8617;</a>", temp_short, LC("return to body"));
856
+ printf(" <a href=\"#fnref:%d\" title=\"%s\" class=\"reversefootnote\">&#160;&#8617;&#xfe0e;</a>", temp_short, LC("return to body"));
823
857
  }
824
858
  }
825
859
 
@@ -827,13 +861,15 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
827
861
  scratch->footnote_para_counter--;
828
862
 
829
863
  if (scratch->footnote_para_counter == 0) {
830
- printf(" <a href=\"#gnref:%d\" title=\"%s\" class=\"reverseglossary\">&#160;&#8617;</a>", scratch->glossary_being_printed, LC("return to body"));
864
+ printf(" <a href=\"#gnref:%d\" title=\"%s\" class=\"reverseglossary\">&#160;&#8617;&#xfe0e;</a>", scratch->glossary_being_printed, LC("return to body"));
831
865
  }
832
866
  }
833
867
 
834
868
  if (scratch->close_para) {
835
869
  if (!scratch->list_is_tight) {
836
- print_const("</p>");
870
+ if (t->child->type != BLOCK_PARA) {
871
+ print_const("</p>");
872
+ }
837
873
  }
838
874
  } else {
839
875
  scratch->close_para = true;
@@ -849,18 +885,12 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
849
885
  if (scratch->extensions & EXT_NO_LABELS) {
850
886
  printf("<h%1d>", temp_short + scratch->base_header_level - 1);
851
887
  } else {
852
- temp_token = manual_label_from_header(t, source);
853
-
854
- if (temp_token) {
855
- temp_char = label_from_token(source, temp_token);
856
- } else {
857
- temp_char = label_from_token(source, t);
858
- }
859
-
888
+ temp_char = label_from_header(source, t, scratch);
860
889
  printf("<h%1d id=\"%s\">", temp_short + scratch->base_header_level - 1, temp_char);
861
890
  free(temp_char);
862
891
  }
863
892
 
893
+ header_clean_trailing_whitespace(t->child, source);
864
894
  mmd_export_token_tree_html(out, source, t->child, scratch);
865
895
  printf("</h%1d>", temp_short + scratch->base_header_level - 1);
866
896
  scratch->padded = 0;
@@ -873,18 +903,12 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
873
903
  if (scratch->extensions & EXT_NO_LABELS) {
874
904
  printf("<h%1d>", temp_short + scratch->base_header_level - 1);
875
905
  } else {
876
- temp_token = manual_label_from_header(t, source);
877
-
878
- if (temp_token) {
879
- temp_char = label_from_token(source, temp_token);
880
- } else {
881
- temp_char = label_from_token(source, t);
882
- }
883
-
906
+ temp_char = label_from_header(source, t, scratch);
884
907
  printf("<h%1d id=\"%s\">", temp_short + scratch->base_header_level - 1, temp_char);
885
908
  free(temp_char);
886
909
  }
887
910
 
911
+ header_clean_trailing_whitespace(t->child, source);
888
912
  mmd_export_token_tree_html(out, source, t->child, scratch);
889
913
  printf("</h%1d>", temp_short + scratch->base_header_level - 1);
890
914
  scratch->padded = 0;
@@ -892,7 +916,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
892
916
 
893
917
  case BLOCK_TABLE:
894
918
  pad(out, 2, scratch);
895
- print_const("<table>\n");
919
+ print_const("<table");
896
920
 
897
921
  // Are we followed by a caption?
898
922
  if (table_has_caption(t)) {
@@ -904,7 +928,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
904
928
  }
905
929
 
906
930
  temp_char = label_from_token(source, temp_token);
907
- printf("<caption style=\"caption-side: bottom;\" id=\"%s\">", temp_char);
931
+ printf(" id=\"%s\">\n<caption style=\"caption-side: bottom;\">", temp_char);
908
932
  free(temp_char);
909
933
 
910
934
  t->next->child->child->type = TEXT_EMPTY;
@@ -913,6 +937,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
913
937
  print_const("</caption>\n");
914
938
  temp_short = 1;
915
939
  } else {
940
+ print_const(">\n");
916
941
  temp_short = 0;
917
942
  }
918
943
 
@@ -1003,7 +1028,21 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
1003
1028
  pad(out, 2, scratch);
1004
1029
  print_const("<div class=\"TOC\">\n");
1005
1030
 
1006
- mmd_export_toc_html(out, source, scratch);
1031
+ // Define range
1032
+ if (t->child->child->type == TOC) {
1033
+ temp_short = 1;
1034
+ temp_short2 = 6;
1035
+ } else {
1036
+ temp_short = source[t->start + 6] - '0';
1037
+
1038
+ if (t->child->child->type == TOC_RANGE) {
1039
+ temp_short2 = source[t->start + 8] - '0';
1040
+ } else {
1041
+ temp_short2 = temp_short;
1042
+ }
1043
+ }
1044
+
1045
+ mmd_export_toc_html(out, source, scratch, temp_short, temp_short2);
1007
1046
  print_const("</div>");
1008
1047
  scratch->padded = 0;
1009
1048
  break;
@@ -1144,7 +1183,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
1144
1183
  (source[t->start + 1] == ' ')) {
1145
1184
  print_const("&nbsp;");
1146
1185
  } else {
1147
- mmd_print_char_html(out, source[t->start + 1], false);
1186
+ mmd_print_char_html(out, source[t->start + 1], false, false);
1148
1187
  }
1149
1188
 
1150
1189
  break;
@@ -1203,6 +1242,8 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
1203
1242
  case MARKER_H4:
1204
1243
  case MARKER_H5:
1205
1244
  case MARKER_H6:
1245
+ case MARKER_SETEXT_1:
1246
+ case MARKER_SETEXT_2:
1206
1247
  break;
1207
1248
 
1208
1249
  case MARKER_LIST_BULLET:
@@ -1333,15 +1374,15 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
1333
1374
  temp_bool = true;
1334
1375
 
1335
1376
  if (strncmp("mailto:", temp_char, 7) != 0) {
1336
- mmd_print_string_html(out, "mailto:", true);
1377
+ mmd_print_string_html(out, "mailto:", true, false);
1337
1378
  }
1338
1379
  } else {
1339
1380
  temp_bool = false;
1340
1381
  }
1341
1382
 
1342
- mmd_print_string_html(out, temp_char, temp_bool);
1383
+ mmd_print_string_html(out, temp_char, temp_bool, false);
1343
1384
  print_const("\">");
1344
- mmd_print_string_html(out, temp_char, temp_bool);
1385
+ mmd_print_string_html(out, temp_char, temp_bool, false);
1345
1386
  print_const("</a>");
1346
1387
  } else if (scan_html(&source[t->start])) {
1347
1388
  print_token(t);
@@ -1442,7 +1483,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
1442
1483
  if (temp_short2 == scratch->used_abbreviations->size) {
1443
1484
  // This is a re-use of a previously used note
1444
1485
  print_const("<abbr title=\"");
1445
- mmd_print_string_html(out, temp_note->clean_text, false);
1486
+ mmd_print_string_html(out, temp_note->clean_text, false, false);
1446
1487
  print_const("\">");
1447
1488
 
1448
1489
  if (t->child) {
@@ -1454,9 +1495,9 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
1454
1495
  print_const("</abbr>");
1455
1496
  } else {
1456
1497
  // This is the first time this note was used
1457
- mmd_print_string_html(out, temp_note->clean_text, false);
1498
+ mmd_print_string_html(out, temp_note->clean_text, false, false);
1458
1499
  print_const(" (<abbr title=\"");
1459
- mmd_print_string_html(out, temp_note->clean_text, false);
1500
+ mmd_print_string_html(out, temp_note->clean_text, false, false);
1460
1501
  print_const("\">");
1461
1502
 
1462
1503
  if (t->child) {
@@ -1469,11 +1510,11 @@ void mmd_export_token_html(DString * out, const char * source, token * t, scratc
1469
1510
  }
1470
1511
  } else {
1471
1512
  // This is an inline definition (and therefore the first use)
1472
- mmd_print_string_html(out, temp_note->clean_text, false);
1513
+ mmd_print_string_html(out, temp_note->clean_text, false, false);
1473
1514
  print_const(" (<abbr title=\"");
1474
- mmd_print_string_html(out, temp_note->clean_text, false);
1515
+ mmd_print_string_html(out, temp_note->clean_text, false, false);
1475
1516
  print_const("\">");
1476
- mmd_print_string_html(out, temp_note->label_text, false);
1517
+ mmd_print_string_html(out, temp_note->label_text, false, false);
1477
1518
  print_const("</abbr>)");
1478
1519
  }
1479
1520
  } else {
@@ -1651,7 +1692,7 @@ parse_citation:
1651
1692
 
1652
1693
  printf("<a href=\"#gn:%d\" title=\"%s\" class=\"glossary\">",
1653
1694
  temp_short, LC("see glossary"));
1654
- mmd_print_string_html(out, temp_note->clean_text, false);
1695
+ mmd_print_string_html(out, temp_note->clean_text, false, true);
1655
1696
  print_const("</a>");
1656
1697
  } else {
1657
1698
  // This is the first time this note was used
@@ -1659,7 +1700,7 @@ parse_citation:
1659
1700
 
1660
1701
  printf("<a href=\"#gn:%d\" id=\"gnref:%d\" title=\"%s\" class=\"glossary\">",
1661
1702
  temp_short, temp_short, LC("see glossary"));
1662
- mmd_print_string_html(out, temp_note->clean_text, false);
1703
+ mmd_print_string_html(out, temp_note->clean_text, false, true);
1663
1704
  print_const("</a>");
1664
1705
  }
1665
1706
  } else {
@@ -1674,7 +1715,7 @@ parse_citation:
1674
1715
  temp_char2 = extract_metadata(scratch, temp_char);
1675
1716
 
1676
1717
  if (temp_char2) {
1677
- mmd_print_string_html(out, temp_char2, false);
1718
+ mmd_print_string_html(out, temp_char2, false, true);
1678
1719
  } else {
1679
1720
  mmd_export_token_tree_html(out, source, t->child, scratch);
1680
1721
  }
@@ -1684,6 +1725,7 @@ parse_citation:
1684
1725
  break;
1685
1726
 
1686
1727
  case PAIR_CRITIC_ADD:
1728
+ stack_push(scratch->critic_stack, t);
1687
1729
 
1688
1730
  // Ignore if we're rejecting
1689
1731
  if (scratch->extensions & EXT_CRITIC_REJECT) {
@@ -1708,6 +1750,7 @@ parse_citation:
1708
1750
  break;
1709
1751
 
1710
1752
  case PAIR_CRITIC_DEL:
1753
+ stack_push(scratch->critic_stack, t);
1711
1754
 
1712
1755
  // Ignore if we're accepting
1713
1756
  if (scratch->extensions & EXT_CRITIC_ACCEPT) {
@@ -1732,6 +1775,7 @@ parse_citation:
1732
1775
  break;
1733
1776
 
1734
1777
  case PAIR_CRITIC_COM:
1778
+ stack_push(scratch->critic_stack, t);
1735
1779
 
1736
1780
  // Ignore if we're rejecting or accepting
1737
1781
  if ((scratch->extensions & EXT_CRITIC_REJECT) ||
@@ -1752,6 +1796,7 @@ parse_citation:
1752
1796
  break;
1753
1797
 
1754
1798
  case PAIR_CRITIC_HI:
1799
+ stack_push(scratch->critic_stack, t);
1755
1800
 
1756
1801
  // Ignore if we're rejecting or accepting
1757
1802
  if ((scratch->extensions & EXT_CRITIC_REJECT) ||
@@ -1783,6 +1828,8 @@ parse_citation:
1783
1828
  break;
1784
1829
 
1785
1830
  case PAIR_CRITIC_SUB_DEL:
1831
+ stack_push(scratch->critic_stack, t);
1832
+
1786
1833
  if ((scratch->extensions & EXT_CRITIC) &&
1787
1834
  (t->next) &&
1788
1835
  (t->next->type == PAIR_CRITIC_SUB_ADD)) {
@@ -1805,6 +1852,8 @@ parse_citation:
1805
1852
  break;
1806
1853
 
1807
1854
  case PAIR_CRITIC_SUB_ADD:
1855
+ stack_push(scratch->critic_stack, t);
1856
+
1808
1857
  if ((scratch->extensions & EXT_CRITIC) &&
1809
1858
  (t->prev) &&
1810
1859
  (t->prev->type == PAIR_CRITIC_SUB_DEL)) {
@@ -1937,21 +1986,25 @@ parse_citation:
1937
1986
  print_const("\t<td");
1938
1987
  }
1939
1988
 
1940
- switch (scratch->table_alignment[scratch->table_cell_count]) {
1941
- case 'l':
1942
- case 'L':
1943
- print_const(" style=\"text-align:left;\"");
1944
- break;
1989
+ if (scratch->table_cell_count < kMaxTableColumns) {
1990
+ switch (scratch->table_alignment[scratch->table_cell_count]) {
1991
+ case 'l':
1992
+ case 'L':
1993
+ print_const(" style=\"text-align:left;\"");
1994
+ break;
1945
1995
 
1946
- case 'r':
1947
- case 'R':
1948
- print_const(" style=\"text-align:right;\"");
1949
- break;
1996
+ case 'r':
1997
+ case 'R':
1998
+ print_const(" style=\"text-align:right;\"");
1999
+ break;
1950
2000
 
1951
- case 'c':
1952
- case 'C':
1953
- print_const(" style=\"text-align:center;\"");
1954
- break;
2001
+ case 'c':
2002
+ case 'C':
2003
+ print_const(" style=\"text-align:center;\"");
2004
+ break;
2005
+ }
2006
+ } else {
2007
+ print_const(" style=\"text-align:left;\"");
1955
2008
  }
1956
2009
 
1957
2010
  if (t->next && t->next->type == TABLE_DIVIDER) {
@@ -1998,6 +2051,7 @@ parse_citation:
1998
2051
  case CODE_FENCE:
1999
2052
  case TEXT_EMPTY:
2000
2053
  case MANUAL_LABEL:
2054
+ case OBJECT_REPLACEMENT_CHARACTER:
2001
2055
  break;
2002
2056
 
2003
2057
  case TEXT_NL:
@@ -2017,6 +2071,8 @@ parse_citation:
2017
2071
  case TEXT_PERIOD:
2018
2072
  case TEXT_PLAIN:
2019
2073
  case TOC:
2074
+ case TOC_SINGLE:
2075
+ case TOC_RANGE:
2020
2076
  print_token(t);
2021
2077
  break;
2022
2078
 
@@ -2027,8 +2083,11 @@ parse_citation:
2027
2083
  default:
2028
2084
  fprintf(stderr, "Unknown token type: %d (%lu:%lu)\n", t->type, t->start, t->len);
2029
2085
  token_describe(t, source);
2086
+ exit(0);
2030
2087
  break;
2031
2088
  }
2089
+
2090
+ t->out_len = out->currentStringLength - t->out_start;
2032
2091
  }
2033
2092
 
2034
2093
 
@@ -2108,7 +2167,7 @@ void mmd_export_token_html_raw(DString * out, const char * source, token * t, sc
2108
2167
 
2109
2168
  if (t->next && t->next->type == TEXT_EMPTY && source[t->start + 1] == ' ') {
2110
2169
  } else {
2111
- mmd_print_char_html(out, source[t->start + 1], false);
2170
+ mmd_print_char_html(out, source[t->start + 1], false, false);
2112
2171
  }
2113
2172
 
2114
2173
  break;
@@ -2212,6 +2271,8 @@ void mmd_export_token_html_raw(DString * out, const char * source, token * t, sc
2212
2271
 
2213
2272
  break;
2214
2273
  }
2274
+
2275
+ t->out_len = out->currentStringLength - t->out_start;
2215
2276
  }
2216
2277
 
2217
2278
 
@@ -2292,6 +2353,10 @@ void mmd_start_complete_html(DString * out, const char * source, scratch_pad * s
2292
2353
  print_const(" lang=\"sv\"");
2293
2354
  break;
2294
2355
 
2356
+ case LC_HE:
2357
+ print_const(" lang=\"he\"");
2358
+ break;
2359
+
2295
2360
  default:
2296
2361
  print_const(" lang=\"en\"");
2297
2362
  }
@@ -2312,10 +2377,10 @@ void mmd_start_complete_html(DString * out, const char * source, scratch_pad * s
2312
2377
  store_asset(scratch, m->value);
2313
2378
  asset * a = extract_asset(scratch, m->value);
2314
2379
 
2315
- mmd_print_string_html(out, "assets/", false);
2316
- mmd_print_string_html(out, a->asset_path, false);
2380
+ mmd_print_string_html(out, "assets/", false, false);
2381
+ mmd_print_string_html(out, a->asset_path, false, false);
2317
2382
  } else {
2318
- mmd_print_string_html(out, m->value, false);
2383
+ mmd_print_string_html(out, m->value, false, false);
2319
2384
  }
2320
2385
 
2321
2386
  print_const("\"/>\n");
@@ -2339,7 +2404,7 @@ void mmd_start_complete_html(DString * out, const char * source, scratch_pad * s
2339
2404
  } else if (strcmp(m->key, "quoteslanguage") == 0) {
2340
2405
  } else if (strcmp(m->key, "title") == 0) {
2341
2406
  print_const("\t<title>");
2342
- mmd_print_string_html(out, m->value, false);
2407
+ mmd_print_string_html(out, m->value, false, true);
2343
2408
  print_const("</title>\n");
2344
2409
  } else if (strcmp(m->key, "transcludebase") == 0) {
2345
2410
  } else if (strcmp(m->key, "xhtmlheader") == 0) {
@@ -2348,9 +2413,9 @@ void mmd_start_complete_html(DString * out, const char * source, scratch_pad * s
2348
2413
  } else if (strcmp(m->key, "xhtmlheaderlevel") == 0) {
2349
2414
  } else {
2350
2415
  print_const("\t<meta name=\"");
2351
- mmd_print_string_html(out, m->key, false);
2416
+ mmd_print_string_html(out, m->key, false, false);
2352
2417
  print_const("\" content=\"");
2353
- mmd_print_string_html(out, m->value, false);
2418
+ mmd_print_string_html(out, m->value, false, false);
2354
2419
  print_const("\"/>\n");
2355
2420
  }
2356
2421
  }
@@ -2469,7 +2534,7 @@ void mmd_export_glossary_list_html(DString * out, const char * source, scratch_p
2469
2534
  content = note->content;
2470
2535
 
2471
2536
  // Print term
2472
- mmd_print_string_html(out, note->clean_text, false);
2537
+ mmd_print_string_html(out, note->clean_text, false, true);
2473
2538
  print_const(": ");
2474
2539
 
2475
2540
  // Print contents
data/ext/mmd/html.h CHANGED
@@ -56,7 +56,8 @@
56
56
  #ifndef HTML_MULTIMARKDOWN_H
57
57
  #define HTML_MULTIMARKDOWN_H
58
58
 
59
- #include "d_string.h"
59
+ typedef struct DString DString;
60
+
60
61
  #include "token.h"
61
62
  #include "writer.h"
62
63
 
@@ -75,7 +76,7 @@ void mmd_export_glossary_list_html(DString * out, const char * source, scratch_p
75
76
  void mmd_start_complete_html(DString * out, const char * source, scratch_pad * scratch);
76
77
  void mmd_end_complete_html(DString * out, const char * source, scratch_pad * scratch);
77
78
 
78
- void mmd_print_string_html(DString * out, const char * str, bool obfuscate);
79
+ void mmd_print_string_html(DString * out, const char * str, bool obfuscate, bool line_breaks);
79
80
 
80
81
 
81
82
  #endif