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 }