1 module hunt.markdown.internal.BlockQuoteParser;
2 
3 import hunt.markdown.internal.util.Parsing;
4 import hunt.markdown.node.Block;
5 import hunt.markdown.node.BlockQuote;
6 import hunt.markdown.parser.block.AbstractBlockParser;
7 import hunt.markdown.parser.block.BlockContinue;
8 import hunt.markdown.parser.block.ParserState;
9 import hunt.markdown.parser.block.AbstractBlockParserFactory;
10 import hunt.markdown.parser.block.BlockStart;
11 import hunt.markdown.parser.block.MatchedBlockParser;
12 
13 class BlockQuoteParser : AbstractBlockParser {
14 
15     private BlockQuote block;
16 
17     this()
18     {
19         block = new BlockQuote();
20     }
21 
22     override public bool isContainer() {
23         return true;
24     }
25 
26     override public bool canContain(Block block) {
27         return true;
28     }
29 
30     override
31     public Block getBlock() {
32         return block;
33     }
34 
35     public BlockContinue tryContinue(ParserState state) {
36         int nextNonSpace = state.getNextNonSpaceIndex();
37         if (isMarker(state, nextNonSpace)) {
38             int newColumn = state.getColumn() + state.getIndent() + 1;
39             // optional following space or tab
40             if (Parsing.isSpaceOrTab(state.getLine(), nextNonSpace + 1)) {
41                 newColumn++;
42             }
43             return BlockContinue.atColumn(newColumn);
44         } else {
45             return BlockContinue.none();
46         }
47     }
48 
49     private static bool isMarker(ParserState state, int index) {
50         string line = state.getLine();
51         return state.getIndent() < Parsing.CODE_BLOCK_INDENT && index < line.length && line[index] == '>';
52     }
53 
54     public static class Factory : AbstractBlockParserFactory {
55         public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) {
56             int nextNonSpace = state.getNextNonSpaceIndex();
57             if (isMarker(state, nextNonSpace)) {
58                 int newColumn = state.getColumn() + state.getIndent() + 1;
59                 // optional following space or tab
60                 if (Parsing.isSpaceOrTab(state.getLine(), nextNonSpace + 1)) {
61                     newColumn++;
62                 }
63                 return BlockStart.of(new BlockQuoteParser()).atColumn(newColumn);
64             } else {
65                 return BlockStart.none();
66             }
67         }
68     }
69 }