1 module hunt.markdown.internal.inline.EmphasisDelimiterProcessor;
2 
3 import hunt.markdown.node.Emphasis;
4 import hunt.markdown.node.Node;
5 import hunt.markdown.node.StrongEmphasis;
6 import hunt.markdown.node.Text;
7 import hunt.markdown.parser.delimiter.DelimiterProcessor;
8 import hunt.markdown.parser.delimiter.DelimiterRun;
9 
10 abstract class EmphasisDelimiterProcessor : DelimiterProcessor {
11 
12     private char delimiterChar;
13 
14     protected this(char delimiterChar) {
15         this.delimiterChar = delimiterChar;
16     }
17 
18     override public char getOpeningCharacter() {
19         return delimiterChar;
20     }
21 
22     override public char getClosingCharacter() {
23         return delimiterChar;
24     }
25 
26     override public int getMinLength() {
27         return 1;
28     }
29 
30     override public int getDelimiterUse(DelimiterRun opener, DelimiterRun closer) {
31         // "multiple of 3" rule for internal delimiter runs
32         if ((opener.canClose() || closer.canOpen()) && (opener.originalLength() + closer.originalLength()) % 3 == 0) {
33             return 0;
34         }
35         // calculate actual number of delimiters used from this closer
36         if (opener.length >= 2 && closer.length >= 2) {
37             return 2;
38         } else {
39             return 1;
40         }
41     }
42 
43     override public void process(Text opener, Text closer, int delimiterUse) {
44         string singleDelimiter = "" ~ (getOpeningCharacter());
45         Node emphasis = delimiterUse == 1
46                 ? new Emphasis(singleDelimiter)
47                 : new StrongEmphasis(singleDelimiter ~ singleDelimiter);
48 
49         Node tmp = opener.getNext();
50         while (tmp !is null && tmp != closer) {
51             Node next = tmp.getNext();
52             emphasis.appendChild(tmp);
53             tmp = next;
54         }
55 
56         opener.insertAfter(emphasis);
57     }
58 }