1 module hunt.markdown.internal.ThematicBreakParser; 2 3 import hunt.markdown.node.Block; 4 import hunt.markdown.node.ThematicBreak; 5 import hunt.markdown.parser.block.AbstractBlockParser; 6 import hunt.markdown.parser.block.BlockContinue; 7 import hunt.markdown.parser.block.ParserState; 8 import hunt.markdown.parser.block.BlockStart; 9 import hunt.markdown.parser.block.MatchedBlockParser; 10 import hunt.markdown.parser.block.AbstractBlockParserFactory; 11 12 class ThematicBreakParser : AbstractBlockParser { 13 14 private ThematicBreak block; 15 16 this() 17 { 18 block = new ThematicBreak(); 19 } 20 21 override public Block getBlock() { 22 return block; 23 } 24 25 public BlockContinue tryContinue(ParserState state) { 26 // a horizontal rule can never container > 1 line, so fail to match 27 return BlockContinue.none(); 28 } 29 30 public static class Factory : AbstractBlockParserFactory { 31 32 public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) { 33 if (state.getIndent() >= 4) { 34 return BlockStart.none(); 35 } 36 int nextNonSpace = state.getNextNonSpaceIndex(); 37 string line = state.getLine(); 38 if (isThematicBreak(line, nextNonSpace)) { 39 return BlockStart.of(new ThematicBreakParser()).atIndex(cast(int)(line.length)); 40 } else { 41 return BlockStart.none(); 42 } 43 } 44 } 45 46 // spec: A line consisting of 0-3 spaces of indentation, followed by a sequence of three or more matching -, _, or * 47 // characters, each followed optionally by any number of spaces, forms a thematic break. 48 private static bool isThematicBreak(string line, int index) { 49 int dashes = 0; 50 int underscores = 0; 51 int asterisks = 0; 52 int length =cast(int)(line.length); 53 for (int i = index; i < length; i++) { 54 switch (line[i]) { 55 case '-': 56 dashes++; 57 break; 58 case '_': 59 underscores++; 60 break; 61 case '*': 62 asterisks++; 63 break; 64 case ' ': 65 case '\t': 66 // Allowed, even between markers 67 break; 68 default: 69 return false; 70 } 71 } 72 73 return ((dashes >= 3 && underscores == 0 && asterisks == 0) || 74 (underscores >= 3 && dashes == 0 && asterisks == 0) || 75 (asterisks >= 3 && dashes == 0 && underscores == 0)); 76 } 77 }