├── src ├── helpers.php ├── Extension │ └── ParsedownExtension.php ├── TokenParser │ └── ParsedownTokenParser.php └── Node │ └── ParsedownNode.php └── composer.json /src/helpers.php: -------------------------------------------------------------------------------- 1 | text($text); 15 | } else { 16 | $text = $parser->line($text); 17 | } 18 | 19 | return $text; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parsedown/twig", 3 | "description": "Parsedown's Official Twig Extension", 4 | "keywords": [ 5 | "parsedown", 6 | "twig" 7 | ], 8 | "license": "MIT", 9 | "homepage": "http://parsedown.org", 10 | "support": { 11 | "issues": "https://github.com/parsedown/twig/issues", 12 | "source": "https://github.com/parsedown/twig" 13 | }, 14 | "authors": [{ 15 | "name": "Eduardo Agostini", 16 | "email": "edu.agostini@gmail.com" 17 | }], 18 | "require": { 19 | "php": ">=5.4", 20 | "erusev/parsedown": "~1.6" 21 | }, 22 | "autoload": { 23 | "files": [ 24 | "src/helpers.php" 25 | ], 26 | "psr-4": { 27 | "Parsedown\\": "src/" 28 | } 29 | }, 30 | "prefer-stable": true 31 | } 32 | -------------------------------------------------------------------------------- /src/Extension/ParsedownExtension.php: -------------------------------------------------------------------------------- 1 | ['all'] 21 | ]), 22 | ]; 23 | } 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function getFunctions() 29 | { 30 | return [ 31 | new \Twig_SimpleFunction('parsedown', 'parsedown', [ 32 | 'is_safe' => ['all'] 33 | ]), 34 | ]; 35 | } 36 | 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function getTokenParsers() 42 | { 43 | return array( 44 | new ParsedownTokenParser(), 45 | ); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function getName() 52 | { 53 | return 'parsedown'; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/TokenParser/ParsedownTokenParser.php: -------------------------------------------------------------------------------- 1 | getLine(); 19 | $stream = $this->parser->getStream(); 20 | 21 | if (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { 22 | $text = $this->parser->getExpressionParser()->parseExpression()->getAttribute('value'); 23 | } else { 24 | $stream->expect(\Twig_Token::BLOCK_END_TYPE); 25 | 26 | $text = $this->parser->subparse(function (\Twig_Token $token) { 27 | return $token->test('endparsedown'); 28 | }, true)->getAttribute('data'); 29 | } 30 | 31 | $stream->expect(\Twig_Token::BLOCK_END_TYPE); 32 | 33 | return new ParsedownNode($text, $lineno, $this->getTag()); 34 | } 35 | 36 | /** 37 | * @inheritdoc 38 | */ 39 | public function getTag() 40 | { 41 | return 'parsedown'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Node/ParsedownNode.php: -------------------------------------------------------------------------------- 1 | normalize($this->getAttribute('text')); 26 | 27 | $compiler->addDebugInfo($this); 28 | $compiler->write('echo parsedown("' . $text . '");'); 29 | $compiler->raw("\n"); 30 | } 31 | 32 | /** 33 | * @param string $text 34 | * @return string 35 | */ 36 | protected function normalize($text) 37 | { 38 | if ($padding = $this->padding($text)) { 39 | $lines = []; 40 | $pattern = '/^\s{' . strlen($padding) . '}/s'; 41 | 42 | foreach (explode(PHP_EOL, $text) as $line) { 43 | $lines[] = preg_replace($pattern, '', $line); 44 | } 45 | 46 | $text = join(PHP_EOL, $lines); 47 | } 48 | 49 | return $text; 50 | } 51 | 52 | /** 53 | * @param string $text 54 | * @return string 55 | */ 56 | protected function padding($text) 57 | { 58 | $paddings = []; 59 | 60 | foreach (explode(PHP_EOL, $text) as $line) { 61 | if (trim($line) && preg_match('/^\s+/', $line, $matches)) { 62 | if ($padding = end($matches)) { 63 | $paddings[] = $padding; 64 | } 65 | } 66 | } 67 | 68 | return count($paddings) ? min($paddings) : ''; 69 | } 70 | } 71 | --------------------------------------------------------------------------------