Просмотр исходного кода

[Upg] Use Parsedown instead of PHP-Markdown

Laurent Goussard 11 лет назад
Родитель
Сommit
15cfd862e9
100 измененных файлов с 2874 добавлено и 50 удалено
  1. 1 1
      composer.json
  2. 1 3
      lib/pico.php
  3. 1 1
      vendor/autoload.php
  4. 174 42
      vendor/composer/ClassLoader.php
  5. 10 0
      vendor/composer/autoload_files.php
  6. 2 0
      vendor/composer/autoload_namespaces.php
  7. 9 0
      vendor/composer/autoload_psr4.php
  8. 18 3
      vendor/composer/autoload_real.php
  9. 87 0
      vendor/composer/installed.json
  10. 20 0
      vendor/erusev/parsedown-extra/LICENSE.txt
  11. 371 0
      vendor/erusev/parsedown-extra/ParsedownExtra.php
  12. 15 0
      vendor/erusev/parsedown-extra/README.md
  13. 21 0
      vendor/erusev/parsedown-extra/composer.json
  14. 10 0
      vendor/erusev/parsedown/.travis.yml
  15. 20 0
      vendor/erusev/parsedown/LICENSE.txt
  16. 1402 0
      vendor/erusev/parsedown/Parsedown.php
  17. 40 0
      vendor/erusev/parsedown/README.md
  18. 18 0
      vendor/erusev/parsedown/composer.json
  19. 8 0
      vendor/erusev/parsedown/phpunit.xml.dist
  20. 65 0
      vendor/erusev/parsedown/test/Test.php
  21. 3 0
      vendor/erusev/parsedown/test/bootstrap.php
  22. 5 0
      vendor/erusev/parsedown/test/data/HTML_Comment.html
  23. 8 0
      vendor/erusev/parsedown/test/data/HTML_Comment.md
  24. 18 0
      vendor/erusev/parsedown/test/data/aesthetic_table.html
  25. 4 0
      vendor/erusev/parsedown/test/data/aesthetic_table.md
  26. 21 0
      vendor/erusev/parsedown/test/data/aligned_table.html
  27. 4 0
      vendor/erusev/parsedown/test/data/aligned_table.md
  28. 8 0
      vendor/erusev/parsedown/test/data/atx_heading.html
  29. 15 0
      vendor/erusev/parsedown/test/data/atx_heading.md
  30. 1 0
      vendor/erusev/parsedown/test/data/automatic_link.html
  31. 1 0
      vendor/erusev/parsedown/test/data/automatic_link.md
  32. 8 0
      vendor/erusev/parsedown/test/data/block-level_html.html
  33. 11 0
      vendor/erusev/parsedown/test/data/block-level_html.md
  34. 8 0
      vendor/erusev/parsedown/test/data/code_block.html
  35. 10 0
      vendor/erusev/parsedown/test/data/code_block.md
  36. 6 0
      vendor/erusev/parsedown/test/data/code_span.html
  37. 11 0
      vendor/erusev/parsedown/test/data/code_span.md
  38. 9 0
      vendor/erusev/parsedown/test/data/compound_blockquote.html
  39. 10 0
      vendor/erusev/parsedown/test/data/compound_blockquote.md
  40. 2 0
      vendor/erusev/parsedown/test/data/compound_emphasis.html
  41. 4 0
      vendor/erusev/parsedown/test/data/compound_emphasis.md
  42. 12 0
      vendor/erusev/parsedown/test/data/compound_list.html
  43. 7 0
      vendor/erusev/parsedown/test/data/compound_list.md
  44. 12 0
      vendor/erusev/parsedown/test/data/deeply_nested_list.html
  45. 6 0
      vendor/erusev/parsedown/test/data/deeply_nested_list.md
  46. 8 0
      vendor/erusev/parsedown/test/data/em_strong.html
  47. 15 0
      vendor/erusev/parsedown/test/data/em_strong.md
  48. 1 0
      vendor/erusev/parsedown/test/data/email.html
  49. 1 0
      vendor/erusev/parsedown/test/data/email.md
  50. 8 0
      vendor/erusev/parsedown/test/data/emphasis.html
  51. 13 0
      vendor/erusev/parsedown/test/data/emphasis.md
  52. 4 0
      vendor/erusev/parsedown/test/data/escaping.html
  53. 7 0
      vendor/erusev/parsedown/test/data/escaping.md
  54. 6 0
      vendor/erusev/parsedown/test/data/fenced_code_block.html
  55. 14 0
      vendor/erusev/parsedown/test/data/fenced_code_block.md
  56. 5 0
      vendor/erusev/parsedown/test/data/horizontal_rule.html
  57. 9 0
      vendor/erusev/parsedown/test/data/horizontal_rule.md
  58. 1 0
      vendor/erusev/parsedown/test/data/html_entity.html
  59. 1 0
      vendor/erusev/parsedown/test/data/html_entity.md
  60. 1 0
      vendor/erusev/parsedown/test/data/image_reference.html
  61. 3 0
      vendor/erusev/parsedown/test/data/image_reference.md
  62. 1 0
      vendor/erusev/parsedown/test/data/image_title.html
  63. 1 0
      vendor/erusev/parsedown/test/data/image_title.md
  64. 4 0
      vendor/erusev/parsedown/test/data/implicit_reference.html
  65. 13 0
      vendor/erusev/parsedown/test/data/implicit_reference.md
  66. 4 0
      vendor/erusev/parsedown/test/data/inline_link.html
  67. 7 0
      vendor/erusev/parsedown/test/data/inline_link.md
  68. 1 0
      vendor/erusev/parsedown/test/data/inline_link_title.html
  69. 1 0
      vendor/erusev/parsedown/test/data/inline_link_title.md
  70. 1 0
      vendor/erusev/parsedown/test/data/inline_title.html
  71. 1 0
      vendor/erusev/parsedown/test/data/inline_title.md
  72. 6 0
      vendor/erusev/parsedown/test/data/lazy_blockquote.html
  73. 5 0
      vendor/erusev/parsedown/test/data/lazy_blockquote.md
  74. 4 0
      vendor/erusev/parsedown/test/data/lazy_list.html
  75. 2 0
      vendor/erusev/parsedown/test/data/lazy_list.md
  76. 2 0
      vendor/erusev/parsedown/test/data/line_break.html
  77. 2 0
      vendor/erusev/parsedown/test/data/line_break.md
  78. 7 0
      vendor/erusev/parsedown/test/data/multiline_list_paragraph.html
  79. 4 0
      vendor/erusev/parsedown/test/data/multiline_list_paragraph.md
  80. 10 0
      vendor/erusev/parsedown/test/data/nested_block-level_html.html
  81. 11 0
      vendor/erusev/parsedown/test/data/nested_block-level_html.md
  82. 13 0
      vendor/erusev/parsedown/test/data/ordered_list.html
  83. 11 0
      vendor/erusev/parsedown/test/data/ordered_list.md
  84. 12 0
      vendor/erusev/parsedown/test/data/paragraph_list.html
  85. 9 0
      vendor/erusev/parsedown/test/data/paragraph_list.md
  86. 2 0
      vendor/erusev/parsedown/test/data/reference_title.html
  87. 6 0
      vendor/erusev/parsedown/test/data/reference_title.md
  88. 12 0
      vendor/erusev/parsedown/test/data/self-closing_html.html
  89. 12 0
      vendor/erusev/parsedown/test/data/self-closing_html.md
  90. 9 0
      vendor/erusev/parsedown/test/data/separated_nested_list.html
  91. 4 0
      vendor/erusev/parsedown/test/data/separated_nested_list.md
  92. 5 0
      vendor/erusev/parsedown/test/data/setext_header.html
  93. 12 0
      vendor/erusev/parsedown/test/data/setext_header.md
  94. 11 0
      vendor/erusev/parsedown/test/data/simple_blockquote.html
  95. 7 0
      vendor/erusev/parsedown/test/data/simple_blockquote.md
  96. 37 0
      vendor/erusev/parsedown/test/data/simple_table.html
  97. 11 0
      vendor/erusev/parsedown/test/data/simple_table.md
  98. 5 0
      vendor/erusev/parsedown/test/data/span-level_html.html
  99. 8 0
      vendor/erusev/parsedown/test/data/span-level_html.md
  100. 7 0
      vendor/erusev/parsedown/test/data/sparse_dense_list.html

+ 1 - 1
composer.json

@@ -14,7 +14,7 @@
     "require": {
         "php": ">=5.2.4",
         "twig/twig": "1.12.*",
-        "michelf/php-markdown": "1.3"
+        "erusev/parsedown-extra": "dev-master@dev"
     },
     "autoload": {
         "files": ["lib/pico.php"]

+ 1 - 3
lib/pico.php

@@ -1,6 +1,4 @@
 <?php
-use \Michelf\MarkdownExtra;
-
 /**
  * Pico
  *
@@ -138,7 +136,7 @@ class Pico {
 	{
 		$content = preg_replace('#/\*.+?\*/#s', '', $content); // Remove comments and meta
 		$content = str_replace('%base_url%', $this->base_url(), $content);
-		$content = MarkdownExtra::defaultTransform($content);
+		$content = (new ParsedownExtra())->text($content);
 
 		return $content;
 	}

+ 1 - 1
vendor/autoload.php

@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer' . '/autoload_real.php';
 
-return ComposerAutoloaderInit68d29614b81b64051229769b084d96b6::getLoader();
+return ComposerAutoloaderInit0f07733bc2359d393774afca848003a1::getLoader();

+ 174 - 42
vendor/composer/ClassLoader.php

@@ -42,19 +42,36 @@ namespace Composer\Autoload;
  */
 class ClassLoader
 {
-    private $prefixes = array();
-    private $fallbackDirs = array();
+    // PSR-4
+    private $prefixLengthsPsr4 = array();
+    private $prefixDirsPsr4 = array();
+    private $fallbackDirsPsr4 = array();
+
+    // PSR-0
+    private $prefixesPsr0 = array();
+    private $fallbackDirsPsr0 = array();
+
     private $useIncludePath = false;
     private $classMap = array();
 
     public function getPrefixes()
     {
-        return call_user_func_array('array_merge', $this->prefixes);
+        return call_user_func_array('array_merge', $this->prefixesPsr0);
+    }
+
+    public function getPrefixesPsr4()
+    {
+        return $this->prefixDirsPsr4;
     }
 
     public function getFallbackDirs()
     {
-        return $this->fallbackDirs;
+        return $this->fallbackDirsPsr0;
+    }
+
+    public function getFallbackDirsPsr4()
+    {
+        return $this->fallbackDirsPsr4;
     }
 
     public function getClassMap()
@@ -75,23 +92,24 @@ class ClassLoader
     }
 
     /**
-     * Registers a set of classes, merging with any others previously set.
+     * Registers a set of PSR-0 directories for a given prefix, either
+     * appending or prepending to the ones previously set for this prefix.
      *
-     * @param string       $prefix  The classes prefix
-     * @param array|string $paths   The location(s) of the classes
-     * @param bool         $prepend Prepend the location(s)
+     * @param string       $prefix  The prefix
+     * @param array|string $paths   The PSR-0 root directories
+     * @param bool         $prepend Whether to prepend the directories
      */
     public function add($prefix, $paths, $prepend = false)
     {
         if (!$prefix) {
             if ($prepend) {
-                $this->fallbackDirs = array_merge(
+                $this->fallbackDirsPsr0 = array_merge(
                     (array) $paths,
-                    $this->fallbackDirs
+                    $this->fallbackDirsPsr0
                 );
             } else {
-                $this->fallbackDirs = array_merge(
-                    $this->fallbackDirs,
+                $this->fallbackDirsPsr0 = array_merge(
+                    $this->fallbackDirsPsr0,
                     (array) $paths
                 );
             }
@@ -100,38 +118,104 @@ class ClassLoader
         }
 
         $first = $prefix[0];
-        if (!isset($this->prefixes[$first][$prefix])) {
-            $this->prefixes[$first][$prefix] = (array) $paths;
+        if (!isset($this->prefixesPsr0[$first][$prefix])) {
+            $this->prefixesPsr0[$first][$prefix] = (array) $paths;
 
             return;
         }
         if ($prepend) {
-            $this->prefixes[$first][$prefix] = array_merge(
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixesPsr0[$first][$prefix]
+            );
+        } else {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                $this->prefixesPsr0[$first][$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace, either
+     * appending or prepending to the ones previously set for this namespace.
+     *
+     * @param string       $prefix  The prefix/namespace, with trailing '\\'
+     * @param array|string $paths   The PSR-0 base directories
+     * @param bool         $prepend Whether to prepend the directories
+     */
+    public function addPsr4($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            // Register directories for the root namespace.
+            if ($prepend) {
+                $this->fallbackDirsPsr4 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr4
+                );
+            } else {
+                $this->fallbackDirsPsr4 = array_merge(
+                    $this->fallbackDirsPsr4,
+                    (array) $paths
+                );
+            }
+        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+            // Register directories for a new namespace.
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        } elseif ($prepend) {
+            // Prepend directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
                 (array) $paths,
-                $this->prefixes[$first][$prefix]
+                $this->prefixDirsPsr4[$prefix]
             );
         } else {
-            $this->prefixes[$first][$prefix] = array_merge(
-                $this->prefixes[$first][$prefix],
+            // Append directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                $this->prefixDirsPsr4[$prefix],
                 (array) $paths
             );
         }
     }
 
     /**
-     * Registers a set of classes, replacing any others previously set.
+     * Registers a set of PSR-0 directories for a given prefix,
+     * replacing any others previously set for this prefix.
      *
-     * @param string       $prefix The classes prefix
-     * @param array|string $paths  The location(s) of the classes
+     * @param string       $prefix The prefix
+     * @param array|string $paths  The PSR-0 base directories
      */
     public function set($prefix, $paths)
     {
         if (!$prefix) {
-            $this->fallbackDirs = (array) $paths;
+            $this->fallbackDirsPsr0 = (array) $paths;
+        } else {
+            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+        }
+    }
 
-            return;
+    /**
+     * Registers a set of PSR-4 directories for a given namespace,
+     * replacing any others previously set for this namespace.
+     *
+     * @param string       $prefix  The prefix/namespace, with trailing '\\'
+     * @param array|string $paths   The PSR-4 base directories
+     */
+    public function setPsr4($prefix, $paths) {
+        if (!$prefix) {
+            $this->fallbackDirsPsr4 = (array) $paths;
+        } else {
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
         }
-        $this->prefixes[substr($prefix, 0, 1)][$prefix] = (array) $paths;
     }
 
     /**
@@ -182,7 +266,7 @@ class ClassLoader
     public function loadClass($class)
     {
         if ($file = $this->findFile($class)) {
-            include $file;
+            includeFile($file);
 
             return true;
         }
@@ -202,45 +286,93 @@ class ClassLoader
             $class = substr($class, 1);
         }
 
+        // class map lookup
         if (isset($this->classMap[$class])) {
             return $this->classMap[$class];
         }
 
+        $file = $this->findFileWithExtension($class, '.php');
+
+        // Search for Hack files if we are running on HHVM
+        if ($file === null && defined('HHVM_VERSION')) {
+            $file = $this->findFileWithExtension($class, '.hh');
+        }
+
+        if ($file === null) {
+            // Remember that this class does not exist.
+            return $this->classMap[$class] = false;
+        }
+
+        return $file;
+    }
+
+    private function findFileWithExtension($class, $ext)
+    {
+        // PSR-4 lookup
+        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+        $first = $class[0];
+        if (isset($this->prefixLengthsPsr4[$first])) {
+            foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-4 fallback dirs
+        foreach ($this->fallbackDirsPsr4 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 lookup
         if (false !== $pos = strrpos($class, '\\')) {
             // namespaced class name
-            $classPath = strtr(substr($class, 0, $pos), '\\', DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
-            $className = substr($class, $pos + 1);
+            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
         } else {
             // PEAR-like class name
-            $classPath = null;
-            $className = $class;
+            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
         }
 
-        $classPath .= strtr($className, '_', DIRECTORY_SEPARATOR) . '.php';
-
-        $first = $class[0];
-        if (isset($this->prefixes[$first])) {
-            foreach ($this->prefixes[$first] as $prefix => $dirs) {
+        if (isset($this->prefixesPsr0[$first])) {
+            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
                 if (0 === strpos($class, $prefix)) {
                     foreach ($dirs as $dir) {
-                        if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
-                            return $dir . DIRECTORY_SEPARATOR . $classPath;
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                            return $file;
                         }
                     }
                 }
             }
         }
 
-        foreach ($this->fallbackDirs as $dir) {
-            if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
-                return $dir . DIRECTORY_SEPARATOR . $classPath;
+        // PSR-0 fallback dirs
+        foreach ($this->fallbackDirsPsr0 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                return $file;
             }
         }
 
-        if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) {
+        // PSR-0 include paths.
+        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
             return $file;
         }
-
-        return $this->classMap[$class] = false;
     }
 }
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+    include $file;
+}

+ 10 - 0
vendor/composer/autoload_files.php

@@ -0,0 +1,10 @@
+<?php
+
+// autoload_files.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+    $baseDir . '/lib/pico.php',
+);

+ 2 - 0
vendor/composer/autoload_namespaces.php

@@ -7,5 +7,7 @@ $baseDir = dirname($vendorDir);
 
 return array(
     'Twig_' => array($vendorDir . '/twig/twig/lib'),
+    'ParsedownExtra' => array($vendorDir . '/erusev/parsedown-extra'),
+    'Parsedown' => array($vendorDir . '/erusev/parsedown'),
     'Michelf' => array($vendorDir . '/michelf/php-markdown'),
 );

+ 9 - 0
vendor/composer/autoload_psr4.php

@@ -0,0 +1,9 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+);

+ 18 - 3
vendor/composer/autoload_real.php

@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInit68d29614b81b64051229769b084d96b6
+class ComposerAutoloaderInit0f07733bc2359d393774afca848003a1
 {
     private static $loader;
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit68d29614b81b64051229769b084d96b6
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInit68d29614b81b64051229769b084d96b6', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit0f07733bc2359d393774afca848003a1', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInit68d29614b81b64051229769b084d96b6', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit0f07733bc2359d393774afca848003a1', 'loadClassLoader'));
 
         $vendorDir = dirname(__DIR__);
         $baseDir = dirname($vendorDir);
@@ -31,6 +31,11 @@ class ComposerAutoloaderInit68d29614b81b64051229769b084d96b6
             $loader->set($namespace, $path);
         }
 
+        $map = require __DIR__ . '/autoload_psr4.php';
+        foreach ($map as $namespace => $path) {
+            $loader->setPsr4($namespace, $path);
+        }
+
         $classMap = require __DIR__ . '/autoload_classmap.php';
         if ($classMap) {
             $loader->addClassMap($classMap);
@@ -38,6 +43,16 @@ class ComposerAutoloaderInit68d29614b81b64051229769b084d96b6
 
         $loader->register(true);
 
+        $includeFiles = require __DIR__ . '/autoload_files.php';
+        foreach ($includeFiles as $file) {
+            composerRequire0f07733bc2359d393774afca848003a1($file);
+        }
+
         return $loader;
     }
 }
+
+function composerRequire0f07733bc2359d393774afca848003a1($file)
+{
+    require $file;
+}

+ 87 - 0
vendor/composer/installed.json

@@ -102,5 +102,92 @@
         "keywords": [
             "markdown"
         ]
+    },
+    {
+        "name": "erusev/parsedown",
+        "version": "1.0.1",
+        "version_normalized": "1.0.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/erusev/parsedown.git",
+            "reference": "d24439ada0704948deef0d3eda2ea20fd8db1747"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/erusev/parsedown/zipball/d24439ada0704948deef0d3eda2ea20fd8db1747",
+            "reference": "d24439ada0704948deef0d3eda2ea20fd8db1747",
+            "shasum": ""
+        },
+        "time": "2014-05-21 20:20:46",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Parsedown": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Emanuil Rusev",
+                "email": "hello@erusev.com",
+                "homepage": "http://erusev.com"
+            }
+        ],
+        "description": "Parser for Markdown.",
+        "homepage": "http://parsedown.org",
+        "keywords": [
+            "markdown",
+            "parser"
+        ]
+    },
+    {
+        "name": "erusev/parsedown-extra",
+        "version": "dev-master",
+        "version_normalized": "9999999-dev",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/erusev/parsedown-extra.git",
+            "reference": "032a244dd7cae4f1562e9ff6e23a9fcba75c9e56"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/032a244dd7cae4f1562e9ff6e23a9fcba75c9e56",
+            "reference": "032a244dd7cae4f1562e9ff6e23a9fcba75c9e56",
+            "shasum": ""
+        },
+        "require": {
+            "erusev/parsedown": "~1.0"
+        },
+        "time": "2014-05-14 17:04:59",
+        "type": "library",
+        "installation-source": "source",
+        "autoload": {
+            "psr-0": {
+                "ParsedownExtra": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Emanuil Rusev",
+                "email": "hello@erusev.com",
+                "homepage": "http://erusev.com"
+            }
+        ],
+        "description": "An extension of Parsedown that adds support for Markdown Extra.",
+        "homepage": "https://github.com/erusev/parsedown-extra",
+        "keywords": [
+            "markdown",
+            "markdown extra",
+            "parsedown",
+            "parser"
+        ]
     }
 ]

+ 20 - 0
vendor/erusev/parsedown-extra/LICENSE.txt

@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Emanuil Rusev, erusev.com
+
+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.

+ 371 - 0
vendor/erusev/parsedown-extra/ParsedownExtra.php

@@ -0,0 +1,371 @@
+<?php
+
+#
+#
+# Parsedown Extra
+# https://github.com/erusev/parsedown-extra
+#
+# (c) Emanuil Rusev
+# http://erusev.com
+#
+# For the full license information, view the LICENSE file that was distributed
+# with this source code.
+#
+#
+
+class ParsedownExtra extends Parsedown
+{
+    #
+    # ~
+
+    function __construct()
+    {
+        $this->BlockTypes[':'] []= 'DefinitionList';
+
+        $this->DefinitionTypes['*'] []= 'Abbreviation';
+
+        # identify footnote definitions before reference definitions
+        array_unshift($this->DefinitionTypes['['], 'Footnote');
+
+        # identify footnote markers before before links
+        array_unshift($this->SpanTypes['['], 'FootnoteMarker');
+    }
+
+    #
+    # ~
+
+    function text($text)
+    {
+        $markup = parent::text($text);
+
+        # merge consecutive dl elements
+
+        $markup = preg_replace('/<\/dl>\s+<dl>\s+/', '', $markup);
+
+        # add footnotes
+
+        if (isset($this->Definitions['Footnote']))
+        {
+            $Element = $this->buildFootnoteElement();
+
+            $markup .= "\n" . $this->element($Element);
+        }
+
+        return $markup;
+    }
+
+    #
+    # Blocks
+    #
+
+    #
+    # Atx
+
+    protected function identifyAtx($Line)
+    {
+        $Block = parent::identifyAtx($Line);
+
+        if (preg_match('/[ ]*'.$this->attributesPattern.'[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
+        {
+            $attributeString = $matches[1][0];
+
+            $Block['element']['attributes'] = $this->parseAttributes($attributeString);
+
+            $Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]);
+        }
+
+        return $Block;
+    }
+
+    #
+    # Definition List
+
+    protected function identifyDefinitionList($Line, $Block)
+    {
+        if (isset($Block['type']))
+        {
+            return;
+        }
+
+        $Element = array(
+            'name' => 'dl',
+            'handler' => 'elements',
+            'text' => array(),
+        );
+
+        $terms = explode("\n", $Block['element']['text']);
+
+        foreach ($terms as $term)
+        {
+            $Element['text'] []= array(
+                'name' => 'dt',
+                'handler' => 'line',
+                'text' => $term,
+            );
+        }
+
+        $Element['text'] []= array(
+            'name' => 'dd',
+            'handler' => 'line',
+            'text' => ltrim($Line['text'], ' :'),
+        );
+
+        $Block['element'] = $Element;
+
+        return $Block;
+    }
+
+    protected function addToDefinitionList($Line, array $Block)
+    {
+        if ($Line['text'][0] === ':')
+        {
+            $Block['element']['text'] []= array(
+                'name' => 'dd',
+                'handler' => 'line',
+                'text' => ltrim($Line['text'], ' :'),
+            );
+
+            return $Block;
+        }
+
+        if ( ! isset($Block['interrupted']))
+        {
+            $Element = array_pop($Block['element']['text']);
+
+            $Element['text'] .= "\n" . chop($Line['text']);
+
+            $Block['element']['text'] []= $Element;
+
+            return $Block;
+        }
+    }
+
+    #
+    # Setext
+
+    protected function identifySetext($Line, array $Block = null)
+    {
+        $Block = parent::identifySetext($Line, $Block);
+
+        if (preg_match('/[ ]*'.$this->attributesPattern.'[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
+        {
+            $attributeString = $matches[1][0];
+
+            $Block['element']['attributes'] = $this->parseAttributes($attributeString);
+
+            $Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]);
+        }
+
+        return $Block;
+    }
+
+    #
+    # Definitions
+    #
+
+    #
+    # Abbreviation
+
+    protected function identifyAbbreviation($Line)
+    {
+        if (preg_match('/^\*\[(.+?)\]:[ ]*(.+?)[ ]*$/', $Line['text'], $matches))
+        {
+            $Abbreviation = array(
+                'id' => $matches[1],
+                'data' => $matches[2],
+            );
+
+            return $Abbreviation;
+        }
+    }
+
+    #
+    # Footnote
+
+    protected function identifyFootnote($Line)
+    {
+        if (preg_match('/^\[\^(.+?)\]:[ ]?(.+)$/', $Line['text'], $matches))
+        {
+            $Footnote = array(
+                'id' => $matches[1],
+                'data' => array(
+                    'text' => $matches[2],
+                    'count' => null,
+                    'number' => null,
+                ),
+            );
+
+            return $Footnote;
+        }
+    }
+
+    #
+    # Spans
+    #
+
+    #
+    # Footnote Marker
+
+    protected function identifyFootnoteMarker($Excerpt)
+    {
+        if (preg_match('/^\[\^(.+?)\]/', $Excerpt['text'], $matches))
+        {
+            $name = $matches[1];
+
+            if ( ! isset($this->Definitions['Footnote'][$name]))
+            {
+                return;
+            }
+
+            $this->Definitions['Footnote'][$name]['count'] ++;
+
+            if ( ! isset($this->Definitions['Footnote'][$name]['number']))
+            {
+                $this->Definitions['Footnote'][$name]['number'] = ++ $this->footnoteCount; # » &
+            }
+
+            $Element = array(
+                'name' => 'sup',
+                'attributes' => array('id' => 'fnref'.$this->Definitions['Footnote'][$name]['count'].':'.$name),
+                'handler' => 'element',
+                'text' => array(
+                    'name' => 'a',
+                    'attributes' => array('href' => '#fn:'.$name, 'class' => 'footnote-ref'),
+                    'text' => $this->Definitions['Footnote'][$name]['number'],
+                ),
+            );
+
+            return array(
+                'extent' => strlen($matches[0]),
+                'element' => $Element,
+            );
+        }
+    }
+
+    private $footnoteCount = 0;
+
+    #
+    # Link
+
+    protected function identifyLink($Excerpt)
+    {
+        $Span = parent::identifyLink($Excerpt);
+
+        $remainder = substr($Excerpt['text'], $Span['extent']);
+
+        if (preg_match('/^[ ]*'.$this->attributesPattern.'/', $remainder, $matches))
+        {
+            $Span['element']['attributes'] += $this->parseAttributes($matches[1]);
+
+            $Span['extent'] += strlen($matches[0]);
+        }
+
+        return $Span;
+    }
+
+    #
+    # ~
+
+    protected function readPlainText($text)
+    {
+        $text = parent::readPlainText($text);
+
+        if (isset($this->Definitions['Abbreviation']))
+        {
+            foreach ($this->Definitions['Abbreviation'] as $abbreviation => $phrase)
+            {
+                $text = str_replace($abbreviation, '<abbr title="'.$phrase.'">'.$abbreviation.'</abbr>', $text);
+            }
+        }
+
+        return $text;
+    }
+
+    #
+    # ~
+    #
+
+    protected function buildFootnoteElement()
+    {
+        $Element = array(
+            'name' => 'div',
+            'attributes' => array('class' => 'footnotes'),
+            'handler' => 'elements',
+            'text' => array(
+                array(
+                    'name' => 'hr',
+                ),
+                array(
+                    'name' => 'ol',
+                    'handler' => 'elements',
+                    'text' => array(),
+                ),
+            ),
+        );
+
+        usort($this->Definitions['Footnote'], function($A, $B) {
+            return $A['number'] - $B['number'];
+        });
+
+        foreach ($this->Definitions['Footnote'] as $name => $Data)
+        {
+            if ( ! isset($Data['number']))
+            {
+                continue;
+            }
+
+            $text = $Data['text'];
+
+            foreach (range(1, $Data['count']) as $number)
+            {
+                $text .= '&#160;<a href="#fnref'.$number.':'.$name.'" rev="footnote" class="footnote-backref">&#8617;</a>';
+            }
+
+            $Element['text'][1]['text'] []= array(
+                'name' => 'li',
+                'attributes' => array('id' => 'fn:'.$name),
+                'handler' => 'elements',
+                'text' => array(
+                    array(
+                        'name' => 'p',
+                        'text' => $text,
+                    ),
+                ),
+            );
+        }
+
+        return $Element;
+    }
+
+    #
+    # Private
+    #
+
+    private function parseAttributes($attributeString)
+    {
+        $Data = array();
+
+        $attributes = preg_split('/[ ]+/', $attributeString, - 1, PREG_SPLIT_NO_EMPTY);
+
+        foreach ($attributes as $attribute)
+        {
+            if ($attribute[0] === '#')
+            {
+                $Data['id'] = substr($attribute, 1);
+            }
+            else # "."
+            {
+                $classes []= substr($attribute, 1);
+            }
+        }
+
+        if (isset($classes))
+        {
+            $Data['class'] = implode(' ', $classes);
+        }
+
+        return $Data;
+    }
+
+    private $attributesPattern = '{((?:[#.][-\w]+[ ]*)+)}';
+}

+ 15 - 0
vendor/erusev/parsedown-extra/README.md

@@ -0,0 +1,15 @@
+## Parsedown Extra
+
+An extension of [Parsedown](http://parsedown.org) that adds support for [Markdown Extra](http://en.wikipedia.org/wiki/Markdown_Extra).
+
+### Installation
+
+Include both `Parsedown.php` and `ParsedownExtra.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown-extra).
+
+### Example
+
+``` php
+$Instance = new ParsedownExtra();
+
+echo $Instance->text('Hello _Parsedown Extra_!'); # prints: <p>Hello <em>Parsedown Extra</em>!</p>
+```

+ 21 - 0
vendor/erusev/parsedown-extra/composer.json

@@ -0,0 +1,21 @@
+{
+    "name": "erusev/parsedown-extra",
+    "description": "An extension of Parsedown that adds support for Markdown Extra.",
+    "keywords": ["markdown", "markdown extra", "parser", "parsedown"],
+    "homepage": "https://github.com/erusev/parsedown-extra",
+    "type": "library",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Emanuil Rusev",
+            "email": "hello@erusev.com",
+            "homepage": "http://erusev.com"
+        }
+    ],
+    "require": {
+        "erusev/parsedown": "~1.0"
+    },
+    "autoload": {
+        "psr-0": {"ParsedownExtra": ""}
+    }
+}

+ 10 - 0
vendor/erusev/parsedown/.travis.yml

@@ -0,0 +1,10 @@
+language: php
+
+php:
+  - 5.6
+  - 5.5
+  - 5.4
+  - 5.3
+  - 5.2
+  - hhvm
+  

+ 20 - 0
vendor/erusev/parsedown/LICENSE.txt

@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Emanuil Rusev, erusev.com
+
+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.

+ 1402 - 0
vendor/erusev/parsedown/Parsedown.php

@@ -0,0 +1,1402 @@
+<?php
+
+#
+#
+# Parsedown
+# http://parsedown.org
+#
+# (c) Emanuil Rusev
+# http://erusev.com
+#
+# For the full license information, view the LICENSE file that was distributed
+# with this source code.
+#
+#
+
+class Parsedown
+{
+    #
+    # Philosophy
+
+    # Parsedown recognises that the Markdown syntax is optimised for humans so
+    # it tries to read like one. It goes through text line by line. It looks at
+    # how lines start to identify blocks. It looks for special characters to
+    # identify inline elements.
+
+    #
+    # ~
+
+    function text($text)
+    {
+        # make sure no definitions are set
+        $this->Definitions = array();
+
+        # standardize line breaks
+        $text = str_replace("\r\n", "\n", $text);
+        $text = str_replace("\r", "\n", $text);
+
+        # replace tabs with spaces
+        $text = str_replace("\t", '    ', $text);
+
+        # remove surrounding line breaks
+        $text = trim($text, "\n");
+
+        # split text into lines
+        $lines = explode("\n", $text);
+
+        # iterate through lines to identify blocks
+        $markup = $this->lines($lines);
+
+        # trim line breaks
+        $markup = trim($markup, "\n");
+
+        return $markup;
+    }
+
+    #
+    # Setters
+    #
+
+    private $breaksEnabled;
+
+    function setBreaksEnabled($breaksEnabled)
+    {
+        $this->breaksEnabled = $breaksEnabled;
+
+        return $this;
+    }
+
+    #
+    # Lines
+    #
+
+    protected $BlockTypes = array(
+        '#' => array('Atx'),
+        '*' => array('Rule', 'List'),
+        '+' => array('List'),
+        '-' => array('Setext', 'Table', 'Rule', 'List'),
+        '0' => array('List'),
+        '1' => array('List'),
+        '2' => array('List'),
+        '3' => array('List'),
+        '4' => array('List'),
+        '5' => array('List'),
+        '6' => array('List'),
+        '7' => array('List'),
+        '8' => array('List'),
+        '9' => array('List'),
+        ':' => array('Table'),
+        '<' => array('Comment', 'Markup'),
+        '=' => array('Setext'),
+        '>' => array('Quote'),
+        '_' => array('Rule'),
+        '`' => array('FencedCode'),
+        '|' => array('Table'),
+        '~' => array('FencedCode'),
+    );
+
+    # ~
+
+    protected $DefinitionTypes = array(
+        '[' => array('Reference'),
+    );
+
+    # ~
+
+    protected $unmarkedBlockTypes = array(
+        'CodeBlock',
+    );
+
+    #
+    # Blocks
+    #
+
+    private function lines(array $lines)
+    {
+        $CurrentBlock = null;
+
+        foreach ($lines as $line)
+        {
+            if (chop($line) === '')
+            {
+                if (isset($CurrentBlock))
+                {
+                    $CurrentBlock['interrupted'] = true;
+                }
+
+                continue;
+            }
+
+            $indent = 0;
+
+            while (isset($line[$indent]) and $line[$indent] === ' ')
+            {
+                $indent ++;
+            }
+
+            $text = $indent > 0 ? substr($line, $indent) : $line;
+
+            # ~
+
+            $Line = array('body' => $line, 'indent' => $indent, 'text' => $text);
+
+            # ~
+
+            if (isset($CurrentBlock['incomplete']))
+            {
+                $Block = $this->{'addTo'.$CurrentBlock['type']}($Line, $CurrentBlock);
+
+                if (isset($Block))
+                {
+                    $CurrentBlock = $Block;
+
+                    continue;
+                }
+                else
+                {
+                    if (method_exists($this, 'complete'.$CurrentBlock['type']))
+                    {
+                        $CurrentBlock = $this->{'complete'.$CurrentBlock['type']}($CurrentBlock);
+                    }
+
+                    unset($CurrentBlock['incomplete']);
+                }
+            }
+
+            # ~
+
+            $marker = $text[0];
+
+            if (isset($this->DefinitionTypes[$marker]))
+            {
+                foreach ($this->DefinitionTypes[$marker] as $definitionType)
+                {
+                    $Definition = $this->{'identify'.$definitionType}($Line, $CurrentBlock);
+
+                    if (isset($Definition))
+                    {
+                        $this->Definitions[$definitionType][$Definition['id']] = $Definition['data'];
+
+                        continue 2;
+                    }
+                }
+            }
+
+            # ~
+
+            $blockTypes = $this->unmarkedBlockTypes;
+
+            if (isset($this->BlockTypes[$marker]))
+            {
+                foreach ($this->BlockTypes[$marker] as $blockType)
+                {
+                    $blockTypes []= $blockType;
+                }
+            }
+
+            #
+            # ~
+
+            foreach ($blockTypes as $blockType)
+            {
+                $Block = $this->{'identify'.$blockType}($Line, $CurrentBlock);
+
+                if (isset($Block))
+                {
+                    $Block['type'] = $blockType;
+
+                    if ( ! isset($Block['identified']))
+                    {
+                        $Elements []= $CurrentBlock['element'];
+
+                        $Block['identified'] = true;
+                    }
+
+                    if (method_exists($this, 'addTo'.$blockType))
+                    {
+                        $Block['incomplete'] = true;
+                    }
+
+                    $CurrentBlock = $Block;
+
+                    continue 2;
+                }
+            }
+
+            # ~
+
+            if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
+            {
+                $CurrentBlock['element']['text'] .= "\n".$text;
+            }
+            else
+            {
+                $Elements []= $CurrentBlock['element'];
+
+                $CurrentBlock = $this->buildParagraph($Line);
+
+                $CurrentBlock['identified'] = true;
+            }
+        }
+
+        # ~
+
+        if (isset($CurrentBlock['incomplete']) and method_exists($this, 'complete'.$CurrentBlock['type']))
+        {
+            $CurrentBlock = $this->{'complete'.$CurrentBlock['type']}($CurrentBlock);
+        }
+
+        # ~
+
+        $Elements []= $CurrentBlock['element'];
+
+        unset($Elements[0]);
+
+        # ~
+
+        $markup = $this->elements($Elements);
+
+        # ~
+
+        return $markup;
+    }
+
+    #
+    # Atx
+
+    protected function identifyAtx($Line)
+    {
+        if (isset($Line['text'][1]))
+        {
+            $level = 1;
+
+            while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
+            {
+                $level ++;
+            }
+
+            $text = trim($Line['text'], '# ');
+
+            $Block = array(
+                'element' => array(
+                    'name' => 'h'.$level,
+                    'text' => $text,
+                    'handler' => 'line',
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    #
+    # Code
+
+    protected function identifyCodeBlock($Line)
+    {
+        if ($Line['indent'] >= 4)
+        {
+            $text = substr($Line['body'], 4);
+
+            $Block = array(
+                'element' => array(
+                    'name' => 'pre',
+                    'handler' => 'element',
+                    'text' => array(
+                        'name' => 'code',
+                        'text' => $text,
+                    ),
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    protected function addToCodeBlock($Line, $Block)
+    {
+        if ($Line['indent'] >= 4)
+        {
+            if (isset($Block['interrupted']))
+            {
+                $Block['element']['text']['text'] .= "\n";
+
+                unset($Block['interrupted']);
+            }
+
+            $Block['element']['text']['text'] .= "\n";
+
+            $text = substr($Line['body'], 4);
+
+            $Block['element']['text']['text'] .= $text;
+
+            return $Block;
+        }
+    }
+
+    protected function completeCodeBlock($Block)
+    {
+        $text = $Block['element']['text']['text'];
+
+        $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
+
+        $Block['element']['text']['text'] = $text;
+
+        return $Block;
+    }
+
+    #
+    # Comment
+
+    protected function identifyComment($Line)
+    {
+        if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
+        {
+            $Block = array(
+                'element' => $Line['body'],
+            );
+
+            if (preg_match('/-->$/', $Line['text']))
+            {
+                $Block['closed'] = true;
+            }
+
+            return $Block;
+        }
+    }
+
+    protected function addToComment($Line, array $Block)
+    {
+        if (isset($Block['closed']))
+        {
+            return;
+        }
+
+        $Block['element'] .= "\n" . $Line['body'];
+
+        if (preg_match('/-->$/', $Line['text']))
+        {
+            $Block['closed'] = true;
+        }
+
+        return $Block;
+    }
+
+    #
+    # Fenced Code
+
+    protected function identifyFencedCode($Line)
+    {
+        if (preg_match('/^(['.$Line['text'][0].']{3,})[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches))
+        {
+            $Element = array(
+                'name' => 'code',
+                'text' => '',
+            );
+
+            if (isset($matches[2]))
+            {
+                $class = 'language-'.$matches[2];
+
+                $Element['attributes'] = array(
+                    'class' => $class,
+                );
+            }
+
+            $Block = array(
+                'char' => $Line['text'][0],
+                'element' => array(
+                    'name' => 'pre',
+                    'handler' => 'element',
+                    'text' => $Element,
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    protected function addToFencedCode($Line, $Block)
+    {
+        if (isset($Block['complete']))
+        {
+            return;
+        }
+
+        if (isset($Block['interrupted']))
+        {
+            $Block['element']['text']['text'] .= "\n";
+
+            unset($Block['interrupted']);
+        }
+
+        if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text']))
+        {
+            $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1);
+
+            $Block['complete'] = true;
+
+            return $Block;
+        }
+
+        $Block['element']['text']['text'] .= "\n".$Line['body'];;
+
+        return $Block;
+    }
+
+    protected function completeFencedCode($Block)
+    {
+        $text = $Block['element']['text']['text'];
+
+        $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
+
+        $Block['element']['text']['text'] = $text;
+
+        return $Block;
+    }
+
+    #
+    # List
+
+    protected function identifyList($Line)
+    {
+        list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');
+
+        if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches))
+        {
+            $Block = array(
+                'indent' => $Line['indent'],
+                'pattern' => $pattern,
+                'element' => array(
+                    'name' => $name,
+                    'handler' => 'elements',
+                ),
+            );
+
+            $Block['li'] = array(
+                'name' => 'li',
+                'handler' => 'li',
+                'text' => array(
+                    $matches[2],
+                ),
+            );
+
+            $Block['element']['text'] []= & $Block['li'];
+
+            return $Block;
+        }
+    }
+
+    protected function addToList($Line, array $Block)
+    {
+        if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'[ ]+(.*)/', $Line['text'], $matches))
+        {
+            if (isset($Block['interrupted']))
+            {
+                $Block['li']['text'] []= '';
+
+                unset($Block['interrupted']);
+            }
+
+            unset($Block['li']);
+
+            $Block['li'] = array(
+                'name' => 'li',
+                'handler' => 'li',
+                'text' => array(
+                    $matches[1],
+                ),
+            );
+
+            $Block['element']['text'] []= & $Block['li'];
+
+            return $Block;
+        }
+
+        if ( ! isset($Block['interrupted']))
+        {
+            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
+
+            $Block['li']['text'] []= $text;
+
+            return $Block;
+        }
+
+        if ($Line['indent'] > 0)
+        {
+            $Block['li']['text'] []= '';
+
+            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
+
+            $Block['li']['text'] []= $text;
+
+            unset($Block['interrupted']);
+
+            return $Block;
+        }
+    }
+
+    #
+    # Quote
+
+    protected function identifyQuote($Line)
+    {
+        if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
+        {
+            $Block = array(
+                'element' => array(
+                    'name' => 'blockquote',
+                    'handler' => 'lines',
+                    'text' => (array) $matches[1],
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    protected function addToQuote($Line, array $Block)
+    {
+        if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
+        {
+            if (isset($Block['interrupted']))
+            {
+                $Block['element']['text'] []= '';
+
+                unset($Block['interrupted']);
+            }
+
+            $Block['element']['text'] []= $matches[1];
+
+            return $Block;
+        }
+
+        if ( ! isset($Block['interrupted']))
+        {
+            $Block['element']['text'] []= $Line['text'];
+
+            return $Block;
+        }
+    }
+
+    #
+    # Rule
+
+    protected function identifyRule($Line)
+    {
+        if (preg_match('/^(['.$Line['text'][0].'])([ ]{0,2}\1){2,}[ ]*$/', $Line['text']))
+        {
+            $Block = array(
+                'element' => array(
+                    'name' => 'hr'
+                ),
+            );
+
+            return $Block;
+        }
+    }
+
+    #
+    # Setext
+
+    protected function identifySetext($Line, array $Block = null)
+    {
+        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
+        {
+            return;
+        }
+
+        if (chop($Line['text'], $Line['text'][0]) === '')
+        {
+            $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';
+
+            return $Block;
+        }
+    }
+
+    #
+    # Markup
+
+    protected function identifyMarkup($Line)
+    {
+        if (preg_match('/^<(\w[\w\d]*)(?:[ ][^>\/]*)?(\/?)[ ]*>/', $Line['text'], $matches))
+        {
+            if (in_array($matches[1], $this->textLevelElements))
+            {
+                return;
+            }
+
+            $Block = array(
+                'element' => $Line['body'],
+            );
+
+            if ($matches[2] or $matches[1] === 'hr' or preg_match('/<\/'.$matches[1].'>[ ]*$/', $Line['text']))
+            {
+                $Block['closed'] = true;
+            }
+            else
+            {
+                $Block['depth'] = 0;
+                $Block['name'] = $matches[1];
+            }
+
+            return $Block;
+        }
+    }
+
+    protected function addToMarkup($Line, array $Block)
+    {
+        if (isset($Block['closed']))
+        {
+            return;
+        }
+
+        if (preg_match('/<'.$Block['name'].'([ ][^\/]+)?>/', $Line['text'])) # opening tag
+        {
+            $Block['depth'] ++;
+        }
+
+        if (stripos($Line['text'], '</'.$Block['name'].'>') !== false) # closing tag
+        {
+            if ($Block['depth'] > 0)
+            {
+                $Block['depth'] --;
+            }
+            else
+            {
+                $Block['closed'] = true;
+            }
+        }
+
+        $Block['element'] .= "\n".$Line['body'];
+
+        return $Block;
+    }
+
+    #
+    # Table
+
+    protected function identifyTable($Line, array $Block = null)
+    {
+        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
+        {
+            return;
+        }
+
+        if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '')
+        {
+            $alignments = array();
+
+            $divider = $Line['text'];
+
+            $divider = trim($divider);
+            $divider = trim($divider, '|');
+
+            $dividerCells = explode('|', $divider);
+
+            foreach ($dividerCells as $dividerCell)
+            {
+                $dividerCell = trim($dividerCell);
+
+                if ($dividerCell === '')
+                {
+                    continue;
+                }
+
+                $alignment = null;
+
+                if ($dividerCell[0] === ':')
+                {
+                    $alignment = 'left';
+                }
+
+                if (substr($dividerCell, -1) === ':')
+                {
+                    $alignment = $alignment === 'left' ? 'center' : 'right';
+                }
+
+                $alignments []= $alignment;
+            }
+
+            # ~
+
+            $HeaderElements = array();
+
+            $header = $Block['element']['text'];
+
+            $header = trim($header);
+            $header = trim($header, '|');
+
+            $headerCells = explode('|', $header);
+
+            foreach ($headerCells as $index => $headerCell)
+            {
+                $headerCell = trim($headerCell);
+
+                $HeaderElement = array(
+                    'name' => 'th',
+                    'text' => $headerCell,
+                    'handler' => 'line',
+                );
+
+                if (isset($alignments[$index]))
+                {
+                    $alignment = $alignments[$index];
+
+                    $HeaderElement['attributes'] = array(
+                        'align' => $alignment,
+                    );
+                }
+
+                $HeaderElements []= $HeaderElement;
+            }
+
+            # ~
+
+            $Block = array(
+                'alignments' => $alignments,
+                'identified' => true,
+                'element' => array(
+                    'name' => 'table',
+                    'handler' => 'elements',
+                ),
+            );
+
+            $Block['element']['text'] []= array(
+                'name' => 'thead',
+                'handler' => 'elements',
+            );
+
+            $Block['element']['text'] []= array(
+                'name' => 'tbody',
+                'handler' => 'elements',
+                'text' => array(),
+            );
+
+            $Block['element']['text'][0]['text'] []= array(
+                'name' => 'tr',
+                'handler' => 'elements',
+                'text' => $HeaderElements,
+            );
+
+            return $Block;
+        }
+    }
+
+    protected function addToTable($Line, array $Block)
+    {
+        if ($Line['text'][0] === '|' or strpos($Line['text'], '|'))
+        {
+            $Elements = array();
+
+            $row = $Line['text'];
+
+            $row = trim($row);
+            $row = trim($row, '|');
+
+            $cells = explode('|', $row);
+
+            foreach ($cells as $index => $cell)
+            {
+                $cell = trim($cell);
+
+                $Element = array(
+                    'name' => 'td',
+                    'handler' => 'line',
+                    'text' => $cell,
+                );
+
+                if (isset($Block['alignments'][$index]))
+                {
+                    $Element['attributes'] = array(
+                        'align' => $Block['alignments'][$index],
+                    );
+                }
+
+                $Elements []= $Element;
+            }
+
+            $Element = array(
+                'name' => 'tr',
+                'handler' => 'elements',
+                'text' => $Elements,
+            );
+
+            $Block['element']['text'][1]['text'] []= $Element;
+
+            return $Block;
+        }
+    }
+
+    #
+    # Definitions
+    #
+
+    protected function identifyReference($Line)
+    {
+        if (preg_match('/^\[(.+?)\]:[ ]*<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
+        {
+            $Definition = array(
+                'id' => strtolower($matches[1]),
+                'data' => array(
+                    'url' => $matches[2],
+                ),
+            );
+
+            if (isset($matches[3]))
+            {
+                $Definition['data']['title'] = $matches[3];
+            }
+
+            return $Definition;
+        }
+    }
+
+    #
+    # ~
+    #
+
+    protected function buildParagraph($Line)
+    {
+        $Block = array(
+            'element' => array(
+                'name' => 'p',
+                'text' => $Line['text'],
+                'handler' => 'line',
+            ),
+        );
+
+        return $Block;
+    }
+
+    #
+    # ~
+    #
+
+    protected function element(array $Element)
+    {
+        $markup = '<'.$Element['name'];
+
+        if (isset($Element['attributes']))
+        {
+            foreach ($Element['attributes'] as $name => $value)
+            {
+                $markup .= ' '.$name.'="'.$value.'"';
+            }
+        }
+
+        if (isset($Element['text']))
+        {
+            $markup .= '>';
+
+            if (isset($Element['handler']))
+            {
+                $markup .= $this->$Element['handler']($Element['text']);
+            }
+            else
+            {
+                $markup .= $Element['text'];
+            }
+
+            $markup .= '</'.$Element['name'].'>';
+        }
+        else
+        {
+            $markup .= ' />';
+        }
+
+        return $markup;
+    }
+
+    protected function elements(array $Elements)
+    {
+        $markup = '';
+
+        foreach ($Elements as $Element)
+        {
+            if ($Element === null)
+            {
+                continue;
+            }
+
+            $markup .= "\n";
+
+            if (is_string($Element)) # because of Markup
+            {
+                $markup .= $Element;
+
+                continue;
+            }
+
+            $markup .= $this->element($Element);
+        }
+
+        $markup .= "\n";
+
+        return $markup;
+    }
+
+    #
+    # Spans
+    #
+
+    protected $SpanTypes = array(
+        '!' => array('Link'), # ?
+        '&' => array('Ampersand'),
+        '*' => array('Emphasis'),
+        '/' => array('Url'),
+        '<' => array('UrlTag', 'EmailTag', 'Tag', 'LessThan'),
+        '[' => array('Link'),
+        '_' => array('Emphasis'),
+        '`' => array('InlineCode'),
+        '~' => array('Strikethrough'),
+        '\\' => array('EscapeSequence'),
+    );
+
+    # ~
+
+    protected $spanMarkerList = '*_!&[</`~\\';
+
+    #
+    # ~
+    #
+
+    public function line($text)
+    {
+        $markup = '';
+
+        $remainder = $text;
+
+        $markerPosition = 0;
+
+        while ($excerpt = strpbrk($remainder, $this->spanMarkerList))
+        {
+            $marker = $excerpt[0];
+
+            $markerPosition += strpos($remainder, $marker);
+
+            $Excerpt = array('text' => $excerpt, 'context' => $text);
+
+            foreach ($this->SpanTypes[$marker] as $spanType)
+            {
+                $handler = 'identify'.$spanType;
+
+                $Span = $this->$handler($Excerpt);
+
+                if ( ! isset($Span))
+                {
+                    continue;
+                }
+
+                # The identified span can be ahead of the marker.
+
+                if (isset($Span['position']) and $Span['position'] > $markerPosition)
+                {
+                    continue;
+                }
+
+                # Spans that start at the position of their marker don't have to set a position.
+
+                if ( ! isset($Span['position']))
+                {
+                    $Span['position'] = $markerPosition;
+                }
+
+                $plainText = substr($text, 0, $Span['position']);
+
+                $markup .= $this->readPlainText($plainText);
+
+                $markup .= isset($Span['markup']) ? $Span['markup'] : $this->element($Span['element']);
+
+                $text = substr($text, $Span['position'] + $Span['extent']);
+
+                $remainder = $text;
+
+                $markerPosition = 0;
+
+                continue 2;
+            }
+
+            $remainder = substr($excerpt, 1);
+
+            $markerPosition ++;
+        }
+
+        $markup .= $this->readPlainText($text);
+
+        return $markup;
+    }
+
+    #
+    # ~
+    #
+
+    protected function identifyUrl($Excerpt)
+    {
+        if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '/')
+        {
+            return;
+        }
+
+        if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
+        {
+            $url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $matches[0][0]);
+
+            return array(
+                'extent' => strlen($matches[0][0]),
+                'position' => $matches[0][1],
+                'element' => array(
+                    'name' => 'a',
+                    'text' => $url,
+                    'attributes' => array(
+                        'href' => $url,
+                    ),
+                ),
+            );
+        }
+    }
+
+    protected function identifyAmpersand($Excerpt)
+    {
+        if ( ! preg_match('/^&#?\w+;/', $Excerpt['text']))
+        {
+            return array(
+                'markup' => '&amp;',
+                'extent' => 1,
+            );
+        }
+    }
+
+    protected function identifyStrikethrough($Excerpt)
+    {
+        if ( ! isset($Excerpt['text'][1]))
+        {
+            return;
+        }
+
+        if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
+        {
+            return array(
+                'extent' => strlen($matches[0]),
+                'element' => array(
+                    'name' => 'del',
+                    'text' => $matches[1],
+                    'handler' => 'line',
+                ),
+            );
+        }
+    }
+
+    protected function identifyEscapeSequence($Excerpt)
+    {
+        if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters))
+        {
+            return array(
+                'markup' => $Excerpt['text'][1],
+                'extent' => 2,
+            );
+        }
+    }
+
+    protected function identifyLessThan()
+    {
+        return array(
+            'markup' => '&lt;',
+            'extent' => 1,
+        );
+    }
+
+    protected function identifyUrlTag($Excerpt)
+    {
+        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(https?:[\/]{2}[^\s]+?)>/i', $Excerpt['text'], $matches))
+        {
+            $url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $matches[1]);
+
+            return array(
+                'extent' => strlen($matches[0]),
+                'element' => array(
+                    'name' => 'a',
+                    'text' => $url,
+                    'attributes' => array(
+                        'href' => $url,
+                    ),
+                ),
+            );
+        }
+    }
+
+    protected function identifyEmailTag($Excerpt)
+    {
+        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\S+?@\S+?)>/', $Excerpt['text'], $matches))
+        {
+            return array(
+                'extent' => strlen($matches[0]),
+                'element' => array(
+                    'name' => 'a',
+                    'text' => $matches[1],
+                    'attributes' => array(
+                        'href' => 'mailto:'.$matches[1],
+                    ),
+                ),
+            );
+        }
+    }
+
+    protected function identifyTag($Excerpt)
+    {
+        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<\/?\w.*?>/', $Excerpt['text'], $matches))
+        {
+            return array(
+                'markup' => $matches[0],
+                'extent' => strlen($matches[0]),
+            );
+        }
+    }
+
+    protected function identifyInlineCode($Excerpt)
+    {
+        $marker = $Excerpt['text'][0];
+
+        if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/', $Excerpt['text'], $matches))
+        {
+            $text = $matches[2];
+            $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
+
+            return array(
+                'extent' => strlen($matches[0]),
+                'element' => array(
+                    'name' => 'code',
+                    'text' => $text,
+                ),
+            );
+        }
+    }
+
+    protected function identifyLink($Excerpt)
+    {
+        $extent = $Excerpt['text'][0] === '!' ? 1 : 0;
+
+        if (strpos($Excerpt['text'], ']') and preg_match('/\[((?:[^][]|(?R))*)\]/', $Excerpt['text'], $matches))
+        {
+            $Link = array('text' => $matches[1], 'label' => strtolower($matches[1]));
+
+            $extent += strlen($matches[0]);
+
+            $substring = substr($Excerpt['text'], $extent);
+
+            if (preg_match('/^\s*\[([^][]+)\]/', $substring, $matches))
+            {
+                $Link['label'] = strtolower($matches[1]);
+
+                if (isset($this->Definitions['Reference'][$Link['label']]))
+                {
+                    $Link += $this->Definitions['Reference'][$Link['label']];
+
+                    $extent += strlen($matches[0]);
+                }
+                else
+                {
+                    return;
+                }
+            }
+            elseif (isset($this->Definitions['Reference'][$Link['label']]))
+            {
+                $Link += $this->Definitions['Reference'][$Link['label']];
+
+                if (preg_match('/^[ ]*\[\]/', $substring, $matches))
+                {
+                    $extent += strlen($matches[0]);
+                }
+            }
+            elseif (preg_match('/^\([ ]*(.*?)(?:[ ]+[\'"](.+?)[\'"])?[ ]*\)/', $substring, $matches))
+            {
+                $Link['url'] = $matches[1];
+
+                if (isset($matches[2]))
+                {
+                    $Link['title'] = $matches[2];
+                }
+
+                $extent += strlen($matches[0]);
+            }
+            else
+            {
+                return;
+            }
+        }
+        else
+        {
+            return;
+        }
+
+        $url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $Link['url']);
+
+        if ($Excerpt['text'][0] === '!')
+        {
+            $Element = array(
+                'name' => 'img',
+                'attributes' => array(
+                    'alt' => $Link['text'],
+                    'src' => $url,
+                ),
+            );
+        }
+        else
+        {
+            $Element = array(
+                'name' => 'a',
+                'handler' => 'line',
+                'text' => $Link['text'],
+                'attributes' => array(
+                    'href' => $url,
+                ),
+            );
+        }
+
+        if (isset($Link['title']))
+        {
+            $Element['attributes']['title'] = $Link['title'];
+        }
+
+        return array(
+            'extent' => $extent,
+            'element' => $Element,
+        );
+    }
+
+    protected function identifyEmphasis($Excerpt)
+    {
+        if ( ! isset($Excerpt['text'][1]))
+        {
+            return;
+        }
+
+        $marker = $Excerpt['text'][0];
+
+        if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
+        {
+            $emphasis = 'strong';
+        }
+        elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
+        {
+            $emphasis = 'em';
+        }
+        else
+        {
+            return;
+        }
+
+        return array(
+            'extent' => strlen($matches[0]),
+            'element' => array(
+                'name' => $emphasis,
+                'handler' => 'line',
+                'text' => $matches[1],
+            ),
+        );
+    }
+
+    #
+    # ~
+
+    protected function readPlainText($text)
+    {
+        $breakMarker = $this->breaksEnabled ? "\n" : "  \n";
+
+        $text = str_replace($breakMarker, "<br />\n", $text);
+
+        return $text;
+    }
+
+    #
+    # ~
+    #
+
+    protected function li($lines)
+    {
+        $markup = $this->lines($lines);
+
+        $trimmedMarkup = trim($markup);
+
+        if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '<p>')
+        {
+            $markup = $trimmedMarkup;
+            $markup = substr($markup, 3);
+
+            $position = strpos($markup, "</p>");
+
+            $markup = substr_replace($markup, '', $position, 4);
+        }
+
+        return $markup;
+    }
+
+    #
+    # Multiton
+    #
+
+    static function instance($name = 'default')
+    {
+        if (isset(self::$instances[$name]))
+        {
+            return self::$instances[$name];
+        }
+
+        $instance = new self();
+
+        self::$instances[$name] = $instance;
+
+        return $instance;
+    }
+
+    private static $instances = array();
+
+    #
+    # Deprecated Methods
+    #
+
+    /**
+     * @deprecated in favor of "text"
+     */
+    function parse($text)
+    {
+        $markup = $this->text($text);
+
+        return $markup;
+    }
+
+    #
+    # Fields
+    #
+
+    protected $Definitions;
+
+    #
+    # Read-only
+
+    protected $specialCharacters = array(
+        '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!',
+    );
+
+    protected $StrongRegex = array(
+        '*' => '/^[*]{2}((?:[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s',
+        '_' => '/^__((?:[^_]|_[^_]*_)+?)__(?!_)/us',
+    );
+
+    protected $EmRegex = array(
+        '*' => '/^[*]((?:[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s',
+        '_' => '/^_((?:[^_]|__[^_]*__)+?)_(?!_)\b/us',
+    );
+
+    protected $textLevelElements = array(
+        'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont',
+        'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing',
+        'i', 'rp', 'del', 'code',          'strike', 'marquee',
+        'q', 'rt', 'ins', 'font',          'strong',
+        's', 'tt', 'sub', 'mark',
+        'u', 'xm', 'sup', 'nobr',
+                   'var', 'ruby',
+                   'wbr', 'span',
+                          'time',
+    );
+}

+ 40 - 0
vendor/erusev/parsedown/README.md

@@ -0,0 +1,40 @@
+## Parsedown
+
+Better [Markdown](http://en.wikipedia.org/wiki/Markdown) parser for PHP.
+
+* [Demo](http://parsedown.org/demo)
+* [Test Suite](http://parsedown.org/tests/)
+
+### Features
+
+* [Fast](http://parsedown.org/speed)
+* [Consistent](http://parsedown.org/consistency)
+* [GitHub Flavored](https://help.github.com/articles/github-flavored-markdown)
+* [Tested](https://travis-ci.org/erusev/parsedown) in PHP 5.2, 5.3, 5.4, 5.5, 5.6 and [hhvm](http://www.hhvm.com/)
+* Extensible
+* [Markdown Extra extension](https://github.com/erusev/parsedown-extra) <sup>new</sup>
+
+### Installation
+
+Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown).
+
+### Example
+
+``` php
+$Parsedown = new Parsedown();
+
+echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
+```
+
+More examples in [the wiki](https://github.com/erusev/parsedown/wiki/Usage).
+
+### Questions
+
+**How does Parsedown work?**<br/>
+Parsedown recognises that the Markdown syntax is optimised for humans so it tries to read like one. It goes through text line by line. It looks at how lines start to identify blocks. It looks for special characters to identify inline elements.
+
+**Why doesn’t Parsedown use namespaces?**<br/>
+Using namespaces would mean dropping support for PHP 5.2. Since Parsedown is a single class with an uncommon name, making this trade wouldn't make much sense.
+
+**Who uses Parsedown?**<br/>
+[phpDocumentor](http://www.phpdoc.org/), [Bolt CMS](http://bolt.cm/), [RaspberryPi.org](http://www.raspberrypi.org/) and [more](https://www.versioneye.com/php/erusev:parsedown/references).

+ 18 - 0
vendor/erusev/parsedown/composer.json

@@ -0,0 +1,18 @@
+{
+    "name": "erusev/parsedown",
+    "description": "Parser for Markdown.",
+    "keywords": ["markdown", "parser"],
+    "homepage": "http://parsedown.org",
+    "type": "library",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Emanuil Rusev",
+            "email": "hello@erusev.com",
+            "homepage": "http://erusev.com"
+        }
+    ],
+    "autoload": {
+        "psr-0": {"Parsedown": ""}
+    }
+}

+ 8 - 0
vendor/erusev/parsedown/phpunit.xml.dist

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit bootstrap="test/bootstrap.php" colors="true">
+	<testsuites>
+		<testsuite>
+			<file>test/Test.php</file>
+		</testsuite>
+	</testsuites>
+</phpunit>

+ 65 - 0
vendor/erusev/parsedown/test/Test.php

@@ -0,0 +1,65 @@
+<?php
+
+class Test extends PHPUnit_Framework_TestCase
+{
+    public function __construct($name = null, array $data = array(), $dataName = '')
+    {
+        $this->dataDir = dirname(__FILE__).'/data/';
+
+        parent::__construct($name, $data, $dataName);
+    }
+
+    private $dataDir;
+
+    /**
+     * @dataProvider data
+     */
+    function test_($filename)
+    {
+        $markdown = file_get_contents($this->dataDir . $filename . '.md');
+
+        $expectedMarkup = file_get_contents($this->dataDir . $filename . '.html');
+
+        $expectedMarkup = str_replace("\r\n", "\n", $expectedMarkup);
+        $expectedMarkup = str_replace("\r", "\n", $expectedMarkup);
+
+        $actualMarkup = Parsedown::instance()->text($markdown);
+
+        $this->assertEquals($expectedMarkup, $actualMarkup);
+    }
+
+    function data()
+    {
+        $data = array();
+
+        $Folder = new DirectoryIterator($this->dataDir);
+
+        foreach ($Folder as $File)
+        {
+            /** @var $File DirectoryIterator */
+
+            if ( ! $File->isFile())
+            {
+                continue;
+            }
+
+            $filename = $File->getFilename();
+
+            $extension = pathinfo($filename, PATHINFO_EXTENSION);
+
+            if ($extension !== 'md')
+            {
+                continue;
+            }
+
+            $basename = $File->getBasename('.md');
+
+            if (file_exists($this->dataDir . $basename . '.html'))
+            {
+                $data []= array($basename);
+            }
+        }
+
+        return $data;
+    }
+}

+ 3 - 0
vendor/erusev/parsedown/test/bootstrap.php

@@ -0,0 +1,3 @@
+<?php
+
+include 'Parsedown.php';

+ 5 - 0
vendor/erusev/parsedown/test/data/HTML_Comment.html

@@ -0,0 +1,5 @@
+<!-- single line -->
+<p>paragraph</p>
+<!-- 
+  multiline -->
+<p>paragraph</p>

+ 8 - 0
vendor/erusev/parsedown/test/data/HTML_Comment.md

@@ -0,0 +1,8 @@
+<!-- single line -->
+
+paragraph
+
+<!-- 
+  multiline -->
+
+paragraph

+ 18 - 0
vendor/erusev/parsedown/test/data/aesthetic_table.html

@@ -0,0 +1,18 @@
+<table>
+<thead>
+<tr>
+<th>header 1</th>
+<th>header 2</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>cell 1.1</td>
+<td>cell 1.2</td>
+</tr>
+<tr>
+<td>cell 2.1</td>
+<td>cell 2.2</td>
+</tr>
+</tbody>
+</table>

+ 4 - 0
vendor/erusev/parsedown/test/data/aesthetic_table.md

@@ -0,0 +1,4 @@
+| header 1 | header 2 |
+| -------- | -------- |
+| cell 1.1 | cell 1.2 |
+| cell 2.1 | cell 2.2 |

+ 21 - 0
vendor/erusev/parsedown/test/data/aligned_table.html

@@ -0,0 +1,21 @@
+<table>
+<thead>
+<tr>
+<th align="left">header 1</th>
+<th align="center">header 2</th>
+<th align="right">header 2</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left">cell 1.1</td>
+<td align="center">cell 1.2</td>
+<td align="right">cell 1.3</td>
+</tr>
+<tr>
+<td align="left">cell 2.1</td>
+<td align="center">cell 2.2</td>
+<td align="right">cell 2.3</td>
+</tr>
+</tbody>
+</table>

+ 4 - 0
vendor/erusev/parsedown/test/data/aligned_table.md

@@ -0,0 +1,4 @@
+| header 1 | header 2 | header 2 |
+| :------- | :------: | -------: |
+| cell 1.1 | cell 1.2 | cell 1.3 |
+| cell 2.1 | cell 2.2 | cell 2.3 |

+ 8 - 0
vendor/erusev/parsedown/test/data/atx_heading.html

@@ -0,0 +1,8 @@
+<h1>h1</h1>
+<h2>h2</h2>
+<h3>h3</h3>
+<h4>h4</h4>
+<h5>h5</h5>
+<h6>h6</h6>
+<h1>closed h1</h1>
+<p>#</p>

+ 15 - 0
vendor/erusev/parsedown/test/data/atx_heading.md

@@ -0,0 +1,15 @@
+# h1
+
+## h2
+
+### h3
+
+#### h4
+
+##### h5
+
+###### h6
+
+# closed h1 #
+
+#

+ 1 - 0
vendor/erusev/parsedown/test/data/automatic_link.html

@@ -0,0 +1 @@
+<p><a href="http://example.com">http://example.com</a></p>

+ 1 - 0
vendor/erusev/parsedown/test/data/automatic_link.md

@@ -0,0 +1 @@
+<http://example.com>

+ 8 - 0
vendor/erusev/parsedown/test/data/block-level_html.html

@@ -0,0 +1,8 @@
+<div>_content_</div>
+<p>sparse:</p>
+<div>
+<div class="inner">
+_content_
+</div>
+</div>
+<p>paragraph</p>

+ 11 - 0
vendor/erusev/parsedown/test/data/block-level_html.md

@@ -0,0 +1,11 @@
+<div>_content_</div>
+
+sparse:
+
+<div>
+<div class="inner">
+_content_
+</div>
+</div>
+
+paragraph

+ 8 - 0
vendor/erusev/parsedown/test/data/code_block.html

@@ -0,0 +1,8 @@
+<pre><code>&lt;?php
+
+$message = 'Hello World!';
+echo $message;</code></pre>
+<hr />
+<pre><code>&gt; not a quote
+- not a list item
+[not a reference]: http://foo.com</code></pre>

+ 10 - 0
vendor/erusev/parsedown/test/data/code_block.md

@@ -0,0 +1,10 @@
+    <?php
+
+    $message = 'Hello World!';
+    echo $message;
+
+---
+
+    > not a quote
+    - not a list item
+    [not a reference]: http://foo.com

+ 6 - 0
vendor/erusev/parsedown/test/data/code_span.html

@@ -0,0 +1,6 @@
+<p>a <code>code span</code></p>
+<p><code>this is also a codespan</code> trailing text</p>
+<p><code>and look at this one!</code></p>
+<p>single backtick in a code span: <code>`</code></p>
+<p>backtick-delimited string in a code span: <code>`foo`</code></p>
+<p><code>sth `` sth</code></p>

+ 11 - 0
vendor/erusev/parsedown/test/data/code_span.md

@@ -0,0 +1,11 @@
+a `code span`
+
+`this is also a codespan` trailing text
+
+`and look at this one!`
+
+single backtick in a code span: `` ` ``
+
+backtick-delimited string in a code span: `` `foo` ``
+
+`sth `` sth`

+ 9 - 0
vendor/erusev/parsedown/test/data/compound_blockquote.html

@@ -0,0 +1,9 @@
+<blockquote>
+<h2>header</h2>
+<p>paragraph</p>
+<ul>
+<li>li</li>
+</ul>
+<hr />
+<p>paragraph</p>
+</blockquote>

+ 10 - 0
vendor/erusev/parsedown/test/data/compound_blockquote.md

@@ -0,0 +1,10 @@
+> header
+> ------
+>
+> paragraph
+>
+> - li
+>
+> ---
+>
+> paragraph

+ 2 - 0
vendor/erusev/parsedown/test/data/compound_emphasis.html

@@ -0,0 +1,2 @@
+<p><em><code>code</code></em> <strong><code>code</code></strong></p>
+<p><em><code>code</code><strong><code>code</code></strong><code>code</code></em></p>

+ 4 - 0
vendor/erusev/parsedown/test/data/compound_emphasis.md

@@ -0,0 +1,4 @@
+_`code`_ __`code`__
+
+*`code`**`code`**`code`*
+

+ 12 - 0
vendor/erusev/parsedown/test/data/compound_list.html

@@ -0,0 +1,12 @@
+<ul>
+<li>
+<p>paragraph</p>
+<p>paragraph</p>
+</li>
+<li>
+<p>paragraph</p>
+<blockquote>
+<p>quote</p>
+</blockquote>
+</li>
+</ul>

+ 7 - 0
vendor/erusev/parsedown/test/data/compound_list.md

@@ -0,0 +1,7 @@
+- paragraph
+
+  paragraph
+
+- paragraph
+
+  > quote

+ 12 - 0
vendor/erusev/parsedown/test/data/deeply_nested_list.html

@@ -0,0 +1,12 @@
+<ul>
+<li>li
+<ul>
+<li>li
+<ul>
+<li>li</li>
+<li>li</li>
+</ul></li>
+<li>li</li>
+</ul></li>
+<li>li</li>
+</ul>

+ 6 - 0
vendor/erusev/parsedown/test/data/deeply_nested_list.md

@@ -0,0 +1,6 @@
+- li
+    - li
+        - li
+        - li
+    - li
+- li

+ 8 - 0
vendor/erusev/parsedown/test/data/em_strong.html

@@ -0,0 +1,8 @@
+<p><strong><em>em strong</em></strong></p>
+<p><strong><em>em strong</em> strong</strong></p>
+<p><strong>strong <em>em strong</em></strong></p>
+<p><strong>strong <em>em strong</em> strong</strong></p>
+<p><strong><em>em strong</em></strong></p>
+<p><strong><em>em strong</em> strong</strong></p>
+<p><strong>strong <em>em strong</em></strong></p>
+<p><strong>strong <em>em strong</em> strong</strong></p>

+ 15 - 0
vendor/erusev/parsedown/test/data/em_strong.md

@@ -0,0 +1,15 @@
+___em strong___
+
+___em strong_ strong__
+
+__strong _em strong___
+
+__strong _em strong_ strong__
+
+***em strong***
+
+***em strong* strong**
+
+**strong *em strong***
+
+**strong *em strong* strong**

+ 1 - 0
vendor/erusev/parsedown/test/data/email.html

@@ -0,0 +1 @@
+<p>my email is <a href="mailto:me@example.com">me@example.com</a></p>

+ 1 - 0
vendor/erusev/parsedown/test/data/email.md

@@ -0,0 +1 @@
+my email is <me@example.com>

+ 8 - 0
vendor/erusev/parsedown/test/data/emphasis.html

@@ -0,0 +1,8 @@
+<p><em>underscore</em>, <em>asterisk</em>, <em>one two</em>, <em>three four</em>, <em>a</em>, <em>b</em></p>
+<p><strong>strong</strong> and <em>em</em> and <strong>strong</strong> and <em>em</em></p>
+<p><em>line
+line
+line</em></p>
+<p>this_is_not_an_emphasis</p>
+<p>an empty emphasis __ ** is not an emphasis</p>
+<p>*mixed *<em>double and</em> single asterisk** spans</p>

+ 13 - 0
vendor/erusev/parsedown/test/data/emphasis.md

@@ -0,0 +1,13 @@
+_underscore_, *asterisk*, _one two_, *three four*, _a_, *b*
+
+**strong** and *em* and **strong** and *em*
+
+_line
+line
+line_
+
+this_is_not_an_emphasis
+
+an empty emphasis __ ** is not an emphasis
+
+*mixed **double and* single asterisk** spans

+ 4 - 0
vendor/erusev/parsedown/test/data/escaping.html

@@ -0,0 +1,4 @@
+<p>escaped *emphasis*.</p>
+<p><code>escaped \*emphasis\* in a code span</code></p>
+<pre><code>escaped \*emphasis\* in a code block</code></pre>
+<p>\ ` * _ { } [ ] ( ) > # + - . !</p>

+ 7 - 0
vendor/erusev/parsedown/test/data/escaping.md

@@ -0,0 +1,7 @@
+escaped \*emphasis\*.
+
+`escaped \*emphasis\* in a code span`
+
+    escaped \*emphasis\* in a code block
+
+\\ \` \* \_ \{ \} \[ \] \( \) \> \# \+ \- \. \!

+ 6 - 0
vendor/erusev/parsedown/test/data/fenced_code_block.html

@@ -0,0 +1,6 @@
+<pre><code>&lt;?php
+
+$message = 'fenced code block';
+echo $message;</code></pre>
+<pre><code>tilde</code></pre>
+<pre><code class="language-php">echo 'language identifier';</code></pre>

+ 14 - 0
vendor/erusev/parsedown/test/data/fenced_code_block.md

@@ -0,0 +1,14 @@
+```
+<?php
+
+$message = 'fenced code block';
+echo $message;
+```
+
+~~~
+tilde
+~~~
+
+```php
+echo 'language identifier';
+```

+ 5 - 0
vendor/erusev/parsedown/test/data/horizontal_rule.html

@@ -0,0 +1,5 @@
+<hr />
+<hr />
+<hr />
+<hr />
+<hr />

+ 9 - 0
vendor/erusev/parsedown/test/data/horizontal_rule.md

@@ -0,0 +1,9 @@
+---
+
+- - -
+
+   - - -
+
+***
+
+___

+ 1 - 0
vendor/erusev/parsedown/test/data/html_entity.html

@@ -0,0 +1 @@
+<p>&amp; &copy; &#123;</p>

+ 1 - 0
vendor/erusev/parsedown/test/data/html_entity.md

@@ -0,0 +1 @@
+&amp; &copy; &#123;

+ 1 - 0
vendor/erusev/parsedown/test/data/image_reference.html

@@ -0,0 +1 @@
+<p><img alt="Markdown Logo" src="/md.png" /></p>

+ 3 - 0
vendor/erusev/parsedown/test/data/image_reference.md

@@ -0,0 +1,3 @@
+![Markdown Logo][image]
+
+[image]: /md.png

+ 1 - 0
vendor/erusev/parsedown/test/data/image_title.html

@@ -0,0 +1 @@
+<p><img alt="alt" src="/md.png" title="title" /></p>

+ 1 - 0
vendor/erusev/parsedown/test/data/image_title.md

@@ -0,0 +1 @@
+![alt](/md.png "title")

+ 4 - 0
vendor/erusev/parsedown/test/data/implicit_reference.html

@@ -0,0 +1,4 @@
+<p>an <a href="http://example.com">implicit</a> reference link</p>
+<p>an <a href="http://example.com">implicit</a> reference link with an empty link definition</p>
+<p>an <a href="http://example.com">implicit</a> reference link followed by <a href="http://cnn.com">another</a></p>
+<p>an <a href="http://example.com" title="Example">explicit</a> reference link with a title</p>

+ 13 - 0
vendor/erusev/parsedown/test/data/implicit_reference.md

@@ -0,0 +1,13 @@
+an [implicit] reference link
+
+[implicit]: http://example.com
+
+an [implicit][] reference link with an empty link definition
+
+an [implicit][] reference link followed by [another][]
+
+[another]: http://cnn.com
+
+an [explicit][example] reference link with a title
+
+[example]: http://example.com "Example"

+ 4 - 0
vendor/erusev/parsedown/test/data/inline_link.html

@@ -0,0 +1,4 @@
+<p><a href="http://example.com">link</a> and <a href="/tests/">another link</a></p>
+<p><a href="http://example.com"><code>link</code></a></p>
+<p><a href="http://example.com"><img alt="MD Logo" src="http://parsedown.org/md.png" /></a></p>
+<p><a href="http://example.com"><img alt="MD Logo" src="http://parsedown.org/md.png" /> and text</a></p>

+ 7 - 0
vendor/erusev/parsedown/test/data/inline_link.md

@@ -0,0 +1,7 @@
+[link](http://example.com) and [another link](/tests/)
+
+[`link`](http://example.com)
+
+[![MD Logo](http://parsedown.org/md.png)](http://example.com)
+
+[![MD Logo](http://parsedown.org/md.png) and text](http://example.com)

+ 1 - 0
vendor/erusev/parsedown/test/data/inline_link_title.html

@@ -0,0 +1 @@
+<p><a href="http://example.com" title="Title">single quotes</a> and <a href="http://example.com" title="Title">double quotes</a></p>

+ 1 - 0
vendor/erusev/parsedown/test/data/inline_link_title.md

@@ -0,0 +1 @@
+[single quotes](http://example.com 'Title') and [double quotes](http://example.com "Title")

+ 1 - 0
vendor/erusev/parsedown/test/data/inline_title.html

@@ -0,0 +1 @@
+<p><a href="http://example.com" title="Example">single quotes</a> and <a href="http://example.com" title="Example">double quotes</a></p>

+ 1 - 0
vendor/erusev/parsedown/test/data/inline_title.md

@@ -0,0 +1 @@
+[single quotes](http://example.com 'Example') and [double quotes](http://example.com "Example")

+ 6 - 0
vendor/erusev/parsedown/test/data/lazy_blockquote.html

@@ -0,0 +1,6 @@
+<blockquote>
+<p>quote
+the rest of it</p>
+<p>another paragraph
+the rest of it</p>
+</blockquote>

+ 5 - 0
vendor/erusev/parsedown/test/data/lazy_blockquote.md

@@ -0,0 +1,5 @@
+> quote
+the rest of it
+
+> another paragraph
+the rest of it

+ 4 - 0
vendor/erusev/parsedown/test/data/lazy_list.html

@@ -0,0 +1,4 @@
+<ul>
+<li>li
+the rest of it</li>
+</ul>

+ 2 - 0
vendor/erusev/parsedown/test/data/lazy_list.md

@@ -0,0 +1,2 @@
+- li
+the rest of it

+ 2 - 0
vendor/erusev/parsedown/test/data/line_break.html

@@ -0,0 +1,2 @@
+<p>line<br />
+line</p>

+ 2 - 0
vendor/erusev/parsedown/test/data/line_break.md

@@ -0,0 +1,2 @@
+line  
+line

+ 7 - 0
vendor/erusev/parsedown/test/data/multiline_list_paragraph.html

@@ -0,0 +1,7 @@
+<ul>
+<li>
+<p>li</p>
+<p>line
+line</p>
+</li>
+</ul>

+ 4 - 0
vendor/erusev/parsedown/test/data/multiline_list_paragraph.md

@@ -0,0 +1,4 @@
+- li
+
+  line
+  line

+ 10 - 0
vendor/erusev/parsedown/test/data/nested_block-level_html.html

@@ -0,0 +1,10 @@
+<div>
+_parent_
+<div>
+_child_
+</div>
+<pre>
+_adopted child_
+</pre>
+</div>
+<p><em>outside</em></p>

+ 11 - 0
vendor/erusev/parsedown/test/data/nested_block-level_html.md

@@ -0,0 +1,11 @@
+<div>
+_parent_
+<div>
+_child_
+</div>
+<pre>
+_adopted child_
+</pre>
+</div>
+
+_outside_

+ 13 - 0
vendor/erusev/parsedown/test/data/ordered_list.html

@@ -0,0 +1,13 @@
+<ol>
+<li>one</li>
+<li>two</li>
+</ol>
+<p>repeating numbers:</p>
+<ol>
+<li>one</li>
+<li>two</li>
+</ol>
+<p>large numbers:</p>
+<ol>
+<li>one</li>
+</ol>

+ 11 - 0
vendor/erusev/parsedown/test/data/ordered_list.md

@@ -0,0 +1,11 @@
+1. one
+2. two
+
+repeating numbers:
+
+1. one
+1. two
+
+large numbers:
+
+123. one

+ 12 - 0
vendor/erusev/parsedown/test/data/paragraph_list.html

@@ -0,0 +1,12 @@
+<p>paragraph</p>
+<ul>
+<li>li</li>
+<li>li</li>
+</ul>
+<p>paragraph</p>
+<ul>
+<li>
+<p>li</p>
+</li>
+<li>li</li>
+</ul>

+ 9 - 0
vendor/erusev/parsedown/test/data/paragraph_list.md

@@ -0,0 +1,9 @@
+paragraph
+- li
+- li
+
+paragraph
+
+   * li
+   
+   * li

+ 2 - 0
vendor/erusev/parsedown/test/data/reference_title.html

@@ -0,0 +1,2 @@
+<p><a href="http://example.com" title="example title">double quotes</a> and <a href="http://example.com" title="example title">single quotes</a> and <a href="http://example.com" title="example title">parentheses</a></p>
+<p>[invalid title]: <a href="http://example.com">http://example.com</a> example title</p>

+ 6 - 0
vendor/erusev/parsedown/test/data/reference_title.md

@@ -0,0 +1,6 @@
+[double quotes] and [single quotes] and [parentheses]
+
+[double quotes]: http://example.com "example title"
+[single quotes]: http://example.com 'example title'
+[parentheses]: http://example.com (example title)
+[invalid title]: http://example.com example title

+ 12 - 0
vendor/erusev/parsedown/test/data/self-closing_html.html

@@ -0,0 +1,12 @@
+<hr>
+<p>paragraph</p>
+<hr/>
+<p>paragraph</p>
+<hr />
+<p>paragraph</p>
+<hr class="foo" id="bar" />
+<p>paragraph</p>
+<hr class="foo" id="bar"/>
+<p>paragraph</p>
+<hr class="foo" id="bar" >
+<p>paragraph</p>

+ 12 - 0
vendor/erusev/parsedown/test/data/self-closing_html.md

@@ -0,0 +1,12 @@
+<hr>
+paragraph
+<hr/>
+paragraph
+<hr />
+paragraph
+<hr class="foo" id="bar" />
+paragraph
+<hr class="foo" id="bar"/>
+paragraph
+<hr class="foo" id="bar" >
+paragraph

+ 9 - 0
vendor/erusev/parsedown/test/data/separated_nested_list.html

@@ -0,0 +1,9 @@
+<ul>
+<li>
+<p>li</p>
+<ul>
+<li>li</li>
+<li>li</li>
+</ul>
+</li>
+</ul>

+ 4 - 0
vendor/erusev/parsedown/test/data/separated_nested_list.md

@@ -0,0 +1,4 @@
+- li
+
+    - li
+    - li

+ 5 - 0
vendor/erusev/parsedown/test/data/setext_header.html

@@ -0,0 +1,5 @@
+<h1>h1</h1>
+<h2>h2</h2>
+<h2>single character</h2>
+<p>not a header</p>
+<hr />

+ 12 - 0
vendor/erusev/parsedown/test/data/setext_header.md

@@ -0,0 +1,12 @@
+h1
+==
+
+h2
+--
+
+single character
+-
+
+not a header
+
+------------

+ 11 - 0
vendor/erusev/parsedown/test/data/simple_blockquote.html

@@ -0,0 +1,11 @@
+<blockquote>
+<p>quote</p>
+</blockquote>
+<p>indented:</p>
+<blockquote>
+<p>quote</p>
+</blockquote>
+<p>no space after <code>&gt;</code>:</p>
+<blockquote>
+<p>quote</p>
+</blockquote>

+ 7 - 0
vendor/erusev/parsedown/test/data/simple_blockquote.md

@@ -0,0 +1,7 @@
+> quote
+
+indented:
+   > quote
+
+no space after `>`:
+>quote

+ 37 - 0
vendor/erusev/parsedown/test/data/simple_table.html

@@ -0,0 +1,37 @@
+<table>
+<thead>
+<tr>
+<th>header 1</th>
+<th>header 2</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>cell 1.1</td>
+<td>cell 1.2</td>
+</tr>
+<tr>
+<td>cell 2.1</td>
+<td>cell 2.2</td>
+</tr>
+</tbody>
+</table>
+<hr />
+<table>
+<thead>
+<tr>
+<th align="left">header 1</th>
+<th>header 2</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left">cell 1.1</td>
+<td>cell 1.2</td>
+</tr>
+<tr>
+<td align="left">cell 2.1</td>
+<td>cell 2.2</td>
+</tr>
+</tbody>
+</table>

+ 11 - 0
vendor/erusev/parsedown/test/data/simple_table.md

@@ -0,0 +1,11 @@
+header 1 | header 2
+-------- | --------
+cell 1.1 | cell 1.2
+cell 2.1 | cell 2.2
+
+---
+
+header 1 | header 2
+:------- | --------
+cell 1.1 | cell 1.2
+cell 2.1 | cell 2.2

+ 5 - 0
vendor/erusev/parsedown/test/data/span-level_html.html

@@ -0,0 +1,5 @@
+<p>an <b>important</b> <a href=''>link</a></p>
+<p>broken<br/>
+line</p>
+<p><b>inline tag</b> at the beginning</p>
+<p><span><a href="http://example.com">http://example.com</a></span></p>

+ 8 - 0
vendor/erusev/parsedown/test/data/span-level_html.md

@@ -0,0 +1,8 @@
+an <b>important</b> <a href=''>link</a>
+
+broken<br/>
+line
+
+<b>inline tag</b> at the beginning
+
+<span>http://example.com</span>

+ 7 - 0
vendor/erusev/parsedown/test/data/sparse_dense_list.html

@@ -0,0 +1,7 @@
+<ul>
+<li>
+<p>li</p>
+</li>
+<li>li</li>
+<li>li</li>
+</ul>

Некоторые файлы не были показаны из-за большого количества измененных файлов