/**
  * Get block grammar rules for given options.
  *
  * @param  array $options
  * @return array
  */
 protected static function rules(array $options)
 {
     if (!static::$blocks) {
         $blocks = [];
         // normal
         $blocks['normal'] = ['blockquote' => '/^( *>[^\\n]+(\\n(?! *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +["(]([^\\n]+)[")])? *(?:\\n+|$))[^\\n]+)*\\n*)+/', 'bullet' => '/(?:[*+-]|\\d+\\.)/', 'code' => '/^( {4}[^\\n]+\\n*)+/', 'def' => '/^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +["(]([^\\n]+)[")])? *(?:\\n+|$)/', 'fences' => '/nooooop/', 'heading' => '/^ *(#{1,6}) *([^\\n]+?) *#* *(?:\\n+|$)/', 'hr' => '/^( *[-*_]){3,} *(?:\\n+|$)/', 'html' => '/^ *(?:<!--[\\s\\S]*?-->|<((?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:\\/|[^\\w\\s@]*@)\\b)[\\s\\S]+?<\\/\\1>|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:\\/|[^\\w\\s@]*@)\\b(?:"[^"]*"|\'[^\']*\'|[^\'">])*?>) *(?:\\n{2,}|\\s*$)/', 'item' => '/^( *)((?:[*+-]|\\d+\\.)) [^\\n]*(?:\\n(?!\\1(?:[*+-]|\\d+\\.) )[^\\n]*)*$/m', 'lheading' => '/^([^\\n]+)\\n *(=|-){2,} *(?:\\n+|$)/', 'list' => '/^( *)((?:[*+-]|\\d+\\.)) [\\s\\S]+?(?:\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))|\\n+(?= *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +["(]([^\\n]+)[")])? *(?:\\n+|$))|\\n{2,}(?! )(?!\\1(?:[*+-]|\\d+\\.) )\\n*|\\s*$)/', 'newline' => '/^\\n+/', 'nptable' => '/nooooop/', 'paragraph' => '/^((?:[^\\n]+\\n?(?!( *[-*_]){3,} *(?:\\n+|$)| *(#{1,6}) *([^\\n]+?) *#* *(?:\\n+|$)|([^\\n]+)\\n *(=|-){2,} *(?:\\n+|$)|( *>[^\\n]+(\\n(?! *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +["(]([^\\n]+)[")])? *(?:\\n+|$))[^\\n]+)*\\n*)+|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:\\/|[^\\w\\s@]*@)\\b| *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +["(]([^\\n]+)[")])? *(?:\\n+|$)))+)\\n*/', 'table' => '/nooooop/', 'text' => '/^[^\\n]+/'];
         // github flavored markdown
         $blocks['gfm'] = array_merge($blocks['normal'], ['fences' => '/^ *(`{3,}|~{3,}) *(\\S+)? *\\n([\\s\\S]+?)\\s*\\1 *(?:\\n+|$)/', 'paragraph' => '/^((?:[^\\n]+\\n?(?! *(`{3,}|~{3,}) *(\\S+)? *\\n([\\s\\S]+?)\\s*\\2 *(?:\\n+|$)|( *)((?:[*+-]|\\d+\\.)) [\\s\\S]+?(?:\\n+(?=\\3?(?:[-*_] *){3,}(?:\\n+|$))|\\n+(?= *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +["(]([^\\n]+)[")])? *(?:\\n+|$))|\\n{2,}(?! )(?!\\1(?:[*+-]|\\d+\\.) )\\n*|\\s*$)|( *[-*_]){3,} *(?:\\n+|$)| *(#{1,6}) *([^\\n]+?) *#* *(?:\\n+|$)|([^\\n]+)\\n *(=|-){2,} *(?:\\n+|$)|( *>[^\\n]+(\\n(?! *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +["(]([^\\n]+)[")])? *(?:\\n+|$))[^\\n]+)*\\n*)+|<(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:\\/|[^\\w\\s@]*@)\\b| *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +["(]([^\\n]+)[")])? *(?:\\n+|$)))+)\\n*/']);
         // github flavored markdown + tables
         $blocks['tables'] = array_merge($blocks['gfm'], ['nptable' => '/^ *(\\S.*\\|.*)\\n *([-:]+ *\\|[-| :]*)\\n((?:.*\\|.*(?:\\n|$))*)\\n*/', 'table' => '/^ *\\|(.+)\\n *\\|( *[-:]+[-| :]*)\\n((?: *\\|.*(?:\\n|$))*)\\n*/']);
         static::$blocks = $blocks;
     }
     $rules = static::$blocks['normal'];
     if ($options['gfm']) {
         if ($options['tables']) {
             $rules = static::$blocks['tables'];
         } else {
             $rules = static::$blocks['gfm'];
         }
     }
     return $rules;
 }
 /**
  * Flush all the block contents.
  *
  * @return void
  */
 public static function flushBlocks()
 {
     static::$blocks = array();
 }