/**
  * Process ATX-style headers
  *
  * @param   array   $matches    The results from the `transform()` function
  * @return  string
  */
 protected function _atx_callback($matches)
 {
     $level = strlen($matches[1]) + $this->_getRebasedHeaderLevel();
     $domid = !empty($matches[3]) ? $matches[3] : Helper::header2Label($matches[2]);
     $domid = Kernel::get('DomId')->set($domid);
     $title = Lexer::runGamut('span_gamut', $matches[2]);
     Kernel::addConfig('menu', array('level' => $level, 'text' => parent::unhash($title)), $domid);
     $block = Kernel::get('OutputFormatBag')->buildTag('title', $title, array('level' => $level, 'id' => $domid));
     $this->_setContentTitle($title);
     return "\n" . parent::hashBlock($block) . "\n\n";
 }
 /**
  * Form HTML tables: parses table contents
  *
  * @param   array   $matches
  * @return  string
  */
 protected function _callback($matches)
 {
     $attributes = array();
     //self::doDebug($matches);
     // The head string may have a begin slash
     $caption = count($matches) > 3 ? $matches[1] : null;
     $head = count($matches) > 3 ? preg_replace('/^ *[|]/m', '', $matches[2]) : preg_replace('/^ *[|]/m', '', $matches[1]);
     $underline = count($matches) > 3 ? $matches[3] : $matches[2];
     $content = count($matches) > 3 ? preg_replace('/^ *[|]/m', '', $matches[4]) : preg_replace('/^ *[|]/m', '', $matches[3]);
     // Remove any tailing pipes for each line.
     $underline = preg_replace('/[|] *$/m', '', $underline);
     $content = preg_replace('/[|] *$/m', '', $content);
     // Reading alignement from header underline.
     $separators = preg_split('/ *[|] */', $underline);
     foreach ($separators as $n => $s) {
         $attributes[$n] = array();
         if (preg_match('/^ *-+: *$/', $s)) {
             $attributes[$n]['style'] = 'text-align:right;';
         } elseif (preg_match('/^ *:-+: *$/', $s)) {
             $attributes[$n]['style'] = 'text-align:center;';
         } elseif (preg_match('/^ *:-+ *$/', $s)) {
             $attributes[$n]['style'] = 'text-align:left;';
         }
     }
     // Split content by row.
     $headers = explode("\n", trim($head, "\n"));
     $text = '';
     if (!empty($caption)) {
         $this->table_id = Helper::header2Label($caption);
         $text .= preg_replace_callback('/\\[(.*)\\]/', array($this, '_doCaption'), Lexer::runGamut('span_gamut', $caption));
     }
     $lines = '';
     foreach ($headers as $_header) {
         $line = '';
         // Parsing span elements, including code spans, character escapes,
         // and inline HTML tags, so that pipes inside those gets ignored.
         $_header = Lexer::runGamut('filter:Span', $_header);
         // Split row by cell.
         $_header = preg_replace('/[|] *$/m', '', $_header);
         $_headers = preg_split('/[|]/', $_header);
         $col_count = count($_headers);
         // Write column headers.
         // we first loop for colspans
         $headspans = array();
         foreach ($_headers as $_i => $_cell) {
             if ($_cell == '') {
                 if ($_i == 0) {
                     $headspans[1] = 2;
                 } else {
                     if (isset($headspans[$_i - 1])) {
                         $headspans[$_i - 1]++;
                     } else {
                         $headspans[$_i - 1] = 2;
                     }
                 }
             }
         }
         foreach ($_headers as $n => $__header) {
             if ($__header != '') {
                 $cell_attributes = $attributes[$n];
                 if (isset($headspans[$n])) {
                     $cell_attributes['colspan'] = $headspans[$n];
                 }
                 $line .= Kernel::get('OutputFormatBag')->buildTag('table_cell_head', Lexer::runGamut('span_gamut', trim($__header)), $cell_attributes) . "\n";
             }
         }
         $lines .= Kernel::get('OutputFormatBag')->buildTag('table_line', $line) . "\n";
     }
     $text .= Kernel::get('OutputFormatBag')->buildTag('table_header', $lines);
     // Split content by row.
     $rows = explode("\n", trim($content, "\n"));
     $lines = '';
     foreach ($rows as $row) {
         $line = '';
         // Parsing span elements, including code spans, character escapes,
         // and inline HTML tags, so that pipes inside those gets ignored.
         $row = Lexer::runGamut('filter:Span', $row);
         // Split row by cell.
         $row_cells = preg_split('/ *[|] */', $row, $col_count);
         $row_cells = array_pad($row_cells, $col_count, '');
         // we first loop for colspans
         $colspans = array();
         foreach ($row_cells as $_i => $_cell) {
             if ($_cell == '') {
                 if ($_i == 0) {
                     $colspans[1] = 2;
                 } else {
                     if (isset($colspans[$_i - 1])) {
                         $colspans[$_i - 1]++;
                     } else {
                         $colspans[$_i - 1] = 2;
                     }
                 }
             }
         }
         foreach ($row_cells as $n => $cell) {
             if ($cell != '') {
                 $cell_attributes = $attributes[$n];
                 if (isset($colspans[$n])) {
                     $cell_attributes['colspan'] = $colspans[$n];
                 }
                 $line .= Kernel::get('OutputFormatBag')->buildTag('table_cell', Lexer::runGamut('span_gamut', trim($cell)), $cell_attributes) . "\n";
             }
         }
         $lines .= Kernel::get('OutputFormatBag')->buildTag('table_line', $line) . "\n";
     }
     $text .= Kernel::get('OutputFormatBag')->buildTag('table_body', $lines);
     $table = Kernel::get('OutputFormatBag')->buildTag('table', $text);
     return parent::hashBlock($table) . "\n";
 }
 /**
  * @param   array   $matches    A set of results of the `transform` function
  * @return  string
  */
 protected function _reference_callback($matches)
 {
     $whole_match = $matches[1];
     $alt_text = $matches[2];
     $link_id = strtolower($matches[3]);
     if ($link_id == "") {
         $link_id = strtolower($alt_text);
         // for shortcut links like ![this][].
     }
     $urls = Kernel::getConfig('urls');
     $titles = Kernel::getConfig('titles');
     $predef_attributes = Kernel::getConfig('attributes');
     $alt_text = Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $alt_text);
     if (isset($urls[$link_id])) {
         $attributes = array();
         $attributes['alt'] = $alt_text;
         $attributes['id'] = Helper::header2Label($link_id);
         $attributes['src'] = Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $urls[$link_id]);
         if (!empty($titles[$link_id])) {
             $attributes['title'] = Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $titles[$link_id]);
         }
         if (!empty($predef_attributes[$link_id])) {
             $attributes = array_merge(Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':ExtractAttributes', $predef_attributes[$link_id]), $attributes);
         }
         $block = Kernel::get('OutputFormatBag')->buildTag('image', null, $attributes);
         $result = parent::hashPart($block);
     } else {
         // If there's no such link ID, leave intact
         $result = $whole_match;
     }
     return $result;
 }
 /**
  * Writes a content in a local path and returns written length
  *
  * @param string $path
  * @param \MarkdownExtended\API\ContentInterface $content
  *
  * @return int
  */
 protected function writeOutputFile($path, ContentInterface $content)
 {
     // construct output file name
     $name = $content->getMetadata('file_name');
     $path = Helper::fillPlaceholders($path, !empty($name) ? pathinfo($name, PATHINFO_FILENAME) : Helper::header2Label($content->getTitle()));
     // make a backup if `option[force]!==true`
     $backup = (bool) $this->getKernel()->getConfig('force') !== true;
     // write output
     Helper::writeFile($path, (string) $content, $backup);
     // return created path
     return $path;
 }