/** * Process each inclusion, errors are written as comments * * @param array $matches One set of results form the `transform()` function * @return string The result of the inclusion parsed if so */ protected function _callback($matches) { $filename = $matches[1]; if (!file_exists($filename)) { $base_path = Kernel::getConfig('base_path'); if (!is_array($base_path)) { $base_path = array($base_path); } foreach ($base_path as $path) { $file = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename; if (file_exists($file)) { $filename = $file; break; } } } $content_collection = Kernel::get('ContentCollection'); $index = $content_collection->key(); try { $parsed_content = Kernel::get('Parser')->transformSource($filename, false); } catch (\Exception $e) { $parsed_content = Kernel::get('OutputFormatBag')->buildTag('comment', "ERROR while parsing {$filename} : '{$e->getMessage()}'"); } Kernel::get('ContentCollection')->seek($index); return $parsed_content; }
/** * @param array $matches A set of results of the `transform` function * @return string */ protected function _email_callback($matches) { $address = $matches[1]; Kernel::addConfig('urls', $address); $block = Kernel::get('OutputFormatBag')->buildTag('link', $address, array('email' => $address)); return parent::hashPart($block); }
/** * @param string $text * @return string */ public function transform($text) { return preg_replace('{ ^[ ]{0,3} # Leading space ([-*_]) # $1: First marker (?> # Repeated marker group [ ]{0,2} # Zero, one, or two spaces. \\1 # Marker character ){2,} # Group repeated at least twice [ ]* # Tailing spaces $ # End of line. }mx', "\n" . parent::hashBlock(Kernel::get('OutputFormatBag')->buildTag('horizontal_rule')) . "\n", $text); }
/** * Build each blockquote block * * @param array $matches A set of results of the `transform()` function * @return string */ protected function _callback($matches) { $blockq = $matches[1]; $cite = isset($matches[2]) ? $matches[2] : null; // trim one level of quoting - trim whitespace-only lines $blockq = preg_replace('/^[ ]*>[ ]?(\\((.+?)\\))?|^[ ]+$/m', '', $blockq); $blockq = Lexer::runGamut('html_block_gamut', $blockq); # recurse $blockq = preg_replace('/^/m', " ", $blockq); // These leading spaces cause problem with <pre> content, // so we need to fix that: $blockq = preg_replace_callback('{(\\s*<pre>.+?</pre>)}sx', array($this, '_callback_spaces'), $blockq); $attributes = array(); if (!empty($cite)) { $attributes['cite'] = $cite; } $block = Kernel::get('OutputFormatBag')->buildTag('blockquote', $blockq, $attributes); return "\n" . parent::hashBlock($block) . "\n\n"; }
/** * Append footnote and glossary list to text. * * @param array $matches * @return string */ protected function _append_callback($matches) { $note_id = $matches[1]; $note_num = $note_ref = null; // Create footnote marker only if it has a corresponding footnote *and* // the footnote hasn't been used by another marker. $node_id = Kernel::getConfig('footnote_id_prefix') . $note_id; $footnotes = Kernel::getConfig('footnotes'); if (isset($footnotes[$node_id])) { $type_info = $this->getTypeInfo(self::FOOTNOTE_DEFAULT); // Transfer footnote content to the ordered list. self::$notes_ordered[$node_id] = $footnotes[$node_id]; $note_num = array_key_exists($node_id, self::$written_notes) ? self::$written_notes[$node_id] : self::$footnote_counter++; $note_ref = $node_id; } // Create glossary marker only if it has a corresponding note *and* // the glossary hasn't been used by another marker. $glossary_node_id = Kernel::getConfig('glossarynote_id_prefix') . $note_id; $glossaries = Kernel::getConfig('glossaries'); if (isset($glossaries[$glossary_node_id])) { $type_info = $this->getTypeInfo(self::FOOTNOTE_GLOSSARY); // Transfer footnote content to the ordered list. self::$notes_ordered[$glossary_node_id] = $glossaries[$glossary_node_id]; $note_num = array_key_exists($note_id, self::$written_notes) ? self::$written_notes[$note_id] : self::$footnote_counter++; $note_ref = $glossary_node_id; } // Create bibliography marker only if it has a corresponding note *and* // the glossary hasn't been used by another marker. $bibliography_node_id = Kernel::getConfig('bibliographynote_id_prefix') . $note_id; $bibliographies = Kernel::getConfig('bibliographies'); if (isset($bibliographies[$bibliography_node_id])) { $type_info = $this->getTypeInfo(self::FOOTNOTE_BIBLIOGRAPHY); // Transfer footnote content to the ordered list. self::$notes_ordered[$bibliography_node_id] = $bibliographies[$bibliography_node_id]; $note_num = array_key_exists($note_id, self::$written_notes) ? self::$written_notes[$note_id] : self::$footnote_counter++; $note_ref = $bibliography_node_id; } if (isset($type_info) && !empty($note_id) && !empty($note_num) && !empty($note_ref)) { $backlink_id = Kernel::get('DomId')->get($type_info['prefix'] . 'ref:' . $note_ref); $footlink_id = Kernel::get('DomId')->get($type_info['prefix'] . ':' . $note_ref); $attributes = array(); $attributes['rel'] = $type_info['name']; $attributes['href'] = '#' . $footlink_id; $attributes['counter'] = $note_num; $attributes['backlink_id'] = $backlink_id; return Kernel::get('OutputFormatBag')->buildTag($type_info['outputformat_methods']['link'], $note_num, $attributes); } return '[^' . $matches[1] . ']'; }
/** * Build a table caption */ protected function _doCaption($matches) { return Kernel::get('OutputFormatBag')->buildTag('table_caption', $matches[0], array('id' => $this->table_id)); }
/** * Process each abbreviation * * @param array $matches One set of results form the `transform()` function * @return string */ protected function _callback($matches) { $abbr = $matches[0]; $abbr_desciptions = Kernel::getConfig('abbr_desciptions'); if (isset($abbr_desciptions[$abbr])) { $attributes = array(); $desc = trim($abbr_desciptions[$abbr]); if (!empty($desc)) { $attributes['title'] = Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $desc); } $abbr = Kernel::get('OutputFormatBag')->buildTag('abbreviation', $abbr, $attributes); return parent::hashBlock($abbr); } else { return $abbr; } }
/** * Set the page content if it is not set yet */ protected function _setContentTitle($string) { $old = Kernel::get(Kernel::TYPE_CONTENT)->getTitle(); if (empty($old)) { $meta = Kernel::get(Kernel::TYPE_CONTENT)->getMetadata(); $meta['title'] = $string; Kernel::get(Kernel::TYPE_CONTENT)->setMetadata($meta); } }
public function buildFootnoteStandardLink($text = null, array $attributes = array(), $note_type = Note::FOOTNOTE_DEFAULT) { $type_info = Note::getTypeInfo($note_type); if ($this->getConfig($type_info['prefix'] . '_link_class')) { $attributes['class'] = Helper::fillPlaceholders(Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $this->getConfig($type_info['prefix'] . '_link_class')), $text); } if ($this->getConfig($type_info['prefix'] . '_link_title_mask')) { $attributes['title'] = Helper::fillPlaceholders(Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $this->getConfig($type_info['prefix'] . '_link_title_mask')), $text); } $backlink_id = $attributes['backlink_id']; unset($attributes['backlink_id']); unset($attributes['counter']); $link = Kernel::get('OutputFormatBag')->buildTag('link', $text, $attributes); return Kernel::get('OutputFormatBag')->buildTag('sup', $link, array('id' => $backlink_id)); }
/** * @param array $matches A set of results of the `transform()` function * @return string */ protected function _callback($matches) { return parent::hashPart(Kernel::get('OutputFormatBag')->buildTag('new_line') . "\n"); }
/** * Process paragraphs * * @param string $text The text to parse * * @return string The text parsed */ public function RebuildParagraph($text) { // Strip leading and trailing lines: $text = preg_replace('/\\A\\n+|\\n+\\z/', '', $text); $grafs = preg_split('/\\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); // Wrap <p> tags and unhashify HTML blocks foreach ($grafs as $key => $value) { $value = trim(Lexer::runGamut('span_gamut', $value)); // Check if this should be enclosed in a paragraph. // Clean tag hashes & block tag hashes are left alone. $is_p = !preg_match('/^B\\x1A[0-9]+B|^C\\x1A[0-9]+C$/', $value); if ($is_p) { $value = Kernel::get('OutputFormatBag')->buildTag('paragraph', $value); } $grafs[$key] = $value; } // Join grafs in one text, then unhash HTML tags. // $text = implode("\n\n", $grafs); $text = implode('', $grafs); // Finish by removing any tag hashes still present in $text. $text = Lexer::runGamut('filter:HTML:unhash', $text, true); return $text; }
/** * Run a gamut stack from a filter or tool * * @param string $gamut The name of a single Gamut or a Gamuts stack * @param string $text * @param bool $forced Forces to run the gamut event if it is disabled * * @return string */ public function runGamut($gamut, $text, $forced = false) { $loader = Kernel::get('GamutLoader'); return $loader->isGamutEnabled($gamut) || $forced ? $loader->runGamut($gamut, $text) : $text; }
public function teardown($text) { $headers = array(); $content = Kernel::get(Kernel::TYPE_CONTENT); foreach ($content->getMetadata() as $name => $value) { if ($name === 'title') { $headers['name'] = $value; } elseif (in_array($name, self::$headers_meta_data)) { $headers[$name] = $value; } } $title = $content->getTitle(); if (empty($headers['name']) && $title) { $headers['name'] = $title; } $text = $this->buildTag('meta_title', null, $headers) . $text; return $text; }
/** * Actually do content's parsing * * @param \MarkdownExtended\API\ContentInterface $content * * @return \MarkdownExtended\API\ContentInterface */ protected function parseContent(ContentInterface $content) { $this->_registerContent($content); $this->getKernel()->set(Kernel::TYPE_CONTENT, function () { return Kernel::get('ContentCollection')->current(); })->set('Lexer', new Lexer())->set('DomId', new DomIdRegistry()); // actually parse content $this->getKernel()->get('Lexer')->parse($content); return $content; }
/** * Build meta data strings */ public function append($text) { $metadata = Kernel::getConfig('metadata'); if (!empty($metadata)) { foreach ($metadata as $meta_name => $meta_value) { if (!empty($meta_name) && is_string($meta_name)) { if (in_array($meta_name, $this->special_metadata)) { Kernel::setConfig($meta_name, $meta_value); } elseif ($meta_name == 'title') { Kernel::get(Kernel::TYPE_CONTENT)->setTitle($meta_value); } } } } return $text; }
/** * @param string $text * @return string */ public function transform($text) { $token_stack = array(''); $text_stack = array(''); $italic = ''; $strong = ''; $tree_char_em = false; while (1) { // Get prepared regular expression for seraching emphasis tokens in current context. $token_re = self::$em_strong_prepared["{$italic}{$strong}"]; // Each loop iteration search for the next emphasis token. // Each token is then passed to handleSpanToken. $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); $text_stack[0] .= $parts[0]; $token =& $parts[1]; $text =& $parts[2]; if (empty($token)) { // Reached end of text span: empty stack without emitting any more emphasis. while ($token_stack[0]) { $text_stack[1] .= array_shift($token_stack); $text_stack[0] .= array_shift($text_stack); } break; } $token_len = strlen($token); if ($tree_char_em) { // Reached closing marker while inside a three-char emphasis. if ($token_len == 3) { // Three-char closing marker, close em and strong. array_shift($token_stack); $span = Lexer::runGamut('span_gamut', array_shift($text_stack)); $span = Kernel::get('OutputFormatBag')->buildTag('italic', $span); $span = Kernel::get('OutputFormatBag')->buildTag('bold', $span); $text_stack[0] .= parent::hashPart($span); $italic = ''; $strong = ''; } else { // Other closing marker: close one em or strong and // change current token state to match the other $token_stack[0] = str_repeat($token[0], 3 - $token_len); $tag = $token_len == 2 ? "bold" : "italic"; $span = Lexer::runGamut('span_gamut', $text_stack[0]); $span = Kernel::get('OutputFormatBag')->buildTag($tag, $span); $text_stack[0] = parent::hashPart($span); ${$tag} = ''; // $$tag stands for $italic or $strong } $tree_char_em = false; } elseif ($token_len == 3) { if ($italic) { // Reached closing marker for both em and strong. // Closing strong marker: for ($i = 0; $i < 2; ++$i) { $shifted_token = array_shift($token_stack); $tag = strlen($shifted_token) == 2 ? "bold" : "italic"; $span = Lexer::runGamut('span_gamut', array_shift($text_stack)); $span = Kernel::get('OutputFormatBag')->buildTag($tag, $span); $text_stack[0] .= parent::hashPart($span); ${$tag} = ''; // $$tag stands for $italic or $strong } } else { // Reached opening three-char emphasis marker. Push on token // stack; will be handled by the special condition above. $italic = $token[0]; $strong = "{$italic}{$italic}"; array_unshift($token_stack, $token); array_unshift($text_stack, ''); $tree_char_em = true; } } elseif ($token_len == 2) { if ($strong) { // Unwind any dangling emphasis marker: if (strlen($token_stack[0]) == 1) { $text_stack[1] .= array_shift($token_stack); $text_stack[0] .= array_shift($text_stack); } // Closing strong marker: array_shift($token_stack); $span = Lexer::runGamut('span_gamut', array_shift($text_stack)); $span = Kernel::get('OutputFormatBag')->buildTag('bold', $span); $text_stack[0] .= parent::hashPart($span); $strong = ''; } else { array_unshift($token_stack, $token); array_unshift($text_stack, ''); $strong = $token; } } else { // Here $token_len == 1 if ($italic) { if (strlen($token_stack[0]) == 1) { // Closing emphasis marker: array_shift($token_stack); $span = Lexer::runGamut('span_gamut', array_shift($text_stack)); $span = Kernel::get('OutputFormatBag')->buildTag('italic', $span); $text_stack[0] .= parent::hashPart($span); $italic = ''; } else { $text_stack[0] .= $token; } } else { array_unshift($token_stack, $token); array_unshift($text_stack, ''); $italic = $token; } } } return $text_stack[0]; }
/** * @param array $matches A set of results of the `transform()` function * @return string */ protected function _items_callback($matches) { $item = $matches[4]; $leading_line =& $matches[1]; $leading_space =& $matches[2]; $marker_space = $matches[3]; $trailing_blank_line =& $matches[5]; if ($leading_line || $trailing_blank_line || preg_match('/\\n{2,}/', $item)) { // Replace marker with the appropriate whitespace indentation $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; $item = Lexer::runGamut('html_block_gamut', Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':Outdent', $item) . "\n"); } else { // Recursion for sub-lists: $item = self::transform(Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':Outdent', $item)); $item = preg_replace('/\\n+$/', '', $item); $item = Lexer::runGamut('span_gamut', $item); } return Kernel::get('OutputFormatBag')->buildTag('list_item', $item); }
/** * Gets an array of all defined gamuts * * @return array */ public function getAllGamuts() { if (empty($this->all_gamuts)) { $this->all_gamuts = array(); foreach (Kernel::get('config')->getAll() as $var => $val) { if ($this->isGamutStackName($var)) { foreach ($val as $item => $priority) { if (!$this->isGamutStackName($item)) { $name = $this->getGamutBaseName($item); if (!in_array($name, $this->all_gamuts, true)) { $this->all_gamuts[] = $name; } } } } } } return $this->all_gamuts; }
/** * Process the dd contents. * * @param array $matches * @return string */ protected function _item_callback_dd($matches) { $leading_line = $matches[1]; $marker_space = $matches[2]; $def = $matches[3]; if ($leading_line || preg_match('/\\n{2,}/', $def)) { // Replace marker with the appropriate whitespace indentation $def = str_repeat(' ', strlen($marker_space)) . $def; $def = Lexer::runGamut('html_block_gamut', Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':Outdent', $def . "\n\n")); // $def = "\n$def\n"; } else { $def = rtrim($def); $def = Lexer::runGamut('span_gamut', Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':Outdent', $def)); } return Kernel::get('OutputFormatBag')->buildTag('definition_list_item_definition', $def); }
/** * 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); }
/** * @param array $matches A set of results of the `transform` function * @return string */ protected function _inline_callback($matches) { $alt_text = $matches[2]; $url = $matches[3] == '' ? $matches[4] : $matches[3]; $title =& $matches[7]; $attributes = array(); $attributes['alt'] = Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $alt_text); $attributes['src'] = Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $url); if (!empty($title)) { $attributes['title'] = Lexer::runGamut(GamutLoader::TOOL_ALIAS . ':EncodeAttribute', $title); } $block = Kernel::get('OutputFormatBag')->buildTag('image', null, $attributes); return parent::hashPart($block); }
/** * {@inheritDoc} */ public function getMetadataFormatted() { return Kernel::get('OutputFormatBag')->getMetadataToString($this->metadata, $this); }
/** * Clearing extra-specific variables * * This will call any `_teardown()` method of all enabled filters. */ protected function _teardown() { // clear global hashes $this->_clearHashes(); // call all gamuts '_teardown' $loader = Kernel::get('GamutLoader'); $loader->runGamutsMethod($loader->getAllGamutsReversed(), '_teardown'); }
/** * Process the fenced code blocks new lines * * @param array $matches * @return string */ protected function _newlines($matches) { return str_repeat(Kernel::get('OutputFormatBag')->buildTag('new_line'), strlen($matches[0])); }
/** * Build each maths span * * @param string $texblock * @return string */ public function span($texblock) { $texblock = trim($texblock); $block = Kernel::get('OutputFormatBag')->buildTag('maths_span', $texblock, array()); return parent::hashPart($block); }
/** * Lists runtime configuration settings */ protected function runTaskConfigList() { // create the MDE instance $mde = $this->getMarkdownExtendedParser(); $loader = Kernel::get('GamutLoader'); $config = array(); foreach (Kernel::get('config')->getAll() as $var => $val) { if ($loader->isGamutStackName($var)) { continue; } if (is_null($val)) { $config[$var] = 'NULL'; } elseif (is_bool($val)) { $config[$var] = $val === true ? 'true' : 'false'; } elseif (is_callable($val)) { $config[$var] = 'function()'; } elseif (is_array($val)) { foreach ($val as $subvar => $subval) { $config[$var . '.' . $subvar] = $subval; } } else { $config[$var] = $val; } } // var_export($config); $this->_writeTask($config, 'Configuration settings'); }