Fossil SCM

In the Markdown formatter, bring emphasis markup into closer alignment with the CommonMark spec. In particular, this should allow underscores in the middle of identifiers to be rendered correctly without escapes.

drh 2020-06-11 21:03 trunk
Commit 37806e85d2601bfbf3f4689a78de9a239873299c54034652742fdfdf67312b54
2 files changed +48 -17 +55 -25
+48 -17
--- src/markdown.c
+++ src/markdown.c
@@ -555,10 +555,43 @@
555555
}
556556
}
557557
return 0;
558558
}
559559
560
+/* CommonMark defines separate "right-flanking" and "left-flanking"
561
+** deliminators for emphasis. Whether a deliminator is left- or
562
+** right-flanking, or both, or neither depends on the characters
563
+** immediately before and after.
564
+**
565
+** before after example left-flanking right-flanking
566
+** ------ ----- ------- ------------- --------------
567
+** space space * no no
568
+** space punct *) yes no
569
+** space alnum *x yes no
570
+** punct space (* no yes
571
+** punct punct (*) yes yes
572
+** punct alnum (*x yes no
573
+** alnum space a* no yes
574
+** alnum punct a*( no yes
575
+** alnum alnum a*x yes yes
576
+**
577
+** The following routines determine whether a delimitor is left
578
+** or right flanking.
579
+*/
580
+static int left_flanking(char before, char after){
581
+ if( fossil_isspace(after) ) return 0;
582
+ if( fossil_isalnum(after) ) return 1;
583
+ if( fossil_isalnum(before) ) return 0;
584
+ return 1;
585
+}
586
+static int right_flanking(char before, char after){
587
+ if( fossil_isspace(before) ) return 0;
588
+ if( fossil_isalnum(before) ) return 1;
589
+ if( fossil_isalnum(after) ) return 0;
590
+ return 1;
591
+}
592
+
560593
561594
/* parse_emph1 -- parsing single emphasis */
562595
/* closed by a symbol not preceded by whitespace and not followed by symbol */
563596
static size_t parse_emph1(
564597
struct Blob *ob,
@@ -568,10 +601,11 @@
568601
char c
569602
){
570603
size_t i = 0, len;
571604
struct Blob *work = 0;
572605
int r;
606
+ char after;
573607
574608
if( !rndr->make.emphasis ) return 0;
575609
576610
/* skipping one symbol if coming from emph3 */
577611
if( size>1 && data[0]==c && data[1]==c ) i = 1;
@@ -584,14 +618,14 @@
584618
585619
if( i+1<size && data[i+1]==c ){
586620
i++;
587621
continue;
588622
}
623
+ after = i+1<size ? data[i+1] : ' ';
589624
if( data[i]==c
590
- && data[i-1]!=' '
591
- && data[i-1]!='\t'
592
- && data[i-1]!='\n'
625
+ && right_flanking(data[i-1],after)
626
+ && (c!='_' || !fossil_isalnum(after))
593627
&& !too_deep(rndr)
594628
){
595629
work = new_work_buffer(rndr);
596630
parse_inline(work, rndr, data, i);
597631
r = rndr->make.emphasis(ob, work, c, rndr->make.opaque);
@@ -612,24 +646,24 @@
612646
char c
613647
){
614648
size_t i = 0, len;
615649
struct Blob *work = 0;
616650
int r;
651
+ char after;
617652
618653
if( !rndr->make.double_emphasis ) return 0;
619654
620655
while( i<size ){
621656
len = find_emph_char(data+i, size-i, c);
622657
if( !len ) return 0;
623658
i += len;
659
+ after = i+2<size ? data[i+2] : ' ';
624660
if( i+1<size
625661
&& data[i]==c
626662
&& data[i+1]==c
627
- && i
628
- && data[i-1]!=' '
629
- && data[i-1]!='\t'
630
- && data[i-1]!='\n'
663
+ && right_flanking(data[i-1],after)
664
+ && (c!='_' || !fossil_isalnum(after))
631665
&& !too_deep(rndr)
632666
){
633667
work = new_work_buffer(rndr);
634668
parse_inline(work, rndr, data, i);
635669
r = rndr->make.double_emphasis(ob, work, c, rndr->make.opaque);
@@ -697,39 +731,36 @@
697731
char *data,
698732
size_t offset,
699733
size_t size
700734
){
701735
char c = data[0];
736
+ char before = offset>0 ? data[-1] : ' ';
702737
size_t ret;
703738
704739
if( size>2 && data[1]!=c ){
705
- /* whitespace cannot follow an opening emphasis */
706
- if( data[1]==' '
707
- || data[1]=='\t'
708
- || data[1]=='\n'
740
+ if( !left_flanking(before, data[1])
741
+ || (c=='_' && fossil_isalnum(before))
709742
|| (ret = parse_emph1(ob, rndr, data+1, size-1, c))==0
710743
){
711744
return 0;
712745
}
713746
return ret+1;
714747
}
715748
716749
if( size>3 && data[1]==c && data[2]!=c ){
717
- if( data[2]==' '
718
- || data[2]=='\t'
719
- || data[2]=='\n'
750
+ if( !left_flanking(before, data[2])
751
+ || (c=='_' && fossil_isalnum(before))
720752
|| (ret = parse_emph2(ob, rndr, data+2, size-2, c))==0
721753
){
722754
return 0;
723755
}
724756
return ret+2;
725757
}
726758
727759
if( size>4 && data[1]==c && data[2]==c && data[3]!=c ){
728
- if( data[3]==' '
729
- || data[3]=='\t'
730
- || data[3]=='\n'
760
+ if( !left_flanking(before, data[3])
761
+ || (c=='_' && fossil_isalnum(before))
731762
|| (ret = parse_emph3(ob, rndr, data+3, size-3, c))==0
732763
){
733764
return 0;
734765
}
735766
return ret+3;
736767
--- src/markdown.c
+++ src/markdown.c
@@ -555,10 +555,43 @@
555 }
556 }
557 return 0;
558 }
559
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
561 /* parse_emph1 -- parsing single emphasis */
562 /* closed by a symbol not preceded by whitespace and not followed by symbol */
563 static size_t parse_emph1(
564 struct Blob *ob,
@@ -568,10 +601,11 @@
568 char c
569 ){
570 size_t i = 0, len;
571 struct Blob *work = 0;
572 int r;
 
573
574 if( !rndr->make.emphasis ) return 0;
575
576 /* skipping one symbol if coming from emph3 */
577 if( size>1 && data[0]==c && data[1]==c ) i = 1;
@@ -584,14 +618,14 @@
584
585 if( i+1<size && data[i+1]==c ){
586 i++;
587 continue;
588 }
 
589 if( data[i]==c
590 && data[i-1]!=' '
591 && data[i-1]!='\t'
592 && data[i-1]!='\n'
593 && !too_deep(rndr)
594 ){
595 work = new_work_buffer(rndr);
596 parse_inline(work, rndr, data, i);
597 r = rndr->make.emphasis(ob, work, c, rndr->make.opaque);
@@ -612,24 +646,24 @@
612 char c
613 ){
614 size_t i = 0, len;
615 struct Blob *work = 0;
616 int r;
 
617
618 if( !rndr->make.double_emphasis ) return 0;
619
620 while( i<size ){
621 len = find_emph_char(data+i, size-i, c);
622 if( !len ) return 0;
623 i += len;
 
624 if( i+1<size
625 && data[i]==c
626 && data[i+1]==c
627 && i
628 && data[i-1]!=' '
629 && data[i-1]!='\t'
630 && data[i-1]!='\n'
631 && !too_deep(rndr)
632 ){
633 work = new_work_buffer(rndr);
634 parse_inline(work, rndr, data, i);
635 r = rndr->make.double_emphasis(ob, work, c, rndr->make.opaque);
@@ -697,39 +731,36 @@
697 char *data,
698 size_t offset,
699 size_t size
700 ){
701 char c = data[0];
 
702 size_t ret;
703
704 if( size>2 && data[1]!=c ){
705 /* whitespace cannot follow an opening emphasis */
706 if( data[1]==' '
707 || data[1]=='\t'
708 || data[1]=='\n'
709 || (ret = parse_emph1(ob, rndr, data+1, size-1, c))==0
710 ){
711 return 0;
712 }
713 return ret+1;
714 }
715
716 if( size>3 && data[1]==c && data[2]!=c ){
717 if( data[2]==' '
718 || data[2]=='\t'
719 || data[2]=='\n'
720 || (ret = parse_emph2(ob, rndr, data+2, size-2, c))==0
721 ){
722 return 0;
723 }
724 return ret+2;
725 }
726
727 if( size>4 && data[1]==c && data[2]==c && data[3]!=c ){
728 if( data[3]==' '
729 || data[3]=='\t'
730 || data[3]=='\n'
731 || (ret = parse_emph3(ob, rndr, data+3, size-3, c))==0
732 ){
733 return 0;
734 }
735 return ret+3;
736
--- src/markdown.c
+++ src/markdown.c
@@ -555,10 +555,43 @@
555 }
556 }
557 return 0;
558 }
559
560 /* CommonMark defines separate "right-flanking" and "left-flanking"
561 ** deliminators for emphasis. Whether a deliminator is left- or
562 ** right-flanking, or both, or neither depends on the characters
563 ** immediately before and after.
564 **
565 ** before after example left-flanking right-flanking
566 ** ------ ----- ------- ------------- --------------
567 ** space space * no no
568 ** space punct *) yes no
569 ** space alnum *x yes no
570 ** punct space (* no yes
571 ** punct punct (*) yes yes
572 ** punct alnum (*x yes no
573 ** alnum space a* no yes
574 ** alnum punct a*( no yes
575 ** alnum alnum a*x yes yes
576 **
577 ** The following routines determine whether a delimitor is left
578 ** or right flanking.
579 */
580 static int left_flanking(char before, char after){
581 if( fossil_isspace(after) ) return 0;
582 if( fossil_isalnum(after) ) return 1;
583 if( fossil_isalnum(before) ) return 0;
584 return 1;
585 }
586 static int right_flanking(char before, char after){
587 if( fossil_isspace(before) ) return 0;
588 if( fossil_isalnum(before) ) return 1;
589 if( fossil_isalnum(after) ) return 0;
590 return 1;
591 }
592
593
594 /* parse_emph1 -- parsing single emphasis */
595 /* closed by a symbol not preceded by whitespace and not followed by symbol */
596 static size_t parse_emph1(
597 struct Blob *ob,
@@ -568,10 +601,11 @@
601 char c
602 ){
603 size_t i = 0, len;
604 struct Blob *work = 0;
605 int r;
606 char after;
607
608 if( !rndr->make.emphasis ) return 0;
609
610 /* skipping one symbol if coming from emph3 */
611 if( size>1 && data[0]==c && data[1]==c ) i = 1;
@@ -584,14 +618,14 @@
618
619 if( i+1<size && data[i+1]==c ){
620 i++;
621 continue;
622 }
623 after = i+1<size ? data[i+1] : ' ';
624 if( data[i]==c
625 && right_flanking(data[i-1],after)
626 && (c!='_' || !fossil_isalnum(after))
 
627 && !too_deep(rndr)
628 ){
629 work = new_work_buffer(rndr);
630 parse_inline(work, rndr, data, i);
631 r = rndr->make.emphasis(ob, work, c, rndr->make.opaque);
@@ -612,24 +646,24 @@
646 char c
647 ){
648 size_t i = 0, len;
649 struct Blob *work = 0;
650 int r;
651 char after;
652
653 if( !rndr->make.double_emphasis ) return 0;
654
655 while( i<size ){
656 len = find_emph_char(data+i, size-i, c);
657 if( !len ) return 0;
658 i += len;
659 after = i+2<size ? data[i+2] : ' ';
660 if( i+1<size
661 && data[i]==c
662 && data[i+1]==c
663 && right_flanking(data[i-1],after)
664 && (c!='_' || !fossil_isalnum(after))
 
 
665 && !too_deep(rndr)
666 ){
667 work = new_work_buffer(rndr);
668 parse_inline(work, rndr, data, i);
669 r = rndr->make.double_emphasis(ob, work, c, rndr->make.opaque);
@@ -697,39 +731,36 @@
731 char *data,
732 size_t offset,
733 size_t size
734 ){
735 char c = data[0];
736 char before = offset>0 ? data[-1] : ' ';
737 size_t ret;
738
739 if( size>2 && data[1]!=c ){
740 if( !left_flanking(before, data[1])
741 || (c=='_' && fossil_isalnum(before))
 
 
742 || (ret = parse_emph1(ob, rndr, data+1, size-1, c))==0
743 ){
744 return 0;
745 }
746 return ret+1;
747 }
748
749 if( size>3 && data[1]==c && data[2]!=c ){
750 if( !left_flanking(before, data[2])
751 || (c=='_' && fossil_isalnum(before))
 
752 || (ret = parse_emph2(ob, rndr, data+2, size-2, c))==0
753 ){
754 return 0;
755 }
756 return ret+2;
757 }
758
759 if( size>4 && data[1]==c && data[2]==c && data[3]!=c ){
760 if( !left_flanking(before, data[3])
761 || (c=='_' && fossil_isalnum(before))
 
762 || (ret = parse_emph3(ob, rndr, data+3, size-3, c))==0
763 ){
764 return 0;
765 }
766 return ret+3;
767
--- test/markdown-test2.md
+++ test/markdown-test2.md
@@ -20,31 +20,60 @@
2020
}
2121
</style>
2222
2323
See <https://spec.commonmark.org/0.29/#emphasis-and-strong-emphasis>
2424
25
-| Id | Source Text | Actual Rendering | Correct Rendering |
----------------------------------------------------------------------------
26
-| 1:| `*foo bar*` | *foo bar* | <em>foo bar</em> |
27
-| 2:| `a * foo bar*` | a * foo bar* | a &#42; foo bar&#42; |
28
-| 3:| `a*"foo"*` | a*"foo"* | a&#42;&quot;foo&quot;&#42; |
29
-| 4:| `* a *` | * a * | &#42; a &#42; |
30
-| 5:| `foo*bar*` | foo*bar* | foo<em>bar</em> |
31
-| 6:| `5*6*78` | 5*6*78 | 5<em>6</em>78 |
32
-| 7:| `_foo bar_` | _foo bar_ | <em>foo bar</em> |
33
-| 8:| `_ foo bar_` | _ foo bar_ | &#95; foo bar&#95; |
34
-| 9:| `a_"foo"_` | a_"foo"_ | a&#95;&quot;foo&quot;&#95; |
35
-| 10:| `foo_bar_` | foo_bar_ | foo&#95;bar&#95; |
36
-| 11:| `5_6_78` | 5_6_78 | 5&#95;6&#95;78 |
37
-| 12:| `пристаням_стремятся_` | пристаням_стремятся_ | пристаням&#95;стремятся&#95; |
38
-| 13:| `aa_"bb"_cc` | aa_"bb"_cc | aa&#95;&quot;bb&quot;&#95;cc |
39
-| 14:| `foo-_(bar)_` | foo-_(bar)_ | foo-<em>(bar)</em> |
40
-| 15:| `*(*foo` | *(*foo | &#42;(&#42;foo |
41
-| 16:| `*(*foo*)*` | *(*foo*)* | <em>(</em>foo<em>)</em> |
42
-| 17:| `*foo*bar` | *foo*bar | <em>foo</em>bar |
43
-| 18:| `_foo bar _` | _foo bar _ | &#95;foo bar &#95; |
44
-| 19:| `_(_foo)` | _(_foo) | &#95;(&#95;foo) |
45
-| 20:| `_(_foo_)_` | _(_foo_)_ | <em>(</em>foo<em>)</em> |
46
-| 21:| `_foo_bar` | _foo_bar | &#95;foo&#95;bar |
47
-| 22:| `_пристаням_стремятся` | _пристаням_стремятся | \_пристаням\_стремятся |
48
-| 23:| `_foo_bar_baz_` | _foo_bar_baz_ | <em>foo&#95;bar&#95;baz</em> |
49
-| 24:| `_(bar)_` | _(bar)_ | <em>(bar)</em> |
25
+| Id | Source Text | Actual Rendering | Correct Rendering |
26
+-----------------------------------------------------------------------------
27
+| 1:| `*foo bar*` | *foo bar* | <em>foo bar</em> |
28
+| 2:| `a * foo bar*` | a * foo bar* | a &#42; foo bar&#42; |
29
+| 3:| `a*"foo"*` | a*"foo"* | a&#42;&quot;foo&quot;&#42; |
30
+| 4:| `* a *` | * a * | &#42; a &#42; |
31
+| 5:| `foo*bar*` | foo*bar* | foo<em>bar</em> |
32
+| 6:| `5*6*78` | 5*6*78 | 5<em>6</em>78 |
33
+| 7:| `_foo bar_` | _foo bar_ | <em>foo bar</em> |
34
+| 8:| `_ foo bar_` | _ foo bar_ | &#95; foo bar&#95; |
35
+| 9:| `a_"foo"_` | a_"foo"_ | a&#95;&quot;foo&quot;&#95; |
36
+| 10:| `foo_bar_` | foo_bar_ | foo&#95;bar&#95; |
37
+| 11:| `5_6_78` | 5_6_78 | 5&#95;6&#95;78 |
38
+| 12:| `aa_"bb"_cc` | aa_"bb"_cc | aa&#95;&quot;bb&quot;&#95;cc |
39
+| 13:| `foo-_(bar)_` | foo-_(bar)_ | foo-<em>(bar)</em> |
40
+| 14:| `*(*foo` | *(*foo | &#42;(&#42;foo |
41
+| 15:| `*(*foo*)*` | *(*foo*)* | <em>(<em>foo</em>)</em> |
42
+| 16:| `*foo*bar` | *foo*bar | <em>foo</em>bar |
43
+| 17:| `_foo bar _` | _foo bar _ | &#95;foo bar &#95; |
44
+| 18:| `_(_foo)` | _(_foo) | &#95;(&#95;foo) |
45
+| 19:| `_(_foo_)_` | _(_foo_)_ | <em>(</em>foo<em>)</em> |
46
+| 20:| `_foo_bar` | _foo_bar | &#95;foo&#95;bar |
47
+| 21:| `_foo_bar_baz_` | _foo_bar_baz_ | <em>foo&#95;bar&#95;baz</em> |
48
+| 22:| `foo_bar_baz` | foo_bar_baz | foo&#95;bar&#95;baz |
49
+| 23:| `_(bar)_` | _(bar)_ | <em>(bar)</em> |
50
+
51
+
52
+# Strong emphasis
53
+
54
+
55
+| Id | Source Text | Actual Rendering | Correct Rendering |
56
+-------------------------------------------------------------------------------------------
57
+| 1:| `**foo bar**` | **foo bar** | <strong>foo bar</strong> |
58
+| 2:| `a ** foo bar**` | a ** foo bar** | a &#42;&#42; foo bar&#42;&#42; |
59
+| 3:| `a**"foo"**` | a**"foo"** | a&#42;&#42;&quot;foo&quot;&#42;&#42; |
60
+| 4:| `** a **` | ** a ** | &#42;&#42; a &#42;&#42; |
61
+| 5:| `foo**bar**` | foo**bar** | foo<strong>bar</strong> |
62
+| 6:| `5**6**78` | 5**6**78 | 5<strong>6</strong>78 |
63
+| 7:| `__foo bar__` | __foo bar__ | <strong>foo bar</strong> |
64
+| 8:| `__ foo bar__` | __ foo bar__ | &#95;&#95; foo bar&#95;&#95; |
65
+| 9:| `a__"foo"__` | a__"foo"__ | a&#95;&#95;&quot;foo&quot;&#95;&#95; |
66
+| 10:| `foo__bar__` | foo__bar__ | foo&#95;&#95;bar&#95;&#95; |
67
+| 11:| `5__6__78` | 5__6__78 | 5&#95;&#95;6&#95;&#95;78 |
68
+| 12:| `aa__"bb"__cc` | aa__"bb"__cc | aa&#95;&#95;&quot;bb&quot;&#95;&#95;cc |
69
+| 13:| `foo-__(bar)__` | foo-__(bar)__ | foo-<strong>(bar)</strong> |
70
+| 14:| `**(**foo` | **(**foo | &#42;&#42;(&#42;&#42;foo |
71
+| 15:| `**(**foo**)**` | **(**foo**)** | <strong>(<strong>foo</strong>)</strong> |
72
+| 16:| `**foo**bar` | **foo**bar | <strong>foo</strong>bar |
73
+| 17:| `__foo bar __` | __foo bar __ | &#95;&#95;foo bar &#95;&#95; |
74
+| 18:| `__(__foo)` | __(__foo) | &#95;&#95;(&#95;&#95;foo) |
75
+| 19:| `__(__foo__)__` | __(__foo__)__ | <strong>(</strong>foo<strong>)</strong> |
76
+| 20:| `__foo__bar` | __foo__bar | &#95;&#95;foo&#95;&#95;bar |
77
+| 21:| `__foo__bar__baz__` | __foo__bar__baz__ | <strong>foo&#95;&#95;bar&#95;&#95;baz</strong> |
78
+| 22:| `foo__bar__baz` | foo__bar__baz | foo&#95;&#95;bar&#95;&#95;baz |
79
+| 23:| `__(bar)__` | __(bar)__ | <strong>(bar)</strong> |
5080
--- test/markdown-test2.md
+++ test/markdown-test2.md
@@ -20,31 +20,60 @@
20 }
21 </style>
22
23 See <https://spec.commonmark.org/0.29/#emphasis-and-strong-emphasis>
24
25 | Id | Source Text | Actual Rendering | Correct Rendering |
----------------------------------------------------------------------------
26 | 1:| `*foo bar*` | *foo bar* | <em>foo bar</em> |
27 | 2:| `a * foo bar*` | a * foo bar* | a &#42; foo bar&#42; |
28 | 3:| `a*"foo"*` | a*"foo"* | a&#42;&quot;foo&quot;&#42; |
29 | 4:| `* a *` | * a * | &#42; a &#42; |
30 | 5:| `foo*bar*` | foo*bar* | foo<em>bar</em> |
31 | 6:| `5*6*78` | 5*6*78 | 5<em>6</em>78 |
32 | 7:| `_foo bar_` | _foo bar_ | <em>foo bar</em> |
33 | 8:| `_ foo bar_` | _ foo bar_ | &#95; foo bar&#95; |
34 | 9:| `a_"foo"_` | a_"foo"_ | a&#95;&quot;foo&quot;&#95; |
35 | 10:| `foo_bar_` | foo_bar_ | foo&#95;bar&#95; |
36 | 11:| `5_6_78` | 5_6_78 | 5&#95;6&#95;78 |
37 | 12:| `пристаням_стремятся_` | пристаням_стремятся_ | пристаням&#95;стремятся&#95; |
38 | 13:| `aa_"bb"_cc` | aa_"bb"_cc | aa&#95;&quot;bb&quot;&#95;cc |
39 | 14:| `foo-_(bar)_` | foo-_(bar)_ | foo-<em>(bar)</em> |
40 | 15:| `*(*foo` | *(*foo | &#42;(&#42;foo |
41 | 16:| `*(*foo*)*` | *(*foo*)* | <em>(</em>foo<em>)</em> |
42 | 17:| `*foo*bar` | *foo*bar | <em>foo</em>bar |
43 | 18:| `_foo bar _` | _foo bar _ | &#95;foo bar &#95; |
44 | 19:| `_(_foo)` | _(_foo) | &#95;(&#95;foo) |
45 | 20:| `_(_foo_)_` | _(_foo_)_ | <em>(</em>foo<em>)</em> |
46 | 21:| `_foo_bar` | _foo_bar | &#95;foo&#95;bar |
47 | 22:| `_пристаням_стремятся` | _пристаням_стремятся | \_пристаням\_стремятся |
48 | 23:| `_foo_bar_baz_` | _foo_bar_baz_ | <em>foo&#95;bar&#95;baz</em> |
49 | 24:| `_(bar)_` | _(bar)_ | <em>(bar)</em> |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
--- test/markdown-test2.md
+++ test/markdown-test2.md
@@ -20,31 +20,60 @@
20 }
21 </style>
22
23 See <https://spec.commonmark.org/0.29/#emphasis-and-strong-emphasis>
24
 
----------------------------------------------------------------------------
25 | Id | Source Text | Actual Rendering | Correct Rendering |
26 -----------------------------------------------------------------------------
27 | 1:| `*foo bar*` | *foo bar* | <em>foo bar</em> |
28 | 2:| `a * foo bar*` | a * foo bar* | a &#42; foo bar&#42; |
29 | 3:| `a*"foo"*` | a*"foo"* | a&#42;&quot;foo&quot;&#42; |
30 | 4:| `* a *` | * a * | &#42; a &#42; |
31 | 5:| `foo*bar*` | foo*bar* | foo<em>bar</em> |
32 | 6:| `5*6*78` | 5*6*78 | 5<em>6</em>78 |
33 | 7:| `_foo bar_` | _foo bar_ | <em>foo bar</em> |
34 | 8:| `_ foo bar_` | _ foo bar_ | &#95; foo bar&#95; |
35 | 9:| `a_"foo"_` | a_"foo"_ | a&#95;&quot;foo&quot;&#95; |
36 | 10:| `foo_bar_` | foo_bar_ | foo&#95;bar&#95; |
37 | 11:| `5_6_78` | 5_6_78 | 5&#95;6&#95;78 |
38 | 12:| `aa_"bb"_cc` | aa_"bb"_cc | aa&#95;&quot;bb&quot;&#95;cc |
39 | 13:| `foo-_(bar)_` | foo-_(bar)_ | foo-<em>(bar)</em> |
40 | 14:| `*(*foo` | *(*foo | &#42;(&#42;foo |
41 | 15:| `*(*foo*)*` | *(*foo*)* | <em>(<em>foo</em>)</em> |
42 | 16:| `*foo*bar` | *foo*bar | <em>foo</em>bar |
43 | 17:| `_foo bar _` | _foo bar _ | &#95;foo bar &#95; |
44 | 18:| `_(_foo)` | _(_foo) | &#95;(&#95;foo) |
45 | 19:| `_(_foo_)_` | _(_foo_)_ | <em>(</em>foo<em>)</em> |
46 | 20:| `_foo_bar` | _foo_bar | &#95;foo&#95;bar |
47 | 21:| `_foo_bar_baz_` | _foo_bar_baz_ | <em>foo&#95;bar&#95;baz</em> |
48 | 22:| `foo_bar_baz` | foo_bar_baz | foo&#95;bar&#95;baz |
49 | 23:| `_(bar)_` | _(bar)_ | <em>(bar)</em> |
50
51
52 # Strong emphasis
53
54
55 | Id | Source Text | Actual Rendering | Correct Rendering |
56 -------------------------------------------------------------------------------------------
57 | 1:| `**foo bar**` | **foo bar** | <strong>foo bar</strong> |
58 | 2:| `a ** foo bar**` | a ** foo bar** | a &#42;&#42; foo bar&#42;&#42; |
59 | 3:| `a**"foo"**` | a**"foo"** | a&#42;&#42;&quot;foo&quot;&#42;&#42; |
60 | 4:| `** a **` | ** a ** | &#42;&#42; a &#42;&#42; |
61 | 5:| `foo**bar**` | foo**bar** | foo<strong>bar</strong> |
62 | 6:| `5**6**78` | 5**6**78 | 5<strong>6</strong>78 |
63 | 7:| `__foo bar__` | __foo bar__ | <strong>foo bar</strong> |
64 | 8:| `__ foo bar__` | __ foo bar__ | &#95;&#95; foo bar&#95;&#95; |
65 | 9:| `a__"foo"__` | a__"foo"__ | a&#95;&#95;&quot;foo&quot;&#95;&#95; |
66 | 10:| `foo__bar__` | foo__bar__ | foo&#95;&#95;bar&#95;&#95; |
67 | 11:| `5__6__78` | 5__6__78 | 5&#95;&#95;6&#95;&#95;78 |
68 | 12:| `aa__"bb"__cc` | aa__"bb"__cc | aa&#95;&#95;&quot;bb&quot;&#95;&#95;cc |
69 | 13:| `foo-__(bar)__` | foo-__(bar)__ | foo-<strong>(bar)</strong> |
70 | 14:| `**(**foo` | **(**foo | &#42;&#42;(&#42;&#42;foo |
71 | 15:| `**(**foo**)**` | **(**foo**)** | <strong>(<strong>foo</strong>)</strong> |
72 | 16:| `**foo**bar` | **foo**bar | <strong>foo</strong>bar |
73 | 17:| `__foo bar __` | __foo bar __ | &#95;&#95;foo bar &#95;&#95; |
74 | 18:| `__(__foo)` | __(__foo) | &#95;&#95;(&#95;&#95;foo) |
75 | 19:| `__(__foo__)__` | __(__foo__)__ | <strong>(</strong>foo<strong>)</strong> |
76 | 20:| `__foo__bar` | __foo__bar | &#95;&#95;foo&#95;&#95;bar |
77 | 21:| `__foo__bar__baz__` | __foo__bar__baz__ | <strong>foo&#95;&#95;bar&#95;&#95;baz</strong> |
78 | 22:| `foo__bar__baz` | foo__bar__baz | foo&#95;&#95;bar&#95;&#95;baz |
79 | 23:| `__(bar)__` | __(bar)__ | <strong>(bar)</strong> |
80

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button