dtext_rb 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +11 -3
- data/VERSION +1 -1
- data/dtext_rb.gemspec +5 -3
- data/ext/dtext/dtext.c +2608 -2618
- data/ext/dtext/dtext.rl +217 -199
- data/lib/dtext_ruby.rb +1 -1
- data/test/dtext_test.rb +28 -2
- data/test/test_forum_posts.rb +13 -0
- data/test/test_wiki_pages.rb +13 -0
- metadata +4 -2
data/ext/dtext/dtext.rl
CHANGED
@@ -13,6 +13,7 @@ typedef struct StateMachine {
|
|
13
13
|
int cs;
|
14
14
|
int act;
|
15
15
|
const char * p;
|
16
|
+
const char * pb;
|
16
17
|
const char * pe;
|
17
18
|
const char * eof;
|
18
19
|
const char * ts;
|
@@ -25,6 +26,7 @@ typedef struct StateMachine {
|
|
25
26
|
bool f_inline;
|
26
27
|
bool f_strip;
|
27
28
|
bool list_mode;
|
29
|
+
bool header_mode;
|
28
30
|
GString * output;
|
29
31
|
GArray * stack;
|
30
32
|
GQueue * dstack;
|
@@ -57,6 +59,12 @@ static const int BLOCK_TR = 19;
|
|
57
59
|
static const int BLOCK_UL = 20;
|
58
60
|
static const int BLOCK_LI = 21;
|
59
61
|
static const int BLOCK_TH = 22;
|
62
|
+
static const int BLOCK_H1 = 23;
|
63
|
+
static const int BLOCK_H2 = 24;
|
64
|
+
static const int BLOCK_H3 = 25;
|
65
|
+
static const int BLOCK_H4 = 26;
|
66
|
+
static const int BLOCK_H5 = 27;
|
67
|
+
static const int BLOCK_H6 = 28;
|
60
68
|
|
61
69
|
%%{
|
62
70
|
machine dtext;
|
@@ -100,9 +108,9 @@ action mark_b2 {
|
|
100
108
|
sm->b2 = sm->p;
|
101
109
|
}
|
102
110
|
|
103
|
-
newline = '\r\n' | '\
|
111
|
+
newline = '\r\n' | '\n';
|
104
112
|
|
105
|
-
nonnewline = any - (newline | '\0');
|
113
|
+
nonnewline = any - (newline | '\0' | '\r');
|
106
114
|
nonquote = ^'"';
|
107
115
|
nonbracket = ^']';
|
108
116
|
nonpipe = ^'|';
|
@@ -121,20 +129,20 @@ aliased_wiki_link = '[[' nonpipebracket+ >mark_a1 %mark_a2 '|' nonbracket+ >mark
|
|
121
129
|
|
122
130
|
post_link = '{{' noncurly+ >mark_a1 %mark_a2 '}}';
|
123
131
|
|
124
|
-
post_id = 'post #' digit+ >mark_a1 %mark_a2;
|
125
|
-
forum_post_id = 'forum #' digit+ >mark_a1 %mark_a2;
|
126
|
-
forum_topic_id = 'topic #' digit+ >mark_a1 %mark_a2;
|
127
|
-
forum_topic_paged_id = 'topic #' digit+ >mark_a1 %mark_a2 '/p' digit+ >mark_b1 %mark_b2;
|
128
|
-
comment_id = 'comment #' digit+ >mark_a1 %mark_a2;
|
129
|
-
pool_id = 'pool #' digit+ >mark_a1 %mark_a2;
|
130
|
-
user_id = 'user #' digit+ >mark_a1 %mark_a2;
|
131
|
-
artist_id = 'artist #' digit+ >mark_a1 %mark_a2;
|
132
|
-
github_issue_id = 'issue #' digit+ >mark_a1 %mark_a2;
|
133
|
-
pixiv_id = 'pixiv #' digit+ >mark_a1 %mark_a2;
|
134
|
-
pixiv_paged_id = 'pixiv #' digit+ >mark_a1 %mark_a2 '/p' digit+ >mark_b1 %mark_b2;
|
132
|
+
post_id = 'post #'i digit+ >mark_a1 %mark_a2;
|
133
|
+
forum_post_id = 'forum #'i digit+ >mark_a1 %mark_a2;
|
134
|
+
forum_topic_id = 'topic #'i digit+ >mark_a1 %mark_a2;
|
135
|
+
forum_topic_paged_id = 'topic #'i digit+ >mark_a1 %mark_a2 '/p' digit+ >mark_b1 %mark_b2;
|
136
|
+
comment_id = 'comment #'i digit+ >mark_a1 %mark_a2;
|
137
|
+
pool_id = 'pool #'i digit+ >mark_a1 %mark_a2;
|
138
|
+
user_id = 'user #'i digit+ >mark_a1 %mark_a2;
|
139
|
+
artist_id = 'artist #'i digit+ >mark_a1 %mark_a2;
|
140
|
+
github_issue_id = 'issue #'i digit+ >mark_a1 %mark_a2;
|
141
|
+
pixiv_id = 'pixiv #'i digit+ >mark_a1 %mark_a2;
|
142
|
+
pixiv_paged_id = 'pixiv #'i digit+ >mark_a1 %mark_a2 '/p' digit+ >mark_b1 %mark_b2;
|
135
143
|
|
136
144
|
ws = ' ' | '\t';
|
137
|
-
header = 'h' [123456] >mark_a1 %mark_a2 '.' ws
|
145
|
+
header = 'h' [123456] >mark_a1 %mark_a2 '.' ws*;
|
138
146
|
aliased_expand = '[expand=' (nonbracket+ >mark_a1 %mark_a2) ']';
|
139
147
|
|
140
148
|
list_item = '*'+ >mark_a1 %mark_a2 ws+ nonnewline+ >mark_b1 %mark_b2;
|
@@ -307,7 +315,7 @@ inline := |*
|
|
307
315
|
}
|
308
316
|
|
309
317
|
append(sm, true, "<a href=\"");
|
310
|
-
|
318
|
+
append_segment_html_escaped(sm, sm->b1, sm->b2 - sm->d);
|
311
319
|
append(sm, true, "\">");
|
312
320
|
append_segment_html_escaped(sm, sm->a1, sm->a2 - 1);
|
313
321
|
append(sm, true, "</a>");
|
@@ -319,7 +327,7 @@ inline := |*
|
|
319
327
|
|
320
328
|
bracketed_textile_link => {
|
321
329
|
append(sm, true, "<a href=\"");
|
322
|
-
|
330
|
+
append_segment_html_escaped(sm, sm->b1, sm->b2 - 1);
|
323
331
|
append(sm, true, "\">");
|
324
332
|
append_segment_html_escaped(sm, sm->a1, sm->a2 - 1);
|
325
333
|
append(sm, true, "</a>");
|
@@ -335,7 +343,7 @@ inline := |*
|
|
335
343
|
}
|
336
344
|
|
337
345
|
append(sm, true, "<a href=\"");
|
338
|
-
|
346
|
+
append_segment_html_escaped(sm, sm->ts, sm->te - sm->d);
|
339
347
|
append(sm, true, "\">");
|
340
348
|
append_segment_html_escaped(sm, sm->ts, sm->te - sm->d);
|
341
349
|
append(sm, true, "</a>");
|
@@ -371,17 +379,20 @@ inline := |*
|
|
371
379
|
}
|
372
380
|
};
|
373
381
|
|
374
|
-
list_item => {
|
382
|
+
newline list_item => {
|
375
383
|
g_debug("inline list");
|
376
384
|
|
377
|
-
if (dstack_check(sm,
|
385
|
+
if (dstack_check(sm, BLOCK_LI)) {
|
386
|
+
g_debug(" rewind li");
|
387
|
+
dstack_rewind(sm);
|
388
|
+
} else if (dstack_check(sm, BLOCK_P)) {
|
378
389
|
g_debug(" rewind p");
|
379
390
|
dstack_rewind(sm);
|
380
391
|
}
|
381
392
|
|
382
|
-
g_debug("
|
383
|
-
fexec sm->ts;
|
384
|
-
|
393
|
+
g_debug(" next list");
|
394
|
+
fexec sm->ts + 1;
|
395
|
+
fnext list;
|
385
396
|
};
|
386
397
|
|
387
398
|
'[b]' => {
|
@@ -446,10 +457,10 @@ inline := |*
|
|
446
457
|
};
|
447
458
|
|
448
459
|
'[/tn]' => {
|
460
|
+
dstack_close_before_block(sm);
|
461
|
+
|
449
462
|
if (dstack_check(sm, BLOCK_TN)) {
|
450
463
|
dstack_pop(sm);
|
451
|
-
append_closing_p(sm);
|
452
|
-
append_newline(sm);
|
453
464
|
fret;
|
454
465
|
} else if (dstack_check(sm, INLINE_TN)) {
|
455
466
|
dstack_pop(sm);
|
@@ -469,25 +480,17 @@ inline := |*
|
|
469
480
|
|
470
481
|
'[quote]' => {
|
471
482
|
g_debug("inline [quote]");
|
472
|
-
|
473
|
-
if (dstack_check(sm, BLOCK_P)) {
|
474
|
-
g_debug(" pop dstack");
|
475
|
-
g_debug(" print </p>");
|
476
|
-
|
477
|
-
dstack_pop(sm);
|
478
|
-
append_closing_p(sm);
|
479
|
-
append_newline(sm);
|
480
|
-
}
|
481
|
-
|
483
|
+
dstack_close_before_block(sm);
|
482
484
|
fexec sm->ts;
|
483
485
|
fret;
|
484
486
|
};
|
485
487
|
|
486
488
|
'[/quote]' space* => {
|
487
489
|
g_debug("inline [/quote]");
|
490
|
+
dstack_close_before_block(sm);
|
488
491
|
|
489
|
-
if (dstack_check(sm,
|
490
|
-
|
492
|
+
if (dstack_check(sm, BLOCK_LI)) {
|
493
|
+
dstack_close_list(sm);
|
491
494
|
}
|
492
495
|
|
493
496
|
if (dstack_check(sm, BLOCK_QUOTE)) {
|
@@ -507,24 +510,19 @@ inline := |*
|
|
507
510
|
|
508
511
|
'[/spoiler]' => {
|
509
512
|
g_debug("inline [/spoiler]");
|
513
|
+
dstack_close_before_block(sm);
|
510
514
|
|
511
515
|
if (dstack_check(sm, INLINE_SPOILER)) {
|
512
516
|
g_debug(" pop dstack");
|
513
517
|
g_debug(" print </span>");
|
514
518
|
dstack_pop(sm);
|
515
519
|
append(sm, true, "</span>");
|
516
|
-
} else if (dstack_check(sm,
|
520
|
+
} else if (dstack_check(sm, BLOCK_SPOILER)) {
|
517
521
|
g_debug(" pop dstack");
|
518
|
-
g_debug(" print </
|
522
|
+
g_debug(" print </div>");
|
519
523
|
g_debug(" return");
|
520
524
|
dstack_pop(sm);
|
521
|
-
dstack_pop(sm);
|
522
|
-
append_newline(sm);
|
523
|
-
append_closing_p(sm);
|
524
525
|
append_block(sm, "</div>");
|
525
|
-
append_newline(sm);
|
526
|
-
append_newline(sm);
|
527
|
-
|
528
526
|
fret;
|
529
527
|
} else {
|
530
528
|
append_block(sm, "[/spoiler]");
|
@@ -539,17 +537,10 @@ inline := |*
|
|
539
537
|
};
|
540
538
|
|
541
539
|
'[/expand]' => {
|
542
|
-
|
543
|
-
append_closing_p(sm);
|
544
|
-
append_newline(sm);
|
545
|
-
dstack_pop(sm);
|
546
|
-
}
|
540
|
+
dstack_close_before_block(sm);
|
547
541
|
|
548
542
|
if (dstack_check(sm, BLOCK_EXPAND)) {
|
549
|
-
append_newline(sm);
|
550
543
|
append_block(sm, "</div></div>");
|
551
|
-
append_newline(sm);
|
552
|
-
append_newline(sm);
|
553
544
|
dstack_pop(sm);
|
554
545
|
fret;
|
555
546
|
} else {
|
@@ -565,9 +556,7 @@ inline := |*
|
|
565
556
|
'[/th]' => {
|
566
557
|
if (dstack_check(sm, BLOCK_TH)) {
|
567
558
|
dstack_pop(sm);
|
568
|
-
append_newline(sm);
|
569
559
|
append_block(sm, "</th>");
|
570
|
-
append_newline(sm);
|
571
560
|
fret;
|
572
561
|
} else {
|
573
562
|
append_block(sm, "[/th]");
|
@@ -577,9 +566,7 @@ inline := |*
|
|
577
566
|
'[/td]' => {
|
578
567
|
if (dstack_check(sm, BLOCK_TD)) {
|
579
568
|
dstack_pop(sm);
|
580
|
-
append_newline(sm);
|
581
569
|
append_block(sm, "</td>");
|
582
|
-
append_newline(sm);
|
583
570
|
fret;
|
584
571
|
} else {
|
585
572
|
append_block(sm, "[/td]");
|
@@ -599,10 +586,7 @@ inline := |*
|
|
599
586
|
g_debug(" return");
|
600
587
|
|
601
588
|
if (sm->list_mode) {
|
602
|
-
|
603
|
-
dstack_rewind(sm);
|
604
|
-
}
|
605
|
-
|
589
|
+
dstack_close_list(sm);
|
606
590
|
sm->list_mode = false;
|
607
591
|
}
|
608
592
|
|
@@ -613,16 +597,21 @@ inline := |*
|
|
613
597
|
newline => {
|
614
598
|
g_debug("inline newline");
|
615
599
|
|
616
|
-
if (sm->
|
600
|
+
if (sm->header_mode) {
|
601
|
+
sm->header_mode = false;
|
617
602
|
dstack_rewind(sm);
|
603
|
+
fret;
|
618
604
|
} else {
|
619
605
|
append(sm, true, "<br>");
|
620
|
-
append_newline(sm);
|
621
606
|
}
|
622
607
|
};
|
623
608
|
|
609
|
+
'\r' => {
|
610
|
+
append_c(sm, ' ');
|
611
|
+
};
|
612
|
+
|
624
613
|
any => {
|
625
|
-
g_debug("inline
|
614
|
+
g_debug("inline char: %c", fc);
|
626
615
|
append_c_html_escaped(sm, fc);
|
627
616
|
};
|
628
617
|
*|;
|
@@ -651,10 +640,7 @@ nodtext := |*
|
|
651
640
|
'[/nodtext]' => {
|
652
641
|
if (dstack_check(sm, BLOCK_NODTEXT)) {
|
653
642
|
dstack_pop(sm);
|
654
|
-
|
655
|
-
append_closing_p(sm);
|
656
|
-
append_newline(sm);
|
657
|
-
append_newline(sm);
|
643
|
+
append_block(sm, "</p>");
|
658
644
|
fret;
|
659
645
|
} else if (dstack_check(sm, INLINE_NODTEXT)) {
|
660
646
|
dstack_pop(sm);
|
@@ -677,17 +663,13 @@ nodtext := |*
|
|
677
663
|
table := |*
|
678
664
|
'[thead]' => {
|
679
665
|
dstack_push(sm, &BLOCK_THEAD);
|
680
|
-
append_newline(sm);
|
681
666
|
append_block(sm, "<thead>");
|
682
|
-
append_newline(sm);
|
683
667
|
};
|
684
668
|
|
685
669
|
'[/thead]' => {
|
686
670
|
if (dstack_check(sm, BLOCK_THEAD)) {
|
687
671
|
dstack_pop(sm);
|
688
|
-
append_newline(sm);
|
689
672
|
append_block(sm, "</thead>");
|
690
|
-
append_newline(sm);
|
691
673
|
} else {
|
692
674
|
append(sm, true, "[/thead]");
|
693
675
|
}
|
@@ -695,17 +677,13 @@ table := |*
|
|
695
677
|
|
696
678
|
'[tbody]' => {
|
697
679
|
dstack_push(sm, &BLOCK_TBODY);
|
698
|
-
append_newline(sm);
|
699
680
|
append_block(sm, "<tbody>");
|
700
|
-
append_newline(sm);
|
701
681
|
};
|
702
682
|
|
703
683
|
'[/tbody]' => {
|
704
684
|
if (dstack_check(sm, BLOCK_TBODY)) {
|
705
685
|
dstack_pop(sm);
|
706
|
-
append_newline(sm);
|
707
686
|
append_block(sm, "</tbody>");
|
708
|
-
append_newline(sm);
|
709
687
|
} else {
|
710
688
|
append(sm, true, "[/tbody]");
|
711
689
|
}
|
@@ -713,25 +691,19 @@ table := |*
|
|
713
691
|
|
714
692
|
'[th]' => {
|
715
693
|
dstack_push(sm, &BLOCK_TH);
|
716
|
-
append_newline(sm);
|
717
694
|
append_block(sm, "<th>");
|
718
|
-
append_newline(sm);
|
719
695
|
fcall inline;
|
720
696
|
};
|
721
697
|
|
722
698
|
'[tr]' => {
|
723
699
|
dstack_push(sm, &BLOCK_TR);
|
724
|
-
append_newline(sm);
|
725
700
|
append_block(sm, "<tr>");
|
726
|
-
append_newline(sm);
|
727
701
|
};
|
728
702
|
|
729
703
|
'[/tr]' => {
|
730
704
|
if (dstack_check(sm, BLOCK_TR)) {
|
731
705
|
dstack_pop(sm);
|
732
|
-
append_newline(sm);
|
733
706
|
append_block(sm, "</tr>");
|
734
|
-
append_newline(sm);
|
735
707
|
} else {
|
736
708
|
append(sm, true, "[/tr]");
|
737
709
|
}
|
@@ -739,19 +711,14 @@ table := |*
|
|
739
711
|
|
740
712
|
'[td]' => {
|
741
713
|
dstack_push(sm, &BLOCK_TD);
|
742
|
-
append_newline(sm);
|
743
714
|
append_block(sm, "<td>");
|
744
|
-
append_newline(sm);
|
745
715
|
fcall inline;
|
746
716
|
};
|
747
717
|
|
748
718
|
'[/table]' => {
|
749
719
|
if (dstack_check(sm, BLOCK_TABLE)) {
|
750
720
|
dstack_pop(sm);
|
751
|
-
append_newline(sm);
|
752
721
|
append_block(sm, "</table>");
|
753
|
-
append_newline(sm);
|
754
|
-
append_newline(sm);
|
755
722
|
fret;
|
756
723
|
} else {
|
757
724
|
append(sm, true, "[/table]");
|
@@ -769,8 +736,8 @@ table := |*
|
|
769
736
|
list := |*
|
770
737
|
list_item => {
|
771
738
|
int prev_nest = sm->list_nest;
|
739
|
+
append_closing_p_if(sm);
|
772
740
|
g_debug("list start");
|
773
|
-
|
774
741
|
sm->list_mode = true;
|
775
742
|
sm->list_nest = sm->a2 - sm->a1;
|
776
743
|
fexec sm->b1;
|
@@ -781,7 +748,6 @@ list := |*
|
|
781
748
|
g_debug(" dstack push ul");
|
782
749
|
g_debug(" print <ul>");
|
783
750
|
append_block(sm, "<ul>");
|
784
|
-
append_newline(sm);
|
785
751
|
dstack_push(sm, &BLOCK_UL);
|
786
752
|
}
|
787
753
|
} else if (sm->list_nest < prev_nest) {
|
@@ -792,7 +758,6 @@ list := |*
|
|
792
758
|
g_debug(" print </ul>");
|
793
759
|
dstack_pop(sm);
|
794
760
|
append_block(sm, "</ul>");
|
795
|
-
append_newline(sm);
|
796
761
|
}
|
797
762
|
}
|
798
763
|
}
|
@@ -809,7 +774,7 @@ list := |*
|
|
809
774
|
|
810
775
|
# exit list
|
811
776
|
(newline{2,} | '\0') => {
|
812
|
-
|
777
|
+
dstack_close_list(sm);
|
813
778
|
fexec sm->ts;
|
814
779
|
fret;
|
815
780
|
};
|
@@ -831,135 +796,128 @@ main := |*
|
|
831
796
|
header = '6';
|
832
797
|
}
|
833
798
|
|
834
|
-
append_newline(sm);
|
835
|
-
append_newline(sm);
|
836
|
-
if (!sm->f_strip) {
|
837
|
-
append(sm, true, "<h");
|
838
|
-
append_c(sm, header);
|
839
|
-
append_c(sm, '>');
|
840
|
-
}
|
841
|
-
append_segment(sm, false, sm->b1, sm->b2 - 1);
|
842
799
|
if (!sm->f_strip) {
|
843
|
-
|
844
|
-
|
845
|
-
|
800
|
+
switch (header) {
|
801
|
+
case '1':
|
802
|
+
dstack_push(sm, &BLOCK_H1);
|
803
|
+
append_block(sm, "<h1>");
|
804
|
+
break;
|
805
|
+
|
806
|
+
case '2':
|
807
|
+
dstack_push(sm, &BLOCK_H2);
|
808
|
+
append_block(sm, "<h2>");
|
809
|
+
break;
|
810
|
+
|
811
|
+
case '3':
|
812
|
+
dstack_push(sm, &BLOCK_H3);
|
813
|
+
append_block(sm, "<h3>");
|
814
|
+
break;
|
815
|
+
|
816
|
+
case '4':
|
817
|
+
dstack_push(sm, &BLOCK_H4);
|
818
|
+
append_block(sm, "<h4>");
|
819
|
+
break;
|
820
|
+
|
821
|
+
case '5':
|
822
|
+
dstack_push(sm, &BLOCK_H5);
|
823
|
+
append_block(sm, "<h5>");
|
824
|
+
break;
|
825
|
+
|
826
|
+
case '6':
|
827
|
+
dstack_push(sm, &BLOCK_H6);
|
828
|
+
append_block(sm, "<h6>");
|
829
|
+
break;
|
830
|
+
}
|
846
831
|
}
|
847
|
-
|
848
|
-
|
832
|
+
|
833
|
+
sm->header_mode = true;
|
834
|
+
fcall inline;
|
849
835
|
};
|
850
836
|
|
851
837
|
'[quote]' space* => {
|
852
838
|
g_debug("block [quote]");
|
853
839
|
g_debug(" push quote");
|
854
|
-
g_debug(" push p");
|
855
840
|
g_debug(" print <blockquote>");
|
856
|
-
|
857
|
-
g_debug(" call inline");
|
858
|
-
|
841
|
+
dstack_close_before_block(sm);
|
859
842
|
dstack_push(sm, &BLOCK_QUOTE);
|
860
|
-
|
861
|
-
append_newline(sm);
|
862
|
-
append_newline(sm);
|
863
|
-
append_block(sm, "<blockquote><p>");
|
864
|
-
append_newline(sm);
|
865
|
-
fcall inline;
|
843
|
+
append_block(sm, "<blockquote>");
|
866
844
|
};
|
867
845
|
|
868
846
|
'[spoiler]' space* => {
|
869
847
|
g_debug("block [spoiler]");
|
870
848
|
g_debug(" push spoiler");
|
871
|
-
g_debug(" push p");
|
872
849
|
g_debug(" print <div>");
|
873
|
-
|
874
|
-
g_debug(" call inline");
|
850
|
+
dstack_close_before_block(sm);
|
875
851
|
dstack_push(sm, &BLOCK_SPOILER);
|
876
|
-
|
877
|
-
append_newline(sm);
|
878
|
-
append_newline(sm);
|
879
|
-
append_block(sm, "<div class=\"spoiler\"><p>");
|
880
|
-
append_newline(sm);
|
881
|
-
fcall inline;
|
852
|
+
append_block(sm, "<div class=\"spoiler\">");
|
882
853
|
};
|
883
854
|
|
884
855
|
'[/spoiler]' => {
|
885
|
-
|
886
|
-
|
887
|
-
}
|
888
|
-
|
856
|
+
g_debug("block [/spoiler]");
|
857
|
+
dstack_close_before_block(sm);
|
889
858
|
if (dstack_check(sm, BLOCK_SPOILER)) {
|
859
|
+
g_debug(" rewind");
|
890
860
|
dstack_rewind(sm);
|
891
861
|
}
|
892
862
|
};
|
893
863
|
|
894
864
|
'[code]' space* => {
|
865
|
+
g_debug("block [code]");
|
866
|
+
dstack_close_before_block(sm);
|
895
867
|
dstack_push(sm, &BLOCK_CODE);
|
896
|
-
append_newline(sm);
|
897
|
-
append_newline(sm);
|
898
868
|
append_block(sm, "<pre>");
|
899
|
-
append_newline(sm);
|
900
869
|
fcall code;
|
901
870
|
};
|
902
871
|
|
903
872
|
'[expand]' space* => {
|
873
|
+
g_debug("block [expand]");
|
874
|
+
dstack_close_before_block(sm);
|
904
875
|
dstack_push(sm, &BLOCK_EXPAND);
|
905
|
-
dstack_push(sm, &BLOCK_P);
|
906
|
-
append_newline(sm);
|
907
|
-
append_newline(sm);
|
908
876
|
append_block(sm, "<div class=\"expandable\"><div class=\"expandable-header\">");
|
909
877
|
append_block(sm, "<input type=\"button\" value=\"Show\" class=\"expandable-button\"/></div>");
|
910
878
|
append_block(sm, "<div class=\"expandable-content\">");
|
911
|
-
append_block(sm, "<p>");
|
912
|
-
append_newline(sm);
|
913
|
-
fcall inline;
|
914
879
|
};
|
915
880
|
|
916
881
|
aliased_expand space* => {
|
882
|
+
g_debug("block [expand=]");
|
883
|
+
dstack_close_before_block(sm);
|
917
884
|
dstack_push(sm, &BLOCK_EXPAND);
|
918
|
-
dstack_push(sm, &BLOCK_P);
|
919
|
-
append_newline(sm);
|
920
|
-
append_newline(sm);
|
921
885
|
append_block(sm, "<div class=\"expandable\"><div class=\"expandable-header\">");
|
922
886
|
append(sm, true, "<span>");
|
923
|
-
append_segment_html_escaped(sm, sm->a1, sm->a2);
|
887
|
+
append_segment_html_escaped(sm, sm->a1, sm->a2 - 1);
|
924
888
|
append(sm, true, "</span>");
|
925
889
|
append_block(sm, "<input type=\"button\" value=\"Show\" class=\"expandable-button\"/></div>");
|
926
890
|
append_block(sm, "<div class=\"expandable-content\">");
|
927
|
-
append_newline(sm);
|
928
|
-
fcall inline;
|
929
891
|
};
|
930
892
|
|
931
893
|
'[nodtext]' space* => {
|
894
|
+
g_debug("block [nodtext]");
|
895
|
+
dstack_close_before_block(sm);
|
932
896
|
dstack_push(sm, &BLOCK_NODTEXT);
|
933
|
-
|
897
|
+
dstack_push(sm, &BLOCK_P);
|
934
898
|
append_block(sm, "<p>");
|
935
899
|
fcall nodtext;
|
936
900
|
};
|
937
901
|
|
938
902
|
'[table]' => {
|
903
|
+
dstack_close_before_block(sm);
|
939
904
|
dstack_push(sm, &BLOCK_TABLE);
|
940
|
-
append_newline(sm);
|
941
|
-
append_newline(sm);
|
942
905
|
append_block(sm, "<table class=\"striped\">");
|
943
906
|
fcall table;
|
944
907
|
};
|
945
908
|
|
946
909
|
'[tn]' => {
|
947
910
|
dstack_push(sm, &BLOCK_TN);
|
948
|
-
append_newline(sm);
|
949
|
-
append_newline(sm);
|
950
911
|
append_block(sm, "<p class=\"tn\">");
|
951
912
|
fcall inline;
|
952
913
|
};
|
953
914
|
|
954
915
|
list_item => {
|
955
|
-
g_debug("
|
916
|
+
g_debug("block list");
|
917
|
+
g_debug(" call list");
|
956
918
|
sm->list_nest = 0;
|
957
919
|
sm->list_mode = true;
|
958
|
-
|
959
|
-
g_debug(" pop dstack");
|
960
|
-
dstack_rewind(sm);
|
961
|
-
}
|
962
|
-
g_debug(" call list");
|
920
|
+
append_closing_p_if(sm);
|
963
921
|
fexec sm->ts;
|
964
922
|
fcall list;
|
965
923
|
};
|
@@ -972,9 +930,12 @@ main := |*
|
|
972
930
|
|
973
931
|
newline{2,} => {
|
974
932
|
g_debug("block newline2");
|
975
|
-
|
976
|
-
|
933
|
+
|
934
|
+
if (sm->header_mode) {
|
935
|
+
sm->header_mode = false;
|
977
936
|
dstack_rewind(sm);
|
937
|
+
} else {
|
938
|
+
dstack_close_before_block(sm);
|
978
939
|
}
|
979
940
|
};
|
980
941
|
|
@@ -983,14 +944,13 @@ main := |*
|
|
983
944
|
};
|
984
945
|
|
985
946
|
any => {
|
986
|
-
g_debug("block
|
947
|
+
g_debug("block char: %c", fc);
|
987
948
|
fhold;
|
988
949
|
|
989
950
|
if (g_queue_is_empty(sm->dstack) || dstack_check(sm, BLOCK_QUOTE) || dstack_check(sm, BLOCK_SPOILER) || dstack_check(sm, BLOCK_EXPAND)) {
|
990
951
|
g_debug(" push p");
|
991
952
|
g_debug(" print <p>");
|
992
953
|
dstack_push(sm, &BLOCK_P);
|
993
|
-
append_newline(sm);
|
994
954
|
append_block(sm, "<p>");
|
995
955
|
}
|
996
956
|
|
@@ -1010,18 +970,44 @@ static inline void underscore_string(char * str, size_t len) {
|
|
1010
970
|
}
|
1011
971
|
}
|
1012
972
|
|
973
|
+
static inline void dstack_push(StateMachine * sm, const int * element) {
|
974
|
+
g_queue_push_tail(sm->dstack, (gpointer)element);
|
975
|
+
}
|
976
|
+
|
977
|
+
static inline int * dstack_pop(StateMachine * sm) {
|
978
|
+
return g_queue_pop_tail(sm->dstack);
|
979
|
+
}
|
980
|
+
|
981
|
+
static inline int * dstack_peek(StateMachine * sm) {
|
982
|
+
return g_queue_peek_tail(sm->dstack);
|
983
|
+
}
|
984
|
+
|
985
|
+
static inline bool dstack_search(StateMachine * sm, const int * element) {
|
986
|
+
return g_queue_find(sm->dstack, (gconstpointer)element);
|
987
|
+
}
|
988
|
+
|
989
|
+
static inline bool dstack_check(StateMachine * sm, int expected_element) {
|
990
|
+
int * top = dstack_peek(sm);
|
991
|
+
return top && *top == expected_element;
|
992
|
+
}
|
993
|
+
|
994
|
+
static inline bool dstack_check2(StateMachine * sm, int expected_element) {
|
995
|
+
int * top2 = NULL;
|
996
|
+
|
997
|
+
if (sm->dstack->length < 2) {
|
998
|
+
return false;
|
999
|
+
}
|
1000
|
+
|
1001
|
+
top2 = g_queue_peek_nth(sm->dstack, sm->dstack->length - 2);
|
1002
|
+
return top2 && *top2 == expected_element;
|
1003
|
+
}
|
1004
|
+
|
1013
1005
|
static inline void append(StateMachine * sm, bool is_markup, const char * s) {
|
1014
1006
|
if (!(is_markup && sm->f_strip)) {
|
1015
1007
|
sm->output = g_string_append(sm->output, s);
|
1016
1008
|
}
|
1017
1009
|
}
|
1018
1010
|
|
1019
|
-
static inline void append_newline(StateMachine * sm) {
|
1020
|
-
#if (PRETTY_PRINT)
|
1021
|
-
g_string_append_c(sm->output, '\n');
|
1022
|
-
#endif
|
1023
|
-
}
|
1024
|
-
|
1025
1011
|
static inline void append_c(StateMachine * sm, char s) {
|
1026
1012
|
sm->output = g_string_append_c(sm->output, s);
|
1027
1013
|
}
|
@@ -1040,6 +1026,10 @@ static inline void append_c_html_escaped(StateMachine * sm, char s) {
|
|
1040
1026
|
sm->output = g_string_append(sm->output, "&");
|
1041
1027
|
break;
|
1042
1028
|
|
1029
|
+
// case '"':
|
1030
|
+
// sm->output = g_string_append(sm->output, """);
|
1031
|
+
// break;
|
1032
|
+
|
1043
1033
|
default:
|
1044
1034
|
sm->output = g_string_append_c(sm->output, s);
|
1045
1035
|
break;
|
@@ -1057,11 +1047,16 @@ static inline void append_segment_uri_escaped(StateMachine * sm, const char * a,
|
|
1057
1047
|
return;
|
1058
1048
|
}
|
1059
1049
|
|
1050
|
+
char * segment1 = NULL;
|
1051
|
+
char * segment2 = NULL;
|
1060
1052
|
GString * segment_string = g_string_new_len(a, b - a + 1);
|
1061
|
-
|
1062
|
-
|
1053
|
+
|
1054
|
+
segment1 = g_uri_escape_string(segment_string->str, NULL, TRUE);
|
1055
|
+
segment2 = g_markup_escape_text(segment1, -1);
|
1056
|
+
sm->output = g_string_append(sm->output, segment2);
|
1063
1057
|
g_string_free(segment_string, TRUE);
|
1064
|
-
g_free(
|
1058
|
+
g_free(segment1);
|
1059
|
+
g_free(segment2);
|
1065
1060
|
}
|
1066
1061
|
|
1067
1062
|
static inline void append_segment_html_escaped(StateMachine * sm, const char * a, const char * b) {
|
@@ -1080,46 +1075,28 @@ static inline void append_block(StateMachine * sm, const char * s) {
|
|
1080
1075
|
}
|
1081
1076
|
}
|
1082
1077
|
|
1083
|
-
static
|
1078
|
+
static void append_closing_p(StateMachine * sm) {
|
1084
1079
|
size_t i = sm->output->len;
|
1085
1080
|
|
1086
1081
|
if (i > 4 && !strncmp(sm->output->str + i - 4, "<br>", 4)) {
|
1087
1082
|
sm->output = g_string_truncate(sm->output, sm->output->len - 4);
|
1088
1083
|
}
|
1089
1084
|
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
g_queue_push_tail(sm->dstack, (gpointer)element);
|
1095
|
-
}
|
1096
|
-
|
1097
|
-
static inline int * dstack_pop(StateMachine * sm) {
|
1098
|
-
return g_queue_pop_tail(sm->dstack);
|
1099
|
-
}
|
1100
|
-
|
1101
|
-
static inline int * dstack_peek(StateMachine * sm) {
|
1102
|
-
return g_queue_peek_tail(sm->dstack);
|
1103
|
-
}
|
1104
|
-
|
1105
|
-
static inline bool dstack_search(StateMachine * sm, const int * element) {
|
1106
|
-
return g_queue_find(sm->dstack, (gconstpointer)element);
|
1107
|
-
}
|
1085
|
+
if (i > 3 && !strncmp(sm->output->str + i - 3, "<p>", 3)) {
|
1086
|
+
sm->output = g_string_truncate(sm->output, sm->output->len - 3);
|
1087
|
+
return;
|
1088
|
+
}
|
1108
1089
|
|
1109
|
-
|
1110
|
-
int * top = dstack_peek(sm);
|
1111
|
-
return top && *top == expected_element;
|
1090
|
+
append_block(sm, "</p>");
|
1112
1091
|
}
|
1113
1092
|
|
1114
|
-
static
|
1115
|
-
|
1116
|
-
|
1117
|
-
if (sm->dstack->length < 2) {
|
1118
|
-
return false;
|
1093
|
+
static void append_closing_p_if(StateMachine * sm) {
|
1094
|
+
if (!dstack_check(sm, BLOCK_P)) {
|
1095
|
+
return;
|
1119
1096
|
}
|
1120
1097
|
|
1121
|
-
|
1122
|
-
|
1098
|
+
dstack_pop(sm);
|
1099
|
+
append_closing_p(sm);
|
1123
1100
|
}
|
1124
1101
|
|
1125
1102
|
static void dstack_rewind(StateMachine * sm) {
|
@@ -1131,7 +1108,6 @@ static void dstack_rewind(StateMachine * sm) {
|
|
1131
1108
|
|
1132
1109
|
if (*element == BLOCK_P) {
|
1133
1110
|
append_closing_p(sm);
|
1134
|
-
append_newline(sm);
|
1135
1111
|
|
1136
1112
|
} else if (*element == INLINE_SPOILER) {
|
1137
1113
|
append(sm, true, "</span>");
|
@@ -1147,7 +1123,6 @@ static void dstack_rewind(StateMachine * sm) {
|
|
1147
1123
|
|
1148
1124
|
} else if (*element == BLOCK_NODTEXT) {
|
1149
1125
|
append_closing_p(sm);
|
1150
|
-
append_newline(sm);
|
1151
1126
|
|
1152
1127
|
} else if (*element == BLOCK_CODE) {
|
1153
1128
|
append_block(sm, "</pre>");
|
@@ -1174,7 +1149,6 @@ static void dstack_rewind(StateMachine * sm) {
|
|
1174
1149
|
|
1175
1150
|
} else if (*element == BLOCK_TN) {
|
1176
1151
|
append_closing_p(sm);
|
1177
|
-
append_newline(sm);
|
1178
1152
|
|
1179
1153
|
} else if (*element == BLOCK_TABLE) {
|
1180
1154
|
append_block(sm, "</table>");
|
@@ -1190,11 +1164,40 @@ static void dstack_rewind(StateMachine * sm) {
|
|
1190
1164
|
|
1191
1165
|
} else if (*element == BLOCK_UL) {
|
1192
1166
|
append_block(sm, "</ul>");
|
1193
|
-
append_newline(sm);
|
1194
1167
|
|
1195
1168
|
} else if (*element == BLOCK_LI) {
|
1196
1169
|
append_block(sm, "</li>");
|
1197
|
-
|
1170
|
+
|
1171
|
+
} else if (*element == BLOCK_H6) {
|
1172
|
+
append_block(sm, "</h6>");
|
1173
|
+
|
1174
|
+
} else if (*element == BLOCK_H5) {
|
1175
|
+
append_block(sm, "</h5>");
|
1176
|
+
|
1177
|
+
} else if (*element == BLOCK_H4) {
|
1178
|
+
append_block(sm, "</h4>");
|
1179
|
+
|
1180
|
+
} else if (*element == BLOCK_H3) {
|
1181
|
+
append_block(sm, "</h3>");
|
1182
|
+
|
1183
|
+
} else if (*element == BLOCK_H2) {
|
1184
|
+
append_block(sm, "</h2>");
|
1185
|
+
|
1186
|
+
} else if (*element == BLOCK_H1) {
|
1187
|
+
append_block(sm, "</h1>");
|
1188
|
+
}
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
static void dstack_close_before_block(StateMachine * sm) {
|
1192
|
+
while (1) {
|
1193
|
+
if (dstack_check(sm, BLOCK_P)) {
|
1194
|
+
dstack_pop(sm);
|
1195
|
+
append_closing_p(sm);
|
1196
|
+
} else if (dstack_check(sm, BLOCK_LI) || dstack_check(sm, BLOCK_UL)) {
|
1197
|
+
dstack_rewind(sm);
|
1198
|
+
} else {
|
1199
|
+
return;
|
1200
|
+
}
|
1198
1201
|
}
|
1199
1202
|
}
|
1200
1203
|
|
@@ -1204,6 +1207,12 @@ static void dstack_close(StateMachine * sm) {
|
|
1204
1207
|
}
|
1205
1208
|
}
|
1206
1209
|
|
1210
|
+
static void dstack_close_list(StateMachine * sm) {
|
1211
|
+
while (dstack_check(sm, BLOCK_LI) || dstack_check(sm, BLOCK_UL)) {
|
1212
|
+
dstack_rewind(sm);
|
1213
|
+
}
|
1214
|
+
}
|
1215
|
+
|
1207
1216
|
static inline bool is_boundary_c(char c) {
|
1208
1217
|
switch (c) {
|
1209
1218
|
case ':':
|
@@ -1222,9 +1231,15 @@ static inline bool is_boundary_c(char c) {
|
|
1222
1231
|
return false;
|
1223
1232
|
}
|
1224
1233
|
|
1234
|
+
static bool print_machine(StateMachine * sm) {
|
1235
|
+
printf("p=%c\n", *sm->p);
|
1236
|
+
return true;
|
1237
|
+
}
|
1238
|
+
|
1225
1239
|
static void init_machine(StateMachine * sm, VALUE input) {
|
1226
1240
|
size_t output_length = 0;
|
1227
1241
|
sm->p = RSTRING_PTR(input);
|
1242
|
+
sm->pb = sm->p;
|
1228
1243
|
sm->pe = sm->p + RSTRING_LEN(input);
|
1229
1244
|
sm->eof = sm->pe;
|
1230
1245
|
sm->ts = NULL;
|
@@ -1247,6 +1262,9 @@ static void init_machine(StateMachine * sm, VALUE input) {
|
|
1247
1262
|
sm->dstack = g_queue_new();
|
1248
1263
|
sm->list_nest = 0;
|
1249
1264
|
sm->list_mode = false;
|
1265
|
+
sm->header_mode = false;
|
1266
|
+
sm->d = 0;
|
1267
|
+
sm->b = 0;
|
1250
1268
|
}
|
1251
1269
|
|
1252
1270
|
static void free_machine(StateMachine * sm) {
|