private function __addBin($phar, $binary = 'bin/markdown-extended')
 {
     $content = Helper::readFile($this->root_dir . '/bin/markdown-extended');
     $content = preg_replace('{^#!/usr/bin/env php\\s*}', '', $content);
     $this->_logs[] = sprintf('Adding binary file "%s" from source (length %d)', $binary, strlen($content));
     $phar->addFromString($binary, $content);
     return $this;
 }
 /**
  * Find defined inclusion blocks
  *
  * @param   string  $text
  * @return  string
  */
 public function transform($text)
 {
     $mask = Kernel::getConfig('block_inclusion_mask');
     if (!empty($mask)) {
         $regex = Helper::buildRegex($mask);
         $text = preg_replace_callback($regex, array($this, '_callback'), $text);
     }
     return $text;
 }
 /**
  * Process the fenced code blocks
  *
  * @param   array   $matches    Results form the `transform()` function
  * @return  string
  */
 protected function _callback($matches)
 {
     $language = $matches[2];
     $codeblock = Helper::escapeCodeContent($matches[3]);
     $codeblock = preg_replace_callback('/^\\n+/', array($this, '_newlines'), $codeblock);
     $attributes = array();
     if (!empty($language)) {
         $attributes['language'] = $language;
     }
     $codeblock = Kernel::get('OutputFormatBag')->buildTag('preformatted', $codeblock, $attributes);
     return "\n\n" . parent::hashBlock($codeblock) . "\n\n";
 }
 /**
  * Loads a new formatter
  *
  * @param   string  $format     The formatter name
  * @throws  \MarkdownExtended\Exception\InvalidArgumentException if the class can not be found
  */
 public function load($format)
 {
     $cls_name = $format;
     if (!class_exists($cls_name)) {
         $cls_name = '\\MarkdownExtended\\OutputFormat\\' . Helper::toCamelCase($format);
     }
     if (!class_exists($cls_name)) {
         throw new InvalidArgumentException(sprintf('Output format "%s" not found', $format));
     }
     $cls = new $cls_name();
     if (Kernel::validate($cls, Kernel::TYPE_OUTPUTFORMAT, $format)) {
         $this->setFormatter($cls);
     }
 }
 /**
  * This will try to call a method `build{TagName}()` if it exists, then will try to use
  * the object `$tags_map` static to automatically find what to do, and then call the
  * default `getTagString()` method passing it the arguments.
  *
  * @param   string  $tag_name
  * @param   string  $content
  * @param   array   $attributes     An array of attributes constructed like "variable=>value" pairs
  *
  * @return  string
  */
 public function buildTag($tag_name, $content = null, array $attributes = array())
 {
     $_method = 'build' . Helper::toCamelCase($tag_name);
     if (isset($this->tags_map[$tag_name]) && isset($this->tags_map[$tag_name]['prefix'])) {
         $attributes['mde-prefix'] = $this->tags_map[$tag_name]['prefix'];
     }
     if (method_exists($this, $_method)) {
         return call_user_func_array(array($this, $_method), array($content, $attributes));
     }
     $closable = false;
     if (isset($this->tags_map[$tag_name])) {
         $closable = isset($this->tags_map[$tag_name]['closable']) ? $this->tags_map[$tag_name]['closable'] : false;
         $tag_name = isset($this->tags_map[$tag_name]['tag']) ? $this->tags_map[$tag_name]['tag'] : $tag_name;
     }
     return call_user_func_array(array($this, 'getTagString'), array($content, $tag_name, $attributes, $closable));
 }
 /**
  * Gets the array of parameters to pass in the template based on a content object
  *
  * @param \MarkdownExtended\API\ContentInterface $content
  *
  * @return array
  *
  * @throws \MarkdownExtended\Exception\UnexpectedValueException if a keyword can not be found in the content object
  */
 public function getParams(ContentInterface $content)
 {
     $params = array();
     $keywords = $this->config->get('keywords');
     // all options keywords
     foreach ($keywords as $var => $word) {
         $mask = $this->_buildKeywordMask($word);
         $method = 'get' . Helper::toCamelCase($var);
         if (!method_exists($content, $method)) {
             throw new UnexpectedValueException(sprintf('Template keyword "%s" not found in content', $var));
         }
         $method_tostring = $method . 'Formatted';
         $params[$mask] = function () use($content, $method, $method_tostring) {
             return call_user_func(array($content, method_exists($content, $method_tostring) ? $method_tostring : $method));
         };
     }
     // all metadata: META:name
     $meta = $content->getMetadata();
     if (!empty($meta) && isset($keywords['metadata'])) {
         foreach ($meta as $name => $value) {
             $mask = $this->_buildKeywordMask($keywords['metadata'] . ':' . $name);
             $params[$mask] = function () use($value) {
                 return Helper::getSafeString($value);
             };
         }
     }
     return $params;
 }
예제 #7
0
 /**
  * @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;
 }
예제 #8
0
 /**
  * Be sure to have a full attributes set (add a title if needed)
  *
  * @param   array   $attributes     Passed by reference
  */
 protected function _validateLinkAttributes(array &$attributes, &$text)
 {
     if (isset($attributes['email'])) {
         list($address_link, $address_text) = Helper::encodeEmailAddress($attributes['email']);
         if (!isset($attributes['href']) || empty($attributes['href'])) {
             $attributes['href'] = $address_link;
         }
         if ($this->getConfig('mailto_title_mask') && empty($attributes['title'])) {
             $attributes['title'] = Helper::fillPlaceholders($this->getConfig('mailto_title_mask'), $address_text);
         }
         unset($attributes['email']);
         $text = $address_text;
     }
     if (empty($attributes['title']) && isset($attributes['href'])) {
         $first_char = substr($attributes['href'], 0, 1);
         if ($first_char === '#' && $this->getConfig('anchor_title_mask')) {
             $attributes['title'] = Helper::fillPlaceholders($this->getConfig('anchor_title_mask'), $attributes['href']);
         } elseif ($this->getConfig('link_title_mask')) {
             $attributes['title'] = Helper::fillPlaceholders($this->getConfig('link_title_mask'), !empty($attributes['href']) ? $attributes['href'] : '');
         }
     }
 }
예제 #9
0
 /**
  * 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";
 }
예제 #10
0
 /**
  * Dumps the composer.json file
  */
 protected function runTaskManifest()
 {
     if (file_exists($manifest = MDE_BASE_PATH . self::MANIFEST_FILE)) {
         $content = json_decode(Helper::readFile($manifest), true);
         foreach (array('extra', 'autoload', 'autoload-dev', 'config', 'scripts', 'archive') as $entry) {
             if (isset($content[$entry])) {
                 unset($content[$entry]);
             }
         }
         if (isset($content['keywords']) && is_array($content['keywords'])) {
             $content['keywords'] = implode(',', $content['keywords']);
         }
         if (isset($content['authors'])) {
             foreach ($content['authors'] as $i => $author) {
                 if (is_array($author)) {
                     $content['authors'][$i] = implode(', ', $author);
                 }
             }
         }
         $this->_writeTask($content, 'Manifest');
     } else {
         $this->stream->writeln('Manifest file not found', Stream::IO_STDERR);
     }
 }
 /**
  * App's default settings
  *
  * @return array
  */
 public static function getDefaults()
 {
     return array('escaped_characters' => "0`*_{}[]()<>#+-.!:|\\", 'tab_width' => 4, 'nested_brackets_depth' => 6, 'nested_parenthesis_depth' => 4, 'no_markup' => false, 'no_entities' => false, 'special_metadata' => array('baseheaderlevel', 'quoteslanguage', 'last_update', 'file_name'), 'block_inclusion_mask' => '<!-- @([^ @]+)@ -->', 'base_path' => array(getcwd()), 'footnote_id_prefix' => '', 'glossarynote_id_prefix' => '', 'bibliographynote_id_prefix' => '', 'date_to_string' => function (\DateTime $date) {
         return $date->format(DATE_W3C);
     }, 'filepath_to_title' => function ($path) {
         return \MarkdownExtended\Util\Helper::humanReadable(pathinfo($path, PATHINFO_FILENAME));
     }, 'output_format' => 'html', 'output_format_options' => array('html' => array('html_empty_element_suffix' => ' />', 'anchor_title_mask' => 'Reach inpage section %%', 'link_title_mask' => 'See online %%', 'mailto_title_mask' => 'Contact %%', 'codeblock_language_attribute' => 'class', 'codeblock_attribute_mask' => 'language-%%', 'fn_link_title_mask' => 'See footnote %%', 'fn_backlink_title_mask' => 'Return to content', 'fn_link_class' => 'footnote', 'fn_backlink_class' => 'reverse_footnote', 'fng_link_title_mask' => 'See glossary entry %%', 'fng_backlink_title_mask' => 'Return to content', 'fng_link_class' => 'footnote_glossary', 'fng_backlink_class' => 'reverse_footnote_glossary', 'fnb_link_title_mask' => 'See bibliography reference %%', 'fnb_backlink_title_mask' => 'Return to content', 'fnb_link_class' => 'footnote_bibliography', 'fnb_backlink_class' => 'reverse_footnote_bibliography', 'math_type' => 'mathjax', 'default_template' => 'html5')), 'predefined_urls' => array(), 'predefined_titles' => array(), 'predefined_attributes' => array(), 'predefined_abbr' => array(), 'template' => 'auto', 'template_options' => array('keywords_mask' => "{%% ?%s ?%%}", 'keywords' => array('body' => 'BODY', 'notes' => 'NOTES', 'metadata' => 'META', 'charset' => 'CHARSET', 'title' => 'TITLE'), 'inline_template' => "{% META %}\n{% BODY %}\n{% NOTES %}"), 'initial_gamut' => array('filter:Detab:init' => '5', 'filter:Emphasis:prepare' => '10'), 'transform_gamut' => array('tool:RemoveUtf8Marker' => '5', 'tool:StandardizeLineEnding' => '10', 'tool:AppendEndingNewLines' => '15', 'filter:Detab' => '20', 'filter:HTML' => '25', 'tool:StripSpacedLines' => '30'), 'document_gamut' => array('tool:prepareOutputFormat' => '0', 'filter:MetaData:strip' => '1', 'filter:FencedCodeBlock' => '5', 'filter:Note:strip' => '10', 'filter:LinkDefinition:strip' => '20', 'filter:Abbreviation:strip' => '25', 'block_gamut' => '30', 'filter:MetaData:append' => '35', 'filter:Note:append' => '40', 'filter:BlockInclusion' => '50', 'tool:teardownOutputFormat' => '70'), 'span_gamut' => array('filter:Span' => '-30', 'filter:Note' => '5', 'filter:Image' => '10', 'filter:Anchor' => '20', 'filter:AutoLink' => '30', 'tool:EncodeAmpAndAngle' => '40', 'filter:Emphasis' => '50', 'filter:HardBreak' => '60', 'filter:Abbreviation' => '70'), 'block_gamut' => array('filter:FencedCodeBlock' => '5', 'filter:Header' => '10', 'filter:Table' => '15', 'filter:HorizontalRule' => '20', 'filter:ListItem' => '40', 'filter:DefinitionList' => '45', 'filter:CodeBlock' => '50', 'filter:BlockQuote' => '60', 'filter:Maths' => '70', 'tool:RebuildParagraph' => '100'), 'html_block_gamut' => array('filter:HTML' => '10', 'block_gamut' => '20'));
 }
 /**
  * Create a code span markup for $code. Called from handleSpanToken.
  *
  * @param   string  $code
  * @return  string
  */
 public function span($code)
 {
     $codeblock = Kernel::get('OutputFormatBag')->buildTag('code', Helper::escapeCodeContent(trim($code)));
     return parent::hashPart($codeblock);
 }
예제 #13
0
 public function buildMetaData($text = null, array $attributes = array())
 {
     $text = $this->escapeString($text);
     if (!empty($attributes['name'])) {
         if (empty($attributes['content']) && !empty($text)) {
             $attributes['content'] = $text;
         }
         return '.\\" ' . $attributes['name'] . ': ' . Helper::getSafeString($attributes['content']);
     }
     return '.\\" ' . $text;
 }
예제 #14
0
 private function _hardDebugContent(ContentInterface $content)
 {
     echo Helper::debug($content->getBody(), 'content body');
     echo Helper::debug($content->getNotes(), 'content notes', false);
     echo Helper::debug($content->getMetadata(), 'content metadata', false);
 }
예제 #15
0
 /**
  * Finds an internal resource file by type
  *
  * @param string $name
  * @param string $type
  * @return null|string
  */
 public static function getResourcePath($name, $type)
 {
     if ($type === self::RESOURCE_CONFIG || $type === self::RESOURCE_TEMPLATE) {
         $local_path = realpath(Helper::getPath(array(dirname(__DIR__), 'Resources', strtolower($type))));
         if (file_exists($local = $local_path . DIRECTORY_SEPARATOR . $name)) {
             return $local;
         }
         $mask = $type === self::RESOURCE_TEMPLATE ? self::RESOURCE_TEMPLATE_MASK : self::RESOURCE_CONFIG_MASK;
         $final_name = sprintf($mask, $name);
         if (file_exists($final = $local_path . DIRECTORY_SEPARATOR . $final_name)) {
             return $final;
         }
     }
     return null;
 }
예제 #16
0
 /**
  * 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";
 }
 private function _hardDebug()
 {
     $short_options = $this->getFilteredOptions('short_option');
     $long_options = $this->getFilteredOptions('long_option');
     echo Helper::debug(array_values($short_options), 'short options', false);
     echo Helper::debug(array_values($long_options), 'long options', false);
     echo Helper::debug($this->getFilteredOptions('_default'), 'defaults', false);
     echo Helper::debug($this->user_options->original, 'input user options', false);
     echo Helper::debug($this->user_options->remaining, 'remaining arguments', false);
     echo Helper::debug($this->user_options->options, 'final full options', false);
 }