`). Inline elements are elements that are added inside of block elements i.e. inside of text. This markdown parser allows you to extend the markdown language by changing existing elements behavior and also adding new block and inline elements. You do this by extending from the parser class and adding/overriding class methods and properties. For the different element types there are different ways to extend them as you will see in the following sections. ### Adding block elements The markdown is parsed line by line to identify each non-empty line as one of the block element types. To identify a line as the beginning of a block element it calls all protected class methods who's name begins with `identify`. An identify function returns true if it has identified the block element it is responsible for or false if not. In the following example we will implement support for [fenced code blocks][] which are part of the github flavored markdown. [fenced code blocks]: https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks "Fenced code block feature of github flavored markdown" ```php [], ]; $line = rtrim($lines[$current]); // detect language and fence length (can be more than 3 backticks) $fence = substr($line, 0, $pos = strrpos($line, '`') + 1); $language = substr($line, $pos); if (!empty($language)) { $block['language'] = $language; } // consume all lines until ``` for($i = $current + 1, $count = count($lines); $i < $count; $i++) { if (rtrim($line = $lines[$i]) !== $fence) { $block['content'][] = $line; } else { // stop consuming when code block is over break; } } return [$block, $i]; } ``` 2. "rendering" the element. After all blocks have been consumed, they are being rendered using the `render{elementName}()`-method where `elementName` refers to the name of the element in the abstract syntax tree: ```php protected function renderFencedCode($block) { $class = isset($block['language']) ? ' class="language-' . $block['language'] . '"' : ''; return "
" . htmlspecialchars(implode("\n", $block['content']) . "\n", ENT_NOQUOTES, 'UTF-8') . '
';
}
```
You may also add code highlighting here. In general it would also be possible to render ouput in a different language than
HTML for example LaTeX.
### Adding inline elements
Adding inline elements is different from block elements as they are parsed using markers in the text.
An inline element is identified by a marker that marks the beginning of an inline element (e.g. `[` will mark a possible
beginning of a link or `` ` `` will mark inline code).
Parsing methods for inline elements are also protected and identified by the prefix `parse`. Additionally a `@marker` annotation
in PHPDoc is needed to register the parse function for one or multiple markers.
The method will then be called when a marker is found in the text. As an argument it takes the text starting at the position of the marker.
The parser method will return an array containing the element of the abstract sytnax tree and an offset of text it has
parsed from the input markdown. All text up to this offset will be removed from the markdown before the next marker will be searched.
As an example, we will add support for the [strikethrough][] feature of github flavored markdown:
[strikethrough]: https://help.github.com/articles/github-flavored-markdown#strikethrough "Strikethrough feature of github flavored markdown"
```php
parseInline($matches[1])],
// return the offset of the parsed text
strlen($matches[0])
];
}
// in case we did not find a closing ~~ we just return the marker and skip 2 characters
return [['text', '~~'], 2];
}
// rendering is the same as for block elements, we turn the abstract syntax array into a string.
protected function renderStrike($element)
{
return '