Merge pull request #30 from cordoval/feature/addSundownSupport

add sundown support
This commit is contained in:
Joseph Bielawski 2012-10-13 07:13:49 -07:00
commit 7c088d3094
15 changed files with 131 additions and 81 deletions

7
.gitignore vendored
View file

@ -1,3 +1,4 @@
/phpunit.xml
/vendor/symfony
/Tests/autoload.php
phpunit.xml
vendor/*
!vendor/parser
composer.lock

View file

@ -1,17 +1,19 @@
language: php
php:
- 5.3.2
- 5.3.3
- 5.3
- 5.4
env:
- SYMFONY_VERSION=v2.0.5
- SYMFONY_VERSION=origin/master
- SYMFONY_VERSION=2.0.*
- SYMFONY_VERSION=2.1.*
before_script: php vendor/vendors.php
before_script:
- composer require symfony/framework-bundle:${SYMFONY_VERSION}
- composer install
script: phpunit
script: phpunit --coverage-text
notifications:
email:

View file

@ -3,15 +3,16 @@
namespace Knp\Bundle\MarkdownBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration
class Configuration implements ConfigurationInterface
{
/**
* Generates the configuration tree.
* Generates the configuration tree builder.
*
* @return TreeBuilder
*/
public function getConfigTree()
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
@ -19,14 +20,46 @@ class Configuration
->addDefaultsIfNotSet()
->children()
->arrayNode('parser')
->addDefaultsIfNotSet()
->addDefaultsIfNotSet()
->children()
->scalarNode('service')->cannotBeEmpty()->defaultValue('markdown.parser.max')->end()
->end()
->end()
->arrayNode('sundown')
->info('Use only if using sundown parser')
->addDefaultsIfNotSet()
->children()
->arrayNode('extensions')
->addDefaultsIfNotSet()
->children()
->booleanNode('fenced_code_blocks')->defaultFalse()->end()
->booleanNode('no_intra_emphasis')->defaultFalse()->end()
->booleanNode('tables')->defaultFalse()->end()
->booleanNode('autolink')->defaultFalse()->end()
->booleanNode('strikethrough')->defaultFalse()->end()
->booleanNode('lax_html_blocks')->defaultFalse()->end()
->booleanNode('space_after_headers')->defaultFalse()->end()
->booleanNode('superscript')->defaultFalse()->end()
->end()
->end()
->arrayNode('render_flags')
->addDefaultsIfNotSet()
->children()
->booleanNode('filter_html')->defaultFalse()->end()
->booleanNode('no_images')->defaultFalse()->end()
->booleanNode('no_links')->defaultFalse()->end()
->booleanNode('no_styles')->defaultFalse()->end()
->booleanNode('safe_links_only')->defaultFalse()->end()
->booleanNode('with_toc_data')->defaultFalse()->end()
->booleanNode('hard_wrap')->defaultFalse()->end()
->booleanNode('xhtml')->defaultFalse()->end()
->end()
->end()
->end()
->end()
->end()
->end();
return $treeBuilder->buildTree();
return $treeBuilder;
}
}

View file

@ -3,6 +3,7 @@
namespace Knp\Bundle\MarkdownBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\Config\FileLocator;
@ -18,16 +19,21 @@ class KnpMarkdownExtension extends Extension
*/
public function load(array $configs , ContainerBuilder $container)
{
$processor = new Processor();
$configuration = new Configuration();
$config = $processor->process($configuration->getConfigTree(), $configs);
$config = $this->processConfiguration($configuration, $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('parser.xml');
$loader->load('helper.xml');
$loader->load('twig.xml');
$container->setParameter('markdown.sundown.extensions', $config['sundown']['extensions']);
$container->setParameter('markdown.sundown.render_flags', $config['sundown']['render_flags']);
$container->setAlias('markdown.parser', $config['parser']['service']);
if ($config['parser']['service'] == 'markdown.parser.sundown' && !class_exists('Sundown\Markdown')) {
throw new InvalidConfigurationException('Sundown extension not installed or configured.');
}
}
}

View file

@ -27,7 +27,8 @@ class Light extends MarkdownParser
'code_block' => false,
'auto_link' => true,
'auto_mailto' => false,
'entities' => false
'entities' => false,
'no_html' => false,
);
}

View file

@ -27,7 +27,8 @@ class Medium extends MarkdownParser
'code_block' => true,
'auto_link' => true,
'auto_mailto' => false,
'entities' => false
'entities' => false,
'no_html' => false,
);
}

30
Parser/SundownParser.php Normal file
View file

@ -0,0 +1,30 @@
<?php
namespace Knp\Bundle\MarkdownBundle\Parser;
use Knp\Bundle\MarkdownBundle\MarkdownParserInterface;
use Sundown\Markdown;
/**
* SundownParser
*
* This class wraps the original Sundown parser to implement the KnpMardownBundle interface
*/
class SundownParser implements MarkdownParserInterface
{
private $parser;
public function __construct(Markdown $parser)
{
$this->parser = $parser;
}
/**
* {@inheritdoc}
*/
public function transform($text)
{
return $this->parser->render($text);
}
}

View file

@ -48,13 +48,23 @@ then configure the bundle to use it:
parser:
service: my.markdown.parser
This bundle comes with 4 parser services, all based on the same algorithm
but providing different levels of compliance to the markdown specification:
Alternatively if you are using the ``markdown.parser.sundown`` there are
options for enabling sundown extensions and render flags, see the
default Configuration with:
php app/console config:dump-reference knp_markdown
This bundle comes with 5 parser services, 4 based on the same algorithm
but providing different levels of compliance to the markdown specification,
and one which is uses the php sundown extension:
- markdown.parser.max // fully compliant = slower (default implementation)
- markdown.parser.medium // expensive and uncommon features dropped
- markdown.parser.light // expensive features dropped
- markdown.parser.min // most features dropped = faster
- markdown.parser.sundown // faster and fully compliant (recommended)
``markdown.parser.sundown`` requires [php sundown extension](https://github.com/chobie/php-sundown).
For more details, see the implementations in Parser/Preset.

View file

@ -4,11 +4,24 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="markdown.parser.min" class="Knp\Bundle\MarkdownBundle\Parser\Preset\Min" />
<service id="markdown.parser.light" class="Knp\Bundle\MarkdownBundle\Parser\Preset\Light" />
<service id="markdown.parser.medium" class="Knp\Bundle\MarkdownBundle\Parser\Preset\Medium" />
<service id="markdown.parser.max" class="Knp\Bundle\MarkdownBundle\Parser\Preset\Max" />
</services>
<services>
<service id="markdown.parser.min" class="Knp\Bundle\MarkdownBundle\Parser\Preset\Min" />
<service id="markdown.parser.light" class="Knp\Bundle\MarkdownBundle\Parser\Preset\Light" />
<service id="markdown.parser.medium" class="Knp\Bundle\MarkdownBundle\Parser\Preset\Medium" />
<service id="markdown.parser.max" class="Knp\Bundle\MarkdownBundle\Parser\Preset\Max" />
<service id="markdown.parser.sundown" public="false" class="Knp\Bundle\MarkdownBundle\Parser\SundownParser">
<argument type="service" id="markdown.sundown.base_parser"/>
</service>
<service id="markdown.sundown.base_parser" public="false" class="Sundown\Markdown">
<argument type="service" id="markdown.sundown.renderer"/>
<argument>%markdown.sundown.extensions%</argument>
</service>
<service id="markdown.sundown.renderer" public="false" class="Sundown\Render\HTML">
<argument>%markdown.sundown.render_flags%</argument>
</service>
</services>
</container>

View file

@ -15,6 +15,8 @@ class EscapingTest extends \PHPUnit_Framework_TestCase
public function testHtmlEscaping()
{
$this->markTestIncomplete('This tests a very deep escaping capability of the wrapped library @todo');
$text = <<<EOF
<a>a tag injection</a>
EOF;
@ -29,6 +31,8 @@ EOF;
public function testScriptEscaping()
{
$this->markTestIncomplete('This tests a very deep escaping capability of the wrapped library @todo');
$text = <<<EOF
<script>alert("haha");</script>
EOF;

View file

@ -1,23 +0,0 @@
<?php
$libDir = __DIR__.'/..';
$vendorDir = $libDir.'/vendor';
require_once $vendorDir.'/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
use Symfony\Component\ClassLoader\UniversalClassLoader;
$loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
'Symfony' => $vendorDir.'/symfony/src',
));
$loader->register();
spl_autoload_register(function($class) {
$class = ltrim($class, '\\');
if (0 === strpos($class, 'Knp\Bundle\MarkdownBundle\\')) {
$file = __DIR__.'/../'.str_replace('\\', '/', substr($class, strlen('Knp\Bundle\MarkdownBundle\\'))).'.php';
if (file_exists($file)) {
require $file;
}
}
});

View file

@ -1,7 +0,0 @@
<?php
if (file_exists($file = __DIR__.'/autoload.php')) {
require_once $file;
} elseif (file_exists($file = __DIR__.'/autoload.php.dist')) {
require_once $file;
}

View file

@ -18,12 +18,13 @@
],
"require": {
"php": ">=5.3.2",
"symfony/framework-bundle": ">=2.0,<2.2-dev"
"php": ">=5.3.3",
"symfony/framework-bundle": ">=2.0,<2.3-dev"
},
"suggest": {
"symfony/twig-bundle": "to use the Twig markdown filter"
"symfony/twig-bundle": "to use the Twig markdown filter",
"ext-sundown": "to use optional support for php-sundown extension instead of php implementation"
},
"autoload": {

View file

@ -9,7 +9,7 @@
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./Tests/bootstrap.php"
bootstrap="./vendor/autoload.php"
>
<testsuites>
<testsuite name="Markdown Test Suite">

22
vendor/vendors.php vendored
View file

@ -1,22 +0,0 @@
#!/usr/bin/env php
<?php
set_time_limit(0);
$vendorDir = __DIR__;
$deps = array(
array('symfony', 'https://github.com/symfony/symfony', isset($_SERVER['SYMFONY_VERSION']) ? $_SERVER['SYMFONY_VERSION'] : 'origin/master'),
);
foreach ($deps as $dep) {
list($name, $url, $rev) = $dep;
echo "> Installing/Updating $name\n";
$installDir = $vendorDir.'/'.$name;
if (!is_dir($installDir)) {
system(sprintf('git clone -q %s %s', escapeshellarg($url), escapeshellarg($installDir)));
}
system(sprintf('cd %s && git fetch -q origin && git reset --hard %s', escapeshellarg($installDir), escapeshellarg($rev)));
}