From 41a5a2043864e90b79d520ad5336f49a0c011bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Haso=C5=88?= Date: Thu, 16 Jul 2015 10:44:11 +0200 Subject: [PATCH] Created initial version of bundle --- .gitattributes | 6 ++ .gitignore | 3 + .php_cs | 28 +++++++ .travis.yml | 23 ++++++ CHANGELOG.md | 8 ++ LICENSE | 19 +++++ README.md | 30 +++++++ composer.json | 38 +++++++++ phpspec.yml.dist | 7 ++ spec/ConverterRegistrySpec.php | 14 ++++ .../Compiler/CommonMarkExtensionPassSpec.php | 56 +++++++++++++ .../DependencyInjection/ConfigurationSpec.php | 80 +++++++++++++++++++ .../WebuniCommonMarkExtensionSpec.php | 52 ++++++++++++ spec/WebuniCommonMarkBundleSpec.php | 38 +++++++++ src/ConverterRegistry.php | 37 +++++++++ .../Compiler/CommonMarkExtensionPass.php | 32 ++++++++ src/DependencyInjection/Configuration.php | 66 +++++++++++++++ .../WebuniCommonMarkExtension.php | 58 ++++++++++++++ src/Resources/config/services.xml | 29 +++++++ src/WebuniCommonMarkBundle.php | 24 ++++++ 20 files changed, 648 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .php_cs create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 composer.json create mode 100644 phpspec.yml.dist create mode 100644 spec/ConverterRegistrySpec.php create mode 100644 spec/DependencyInjection/Compiler/CommonMarkExtensionPassSpec.php create mode 100644 spec/DependencyInjection/ConfigurationSpec.php create mode 100644 spec/DependencyInjection/WebuniCommonMarkExtensionSpec.php create mode 100644 spec/WebuniCommonMarkBundleSpec.php create mode 100644 src/ConverterRegistry.php create mode 100644 src/DependencyInjection/Compiler/CommonMarkExtensionPass.php create mode 100644 src/DependencyInjection/Configuration.php create mode 100644 src/DependencyInjection/WebuniCommonMarkExtension.php create mode 100644 src/Resources/config/services.xml create mode 100644 src/WebuniCommonMarkBundle.php diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..895b080 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +/spec export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.php_cs export-ignore +/.travis.yml export-ignore +/phpspec.yml.dist export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b04796 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/composer.lock +/vendor/ +phpspec.yml diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..7cd930f --- /dev/null +++ b/.php_cs @@ -0,0 +1,28 @@ + + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +EOF; + +Symfony\CS\Fixer\Contrib\HeaderCommentFixer::setHeader($header); + +$finder = Symfony\CS\Finder\DefaultFinder::create() + ->in(['src', 'spec']) +; + +return Symfony\CS\Config\Config::create() + ->level(Symfony\CS\FixerInterface::SYMFONY_LEVEL) + ->fixers([ + 'header_comment', + 'align_double_arrow', + 'newline_after_open_tag', + 'ordered_use', + 'short_array_syntax', + ]) + ->finder($finder) +; diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ad6dcb8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,23 @@ +language: php + +sudo: false + +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - hhvm + +cache: + directories: + - $HOME/.composer/cache + - vendor + +before_script: + - composer self-update + - composer install --prefer-source --no-interaction + +script: + - php vendor/bin/phpspec run + - php vendor/bin/php-cs-fixer fix --dry-run diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e31ecb1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +CHANGELOG +========= + +0.1.0 +----- + + * Initial version + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..641237b --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 Martin Hasoň + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6aabd17 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +CommonMark Bundle +================= + +[![Packagist](https://img.shields.io/packagist/v/webuni/commonmark-bundle.svg?style=flat-square)](https://packagist.org/packages/webuni/commonmark-bundle) +[![Build Status](https://img.shields.io/travis/webuni/commonmark-bundle.svg?style=flat-square)](https://travis-ci.org/webuni/commonmark-bundle) +[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/webuni/commonmark-bundle.svg?style=flat-square)](https://scrutinizer-ci.com/g/webuni/commonmark-bundle) +[![SensioLabsInsight](https://img.shields.io/sensiolabs/i/29bd3e8e-1b60-4ad5-aa6a-e04efb41e9e2.svg?style=flat-square)](https://insight.sensiolabs.com/projects/29bd3e8e-1b60-4ad5-aa6a-e04efb41e9e2) + +Symfony bundle that integrates the league/commonmark markdown parser. + +Installation +------------ + +This project can be installed via Composer: + + composer require webuni/commonmark-bundle + +Add WebuniCommonMarkBundle to your application kernel + +```php +// app/AppKernel.php +public function registerBundles() +{ + return array( + // ... + new Webuni\Bundle\CommonMarkBundle\WebuniCommonMarkBundle(), + // ... + ); +} +``` diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..12924cd --- /dev/null +++ b/composer.json @@ -0,0 +1,38 @@ +{ + "name": "webuni/commonmark-bundle", + "type": "symfony-bundle", + "description": "The table extension for CommonMark PHP implementation", + "keywords": ["markdown","symfony","bundle","commonmark"], + "homepage": "https://github.com/webuni/commonmark-bundle", + "license": "MIT", + "authors": [ + { + "name": "Martin Hasoň", + "email": "martin.hason@gmail.com", + "role": "Lead Developer" + } + ], + "require": { + "php": ">=5.4", + "symfony/http-kernel": "^2.3", + "symfony/config": "^2.3", + "symfony/dependency-injection": "^2.3", + "league/commonmark": "~0.7" + }, + "require-dev": { + "phpspec/phpspec": "^2.2", + "coduo/phpspec-data-provider-extension": "^1.0", + "bossa/phpspec2-expect": "^1.0", + "fabpot/php-cs-fixer": "^1.9" + }, + "autoload": { + "psr-4": { + "Webuni\\Bundle\\CommonMarkBundle\\": "src" + } + }, + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + } +} diff --git a/phpspec.yml.dist b/phpspec.yml.dist new file mode 100644 index 0000000..9b7e63a --- /dev/null +++ b/phpspec.yml.dist @@ -0,0 +1,7 @@ +suites: + default: + namespace: Webuni\Bundle\CommonMarkBundle + psr4_prefix: Webuni\Bundle\CommonMarkBundle + +extensions: + - Coduo\PhpSpec\DataProvider\DataProviderExtension diff --git a/spec/ConverterRegistrySpec.php b/spec/ConverterRegistrySpec.php new file mode 100644 index 0000000..41b9023 --- /dev/null +++ b/spec/ConverterRegistrySpec.php @@ -0,0 +1,14 @@ +shouldHaveType('Webuni\Bundle\CommonMarkBundle\ConverterRegistry'); + } +} diff --git a/spec/DependencyInjection/Compiler/CommonMarkExtensionPassSpec.php b/spec/DependencyInjection/Compiler/CommonMarkExtensionPassSpec.php new file mode 100644 index 0000000..2929610 --- /dev/null +++ b/spec/DependencyInjection/Compiler/CommonMarkExtensionPassSpec.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace spec\Webuni\Bundle\CommonMarkBundle\DependencyInjection\Compiler; + +use PhpSpec\ObjectBehavior; +use Prophecy\Argument; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * @mixin CompilerPassInterface + */ +class CommonMarkExtensionPassSpec extends ObjectBehavior +{ + const SERVICE_ENV = 'webuni_commonmark.default_environment'; + const EXTENSION_TAG = 'webuni_commonmark.extension'; + + public function it_is_initializable() + { + $this->shouldHaveType('Webuni\Bundle\CommonMarkBundle\DependencyInjection\Compiler\CommonMarkExtensionPass'); + } + + /** + * @param Symfony\Component\DependencyInjection\ContainerBuilder $container + */ + public function it_should_not_register_extension_if_extension_is_not_loaded($container) + { + $container->hasDefinition(self::SERVICE_ENV)->willReturn(false); + $container->getDefinition(self::SERVICE_ENV)->shouldNotBeCalled(); + + $this->process($container); + } + + /** + * @param Symfony\Component\DependencyInjection\ContainerBuilder $container + * @param Symfony\Component\DependencyInjection\Definition $definition + */ + public function it_should_register_extension($container, $definition) + { + $container->hasDefinition(self::SERVICE_ENV)->willReturn(true); + $container->getDefinition(self::SERVICE_ENV)->willReturn($definition); + $container->findTaggedServiceIds(self::EXTENSION_TAG)->willReturn(['my_service' => []]); + + $definition->addMethodCall('addExtension', Argument::containing(Argument::type('Symfony\Component\DependencyInjection\Reference')))->shouldBeCalled(); + + $this->process($container); + } +} diff --git a/spec/DependencyInjection/ConfigurationSpec.php b/spec/DependencyInjection/ConfigurationSpec.php new file mode 100644 index 0000000..b34dcd0 --- /dev/null +++ b/spec/DependencyInjection/ConfigurationSpec.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace spec\Webuni\Bundle\CommonMarkBundle\DependencyInjection; + +use PhpSpec\ObjectBehavior; +use Symfony\Component\Config\Definition\Processor; +use Webuni\Bundle\CommonMarkBundle\DependencyInjection\Configuration; + +/** + * @mixin Configuration + */ +class ConfigurationSpec extends ObjectBehavior +{ + public function it_is_initializable() + { + $this->shouldHaveType('Webuni\Bundle\CommonMarkBundle\DependencyInjection\Configuration'); + } + + /** + * @dataProvider get_configuration + */ + public function it_should_process_configuration(array $config, array $expected) + { + $processor = new Processor(); + + expect($processor->processConfiguration(new Configuration(), [$config]))->shouldBe($expected); + } + + public function get_configuration() + { + $converter = [ + 'converter' => 'webuni_commonmark.converter', + 'environment' => 'webuni_commonmark.default_environment', + 'parser' => 'webuni_commonmark.docparser', + 'renderer' => 'webuni_commonmark.htmlrenderer', + 'config' => [], + 'extensions' => [], + ]; + + return [ + [ + [], + [ + 'default_converter' => 'default', + 'converters' => [ + 'default' => $converter, + ] + ], + ], + [ + ['converters' => ['custom' => null,]], + [ + 'converters' => [ + 'default' => $converter, + 'custom' => $converter, + ], + 'default_converter' => 'default', + ], + ], + [ + ['converters' => ['default' => ['config' => ['foo' => 'bar']]]], + [ + 'converters' => [ + 'default' => ['config' => ['foo' => 'bar']] + $converter, + ], + 'default_converter' => 'default', + ], + ], + ]; + } +} diff --git a/spec/DependencyInjection/WebuniCommonMarkExtensionSpec.php b/spec/DependencyInjection/WebuniCommonMarkExtensionSpec.php new file mode 100644 index 0000000..b38249a --- /dev/null +++ b/spec/DependencyInjection/WebuniCommonMarkExtensionSpec.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace spec\Webuni\Bundle\CommonMarkBundle\DependencyInjection; + +use PhpSpec\ObjectBehavior; +use Prophecy\Argument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Webuni\Bundle\CommonMarkBundle\DependencyInjection\WebuniCommonMarkExtension; + +/** + * @mixin WebuniCommonMarkExtension + */ +class WebuniCommonMarkExtensionSpec extends ObjectBehavior +{ + public function it_is_initializable() + { + $this->shouldHaveType('Webuni\Bundle\CommonMarkBundle\DependencyInjection\WebuniCommonMarkExtension'); + } + + public function it_should_have_correct_name() + { + $this->getAlias()->shouldBe('webuni_commonmark'); + } + + public function it_should_create_default_converter() + { + $builder = new ContainerBuilder(); + + $this->load([], $builder); + + $converters = $builder->getDefinition('webuni_commonmark.converter_registry')->getArgument(0); + expect($converters)->shouldHaveKey('default'); + } + + public function it_should_be_compilabl() + { + $builder = new ContainerBuilder(); + + $this->load([], $builder); + $builder->compile(); + var_dump($builder->get('webuni_commonmark.converter_registry')); + } +} diff --git a/spec/WebuniCommonMarkBundleSpec.php b/spec/WebuniCommonMarkBundleSpec.php new file mode 100644 index 0000000..cc9b4b6 --- /dev/null +++ b/spec/WebuniCommonMarkBundleSpec.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace spec\Webuni\Bundle\CommonMarkBundle; + +use PhpSpec\ObjectBehavior; +use Prophecy\Argument; + +class WebuniCommonMarkBundleSpec extends ObjectBehavior +{ + public function it_is_initializable() + { + $this->shouldHaveType('Webuni\Bundle\CommonMarkBundle\WebuniCommonMarkBundle'); + } + + public function it_should_implements_symfony_bundle() + { + $this->shouldBeAnInstanceOf('Symfony\Component\HttpKernel\Bundle\Bundle'); + } + + /** + * @param Symfony\Component\DependencyInjection\ContainerBuilder $container + */ + public function it_should_register_dependency_injection_compiler_for_commonmark_extensions($container) + { + $container->addCompilerPass(Argument::type('Webuni\Bundle\CommonMarkBundle\DependencyInjection\Compiler\CommonMarkExtensionPass'))->shouldBeCalled(); + + $this->build($container); + } +} diff --git a/src/ConverterRegistry.php b/src/ConverterRegistry.php new file mode 100644 index 0000000..c9704ae --- /dev/null +++ b/src/ConverterRegistry.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Webuni\Bundle\CommonMarkBundle; + +class ConverterRegistry +{ + private $converters; + + /** + * Constructor. + * + * @param Converter[] $converters + */ + public function __construct(array $converters = []) + { + $this->converters = $converters; + } + + public function has($name) + { + return isset($this->converters[$name]); + } + + public function get($name) + { + return $this->converters[$name]; + } +} diff --git a/src/DependencyInjection/Compiler/CommonMarkExtensionPass.php b/src/DependencyInjection/Compiler/CommonMarkExtensionPass.php new file mode 100644 index 0000000..21ade59 --- /dev/null +++ b/src/DependencyInjection/Compiler/CommonMarkExtensionPass.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Webuni\Bundle\CommonMarkBundle\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class CommonMarkExtensionPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (false === $container->hasDefinition('webuni_commonmark.default_environment')) { + return; + } + + $definition = $container->getDefinition('webuni_commonmark.default_environment'); + foreach ($container->findTaggedServiceIds('webuni_commonmark.extension') as $id => $tag) { + $alias = isset($tag[0]['alias']) ? $tag[0]['alias'] : $id; + $definition->addMethodCall('addExtension', [new Reference($id), $alias]); + } + } +} diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php new file mode 100644 index 0000000..6727796 --- /dev/null +++ b/src/DependencyInjection/Configuration.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Webuni\Bundle\CommonMarkBundle\DependencyInjection; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +class Configuration implements ConfigurationInterface +{ + public function getConfigTreeBuilder() + { + $builder = new TreeBuilder(); + + $builder->root('webuni_commonmark', 'array') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('default_converter')->defaultValue('default')->end() + ->arrayNode('converters') + ->defaultValue(['default' => [ + 'converter' => 'webuni_commonmark.converter', + 'environment' => 'webuni_commonmark.default_environment', + 'parser' => 'webuni_commonmark.docparser', + 'renderer' => 'webuni_commonmark.htmlrenderer', + 'config' => [], + 'extensions' => [] + ]]) + ->beforeNormalization() + ->always() + ->then(function ($v) { + return array_merge(['default' => null], $v); + }) + ->end() + ->prototype('array') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('converter')->defaultValue('webuni_commonmark.converter')->end() + ->scalarNode('environment')->defaultValue('webuni_commonmark.default_environment')->end() + ->scalarNode('parser')->defaultValue('webuni_commonmark.docparser')->end() + ->scalarNode('renderer')->defaultValue('webuni_commonmark.htmlrenderer')->end() + ->arrayNode('config') + ->prototype('variable') + ->defaultValue([]) + ->end() + ->end() + ->arrayNode('extensions') + ->defaultValue([]) + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + + return $builder; + } +} diff --git a/src/DependencyInjection/WebuniCommonMarkExtension.php b/src/DependencyInjection/WebuniCommonMarkExtension.php new file mode 100644 index 0000000..90dba07 --- /dev/null +++ b/src/DependencyInjection/WebuniCommonMarkExtension.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Webuni\Bundle\CommonMarkBundle\DependencyInjection; + +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\DefinitionDecorator; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension; + +class WebuniCommonMarkExtension extends ConfigurableExtension +{ + protected function loadInternal(array $mergedConfig, ContainerBuilder $container) + { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); + + $converters = []; + foreach ($mergedConfig['converters'] as $name => $config) { + $environment = new DefinitionDecorator($config['environment']); + $environment->setClass($container->getDefinition($config['environment'])->getClass()); + $environment->addMethodCall('mergeConfig', [$config['config']]); + $environment->addTag('webuni_commonmark.environment_extensions', $config['extensions']); + + $parser = new DefinitionDecorator($config['parser']); + $parser->setClass($container->getDefinition($config['parser'])->getClass()); + $parser->replaceArgument(0, $environment); + + $renderer = new DefinitionDecorator($config['renderer']); + $renderer->setClass($container->getDefinition($config['renderer'])->getClass()); + $renderer->replaceArgument(0, $environment); + + $converter = new DefinitionDecorator($config['converter']); + $converter->setClass($container->getDefinition($config['converter'])->getClass()); + $converter->replaceArgument(0, $parser); + $converter->replaceArgument(1, $renderer); + + $converters[$name] = $converter; + } + + $registry = $container->getDefinition('webuni_commonmark.converter_registry'); + $registry->replaceArgument(0, $converters); + } + + public function getAlias() + { + return 'webuni_commonmark'; + } +} diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml new file mode 100644 index 0000000..f74602f --- /dev/null +++ b/src/Resources/config/services.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/WebuniCommonMarkBundle.php b/src/WebuniCommonMarkBundle.php new file mode 100644 index 0000000..d5f8bfe --- /dev/null +++ b/src/WebuniCommonMarkBundle.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Webuni\Bundle\CommonMarkBundle; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; +use Webuni\Bundle\CommonMarkBundle\DependencyInjection\Compiler\CommonMarkExtensionPass; + +class WebuniCommonMarkBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + $container->addCompilerPass(new CommonMarkExtensionPass()); + } +}