rmultimarkdown 6.4.0.4 → 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.
- checksums.yaml +5 -5
- data/Rakefile +7 -13
- data/ext/Makefile +67 -55
- data/ext/extconf.rb +7 -5
- data/ext/mmd/aho-corasick.c +8 -8
- data/ext/mmd/aho-corasick.h +3 -3
- data/ext/mmd/argtable3.c +6537 -0
- data/ext/mmd/argtable3.h +273 -0
- data/ext/mmd/beamer.c +12 -1
- data/ext/mmd/char.c +120 -27
- data/ext/mmd/char.h +23 -23
- data/ext/mmd/critic_markup.c +7 -6
- data/ext/mmd/d_string.c +88 -32
- data/ext/mmd/{include/d_string.h → d_string.h} +50 -38
- data/ext/mmd/epub.c +36 -12
- data/ext/mmd/epub.h +2 -2
- data/ext/mmd/file.c +50 -40
- data/ext/mmd/file.h +2 -2
- data/ext/mmd/html.c +164 -99
- data/ext/mmd/html.h +3 -2
- data/ext/mmd/i18n.h +15 -11
- data/ext/mmd/itmz-lexer.c +16978 -0
- data/ext/mmd/itmz-lexer.h +132 -0
- data/ext/mmd/itmz-parser.c +1189 -0
- data/ext/mmd/itmz-parser.h +11 -0
- data/ext/mmd/itmz-reader.c +388 -0
- data/ext/mmd/itmz-reader.h +111 -0
- data/ext/mmd/itmz.c +567 -0
- data/ext/mmd/itmz.h +117 -0
- data/ext/mmd/latex.c +93 -41
- data/ext/mmd/lexer.c +3506 -2774
- data/ext/mmd/{include/libMultiMarkdown.h → libMultiMarkdown.h} +49 -2
- data/ext/mmd/main.c +612 -0
- data/ext/mmd/memoir.c +4 -1
- data/ext/mmd/miniz.c +6905 -6680
- data/ext/mmd/miniz.h +456 -476
- data/ext/mmd/mmd.c +399 -94
- data/ext/mmd/mmd.h +25 -25
- data/ext/mmd/object_pool.h +3 -3
- data/ext/mmd/opendocument-content.c +137 -69
- data/ext/mmd/opendocument-content.h +2 -2
- data/ext/mmd/opendocument.c +35 -14
- data/ext/mmd/opendocument.h +2 -2
- data/ext/mmd/opml-lexer.c +259 -637
- data/ext/mmd/opml-lexer.h +1 -17
- data/ext/mmd/opml-parser.c +194 -188
- data/ext/mmd/opml-reader.c +72 -142
- data/ext/mmd/opml-reader.h +1 -1
- data/ext/mmd/opml.c +13 -13
- data/ext/mmd/opml.h +1 -1
- data/ext/mmd/parser.c +1623 -1244
- data/ext/mmd/rng.c +8 -3
- data/ext/mmd/scanners.c +66625 -103198
- data/ext/mmd/scanners.h +1 -0
- data/ext/mmd/stack.c +62 -20
- data/ext/mmd/stack.h +10 -21
- data/ext/mmd/textbundle.c +23 -7
- data/ext/mmd/textbundle.h +2 -2
- data/ext/mmd/token.c +42 -16
- data/ext/mmd/{include/token.h → token.h} +22 -8
- data/ext/mmd/token_pairs.c +0 -16
- data/ext/mmd/transclude.c +6 -2
- data/ext/mmd/uthash.h +745 -745
- data/ext/mmd/version.h +8 -8
- data/ext/mmd/writer.c +225 -63
- data/ext/mmd/writer.h +50 -36
- data/ext/mmd/xml.c +855 -0
- data/ext/mmd/xml.h +134 -0
- data/ext/mmd/zip.c +71 -4
- data/ext/mmd/zip.h +7 -1
- data/ext/ruby_multi_markdown.c +9 -18
- data/lib/multi_markdown/version.rb +1 -1
- data/lib/multi_markdown.bundle +0 -0
- data/rmultimarkdown.gemspec +0 -2
- metadata +22 -28
- data/ext/mmd/char_lookup.c +0 -212
data/ext/mmd/version.h
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
|
|
3
|
-
version.h --
|
|
3
|
+
version.h -- libMultiMarkdown
|
|
4
4
|
|
|
5
|
-
Copyright © 2016 -
|
|
5
|
+
Copyright © 2016 - 2023 Fletcher T. Penney.
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
**/
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
#ifndef
|
|
22
|
-
#define
|
|
21
|
+
#ifndef FILE_LIBMULTIMARKDOWN_H
|
|
22
|
+
#define FILE_LIBMULTIMARKDOWN_H
|
|
23
23
|
|
|
24
|
-
#define
|
|
24
|
+
#define LIBMULTIMARKDOWN_NAME "MultiMarkdown"
|
|
25
25
|
|
|
26
|
-
#define
|
|
27
|
-
#define
|
|
26
|
+
#define LIBMULTIMARKDOWN_VERSION "6.7.0"
|
|
27
|
+
#define LIBMULTIMARKDOWN_COPYRIGHT "Copyright © 2016 - 2023 Fletcher T. Penney."
|
|
28
28
|
|
|
29
|
-
#define
|
|
29
|
+
#define LIBMULTIMARKDOWN_LICENSE "\tThe `MultiMarkdown 6` project is released under the MIT License..\n"\
|
|
30
30
|
" \n"\
|
|
31
31
|
" GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project:\n"\
|
|
32
32
|
" \n"\
|
data/ext/mmd/writer.c
CHANGED
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
#include "char.h"
|
|
65
65
|
#include "d_string.h"
|
|
66
66
|
#include "html.h"
|
|
67
|
+
#include "itmz.h"
|
|
67
68
|
#include "i18n.h"
|
|
68
69
|
#include "latex.h"
|
|
69
70
|
#include "memoir.h"
|
|
@@ -72,6 +73,7 @@
|
|
|
72
73
|
#include "opml.h"
|
|
73
74
|
#include "parser.h"
|
|
74
75
|
#include "scanners.h"
|
|
76
|
+
#include "stack.h"
|
|
75
77
|
#include "token.h"
|
|
76
78
|
#include "uuid.h"
|
|
77
79
|
#include "writer.h"
|
|
@@ -100,9 +102,9 @@ static char * my_strndup(const char * source, size_t n) {
|
|
|
100
102
|
char * result;
|
|
101
103
|
const char * test = source;
|
|
102
104
|
|
|
103
|
-
// strlen is too slow
|
|
105
|
+
// strlen is too slow if strlen(source) >> n
|
|
104
106
|
for (len = 0; len < n; ++len) {
|
|
105
|
-
if (test == '\0') {
|
|
107
|
+
if (*test == '\0') {
|
|
106
108
|
break;
|
|
107
109
|
}
|
|
108
110
|
|
|
@@ -168,6 +170,14 @@ scratch_pad * scratch_pad_new(mmd_engine * e, short format) {
|
|
|
168
170
|
p->random_seed_base = 0;
|
|
169
171
|
}
|
|
170
172
|
|
|
173
|
+
if (e->extensions & EXT_RANDOM_LABELS) {
|
|
174
|
+
p->random_seed_base_labels = rand() % 32000;
|
|
175
|
+
} else {
|
|
176
|
+
p->random_seed_base_labels = 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
p->label_counter = 0;
|
|
180
|
+
|
|
171
181
|
// Store links in a hash for rapid retrieval when exporting
|
|
172
182
|
p->link_hash = NULL;
|
|
173
183
|
link * l;
|
|
@@ -248,6 +258,8 @@ scratch_pad * scratch_pad_new(mmd_engine * e, short format) {
|
|
|
248
258
|
p->asset_hash = NULL;
|
|
249
259
|
p->store_assets = 0;
|
|
250
260
|
p->remember_assets = 0;
|
|
261
|
+
|
|
262
|
+
p->critic_stack = e->critic_stack;
|
|
251
263
|
}
|
|
252
264
|
|
|
253
265
|
return p;
|
|
@@ -358,10 +370,12 @@ void print_token_raw(DString * out, const char * source, token * t) {
|
|
|
358
370
|
case STRONG_START:
|
|
359
371
|
case STRONG_STOP:
|
|
360
372
|
case TEXT_EMPTY:
|
|
373
|
+
case MARKER_BLOCKQUOTE:
|
|
361
374
|
break;
|
|
362
375
|
|
|
363
376
|
case PAIR_EMPH:
|
|
364
377
|
case PAIR_STRONG:
|
|
378
|
+
case BLOCK_HTML:
|
|
365
379
|
print_token_tree_raw(out, source, t->child);
|
|
366
380
|
break;
|
|
367
381
|
|
|
@@ -451,14 +465,40 @@ char * label_from_token(const char * source, token * t) {
|
|
|
451
465
|
}
|
|
452
466
|
|
|
453
467
|
|
|
454
|
-
char * label_from_header(const char * source, token * t) {
|
|
468
|
+
char * label_from_header(const char * source, token * t, scratch_pad * scratch) {
|
|
455
469
|
char * result;
|
|
470
|
+
short temp_short;
|
|
471
|
+
|
|
456
472
|
token * temp_token = manual_label_from_header(t, source);
|
|
457
473
|
|
|
458
474
|
if (temp_token) {
|
|
459
475
|
result = label_from_token(source, temp_token);
|
|
460
476
|
} else {
|
|
461
|
-
|
|
477
|
+
if (scratch->extensions & EXT_RANDOM_LABELS) {
|
|
478
|
+
srand(scratch->random_seed_base_labels + scratch->label_counter);
|
|
479
|
+
temp_short = rand() % 32000 + 1;
|
|
480
|
+
result = malloc(sizeof(char) * 6);
|
|
481
|
+
sprintf(result, "%d", temp_short);
|
|
482
|
+
|
|
483
|
+
scratch->label_counter++;
|
|
484
|
+
} else {
|
|
485
|
+
temp_token = token_new(t->type, t->start, t->len);
|
|
486
|
+
|
|
487
|
+
if (t->child && t->child->tail) {
|
|
488
|
+
switch (t->child->tail->type) {
|
|
489
|
+
case MARKER_SETEXT_1:
|
|
490
|
+
case MARKER_SETEXT_2:
|
|
491
|
+
temp_token->len = t->child->tail->start - t->start;
|
|
492
|
+
break;
|
|
493
|
+
|
|
494
|
+
default:
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
result = label_from_token(source, temp_token);
|
|
500
|
+
token_free(temp_token);
|
|
501
|
+
}
|
|
462
502
|
}
|
|
463
503
|
|
|
464
504
|
return result;
|
|
@@ -466,7 +506,7 @@ char * label_from_header(const char * source, token * t) {
|
|
|
466
506
|
|
|
467
507
|
|
|
468
508
|
/// Clean up whitespace in string for standardization
|
|
469
|
-
char * clean_string(const char * str, bool lowercase) {
|
|
509
|
+
char * clean_string(const char * str, bool lowercase, bool url_clean) {
|
|
470
510
|
if (str == NULL) {
|
|
471
511
|
return NULL;
|
|
472
512
|
}
|
|
@@ -478,17 +518,19 @@ char * clean_string(const char * str, bool lowercase) {
|
|
|
478
518
|
while (*str != '\0') {
|
|
479
519
|
switch (*str) {
|
|
480
520
|
case '\\':
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
521
|
+
if (!url_clean) {
|
|
522
|
+
switch (*(str + 1)) {
|
|
523
|
+
case '\n':
|
|
524
|
+
case '\r':
|
|
525
|
+
d_string_append_c(out, '\n');
|
|
526
|
+
block_whitespace = true;
|
|
527
|
+
break;
|
|
528
|
+
|
|
529
|
+
default:
|
|
530
|
+
d_string_append_c(out, '\\');
|
|
531
|
+
block_whitespace = false;
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
492
534
|
}
|
|
493
535
|
|
|
494
536
|
break;
|
|
@@ -504,6 +546,16 @@ char * clean_string(const char * str, bool lowercase) {
|
|
|
504
546
|
|
|
505
547
|
break;
|
|
506
548
|
|
|
549
|
+
case '&':
|
|
550
|
+
if (url_clean) {
|
|
551
|
+
if (strncmp(str, "&", 5) == 0) {
|
|
552
|
+
str += 4;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
d_string_append_c(out, '&');
|
|
557
|
+
break;
|
|
558
|
+
|
|
507
559
|
default:
|
|
508
560
|
if (lowercase) {
|
|
509
561
|
d_string_append_c(out, tolower(*str));
|
|
@@ -540,7 +592,7 @@ char * clean_string_from_range(const char * source, size_t start, size_t len, bo
|
|
|
540
592
|
|
|
541
593
|
d_string_append_c_array(raw, &source[start], len);
|
|
542
594
|
|
|
543
|
-
clean = clean_string(raw->str, lowercase);
|
|
595
|
+
clean = clean_string(raw->str, lowercase, false);
|
|
544
596
|
|
|
545
597
|
d_string_free(raw, true);
|
|
546
598
|
|
|
@@ -556,7 +608,7 @@ char * clean_string_from_token(const char * source, token * t, bool lowercase) {
|
|
|
556
608
|
char * clean_inside_pair(const char * source, token * t, bool lowercase) {
|
|
557
609
|
char * text = text_inside_pair(source, t);
|
|
558
610
|
|
|
559
|
-
char * clean = clean_string(text, lowercase);
|
|
611
|
+
char * clean = clean_string(text, lowercase, false);
|
|
560
612
|
|
|
561
613
|
free(text);
|
|
562
614
|
|
|
@@ -616,10 +668,10 @@ attr * parse_attributes(char * source) {
|
|
|
616
668
|
a->next = attr_new(key, value);
|
|
617
669
|
a = a->next;
|
|
618
670
|
} else {
|
|
619
|
-
|
|
671
|
+
#ifndef __clang_analyzer__
|
|
620
672
|
a = attr_new(key, value);
|
|
621
673
|
attributes = a;
|
|
622
|
-
|
|
674
|
+
#endif
|
|
623
675
|
}
|
|
624
676
|
|
|
625
677
|
free(value); // We stored a modified copy
|
|
@@ -643,7 +695,7 @@ link * link_new(const char * source, token * label, char * url, char * title, ch
|
|
|
643
695
|
l->label_text = NULL;
|
|
644
696
|
}
|
|
645
697
|
|
|
646
|
-
l->url = clean_string(url, false);
|
|
698
|
+
l->url = clean_string(url, false, true);
|
|
647
699
|
l->title = (title == NULL) ? NULL : my_strdup(title);
|
|
648
700
|
l->attributes = (attributes == NULL) ? NULL : parse_attributes(attributes);
|
|
649
701
|
|
|
@@ -713,7 +765,7 @@ link * retrieve_link(scratch_pad * scratch, const char * key) {
|
|
|
713
765
|
return l;
|
|
714
766
|
}
|
|
715
767
|
|
|
716
|
-
char * clean = clean_string(key, true);
|
|
768
|
+
char * clean = clean_string(key, true, false);
|
|
717
769
|
|
|
718
770
|
HASH_FIND_STR(scratch->link_hash, clean, l);
|
|
719
771
|
|
|
@@ -839,24 +891,44 @@ void store_abbreviation(scratch_pad * scratch, footnote * f) {
|
|
|
839
891
|
|
|
840
892
|
|
|
841
893
|
void link_free(link * l) {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
894
|
+
if (l) {
|
|
895
|
+
free(l->label_text);
|
|
896
|
+
free(l->clean_text);
|
|
897
|
+
free(l->url);
|
|
898
|
+
free(l->title);
|
|
899
|
+
// free(l->id);
|
|
900
|
+
|
|
901
|
+
attr * a = l->attributes;
|
|
902
|
+
attr * b;
|
|
903
|
+
|
|
904
|
+
while (a) {
|
|
905
|
+
b = a->next;
|
|
906
|
+
free(a->key);
|
|
907
|
+
free(a->value);
|
|
908
|
+
free(a);
|
|
909
|
+
a = b;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
free(l);
|
|
857
913
|
}
|
|
914
|
+
}
|
|
858
915
|
|
|
859
|
-
|
|
916
|
+
|
|
917
|
+
/// Fix single whitespace characters
|
|
918
|
+
void whitespace_fix(token * t, const char * source) {
|
|
919
|
+
while (t) {
|
|
920
|
+
if ((t->type == TEXT_PLAIN) && (t->len == 1)) {
|
|
921
|
+
if (source[t->start] == ' ') {
|
|
922
|
+
t->type = NON_INDENT_SPACE;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
if (t->child) {
|
|
927
|
+
whitespace_fix(t->child, source);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
t = t->next;
|
|
931
|
+
}
|
|
860
932
|
}
|
|
861
933
|
|
|
862
934
|
|
|
@@ -867,7 +939,7 @@ void whitespace_accept(token ** remainder) {
|
|
|
867
939
|
|
|
868
940
|
/// Find link based on label
|
|
869
941
|
link * extract_link_from_stack(scratch_pad * scratch, const char * target) {
|
|
870
|
-
char * key = clean_string(target, true);
|
|
942
|
+
char * key = clean_string(target, true, false);
|
|
871
943
|
|
|
872
944
|
link * temp = NULL;
|
|
873
945
|
|
|
@@ -954,7 +1026,7 @@ char * destination_accept(const char * source, token ** remainder, bool validate
|
|
|
954
1026
|
}
|
|
955
1027
|
|
|
956
1028
|
// Is this a valid URL?
|
|
957
|
-
clean = clean_string(url, false);
|
|
1029
|
+
clean = clean_string(url, false, true);
|
|
958
1030
|
|
|
959
1031
|
if (validate && !validate_url(clean)) {
|
|
960
1032
|
free(clean);
|
|
@@ -992,7 +1064,7 @@ char * url_accept(const char * source, size_t start, size_t max_len, size_t * en
|
|
|
992
1064
|
|
|
993
1065
|
url = my_strndup(&source[start], scan_len);
|
|
994
1066
|
|
|
995
|
-
clean = clean_string(url, false);
|
|
1067
|
+
clean = clean_string(url, false, true);
|
|
996
1068
|
|
|
997
1069
|
if (validate && !validate_url(clean)) {
|
|
998
1070
|
free(clean);
|
|
@@ -1130,11 +1202,11 @@ footnote * footnote_new(const char * source, token * label, token * content, boo
|
|
|
1130
1202
|
void footnote_free(footnote * f) {
|
|
1131
1203
|
if (f) {
|
|
1132
1204
|
if (f->free_para) {
|
|
1133
|
-
|
|
1205
|
+
#ifdef kUseObjectPool
|
|
1134
1206
|
// Nothing to do here
|
|
1135
|
-
|
|
1207
|
+
#else
|
|
1136
1208
|
free(f->content);
|
|
1137
|
-
|
|
1209
|
+
#endif
|
|
1138
1210
|
}
|
|
1139
1211
|
|
|
1140
1212
|
free(f->clean_text);
|
|
@@ -1167,22 +1239,24 @@ void meta_set_value(meta * m, const char * value) {
|
|
|
1167
1239
|
free(m->value);
|
|
1168
1240
|
}
|
|
1169
1241
|
|
|
1170
|
-
m->value = clean_string(value, false);
|
|
1242
|
+
m->value = clean_string(value, false, false);
|
|
1171
1243
|
}
|
|
1172
1244
|
}
|
|
1173
1245
|
|
|
1174
1246
|
|
|
1175
1247
|
void meta_free(meta * m) {
|
|
1176
|
-
|
|
1177
|
-
|
|
1248
|
+
if (m) {
|
|
1249
|
+
free(m->key);
|
|
1250
|
+
free(m->value);
|
|
1178
1251
|
|
|
1179
|
-
|
|
1252
|
+
free(m);
|
|
1253
|
+
}
|
|
1180
1254
|
}
|
|
1181
1255
|
|
|
1182
1256
|
|
|
1183
1257
|
/// Find metadata based on key
|
|
1184
1258
|
meta * extract_meta_from_stack(scratch_pad * scratch, const char * target) {
|
|
1185
|
-
char * key = clean_string(target, true);
|
|
1259
|
+
char * key = clean_string(target, true, false);
|
|
1186
1260
|
|
|
1187
1261
|
meta * temp = NULL;
|
|
1188
1262
|
|
|
@@ -1293,6 +1367,7 @@ bool definition_extract(mmd_engine * e, token ** remainder) {
|
|
|
1293
1367
|
}
|
|
1294
1368
|
|
|
1295
1369
|
// Skip space
|
|
1370
|
+
whitespace_fix(*remainder, e->dstr->str);
|
|
1296
1371
|
whitespace_accept(remainder);
|
|
1297
1372
|
|
|
1298
1373
|
// Grab destination
|
|
@@ -1408,14 +1483,15 @@ void process_definition_block(mmd_engine * e, token * block) {
|
|
|
1408
1483
|
if (f) {
|
|
1409
1484
|
free(f->label_text);
|
|
1410
1485
|
f->label_text = f->clean_text;
|
|
1411
|
-
}
|
|
1412
1486
|
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1487
|
+
if (f->content &&
|
|
1488
|
+
f->content->child &&
|
|
1489
|
+
f->content->child->next &&
|
|
1490
|
+
f->content->child->next->next) {
|
|
1491
|
+
f->clean_text = clean_string_from_range(e->dstr->str, f->content->child->next->next->start, block->start + block->len - f->content->child->next->next->start, false);
|
|
1492
|
+
} else {
|
|
1493
|
+
f->clean_text = NULL;
|
|
1494
|
+
}
|
|
1419
1495
|
}
|
|
1420
1496
|
|
|
1421
1497
|
stack_push(e->abbreviation_stack, f);
|
|
@@ -1502,10 +1578,17 @@ token * manual_label_from_header(token * h, const char * source) {
|
|
|
1502
1578
|
case MARKER_H4:
|
|
1503
1579
|
case MARKER_H5:
|
|
1504
1580
|
case MARKER_H6:
|
|
1581
|
+
case MARKER_SETEXT_1:
|
|
1582
|
+
case MARKER_SETEXT_2:
|
|
1505
1583
|
walker = walker->prev;
|
|
1506
1584
|
break;
|
|
1507
1585
|
|
|
1508
1586
|
case TEXT_PLAIN:
|
|
1587
|
+
if (walker->len == 0) {
|
|
1588
|
+
walker = walker->prev;
|
|
1589
|
+
break;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1509
1592
|
if (walker->len == 1) {
|
|
1510
1593
|
if (source[walker->start] == ' ') {
|
|
1511
1594
|
walker = walker->prev;
|
|
@@ -1666,6 +1749,9 @@ void process_metadata_stack(mmd_engine * e, scratch_pad * scratch) {
|
|
|
1666
1749
|
} else if (strcmp(temp_char, "fr") == 0) {
|
|
1667
1750
|
scratch->language = LC_FR;
|
|
1668
1751
|
scratch->quotes_lang = FRENCH;
|
|
1752
|
+
} else if (strcmp(temp_char, "he") == 0) {
|
|
1753
|
+
scratch->language = LC_HE;
|
|
1754
|
+
scratch->quotes_lang = ENGLISH;
|
|
1669
1755
|
} else if (strcmp(temp_char, "nl") == 0) {
|
|
1670
1756
|
scratch->language = LC_NL;
|
|
1671
1757
|
scratch->quotes_lang = DUTCH;
|
|
@@ -1899,6 +1985,10 @@ void mmd_engine_export_token_tree(DString * out, mmd_engine * e, short format) {
|
|
|
1899
1985
|
|
|
1900
1986
|
break;
|
|
1901
1987
|
|
|
1988
|
+
case FORMAT_HTML_WITH_ASSETS:
|
|
1989
|
+
scratch->remember_assets = true;
|
|
1990
|
+
scratch->output_format = FORMAT_HTML;
|
|
1991
|
+
|
|
1902
1992
|
case FORMAT_HTML:
|
|
1903
1993
|
if (scratch->extensions & EXT_COMPLETE) {
|
|
1904
1994
|
mmd_start_complete_html(out, e->dstr->str, scratch);
|
|
@@ -1957,11 +2047,18 @@ void mmd_engine_export_token_tree(DString * out, mmd_engine * e, short format) {
|
|
|
1957
2047
|
case FORMAT_OPML:
|
|
1958
2048
|
mmd_export_token_tree_opml(out, e->dstr->str, e->root, scratch);
|
|
1959
2049
|
break;
|
|
2050
|
+
|
|
2051
|
+
case FORMAT_ITMZ:
|
|
2052
|
+
mmd_export_token_tree_itmz(out, e->dstr->str, e->root, scratch);
|
|
2053
|
+
break;
|
|
1960
2054
|
}
|
|
1961
2055
|
|
|
1962
2056
|
// Preserve asset_hash for possible use in export
|
|
1963
2057
|
e->asset_hash = scratch->asset_hash;
|
|
1964
2058
|
|
|
2059
|
+
// Preserve random label seed
|
|
2060
|
+
e->random_seed_base_labels = scratch->random_seed_base_labels;
|
|
2061
|
+
|
|
1965
2062
|
scratch_pad_free(scratch);
|
|
1966
2063
|
}
|
|
1967
2064
|
|
|
@@ -2112,7 +2209,7 @@ void mark_abbreviation_as_used(scratch_pad * scratch, footnote * c) {
|
|
|
2112
2209
|
|
|
2113
2210
|
|
|
2114
2211
|
size_t extract_citation_from_stack(scratch_pad * scratch, const char * target) {
|
|
2115
|
-
char * key = clean_string(target, true);
|
|
2212
|
+
char * key = clean_string(target, true, false);
|
|
2116
2213
|
|
|
2117
2214
|
fn_holder * h;
|
|
2118
2215
|
|
|
@@ -2142,7 +2239,7 @@ size_t extract_citation_from_stack(scratch_pad * scratch, const char * target) {
|
|
|
2142
2239
|
|
|
2143
2240
|
|
|
2144
2241
|
size_t extract_footnote_from_stack(scratch_pad * scratch, const char * target) {
|
|
2145
|
-
char * key = clean_string(target, true);
|
|
2242
|
+
char * key = clean_string(target, true, false);
|
|
2146
2243
|
|
|
2147
2244
|
fn_holder * h;
|
|
2148
2245
|
|
|
@@ -2172,7 +2269,7 @@ size_t extract_footnote_from_stack(scratch_pad * scratch, const char * target) {
|
|
|
2172
2269
|
|
|
2173
2270
|
|
|
2174
2271
|
size_t extract_abbreviation_from_stack(scratch_pad * scratch, const char * target) {
|
|
2175
|
-
char * key = clean_string(target, false);
|
|
2272
|
+
char * key = clean_string(target, false, false);
|
|
2176
2273
|
|
|
2177
2274
|
fn_holder * h;
|
|
2178
2275
|
|
|
@@ -2202,7 +2299,7 @@ size_t extract_abbreviation_from_stack(scratch_pad * scratch, const char * targe
|
|
|
2202
2299
|
|
|
2203
2300
|
|
|
2204
2301
|
size_t extract_glossary_from_stack(scratch_pad * scratch, const char * target) {
|
|
2205
|
-
char * key = clean_string(target, false);
|
|
2302
|
+
char * key = clean_string(target, false, false);
|
|
2206
2303
|
|
|
2207
2304
|
fn_holder * h;
|
|
2208
2305
|
|
|
@@ -2494,7 +2591,6 @@ void strip_leading_whitespace(token * chain, const char * source) {
|
|
|
2494
2591
|
chain->type = TEXT_EMPTY;
|
|
2495
2592
|
|
|
2496
2593
|
case TEXT_EMPTY:
|
|
2497
|
-
chain = chain->next;
|
|
2498
2594
|
break;
|
|
2499
2595
|
|
|
2500
2596
|
case TEXT_PLAIN:
|
|
@@ -2562,6 +2658,10 @@ bool table_has_caption(token * t) {
|
|
|
2562
2658
|
/// or
|
|
2563
2659
|
/// ```` perl
|
|
2564
2660
|
char * get_fence_language_specifier(token * fence, const char * source) {
|
|
2661
|
+
if (fence == NULL) {
|
|
2662
|
+
return NULL;
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2565
2665
|
char * result = NULL;
|
|
2566
2666
|
size_t start = fence->start + fence->len;
|
|
2567
2667
|
size_t len = 0;
|
|
@@ -2609,6 +2709,67 @@ short raw_level_for_header(token * header) {
|
|
|
2609
2709
|
}
|
|
2610
2710
|
|
|
2611
2711
|
|
|
2712
|
+
void header_clean_trailing_whitespace(token * header, const char * source) {
|
|
2713
|
+
token * walker = header->tail;
|
|
2714
|
+
bool done = false;
|
|
2715
|
+
|
|
2716
|
+
while (!done && walker) {
|
|
2717
|
+
switch (walker->type) {
|
|
2718
|
+
case TEXT_PLAIN:
|
|
2719
|
+
token_trim_trailing_whitespace(walker, source);
|
|
2720
|
+
|
|
2721
|
+
if (walker->len) {
|
|
2722
|
+
done = true;
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
break;
|
|
2726
|
+
|
|
2727
|
+
case NON_INDENT_SPACE:
|
|
2728
|
+
case INDENT_SPACE:
|
|
2729
|
+
case INDENT_TAB:
|
|
2730
|
+
walker->type = TEXT_PLAIN;
|
|
2731
|
+
|
|
2732
|
+
case TEXT_NL:
|
|
2733
|
+
case TEXT_NL_SP:
|
|
2734
|
+
case TEXT_LINEBREAK:
|
|
2735
|
+
case TEXT_LINEBREAK_SP:
|
|
2736
|
+
token_trim_trailing_whitespace(walker, source);
|
|
2737
|
+
break;
|
|
2738
|
+
|
|
2739
|
+
case MARKER_H1:
|
|
2740
|
+
case MARKER_H2:
|
|
2741
|
+
case MARKER_H3:
|
|
2742
|
+
case MARKER_H4:
|
|
2743
|
+
case MARKER_H5:
|
|
2744
|
+
case MARKER_H6:
|
|
2745
|
+
case MANUAL_LABEL:
|
|
2746
|
+
break;
|
|
2747
|
+
|
|
2748
|
+
case MARKER_SETEXT_1:
|
|
2749
|
+
case MARKER_SETEXT_2:
|
|
2750
|
+
if (walker->prev) {
|
|
2751
|
+
switch (walker->prev->type) {
|
|
2752
|
+
case TEXT_NL:
|
|
2753
|
+
case TEXT_NL_SP:
|
|
2754
|
+
case TEXT_LINEBREAK:
|
|
2755
|
+
case TEXT_LINEBREAK_SP:
|
|
2756
|
+
walker->prev->type = NON_INDENT_SPACE;
|
|
2757
|
+
break;
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
break;
|
|
2762
|
+
|
|
2763
|
+
default:
|
|
2764
|
+
done = true;
|
|
2765
|
+
break;
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
walker = walker->prev;
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
|
|
2772
|
+
|
|
2612
2773
|
asset * asset_new(char * url, scratch_pad * scratch) {
|
|
2613
2774
|
asset * a = malloc(sizeof(asset));
|
|
2614
2775
|
|
|
@@ -2627,9 +2788,9 @@ void asset_free(asset * a) {
|
|
|
2627
2788
|
if (a) {
|
|
2628
2789
|
free(a->url);
|
|
2629
2790
|
free(a->asset_path);
|
|
2630
|
-
}
|
|
2631
2791
|
|
|
2632
|
-
|
|
2792
|
+
free(a);
|
|
2793
|
+
}
|
|
2633
2794
|
}
|
|
2634
2795
|
|
|
2635
2796
|
|
|
@@ -2666,6 +2827,7 @@ bool raw_filter_text_matches(char * pattern, short format) {
|
|
|
2666
2827
|
} else {
|
|
2667
2828
|
switch (format) {
|
|
2668
2829
|
case FORMAT_HTML:
|
|
2830
|
+
case FORMAT_HTML_WITH_ASSETS:
|
|
2669
2831
|
if (strstr(pattern, "html")) {
|
|
2670
2832
|
return true;
|
|
2671
2833
|
}
|