[
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\non: [push, pull_request]\n\njobs:\n  run:\n    runs-on: 'ubuntu-latest'\n    strategy:\n      matrix:\n        php-versions: ['7.2', '7.3', '7.4', '8.0']\n\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v2\n\n    - name: Setup PHP\n      uses: shivammathur/setup-php@v2\n      with:\n        php-version: ${{ matrix.php-versions }}\n        coverage: xdebug\n\n    - run: mkdir -p build/logs\n\n    - name: Install composer dependencies\n      uses: ramsey/composer-install@v1\n\n    - name: Run Tests\n      run: vendor/bin/phpunit\n"
  },
  {
    "path": ".gitignore",
    "content": "vendor\ncomposer.phar\ncomposer.lock\nphpunit.xml\n.phpunit.result.cache\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "CHANGELOG\n=========\n\n3.4.1\n-----\n\n- **Added**: Define implements \\Twig\\Extension\\ExtensionInterface\n\n3.4.0\n-----\n\n - **Added**: PHP 8.0 compatibility\n - **Changed**: Migrate test suite from Travis to GitHub\n\n3.3.1\n-----\n\n- **FIX**: Fix invalid cacheDir for GH engine on Windows\n\n3.3.0\n-----\n\n- **Added**: Support for Twig 3\n\n3.2.0\n\n- **Added**: Support for HMTL escaping in ParsdownEngine\n\n2.1.0\n-----\n\n- **FIX**: Upgrade to Twig 2.7 and namespace, due to [a security issue](https://symfony.com/blog/twig-sandbox-information-disclosure)\n\n2.0.0\n-----\n\n- **BC**: Require Twig v1.12, in order to replace deprecated Twig_Filter_Method with Twig_SimpleFilter\n- **Added**: Add support for ParsedownEngine\n\n1.2.0\n-----\n\n- **Added**: Add support for GitHub's markdown engine\n\n1.1.0\n-----\n\n- **Added**: Add support for PHP League CommonMark engine\n\n1.0.0\n-----\n\n- **BC**: Remove deprecated dflydev-markdown parser\n"
  },
  {
    "path": "README.md",
    "content": "Twig Markdown Extension\n=======================\n\n[![Build Status](https://github.com/aptoma/twig-markdown/workflows/Test/badge.svg?branch=master)](https://github.com/aptoma/twig-markdown/actions?query=branch%3Amaster)\n\n**THIS EXTENSION IS NO LONGER MAINTAINED, AND WE WILL NOT MAKE ANY NEW RELEASES. IF ANYONE WANTS TO TAKE OVER, PLEASE MAKE A FORK AND PUBLISH A NEW PACKAGE, AND WE'LL LINK TO THE NEW VERSION.**\n\nTwig Markdown extension provides a new filter and a tag to allow parsing of\ncontent as Markdown in [Twig][1] templates.\n\nThis extension could be integrated with several Markdown parser as it provides an interface, which allows you to customize your Markdown parser.\n\n### Supported parsers\n\n * [michelf/php-markdown](https://github.com/michelf/php-markdown) (+ MarkdownExtra)\n * [league/commonmark](http://commonmark.thephpleague.com/)\n * [KnpLabs/php-github-api](https://github.com/KnpLabs/php-github-api)\n * [erusev/parsedown](https://github.com/erusev/parsedown)\n\n## Features\n\n * Filter support `{{ \"# Heading Level 1\"|markdown }}`\n * Tag support `{% markdown %}{% endmarkdown %}`\n\nWhen used as a tag, the indentation level of the first line sets the default indentation level for the rest of the tag content.\nFrom this indentation level, all same indentation or outdented levels text will be transformed as regular text.\n\nThis feature allows you to write your Markdown content at any indentation level without caring of Markdown internal transformation:\n\n```php\n<div>\n    <h1 class=\"someClass\">{{ title }}</h1>\n\n    {% markdown %}\n    This is a list that is indented to match the context around the markdown tag:\n\n    * List item 1\n    * List item 2\n        * Sub List Item\n            * Sub Sub List Item\n\n    The following block will be transformed as code, as it is indented more than the\n    surrounding content:\n\n        $code = \"good\";\n\n    {% endmarkdown %}\n\n</div>\n```\n\n## Installation\n\nRun the composer command to install the latest stable version:\n\n```bash\ncomposer require aptoma/twig-markdown\n```\n\nOr update your `composer.json`:\n\n```json\n{\n    \"require\": {\n        \"aptoma/twig-markdown\": \"~3.0\"\n    }\n}\n```\n\nYou can choose to provide your own Markdown engine, although we recommend\nusing [michelf/php-markdown](https://github.com/michelf/php-markdown):\n\n```bash\ncomposer require michelf/php-markdown ~1.8\n```\n\n```json\n{\n    \"require\": {\n        \"michelf/php-markdown\": \"~1.8\"\n    }\n}\n```\n\nYou may also use the [PHP League CommonMark engine](http://commonmark.thephpleague.com/):\n\n```bash\ncomposer require league/commonmark ~0.19\n```\n\n```json\n{\n    \"require\": {\n        \"league/commonmark\": \"~0.19\"\n    }\n}\n```\n\n## Usage\n\n### Twig Extension\n\nThe Twig extension provides the `markdown` tag and filter support.\n\nAssuming that you are using [composer](http://getcomposer.org) autoloading,\nadd the extension to the Twig environment:\n\n```php\n\nuse Aptoma\\Twig\\Extension\\MarkdownExtension;\nuse Aptoma\\Twig\\Extension\\MarkdownEngine;\n\n$engine = new MarkdownEngine\\MichelfMarkdownEngine();\n\n$twig->addExtension(new MarkdownExtension($engine));\n```\n\n### Twig Token Parser\n\nThe Twig token parser provides the `markdown` tag only!\n\n```php\nuse Aptoma\\Twig\\TokenParser\\MarkdownTokenParser;\n\n$twig->addTokenParser(new MarkdownTokenParser());\n```\n\n### Symfony\n\nTo use this extension in a [Symfony 3/4 app](https://symfony.com) (including [Pimcore](https://pimcore.com/)), add the following snippet to your app's `app/config/services.yml` file:\n\n```yaml\nservices:\n    # ...\n\n    markdown.engine:\n        class: Aptoma\\Twig\\Extension\\MarkdownEngine\\MichelfMarkdownEngine\n    twig.markdown:\n        class: Aptoma\\Twig\\Extension\\MarkdownExtension\n        arguments: ['@markdown.engine']\n        tags:\n            - { name: twig.extension }\n```\n\n### GitHub Markdown Engine\n\n`MarkdownEngine\\GitHubMarkdownEngine` provides an interface to GitHub's markdown engine using their public API via [`KnpLabs\\php-github-api`][2]. To reduce API calls, rendered documents are hashed and cached in the filesystem. You can pass a GitHub repository and the path to be used for caching to the constructor:\n\n```php\nuse Aptoma\\Twig\\Extension\\MarkdownEngine;\n\n$engine = new MarkdownEngine\\GitHubMarkdownEngine(\n    'aptoma/twig-markdown', // The GitHub repository to use as a context\n    true,                   // Whether to use GitHub's Flavored Markdown (GFM)\n    '/tmp/markdown-cache',  // Path on filesystem to store rendered documents\n);\n```\n\nIn order to authenticate the API client (for instance), it's possible to pass an own instance of `\\GitHub\\Client` instead of letting the engine create one itself:\n\n```php\n$client = new \\Github\\Client;\n$client->authenticate('GITHUB_CLIENT_ID', 'GITHUB_CLIENT_SECRET', \\Github\\Client::AUTH_URL_CLIENT_ID);\n\n$engine = new MarkdownEngine\\GitHubMarkdownEngine('aptoma/twig-markdown', true, '/tmp/markdown-cache', $client);\n```\n\n### Using a different Markdown parser engine\n\nIf you want to use a different Markdown parser, you need to create an adapter\nthat implements `Aptoma\\Twig\\Extension\\MarkdownEngineInterface.php`. Have\na look at `Aptoma\\Twig\\Extension\\MarkdownEngine\\MichelfMarkdownEngine` for an\nexample.\n\n## Tests\n\nThe test suite uses PHPUnit:\n\n    $ phpunit\n\n## License\n\nTwig Markdown Extension is licensed under the MIT license.\n\n[1]: http://twig.sensiolabs.org\n[2]: https://github.com/knplabs/php-github-api\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"aptoma/twig-markdown\",\n    \"description\": \"Twig extension to work with Markdown content\",\n    \"keywords\": [\"twig\", \"markdown\"],\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"Gunnar Lium\",\n            \"email\": \"gunnar@aptoma.com\"\n        },\n        {\n            \"name\": \"Joris Berthelot\",\n            \"email\": \"joris@berthelot.tel\"\n        }\n    ],\n    \"require\": {\n        \"php\": \"^7.0|^8.0\",\n        \"twig/twig\": \"^2.7.0|^3.0\"\n    },\n    \"require-dev\": {\n        \"php\": \"^7.2.5|^8.0\",\n        \"phpunit/phpunit\": \"~6.0|~5.0|~8.0\",\n        \"michelf/php-markdown\": \"~1\",\n        \"league/commonmark\": \"~0.5\",\n        \"knplabs/github-api\": \"~3.0\",\n        \"erusev/parsedown\": \"^1.6\",\n        \"guzzlehttp/guzzle\": \"^7.2\",\n        \"http-interop/http-factory-guzzle\": \"^1.0\"\n    },\n    \"suggest\": {\n        \"michelf/php-markdown\": \"Original Markdown engine with MarkdownExtra.\",\n        \"knplabs/github-api\": \"Needed for using GitHub's Markdown engine provided through their API.\"\n    },\n    \"autoload\": {\n        \"psr-0\": { \"Aptoma\": \"src/\" }\n    }\n}\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit backupGlobals=\"false\"\n         backupStaticAttributes=\"false\"\n         colors=\"true\"\n         convertErrorsToExceptions=\"true\"\n         convertNoticesToExceptions=\"true\"\n         convertWarningsToExceptions=\"true\"\n         processIsolation=\"false\"\n         stopOnFailure=\"false\"\n         bootstrap=\"vendor/autoload.php\"\n>\n    <testsuites>\n        <testsuite name=\"Aptoma Markdown Test Suite\">\n            <directory>./tests/</directory>\n        </testsuite>\n    </testsuites>\n    <filter>\n        <whitelist>\n            <directory>src/</directory>\n        </whitelist>\n    </filter>\n</phpunit>\n"
  },
  {
    "path": "src/Aptoma/Twig/Extension/MarkdownEngine/GitHubMarkdownEngine.php",
    "content": "<?php\nnamespace Aptoma\\Twig\\Extension\\MarkdownEngine;\n\nuse Aptoma\\Twig\\Extension\\MarkdownEngineInterface;\n\n/**\n * GithubMarkdownEngine.php\n *\n * Maps GitHub's Markdown engine API to Aptoma\\Twig Markdown Extension using\n * KnpLabs\\php-github-api.\n *\n * @author Lukas W <lukaswhl@gmail.com>\n */\nclass GitHubMarkdownEngine implements MarkdownEngineInterface\n{\n    /**\n     * Constructor\n     *\n     * @param string $contextRepo The repository context. Pass a GitHub repo\n     *        such as 'aptoma/twig-markdown' to render e.g. issues #23 in the\n     *        context of the repo.\n     * @param bool $gfm Whether to use GitHub's Flavored Markdown or the\n     *        standard markdown. Default is true.\n     * @param string $cacheDir Location on disk where rendered documents should\n     *        be stored. Defaults to 'github-markdown-cache' folder in system\n     *        temp directory if no path is provided.\n     * @param \\Github\\Client $client Client object to use. A new Github\\Client()\n     *        object is constructed automatically if $client is null.\n     */\n    public function __construct($contextRepo = null, $gfm = true, $cacheDir = null, \\GitHub\\Client $client=null)\n    {\n        $this->repo = $contextRepo;\n        $this->mode = $gfm ? 'gfm' : 'markdown';\n        if (is_null($cacheDir)) {\n            $cacheDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'github-markdown-cache';\n        }\n        $this->cacheDir = rtrim($cacheDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;\n        if (!is_dir($this->cacheDir)) {\n            @mkdir($this->cacheDir, 0777, true);\n        }\n\n        if ($client === null) {\n            $client = new \\Github\\Client();\n        }\n        $this->api = $client->api('markdown');\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function transform($content)\n    {\n        $cacheFile = $this->getCachePath($content);\n        if (file_exists($cacheFile)) {\n            return file_get_contents($cacheFile);;\n        }\n\n        $response = $this->api->render($content, $this->mode, $this->repo);\n        file_put_contents($cacheFile, $response);\n        return $response;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getName()\n    {\n        return 'KnpLabs\\php-github-api';\n    }\n\n    private function getCachePath($content)\n    {\n        return $this->cacheDir . md5($content) . '_' . $this->mode. '_' . str_replace('/', '.', $this->repo);\n    }\n\n    private $api;\n    private $cacheDir;\n    private $repo;\n    private $mode;\n}\n"
  },
  {
    "path": "src/Aptoma/Twig/Extension/MarkdownEngine/MichelfMarkdownEngine.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension\\MarkdownEngine;\n\nuse Aptoma\\Twig\\Extension\\MarkdownEngineInterface;\nuse Michelf\\MarkdownExtra;\n\n/**\n * MichelfMarkdownEngine.php\n *\n * Maps Michelf\\MarkdownExtra to Aptoma\\Twig Markdown Extension\n *\n * @author Joris Berthelot <joris@berthelot.tel>\n */\nclass MichelfMarkdownEngine implements MarkdownEngineInterface\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function transform($content)\n    {\n        return MarkdownExtra::defaultTransform($content);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getName()\n    {\n        return 'Michelf\\Markdown';\n    }\n}\n"
  },
  {
    "path": "src/Aptoma/Twig/Extension/MarkdownEngine/PHPLeagueCommonMarkEngine.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension\\MarkdownEngine;\n\nuse Aptoma\\Twig\\Extension\\MarkdownEngineInterface;\nuse League\\CommonMark\\CommonMarkConverter;\n\n/**\n * PHPLeagueCommonMarkEngine.php\n *\n * Maps League\\CommonMark\\CommonMarkConverter to Aptoma\\Twig Markdown Extension\n *\n * @author Casey McLaughlin <caseyamcl@gmail.com>\n */\nclass PHPLeagueCommonMarkEngine implements MarkdownEngineInterface\n{\n    /**\n     * @var \\League\\CommonMark\\CommonMarkConverter\n     */\n    private $converter;\n\n    /**\n     * Constructor\n     *\n     * Accepts CommonMarkConverter or creates one automatically\n     *\n     * @param \\League\\CommonMark\\CommonMarkConverter $converter\n     */\n    public function __construct(CommonMarkConverter $converter = null)\n    {\n        $this->converter = $converter ?: new CommonMarkConverter();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function transform($content)\n    {\n        return $this->converter->convertToHtml($content);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getName()\n    {\n        return 'League\\CommonMark';\n    }\n}\n"
  },
  {
    "path": "src/Aptoma/Twig/Extension/MarkdownEngine/ParsedownEngine.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension\\MarkdownEngine;\n\nuse Aptoma\\Twig\\Extension\\MarkdownEngineInterface;\nuse Parsedown;\n\n/**\n * ParsedownEngine.php\n *\n * Maps erusev/parsedown to Aptoma\\Twig Markdown Extension\n *\n * @author Sébastien Lourseau <https://github.com/SebLours>\n */\nclass ParsedownEngine implements MarkdownEngineInterface\n{\n    /**\n     * @var Parsedown\n     */\n    protected $engine;\n\n    /**\n     * @param string|null $instanceName\n     */\n    public function __construct($instanceName = null)\n    {\n        $this->engine = Parsedown::instance($instanceName);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function transform($content)\n    {\n        return $this->engine->parse($content);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getName()\n    {\n        return 'erusev/parsedown';\n    }\n    \n    /**\n     * Turn on/off escaping within the generated HTML. Should be\n     * turned on for untrusted user input.\n     *\n     * @param bool $bool Flag to set Safe Mode to\n     */\n    public function setSafeMode($bool)\n    {\n        $this->engine->setSafeMode($bool === true);\n    }\n    \n    /**\n     * Turn on/off escaping HTML in trusted user input.\n     *\n     * @param bool $bool Flag to set markup escaped to\n     */\n    public function setMarkupEscaped($bool)\n    {\n        $this->engine->setMarkupEscaped($bool === true);\n    }\n}\n"
  },
  {
    "path": "src/Aptoma/Twig/Extension/MarkdownEngineInterface.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension;\n\n/**\n * MarkdownEngineInterface.php\n *\n * Provide software interface to maps various Markdown engines\n *\n * @author Joris Berthelot <joris@berthelot.tel>\n */\ninterface MarkdownEngineInterface\n{\n    /**\n     * Transforms the given markdown data in HTML\n     *\n     * @param string $content Markdown data\n     * @return string\n     */\n    public function transform($content);\n\n    /**\n     * Return Markdown engine vendor ID\n     *\n     * @return string\n     */\n    public function getName();\n}\n"
  },
  {
    "path": "src/Aptoma/Twig/Extension/MarkdownExtension.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension;\n\nuse Aptoma\\Twig\\TokenParser\\MarkdownTokenParser;\n\n/**\n * MarkdownExtension provides support for Markdown.\n *\n * @author Gunnar Lium <gunnar@aptoma.com>\n * @author Joris Berthelot <joris@berthelot.tel>\n */\nclass MarkdownExtension extends \\Twig\\Extension\\AbstractExtension implements \\Twig\\Extension\\ExtensionInterface\n{\n\n    /**\n     * @var MarkdownEngineInterface $markdownEngine\n     */\n    private $markdownEngine;\n\n    /**\n     * @param MarkdownEngineInterface $markdownEngine The Markdown parser engine\n     */\n    public function __construct(MarkdownEngineInterface $markdownEngine)\n    {\n        $this->markdownEngine = $markdownEngine;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getFilters()\n    {\n        return array(\n            new \\Twig\\TwigFilter(\n                'markdown',\n                array($this, 'parseMarkdown'),\n                array('is_safe' => array('html'))\n            )\n        );\n    }\n\n    /**\n     * Transform Markdown content to HTML\n     *\n     * @param string $content The Markdown content to be transformed\n     * @return string The result of the Markdown engine transformation\n     */\n    public function parseMarkdown($content)\n    {\n        return $this->markdownEngine->transform($content);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getTokenParsers()\n    {\n        return array(new MarkdownTokenParser());\n    }\n}\n"
  },
  {
    "path": "src/Aptoma/Twig/Node/MarkdownNode.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Node;\n\n/**\n * Represents a markdown node.\n *\n * It parses content as Markdown.\n *\n * @author Gunnar Lium <gunnar@aptoma.com>\n * @author Joris Berthelot <joris@berthelot.tel>\n */\nclass MarkdownNode extends \\Twig\\Node\\Node\n{\n    public function __construct(\\Twig\\Node\\Node $body, $lineno, $tag = 'markdown')\n    {\n        parent::__construct(array('body' => $body), array(), $lineno, $tag);\n    }\n\n    /**\n     * Compiles the node to PHP.\n     *\n     * @param \\Twig\\Compiler A Twig\\Compiler instance\n     */\n    public function compile(\\Twig\\Compiler $compiler)\n    {\n        $compiler\n            ->addDebugInfo($this)\n            ->write('ob_start();' . PHP_EOL)\n            ->subcompile($this->getNode('body'))\n            ->write('$content = ob_get_clean();' . PHP_EOL)\n            ->write('preg_match(\"/^\\s*/\", $content, $matches);' . PHP_EOL)\n            ->write('$lines = explode(\"\\n\", $content);' . PHP_EOL)\n            ->write('$content = preg_replace(\\'/^\\' . $matches[0]. \\'/\\', \"\", $lines);' . PHP_EOL)\n            ->write('$content = join(\"\\n\", $content);' . PHP_EOL)\n            ->write('echo $this->env->getExtension(\\'Aptoma\\Twig\\Extension\\MarkdownExtension\\')->parseMarkdown($content);' . PHP_EOL);\n    }\n}\n"
  },
  {
    "path": "src/Aptoma/Twig/TokenParser/MarkdownTokenParser.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\TokenParser;\n\nuse Aptoma\\Twig\\Node\\MarkdownNode;\n\n/**\n * @author Gunnar Lium <gunnar@aptoma.com>\n * @author Joris Berthelot <joris@berthelot.tel>\n */\nclass MarkdownTokenParser extends \\Twig\\TokenParser\\AbstractTokenParser\n{\n    /**\n     * {@inheritdoc}\n     */\n    public function parse(\\Twig\\Token $token)\n    {\n        $lineno = $token->getLine();\n\n        $this->parser->getStream()->expect(\\Twig\\Token::BLOCK_END_TYPE);\n        $body = $this->parser->subparse(array($this, 'decideMarkdownEnd'), true);\n        $this->parser->getStream()->expect(\\Twig\\Token::BLOCK_END_TYPE);\n\n        return new MarkdownNode($body, $lineno, $this->getTag());\n    }\n\n    /**\n     * Decide if current token marks end of Markdown block.\n     *\n     * @param \\Twig\\Token $token\n     * @return bool\n     */\n    public function decideMarkdownEnd(\\Twig\\Token $token)\n    {\n        return $token->test('endmarkdown');\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getTag()\n    {\n        return 'markdown';\n    }\n}\n"
  },
  {
    "path": "tests/Aptoma/Twig/Extension/MarkdownEngine/GithubMarkdownEngineTest.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension\\MarkdownEngine;\n\nuse Aptoma\\Twig\\Extension\\MarkdownExtensionTest;\nuse Github\\Client;\n\nrequire_once(__DIR__ . '/../MarkdownExtensionTest.php');\n\n/**\n * Class GitHubMarkdownEngineTest\n *\n * @author Lukas W <lukaswhl@gmail.com>\n */\nclass GitHubMarkdownEngineTest extends MarkdownExtensionTest\n{\n    /**\n     * @dataProvider getParseMarkdownTests\n     */\n    public function testParseMarkdown($template, $expected, $context = array())\n    {\n        try {\n           $this->assertEquals($expected, $this->getTemplate($template)->render($context));\n        } catch (\\Exception $e) {\n            $this->markTestSkipped($e->getMessage());\n        }\n    }\n\n    public function getParseMarkdownTests()\n    {\n        return array(\n            array('{{ \"# Main Title\"|markdown }}', '<h1>Main Title</h1>'),\n            array('{{ content|markdown }}', '<h1>Main Title</h1>', array('content' => '# Main Title')),\n            // Check if GFM is working\n            array('{{ \"@aptoma\"|markdown }}',\n                  '<p><a href=\"https://github.com/aptoma\" class=\"user-mention\">@aptoma</a></p>'),\n        );\n    }\n\n    protected function getEngine()\n    {\n        $client = new Client();\n\n        if ($client->rateLimit()->getResource('core')->getLimit() < 1) {\n            $this->markTestSkipped('The github API rate limit is reached, so this engine cannot be tested.');\n        }\n\n        return new GitHubMarkdownEngine();\n    }\n}\n"
  },
  {
    "path": "tests/Aptoma/Twig/Extension/MarkdownEngine/PHPLeagueCommonMarkEngineTest.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension\\MarkdownEngine;\n\nuse Aptoma\\Twig\\Extension\\MarkdownExtensionTest;\n\n// Require parent class if not autoloaded\nif (!class_exists('\\Aptoma\\Twig\\Extension\\MarkdownExtensionTest')) {\n    require_once(__DIR__ . '/../MarkdownExtensionTest.php');\n}\n\n/**\n * Class PHPLeagueCommonMarkEngineTest\n *\n * @author Casey McLaughlin <caseyamcl@gmail.com>\n */\nclass PHPLeagueCommonMarkEngineTest extends MarkdownExtensionTest\n{\n    protected function getEngine()\n    {\n        return new PHPLeagueCommonMarkEngine();\n    }\n}\n"
  },
  {
    "path": "tests/Aptoma/Twig/Extension/MarkdownEngine/ParsedownEngineTest.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension\\MarkdownEngine;\n\nuse Aptoma\\Twig\\Extension\\MarkdownExtension;\nuse Aptoma\\Twig\\Extension\\MarkdownExtensionTest;\n\n// Require parent class if not autoloaded\nif (!class_exists('\\Aptoma\\Twig\\Extension\\MarkdownExtensionTest')) {\n    require_once(__DIR__ . '/../MarkdownExtensionTest.php');\n}\n\n/**\n * Class ParsedownEngineTest\n *\n * @author Sébastien Lourseau <https://github.com/SebLours>\n */\nclass ParsedownEngineTest extends MarkdownExtensionTest\n{\n    public function getParseMarkdownTests()\n    {\n        return array(\n            array('{{ \"# Main Title\"|markdown }}', '<h1>Main Title</h1>'),\n            array('{{ content|markdown }}', '<h1>Main Title</h1>', array('content' => '# Main Title')),\n            array('{% markdown %}{{ content }}{% endmarkdown %}', '<h1>Main Title</h1>', array('content' => '# Main Title'))\n        );\n    }\n\n    protected function getEngine()\n    {\n        return new ParsedownEngine();\n    }\n\n    public function testSafeMode()\n    {\n        $engine = $this->getEngine();\n        $loader = new \\Twig\\Loader\\ArrayLoader(array('index' => '{{ \"_Test_<em>Test</em>[xss](javascript:alert%281%29)\"|markdown }}'));\n        $twig = new \\Twig\\Environment($loader, array('debug' => true, 'cache' => false));\n        $twig->addExtension(new MarkdownExtension($engine));\n\n        $this->assertEquals('<p><em>Test</em><em>Test</em><a href=\"javascript:alert%281%29\">xss</a></p>', $twig->load('index')->render());\n\n        $engine->setSafeMode(true);\n        $this->assertEquals('<p><em>Test</em>&lt;em&gt;Test&lt;/em&gt;<a href=\"javascript%3Aalert%281%29\">xss</a></p>', $twig->load('index')->render());\n        $engine->setSafeMode(false);\n    }\n\n    public function testMarkupEscape()\n    {\n        $engine = $this->getEngine();\n        $loader = new \\Twig\\Loader\\ArrayLoader(array('index' => '{{ \"_Test_<em>Test</em>[xss](javascript:alert%281%29)\"|markdown }}'));\n        $twig = new \\Twig\\Environment($loader, array('debug' => true, 'cache' => false));\n        $twig->addExtension(new MarkdownExtension($engine));\n\n        $this->assertEquals('<p><em>Test</em><em>Test</em><a href=\"javascript:alert%281%29\">xss</a></p>', $twig->load('index')->render());\n\n        $engine->setMarkupEscaped(true);\n        $this->assertEquals('<p><em>Test</em>&lt;em&gt;Test&lt;/em&gt;<a href=\"javascript:alert%281%29\">xss</a></p>', $twig->load('index')->render());        \n        $engine->setMarkupEscaped(false);\n    }\n}\n"
  },
  {
    "path": "tests/Aptoma/Twig/Extension/MarkdownExtensionTest.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\Extension;\n\nuse Aptoma\\Twig\\Extension\\MarkdownEngine\\MichelfMarkdownEngine;\nuse PHPUnit\\Framework\\TestCase;\n\n/**\n * @author Gunnar Liun <gunnar@aptoma.com>\n */\nclass MarkdownExtensionTest extends TestCase\n{\n    /**\n     * @dataProvider getParseMarkdownTests\n     */\n    public function testParseMarkdown($template, $expected, $context = array())\n    {\n        $this->assertEquals($expected, $this->getTemplate($template)->render($context));\n    }\n\n    public function getParseMarkdownTests()\n    {\n        return array(\n            array('{{ \"# Main Title\"|markdown }}', '<h1>Main Title</h1>' . PHP_EOL),\n            array('{{ content|markdown }}', '<h1>Main Title</h1>' . PHP_EOL, array('content' => '# Main Title'))\n        );\n    }\n\n    protected function getEngine()\n    {\n        return new MichelfMarkdownEngine();\n    }\n\n    protected function getTemplate($template)\n    {\n        $loader = new \\Twig\\Loader\\ArrayLoader(array('index' => $template));\n        $twig = new \\Twig\\Environment($loader, array('debug' => true, 'cache' => false));\n        $twig->addExtension(new MarkdownExtension($this->getEngine()));\n\n        return $twig->load('index');\n    }\n}\n"
  },
  {
    "path": "tests/Aptoma/Twig/TokenParser/MarkdownTokenParserTest.php",
    "content": "<?php\n\nnamespace Aptoma\\Twig\\TokenParser;\n\nuse Aptoma\\Twig\\Extension\\MarkdownEngine\\MichelfMarkdownEngine;\nuse Aptoma\\Twig\\Node\\MarkdownNode;\nuse PHPUnit\\Framework\\TestCase;\nuse Twig\\Compiler;\nuse Twig\\Environment;\nuse Twig\\Loader\\ArrayLoader;\nuse Twig\\Node\\Node;\nuse Twig\\Node\\TextNode;\n\n/**\n * @author Gunnar Lium <gunnar@aptoma.com>\n */\nclass MarkdownTokenParserTest extends TestCase\n{\n    public function testConstructor()\n    {\n        $body = new Node(array(new TextNode(\"#Title\\n\\nparagraph\\n\", 1)));\n        $node = new MarkdownNode($body, 1);\n\n        $this->assertEquals($body, $node->getNode('body'));\n    }\n\n    /**\n     * Test that the generated code actually do what we expect\n     *\n     * The contents of this test is the same that we write in the compile method.\n     * This requires manual synchronization, which we should probably not rely on.\n     */\n    public function testMarkdownPrepareBehavior()\n    {\n        $body = \"    #Title\\n\\n    paragraph\\n\\n        code\";\n        $bodyPrepared = \"#Title\\n\\nparagraph\\n\\n    code\";\n\n        ob_start();\n        echo $body;\n        $content = ob_get_clean();\n        preg_match(\"/^\\s*/\", $content, $matches);\n        $lines = explode(\"\\n\", $content);\n        $content = preg_replace('/^' . $matches[0]. '/', \"\", $lines);\n        $content = join(\"\\n\", $content);\n\n        // Assert prepared content looks right\n        $this->assertEquals($bodyPrepared, $content);\n\n        // Assert Markdown output\n        $expectedOutput = \"<h1>Title</h1>\\n\\n<p>paragraph</p>\\n\\n<pre><code>code\\n</code></pre>\\n\";\n        $this->assertEquals($expectedOutput, $this->getEngine()->transform($content));\n    }\n\n    /**\n     * Test that the generated code looks as expected\n     *\n     * @dataProvider getTests\n     */\n    public function testCompile($node, $source, $environment = null, $isPattern = false)\n    {\n        $this->assertNodeCompilation($source, $node, $environment, $isPattern = false);\n    }\n\n    protected function getEngine()\n    {\n        return new MichelfMarkdownEngine();\n    }\n\n    public function getTests()\n    {\n        $tests = array();\n\n        $body = new Node(array(new TextNode(\"#Title\\n\\nparagraph\\n\", 1)));\n        $node = new MarkdownNode($body, 1);\n\n        $tests['simple text'] = array($node, <<<EOF\n// line 1\nob_start();\necho \"#Title\n\nparagraph\n\";\n\\$content = ob_get_clean();\npreg_match(\"/^\\s*/\", \\$content, \\$matches);\n\\$lines = explode(\"\\\\n\", \\$content);\n\\$content = preg_replace('/^' . \\$matches[0]. '/', \"\", \\$lines);\n\\$content = join(\"\\\\n\", \\$content);\necho \\$this->env->getExtension('Aptoma\\Twig\\Extension\\MarkdownExtension')->parseMarkdown(\\$content);\nEOF\n            );\n\n        $body = new Node(array(new TextNode(\"    #Title\\n\\n    paragraph\\n\\n        code\\n\", 1)));\n        $node = new MarkdownNode($body, 1);\n\n        $tests['text with leading indent'] = array($node, <<<EOF\n// line 1\nob_start();\necho \"    #Title\n\n    paragraph\n\n        code\n\";\n\\$content = ob_get_clean();\npreg_match(\"/^\\s*/\", \\$content, \\$matches);\n\\$lines = explode(\"\\\\n\", \\$content);\n\\$content = preg_replace('/^' . \\$matches[0]. '/', \"\", \\$lines);\n\\$content = join(\"\\\\n\", \\$content);\necho \\$this->env->getExtension('Aptoma\\Twig\\Extension\\MarkdownExtension')->parseMarkdown(\\$content);\nEOF\n        );\n\n        return $tests;\n    }\n\n    public function assertNodeCompilation($source, Node $node, Environment $environment = null, $isPattern = false)\n    {\n        $compiler = $this->getCompiler($environment);\n        $compiler->compile($node);\n\n        if ($isPattern) {\n            $this->assertStringMatchesFormat($source, trim($compiler->getSource()));\n        } else {\n            $this->assertEquals($source, trim($compiler->getSource()));\n        }\n    }\n\n    protected function getCompiler(Environment $environment = null)\n    {\n        return new Compiler(null === $environment ? $this->getEnvironment() : $environment);\n    }\n\n    protected function getEnvironment()\n    {\n        return new Environment(new ArrayLoader(array()));\n    }\n}\n"
  }
]