// Path: src/main/java/io/github/gitbucket/markedj/rule/FindFirstRule.java
// public class FindFirstRule implements Rule {
// 
//     private Pattern pattern;
// 
//     public FindFirstRule(String regex){
//         this.pattern = Pattern.compile(regex);
//     }
// 
//     public List<String> exec(String src) {
//         try {
//             Matcher matcher = pattern.matcher(src);
//             if (matcher.find()) {
//                 List<String> result = new ArrayList<>();
//                 for (int i = 0; i <= matcher.groupCount(); i++) {
//                     result.add(matcher.group(i));
//                 }
//                 return result;
//             }
//         } catch(StackOverflowError e){
//             // ignore
//         }
//         return Collections.emptyList();
//     }
// }
// 
// Path: src/main/java/io/github/gitbucket/markedj/rule/FindAllRule.java
// public class FindAllRule implements Rule {
// 
//     private Pattern pattern;
// 
//     public FindAllRule(String regex){
//         this.pattern = Pattern.compile(regex);
//     }
// 
//     public List<String> exec(String src) {
//         try {
//             Matcher matcher = pattern.matcher(src);
//             List<String> result = new ArrayList<>();
//             while (matcher.find()) {
//                 result.add(matcher.group(0));
//             }
//             if (!result.isEmpty()) {
//                 return result;
//             }
//         } catch(StackOverflowError e){
//             // ignore
//         }
//         return Collections.emptyList();
//     }
// }
// 
// Path: src/main/java/io/github/gitbucket/markedj/rule/NoopRule.java
// public class NoopRule implements Rule {
//     public List<String> exec(String src) {
//         return Collections.emptyList();
//     }
// }
// 
// Path: src/main/java/io/github/gitbucket/markedj/rule/Rule.java
// public interface Rule {
//     List<String> exec(String src);
// }


import io.github.gitbucket.markedj.rule.FindFirstRule;
import io.github.gitbucket.markedj.rule.FindAllRule;
import io.github.gitbucket.markedj.rule.NoopRule;
import io.github.gitbucket.markedj.rule.Rule;
import java.util.HashMap;
import java.util.Map;
    public static String DEF               = "^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +[\"(]([^\\n]+)[\")])? *(?:\\n+|$)";
    public static String BLOCK_HR          = "^( *[-*_]){3,} *(?:\\n+|$)";
    public static String BLOCK_HEADING     = "^ *(#{1,6}) *([^\\n]+?) *#* *(?:\\n+|$)";
    public static String BLOCK_LHEADING    = "^([^\\n]+)\\n *(=|-){2,} *(?:\\n+|$)";
    public static String BLOCK_BLOCKQUOTE  = "^( *>[^\\n]+(\\n(?!" + removeLineStart(DEF) + ")[^\\n]+)*\\n*)+";
    //public static String BLOCK_LIST        = "^( *)(" + BULLET + ") [\\s\\S]+?(?:" + HR + "|\\n+(?=" + removeLineStart(DEF) + ")|\\n{2,}(?! )(?!\\1" + BULLET + " )\\n*|\\s*$)";
    public static String BLOCK_LIST        = "^( *)(" + BULLET + ") [\\s\\S]+?(?:\\n{2,}(?! )(?!\\1" + BULLET + " )\\n*|\\s*$)";
    public static String BLOCK_DEF         = "^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +[\"(]([^\\n]+)[\")])? *(?:\\n+|$)";
    public static String BLOCK_PARAGRAPH   = "^((?:[^\\n]+\\n?(?!" + removeLineStart(BLOCK_HR) + "|" + removeLineStart(BLOCK_HEADING) + "|" + removeLineStart(BLOCK_LHEADING) + "|" + removeLineStart(BLOCK_BLOCKQUOTE) + "|<" + TAG + "|" + removeLineStart(BLOCK_DEF) + "))+)\\n*";
    public static String BLOCK_GFM_FENCES  = "^ *(`{3,}|~{3,})([ \\S]+)?\\n([\\s\\S]*?)\\s*\\1 *(?:\\n+|$)";

    public static Map<String, Rule> BLOCK_RULES = new HashMap<>();
    public static Map<String, Rule> BLOCK_GFM_RULES = new HashMap<>();
    public static Map<String, Rule> BLOCK_TABLE_RULES = new HashMap<>();

    static {
        BLOCK_RULES.put("newline", new FindFirstRule("^\n+"));
        BLOCK_RULES.put("code", new FindFirstRule("^( {4}[^\n]+\n*)+"));
        BLOCK_RULES.put("fences", new NoopRule());
        BLOCK_RULES.put("hr", new FindFirstRule(BLOCK_HR));
        BLOCK_RULES.put("heading", new FindFirstRule(BLOCK_HEADING));
        BLOCK_RULES.put("nptable", new NoopRule());
        BLOCK_RULES.put("lheading", new FindFirstRule(BLOCK_LHEADING));
        BLOCK_RULES.put("blockquote", new FindFirstRule(BLOCK_BLOCKQUOTE));
        BLOCK_RULES.put("list", new FindFirstRule(BLOCK_LIST));
        BLOCK_RULES.put("html", new FindFirstRule("^ *(?:" + COMMENT + " *(?:\\n|\\s*$)|" + CLOSED + " *(?:\\n{2,}|\\s*$)|" + CLOSING + " *(?:\\n{2,}|\\s*$))"));
        BLOCK_RULES.put("def", new FindFirstRule(BLOCK_DEF));
        BLOCK_RULES.put("table", new NoopRule());
        BLOCK_RULES.put("paragraph", new FindFirstRule(BLOCK_PARAGRAPH));
        BLOCK_RULES.put("text", new FindFirstRule("^[^\n]+"));
// Path: src/main/java/io/github/gitbucket/markedj/rule/FindFirstRule.java
// public class FindFirstRule implements Rule {
// 
//     private Pattern pattern;
// 
//     public FindFirstRule(String regex){
//         this.pattern = Pattern.compile(regex);
//     }
// 
//     public List<String> exec(String src) {
//         try {
//             Matcher matcher = pattern.matcher(src);
//             if (matcher.find()) {
//                 List<String> result = new ArrayList<>();
//                 for (int i = 0; i <= matcher.groupCount(); i++) {
//                     result.add(matcher.group(i));
//                 }
//                 return result;
//             }
//         } catch(StackOverflowError e){
//             // ignore
//         }
//         return Collections.emptyList();
//     }
// }
// 
// Path: src/main/java/io/github/gitbucket/markedj/rule/FindAllRule.java
// public class FindAllRule implements Rule {
// 
//     private Pattern pattern;
// 
//     public FindAllRule(String regex){
//         this.pattern = Pattern.compile(regex);
//     }
// 
//     public List<String> exec(String src) {
//         try {
//             Matcher matcher = pattern.matcher(src);
//             List<String> result = new ArrayList<>();
//             while (matcher.find()) {
//                 result.add(matcher.group(0));
//             }
//             if (!result.isEmpty()) {
//                 return result;
//             }
//         } catch(StackOverflowError e){
//             // ignore
//         }
//         return Collections.emptyList();
//     }
// }
// 
// Path: src/main/java/io/github/gitbucket/markedj/rule/NoopRule.java
// public class NoopRule implements Rule {
//     public List<String> exec(String src) {
//         return Collections.emptyList();
//     }
// }
// 
// Path: src/main/java/io/github/gitbucket/markedj/rule/Rule.java
// public interface Rule {
//     List<String> exec(String src);
// }


// Path: src/main/java/io/github/gitbucket/markedj/Grammer.java
import io.github.gitbucket.markedj.rule.FindFirstRule;
import io.github.gitbucket.markedj.rule.FindAllRule;
import io.github.gitbucket.markedj.rule.NoopRule;
import io.github.gitbucket.markedj.rule.Rule;
import java.util.HashMap;
import java.util.Map;

    public static String DEF               = "^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +[\"(]([^\\n]+)[\")])? *(?:\\n+|$)";
    public static String BLOCK_HR          = "^( *[-*_]){3,} *(?:\\n+|$)";
    public static String BLOCK_HEADING     = "^ *(#{1,6}) *([^\\n]+?) *#* *(?:\\n+|$)";
    public static String BLOCK_LHEADING    = "^([^\\n]+)\\n *(=|-){2,} *(?:\\n+|$)";
    public static String BLOCK_BLOCKQUOTE  = "^( *>[^\\n]+(\\n(?!" + removeLineStart(DEF) + ")[^\\n]+)*\\n*)+";
    //public static String BLOCK_LIST        = "^( *)(" + BULLET + ") [\\s\\S]+?(?:" + HR + "|\\n+(?=" + removeLineStart(DEF) + ")|\\n{2,}(?! )(?!\\1" + BULLET + " )\\n*|\\s*$)";
    public static String BLOCK_LIST        = "^( *)(" + BULLET + ") [\\s\\S]+?(?:\\n{2,}(?! )(?!\\1" + BULLET + " )\\n*|\\s*$)";
    public static String BLOCK_DEF         = "^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +[\"(]([^\\n]+)[\")])? *(?:\\n+|$)";
    public static String BLOCK_PARAGRAPH   = "^((?:[^\\n]+\\n?(?!" + removeLineStart(BLOCK_HR) + "|" + removeLineStart(BLOCK_HEADING) + "|" + removeLineStart(BLOCK_LHEADING) + "|" + removeLineStart(BLOCK_BLOCKQUOTE) + "|<" + TAG + "|" + removeLineStart(BLOCK_DEF) + "))+)\\n*";
    public static String BLOCK_GFM_FENCES  = "^ *(`{3,}|~{3,})([ \\S]+)?\\n([\\s\\S]*?)\\s*\\1 *(?:\\n+|$)";

    public static Map<String, Rule> BLOCK_RULES = new HashMap<>();
    public static Map<String, Rule> BLOCK_GFM_RULES = new HashMap<>();
    public static Map<String, Rule> BLOCK_TABLE_RULES = new HashMap<>();

    static {
        BLOCK_RULES.put("newline", new FindFirstRule("^\n+"));
        BLOCK_RULES.put("code", new FindFirstRule("^( {4}[^\n]+\n*)+"));
        BLOCK_RULES.put("fences", new NoopRule());
        BLOCK_RULES.put("hr", new FindFirstRule(BLOCK_HR));
        BLOCK_RULES.put("heading", new FindFirstRule(BLOCK_HEADING));
        BLOCK_RULES.put("nptable", new NoopRule());
        BLOCK_RULES.put("lheading", new FindFirstRule(BLOCK_LHEADING));
        BLOCK_RULES.put("blockquote", new FindFirstRule(BLOCK_BLOCKQUOTE));
        BLOCK_RULES.put("list", new FindFirstRule(BLOCK_LIST));
        BLOCK_RULES.put("html", new FindFirstRule("^ *(?:" + COMMENT + " *(?:\\n|\\s*$)|" + CLOSED + " *(?:\\n{2,}|\\s*$)|" + CLOSING + " *(?:\\n{2,}|\\s*$))"));
        BLOCK_RULES.put("def", new FindFirstRule(BLOCK_DEF));
        BLOCK_RULES.put("table", new NoopRule());
        BLOCK_RULES.put("paragraph", new FindFirstRule(BLOCK_PARAGRAPH));
        BLOCK_RULES.put("text", new FindFirstRule("^[^\n]+"));
        BLOCK_RULES.put("item", new FindAllRule(("(?m)^( *)(" + BULLET + ") [^\\n]*(?:\\n(?!\\1" + BULLET + " )[^\\n]*)*")));