dtext_rb 1.0.2 → 1.0.3
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 +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) {
|