From e5265527db43f84026403cde6851212d7ccfdcef Mon Sep 17 00:00:00 2001 From: danpros Date: Tue, 5 May 2020 08:06:22 +0700 Subject: [PATCH] Composer update --- composer.lock | 50 +- system/vendor/autoload.php | 2 +- system/vendor/composer/ClassLoader.php | 60 +- system/vendor/composer/LICENSE | 2 +- system/vendor/composer/autoload_namespaces.php | 1 - system/vendor/composer/autoload_psr4.php | 1 + system/vendor/composer/autoload_real.php | 5 +- system/vendor/composer/autoload_static.php | 15 +- system/vendor/composer/installed.json | 150 +- system/vendor/jbroadway/urlify/.gitignore | 1 + system/vendor/jbroadway/urlify/.travis.yml | 7 +- system/vendor/jbroadway/urlify/INSTALL | 13 +- system/vendor/jbroadway/urlify/README.md | 40 +- system/vendor/jbroadway/urlify/URLify.php | 75 +- system/vendor/jbroadway/urlify/composer.json | 5 +- .../vendor/jbroadway/urlify/tests/URLifyTest.php | 8 +- system/vendor/michelf/php-markdown/.editorconfig | 11 + system/vendor/michelf/php-markdown/.gitignore | 3 + .../vendor/michelf/php-markdown/.scrutinizer.yml | 36 + system/vendor/michelf/php-markdown/.travis.yml | 29 + system/vendor/michelf/php-markdown/License.md | 6 +- .../michelf/php-markdown/Michelf/Markdown.inc.php | 10 +- .../michelf/php-markdown/Michelf/Markdown.php | 1423 ++++++++++------- .../php-markdown/Michelf/MarkdownExtra.inc.php | 10 +- .../michelf/php-markdown/Michelf/MarkdownExtra.php | 1676 ++++++++++++-------- .../php-markdown/Michelf/MarkdownInterface.inc.php | 10 +- .../php-markdown/Michelf/MarkdownInterface.php | 60 +- system/vendor/michelf/php-markdown/Readme.md | 235 ++- system/vendor/michelf/php-markdown/Readme.php | 30 +- system/vendor/michelf/php-markdown/composer.json | 8 +- .../vendor/michelf/php-markdown/phpunit.xml.dist | 24 + .../vendor/michelf/php-markdown/test/bootstrap.php | 6 + .../test/helpers/MarkdownTestHelper.php | 267 ++++ .../test/integration/PhpMarkdownTest.php | 173 ++ .../markdown.mdtest/Amps and angle encoding.text | 21 + .../markdown.mdtest/Amps and angle encoding.xhtml | 17 + .../test/resources/markdown.mdtest/Auto links.text | 13 + .../resources/markdown.mdtest/Auto links.xhtml | 18 + .../markdown.mdtest/Backslash escapes.text | 120 ++ .../markdown.mdtest/Backslash escapes.xhtml | 118 ++ .../Blockquotes with code blocks.text | 11 + .../Blockquotes with code blocks.xhtml | 15 + .../resources/markdown.mdtest/Code Blocks.text | 14 + .../resources/markdown.mdtest/Code Blocks.xhtml | 18 + .../test/resources/markdown.mdtest/Code Spans.text | 5 + .../resources/markdown.mdtest/Code Spans.xhtml | 5 + ...rd-wrapped paragraphs with list-like lines.text | 8 + ...d-wrapped paragraphs with list-like lines.xhtml | 8 + .../markdown.mdtest/Horizontal rules.text | 67 + .../markdown.mdtest/Horizontal rules.xhtml | 71 + .../test/resources/markdown.mdtest/Images.text | 26 + .../test/resources/markdown.mdtest/Images.xhtml | 21 + .../markdown.mdtest/Inline HTML (Advanced).text | 30 + .../markdown.mdtest/Inline HTML (Advanced).xhtml | 30 + .../markdown.mdtest/Inline HTML (Simple).html | 72 + .../markdown.mdtest/Inline HTML (Simple).text | 69 + .../markdown.mdtest/Inline HTML comments.html | 13 + .../markdown.mdtest/Inline HTML comments.text | 13 + .../markdown.mdtest/Links, inline style.text | 24 + .../markdown.mdtest/Links, inline style.xhtml | 23 + .../markdown.mdtest/Links, reference style.text | 71 + .../markdown.mdtest/Links, reference style.xhtml | 52 + .../Links, shortcut references.text | 20 + .../Links, shortcut references.xhtml | 9 + .../markdown.mdtest/Literal quotes in titles.text | 7 + .../markdown.mdtest/Literal quotes in titles.xhtml | 3 + .../Markdown Documentation - Basics.text | 306 ++++ .../Markdown Documentation - Basics.xhtml | 314 ++++ .../Markdown Documentation - Syntax.text | 888 +++++++++++ .../Markdown Documentation - Syntax.xhtml | 942 +++++++++++ .../markdown.mdtest/Nested blockquotes.text | 5 + .../markdown.mdtest/Nested blockquotes.xhtml | 9 + .../Ordered and unordered lists.text | 131 ++ .../Ordered and unordered lists.xhtml | 148 ++ .../markdown.mdtest/Strong and em together.text | 7 + .../markdown.mdtest/Strong and em together.xhtml | 7 + .../test/resources/markdown.mdtest/Tabs.text | 21 + .../test/resources/markdown.mdtest/Tabs.xhtml | 25 + .../test/resources/markdown.mdtest/Tidyness.text | 5 + .../test/resources/markdown.mdtest/Tidyness.xhtml | 8 + .../resources/php-markdown-extra.mdtest/Abbr.text | 31 + .../resources/php-markdown-extra.mdtest/Abbr.xhtml | 15 + .../Backtick Fenced Code Blocks Special Cases.text | 69 + ...Backtick Fenced Code Blocks Special Cases.xhtml | 61 + .../Backtick Fenced Code Blocks.text | 123 ++ .../Backtick Fenced Code Blocks.xhtml | 109 ++ .../Definition Lists.text | 115 ++ .../Definition Lists.xhtml | 155 ++ .../php-markdown-extra.mdtest/Emphasis.text | 100 ++ .../php-markdown-extra.mdtest/Emphasis.xhtml | 106 ++ .../php-markdown-extra.mdtest/Footnotes.text | 70 + .../php-markdown-extra.mdtest/Footnotes.xhtml | 103 ++ .../Headers with attributes.text | 41 + .../Headers with attributes.xhtml | 37 + .../Inline HTML with Markdown content.text | 110 ++ .../Inline HTML with Markdown content.xhtml | 131 ++ .../Link & Image Attributes.text | 10 + .../Link & Image Attributes.xhtml | 8 + .../php-markdown-extra.mdtest/Tables.text | 113 ++ .../php-markdown-extra.mdtest/Tables.xhtml | 333 ++++ .../Tilde Fenced Code Blocks Special Cases.text | 69 + .../Tilde Fenced Code Blocks Special Cases.xhtml | 61 + .../Tilde Fenced Code Blocks.text | 123 ++ .../Tilde Fenced Code Blocks.xhtml | 109 ++ .../php-markdown.mdtest/Adjacent Lists.text | 10 + .../php-markdown.mdtest/Adjacent Lists.xhtml | 19 + .../resources/php-markdown.mdtest/Auto Links.text | 3 + .../resources/php-markdown.mdtest/Auto Links.xhtml | 3 + .../php-markdown.mdtest/Backslash escapes.text | 1 + .../php-markdown.mdtest/Backslash escapes.xhtml | 1 + .../resources/php-markdown.mdtest/Code Spans.text | 6 + .../resources/php-markdown.mdtest/Code Spans.xhtml | 6 + .../Code block in a list item.text | 15 + .../Code block in a list item.xhtml | 18 + .../Code block on second line.text | 2 + .../Code block on second line.xhtml | 2 + .../Code block regressions.text | 15 + .../Code block regressions.xhtml | 18 + .../php-markdown.mdtest/Email auto links.text | 24 + .../php-markdown.mdtest/Email auto links.xhtml | 23 + .../resources/php-markdown.mdtest/Emphasis.text | 101 ++ .../resources/php-markdown.mdtest/Emphasis.xhtml | 105 ++ .../php-markdown.mdtest/Empty List Item.text | 35 + .../php-markdown.mdtest/Empty List Item.xhtml | 47 + .../resources/php-markdown.mdtest/Headers.text | 9 + .../resources/php-markdown.mdtest/Headers.xhtml | 39 + .../php-markdown.mdtest/Horizontal Rules.text | 29 + .../php-markdown.mdtest/Horizontal Rules.xhtml | 30 + .../php-markdown.mdtest/Inline HTML (Simple).html | 25 + .../php-markdown.mdtest/Inline HTML (Simple).text | 25 + .../php-markdown.mdtest/Inline HTML (Span).text | 4 + .../php-markdown.mdtest/Inline HTML (Span).xhtml | 4 + .../php-markdown.mdtest/Inline HTML comments.html | 9 + .../php-markdown.mdtest/Inline HTML comments.text | 9 + .../resources/php-markdown.mdtest/Ins & del.text | 17 + .../resources/php-markdown.mdtest/Ins & del.xhtml | 17 + .../php-markdown.mdtest/Links, inline style.text | 9 + .../php-markdown.mdtest/Links, inline style.xhtml | 7 + .../resources/php-markdown.mdtest/MD5 Hashes.text | 11 + .../resources/php-markdown.mdtest/MD5 Hashes.xhtml | 11 + .../php-markdown.mdtest/Mixed OLs and ULs.text | 13 + .../php-markdown.mdtest/Mixed OLs and ULs.xhtml | 21 + .../resources/php-markdown.mdtest/Nesting.text | 11 + .../resources/php-markdown.mdtest/Nesting.xhtml | 11 + .../php-markdown.mdtest/PHP-Specific Bugs.text | 22 + .../php-markdown.mdtest/PHP-Specific Bugs.xhtml | 17 + .../php-markdown.mdtest/Parens in URL.text | 14 + .../php-markdown.mdtest/Parens in URL.xhtml | 11 + .../php-markdown.mdtest/Quotes in attributes.text | 5 + .../php-markdown.mdtest/Quotes in attributes.xhtml | 5 + .../php-markdown.mdtest/Tight blocks.text | 1 + .../php-markdown.mdtest/Tight blocks.xhtml | 21 + .../php-markdown.mdtest/XML empty tag.text | 2 + .../php-markdown.mdtest/XML empty tag.xhtml | 2 + .../php-markdown/test/unit/MarkdownExtraTest.php | 51 + themes/clean/layout.html.php | 2 +- themes/twentysixteen/main.html.php | 2 +- 157 files changed, 9808 insertions(+), 1594 deletions(-) create mode 100644 system/vendor/michelf/php-markdown/.editorconfig create mode 100644 system/vendor/michelf/php-markdown/.gitignore create mode 100644 system/vendor/michelf/php-markdown/.scrutinizer.yml create mode 100644 system/vendor/michelf/php-markdown/.travis.yml create mode 100644 system/vendor/michelf/php-markdown/phpunit.xml.dist create mode 100644 system/vendor/michelf/php-markdown/test/bootstrap.php create mode 100644 system/vendor/michelf/php-markdown/test/helpers/MarkdownTestHelper.php create mode 100644 system/vendor/michelf/php-markdown/test/integration/PhpMarkdownTest.php create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Amps and angle encoding.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Amps and angle encoding.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Auto links.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Auto links.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Backslash escapes.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Backslash escapes.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Blockquotes with code blocks.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Blockquotes with code blocks.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Code Blocks.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Code Blocks.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Code Spans.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Code Spans.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Hard-wrapped paragraphs with list-like lines.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Hard-wrapped paragraphs with list-like lines.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Horizontal rules.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Horizontal rules.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Images.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Images.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Inline HTML (Advanced).text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Inline HTML (Advanced).xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Inline HTML (Simple).html create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Inline HTML (Simple).text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Inline HTML comments.html create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Inline HTML comments.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Links, inline style.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Links, inline style.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Links, reference style.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Links, reference style.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Links, shortcut references.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Links, shortcut references.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Literal quotes in titles.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Literal quotes in titles.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Markdown Documentation - Basics.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Markdown Documentation - Basics.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Markdown Documentation - Syntax.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Markdown Documentation - Syntax.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Nested blockquotes.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Nested blockquotes.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Ordered and unordered lists.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Ordered and unordered lists.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Strong and em together.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Strong and em together.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Tabs.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Tabs.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Tidyness.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/markdown.mdtest/Tidyness.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Abbr.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Abbr.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Backtick Fenced Code Blocks Special Cases.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Backtick Fenced Code Blocks Special Cases.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Backtick Fenced Code Blocks.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Backtick Fenced Code Blocks.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Definition Lists.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Definition Lists.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Emphasis.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Emphasis.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Footnotes.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Footnotes.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Headers with attributes.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Headers with attributes.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Inline HTML with Markdown content.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Inline HTML with Markdown content.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Link & Image Attributes.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Link & Image Attributes.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Tables.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Tables.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Tilde Fenced Code Blocks Special Cases.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Tilde Fenced Code Blocks Special Cases.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Tilde Fenced Code Blocks.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown-extra.mdtest/Tilde Fenced Code Blocks.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Adjacent Lists.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Adjacent Lists.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Auto Links.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Auto Links.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Backslash escapes.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Backslash escapes.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Code Spans.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Code Spans.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Code block in a list item.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Code block in a list item.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Code block on second line.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Code block on second line.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Code block regressions.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Code block regressions.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Email auto links.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Email auto links.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Emphasis.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Emphasis.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Empty List Item.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Empty List Item.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Headers.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Headers.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Horizontal Rules.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Horizontal Rules.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Inline HTML (Simple).html create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Inline HTML (Simple).text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Inline HTML (Span).text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Inline HTML (Span).xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Inline HTML comments.html create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Inline HTML comments.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Ins & del.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Ins & del.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Links, inline style.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Links, inline style.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/MD5 Hashes.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/MD5 Hashes.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Mixed OLs and ULs.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Mixed OLs and ULs.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Nesting.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Nesting.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/PHP-Specific Bugs.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/PHP-Specific Bugs.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Parens in URL.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Parens in URL.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Quotes in attributes.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Quotes in attributes.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Tight blocks.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/Tight blocks.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/XML empty tag.text create mode 100644 system/vendor/michelf/php-markdown/test/resources/php-markdown.mdtest/XML empty tag.xhtml create mode 100644 system/vendor/michelf/php-markdown/test/unit/MarkdownExtraTest.php diff --git a/composer.lock b/composer.lock index edb9988..b55d54d 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,9 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "hash": "4b4af0298a863441fda250d818d3fc4b", "content-hash": "250bd035a1d26dd3e3e01e504833c798", "packages": [ { @@ -47,25 +46,28 @@ "hashing", "password" ], - "time": "2014-11-20 16:49:30" + "time": "2014-11-20T16:49:30+00:00" }, { "name": "jbroadway/urlify", - "version": "1.0.8-stable", + "version": "1.1.3-stable", "source": { "type": "git", "url": "https://github.com/jbroadway/urlify.git", - "reference": "984c991881501098eafdc41053b243237191cff8" + "reference": "37fe4e7680a1c8cd68ac43a27dac7ef4be476300" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jbroadway/urlify/zipball/984c991881501098eafdc41053b243237191cff8", - "reference": "984c991881501098eafdc41053b243237191cff8", + "url": "https://api.github.com/repos/jbroadway/urlify/zipball/37fe4e7680a1c8cd68ac43a27dac7ef4be476300", + "reference": "37fe4e7680a1c8cd68ac43a27dac7ef4be476300", "shasum": "" }, "require": { "php": ">=5.3.0" }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5" + }, "type": "library", "extra": { "branch-alias": { @@ -79,7 +81,7 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD" + "BSD-3-Clause-Clear" ], "authors": [ { @@ -101,7 +103,7 @@ "url", "urlify" ], - "time": "2016-07-27 15:26:43" + "time": "2019-06-13T18:30:56+00:00" }, { "name": "kanti/hub-updater", @@ -145,34 +147,33 @@ } ], "description": "Simple Github Updater for Web Projects", - "time": "2015-11-28 18:52:10" + "abandoned": true, + "time": "2015-11-28T18:52:10+00:00" }, { "name": "michelf/php-markdown", - "version": "1.6.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/michelf/php-markdown.git", - "reference": "156e56ee036505ec637d761ee62dc425d807183c" + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/156e56ee036505ec637d761ee62dc425d807183c", - "reference": "156e56ee036505ec637d761ee62dc425d807183c", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/c83178d49e372ca967d1a8c77ae4e051b3a3c75c", + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-lib": "1.4.x-dev" - } + "require-dev": { + "phpunit/phpunit": ">=4.3 <5.8" }, + "type": "library", "autoload": { - "psr-0": { - "Michelf": "" + "psr-4": { + "Michelf\\": "Michelf/" } }, "notification-url": "https://packagist.org/downloads/", @@ -196,7 +197,7 @@ "keywords": [ "markdown" ], - "time": "2015-12-24 01:37:31" + "time": "2019-12-02T02:32:27+00:00" }, { "name": "suin/php-rss-writer", @@ -240,7 +241,7 @@ "rss", "writer" ], - "time": "2016-03-01 12:09:17" + "time": "2016-03-01T12:09:17+00:00" } ], "packages-dev": [], @@ -253,5 +254,6 @@ "platform-dev": [], "platform-overrides": { "php": "5.3" - } + }, + "plugin-api-version": "1.1.0" } diff --git a/system/vendor/autoload.php b/system/vendor/autoload.php index 14ef088..637e8f6 100644 --- a/system/vendor/autoload.php +++ b/system/vendor/autoload.php @@ -2,6 +2,6 @@ // autoload.php @generated by Composer -require_once __DIR__ . '/composer' . '/autoload_real.php'; +require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInitd88c6c25320034df85dd42f1462fbda7::getLoader(); diff --git a/system/vendor/composer/ClassLoader.php b/system/vendor/composer/ClassLoader.php index ff6ecfb..fce8549 100644 --- a/system/vendor/composer/ClassLoader.php +++ b/system/vendor/composer/ClassLoader.php @@ -53,8 +53,9 @@ class ClassLoader private $useIncludePath = false; private $classMap = array(); - private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; public function getPrefixes() { @@ -271,6 +272,26 @@ class ClassLoader return $this->classMapAuthoritative; } + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + /** * Registers this instance as an autoloader. * @@ -313,29 +334,34 @@ class ClassLoader */ public function findFile($class) { - // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 - if ('\\' == $class[0]) { - $class = substr($class, 1); - } - // class map lookup if (isset($this->classMap[$class])) { return $this->classMap[$class]; } - if ($this->classMapAuthoritative) { + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { return false; } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } $file = $this->findFileWithExtension($class, '.php'); // Search for Hack files if we are running on HHVM - if ($file === null && defined('HHVM_VERSION')) { + if (false === $file && defined('HHVM_VERSION')) { $file = $this->findFileWithExtension($class, '.hh'); } - if ($file === null) { + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { // Remember that this class does not exist. - return $this->classMap[$class] = false; + $this->missingClasses[$class] = true; } return $file; @@ -348,10 +374,14 @@ class ClassLoader $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))) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { return $file; } } @@ -399,6 +429,8 @@ class ClassLoader if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { return $file; } + + return false; } } diff --git a/system/vendor/composer/LICENSE b/system/vendor/composer/LICENSE index 1a28124..f27399a 100644 --- a/system/vendor/composer/LICENSE +++ b/system/vendor/composer/LICENSE @@ -1,5 +1,5 @@ -Copyright (c) 2016 Nils Adermann, Jordi Boggiano +Copyright (c) Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/system/vendor/composer/autoload_namespaces.php b/system/vendor/composer/autoload_namespaces.php index caba627..6cd4d04 100644 --- a/system/vendor/composer/autoload_namespaces.php +++ b/system/vendor/composer/autoload_namespaces.php @@ -8,5 +8,4 @@ $baseDir = dirname(dirname($vendorDir)); return array( 'URLify' => array($vendorDir . '/jbroadway/urlify'), 'Suin\\RSSWriter' => array($vendorDir . '/suin/php-rss-writer/src'), - 'Michelf' => array($vendorDir . '/michelf/php-markdown'), ); diff --git a/system/vendor/composer/autoload_psr4.php b/system/vendor/composer/autoload_psr4.php index 7e43120..07c859d 100644 --- a/system/vendor/composer/autoload_psr4.php +++ b/system/vendor/composer/autoload_psr4.php @@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname(dirname($vendorDir)); return array( + 'Michelf\\' => array($vendorDir . '/michelf/php-markdown/Michelf'), 'Kanti\\' => array($vendorDir . '/kanti/hub-updater/src'), ); diff --git a/system/vendor/composer/autoload_real.php b/system/vendor/composer/autoload_real.php index ea36e3a..437265b 100644 --- a/system/vendor/composer/autoload_real.php +++ b/system/vendor/composer/autoload_real.php @@ -13,6 +13,9 @@ class ComposerAutoloaderInitd88c6c25320034df85dd42f1462fbda7 } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { @@ -23,7 +26,7 @@ class ComposerAutoloaderInitd88c6c25320034df85dd42f1462fbda7 self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInitd88c6c25320034df85dd42f1462fbda7', 'loadClassLoader')); - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION'); + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; diff --git a/system/vendor/composer/autoload_static.php b/system/vendor/composer/autoload_static.php index a727a40..b537df5 100644 --- a/system/vendor/composer/autoload_static.php +++ b/system/vendor/composer/autoload_static.php @@ -16,6 +16,10 @@ class ComposerStaticInitd88c6c25320034df85dd42f1462fbda7 ); public static $prefixLengthsPsr4 = array ( + 'M' => + array ( + 'Michelf\\' => 8, + ), 'K' => array ( 'Kanti\\' => 6, @@ -23,6 +27,10 @@ class ComposerStaticInitd88c6c25320034df85dd42f1462fbda7 ); public static $prefixDirsPsr4 = array ( + 'Michelf\\' => + array ( + 0 => __DIR__ . '/..' . '/michelf/php-markdown/Michelf', + ), 'Kanti\\' => array ( 0 => __DIR__ . '/..' . '/kanti/hub-updater/src', @@ -44,13 +52,6 @@ class ComposerStaticInitd88c6c25320034df85dd42f1462fbda7 0 => __DIR__ . '/..' . '/suin/php-rss-writer/src', ), ), - 'M' => - array ( - 'Michelf' => - array ( - 0 => __DIR__ . '/..' . '/michelf/php-markdown', - ), - ), ); public static $classMap = array ( diff --git a/system/vendor/composer/installed.json b/system/vendor/composer/installed.json index 4e42456..7bc9df3 100644 --- a/system/vendor/composer/installed.json +++ b/system/vendor/composer/installed.json @@ -17,7 +17,7 @@ "require-dev": { "phpunit/phpunit": "4.*" }, - "time": "2014-11-20 16:49:30", + "time": "2014-11-20T16:49:30+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -44,56 +44,62 @@ ] }, { - "name": "michelf/php-markdown", - "version": "1.6.0", - "version_normalized": "1.6.0.0", + "name": "jbroadway/urlify", + "version": "1.1.3-stable", + "version_normalized": "1.1.3.0", "source": { "type": "git", - "url": "https://github.com/michelf/php-markdown.git", - "reference": "156e56ee036505ec637d761ee62dc425d807183c" + "url": "https://github.com/jbroadway/urlify.git", + "reference": "37fe4e7680a1c8cd68ac43a27dac7ef4be476300" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/156e56ee036505ec637d761ee62dc425d807183c", - "reference": "156e56ee036505ec637d761ee62dc425d807183c", + "url": "https://api.github.com/repos/jbroadway/urlify/zipball/37fe4e7680a1c8cd68ac43a27dac7ef4be476300", + "reference": "37fe4e7680a1c8cd68ac43a27dac7ef4be476300", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2015-12-24 01:37:31", + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5" + }, + "time": "2019-06-13T18:30:56+00:00", "type": "library", "extra": { "branch-alias": { - "dev-lib": "1.4.x-dev" + "dev-master": "1.0-dev" } }, "installation-source": "dist", "autoload": { "psr-0": { - "Michelf": "" + "URLify": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "BSD-3-Clause-Clear" ], "authors": [ { - "name": "Michel Fortin", - "email": "michel.fortin@michelf.ca", - "homepage": "https://michelf.ca/", - "role": "Developer" - }, - { - "name": "John Gruber", - "homepage": "https://daringfireball.net/" + "name": "Johnny Broadway", + "email": "johnny@johnnybroadway.com", + "homepage": "http://www.johnnybroadway.com/" } ], - "description": "PHP Markdown", - "homepage": "https://michelf.ca/projects/php-markdown/", + "description": "PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.", + "homepage": "https://github.com/jbroadway/urlify", "keywords": [ - "markdown" + "encode", + "iconv", + "link", + "slug", + "translit", + "transliterate", + "transliteration", + "url", + "urlify" ] }, { @@ -120,7 +126,7 @@ "sebastian/phpcpd": "*", "squizlabs/php_codesniffer": "*" }, - "time": "2015-11-28 18:52:10", + "time": "2015-11-28T18:52:10+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -140,108 +146,104 @@ "role": "Developer" } ], - "description": "Simple Github Updater for Web Projects" + "description": "Simple Github Updater for Web Projects", + "abandoned": true }, { - "name": "suin/php-rss-writer", - "version": "1.3.2", - "version_normalized": "1.3.2.0", + "name": "michelf/php-markdown", + "version": "1.9.0", + "version_normalized": "1.9.0.0", "source": { "type": "git", - "url": "https://github.com/suin/php-rss-writer.git", - "reference": "51840d2fad4087a4bdd93fb6937aa4b324b5c94f" + "url": "https://github.com/michelf/php-markdown.git", + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/suin/php-rss-writer/zipball/51840d2fad4087a4bdd93fb6937aa4b324b5c94f", - "reference": "51840d2fad4087a4bdd93fb6937aa4b324b5c94f", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/c83178d49e372ca967d1a8c77ae4e051b3a3c75c", + "reference": "c83178d49e372ca967d1a8c77ae4e051b3a3c75c", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2016-03-01 12:09:17", + "require-dev": { + "phpunit/phpunit": ">=4.3 <5.8" + }, + "time": "2019-12-02T02:32:27+00:00", "type": "library", "installation-source": "dist", "autoload": { - "psr-0": { - "Suin\\RSSWriter": "src" + "psr-4": { + "Michelf\\": "Michelf/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Hidehito Nozawa aka Suin", - "email": "suinyeze@gmail.com" + "name": "Michel Fortin", + "email": "michel.fortin@michelf.ca", + "homepage": "https://michelf.ca/", + "role": "Developer" + }, + { + "name": "John Gruber", + "homepage": "https://daringfireball.net/" } ], - "description": "Yet another simple RSS writer library for PHP 5.3 or later.", - "homepage": "https://github.com/suin/php-rss-writer", + "description": "PHP Markdown", + "homepage": "https://michelf.ca/projects/php-markdown/", "keywords": [ - "feed", - "generator", - "php", - "rss", - "writer" + "markdown" ] }, { - "name": "jbroadway/urlify", - "version": "1.0.8-stable", - "version_normalized": "1.0.8.0", + "name": "suin/php-rss-writer", + "version": "1.3.2", + "version_normalized": "1.3.2.0", "source": { "type": "git", - "url": "https://github.com/jbroadway/urlify.git", - "reference": "984c991881501098eafdc41053b243237191cff8" + "url": "https://github.com/suin/php-rss-writer.git", + "reference": "51840d2fad4087a4bdd93fb6937aa4b324b5c94f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jbroadway/urlify/zipball/984c991881501098eafdc41053b243237191cff8", - "reference": "984c991881501098eafdc41053b243237191cff8", + "url": "https://api.github.com/repos/suin/php-rss-writer/zipball/51840d2fad4087a4bdd93fb6937aa4b324b5c94f", + "reference": "51840d2fad4087a4bdd93fb6937aa4b324b5c94f", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2016-07-27 15:26:43", + "time": "2016-03-01T12:09:17+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "installation-source": "dist", "autoload": { "psr-0": { - "URLify": "" + "Suin\\RSSWriter": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD" + "MIT" ], "authors": [ { - "name": "Johnny Broadway", - "email": "johnny@johnnybroadway.com", - "homepage": "http://www.johnnybroadway.com/" + "name": "Hidehito Nozawa aka Suin", + "email": "suinyeze@gmail.com" } ], - "description": "PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.", - "homepage": "https://github.com/jbroadway/urlify", + "description": "Yet another simple RSS writer library for PHP 5.3 or later.", + "homepage": "https://github.com/suin/php-rss-writer", "keywords": [ - "encode", - "iconv", - "link", - "slug", - "translit", - "transliterate", - "transliteration", - "url", - "urlify" + "feed", + "generator", + "php", + "rss", + "writer" ] } ] diff --git a/system/vendor/jbroadway/urlify/.gitignore b/system/vendor/jbroadway/urlify/.gitignore index 9df9b99..7709e3e 100644 --- a/system/vendor/jbroadway/urlify/.gitignore +++ b/system/vendor/jbroadway/urlify/.gitignore @@ -1,3 +1,4 @@ vendor composer.phar composer.lock +.idea \ No newline at end of file diff --git a/system/vendor/jbroadway/urlify/.travis.yml b/system/vendor/jbroadway/urlify/.travis.yml index e06af44..66b358e 100644 --- a/system/vendor/jbroadway/urlify/.travis.yml +++ b/system/vendor/jbroadway/urlify/.travis.yml @@ -1,15 +1,16 @@ language: php php: - - 5.3 - 5.4 - 5.5 - 5.6 - 7.0 - - hhvm + - 7.1 + - 7.2 + - 7.3 before_script: - composer install --no-interaction --prefer-source script: - - phpunit --coverage-text --verbose + - vendor/bin/phpunit --coverage-text --verbose diff --git a/system/vendor/jbroadway/urlify/INSTALL b/system/vendor/jbroadway/urlify/INSTALL index e92e55e..92e1bb0 100644 --- a/system/vendor/jbroadway/urlify/INSTALL +++ b/system/vendor/jbroadway/urlify/INSTALL @@ -1,10 +1,13 @@ -To install URLify, you can add it as a dependency ar by downloading the composer.phar executable. +To install URLify, you can add it as a dependency by downloading Composer, the PHP package manager. -$ curl -s http://getcomposer.org/installer | php +`$ curl -s http://getcomposer.org/installer | php` -and run install +Then run this command to install Composer: -$ php composer.phar install +`$ php composer.phar install` -For more details, see http://getcomposer.org. +For more details, see https://getcomposer.org/ +Then run this command to install the URLify library: + +`$ composer require jbroadway/urlify` diff --git a/system/vendor/jbroadway/urlify/README.md b/system/vendor/jbroadway/urlify/README.md index 334734d..e5aaa86 100644 --- a/system/vendor/jbroadway/urlify/README.md +++ b/system/vendor/jbroadway/urlify/README.md @@ -1,11 +1,19 @@ -# URLify for PHP +# URLify for PHP [![Build Status](https://travis-ci.org/jbroadway/urlify.png)](https://travis-ci.org/jbroadway/urlify) A PHP port of [URLify.js](https://github.com/django/django/blob/master/django/contrib/admin/static/admin/js/urlify.js) -from the Django project. Handles symbols from Latin languages as well as Arabic, Azerbaijani, Czech, German, Greek, -Latvian, Lithuanian, Polish, Romanian, Bulgarian, Russian, Serbian, Turkish, Ukrainian and Vietnamese. Symbols it cannot +from the Django project. Handles symbols from Latin languages as well as Arabic, Azerbaijani, Czech, German, Greek, Kazakh, +Latvian, Lithuanian, Persian, Polish, Romanian, Bulgarian, Russian, Serbian, Turkish, Ukrainian, Vietnamese and Slovak. Symbols it cannot transliterate it will simply omit. -## Usage: +## Installation + +Install the latest version with: + +```bash +$ composer require jbroadway/urlify +``` + +## Usage To generate slugs for URLs: @@ -17,8 +25,6 @@ echo URLify::filter (' J\'étudie le français '); echo URLify::filter ('Lo siento, no hablo español.'); // "lo-siento-no-hablo-espanol" - -?> ``` To generate slugs for file names: @@ -28,11 +34,8 @@ To generate slugs for file names: echo URLify::filter ('фото.jpg', 60, "", true); // "foto.jpg" - -?> ``` - To simply transliterate characters: ```php @@ -48,8 +51,6 @@ echo URLify::downcode ('Lo siento, no hablo español.'); echo URLify::transliterate ('Lo siento, no hablo español.'); // "Lo siento, no hablo espanol." - -?> ``` To extend the character list: @@ -57,15 +58,13 @@ To extend the character list: ```php '?', '®' => '(r)', '¼' => '1/4', '½' => '1/2', '¾' => '3/4', '¶' => 'P' -)); +]); echo URLify::downcode ('¿ ® ¼ ¼ ¾ ¶'); // "? (r) 1/2 1/2 3/4 P" - -?> ``` To extend the list of words to remove: @@ -73,9 +72,7 @@ To extend the list of words to remove: ```php +URLify::remove_words (['remove', 'these', 'too']); ``` To prioritize a certain language map: @@ -83,12 +80,11 @@ To prioritize a certain language map: ```php ``` + Please note that the "ü" is transliterated to "ue" in the first case, whereas it results in a simple "u" in the latter. diff --git a/system/vendor/jbroadway/urlify/URLify.php b/system/vendor/jbroadway/urlify/URLify.php index fea0a6a..09b2524 100644 --- a/system/vendor/jbroadway/urlify/URLify.php +++ b/system/vendor/jbroadway/urlify/URLify.php @@ -5,7 +5,7 @@ * (https://github.com/django/django/blob/master/django/contrib/admin/static/admin/js/urlify.js). * Handles symbols from Latin languages, Greek, Turkish, Bulgarian, Russian, * Ukrainian, Czech, Polish, Romanian, Latvian, Lithuanian, Vietnamese, Arabic, - * Serbian, and Azerbaijani. Symbols it cannot transliterate + * Serbian, Azerbaijani, Kazakh and Slovak. Symbols it cannot transliterate * it will simply omit. * * Usage: @@ -16,7 +16,8 @@ * echo URLify::filter ('Lo siento, no hablo español.'); * // "lo-siento-no-hablo-espanol" */ -class URLify { +class URLify +{ public static $maps = array ( 'de' => array ( /* German */ 'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue', 'ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'ß' => 'ss', @@ -53,25 +54,25 @@ class URLify { 'ö' => 'o', 'Ö' => 'O', 'ğ' => 'g', 'Ğ' => 'G' ), 'bg' => array( /* Bulgarian */ - "Щ" => 'Sht', "Ш" => 'Sh', "Ч" => 'Ch', "Ц" => 'C', "Ю" => 'Yu', "Я" => 'Ya', - "Ж" => 'J', "А" => 'A', "Б" => 'B', "В" => 'V', "Г" => 'G', "Д" => 'D', - "Е" => 'E', "З" => 'Z', "И" => 'I', "Й" => 'Y', "К" => 'K', "Л" => 'L', - "М" => 'M', "Н" => 'N', "О" => 'O', "П" => 'P', "Р" => 'R', "С" => 'S', - "Т" => 'T', "У" => 'U', "Ф" => 'F', "Х" => 'H', "Ь" => '', "Ъ" => 'A', - "щ" => 'sht', "ш" => 'sh', "ч" => 'ch', "ц" => 'c', "ю" => 'yu', "я" => 'ya', - "ж" => 'j', "а" => 'a', "б" => 'b', "в" => 'v', "г" => 'g', "д" => 'd', - "е" => 'e', "з" => 'z', "и" => 'i', "й" => 'y', "к" => 'k', "л" => 'l', - "м" => 'm', "н" => 'n', "о" => 'o', "п" => 'p', "р" => 'r', "с" => 's', - "т" => 't', "у" => 'u', "ф" => 'f', "х" => 'h', "ь" => '', "ъ" => 'a' + 'Щ' => 'Sht', 'Ш' => 'Sh', 'Ч' => 'Ch', 'Ц' => 'C', 'Ю' => 'Yu', 'Я' => 'Ya', + 'Ж' => 'J', 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', + 'Е' => 'E', 'З' => 'Z', 'И' => 'I', 'Й' => 'Y', 'К' => 'K', 'Л' => 'L', + 'М' => 'M', 'Н' => 'N', 'О' => 'O', 'П' => 'P', 'Р' => 'R', 'С' => 'S', + 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'H', 'Ь' => '', 'Ъ' => 'A', + 'щ' => 'sht', 'ш' => 'sh', 'ч' => 'ch', 'ц' => 'c', 'ю' => 'yu', 'я' => 'ya', + 'ж' => 'j', 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', + 'е' => 'e', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l', + 'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', + 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ь' => '', 'ъ' => 'a' ), 'ru' => array ( /* Russian */ 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'yo', 'ж' => 'zh', - 'з' => 'z', 'и' => 'i', 'й' => 'j', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o', + 'з' => 'z', 'и' => 'i', 'й' => 'i', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sh', 'ъ' => '', 'ы' => 'y', 'ь' => '', 'э' => 'e', 'ю' => 'yu', 'я' => 'ya', 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'Yo', 'Ж' => 'Zh', - 'З' => 'Z', 'И' => 'I', 'Й' => 'J', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O', + 'З' => 'Z', 'И' => 'I', 'Й' => 'I', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O', 'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'H', 'Ц' => 'C', 'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sh', 'Ъ' => '', 'Ы' => 'Y', 'Ь' => '', 'Э' => 'E', 'Ю' => 'Yu', 'Я' => 'Ya', @@ -80,6 +81,10 @@ class URLify { 'uk' => array ( /* Ukrainian */ 'Є' => 'Ye', 'І' => 'I', 'Ї' => 'Yi', 'Ґ' => 'G', 'є' => 'ye', 'і' => 'i', 'ї' => 'yi', 'ґ' => 'g' ), + 'kk' => array ( /* Kazakh */ + 'Ә' => 'A', 'Ғ' => 'G', 'Қ' => 'Q', 'Ң' => 'N', 'Ө' => 'O', 'Ұ' => 'U', 'Ү' => 'U', 'Һ' => 'H', + 'ә' => 'a', 'ғ' => 'g', 'қ' => 'q', 'ң' => 'n', 'ө' => 'o', 'ұ' => 'u', 'ү' => 'u', 'һ' => 'h', + ), 'cs' => array ( /* Czech */ 'č' => 'c', 'ď' => 'd', 'ě' => 'e', 'ň' => 'n', 'ř' => 'r', 'š' => 's', 'ť' => 't', 'ů' => 'u', 'ž' => 'z', 'Č' => 'C', 'Ď' => 'D', 'Ě' => 'E', 'Ň' => 'N', 'Ř' => 'R', 'Š' => 'S', 'Ť' => 'T', @@ -102,7 +107,7 @@ class URLify { 'ą' => 'a', 'č' => 'c', 'ę' => 'e', 'ė' => 'e', 'į' => 'i', 'š' => 's', 'ų' => 'u', 'ū' => 'u', 'ž' => 'z', 'Ą' => 'A', 'Č' => 'C', 'Ę' => 'E', 'Ė' => 'E', 'Į' => 'I', 'Š' => 'S', 'Ų' => 'U', 'Ū' => 'U', 'Ž' => 'Z' ), - 'vn' => array ( /* Vietnamese */ + 'vi' => array ( /* Vietnamese */ 'Á' => 'A', 'À' => 'A', 'Ả' => 'A', 'Ã' => 'A', 'Ạ' => 'A', 'Ă' => 'A', 'Ắ' => 'A', 'Ằ' => 'A', 'Ẳ' => 'A', 'Ẵ' => 'A', 'Ặ' => 'A', 'Â' => 'A', 'Ấ' => 'A', 'Ầ' => 'A', 'Ẩ' => 'A', 'Ẫ' => 'A', 'Ậ' => 'A', 'á' => 'a', 'à' => 'a', 'ả' => 'a', 'ã' => 'a', 'ạ' => 'a', 'ă' => 'a', 'ắ' => 'a', 'ằ' => 'a', 'ẳ' => 'a', 'ẵ' => 'a', 'ặ' => 'a', 'â' => 'a', 'ấ' => 'a', 'ầ' => 'a', 'ẩ' => 'a', 'ẫ' => 'a', 'ậ' => 'a', 'É' => 'E', 'È' => 'E', 'Ẻ' => 'E', 'Ẽ' => 'E', 'Ẹ' => 'E', 'Ê' => 'E', 'Ế' => 'E', 'Ề' => 'E', 'Ể' => 'E', 'Ễ' => 'E', 'Ệ' => 'E', @@ -119,7 +124,13 @@ class URLify { 'أ' => 'a', 'ب' => 'b', 'ت' => 't', 'ث' => 'th', 'ج' => 'g', 'ح' => 'h', 'خ' => 'kh', 'د' => 'd', 'ذ' => 'th', 'ر' => 'r', 'ز' => 'z', 'س' => 's', 'ش' => 'sh', 'ص' => 's', 'ض' => 'd', 'ط' => 't', 'ظ' => 'th', 'ع' => 'aa', 'غ' => 'gh', 'ف' => 'f', 'ق' => 'k', 'ك' => 'k', 'ل' => 'l', 'م' => 'm', - 'ن' => 'n', 'ه' => 'h', 'و' => 'o', 'ي' => 'y' + 'ن' => 'n', 'ه' => 'h', 'و' => 'o', 'ي' => 'y', + 'ا' => 'a', 'إ' => 'a', 'آ' => 'a', 'ؤ' => 'o', 'ئ' => 'y', 'ء' => 'aa', + '٠' => '0', '١' => '1', '٢' => '2', '٣' => '3', '٤' => '4', '٥' => '5', '٦' => '6', '٧' => '7', '٨' => '8', '٩' => '9', + ), + 'fa' => array ( /* Persian */ + 'گ' => 'g', 'ژ' => 'j', 'پ' => 'p', 'چ' => 'ch', 'ی' => 'y', 'ک' => 'k', + '۰' => '0', '۱' => '1', '۲' => '2', '۳' => '3', '۴' => '4', '۵' => '5', '۶' => '6', '۷' => '7', '۸' => '8', '۹' => '9', ), 'sr' => array ( /* Serbian */ 'ђ' => 'dj', 'ј' => 'j', 'љ' => 'lj', 'њ' => 'nj', 'ћ' => 'c', 'џ' => 'dz', 'đ' => 'dj', @@ -128,6 +139,9 @@ class URLify { 'az' => array ( /* Azerbaijani */ 'ç' => 'c', 'ə' => 'e', 'ğ' => 'g', 'ı' => 'i', 'ö' => 'o', 'ş' => 's', 'ü' => 'u', 'Ç' => 'C', 'Ə' => 'E', 'Ğ' => 'G', 'İ' => 'I', 'Ö' => 'O', 'Ş' => 'S', 'Ü' => 'U' + ), + 'sk' => array ( /* Slovak */ + 'ĺ' => 'l', 'ľ' => 'l', 'ŕ' => 'r' ) ); @@ -163,8 +177,10 @@ class URLify { /** * Initializes the character map. + * @param string $language */ - private static function init ($language = "") { + private static function init ($language = "") + { if (count (self::$map) > 0 && (($language == "") || ($language == self::$language))) { return; } @@ -188,13 +204,15 @@ class URLify { } } - self::$regex = '/[' . self::$chars . ']/u'; + self::$regex = '/[' . preg_quote(self::$chars, '/') . ']/u'; } /** * Add new characters to the list. `$map` should be a hash. + * @param array $map */ - public static function add_chars ($map) { + public static function add_chars ($map) + { if (! is_array ($map)) { throw new LogicException ('$map must be an associative array.'); } @@ -206,18 +224,24 @@ class URLify { /** * Append words to the remove list. Accepts either single words * or an array of words. + * @param mixed $words */ - public static function remove_words ($words) { + public static function remove_words ($words) + { $words = is_array ($words) ? $words : array ($words); - self::$remove_list = array_merge (self::$remove_list, $words); + self::$remove_list = array_unique (array_merge (self::$remove_list, $words)); } /** * Transliterates characters to their ASCII equivalents. * $language specifies a priority for a specific language. * The latter is useful if languages have different rules for the same character. + * @param string $text + * @param string $language + * @return string */ - public static function downcode ($text, $language = "") { + public static function downcode ($text, $language = "") + { self::init ($language); if (preg_match_all (self::$regex, $text, $matches)) { @@ -240,8 +264,10 @@ class URLify { * @param bool $use_remove_list Whether you want to remove specific elements previously set in self::$remove_list * @param bool $lower_case Whether you want the filter to maintain casing or lowercase everything (default) * @param bool $treat_underscore_as_space Treat underscore as space, so it will replaced with "-" + * @return string */ - public static function filter ($text, $length = 60, $language = "", $file_name = false, $use_remove_list = true, $lower_case = true, $treat_underscore_as_space = true) { + public static function filter ($text, $length = 60, $language = "", $file_name = false, $use_remove_list = true, $lower_case = true, $treat_underscore_as_space = true) + { $text = self::downcode ($text,$language); if ($use_remove_list) { @@ -267,7 +293,8 @@ class URLify { /** * Alias of `URLify::downcode()`. */ - public static function transliterate ($text) { + public static function transliterate ($text) + { return self::downcode ($text); } } diff --git a/system/vendor/jbroadway/urlify/composer.json b/system/vendor/jbroadway/urlify/composer.json index b226f8e..38846a2 100644 --- a/system/vendor/jbroadway/urlify/composer.json +++ b/system/vendor/jbroadway/urlify/composer.json @@ -4,7 +4,7 @@ "description": "PHP port of URLify.js from the Django project. Transliterates non-ascii characters for use in URLs.", "keywords": ["urlify","transliterate","translit","transliteration","url","encode","slug","link","iconv"], "homepage": "https://github.com/jbroadway/urlify", - "license": "BSD", + "license": "BSD-3-Clause-Clear", "authors": [ { "name": "Johnny Broadway", @@ -15,6 +15,9 @@ "require": { "php": ">=5.3.0" }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5" + }, "autoload": { "psr-0": { "URLify": "" } }, diff --git a/system/vendor/jbroadway/urlify/tests/URLifyTest.php b/system/vendor/jbroadway/urlify/tests/URLifyTest.php index 639cd73..aa3ac30 100644 --- a/system/vendor/jbroadway/urlify/tests/URLifyTest.php +++ b/system/vendor/jbroadway/urlify/tests/URLifyTest.php @@ -1,5 +1,8 @@ assertEquals (' J\'etudie le francais ', URLify::downcode (' J\'étudie le français ')); $this->assertEquals ('Lo siento, no hablo espanol.', URLify::downcode ('Lo siento, no hablo español.')); @@ -13,7 +16,8 @@ class URLifyTest extends PHPUnit_Framework_TestCase { $this->assertEquals ('f3pws', URLify::filter ('ΦΞΠΏΣ')); $this->assertEquals ('', URLify::filter('大般若經')); $this->assertEquals ('test-.txt', URLify::filter('test-大般若經.txt', 60, "", $file_name = true)); - $this->assertEquals ('ykrhy-ltoytr', URLify::filter('ياكرهي لتويتر')); + $this->assertEquals ('yakrhy-ltoytr', URLify::filter('ياكرهي لتويتر')); + $this->assertEquals ('saaat-25', URLify::filter('ساعت ۲۵')); $this->assertEquals ('foto.jpg', URLify::filter ('фото.jpg', 60, "", $file_name = true)); // priorization of language-specific maps $this->assertEquals ('aouaou', URLify::filter ('ÄÖÜäöü',60,"tr")); diff --git a/system/vendor/michelf/php-markdown/.editorconfig b/system/vendor/michelf/php-markdown/.editorconfig new file mode 100644 index 0000000..179d40c --- /dev/null +++ b/system/vendor/michelf/php-markdown/.editorconfig @@ -0,0 +1,11 @@ +# EditorConfig is awesome: https://EditorConfig.org +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false + +[*.php] +indent_style = tab +insert_final_newline = true diff --git a/system/vendor/michelf/php-markdown/.gitignore b/system/vendor/michelf/php-markdown/.gitignore new file mode 100644 index 0000000..5bd6475 --- /dev/null +++ b/system/vendor/michelf/php-markdown/.gitignore @@ -0,0 +1,3 @@ +*~ +/composer.lock +/vendor/ diff --git a/system/vendor/michelf/php-markdown/.scrutinizer.yml b/system/vendor/michelf/php-markdown/.scrutinizer.yml new file mode 100644 index 0000000..b4f5dfb --- /dev/null +++ b/system/vendor/michelf/php-markdown/.scrutinizer.yml @@ -0,0 +1,36 @@ +build: + environment: + php: + version: '7.0.20' + nodes: + analysis: + project_setup: + override: + - 'true' + tests: + override: + - + command: 'vendor/bin/phpunit --coverage-clover=clover.xml' + coverage: + file: 'clover.xml' + format: 'clover' + - + command: phpcs-run + use_website_config: true + environment: + node: + version: 6.0.0 + tests: true +filter: + excluded_paths: + - 'test/*' +checks: + php: true +coding_style: + php: + indentation: + general: + use_tabs: true + spaces: + around_operators: + concatenation: true diff --git a/system/vendor/michelf/php-markdown/.travis.yml b/system/vendor/michelf/php-markdown/.travis.yml new file mode 100644 index 0000000..d467147 --- /dev/null +++ b/system/vendor/michelf/php-markdown/.travis.yml @@ -0,0 +1,29 @@ +language: php + +sudo: false + +cache: + directories: + - $HOME/.composer/ + +# Run tests against all these PHP versions +# TODO: When it becomes possible in TravisCI, switch 7.4snapshot to plain 7.4 +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - 7.2 + - 7.3 + - 7.4snapshot + - hhvm + +before_script: + - composer install --prefer-dist + +script: + - vendor/bin/phpunit --log-junit=phpunit.log + +notifications: + email: false diff --git a/system/vendor/michelf/php-markdown/License.md b/system/vendor/michelf/php-markdown/License.md index a26243e..16bbd54 100644 --- a/system/vendor/michelf/php-markdown/License.md +++ b/system/vendor/michelf/php-markdown/License.md @@ -1,11 +1,11 @@ PHP Markdown Lib -Copyright (c) 2004-2015 Michel Fortin +Copyright (c) 2004-2019 Michel Fortin All rights reserved. Based on Markdown -Copyright (c) 2003-2006 John Gruber - +Copyright (c) 2003-2006 John Gruber + All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/system/vendor/michelf/php-markdown/Michelf/Markdown.inc.php b/system/vendor/michelf/php-markdown/Michelf/Markdown.inc.php index 8c28109..e2bd380 100644 --- a/system/vendor/michelf/php-markdown/Michelf/Markdown.inc.php +++ b/system/vendor/michelf/php-markdown/Michelf/Markdown.inc.php @@ -1,10 +1,10 @@ -# -# Original Markdown -# Copyright (c) 2004-2006 John Gruber -# -# -namespace Michelf; - +/** + * Markdown - A text-to-HTML conversion tool for web writers + * + * @package php-markdown + * @author Michel Fortin + * @copyright 2004-2019 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ -# -# Markdown Parser Class -# +namespace Michelf; +/** + * Markdown Parser Class + */ class Markdown implements MarkdownInterface { - - ### Version ### - - const MARKDOWNLIB_VERSION = "1.6.0"; - - ### Simple Function Interface ### - + /** + * Define the package version + * @var string + */ + const MARKDOWNLIB_VERSION = "1.9.0"; + + /** + * Simple function interface - Initialize the parser and return the result + * of its transform method. This will work fine for derived classes too. + * + * @api + * + * @param string $text + * @return string + */ public static function defaultTransform($text) { - # - # Initialize the parser and return the result of its transform method. - # This will work fine for derived classes too. - # - # Take parser class on which this function was called. + // Take parser class on which this function was called. $parser_class = \get_called_class(); - # try to take parser from the static parser list + // Try to take parser from the static parser list static $parser_list; $parser =& $parser_list[$parser_class]; - # create the parser it not already set - if (!$parser) + // Create the parser it not already set + if (!$parser) { $parser = new $parser_class; + } - # Transform text using parser. + // Transform text using parser. return $parser->transform($text); } - ### Configuration Variables ### + /** + * Configuration variables + */ - # Change to ">" for HTML output. + /** + * Change to ">" for HTML output. + * @var string + */ public $empty_element_suffix = " />"; + + /** + * The width of indentation of the output markup + * @var int + */ public $tab_width = 4; - - # Change to `true` to disallow markup or entities. - public $no_markup = false; + + /** + * Change to `true` to disallow markup or entities. + * @var boolean + */ + public $no_markup = false; public $no_entities = false; - - # Predefined urls and titles for reference links and images. - public $predef_urls = array(); + + + /** + * Change to `true` to enable line breaks on \n without two trailling spaces + * @var boolean + */ + public $hard_wrap = false; + + /** + * Predefined URLs and titles for reference links and images. + * @var array + */ + public $predef_urls = array(); public $predef_titles = array(); - # Optional filter function for URLs + /** + * Optional filter function for URLs + * @var callable|null + */ public $url_filter_func = null; - # Optional header id="" generation callback function. + /** + * Optional header id="" generation callback function. + * @var callable|null + */ public $header_id_func = null; - - # Optional function for converting code block content to HTML + + /** + * Optional function for converting code block content to HTML + * @var callable|null + */ public $code_block_content_func = null; - # Class attribute to toggle "enhanced ordered list" behaviour - # setting this to true will allow ordered lists to start from the index - # number that is defined first. For example: - # 2. List item two - # 3. List item three - # - # becomes - #
    - #
  1. List item two
  2. - #
  3. List item three
  4. - #
+ /** + * Optional function for converting code span content to HTML. + * @var callable|null + */ + public $code_span_content_func = null; + + /** + * Class attribute to toggle "enhanced ordered list" behaviour + * setting this to true will allow ordered lists to start from the index + * number that is defined first. + * + * For example: + * 2. List item two + * 3. List item three + * + * Becomes: + *
    + *
  1. List item two
  2. + *
  3. List item three
  4. + *
+ * + * @var bool + */ public $enhanced_ordered_list = false; - ### Parser Implementation ### + /** + * Parser implementation + */ - # Regex to match balanced [brackets]. - # Needed to insert a maximum bracked depth while converting to PHP. + /** + * Regex to match balanced [brackets]. + * Needed to insert a maximum bracked depth while converting to PHP. + * @var int + */ protected $nested_brackets_depth = 6; protected $nested_brackets_re; - + protected $nested_url_parenthesis_depth = 4; protected $nested_url_parenthesis_re; - # Table of hash values for escaped characters: + /** + * Table of hash values for escaped characters: + * @var string + */ protected $escape_chars = '\`*_{}[]()>#+-.!'; protected $escape_chars_re; - + /** + * Constructor function. Initialize appropriate member variables. + * @return void + */ public function __construct() { - # - # Constructor function. Initialize appropriate member variables. - # $this->_initDetab(); $this->prepareItalicsAndBold(); - - $this->nested_brackets_re = + + $this->nested_brackets_re = str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). str_repeat('\])*', $this->nested_brackets_depth); - - $this->nested_url_parenthesis_re = + + $this->nested_url_parenthesis_re = str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); - + $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; - - # Sort document, block, and span gamut in ascendent priority order. + + // Sort document, block, and span gamut in ascendent priority order. asort($this->document_gamut); asort($this->block_gamut); asort($this->span_gamut); } - # Internal hashes used during transformation. - protected $urls = array(); - protected $titles = array(); + /** + * Internal hashes used during transformation. + * @var array + */ + protected $urls = array(); + protected $titles = array(); protected $html_hashes = array(); - - # Status flag to avoid invalid nesting. + + /** + * Status flag to avoid invalid nesting. + * @var boolean + */ protected $in_anchor = false; - - + + /** + * Status flag to avoid invalid nesting. + * @var boolean + */ + protected $in_emphasis_processing = false; + + /** + * Called before the transformation process starts to setup parser states. + * @return void + */ protected function setup() { - # - # Called before the transformation process starts to setup parser - # states. - # - # Clear global hashes. - $this->urls = $this->predef_urls; - $this->titles = $this->predef_titles; + // Clear global hashes. + $this->urls = $this->predef_urls; + $this->titles = $this->predef_titles; $this->html_hashes = array(); - - $this->in_anchor = false; + $this->in_anchor = false; + $this->in_emphasis_processing = false; } - + + /** + * Called after the transformation process to clear any variable which may + * be taking up memory unnecessarly. + * @return void + */ protected function teardown() { - # - # Called after the transformation process to clear any variable - # which may be taking up memory unnecessarly. - # - $this->urls = array(); - $this->titles = array(); + $this->urls = array(); + $this->titles = array(); $this->html_hashes = array(); } - + /** + * Main function. Performs some preprocessing on the input text and pass + * it through the document gamut. + * + * @api + * + * @param string $text + * @return string + */ public function transform($text) { - # - # Main function. Performs some preprocessing on the input text - # and pass it through the document gamut. - # $this->setup(); - + # Remove UTF-8 BOM and marker character in input, if present. $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); @@ -186,28 +255,33 @@ class Markdown implements MarkdownInterface { foreach ($this->document_gamut as $method => $priority) { $text = $this->$method($text); } - + $this->teardown(); return $text . "\n"; } - + + /** + * Define the document gamut + * @var array + */ protected $document_gamut = array( - # Strip link definitions, store in hashes. + // Strip link definitions, store in hashes. "stripLinkDefinitions" => 20, - "runBasicBlockGamut" => 30, - ); - - + ); + + /** + * Strips link definitions from text, stores the URLs and titles in + * hash references + * @param string $text + * @return string + */ protected function stripLinkDefinitions($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # + $less_than_tab = $this->tab_width - 1; - # Link defs are in the form: ^[id]: url "optional title" + // Link defs are in the form: ^[id]: url "optional title" $text = preg_replace_callback('{ ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 [ ]* @@ -231,43 +305,58 @@ class Markdown implements MarkdownInterface { (?:\n+|\Z) }xm', array($this, '_stripLinkDefinitions_callback'), - $text); + $text + ); return $text; } + + /** + * The callback to strip link definitions + * @param array $matches + * @return string + */ protected function _stripLinkDefinitions_callback($matches) { $link_id = strtolower($matches[1]); $url = $matches[2] == '' ? $matches[3] : $matches[2]; $this->urls[$link_id] = $url; $this->titles[$link_id] =& $matches[4]; - return ''; # String that will replace the block + return ''; // String that will replace the block } - + /** + * Hashify HTML blocks + * @param string $text + * @return string + */ protected function hashHTMLBlocks($text) { - if ($this->no_markup) return $text; + if ($this->no_markup) { + return $text; + } $less_than_tab = $this->tab_width - 1; - # Hashify HTML blocks: - # We only want to do this for block-level HTML tags, such as headers, - # lists, and tables. That's because we still want to wrap

s around - # "paragraphs" that are wrapped in non-block-level tags, such as anchors, - # phrase emphasis, and spans. The list of tags we're looking for is - # hard-coded: - # - # * List "a" is made of tags which can be both inline or block-level. - # These will be treated block-level when the start tag is alone on - # its line, otherwise they're not matched here and will be taken as - # inline later. - # * List "b" is made of tags which are always block-level; - # + /** + * Hashify HTML blocks: + * + * We only want to do this for block-level HTML tags, such as headers, + * lists, and tables. That's because we still want to wrap

s around + * "paragraphs" that are wrapped in non-block-level tags, such as + * anchors, phrase emphasis, and spans. The list of tags we're looking + * for is hard-coded: + * + * * List "a" is made of tags which can be both inline or block-level. + * These will be treated block-level when the start tag is alone on + * its line, otherwise they're not matched here and will be taken as + * inline later. + * * List "b" is made of tags which are always block-level; + */ $block_tags_a_re = 'ins|del'; $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. 'script|noscript|style|form|fieldset|iframe|math|svg|'. 'article|section|nav|aside|hgroup|header|footer|'. 'figure'; - # Regular expression for the content of a block tag. + // Regular expression for the content of a block tag. $nested_tags_level = 4; $attr = ' (?> # optional tag attributes @@ -281,7 +370,7 @@ class Markdown implements MarkdownInterface { | \'[^\']*\' # text inside single quotes (tolerate ">") )* - )? + )? '; $content = str_repeat(' @@ -293,29 +382,32 @@ class Markdown implements MarkdownInterface { (?> /> | - >', $nested_tags_level). # end of opening tag - '.*?'. # last level nested tag content + >', $nested_tags_level). // end of opening tag + '.*?'. // last level nested tag content str_repeat(' # closing nested tag ) - | + | <(?!/\2\s*> # other tags with a different name ) )*', $nested_tags_level); $content2 = str_replace('\2', '\3', $content); - # First, look for nested blocks, e.g.: - #

- #
- # tags for inner block must be indented. - #
- #
- # - # The outermost tags must start at the left margin for this to match, and - # the inner nested divs must be indented. - # We need to do this before the next, more liberal match, because the next - # match will start at the first `
` and stop at the first `
`. + /** + * First, look for nested blocks, e.g.: + *
+ *
+ * tags for inner block must be indented. + *
+ *
+ * + * The outermost tags must start at the left margin for this to match, + * and the inner nested divs must be indented. + * We need to do this before the next, more liberal match, because the + * next match will start at the first `
` and stop at the + * first `
`. + */ $text = preg_replace_callback('{(?> (?> (?<=\n) # Starting on its own line @@ -324,9 +416,9 @@ class Markdown implements MarkdownInterface { ) ( # save in $1 - # Match from `\n` to `\n`, handling nested tags + # Match from `\n` to `\n`, handling nested tags # in between. - + [ ]{0,'.$less_than_tab.'} <('.$block_tags_b_re.')# start tag = $2 '.$attr.'> # attributes followed by > and \n @@ -344,28 +436,28 @@ class Markdown implements MarkdownInterface { # the matching end tag [ ]* # trailing spaces/tabs (?=\n+|\Z) # followed by a newline or end of document - - | # Special case just for
. It was easier to make a special + + | # Special case just for
. It was easier to make a special # case than to make the other regex more complicated. - + [ ]{0,'.$less_than_tab.'} <(hr) # start tag = $2 '.$attr.' # attributes /?> # the matching end tag [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document - + | # Special case for standalone HTML comments: - + [ ]{0,'.$less_than_tab.'} (?s: ) [ ]* (?=\n{2,}|\Z) # followed by a blank line or end of document - + | # PHP and ASP-style processor instructions (hashBlock($text); return "\n\n$key\n\n"; } - - + + /** + * Called whenever a tag must be hashed when a function insert an atomic + * element in the text stream. Passing $text to through this function gives + * a unique text-token which will be reverted back when calling unhash. + * + * The $boundary argument specify what character should be used to surround + * the token. By convension, "B" is used for block elements that needs not + * to be wrapped into paragraph tags at the end, ":" is used for elements + * that are word separators and "X" is used in the general case. + * + * @param string $text + * @param string $boundary + * @return string + */ protected function hashPart($text, $boundary = 'X') { - # - # Called whenever a tag must be hashed when a function insert an atomic - # element in the text stream. Passing $text to through this function gives - # a unique text-token which will be reverted back when calling unhash. - # - # The $boundary argument specify what character should be used to surround - # the token. By convension, "B" is used for block elements that needs not - # to be wrapped into paragraph tags at the end, ":" is used for elements - # that are word separators and "X" is used in the general case. - # - # Swap back any tag hash found in $text so we do not have to `unhash` - # multiple times at the end. + // Swap back any tag hash found in $text so we do not have to `unhash` + // multiple times at the end. $text = $this->unhash($text); - - # Then hash the block. + + // Then hash the block. static $i = 0; $key = "$boundary\x1A" . ++$i . $boundary; $this->html_hashes[$key] = $text; - return $key; # String that will replace the tag. + return $key; // String that will replace the tag. } - + /** + * Shortcut function for hashPart with block-level boundaries. + * @param string $text + * @return string + */ protected function hashBlock($text) { - # - # Shortcut function for hashPart with block-level boundaries. - # return $this->hashPart($text, 'B'); } - + /** + * Define the block gamut - these are all the transformations that form + * block-level tags like paragraphs, headers, and list items. + * @var array + */ protected $block_gamut = array( - # - # These are all the transformations that form block-level - # tags like paragraphs, headers, and list items. - # "doHeaders" => 10, "doHorizontalRules" => 20, - "doLists" => 40, "doCodeBlocks" => 50, "doBlockQuotes" => 60, - ); - + ); + + /** + * Run block gamut tranformations. + * + * We need to escape raw HTML in Markdown source before doing anything + * else. This need to be done for each block, and not only at the + * begining in the Markdown function since hashed blocks can be part of + * list items and could have been indented. Indented blocks would have + * been seen as a code block in a previous pass of hashHTMLBlocks. + * + * @param string $text + * @return string + */ protected function runBlockGamut($text) { - # - # Run block gamut tranformations. - # - # We need to escape raw HTML in Markdown source before doing anything - # else. This need to be done for each block, and not only at the - # begining in the Markdown function since hashed blocks can be part of - # list items and could have been indented. Indented blocks would have - # been seen as a code block in a previous pass of hashHTMLBlocks. $text = $this->hashHTMLBlocks($text); - return $this->runBasicBlockGamut($text); } - + + /** + * Run block gamut tranformations, without hashing HTML blocks. This is + * useful when HTML blocks are known to be already hashed, like in the first + * whole-document pass. + * + * @param string $text + * @return string + */ protected function runBasicBlockGamut($text) { - # - # Run block gamut tranformations, without hashing HTML blocks. This is - # useful when HTML blocks are known to be already hashed, like in the first - # whole-document pass. - # + foreach ($this->block_gamut as $method => $priority) { $text = $this->$method($text); } - - # Finally form paragraph and restore hashed blocks. + + // Finally form paragraph and restore hashed blocks. $text = $this->formParagraphs($text); return $text; } - - + + /** + * Convert horizontal rules + * @param string $text + * @return string + */ protected function doHorizontalRules($text) { - # Do Horizontal Rules: return preg_replace( '{ ^[ ]{0,3} # Leading space @@ -477,67 +589,82 @@ class Markdown implements MarkdownInterface { [ ]* # Tailing spaces $ # End of line. }mx', - "\n".$this->hashBlock("empty_element_suffix")."\n", - $text); + "\n".$this->hashBlock("empty_element_suffix")."\n", + $text + ); } - + /** + * These are all the transformations that occur *within* block-level + * tags like paragraphs, headers, and list items. + * @var array + */ protected $span_gamut = array( - # - # These are all the transformations that occur *within* block-level - # tags like paragraphs, headers, and list items. - # - # Process character escapes, code spans, and inline HTML - # in one shot. + // Process character escapes, code spans, and inline HTML + // in one shot. "parseSpan" => -30, - - # Process anchor and image tags. Images must come first, - # because ![foo][f] looks like an anchor. + // Process anchor and image tags. Images must come first, + // because ![foo][f] looks like an anchor. "doImages" => 10, "doAnchors" => 20, - - # Make links out of things like `` - # Must come after doAnchors, because you can use < and > - # delimiters in inline links like [this](). + // Make links out of things like `` + // Must come after doAnchors, because you can use < and > + // delimiters in inline links like [this](). "doAutoLinks" => 30, "encodeAmpsAndAngles" => 40, - "doItalicsAndBold" => 50, "doHardBreaks" => 60, - ); + ); + /** + * Run span gamut transformations + * @param string $text + * @return string + */ protected function runSpanGamut($text) { - # - # Run span gamut tranformations. - # foreach ($this->span_gamut as $method => $priority) { $text = $this->$method($text); } return $text; } - - + + /** + * Do hard breaks + * @param string $text + * @return string + */ protected function doHardBreaks($text) { - # Do hard breaks: - return preg_replace_callback('/ {2,}\n/', - array($this, '_doHardBreaks_callback'), $text); + if ($this->hard_wrap) { + return preg_replace_callback('/ *\n/', + array($this, '_doHardBreaks_callback'), $text); + } else { + return preg_replace_callback('/ {2,}\n/', + array($this, '_doHardBreaks_callback'), $text); + } } + + /** + * Trigger part hashing for the hard break (callback method) + * @param array $matches + * @return string + */ protected function _doHardBreaks_callback($matches) { return $this->hashPart("empty_element_suffix\n"); } - + /** + * Turn Markdown link shortcuts into XHTML tags. + * @param string $text + * @return string + */ protected function doAnchors($text) { - # - # Turn Markdown link shortcuts into XHTML tags. - # - if ($this->in_anchor) return $text; + if ($this->in_anchor) { + return $text; + } $this->in_anchor = true; - - # - # First, handle reference-style links: [link text] [id] - # + + // First, handle reference-style links: [link text] [id] $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ @@ -554,9 +681,7 @@ class Markdown implements MarkdownInterface { }xs', array($this, '_doAnchors_reference_callback'), $text); - # - # Next, inline-style links: [link text](url "optional title") - # + // Next, inline-style links: [link text](url "optional title") $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ @@ -581,11 +706,9 @@ class Markdown implements MarkdownInterface { }xs', array($this, '_doAnchors_inline_callback'), $text); - # - # Last, handle reference-style shortcuts: [link text] - # These must come last in case you've also got [link text][1] - # or [link text](/foo) - # + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link text][1] + // or [link text](/foo) $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ @@ -598,50 +721,61 @@ class Markdown implements MarkdownInterface { $this->in_anchor = false; return $text; } + + /** + * Callback method to parse referenced anchors + * @param string $matches + * @return string + */ protected function _doAnchors_reference_callback($matches) { $whole_match = $matches[1]; $link_text = $matches[2]; $link_id =& $matches[3]; if ($link_id == "") { - # for shortcut links like [this][] or [this]. + // for shortcut links like [this][] or [this]. $link_id = $link_text; } - - # lower-case and turn embedded newlines into spaces + + // lower-case and turn embedded newlines into spaces $link_id = strtolower($link_id); $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); if (isset($this->urls[$link_id])) { $url = $this->urls[$link_id]; $url = $this->encodeURLAttribute($url); - + $result = "titles[$link_id] ) ) { $title = $this->titles[$link_id]; $title = $this->encodeAttribute($title); $result .= " title=\"$title\""; } - + $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text"; $result = $this->hashPart($result); - } - else { + } else { $result = $whole_match; } return $result; } + + /** + * Callback method to parse inline anchors + * @param string $matches + * @return string + */ protected function _doAnchors_inline_callback($matches) { - $whole_match = $matches[1]; $link_text = $this->runSpanGamut($matches[2]); - $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $url = $matches[3] === '' ? $matches[4] : $matches[3]; $title =& $matches[7]; - // if the URL was of the form it got caught by the HTML - // tag parser and hashed. Need to reverse the process before using the URL. + // If the URL was of the form it got caught by the HTML + // tag parser and hashed. Need to reverse the process before using + // the URL. $unhashed = $this->unhash($url); - if ($unhashed != $url) + if ($unhashed !== $url) $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); $url = $this->encodeURLAttribute($url); @@ -651,21 +785,20 @@ class Markdown implements MarkdownInterface { $title = $this->encodeAttribute($title); $result .= " title=\"$title\""; } - + $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text"; return $this->hashPart($result); } - + /** + * Turn Markdown image shortcuts into tags. + * @param string $text + * @return string + */ protected function doImages($text) { - # - # Turn Markdown image shortcuts into tags. - # - # - # First, handle reference-style labeled images: ![alt text][id] - # + // First, handle reference-style labeled images: ![alt text][id] $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ @@ -680,13 +813,11 @@ class Markdown implements MarkdownInterface { \] ) - }xs', + }xs', array($this, '_doImages_reference_callback'), $text); - # - # Next, handle inline images: ![alt text](url "optional title") - # Don't forget: encode * and _ - # + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ @@ -714,13 +845,19 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * Callback to parse references image tags + * @param array $matches + * @return string + */ protected function _doImages_reference_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; $link_id = strtolower($matches[3]); if ($link_id == "") { - $link_id = strtolower($alt_text); # for shortcut links like ![this][]. + $link_id = strtolower($alt_text); // for shortcut links like ![this][]. } $alt_text = $this->encodeAttribute($alt_text); @@ -734,14 +871,19 @@ class Markdown implements MarkdownInterface { } $result .= $this->empty_element_suffix; $result = $this->hashPart($result); - } - else { - # If there's no such link ID, leave intact: + } else { + // If there's no such link ID, leave intact: $result = $whole_match; } return $result; } + + /** + * Callback to parse inline image tags + * @param array $matches + * @return string + */ protected function _doImages_inline_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; @@ -753,32 +895,38 @@ class Markdown implements MarkdownInterface { $result = "\"$alt_text\"";encodeAttribute($title); - $result .= " title=\"$title\""; # $title already quoted + $result .= " title=\"$title\""; // $title already quoted } $result .= $this->empty_element_suffix; return $this->hashPart($result); } - + /** + * Parse Markdown heading elements to HTML + * @param string $text + * @return string + */ protected function doHeaders($text) { - # Setext-style headers: - # Header 1 - # ======== - # - # Header 2 - # -------- - # + /** + * Setext-style headers: + * Header 1 + * ======== + * + * Header 2 + * -------- + */ $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', array($this, '_doHeaders_callback_setext'), $text); - # atx-style headers: - # # Header 1 - # ## Header 2 - # ## Header 2 with closing hashes ## - # ... - # ###### Header 6 - # + /** + * atx-style headers: + * # Header 1 + * ## Header 2 + * ## Header 2 with closing hashes ## + * ... + * ###### Header 6 + */ $text = preg_replace_callback('{ ^(\#{1,6}) # $1 = string of #\'s [ ]* @@ -792,22 +940,33 @@ class Markdown implements MarkdownInterface { return $text; } + /** + * Setext header parsing callback + * @param array $matches + * @return string + */ protected function _doHeaders_callback_setext($matches) { - # Terrible hack to check we haven't found an empty list item. - if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) + // Terrible hack to check we haven't found an empty list item. + if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) { return $matches[0]; - - $level = $matches[2]{0} == '=' ? 1 : 2; + } + + $level = $matches[2][0] == '=' ? 1 : 2; - # id attribute generation + // ID attribute generation $idAtt = $this->_generateIdFromHeaderValue($matches[1]); $block = "".$this->runSpanGamut($matches[1]).""; return "\n" . $this->hashBlock($block) . "\n\n"; } - protected function _doHeaders_callback_atx($matches) { - # id attribute generation + /** + * ATX header parsing callback + * @param array $matches + * @return string + */ + protected function _doHeaders_callback_atx($matches) { + // ID attribute generation $idAtt = $this->_generateIdFromHeaderValue($matches[2]); $level = strlen($matches[1]); @@ -815,30 +974,37 @@ class Markdown implements MarkdownInterface { return "\n" . $this->hashBlock($block) . "\n\n"; } + /** + * If a header_id_func property is set, we can use it to automatically + * generate an id attribute. + * + * This method returns a string in the form id="foo", or an empty string + * otherwise. + * @param string $headerValue + * @return string + */ protected function _generateIdFromHeaderValue($headerValue) { - - # if a header_id_func property is set, we can use it to automatically - # generate an id attribute. - # - # This method returns a string in the form id="foo", or an empty string - # otherwise. if (!is_callable($this->header_id_func)) { return ""; } + $idValue = call_user_func($this->header_id_func, $headerValue); - if (!$idValue) return ""; + if (!$idValue) { + return ""; + } return ' id="' . $this->encodeAttribute($idValue) . '"'; - } + /** + * Form HTML ordered (numbered) and unordered (bulleted) lists. + * @param string $text + * @return string + */ protected function doLists($text) { - # - # Form HTML ordered (numbered) and unordered (bulleted) lists. - # $less_than_tab = $this->tab_width - 1; - # Re-usable patterns to match list item bullets and number markers: + // Re-usable patterns to match list item bullets and number markers: $marker_ul_re = '[*+-]'; $marker_ol_re = '\d+[\.]'; @@ -848,7 +1014,7 @@ class Markdown implements MarkdownInterface { ); foreach ($markers_relist as $marker_re => $other_marker_re) { - # Re-usable pattern to match any entirel ul or ol list: + // Re-usable pattern to match any entirel ul or ol list: $whole_list_re = ' ( # $1 = whole list ( # $2 @@ -875,18 +1041,17 @@ class Markdown implements MarkdownInterface { ) ) '; // mx - - # We use a different prefix before nested lists than top-level lists. - # See extended comment in _ProcessListItems(). - + + // We use a different prefix before nested lists than top-level lists. + //See extended comment in _ProcessListItems(). + if ($this->list_level) { $text = preg_replace_callback('{ ^ '.$whole_list_re.' }mx', array($this, '_doLists_callback'), $text); - } - else { + } else { $text = preg_replace_callback('{ (?:(?<=\n)\n|\A\n?) # Must eat the newline '.$whole_list_re.' @@ -897,8 +1062,14 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * List parsing callback + * @param array $matches + * @return string + */ protected function _doLists_callback($matches) { - # Re-usable patterns to match list item bullets and number markers: + // Re-usable patterns to match list item bullets and number markers: $marker_ul_re = '[*+-]'; $marker_ol_re = '\d+[\.]'; $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)"; @@ -914,7 +1085,7 @@ class Markdown implements MarkdownInterface { $ol_start = 1; if ($this->enhanced_ordered_list) { - # Get the start number for ordered list. + // Get the start number for ordered list. if ($list_type == 'ol') { $ol_start_array = array(); $ol_start_check = preg_match("/$marker_ol_start_re/", $matches[4], $ol_start_array); @@ -932,37 +1103,45 @@ class Markdown implements MarkdownInterface { return "\n". $result ."\n\n"; } + /** + * Nesting tracker for list levels + * @var integer + */ protected $list_level = 0; + /** + * Process the contents of a single ordered or unordered list, splitting it + * into individual list items. + * @param string $list_str + * @param string $marker_any_re + * @return string + */ protected function processListItems($list_str, $marker_any_re) { - # - # Process the contents of a single ordered or unordered list, splitting it - # into individual list items. - # - # The $this->list_level global keeps track of when we're inside a list. - # Each time we enter a list, we increment it; when we leave a list, - # we decrement. If it's zero, we're not in a list anymore. - # - # We do this because when we're not inside a list, we want to treat - # something like this: - # - # I recommend upgrading to version - # 8. Oops, now this line is treated - # as a sub-list. - # - # As a single paragraph, despite the fact that the second line starts - # with a digit-period-space sequence. - # - # Whereas when we're inside a list (or sub-list), that line will be - # treated as the start of a sub-list. What a kludge, huh? This is - # an aspect of Markdown's syntax that's hard to parse perfectly - # without resorting to mind-reading. Perhaps the solution is to - # change the syntax rules such that sub-lists must start with a - # starting cardinal number; e.g. "1." or "a.". - + /** + * The $this->list_level global keeps track of when we're inside a list. + * Each time we enter a list, we increment it; when we leave a list, + * we decrement. If it's zero, we're not in a list anymore. + * + * We do this because when we're not inside a list, we want to treat + * something like this: + * + * I recommend upgrading to version + * 8. Oops, now this line is treated + * as a sub-list. + * + * As a single paragraph, despite the fact that the second line starts + * with a digit-period-space sequence. + * + * Whereas when we're inside a list (or sub-list), that line will be + * treated as the start of a sub-list. What a kludge, huh? This is + * an aspect of Markdown's syntax that's hard to parse perfectly + * without resorting to mind-reading. Perhaps the solution is to + * change the syntax rules such that sub-lists must start with a + * starting cardinal number; e.g. "1." or "a.". + */ $this->list_level++; - # trim trailing blank lines: + // Trim trailing blank lines: $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); $list_str = preg_replace_callback('{ @@ -980,6 +1159,12 @@ class Markdown implements MarkdownInterface { $this->list_level--; return $list_str; } + + /** + * List item parsing callback + * @param array $matches + * @return string + */ protected function _processListItems_callback($matches) { $item = $matches[4]; $leading_line =& $matches[1]; @@ -987,28 +1172,27 @@ class Markdown implements MarkdownInterface { $marker_space = $matches[3]; $tailing_blank_line =& $matches[5]; - if ($leading_line || $tailing_blank_line || + if ($leading_line || $tailing_blank_line || preg_match('/\n{2,}/', $item)) { - # Replace marker with the appropriate whitespace indentation + // Replace marker with the appropriate whitespace indentation $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item; $item = $this->runBlockGamut($this->outdent($item)."\n"); - } - else { - # Recursion for sub-lists: + } else { + // Recursion for sub-lists: $item = $this->doLists($this->outdent($item)); - $item = preg_replace('/\n+$/', '', $item); - $item = $this->runSpanGamut($item); + $item = $this->formParagraphs($item, false); } return "
  • " . $item . "
  • \n"; } - + /** + * Process Markdown `
    ` blocks.
    +	 * @param  string $text
    +	 * @return string
    +	 */
     	protected function doCodeBlocks($text) {
    -	#
    -	#	Process Markdown `
    ` blocks.
    -	#
     		$text = preg_replace_callback('{
     				(?:\n\n|\A\n?)
     				(	            # $1 = the code block -- one or more lines, starting with a space/tab
    @@ -1023,11 +1207,17 @@ class Markdown implements MarkdownInterface {
     
     		return $text;
     	}
    +
    +	/**
    +	 * Code block parsing callback
    +	 * @param  array $matches
    +	 * @return string
    +	 */
     	protected function _doCodeBlocks_callback($matches) {
     		$codeblock = $matches[1];
     
     		$codeblock = $this->outdent($codeblock);
    -		if ($this->code_block_content_func) {
    +		if (is_callable($this->code_block_content_func)) {
     			$codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
     		} else {
     			$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
    @@ -1037,96 +1227,126 @@ class Markdown implements MarkdownInterface {
     		$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
     
     		$codeblock = "
    $codeblock\n
    "; - return "\n\n".$this->hashBlock($codeblock)."\n\n"; + return "\n\n" . $this->hashBlock($codeblock) . "\n\n"; } - + /** + * Create a code span markup for $code. Called from handleSpanToken. + * @param string $code + * @return string + */ protected function makeCodeSpan($code) { - # - # Create a code span markup for $code. Called from handleSpanToken. - # - $code = htmlspecialchars(trim($code), ENT_NOQUOTES); + if (is_callable($this->code_span_content_func)) { + $code = call_user_func($this->code_span_content_func, $code); + } else { + $code = htmlspecialchars(trim($code), ENT_NOQUOTES); + } return $this->hashPart("$code"); } - + /** + * Define the emphasis operators with their regex matches + * @var array + */ protected $em_relist = array( '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(?em_relist as $em => $em_re) { foreach ($this->strong_relist as $strong => $strong_re) { - # Construct list of allowed token expressions. + // Construct list of allowed token expressions. $token_relist = array(); if (isset($this->em_strong_relist["$em$strong"])) { $token_relist[] = $this->em_strong_relist["$em$strong"]; } $token_relist[] = $em_re; $token_relist[] = $strong_re; - - # Construct master expression from list. - $token_re = '{('. implode('|', $token_relist) .')}'; + + // Construct master expression from list. + $token_re = '{(' . implode('|', $token_relist) . ')}'; $this->em_strong_prepared_relist["$em$strong"] = $token_re; } } } - + + /** + * Convert Markdown italics (emphasis) and bold (strong) to HTML + * @param string $text + * @return string + */ protected function doItalicsAndBold($text) { + if ($this->in_emphasis_processing) { + return $text; // avoid reentrency + } + $this->in_emphasis_processing = true; + $token_stack = array(''); $text_stack = array(''); $em = ''; $strong = ''; $tree_char_em = false; - + while (1) { - # - # Get prepared regular expression for seraching emphasis tokens - # in current context. - # + // Get prepared regular expression for seraching emphasis tokens + // in current context. $token_re = $this->em_strong_prepared_relist["$em$strong"]; - - # - # Each loop iteration search for the next emphasis token. - # Each token is then passed to handleSpanToken. - # + + // Each loop iteration search for the next emphasis token. + // Each token is then passed to handleSpanToken. $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); $text_stack[0] .= $parts[0]; $token =& $parts[1]; $text =& $parts[2]; - + if (empty($token)) { - # Reached end of text span: empty stack without emitting. - # any more emphasis. + // Reached end of text span: empty stack without emitting. + // any more emphasis. while ($token_stack[0]) { $text_stack[1] .= array_shift($token_stack); $text_stack[0] .= array_shift($text_stack); } break; } - + $token_len = strlen($token); if ($tree_char_em) { - # Reached closing marker while inside a three-char emphasis. + // Reached closing marker while inside a three-char emphasis. if ($token_len == 3) { - # Three-char closing marker, close em and strong. + // Three-char closing marker, close em and strong. array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); @@ -1135,21 +1355,21 @@ class Markdown implements MarkdownInterface { $em = ''; $strong = ''; } else { - # Other closing marker: close one em or strong and - # change current token state to match the other - $token_stack[0] = str_repeat($token{0}, 3-$token_len); + // Other closing marker: close one em or strong and + // change current token state to match the other + $token_stack[0] = str_repeat($token[0], 3-$token_len); $tag = $token_len == 2 ? "strong" : "em"; $span = $text_stack[0]; $span = $this->runSpanGamut($span); $span = "<$tag>$span"; $text_stack[0] = $this->hashPart($span); - $$tag = ''; # $$tag stands for $em or $strong + $$tag = ''; // $$tag stands for $em or $strong } $tree_char_em = false; } else if ($token_len == 3) { if ($em) { - # Reached closing marker for both em and strong. - # Closing strong marker: + // Reached closing marker for both em and strong. + // Closing strong marker: for ($i = 0; $i < 2; ++$i) { $shifted_token = array_shift($token_stack); $tag = strlen($shifted_token) == 2 ? "strong" : "em"; @@ -1157,12 +1377,12 @@ class Markdown implements MarkdownInterface { $span = $this->runSpanGamut($span); $span = "<$tag>$span"; $text_stack[0] .= $this->hashPart($span); - $$tag = ''; # $$tag stands for $em or $strong + $$tag = ''; // $$tag stands for $em or $strong } } else { - # Reached opening three-char emphasis marker. Push on token - # stack; will be handled by the special condition above. - $em = $token{0}; + // Reached opening three-char emphasis marker. Push on token + // stack; will be handled by the special condition above. + $em = $token[0]; $strong = "$em$em"; array_unshift($token_stack, $token); array_unshift($text_stack, ''); @@ -1170,12 +1390,13 @@ class Markdown implements MarkdownInterface { } } else if ($token_len == 2) { if ($strong) { - # Unwind any dangling emphasis marker: + // Unwind any dangling emphasis marker: if (strlen($token_stack[0]) == 1) { $text_stack[1] .= array_shift($token_stack); $text_stack[0] .= array_shift($text_stack); + $em = ''; } - # Closing strong marker: + // Closing strong marker: array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); @@ -1188,10 +1409,10 @@ class Markdown implements MarkdownInterface { $strong = $token; } } else { - # Here $token_len == 1 + // Here $token_len == 1 if ($em) { if (strlen($token_stack[0]) == 1) { - # Closing emphasis marker: + // Closing emphasis marker: array_shift($token_stack); $span = array_shift($text_stack); $span = $this->runSpanGamut($span); @@ -1208,10 +1429,15 @@ class Markdown implements MarkdownInterface { } } } + $this->in_emphasis_processing = false; return $text_stack[0]; } - + /** + * Parse Markdown blockquotes to HTML + * @param string $text + * @return string + */ protected function doBlockQuotes($text) { $text = preg_replace_callback('/ ( # Wrap whole match in $1 @@ -1227,51 +1453,64 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * Blockquote parsing callback + * @param array $matches + * @return string + */ protected function _doBlockQuotes_callback($matches) { $bq = $matches[1]; - # trim one level of quoting - trim whitespace-only lines + // trim one level of quoting - trim whitespace-only lines $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq); - $bq = $this->runBlockGamut($bq); # recurse + $bq = $this->runBlockGamut($bq); // recurse $bq = preg_replace('/^/m', " ", $bq); - # These leading spaces cause problem with
     content, 
    -		# so we need to fix that:
    -		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', + // These leading spaces cause problem with
     content,
    +		// so we need to fix that:
    +		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', array($this, '_doBlockQuotes_callback2'), $bq); - return "\n". $this->hashBlock("
    \n$bq\n
    ")."\n\n"; + return "\n" . $this->hashBlock("
    \n$bq\n
    ") . "\n\n"; } + + /** + * Blockquote parsing callback + * @param array $matches + * @return string + */ protected function _doBlockQuotes_callback2($matches) { $pre = $matches[1]; $pre = preg_replace('/^ /m', '', $pre); return $pre; } - - protected function formParagraphs($text) { - # - # Params: - # $text - string to process with html

    tags - # - # Strip leading and trailing lines: + /** + * Parse paragraphs + * + * @param string $text String to process in paragraphs + * @param boolean $wrap_in_p Whether paragraphs should be wrapped in

    tags + * @return string + */ + protected function formParagraphs($text, $wrap_in_p = true) { + // Strip leading and trailing lines: $text = preg_replace('/\A\n+|\n+\z/', '', $text); $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); - # - # Wrap

    tags and unhashify HTML blocks - # + // Wrap

    tags and unhashify HTML blocks foreach ($grafs as $key => $value) { if (!preg_match('/^B\x1A[0-9]+B$/', $value)) { - # Is a paragraph. + // Is a paragraph. $value = $this->runSpanGamut($value); - $value = preg_replace('/^([ ]*)/', "

    ", $value); - $value .= "

    "; + if ($wrap_in_p) { + $value = preg_replace('/^([ ]*)/', "

    ", $value); + $value .= "

    "; + } $grafs[$key] = $this->unhash($value); - } - else { - # Is a block. - # Modify elements of @grafs in-place... + } else { + // Is a block. + // Modify elements of @grafs in-place... $graf = $value; $block = $this->html_hashes[$graf]; $graf = $block; @@ -1296,11 +1535,11 @@ class Markdown implements MarkdownInterface { // { // list(, $div_open, , $div_content, $div_close) = $matches; // -// # We can't call Markdown(), because that resets the hash; -// # that initialization code should be pulled into its own sub, though. +// // We can't call Markdown(), because that resets the hash; +// // that initialization code should be pulled into its own sub, though. // $div_content = $this->hashHTMLBlocks($div_content); -// -// # Run document gamut methods on the content. +// +// // Run document gamut methods on the content. // foreach ($this->document_gamut as $method => $priority) { // $div_content = $this->$method($div_content); // } @@ -1317,71 +1556,78 @@ class Markdown implements MarkdownInterface { return implode("\n\n", $grafs); } - + /** + * Encode text for a double-quoted HTML attribute. This function + * is *not* suitable for attributes enclosed in single quotes. + * @param string $text + * @return string + */ protected function encodeAttribute($text) { - # - # Encode text for a double-quoted HTML attribute. This function - # is *not* suitable for attributes enclosed in single quotes. - # $text = $this->encodeAmpsAndAngles($text); $text = str_replace('"', '"', $text); return $text; } - + /** + * Encode text for a double-quoted HTML attribute containing a URL, + * applying the URL filter if set. Also generates the textual + * representation for the URL (removing mailto: or tel:) storing it in $text. + * This function is *not* suitable for attributes enclosed in single quotes. + * + * @param string $url + * @param string $text Passed by reference + * @return string URL + */ protected function encodeURLAttribute($url, &$text = null) { - # - # Encode text for a double-quoted HTML attribute containing a URL, - # applying the URL filter if set. Also generates the textual - # representation for the URL (removing mailto: or tel:) storing it in $text. - # This function is *not* suitable for attributes enclosed in single quotes. - # - if ($this->url_filter_func) + if (is_callable($this->url_filter_func)) { $url = call_user_func($this->url_filter_func, $url); + } - if (preg_match('{^mailto:}i', $url)) + if (preg_match('{^mailto:}i', $url)) { $url = $this->encodeEntityObfuscatedAttribute($url, $text, 7); - else if (preg_match('{^tel:}i', $url)) - { + } else if (preg_match('{^tel:}i', $url)) { $url = $this->encodeAttribute($url); $text = substr($url, 4); - } - else - { + } else { $url = $this->encodeAttribute($url); $text = $url; } return $url; } - - + + /** + * Smart processing for ampersands and angle brackets that need to + * be encoded. Valid character entities are left alone unless the + * no-entities mode is set. + * @param string $text + * @return string + */ protected function encodeAmpsAndAngles($text) { - # - # Smart processing for ampersands and angle brackets that need to - # be encoded. Valid character entities are left alone unless the - # no-entities mode is set. - # if ($this->no_entities) { $text = str_replace('&', '&', $text); } else { - # Ampersand-encoding based entirely on Nat Irons's Amputator - # MT plugin: - $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', + // Ampersand-encoding based entirely on Nat Irons's Amputator + // MT plugin: + $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', '&', $text); } - # Encode remaining <'s + // Encode remaining <'s $text = str_replace('<', '<', $text); return $text; } - + /** + * Parse Markdown automatic links to anchor HTML tags + * @param string $text + * @return string + */ protected function doAutoLinks($text) { $text = preg_replace_callback('{<((https?|ftp|dict|tel):[^\'">\s]+)>}i', array($this, '_doAutoLinks_url_callback'), $text); - # Email addresses: + // Email addresses: $text = preg_replace_callback('{ < (?:mailto:)? @@ -1404,11 +1650,23 @@ class Markdown implements MarkdownInterface { return $text; } + + /** + * Parse URL callback + * @param array $matches + * @return string + */ protected function _doAutoLinks_url_callback($matches) { $url = $this->encodeURLAttribute($matches[1], $text); $link = "$text"; return $this->hashPart($link); } + + /** + * Parse email address callback + * @param array $matches + * @return string + */ protected function _doAutoLinks_email_callback($matches) { $addr = $matches[1]; $url = $this->encodeURLAttribute("mailto:$addr", $text); @@ -1416,42 +1674,52 @@ class Markdown implements MarkdownInterface { return $this->hashPart($link); } - + /** + * Input: some text to obfuscate, e.g. "mailto:foo@example.com" + * + * Output: the same text but with most characters encoded as either a + * decimal or hex entity, in the hopes of foiling most address + * harvesting spam bots. E.g.: + * + * mailto:foo + * @example.co + * m + * + * Note: the additional output $tail is assigned the same value as the + * ouput, minus the number of characters specified by $head_length. + * + * Based by a filter by Matthew Wickline, posted to BBEdit-Talk. + * With some optimizations by Milian Wolff. Forced encoding of HTML + * attribute special characters by Allan Odgaard. + * + * @param string $text + * @param string $tail Passed by reference + * @param integer $head_length + * @return string + */ protected function encodeEntityObfuscatedAttribute($text, &$tail = null, $head_length = 0) { - # - # Input: some text to obfuscate, e.g. "mailto:foo@example.com" - # - # Output: the same text but with most characters encoded as either a - # decimal or hex entity, in the hopes of foiling most address - # harvesting spam bots. E.g.: - # - # mailto:foo - # @example.co - # m - # - # Note: the additional output $tail is assigned the same value as the - # ouput, minus the number of characters specified by $head_length. - # - # Based by a filter by Matthew Wickline, posted to BBEdit-Talk. - # With some optimizations by Milian Wolff. Forced encoding of HTML - # attribute special characters by Allan Odgaard. - # - if ($text == "") return $tail = ""; + if ($text == "") { + return $tail = ""; + } $chars = preg_split('/(? $char) { $ord = ord($char); - # Ignore non-ascii chars. + // Ignore non-ascii chars. if ($ord < 128) { - $r = ($seed * (1 + $key)) % 100; # Pseudo-random function. - # roughly 10% raw, 45% hex, 45% dec - # '@' *must* be encoded. I insist. - # '"' and '>' have to be encoded inside the attribute - if ($r > 90 && strpos('@"&>', $char) === false) /* do nothing */; - else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';'; - else $chars[$key] = '&#'.$ord.';'; + $r = ($seed * (1 + $key)) % 100; // Pseudo-random function. + // roughly 10% raw, 45% hex, 45% dec + // '@' *must* be encoded. I insist. + // '"' and '>' have to be encoded inside the attribute + if ($r > 90 && strpos('@"&>', $char) === false) { + /* do nothing */ + } else if ($r < 45) { + $chars[$key] = '&#x'.dechex($ord).';'; + } else { + $chars[$key] = '&#'.$ord.';'; + } } } @@ -1461,14 +1729,15 @@ class Markdown implements MarkdownInterface { return $text; } - + /** + * Take the string $str and parse it into tokens, hashing embeded HTML, + * escaped characters and handling code spans. + * @param string $str + * @return string + */ protected function parseSpan($str) { - # - # Take the string $str and parse it into tokens, hashing embeded HTML, - # escaped characters and handling code spans. - # $output = ''; - + $span_re = '{ ( \\\\'.$this->escape_chars_re.' @@ -1496,121 +1765,145 @@ class Markdown implements MarkdownInterface { }xs'; while (1) { - # - # Each loop iteration seach for either the next tag, the next - # openning code span marker, or the next escaped character. - # Each token is then passed to handleSpanToken. - # + // Each loop iteration seach for either the next tag, the next + // openning code span marker, or the next escaped character. + // Each token is then passed to handleSpanToken. $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE); - - # Create token from text preceding tag. + + // Create token from text preceding tag. if ($parts[0] != "") { $output .= $parts[0]; } - - # Check if we reach the end. + + // Check if we reach the end. if (isset($parts[1])) { $output .= $this->handleSpanToken($parts[1], $parts[2]); $str = $parts[2]; - } - else { + } else { break; } } - + return $output; } - - + + /** + * Handle $token provided by parseSpan by determining its nature and + * returning the corresponding value that should replace it. + * @param string $token + * @param string $str Passed by reference + * @return string + */ protected function handleSpanToken($token, &$str) { - # - # Handle $token provided by parseSpan by determining its nature and - # returning the corresponding value that should replace it. - # - switch ($token{0}) { + switch ($token[0]) { case "\\": - return $this->hashPart("&#". ord($token{1}). ";"); + return $this->hashPart("&#". ord($token[1]). ";"); case "`": - # Search for end marker in remaining text. - if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', + // Search for end marker in remaining text. + if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', $str, $matches)) { $str = $matches[2]; $codespan = $this->makeCodeSpan($matches[1]); return $this->hashPart($codespan); } - return $token; // return as text since no ending marker found. + return $token; // Return as text since no ending marker found. default: return $this->hashPart($token); } } - + /** + * Remove one level of line-leading tabs or spaces + * @param string $text + * @return string + */ protected function outdent($text) { - # - # Remove one level of line-leading tabs or spaces - # - return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text); + return preg_replace('/^(\t|[ ]{1,' . $this->tab_width . '})/m', '', $text); } - # String length function for detab. `_initDetab` will create a function to - # hanlde UTF-8 if the default function does not exist. + /** + * String length function for detab. `_initDetab` will create a function to + * handle UTF-8 if the default function does not exist. + * @var string + */ protected $utf8_strlen = 'mb_strlen'; - + + /** + * Replace tabs with the appropriate amount of spaces. + * + * For each line we separate the line in blocks delemited by tab characters. + * Then we reconstruct every line by adding the appropriate number of space + * between each blocks. + * + * @param string $text + * @return string + */ protected function detab($text) { - # - # Replace tabs with the appropriate amount of space. - # - # For each line we separate the line in blocks delemited by - # tab characters. Then we reconstruct every line by adding the - # appropriate number of space between each blocks. - $text = preg_replace_callback('/^.*\t.*$/m', array($this, '_detab_callback'), $text); return $text; } + + /** + * Replace tabs callback + * @param string $matches + * @return string + */ protected function _detab_callback($matches) { $line = $matches[0]; - $strlen = $this->utf8_strlen; # strlen function for UTF-8. - - # Split in blocks. + $strlen = $this->utf8_strlen; // strlen function for UTF-8. + + // Split in blocks. $blocks = explode("\t", $line); - # Add each blocks to the line. + // Add each blocks to the line. $line = $blocks[0]; - unset($blocks[0]); # Do not add first block twice. + unset($blocks[0]); // Do not add first block twice. foreach ($blocks as $block) { - # Calculate amount of space, insert spaces, insert block. - $amount = $this->tab_width - + // Calculate amount of space, insert spaces, insert block. + $amount = $this->tab_width - $strlen($line, 'UTF-8') % $this->tab_width; $line .= str_repeat(" ", $amount) . $block; } return $line; } + + /** + * Check for the availability of the function in the `utf8_strlen` property + * (initially `mb_strlen`). If the function is not available, create a + * function that will loosely count the number of UTF-8 characters with a + * regular expression. + * @return void + */ protected function _initDetab() { - # - # Check for the availability of the function in the `utf8_strlen` property - # (initially `mb_strlen`). If the function is not available, create a - # function that will loosely count the number of UTF-8 characters with a - # regular expression. - # - if (function_exists($this->utf8_strlen)) return; - $this->utf8_strlen = create_function('$text', 'return preg_match_all( - "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", - $text, $m);'); - } + if (function_exists($this->utf8_strlen)) { + return; + } + + $this->utf8_strlen = function($text) { + return preg_match_all('/[\x00-\xBF]|[\xC0-\xFF][\x80-\xBF]*/', $text, $m); + }; + } + /** + * Swap back in all the tags hashed by _HashHTMLBlocks. + * @param string $text + * @return string + */ protected function unhash($text) { - # - # Swap back in all the tags hashed by _HashHTMLBlocks. - # - return preg_replace_callback('/(.)\x1A[0-9]+\1/', + return preg_replace_callback('/(.)\x1A[0-9]+\1/', array($this, '_unhash_callback'), $text); } + + /** + * Unhashing callback + * @param array $matches + * @return string + */ protected function _unhash_callback($matches) { return $this->html_hashes[$matches[0]]; } - } diff --git a/system/vendor/michelf/php-markdown/Michelf/MarkdownExtra.inc.php b/system/vendor/michelf/php-markdown/Michelf/MarkdownExtra.inc.php index e11b1ef..d09bd7a 100644 --- a/system/vendor/michelf/php-markdown/Michelf/MarkdownExtra.inc.php +++ b/system/vendor/michelf/php-markdown/Michelf/MarkdownExtra.inc.php @@ -1,10 +1,10 @@ -# -# Original Markdown -# Copyright (c) 2004-2006 John Gruber -# -# -namespace Michelf; - +/** + * Markdown Extra - A text-to-HTML conversion tool for web writers + * + * @package php-markdown + * @author Michel Fortin + * @copyright 2004-2019 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ -# -# Markdown Extra Parser Class -# +namespace Michelf; +/** + * Markdown Extra Parser Class + */ class MarkdownExtra extends \Michelf\Markdown { - - ### Configuration Variables ### - - # Prefix for footnote ids. + /** + * Configuration variables + */ + + /** + * Prefix for footnote ids. + * @var string + */ public $fn_id_prefix = ""; - - # Optional title attribute for footnote links and backlinks. + + /** + * Optional title attribute for footnote links. + * @var string + */ public $fn_link_title = ""; - public $fn_backlink_title = ""; - - # Optional class attribute for footnote links and backlinks. - public $fn_link_class = "footnote-ref"; + + /** + * Optional class attribute for footnote links and backlinks. + * @var string + */ + public $fn_link_class = "footnote-ref"; public $fn_backlink_class = "footnote-backref"; - # Content to be displayed within footnote backlinks. The default is '↩'; - # the U+FE0E on the end is a Unicode variant selector used to prevent iOS - # from displaying the arrow character as an emoji. + /** + * Content to be displayed within footnote backlinks. The default is '↩'; + * the U+FE0E on the end is a Unicode variant selector used to prevent iOS + * from displaying the arrow character as an emoji. + * Optionally use '^^' and '%%' to refer to the footnote number and + * reference number respectively. {@see parseFootnotePlaceholders()} + * @var string + */ public $fn_backlink_html = '↩︎'; - # Class name for table cell alignment (%% replaced left/center/right) - # For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' - # If empty, the align attribute is used instead of a class name. + /** + * Optional title and aria-label attributes for footnote backlinks for + * added accessibility (to ensure backlink uniqueness). + * Use '^^' and '%%' to refer to the footnote number and reference number + * respectively. {@see parseFootnotePlaceholders()} + * @var string + */ + public $fn_backlink_title = ""; + public $fn_backlink_label = ""; + + /** + * Class name for table cell alignment (%% replaced left/center/right) + * For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' + * If empty, the align attribute is used instead of a class name. + * @var string + */ public $table_align_class_tmpl = ''; - # Optional class prefix for fenced code block. + /** + * Optional class prefix for fenced code block. + * @var string + */ public $code_class_prefix = ""; - # Class attribute for code blocks goes on the `code` tag; - # setting this to true will put attributes on the `pre` tag instead. + + /** + * Class attribute for code blocks goes on the `code` tag; + * setting this to true will put attributes on the `pre` tag instead. + * @var boolean + */ public $code_attr_on_pre = false; - # Predefined abbreviations. + /** + * Predefined abbreviations. + * @var array + */ public $predef_abbr = array(); - ### Parser Implementation ### - + /** + * Only convert atx-style headers if there's a space between the header and # + * @var boolean + */ + public $hashtag_protection = false; + + /** + * Determines whether footnotes should be appended to the end of the document. + * If true, footnote html can be retrieved from $this->footnotes_assembled. + * @var boolean + */ + public $omit_footnotes = false; + + + /** + * After parsing, the HTML for the list of footnotes appears here. + * This is available only if $omit_footnotes == true. + * + * Note: when placing the content of `footnotes_assembled` on the page, + * consider adding the attribute `role="doc-endnotes"` to the `div` or + * `section` that will enclose the list of footnotes so they are + * reachable to accessibility tools the same way they would be with the + * default HTML output. + * @var null|string + */ + public $footnotes_assembled = null; + + /** + * Parser implementation + */ + + /** + * Constructor function. Initialize the parser object. + * @return void + */ public function __construct() { - # - # Constructor function. Initialize the parser object. - # - # Add extra escapable characters before parent constructor - # initialize the table. + // Add extra escapable characters before parent constructor + // initialize the table. $this->escape_chars .= ':|'; - - # Insert extra document, block, and span transformations. - # Parent constructor will do the sorting. + + // Insert extra document, block, and span transformations. + // Parent constructor will do the sorting. $this->document_gamut += array( "doFencedCodeBlocks" => 5, "stripFootnotes" => 15, "stripAbbreviations" => 25, "appendFootnotes" => 50, - ); + ); $this->block_gamut += array( "doFencedCodeBlocks" => 5, "doTables" => 15, "doDefLists" => 45, - ); + ); $this->span_gamut += array( "doFootnotes" => 5, "doAbbreviations" => 70, - ); - + ); + $this->enhanced_ordered_list = true; parent::__construct(); } - - - # Extra variables used during extra transformations. + + + /** + * Extra variables used during extra transformations. + * @var array + */ protected $footnotes = array(); protected $footnotes_ordered = array(); protected $footnotes_ref_count = array(); protected $footnotes_numbers = array(); protected $abbr_desciptions = array(); + /** @var string */ protected $abbr_word_re = ''; - - # Give the current footnote number. + + /** + * Give the current footnote number. + * @var integer + */ protected $footnote_counter = 1; - - + + /** + * Ref attribute for links + * @var array + */ + protected $ref_attr = array(); + + /** + * Setting up Extra-specific variables. + */ protected function setup() { - # - # Setting up Extra-specific variables. - # parent::setup(); - + $this->footnotes = array(); $this->footnotes_ordered = array(); $this->footnotes_ref_count = array(); @@ -109,7 +184,8 @@ class MarkdownExtra extends \Michelf\Markdown { $this->abbr_desciptions = array(); $this->abbr_word_re = ''; $this->footnote_counter = 1; - + $this->footnotes_assembled = null; + foreach ($this->predef_abbr as $abbr_word => $abbr_desc) { if ($this->abbr_word_re) $this->abbr_word_re .= '|'; @@ -117,52 +193,72 @@ class MarkdownExtra extends \Michelf\Markdown { $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); } } - + + /** + * Clearing Extra-specific variables. + */ protected function teardown() { - # - # Clearing Extra-specific variables. - # $this->footnotes = array(); $this->footnotes_ordered = array(); $this->footnotes_ref_count = array(); $this->footnotes_numbers = array(); $this->abbr_desciptions = array(); $this->abbr_word_re = ''; - + + if ( ! $this->omit_footnotes ) + $this->footnotes_assembled = null; + parent::teardown(); } - - - ### Extra Attribute Parser ### - # Expression to use to catch attributes (includes the braces) + + /** + * Extra attribute parser + */ + + /** + * Expression to use to catch attributes (includes the braces) + * @var string + */ protected $id_class_attr_catch_re = '\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}'; - # Expression to use when parsing in a context when no capture is desired + + /** + * Expression to use when parsing in a context when no capture is desired + * @var string + */ protected $id_class_attr_nocatch_re = '\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}'; + /** + * Parse attributes caught by the $this->id_class_attr_catch_re expression + * and return the HTML-formatted list of attributes. + * + * Currently supported attributes are .class and #id. + * + * In addition, this method also supports supplying a default Id value, + * which will be used to populate the id attribute in case it was not + * overridden. + * @param string $tag_name + * @param string $attr + * @param mixed $defaultIdValue + * @param array $classes + * @return string + */ protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) { - # - # Parse attributes caught by the $this->id_class_attr_catch_re expression - # and return the HTML-formatted list of attributes. - # - # Currently supported attributes are .class and #id. - # - # In addition, this method also supports supplying a default Id value, - # which will be used to populate the id attribute in case it was not - # overridden. - if (empty($attr) && !$defaultIdValue && empty($classes)) return ""; - - # Split on components + if (empty($attr) && !$defaultIdValue && empty($classes)) { + return ""; + } + + // Split on components preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches); $elements = $matches[0]; - # handle classes and ids (only first id taken into account) + // Handle classes and IDs (only first ID taken into account) $attributes = array(); $id = false; foreach ($elements as $element) { - if ($element{0} == '.') { + if ($element[0] === '.') { $classes[] = substr($element, 1); - } else if ($element{0} == '#') { + } else if ($element[0] === '#') { if ($id === false) $id = substr($element, 1); } else if (strpos($element, '=') > 0) { $parts = explode('=', $element, 2); @@ -170,9 +266,11 @@ class MarkdownExtra extends \Michelf\Markdown { } } - if (!$id) $id = $defaultIdValue; + if ($id === false || $id === '') { + $id = $defaultIdValue; + } - # compose attributes as string + // Compose attributes as string $attr_str = ""; if (!empty($id)) { $attr_str .= ' id="'.$this->encodeAttribute($id) .'"'; @@ -186,15 +284,16 @@ class MarkdownExtra extends \Michelf\Markdown { return $attr_str; } - + /** + * Strips link definitions from text, stores the URLs and titles in + * hash references. + * @param string $text + * @return string + */ protected function stripLinkDefinitions($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # $less_than_tab = $this->tab_width - 1; - # Link defs are in the form: ^[id]: url "optional title" + // Link defs are in the form: ^[id]: url "optional title" $text = preg_replace_callback('{ ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 [ ]* @@ -222,109 +321,141 @@ class MarkdownExtra extends \Michelf\Markdown { $text); return $text; } + + /** + * Strip link definition callback + * @param array $matches + * @return string + */ protected function _stripLinkDefinitions_callback($matches) { $link_id = strtolower($matches[1]); $url = $matches[2] == '' ? $matches[3] : $matches[2]; $this->urls[$link_id] = $url; $this->titles[$link_id] =& $matches[4]; $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]); - return ''; # String that will replace the block + return ''; // String that will replace the block } - ### HTML Block Parser ### - - # Tags that are always treated as block tags: + /** + * HTML block parser + */ + + /** + * Tags that are always treated as block tags + * @var string + */ protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure'; - - # Tags treated as block tags only if the opening tag is alone on its line: + + /** + * Tags treated as block tags only if the opening tag is alone on its line + * @var string + */ protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video'; - - # Tags where markdown="1" default to span mode: + + /** + * Tags where markdown="1" default to span mode: + * @var string + */ protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; - - # Tags which must not have their contents modified, no matter where - # they appear: + + /** + * Tags which must not have their contents modified, no matter where + * they appear + * @var string + */ protected $clean_tags_re = 'script|style|math|svg'; - - # Tags that do not need to be closed. + + /** + * Tags that do not need to be closed. + * @var string + */ protected $auto_close_tags_re = 'hr|img|param|source|track'; - + /** + * Hashify HTML Blocks and "clean tags". + * + * We only want to do this for block-level HTML tags, such as headers, + * lists, and tables. That's because we still want to wrap

    s around + * "paragraphs" that are wrapped in non-block-level tags, such as anchors, + * phrase emphasis, and spans. The list of tags we're looking for is + * hard-coded. + * + * This works by calling _HashHTMLBlocks_InMarkdown, which then calls + * _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" + * attribute is found within a tag, _HashHTMLBlocks_InHTML calls back + * _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. + * These two functions are calling each other. It's recursive! + * @param string $text + * @return string + */ protected function hashHTMLBlocks($text) { - # - # Hashify HTML Blocks and "clean tags". - # - # We only want to do this for block-level HTML tags, such as headers, - # lists, and tables. That's because we still want to wrap

    s around - # "paragraphs" that are wrapped in non-block-level tags, such as anchors, - # phrase emphasis, and spans. The list of tags we're looking for is - # hard-coded. - # - # This works by calling _HashHTMLBlocks_InMarkdown, which then calls - # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" - # attribute is found within a tag, _HashHTMLBlocks_InHTML calls back - # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag. - # These two functions are calling each other. It's recursive! - # - if ($this->no_markup) return $text; - - # - # Call the HTML-in-Markdown hasher. - # + if ($this->no_markup) { + return $text; + } + + // Call the HTML-in-Markdown hasher. list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text); - + return $text; } + + /** + * Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. + * + * * $indent is the number of space to be ignored when checking for code + * blocks. This is important because if we don't take the indent into + * account, something like this (which looks right) won't work as expected: + * + *

    + *
    + * Hello World. <-- Is this a Markdown code block or text? + *
    <-- Is this a Markdown code block or a real tag? + *
    + * + * If you don't like this, just don't indent the tag on which + * you apply the markdown="1" attribute. + * + * * If $enclosing_tag_re is not empty, stops at the first unmatched closing + * tag with that name. Nested tags supported. + * + * * If $span is true, text inside must treated as span. So any double + * newline will be replaced by a single newline so that it does not create + * paragraphs. + * + * Returns an array of that form: ( processed text , remaining text ) + * + * @param string $text + * @param integer $indent + * @param string $enclosing_tag_re + * @param boolean $span + * @return array + */ protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0, $enclosing_tag_re = '', $span = false) { - # - # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags. - # - # * $indent is the number of space to be ignored when checking for code - # blocks. This is important because if we don't take the indent into - # account, something like this (which looks right) won't work as expected: - # - #
    - #
    - # Hello World. <-- Is this a Markdown code block or text? - #
    <-- Is this a Markdown code block or a real tag? - #
    - # - # If you don't like this, just don't indent the tag on which - # you apply the markdown="1" attribute. - # - # * If $enclosing_tag_re is not empty, stops at the first unmatched closing - # tag with that name. Nested tags supported. - # - # * If $span is true, text inside must treated as span. So any double - # newline will be replaced by a single newline so that it does not create - # paragraphs. - # - # Returns an array of that form: ( processed text , remaining text ) - # + if ($text === '') return array('', ''); - # Regex to check for the presense of newlines around a block tag. + // Regex to check for the presense of newlines around a block tag. $newline_before_re = '/(?:^\n?|\n\n)*$/'; - $newline_after_re = + $newline_after_re = '{ ^ # Start of text following the tag. (?>[ ]*)? # Optional comment. [ ]*\n # Must be followed by newline. }xs'; - - # Regex to match any tag. + + // Regex to match any tag. $block_tag_re = '{ ( # $2: Capture whole tag. # Tag name. - '.$this->block_tags_re.' | - '.$this->context_block_tags_re.' | - '.$this->clean_tags_re.' | - (?!\s)'.$enclosing_tag_re.' + ' . $this->block_tags_re . ' | + ' . $this->context_block_tags_re . ' | + ' . $this->clean_tags_re . ' | + (?!\s)'.$enclosing_tag_re . ' ) (?: (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name. @@ -341,25 +472,25 @@ class MarkdownExtra extends \Michelf\Markdown { <\?.*?\?> | <%.*?%> # Processing instruction | # CData Block - '. ( !$span ? ' # If not in span. + ' . ( !$span ? ' # If not in span. | # Indented code block (?: ^[ ]*\n | ^ | \n[ ]*\n ) - [ ]{'.($indent+4).'}[^\n]* \n + [ ]{' . ($indent + 4) . '}[^\n]* \n (?> - (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n + (?: [ ]{' . ($indent + 4) . '}[^\n]* | [ ]* ) \n )* | # Fenced code block marker (?<= ^ | \n ) - [ ]{0,'.($indent+3).'}(?:~{3,}|`{3,}) + [ ]{0,' . ($indent + 3) . '}(?:~{3,}|`{3,}) [ ]* (?: \.?[-_:a-zA-Z0-9]+ )? # standalone class name [ ]* - (?: '.$this->id_class_attr_nocatch_re.' )? # extra attributes + (?: ' . $this->id_class_attr_nocatch_re . ' )? # extra attributes [ ]* (?= \n ) - ' : '' ). ' # End (if not is span). + ' : '' ) . ' # End (if not is span). | # Code span marker # Note, this regex needs to go after backtick fenced @@ -369,185 +500,172 @@ class MarkdownExtra extends \Michelf\Markdown { ) }xs'; - - $depth = 0; # Current depth inside the tag tree. - $parsed = ""; # Parsed text that will be returned. - # - # Loop through every tag until we find the closing tag of the parent - # or loop until reaching the end of text if no parent tag specified. - # + $depth = 0; // Current depth inside the tag tree. + $parsed = ""; // Parsed text that will be returned. + + // Loop through every tag until we find the closing tag of the parent + // or loop until reaching the end of text if no parent tag specified. do { - # - # Split the text using the first $tag_match pattern found. - # Text before pattern will be first in the array, text after - # pattern will be at the end, and between will be any catches made - # by the pattern. - # - $parts = preg_split($block_tag_re, $text, 2, + // Split the text using the first $tag_match pattern found. + // Text before pattern will be first in the array, text after + // pattern will be at the end, and between will be any catches made + // by the pattern. + $parts = preg_split($block_tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); - - # If in Markdown span mode, add a empty-string span-level hash - # after each newline to prevent triggering any block element. + + // If in Markdown span mode, add a empty-string span-level hash + // after each newline to prevent triggering any block element. if ($span) { $void = $this->hashPart("", ':'); - $newline = "$void\n"; + $newline = "\n$void"; $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void; } - - $parsed .= $parts[0]; # Text before current tag. - - # If end of $text has been reached. Stop loop. + + $parsed .= $parts[0]; // Text before current tag. + + // If end of $text has been reached. Stop loop. if (count($parts) < 3) { $text = ""; break; } - - $tag = $parts[1]; # Tag to handle. - $text = $parts[2]; # Remaining text after current tag. - $tag_re = preg_quote($tag); # For use in a regular expression. - - # - # Check for: Fenced code block marker. - # Note: need to recheck the whole tag to disambiguate backtick - # fences from code spans - # - if (preg_match('{^\n?([ ]{0,'.($indent+3).'})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+)?[ ]*(?:'.$this->id_class_attr_nocatch_re.')?[ ]*\n?$}', $tag, $capture)) { - # Fenced code block marker: find matching end marker. - $fence_indent = strlen($capture[1]); # use captured indent in re - $fence_re = $capture[2]; # use captured fence in re - if (preg_match('{^(?>.*\n)*?[ ]{'.($fence_indent).'}'.$fence_re.'[ ]*(?:\n|$)}', $text, - $matches)) + + $tag = $parts[1]; // Tag to handle. + $text = $parts[2]; // Remaining text after current tag. + + // Check for: Fenced code block marker. + // Note: need to recheck the whole tag to disambiguate backtick + // fences from code spans + if (preg_match('{^\n?([ ]{0,' . ($indent + 3) . '})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+)?[ ]*(?:' . $this->id_class_attr_nocatch_re . ')?[ ]*\n?$}', $tag, $capture)) { + // Fenced code block marker: find matching end marker. + $fence_indent = strlen($capture[1]); // use captured indent in re + $fence_re = $capture[2]; // use captured fence in re + if (preg_match('{^(?>.*\n)*?[ ]{' . ($fence_indent) . '}' . $fence_re . '[ ]*(?:\n|$)}', $text, + $matches)) { - # End marker found: pass text unchanged until marker. + // End marker found: pass text unchanged until marker. $parsed .= $tag . $matches[0]; $text = substr($text, strlen($matches[0])); } else { - # No end marker: just skip it. + // No end marker: just skip it. $parsed .= $tag; } } - # - # Check for: Indented code block. - # - else if ($tag{0} == "\n" || $tag{0} == " ") { - # Indented code block: pass it unchanged, will be handled - # later. + // Check for: Indented code block. + else if ($tag[0] === "\n" || $tag[0] === " ") { + // Indented code block: pass it unchanged, will be handled + // later. $parsed .= $tag; } - # - # Check for: Code span marker - # Note: need to check this after backtick fenced code blocks - # - else if ($tag{0} == "`") { - # Find corresponding end marker. + // Check for: Code span marker + // Note: need to check this after backtick fenced code blocks + else if ($tag[0] === "`") { + // Find corresponding end marker. $tag_re = preg_quote($tag); - if (preg_match('{^(?>.+?|\n(?!\n))*?(?.+?|\n(?!\n))*?(?block_tags_re.')\b}', $tag) || - ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) && + // Check for: Opening Block level tag or + // Opening Context Block tag (like ins and del) + // used as a block tag (tag is alone on it's line). + else if (preg_match('{^<(?:' . $this->block_tags_re . ')\b}', $tag) || + ( preg_match('{^<(?:' . $this->context_block_tags_re . ')\b}', $tag) && preg_match($newline_before_re, $parsed) && preg_match($newline_after_re, $text) ) ) { - # Need to parse tag and following text using the HTML parser. - list($block_text, $text) = + // Need to parse tag and following text using the HTML parser. + list($block_text, $text) = $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true); - - # Make sure it stays outside of any paragraph by adding newlines. + + // Make sure it stays outside of any paragraph by adding newlines. $parsed .= "\n\n$block_text\n\n"; } - # - # Check for: Clean tag (like script, math) - # HTML Comments, processing instructions. - # - else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) || - $tag{1} == '!' || $tag{1} == '?') + // Check for: Clean tag (like script, math) + // HTML Comments, processing instructions. + else if (preg_match('{^<(?:' . $this->clean_tags_re . ')\b}', $tag) || + $tag[1] === '!' || $tag[1] === '?') { - # Need to parse tag and following text using the HTML parser. - # (don't check for markdown attribute) - list($block_text, $text) = + // Need to parse tag and following text using the HTML parser. + // (don't check for markdown attribute) + list($block_text, $text) = $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false); - + $parsed .= $block_text; } - # - # Check for: Tag with same name as enclosing tag. - # + // Check for: Tag with same name as enclosing tag. else if ($enclosing_tag_re !== '' && - # Same name as enclosing tag. - preg_match('{^= 0); - + return array($parsed, $text); } + + /** + * Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. + * + * * Calls $hash_method to convert any blocks. + * * Stops when the first opening tag closes. + * * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. + * (it is not inside clean tags) + * + * Returns an array of that form: ( processed text , remaining text ) + * @param string $text + * @param string $hash_method + * @param bool $md_attr Handle `markdown="1"` attribute + * @return array + */ protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) { - # - # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags. - # - # * Calls $hash_method to convert any blocks. - # * Stops when the first opening tag closes. - # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed. - # (it is not inside clean tags) - # - # Returns an array of that form: ( processed text , remaining text ) - # if ($text === '') return array('', ''); - - # Regex to match `markdown` attribute inside of a tag. + + // Regex to match `markdown` attribute inside of a tag. $markdown_attr_re = ' { \s* # Eat whitespace before the `markdown` attribute markdown \s*=\s* (?> - (["\']) # $1: quote delimiter + (["\']) # $1: quote delimiter (.*?) # $2: attribute value - \1 # matching delimiter + \1 # matching delimiter | ([^\s>]*) # $3: unquoted attribute value ) () # $4: make $3 always defined (avoid warnings) }xs'; - - # Regex to match any tag. + + // Regex to match any tag. $tag_re = '{ ( # $2: Capture whole tag. # CData Block ) }xs'; - - $original_text = $text; # Save original text in case of faliure. - - $depth = 0; # Current depth inside the tag tree. - $block_text = ""; # Temporary text holder for current text. - $parsed = ""; # Parsed text that will be returned. - - # - # Get the name of the starting tag. - # (This pattern makes $base_tag_name_re safe without quoting.) - # + + $original_text = $text; // Save original text in case of faliure. + + $depth = 0; // Current depth inside the tag tree. + $block_text = ""; // Temporary text holder for current text. + $parsed = ""; // Parsed text that will be returned. + $base_tag_name_re = ''; + + // Get the name of the starting tag. + // (This pattern makes $base_tag_name_re safe without quoting.) if (preg_match('/^<([\w:$]*)\b/', $text, $matches)) $base_tag_name_re = $matches[1]; - # - # Loop through every tag until we find the corresponding closing tag. - # + // Loop through every tag until we find the corresponding closing tag. do { - # - # Split the text using the first $tag_match pattern found. - # Text before pattern will be first in the array, text after - # pattern will be at the end, and between will be any catches made - # by the pattern. - # + // Split the text using the first $tag_match pattern found. + // Text before pattern will be first in the array, text after + // pattern will be at the end, and between will be any catches made + // by the pattern. $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); - + if (count($parts) < 3) { - # - # End of $text reached with unbalenced tag(s). - # In that case, we return original text unchanged and pass the - # first character as filtered to prevent an infinite loop in the - # parent function. - # - return array($original_text{0}, substr($original_text, 1)); + // End of $text reached with unbalenced tag(s). + // In that case, we return original text unchanged and pass the + // first character as filtered to prevent an infinite loop in the + // parent function. + return array($original_text[0], substr($original_text, 1)); } - - $block_text .= $parts[0]; # Text before current tag. - $tag = $parts[1]; # Tag to handle. - $text = $parts[2]; # Remaining text after current tag. - - # - # Check for: Auto-close tag (like
    ) - # Comments and Processing Instructions. - # - if (preg_match('{^auto_close_tags_re.')\b}', $tag) || - $tag{1} == '!' || $tag{1} == '?') + + $block_text .= $parts[0]; // Text before current tag. + $tag = $parts[1]; // Tag to handle. + $text = $parts[2]; // Remaining text after current tag. + + // Check for: Auto-close tag (like
    ) + // Comments and Processing Instructions. + if (preg_match('{^auto_close_tags_re . ')\b}', $tag) || + $tag[1] === '!' || $tag[1] === '?') { - # Just add the tag to the block as if it was text. + // Just add the tag to the block as if it was text. $block_text .= $tag; } else { - # - # Increase/decrease nested tag count. Only do so if - # the tag's name match base tag's. - # - if (preg_match('{^mode = $attr_m[2] . $attr_m[3]; - $span_mode = $this->mode == 'span' || $this->mode != 'block' && - preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag); - - # Calculate indent before tag. + + // Check if text inside this tag must be parsed in span mode. + $mode = $attr_m[2] . $attr_m[3]; + $span_mode = $mode === 'span' || ($mode !== 'block' && + preg_match('{^<(?:' . $this->contain_span_tags_re . ')\b}', $tag)); + + // Calculate indent before tag. if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) { $strlen = $this->utf8_strlen; $indent = $strlen($matches[1], 'UTF-8'); } else { $indent = 0; } - - # End preceding block with this tag. + + // End preceding block with this tag. $block_text .= $tag; $parsed .= $this->$hash_method($block_text); - - # Get enclosing tag name for the ParseMarkdown function. - # (This pattern makes $tag_name_re safe without quoting.) + + // Get enclosing tag name for the ParseMarkdown function. + // (This pattern makes $tag_name_re safe without quoting.) preg_match('/^<([\w:$]*)\b/', $tag, $matches); $tag_name_re = $matches[1]; - - # Parse the content using the HTML-in-Markdown parser. + + // Parse the content using the HTML-in-Markdown parser. list ($block_text, $text) - = $this->_hashHTMLBlocks_inMarkdown($text, $indent, + = $this->_hashHTMLBlocks_inMarkdown($text, $indent, $tag_name_re, $span_mode); - - # Outdent markdown text. + + // Outdent markdown text. if ($indent > 0) { - $block_text = preg_replace("/^[ ]{1,$indent}/m", "", + $block_text = preg_replace("/^[ ]{1,$indent}/m", "", $block_text); } - - # Append tag content to parsed text. - if (!$span_mode) $parsed .= "\n\n$block_text\n\n"; - else $parsed .= "$block_text"; - - # Start over with a new block. + + // Append tag content to parsed text. + if (!$span_mode) { + $parsed .= "\n\n$block_text\n\n"; + } else { + $parsed .= (string) $block_text; + } + + // Start over with a new block. $block_text = ""; } else $block_text .= $tag; } - + } while ($depth > 0); - - # - # Hash last block text that wasn't processed inside the loop. - # + + // Hash last block text that wasn't processed inside the loop. $parsed .= $this->$hash_method($block_text); - + return array($parsed, $text); } - + /** + * Called whenever a tag must be hashed when a function inserts a "clean" tag + * in $text, it passes through this function and is automaticaly escaped, + * blocking invalid nested overlap. + * @param string $text + * @return string + */ protected function hashClean($text) { - # - # Called whenever a tag must be hashed when a function inserts a "clean" tag - # in $text, it passes through this function and is automaticaly escaped, - # blocking invalid nested overlap. - # return $this->hashPart($text, 'C'); } - + /** + * Turn Markdown link shortcuts into XHTML tags. + * @param string $text + * @return string + */ protected function doAnchors($text) { - # - # Turn Markdown link shortcuts into XHTML tags. - # - if ($this->in_anchor) return $text; + if ($this->in_anchor) { + return $text; + } $this->in_anchor = true; - - # - # First, handle reference-style links: [link text] [id] - # + + // First, handle reference-style links: [link text] [id] $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ - ('.$this->nested_brackets_re.') # link text = $2 + (' . $this->nested_brackets_re . ') # link text = $2 \] [ ]? # one optional space @@ -729,20 +840,18 @@ class MarkdownExtra extends \Michelf\Markdown { }xs', array($this, '_doAnchors_reference_callback'), $text); - # - # Next, inline-style links: [link text](url "optional title") - # + // Next, inline-style links: [link text](url "optional title") $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ - ('.$this->nested_brackets_re.') # link text = $2 + (' . $this->nested_brackets_re . ') # link text = $2 \] \( # literal paren [ \n]* (?: <(.+?)> # href = $3 | - ('.$this->nested_url_parenthesis_re.') # href = $4 + (' . $this->nested_url_parenthesis_re . ') # href = $4 ) [ \n]* ( # $5 @@ -752,16 +861,14 @@ class MarkdownExtra extends \Michelf\Markdown { [ \n]* # ignore any spaces/tabs between closing quote and ) )? # title is optional \) - (?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes + (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes ) }xs', array($this, '_doAnchors_inline_callback'), $text); - # - # Last, handle reference-style shortcuts: [link text] - # These must come last in case you've also got [link text][1] - # or [link text](/foo) - # + // Last, handle reference-style shortcuts: [link text] + // These must come last in case you've also got [link text][1] + // or [link text](/foo) $text = preg_replace_callback('{ ( # wrap whole match in $1 \[ @@ -774,24 +881,30 @@ class MarkdownExtra extends \Michelf\Markdown { $this->in_anchor = false; return $text; } + + /** + * Callback for reference anchors + * @param array $matches + * @return string + */ protected function _doAnchors_reference_callback($matches) { $whole_match = $matches[1]; $link_text = $matches[2]; $link_id =& $matches[3]; if ($link_id == "") { - # for shortcut links like [this][] or [this]. + // for shortcut links like [this][] or [this]. $link_id = $link_text; } - - # lower-case and turn embedded newlines into spaces + + // lower-case and turn embedded newlines into spaces $link_id = strtolower($link_id); $link_id = preg_replace('{[ ]?\n}', ' ', $link_id); if (isset($this->urls[$link_id])) { $url = $this->urls[$link_id]; $url = $this->encodeURLAttribute($url); - + $result = "titles[$link_id] ) ) { $title = $this->titles[$link_id]; @@ -800,7 +913,7 @@ class MarkdownExtra extends \Michelf\Markdown { } if (isset($this->ref_attr[$link_id])) $result .= $this->ref_attr[$link_id]; - + $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text"; $result = $this->hashPart($result); @@ -810,17 +923,22 @@ class MarkdownExtra extends \Michelf\Markdown { } return $result; } + + /** + * Callback for inline anchors + * @param array $matches + * @return string + */ protected function _doAnchors_inline_callback($matches) { - $whole_match = $matches[1]; $link_text = $this->runSpanGamut($matches[2]); - $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $url = $matches[3] === '' ? $matches[4] : $matches[3]; $title =& $matches[7]; $attr = $this->doExtraAttributes("a", $dummy =& $matches[8]); // if the URL was of the form it got caught by the HTML // tag parser and hashed. Need to reverse the process before using the URL. $unhashed = $this->unhash($url); - if ($unhashed != $url) + if ($unhashed !== $url) $url = preg_replace('/^<(.*)>$/', '\1', $unhashed); $url = $this->encodeURLAttribute($url); @@ -831,25 +949,24 @@ class MarkdownExtra extends \Michelf\Markdown { $result .= " title=\"$title\""; } $result .= $attr; - + $link_text = $this->runSpanGamut($link_text); $result .= ">$link_text"; return $this->hashPart($result); } - + /** + * Turn Markdown image shortcuts into tags. + * @param string $text + * @return string + */ protected function doImages($text) { - # - # Turn Markdown image shortcuts into tags. - # - # - # First, handle reference-style labeled images: ![alt text][id] - # + // First, handle reference-style labeled images: ![alt text][id] $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ - ('.$this->nested_brackets_re.') # alt text = $2 + (' . $this->nested_brackets_re . ') # alt text = $2 \] [ ]? # one optional space @@ -860,17 +977,15 @@ class MarkdownExtra extends \Michelf\Markdown { \] ) - }xs', + }xs', array($this, '_doImages_reference_callback'), $text); - # - # Next, handle inline images: ![alt text](url "optional title") - # Don't forget: encode * and _ - # + // Next, handle inline images: ![alt text](url "optional title") + // Don't forget: encode * and _ $text = preg_replace_callback('{ ( # wrap whole match in $1 !\[ - ('.$this->nested_brackets_re.') # alt text = $2 + (' . $this->nested_brackets_re . ') # alt text = $2 \] \s? # One optional whitespace character \( # literal paren @@ -878,7 +993,7 @@ class MarkdownExtra extends \Michelf\Markdown { (?: <(\S*)> # src url = $3 | - ('.$this->nested_url_parenthesis_re.') # src url = $4 + (' . $this->nested_url_parenthesis_re . ') # src url = $4 ) [ \n]* ( # $5 @@ -888,20 +1003,26 @@ class MarkdownExtra extends \Michelf\Markdown { [ \n]* )? # title is optional \) - (?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes + (?:[ ]? ' . $this->id_class_attr_catch_re . ' )? # $8 = id/class attributes ) }xs', array($this, '_doImages_inline_callback'), $text); return $text; } + + /** + * Callback for referenced images + * @param array $matches + * @return string + */ protected function _doImages_reference_callback($matches) { $whole_match = $matches[1]; $alt_text = $matches[2]; $link_id = strtolower($matches[3]); - if ($link_id == "") { - $link_id = strtolower($alt_text); # for shortcut links like ![this][]. + if ($link_id === "") { + $link_id = strtolower($alt_text); // for shortcut links like ![this][]. } $alt_text = $this->encodeAttribute($alt_text); @@ -913,22 +1034,28 @@ class MarkdownExtra extends \Michelf\Markdown { $title = $this->encodeAttribute($title); $result .= " title=\"$title\""; } - if (isset($this->ref_attr[$link_id])) + if (isset($this->ref_attr[$link_id])) { $result .= $this->ref_attr[$link_id]; + } $result .= $this->empty_element_suffix; $result = $this->hashPart($result); } else { - # If there's no such link ID, leave intact: + // If there's no such link ID, leave intact: $result = $whole_match; } return $result; } + + /** + * Callback for inline images + * @param array $matches + * @return string + */ protected function _doImages_inline_callback($matches) { - $whole_match = $matches[1]; $alt_text = $matches[2]; - $url = $matches[3] == '' ? $matches[4] : $matches[3]; + $url = $matches[3] === '' ? $matches[4] : $matches[3]; $title =& $matches[7]; $attr = $this->doExtraAttributes("img", $dummy =& $matches[8]); @@ -937,7 +1064,7 @@ class MarkdownExtra extends \Michelf\Markdown { $result = "\"$alt_text\"";encodeAttribute($title); - $result .= " title=\"$title\""; # $title already quoted + $result .= " title=\"$title\""; // $title already quoted } $result .= $attr; $result .= $this->empty_element_suffix; @@ -945,40 +1072,41 @@ class MarkdownExtra extends \Michelf\Markdown { return $this->hashPart($result); } - + /** + * Process markdown headers. Redefined to add ID and class attribute support. + * @param string $text + * @return string + */ protected function doHeaders($text) { - # - # Redefined to add id and class attribute support. - # - # Setext-style headers: - # Header 1 {#header1} - # ======== - # - # Header 2 {#header2 .class1 .class2} - # -------- - # + // Setext-style headers: + // Header 1 {#header1} + // ======== + // + // Header 2 {#header2 .class1 .class2} + // -------- + // $text = preg_replace_callback( '{ (^.+?) # $1: Header text - (?:[ ]+ '.$this->id_class_attr_catch_re.' )? # $3 = id/class attributes + (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer }mx', array($this, '_doHeaders_callback_setext'), $text); - # atx-style headers: - # # Header 1 {#header1} - # ## Header 2 {#header2} - # ## Header 2 with closing hashes ## {#header3.class1.class2} - # ... - # ###### Header 6 {.class2} - # + // atx-style headers: + // # Header 1 {#header1} + // ## Header 2 {#header2} + // ## Header 2 with closing hashes ## {#header3.class1.class2} + // ... + // ###### Header 6 {.class2} + // $text = preg_replace_callback('{ ^(\#{1,6}) # $1 = string of #\'s - [ ]* + [ ]'.($this->hashtag_protection ? '+' : '*').' (.+?) # $2 = Header text [ ]* \#* # optional closing #\'s (not counted) - (?:[ ]+ '.$this->id_class_attr_catch_re.' )? # $3 = id/class attributes + (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )? # $3 = id/class attributes [ ]* \n+ }xm', @@ -986,51 +1114,63 @@ class MarkdownExtra extends \Michelf\Markdown { return $text; } + + /** + * Callback for setext headers + * @param array $matches + * @return string + */ protected function _doHeaders_callback_setext($matches) { - if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) + if ($matches[3] === '-' && preg_match('{^- }', $matches[1])) { return $matches[0]; + } - $level = $matches[3]{0} == '=' ? 1 : 2; + $level = $matches[3][0] === '=' ? 1 : 2; $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[1]) : null; $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[2], $defaultId); - $block = "".$this->runSpanGamut($matches[1]).""; + $block = "" . $this->runSpanGamut($matches[1]) . ""; return "\n" . $this->hashBlock($block) . "\n\n"; } + + /** + * Callback for atx headers + * @param array $matches + * @return string + */ protected function _doHeaders_callback_atx($matches) { $level = strlen($matches[1]); $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[2]) : null; $attr = $this->doExtraAttributes("h$level", $dummy =& $matches[3], $defaultId); - $block = "".$this->runSpanGamut($matches[2]).""; + $block = "" . $this->runSpanGamut($matches[2]) . ""; return "\n" . $this->hashBlock($block) . "\n\n"; } - + /** + * Form HTML tables. + * @param string $text + * @return string + */ protected function doTables($text) { - # - # Form HTML tables. - # $less_than_tab = $this->tab_width - 1; - # - # Find tables with leading pipe. - # - # | Header 1 | Header 2 - # | -------- | -------- - # | Cell 1 | Cell 2 - # | Cell 3 | Cell 4 - # + // Find tables with leading pipe. + // + // | Header 1 | Header 2 + // | -------- | -------- + // | Cell 1 | Cell 2 + // | Cell 3 | Cell 4 $text = preg_replace_callback(' { ^ # Start of a line - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. [|] # Optional leading pipe (present) (.+) \n # $1: Header row (at least one pipe) - - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline - + ( # $3: Cells (?> [ ]* # Allowed whitespace. @@ -1040,24 +1180,22 @@ class MarkdownExtra extends \Michelf\Markdown { (?=\n|\Z) # Stop at final double newline. }xm', array($this, '_doTable_leadingPipe_callback'), $text); - - # - # Find tables without leading pipe. - # - # Header 1 | Header 2 - # -------- | -------- - # Cell 1 | Cell 2 - # Cell 3 | Cell 4 - # + + // Find tables without leading pipe. + // + // Header 1 | Header 2 + // -------- | -------- + // Cell 1 | Cell 2 + // Cell 3 | Cell 4 $text = preg_replace_callback(' { ^ # Start of a line - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. (\S.*[|].*) \n # $1: Header row (at least one pipe) - - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + + [ ]{0,' . $less_than_tab . '} # Allowed whitespace. ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline - + ( # $3: Cells (?> .* [|] .* \n # Row content @@ -1069,35 +1207,52 @@ class MarkdownExtra extends \Michelf\Markdown { return $text; } + + /** + * Callback for removing the leading pipe for each row + * @param array $matches + * @return string + */ protected function _doTable_leadingPipe_callback($matches) { $head = $matches[1]; $underline = $matches[2]; $content = $matches[3]; - - # Remove leading pipe for each row. + $content = preg_replace('/^ *[|]/m', '', $content); - + return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); } - protected function _doTable_makeAlignAttr($alignname) - { - if (empty($this->table_align_class_tmpl)) + + /** + * Make the align attribute in a table + * @param string $alignname + * @return string + */ + protected function _doTable_makeAlignAttr($alignname) { + if (empty($this->table_align_class_tmpl)) { return " align=\"$alignname\""; + } $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl); return " class=\"$classname\""; } + + /** + * Calback for processing tables + * @param array $matches + * @return string + */ protected function _doTable_callback($matches) { $head = $matches[1]; $underline = $matches[2]; $content = $matches[3]; - # Remove any tailing pipes for each line. + // Remove any tailing pipes for each line. $head = preg_replace('/[|] *$/m', '', $head); $underline = preg_replace('/[|] *$/m', '', $underline); $content = preg_replace('/[|] *$/m', '', $content); - - # Reading alignement from header underline. + + // Reading alignement from header underline. $separators = preg_split('/ *[|] */', $underline); foreach ($separators as $n => $s) { if (preg_match('/^ *-+: *$/', $s)) @@ -1109,62 +1264,65 @@ class MarkdownExtra extends \Michelf\Markdown { else $attr[$n] = ''; } - - # Parsing span elements, including code spans, character escapes, - # and inline HTML tags, so that pipes inside those gets ignored. + + // Parsing span elements, including code spans, character escapes, + // and inline HTML tags, so that pipes inside those gets ignored. $head = $this->parseSpan($head); $headers = preg_split('/ *[|] */', $head); $col_count = count($headers); $attr = array_pad($attr, $col_count, ''); - - # Write column headers. + + // Write column headers. $text = "\n"; $text .= "\n"; $text .= "\n"; - foreach ($headers as $n => $header) - $text .= " ".$this->runSpanGamut(trim($header))."\n"; + foreach ($headers as $n => $header) { + $text .= " " . $this->runSpanGamut(trim($header)) . "\n"; + } $text .= "\n"; $text .= "\n"; - - # Split content by row. + + // Split content by row. $rows = explode("\n", trim($content, "\n")); - + $text .= "\n"; foreach ($rows as $row) { - # Parsing span elements, including code spans, character escapes, - # and inline HTML tags, so that pipes inside those gets ignored. + // Parsing span elements, including code spans, character escapes, + // and inline HTML tags, so that pipes inside those gets ignored. $row = $this->parseSpan($row); - - # Split row by cell. + + // Split row by cell. $row_cells = preg_split('/ *[|] */', $row, $col_count); $row_cells = array_pad($row_cells, $col_count, ''); - + $text .= "\n"; - foreach ($row_cells as $n => $cell) - $text .= " ".$this->runSpanGamut(trim($cell))."\n"; + foreach ($row_cells as $n => $cell) { + $text .= " " . $this->runSpanGamut(trim($cell)) . "\n"; + } $text .= "\n"; } $text .= "\n"; $text .= "
    "; - + return $this->hashBlock($text) . "\n"; } - + /** + * Form HTML definition lists. + * @param string $text + * @return string + */ protected function doDefLists($text) { - # - # Form HTML definition lists. - # $less_than_tab = $this->tab_width - 1; - # Re-usable pattern to match any entire dl list: + // Re-usable pattern to match any entire dl list: $whole_list_re = '(?> ( # $1 = whole list ( # $2 - [ ]{0,'.$less_than_tab.'} + [ ]{0,' . $less_than_tab . '} ((?>.*\S.*\n)+) # $3 = defined term \n? - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition ) (?s:.+?) ( # $4 @@ -1173,13 +1331,13 @@ class MarkdownExtra extends \Michelf\Markdown { \n{2,} (?=\S) (?! # Negative lookahead for another term - [ ]{0,'.$less_than_tab.'} + [ ]{0,' . $less_than_tab . '} (?: \S.*\n )+? # defined term \n? - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition ) (?! # Negative lookahead for another definition - [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition + [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition ) ) ) @@ -1187,67 +1345,81 @@ class MarkdownExtra extends \Michelf\Markdown { $text = preg_replace_callback('{ (?>\A\n?|(?<=\n\n)) - '.$whole_list_re.' + ' . $whole_list_re . ' }mx', array($this, '_doDefLists_callback'), $text); return $text; } + + /** + * Callback for processing definition lists + * @param array $matches + * @return string + */ protected function _doDefLists_callback($matches) { - # Re-usable patterns to match list item bullets and number markers: + // Re-usable patterns to match list item bullets and number markers: $list = $matches[1]; - - # Turn double returns into triple returns, so that we can make a - # paragraph for the last item in a list, if necessary: + + // Turn double returns into triple returns, so that we can make a + // paragraph for the last item in a list, if necessary: $result = trim($this->processDefListItems($list)); $result = "
    \n" . $result . "\n
    "; return $this->hashBlock($result) . "\n\n"; } - + /** + * Process the contents of a single definition list, splitting it + * into individual term and definition list items. + * @param string $list_str + * @return string + */ protected function processDefListItems($list_str) { - # - # Process the contents of a single definition list, splitting it - # into individual term and definition list items. - # + $less_than_tab = $this->tab_width - 1; - - # trim trailing blank lines: + + // Trim trailing blank lines: $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str); - # Process definition terms. + // Process definition terms. $list_str = preg_replace_callback('{ - (?>\A\n?|\n\n+) # leading line - ( # definition terms = $1 - [ ]{0,'.$less_than_tab.'} # leading whitespace - (?!\:[ ]|[ ]) # negative lookahead for a definition - # mark (colon) or more whitespace. - (?> \S.* \n)+? # actual term (not whitespace). - ) - (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed - # with a definition mark. + (?>\A\n?|\n\n+) # leading line + ( # definition terms = $1 + [ ]{0,' . $less_than_tab . '} # leading whitespace + (?!\:[ ]|[ ]) # negative lookahead for a definition + # mark (colon) or more whitespace. + (?> \S.* \n)+? # actual term (not whitespace). + ) + (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed + # with a definition mark. }xm', array($this, '_processDefListItems_callback_dt'), $list_str); - # Process actual definitions. + // Process actual definitions. $list_str = preg_replace_callback('{ - \n(\n+)? # leading line = $1 - ( # marker space = $2 - [ ]{0,'.$less_than_tab.'} # whitespace before colon - \:[ ]+ # definition mark (colon) + \n(\n+)? # leading line = $1 + ( # marker space = $2 + [ ]{0,' . $less_than_tab . '} # whitespace before colon + \:[ ]+ # definition mark (colon) ) - ((?s:.+?)) # definition text = $3 - (?= \n+ # stop at next definition mark, - (?: # next term or end of text - [ ]{0,'.$less_than_tab.'} \:[ ] | + ((?s:.+?)) # definition text = $3 + (?= \n+ # stop at next definition mark, + (?: # next term or end of text + [ ]{0,' . $less_than_tab . '} \:[ ] |
    | \z - ) - ) + ) + ) }xm', array($this, '_processDefListItems_callback_dd'), $list_str); return $list_str; } + + /** + * Callback for
    elements in definition lists + * @param array $matches + * @return string + */ protected function _processDefListItems_callback_dt($matches) { $terms = explode("\n", trim($matches[1])); $text = ''; @@ -1257,13 +1429,19 @@ class MarkdownExtra extends \Michelf\Markdown { } return $text . "\n"; } + + /** + * Callback for
    elements in definition lists + * @param array $matches + * @return string + */ protected function _processDefListItems_callback_dd($matches) { $leading_line = $matches[1]; $marker_space = $matches[2]; $def = $matches[3]; if ($leading_line || preg_match('/\n{2,}/', $def)) { - # Replace marker with the appropriate whitespace indentation + // Replace marker with the appropriate whitespace indentation $def = str_repeat(' ', strlen($marker_space)) . $def; $def = $this->runBlockGamut($this->outdent($def . "\n\n")); $def = "\n". $def ."\n"; @@ -1276,17 +1454,18 @@ class MarkdownExtra extends \Michelf\Markdown { return "\n
    " . $def . "
    \n"; } - + /** + * Adding the fenced code block syntax to regular Markdown: + * + * ~~~ + * Code block + * ~~~ + * + * @param string $text + * @return string + */ protected function doFencedCodeBlocks($text) { - # - # Adding the fenced code block syntax to regular Markdown: - # - # ~~~ - # Code block - # ~~~ - # - $less_than_tab = $this->tab_width; - + $text = preg_replace_callback('{ (?:\n|\A) # 1: Opening marker @@ -1299,10 +1478,10 @@ class MarkdownExtra extends \Michelf\Markdown { )? [ ]* (?: - '.$this->id_class_attr_catch_re.' # 3: Extra attributes + ' . $this->id_class_attr_catch_re . ' # 3: Extra attributes )? [ ]* \n # Whitespace and newline following marker. - + # 4: Content ( (?> @@ -1310,7 +1489,7 @@ class MarkdownExtra extends \Michelf\Markdown { .*\n+ )+ ) - + # Closing marker. \1 [ ]* (?= \n ) }xm', @@ -1318,6 +1497,12 @@ class MarkdownExtra extends \Michelf\Markdown { return $text; } + + /** + * Callback to process fenced code blocks + * @param array $matches + * @return string + */ protected function _doFencedCodeBlocks_callback($matches) { $classname =& $matches[2]; $attrs =& $matches[3]; @@ -1333,204 +1518,256 @@ class MarkdownExtra extends \Michelf\Markdown { array($this, '_doFencedCodeBlocks_newlines'), $codeblock); $classes = array(); - if ($classname != "") { - if ($classname{0} == '.') + if ($classname !== "") { + if ($classname[0] === '.') { $classname = substr($classname, 1); - $classes[] = $this->code_class_prefix.$classname; + } + $classes[] = $this->code_class_prefix . $classname; } $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes); $pre_attr_str = $this->code_attr_on_pre ? $attr_str : ''; $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str; $codeblock = "$codeblock
    "; - + return "\n\n".$this->hashBlock($codeblock)."\n\n"; } + + /** + * Replace new lines in fenced code blocks + * @param array $matches + * @return string + */ protected function _doFencedCodeBlocks_newlines($matches) { - return str_repeat("empty_element_suffix", + return str_repeat("empty_element_suffix", strlen($matches[0])); } - - # - # Redefining emphasis markers so that emphasis by underscore does not - # work in the middle of a word. - # + /** + * Redefining emphasis markers so that emphasis by underscore does not + * work in the middle of a word. + * @var array + */ protected $em_relist = array( '' => '(?:(? '(? '(? '(?:(? '(? '(? '(?:(? '(? '(? tags - # - # Strip leading and trailing lines: + ); + + /** + * Parse text into paragraphs + * @param string $text String to process in paragraphs + * @param boolean $wrap_in_p Whether paragraphs should be wrapped in

    tags + * @return string HTML output + */ + protected function formParagraphs($text, $wrap_in_p = true) { + // Strip leading and trailing lines: $text = preg_replace('/\A\n+|\n+\z/', '', $text); - + $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY); - # - # Wrap

    tags and unhashify HTML blocks - # + // Wrap

    tags and unhashify HTML blocks foreach ($grafs as $key => $value) { $value = trim($this->runSpanGamut($value)); - - # Check if this should be enclosed in a paragraph. - # Clean tag hashes & block tag hashes are left alone. - $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); - + + // Check if this should be enclosed in a paragraph. + // Clean tag hashes & block tag hashes are left alone. + $is_p = $wrap_in_p && !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value); + if ($is_p) { $value = "

    $value

    "; } $grafs[$key] = $value; } - - # Join grafs in one text, then unhash HTML tags. + + // Join grafs in one text, then unhash HTML tags. $text = implode("\n\n", $grafs); - - # Finish by removing any tag hashes still present in $text. + + // Finish by removing any tag hashes still present in $text. $text = $this->unhash($text); - + return $text; } - - - ### Footnotes - + + + /** + * Footnotes - Strips link definitions from text, stores the URLs and + * titles in hash references. + * @param string $text + * @return string + */ protected function stripFootnotes($text) { - # - # Strips link definitions from text, stores the URLs and titles in - # hash references. - # $less_than_tab = $this->tab_width - 1; - # Link defs are in the form: [^id]: url "optional title" + // Link defs are in the form: [^id]: url "optional title" $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1 + ^[ ]{0,' . $less_than_tab . '}\[\^(.+?)\][ ]?: # note_id = $1 [ ]* \n? # maybe *one* newline ( # text = $2 (no blank lines allowed) - (?: + (?: .+ # actual text | - \n # newlines but + \n # newlines but (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker. - (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed + (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed # by non-indented content )* - ) + ) }xm', array($this, '_stripFootnotes_callback'), $text); return $text; } + + /** + * Callback for stripping footnotes + * @param array $matches + * @return string + */ protected function _stripFootnotes_callback($matches) { $note_id = $this->fn_id_prefix . $matches[1]; $this->footnotes[$note_id] = $this->outdent($matches[2]); - return ''; # String that will replace the block + return ''; // String that will replace the block } - + /** + * Replace footnote references in $text [^id] with a special text-token + * which will be replaced by the actual footnote marker in appendFootnotes. + * @param string $text + * @return string + */ protected function doFootnotes($text) { - # - # Replace footnote references in $text [^id] with a special text-token - # which will be replaced by the actual footnote marker in appendFootnotes. - # if (!$this->in_anchor) { $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text); } return $text; } - + /** + * Append footnote list to text + * @param string $text + * @return string + */ protected function appendFootnotes($text) { - # - # Append footnote list to text. - # - $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', array($this, '_appendFootnotes_callback'), $text); - - if (!empty($this->footnotes_ordered)) { - $text .= "\n\n"; - $text .= "
    \n"; - $text .= "empty_element_suffix ."\n"; - $text .= "
      \n\n"; - $attr = ""; - if ($this->fn_backlink_class != "") { - $class = $this->fn_backlink_class; - $class = $this->encodeAttribute($class); - $attr .= " class=\"$class\""; - } - if ($this->fn_backlink_title != "") { - $title = $this->fn_backlink_title; - $title = $this->encodeAttribute($title); - $attr .= " title=\"$title\""; + if ( ! empty( $this->footnotes_ordered ) ) { + $this->_doFootnotes(); + if ( ! $this->omit_footnotes ) { + $text .= "\n\n"; + $text .= "
      \n"; + $text .= "empty_element_suffix . "\n"; + $text .= $this->footnotes_assembled; + $text .= "
      "; } - $backlink_text = $this->fn_backlink_html; - $num = 0; - - while (!empty($this->footnotes_ordered)) { - $footnote = reset($this->footnotes_ordered); - $note_id = key($this->footnotes_ordered); - unset($this->footnotes_ordered[$note_id]); - $ref_count = $this->footnotes_ref_count[$note_id]; - unset($this->footnotes_ref_count[$note_id]); - unset($this->footnotes[$note_id]); - - $footnote .= "\n"; # Need to append newline before parsing. - $footnote = $this->runBlockGamut("$footnote\n"); - $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array($this, '_appendFootnotes_callback'), $footnote); - - $attr = str_replace("%%", ++$num, $attr); - $note_id = $this->encodeAttribute($note_id); - - # Prepare backlink, multiple backlinks if multiple references - $backlink = "$backlink_text"; - for ($ref_num = 2; $ref_num <= $ref_count; ++$ref_num) { - $backlink .= " $backlink_text"; + } + return $text; + } + + + /** + * Generates the HTML for footnotes. Called by appendFootnotes, even if + * footnotes are not being appended. + * @return void + */ + protected function _doFootnotes() { + $attr = array(); + if ($this->fn_backlink_class !== "") { + $class = $this->fn_backlink_class; + $class = $this->encodeAttribute($class); + $attr['class'] = " class=\"$class\""; + } + $attr['role'] = " role=\"doc-backlink\""; + $num = 0; + + $text = "
        \n\n"; + while (!empty($this->footnotes_ordered)) { + $footnote = reset($this->footnotes_ordered); + $note_id = key($this->footnotes_ordered); + unset($this->footnotes_ordered[$note_id]); + $ref_count = $this->footnotes_ref_count[$note_id]; + unset($this->footnotes_ref_count[$note_id]); + unset($this->footnotes[$note_id]); + + $footnote .= "\n"; // Need to append newline before parsing. + $footnote = $this->runBlockGamut("$footnote\n"); + $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', + array($this, '_appendFootnotes_callback'), $footnote); + + $num++; + $note_id = $this->encodeAttribute($note_id); + + // Prepare backlink, multiple backlinks if multiple references + // Do not create empty backlinks if the html is blank + $backlink = ""; + if (!empty($this->fn_backlink_html)) { + for ($ref_num = 1; $ref_num <= $ref_count; ++$ref_num) { + if (!empty($this->fn_backlink_title)) { + $attr['title'] = ' title="' . $this->encodeAttribute($this->fn_backlink_title) . '"'; + } + if (!empty($this->fn_backlink_label)) { + $attr['label'] = ' aria-label="' . $this->encodeAttribute($this->fn_backlink_label) . '"'; + } + $parsed_attr = $this->parseFootnotePlaceholders( + implode('', $attr), + $num, + $ref_num + ); + $backlink_text = $this->parseFootnotePlaceholders( + $this->fn_backlink_html, + $num, + $ref_num + ); + $ref_count_mark = $ref_num > 1 ? $ref_num : ''; + $backlink .= " $backlink_text"; } - # Add backlink to last paragraph; create new paragraph if needed. + $backlink = trim($backlink); + } + + // Add backlink to last paragraph; create new paragraph if needed. + if (!empty($backlink)) { if (preg_match('{

        $}', $footnote)) { $footnote = substr($footnote, 0, -4) . " $backlink

        "; } else { $footnote .= "\n\n

        $backlink

        "; } - - $text .= "
      1. \n"; - $text .= $footnote . "\n"; - $text .= "
      2. \n\n"; } - - $text .= "
      \n"; - $text .= "
    "; + + $text .= "
  • \n"; + $text .= $footnote . "\n"; + $text .= "
  • \n\n"; } - return $text; + $text .= "\n"; + + $this->footnotes_assembled = $text; } + + /** + * Callback for appending footnotes + * @param array $matches + * @return string + */ protected function _appendFootnotes_callback($matches) { $node_id = $this->fn_id_prefix . $matches[1]; - - # Create footnote marker only if it has a corresponding footnote *and* - # the footnote hasn't been used by another marker. + + // Create footnote marker only if it has a corresponding footnote *and* + // the footnote hasn't been used by another marker. if (isset($this->footnotes[$node_id])) { $num =& $this->footnotes_numbers[$node_id]; if (!isset($num)) { - # Transfer footnote content to the ordered list and give it its - # number + // Transfer footnote content to the ordered list and give it its + // number $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id]; $this->footnotes_ref_count[$node_id] = 1; $num = $this->footnote_counter++; @@ -1540,86 +1777,117 @@ class MarkdownExtra extends \Michelf\Markdown { } $attr = ""; - if ($this->fn_link_class != "") { + if ($this->fn_link_class !== "") { $class = $this->fn_link_class; $class = $this->encodeAttribute($class); $attr .= " class=\"$class\""; } - if ($this->fn_link_title != "") { + if ($this->fn_link_title !== "") { $title = $this->fn_link_title; $title = $this->encodeAttribute($title); $attr .= " title=\"$title\""; } - + $attr .= " role=\"doc-noteref\""; + $attr = str_replace("%%", $num, $attr); $node_id = $this->encodeAttribute($node_id); - + return "". "$num". ""; } - - return "[^".$matches[1]."]"; + + return "[^" . $matches[1] . "]"; + } + + /** + * Build footnote label by evaluating any placeholders. + * - ^^ footnote number + * - %% footnote reference number (Nth reference to footnote number) + * @param string $label + * @param int $footnote_number + * @param int $reference_number + * @return string + */ + protected function parseFootnotePlaceholders($label, $footnote_number, $reference_number) { + return str_replace( + array('^^', '%%'), + array($footnote_number, $reference_number), + $label + ); } - - - ### Abbreviations ### - + + + /** + * Abbreviations - strips abbreviations from text, stores titles in hash + * references. + * @param string $text + * @return string + */ protected function stripAbbreviations($text) { - # - # Strips abbreviations from text, stores titles in hash references. - # $less_than_tab = $this->tab_width - 1; - # Link defs are in the form: [id]*: url "optional title" + // Link defs are in the form: [id]*: url "optional title" $text = preg_replace_callback('{ - ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1 - (.*) # text = $2 (no blank lines allowed) + ^[ ]{0,' . $less_than_tab . '}\*\[(.+?)\][ ]?: # abbr_id = $1 + (.*) # text = $2 (no blank lines allowed) }xm', array($this, '_stripAbbreviations_callback'), $text); return $text; } + + /** + * Callback for stripping abbreviations + * @param array $matches + * @return string + */ protected function _stripAbbreviations_callback($matches) { $abbr_word = $matches[1]; $abbr_desc = $matches[2]; - if ($this->abbr_word_re) + if ($this->abbr_word_re) { $this->abbr_word_re .= '|'; + } $this->abbr_word_re .= preg_quote($abbr_word); $this->abbr_desciptions[$abbr_word] = trim($abbr_desc); - return ''; # String that will replace the block + return ''; // String that will replace the block } - - + + /** + * Find defined abbreviations in text and wrap them in elements. + * @param string $text + * @return string + */ protected function doAbbreviations($text) { - # - # Find defined abbreviations in text and wrap them in elements. - # if ($this->abbr_word_re) { - // cannot use the /x modifier because abbr_word_re may + // cannot use the /x modifier because abbr_word_re may // contain significant spaces: - $text = preg_replace_callback('{'. - '(?abbr_word_re.')'. - '(?![\w\x1A])'. - '}', + $text = preg_replace_callback('{' . + '(?abbr_word_re . ')' . + '(?![\w\x1A])' . + '}', array($this, '_doAbbreviations_callback'), $text); } return $text; } + + /** + * Callback for processing abbreviations + * @param array $matches + * @return string + */ protected function _doAbbreviations_callback($matches) { $abbr = $matches[0]; if (isset($this->abbr_desciptions[$abbr])) { $desc = $this->abbr_desciptions[$abbr]; if (empty($desc)) { return $this->hashPart("$abbr"); - } else { - $desc = $this->encodeAttribute($desc); - return $this->hashPart("$abbr"); } - } else { - return $matches[0]; + $desc = $this->encodeAttribute($desc); + return $this->hashPart("$abbr"); } + return $matches[0]; } } diff --git a/system/vendor/michelf/php-markdown/Michelf/MarkdownInterface.inc.php b/system/vendor/michelf/php-markdown/Michelf/MarkdownInterface.inc.php index a023ed4..c4e9ac7 100644 --- a/system/vendor/michelf/php-markdown/Michelf/MarkdownInterface.inc.php +++ b/system/vendor/michelf/php-markdown/Michelf/MarkdownInterface.inc.php @@ -1,9 +1,9 @@ -# -# Original Markdown -# Copyright (c) 2004-2006 John Gruber -# -# -namespace Michelf; - +/** + * Markdown - A text-to-HTML conversion tool for web writers + * + * @package php-markdown + * @author Michel Fortin + * @copyright 2004-2019 Michel Fortin + * @copyright (Original Markdown) 2004-2006 John Gruber + */ -# -# Markdown Parser Interface -# +namespace Michelf; +/** + * Markdown Parser Interface + */ interface MarkdownInterface { + /** + * Initialize the parser and return the result of its transform method. + * This will work fine for derived classes too. + * + * @api + * + * @param string $text + * @return string + */ + public static function defaultTransform($text); - # - # Initialize the parser and return the result of its transform method. - # This will work fine for derived classes too. - # - public static function defaultTransform($text); - - # - # Main function. Performs some preprocessing on the input text - # and pass it through the document gamut. - # - public function transform($text); - + /** + * Main function. Performs some preprocessing on the input text + * and pass it through the document gamut. + * + * @api + * + * @param string $text + * @return string + */ + public function transform($text); } diff --git a/system/vendor/michelf/php-markdown/Readme.md b/system/vendor/michelf/php-markdown/Readme.md index ec931bc..e1eb306 100644 --- a/system/vendor/michelf/php-markdown/Readme.md +++ b/system/vendor/michelf/php-markdown/Readme.md @@ -1,7 +1,7 @@ PHP Markdown ============ -PHP Markdown Lib 1.6.0 - 23 Dec 2015 +PHP Markdown Lib 1.9.0 - 1 Dec 2019 by Michel Fortin @@ -13,16 +13,16 @@ based on Markdown by John Gruber Introduction ------------ -This is a library package that includes the PHP Markdown parser and its +This is a library package that includes the PHP Markdown parser and its sibling PHP Markdown Extra with additional features. Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML). -"Markdown" is actually two things: a plain text markup syntax, and a -software tool, originally written in Perl, that converts the plain text -markup to HTML. PHP Markdown is a port to PHP of the original Markdown +"Markdown" is actually two things: a plain text markup syntax, and a +software tool, originally written in Perl, that converts the plain text +markup to HTML. PHP Markdown is a port to PHP of the original Markdown program by John Gruber. * [Full documentation of the Markdown syntax]() @@ -37,68 +37,77 @@ Requirement This library package requires PHP 5.3 or later. Note: The older plugin/library hybrid package for PHP Markdown and -PHP Markdown Extra is still maintained and will work with PHP 4.0.5 and later. +PHP Markdown Extra is no longer maintained but will work with PHP 4.0.5 and +later. Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small -in many situations. You might need to set it to higher values. Later PHP +in many situations. You might need to set it to higher values. Later PHP releases defaults to 1 000 000, which is usually fine. Usage ----- -This library package is meant to be used with class autoloading. For autoloading -to work, your project needs have setup a PSR-0-compatible autoloader. See the -included Readme.php file for a minimal autoloader setup. (If you cannot use -autoloading, see below.) +To use this library with Composer, first install it with: -With class autoloading in place, putting the 'Michelf' folder in your -include path should be enough for this to work: + $ composer require michelf/php-markdown - use \Michelf\Markdown; +Then include Composer's generated vendor/autoload.php to [enable autoloading]: + + require 'vendor/autoload.php'; + +Without Composer, for autoloading to work, your project needs an autoloader +compatible with PSR-4 or PSR-0. See the included Readme.php file for a minimal +autoloader setup. (If you cannot use autoloading, see below.) + +With class autoloading in place: + + use Michelf\Markdown; $my_html = Markdown::defaultTransform($my_text); Markdown Extra syntax is also available the same way: - use \Michelf\MarkdownExtra; + use Michelf\MarkdownExtra; $my_html = MarkdownExtra::defaultTransform($my_text); -If you wish to use PHP Markdown with another text filter function +If you wish to use PHP Markdown with another text filter function built to parse HTML, you should filter the text *after* the `transform` -function call. This is an example with [PHP SmartyPants][psp]: +function call. This is an example with [PHP SmartyPants]: - use \Michelf\Markdown, \Michelf\SmartyPants; + use Michelf\Markdown, Michelf\SmartyPants; $my_html = Markdown::defaultTransform($my_text); $my_html = SmartyPants::defaultTransform($my_html); -All these examples are using the static `defaultTransform` static function -found inside the parser class. If you want to customize the parser -configuration, you can also instantiate it directly and change some +All these examples are using the static `defaultTransform` static function +found inside the parser class. If you want to customize the parser +configuration, you can also instantiate it directly and change some configuration variables: - use \Michelf\MarkdownExtra; + use Michelf\MarkdownExtra; $parser = new MarkdownExtra; $parser->fn_id_prefix = "post22-"; $my_html = $parser->transform($my_text); To learn more, see the full list of [configuration variables]. + [enable autoloading]: https://getcomposer.org/doc/01-basic-usage.md#autoloading + [PHP SmartyPants]: https://michelf.ca/projects/php-smartypants/ [configuration variables]: https://michelf.ca/projects/php-markdown/configuration/ ### Usage without an autoloader -If you cannot use class autoloading, you can still use `include` or `require` -to access the parser. To load the `\Michelf\Markdown` parser, do it this way: +If you cannot use class autoloading, you can still use `include` or `require` +to access the parser. To load the `Michelf\Markdown` parser, do it this way: require_once 'Michelf/Markdown.inc.php'; -Or, if you need the `\Michelf\MarkdownExtra` parser: +Or, if you need the `Michelf\MarkdownExtra` parser: require_once 'Michelf/MarkdownExtra.inc.php'; While the plain `.php` files depend on autoloading to work correctly, using the -`.inc.php` files instead will eagerly load the dependencies that would be +`.inc.php` files instead will eagerly load the dependencies that would be loaded on demand if you were using autoloading. @@ -113,19 +122,19 @@ functions and their configuration variables. The public API is stable for a given major version number. It might get additions when the minor version number increments. -**Protected members are not considered public API.** This is unconventional -and deserves an explanation. Incrementing the major version number every time +**Protected members are not considered public API.** This is unconventional +and deserves an explanation. Incrementing the major version number every time the underlying implementation of something changes is going to give nonessential version numbers for the vast majority of people who just use the parser. Protected members are meant to create parser subclasses that behave in -different ways. Very few people create parser subclasses. I don't want to -discourage it by making everything private, but at the same time I can't +different ways. Very few people create parser subclasses. I don't want to +discourage it by making everything private, but at the same time I can't guarantee any stable hook between versions if you use protected members. -**Syntax changes** will increment the minor number for new features, and the -patch number for small corrections. A *new feature* is something that needs a +**Syntax changes** will increment the minor number for new features, and the +patch number for small corrections. A *new feature* is something that needs a change in the syntax documentation. Note that since PHP Markdown Lib includes -two parsers, a syntax change for either of them will increment the minor +two parsers, a syntax change for either of them will increment the minor number. Also note that there is nothing perfectly backward-compatible with the Markdown syntax: all inputs are always valid, so new features always replace something that was previously legal, although generally nonsensical to do. @@ -140,7 +149,7 @@ To file bug reports please send email to: Please include with your report: (1) the example input; (2) the output you expected; (3) the output PHP Markdown actually produced. -If you have a problem where Markdown gives you an empty result, first check +If you have a problem where Markdown gives you an empty result, first check that the backtrack limit is not too low by running `php --info | grep pcre`. See Installation and Requirement above for details. @@ -149,55 +158,125 @@ Development and Testing ----------------------- Pull requests for fixing bugs are welcome. Proposed new features are -going meticulously reviewed -- taking into account backward compatibility, +going to be meticulously reviewed -- taking into account backward compatibility, potential side effects, and future extensibility -- before deciding on acceptance or rejection. -If you make a pull request that includes changes to the parser please add -tests for what is being changed to [MDTest][] and make a pull request there -too. +If you make a pull request that includes changes to the parser please add +tests for what is being changed to the `test/` directory. This can be as +simple as adding a `.text` (input) file with a corresponding `.xhtml` +(output) file to proper category under `./test/resources/`. - [MDTest]: https://github.com/michelf/mdtest/ +Traditionally tests were in a separate repository, [MDTest](https://github.com/michelf/mdtest) +but they are now located here, alongside the source code. Donations --------- -If you wish to make a donation that will help me devote more time to -PHP Markdown, please visit [michelf.ca/donate] or send Bitcoin to -[1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH]. +If you wish to make a donation that will help me devote more time to +PHP Markdown, please visit [michelf.ca/donate]. [michelf.ca/donate]: https://michelf.ca/donate/#!Thanks%20for%20PHP%20Markdown - [1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH]: bitcoin:1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH Version History --------------- -PHP Markdown Lib 1.6.0 (23 Dec 2015) +PHP Markdown Lib 1.9.0 (1 Dec 2019) + +* Added `fn_backlink_label` configuration variable to put some text in the + `aria-label` attribute. + (Thanks to Sunny Walker for the implementation.) + +* Occurances of "`^^`" in `fn_backlink_html`, `fn_backlink_class`, + `fn_backlink_title`, and `fn_backlink_label` will be replaced by the + corresponding footnote number in the HTML output. Occurances of "`%%`" will be + replaced by a number for the reference (footnotes can have multiple references). + (Thanks to Sunny Walker for the implementation.) + +* Added configuration variable `omit_footnotes`. When `true` footnotes are not + appended at the end of the generated HTML and the `footnotes_assembled` + variable will contain the HTML for the footnote list, allowing footnotes to be + moved somewhere else on the page. + (Thanks to James K. for the implementation.) + + Note: when placing the content of `footnotes_assembled` on the page, consider + adding the attribute `role="doc-endnotes"` to the `
    ` or `
    ` that will + enclose the list of footnotes so they are reachable to accessibility tools the + same way they would be with the default HTML output. + +* Fixed deprecation warnings from PHP about usage of curly braces to access + characters in text strings. + (Thanks to Remi Collet and Frans-Willem Post.) + + +PHP Markdown Lib 1.8.0 (14 Jan 2018) + +* Autoloading with Composer now uses PSR-4. + +* HTML output for Markdown Extra footnotes now include `role` attributes + with values from [WAI-ARIA](https://www.w3.org/TR/dpub-aria/) to + make them more accessible. + (Thanks to Tobias Bengfort) + +* In Markdown Extra, added the `hashtag_protection` configuration variable. + When set to `true` it prevents ATX-style headers with no space after the initial + hash from being interpreted as headers. This way your precious hashtags + are preserved. + (Thanks to Jaussoin Timothée for the implementation.) + + +PHP Markdown Lib 1.7.0 (29 Oct 2016) -Note: this version was incorrectly released as 1.5.1 on Dec 22, a number +* Added a `hard_wrap` configuration variable to make all newline characters + in the text become `
    ` tags in the HTML output. By default, according + to the standard Markdown syntax these newlines are ignored unless they a + preceded by two spaces. Thanks to Jonathan Cohlmeyer for the implementation. + +* Improved the parsing of list items to fix problematic cases that came to + light with the addition of `hard_wrap`. This should have no effect on the + output except span-level list items that ended with two spaces (and thus + ended with a line break). + +* Added a `code_span_content_func` configuration variable which takes a + function that will convert the content of the code span to HTML. This can + be useful to implement syntax highlighting. Although contrary to its + code block equivalent, there is no syntax for specifying a language. + Credits to styxit for the implementation. + +* Fixed a Markdown Extra issue where two-space-at-end-of-line hard breaks + wouldn't work inside of HTML block elements such as `

    ` + where the element expects only span-level content. + +* In the parser code, switched to PHPDoc comment format. Thanks to + Robbie Averill for the help. + + +PHP Markdown Lib 1.6.0 (23 Dec 2015) + +Note: this version was incorrectly released as 1.5.1 on Dec 22, a number that contradicted the versioning policy. -* For fenced code blocks in Markdown Extra, can now set a class name for the - code block's language before the special attribute block. Previously, this +* For fenced code blocks in Markdown Extra, can now set a class name for the + code block's language before the special attribute block. Previously, this class name was only allowed in the absence of the special attribute block. -* Added a `code_block_content_func` configuration variable which takes a - function that will convert the content of the code block to HTML. This is - most useful for syntax highlighting. For fenced code blocks in Markdown - Extra, the function has access to the language class name (the one outside - of the special attribute block). Credits to Mario Konrad for providing the +* Added a `code_block_content_func` configuration variable which takes a + function that will convert the content of the code block to HTML. This is + most useful for syntax highlighting. For fenced code blocks in Markdown + Extra, the function has access to the language class name (the one outside + of the special attribute block). Credits to Mario Konrad for providing the implementation. * The curled arrow character for the backlink in footnotes is now followed by a Unicode variant selector to prevent it from being displayed in emoji form on iOS. - Note that in older browsers the variant selector is often interpreted as a - separate character, making it visible after the arrow. So there is now a - also a `fn_backlink_html` configuration variable that can be used to set - the link text to something else. Credits to Dana for providing the + Note that in older browsers the variant selector is often interpreted as a + separate character, making it visible after the arrow. So there is now a + also a `fn_backlink_html` configuration variable that can be used to set + the link text to something else. Credits to Dana for providing the implementation. * Fixed an issue in MarkdownExtra where long header lines followed by a @@ -209,13 +288,13 @@ PHP Markdown Lib 1.5.0 (1 Mar 2015) * Added the ability start ordered lists with a number different from 1 and and have that reflected in the HTML output. This can be enabled with - the `enhanced_ordered_lists` configuration variable for the Markdown + the `enhanced_ordered_lists` configuration variable for the Markdown parser; it is enabled by default for Markdown Extra. Credits to Matt Gorle for providing the implementation. -* Added the ability to insert custom HTML attributes with simple values +* Added the ability to insert custom HTML attributes with simple values everywhere an extra attribute block is allowed (links, images, headers). - The value must be unquoted, cannot contains spaces and is limited to + The value must be unquoted, cannot contains spaces and is limited to alphanumeric ASCII characters. Credits to Peter Droogmans for providing the implementation. @@ -230,7 +309,7 @@ PHP Markdown Lib 1.5.0 (1 Mar 2015) PHP Markdown Lib 1.4.1 (4 May 2014) * The HTML block parser will now treat `

    ` as a block-level element - (as it should) and no longer wrap it in `

    ` or parse it's content with + (as it should) and no longer wrap it in `

    ` or parse it's content with the as Markdown syntax (although with Extra you can use `markdown="1"` if you wish to use the Markdown syntax inside it). @@ -239,7 +318,7 @@ PHP Markdown Lib 1.4.1 (4 May 2014) * Corrected an bug where some inline links with spaces in them would not work even when surounded with angle brackets: - + [link]() * Fixed an issue where email addresses with quotes in them would not always @@ -255,9 +334,9 @@ PHP Markdown Lib 1.4.0 (29 Nov 2013) * Added support for the `tel:` URL scheme in automatic links. - + It gets converted to this (note the `tel:` prefix becomes invisible): - + +1-111-111-1111 * Added backtick fenced code blocks to MarkdownExtra, originally from @@ -268,16 +347,16 @@ PHP Markdown Lib 1.4.0 (29 Nov 2013) you want to create a mockup parser object for unit testing. * For those of you who cannot use class autoloading, you can now - include `Michelf/Markdown.inc.php` or `Michelf/MarkdownExtra.inc.php` (note + include `Michelf/Markdown.inc.php` or `Michelf/MarkdownExtra.inc.php` (note the `.inc.php` extension) to automatically include other files required by the parser. PHP Markdown Lib 1.3 (11 Apr 2013) -This is the first release of PHP Markdown Lib. This package requires PHP -version 5.3 or later and is designed to work with PSR-0 autoloading and, -optionally with Composer. Here is a list of the changes since +This is the first release of PHP Markdown Lib. This package requires PHP +version 5.3 or later and is designed to work with PSR-0 autoloading and, +optionally with Composer. Here is a list of the changes since PHP Markdown Extra 1.2.6: * Plugin interface for WordPress and other systems is no longer present in @@ -297,22 +376,22 @@ PHP Markdown Extra 1.2.6: * Added optional class and id attributes to images and links using the same syntax as for headers: - [link](url){#id .class} + [link](url){#id .class} ![img](url){#id .class} - + It work too for reference-style links and images. In this case you need to put those attributes at the reference definition: - [link][linkref] or [linkref] + [link][linkref] or [linkref] ![img][linkref] - + [linkref]: url "optional title" {#id .class} -* Fixed a PHP notice message triggered when some table column separator +* Fixed a PHP notice message triggered when some table column separator markers are missing on the separator line below column headers. * Fixed a small mistake that could cause the parser to retain an invalid - state related to parsing links across multiple runs. This was never + state related to parsing links across multiple runs. This was never observed (that I know of), but it's still worth fixing. @@ -320,25 +399,25 @@ Copyright and License --------------------- PHP Markdown Lib -Copyright (c) 2004-2015 Michel Fortin +Copyright (c) 2004-2019 Michel Fortin All rights reserved. Based on Markdown -Copyright (c) 2003-2005 John Gruber - +Copyright (c) 2003-2005 John Gruber + All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the + documentation and/or other materials provided with the distribution. * Neither the name "Markdown" nor the names of its contributors may diff --git a/system/vendor/michelf/php-markdown/Readme.php b/system/vendor/michelf/php-markdown/Readme.php index d007b11..726bbe3 100644 --- a/system/vendor/michelf/php-markdown/Readme.php +++ b/system/vendor/michelf/php-markdown/Readme.php @@ -1,31 +1,33 @@ - - PHP Markdown Lib - Readme - - + + PHP Markdown Lib - Readme + + - + diff --git a/system/vendor/michelf/php-markdown/composer.json b/system/vendor/michelf/php-markdown/composer.json index 36a4f74..0935075 100644 --- a/system/vendor/michelf/php-markdown/composer.json +++ b/system/vendor/michelf/php-markdown/composer.json @@ -21,11 +21,9 @@ "php": ">=5.3.0" }, "autoload": { - "psr-0": { "Michelf": "" } + "psr-4": { "Michelf\\": "Michelf/" } }, - "extra": { - "branch-alias": { - "dev-lib": "1.4.x-dev" - } + "require-dev": { + "phpunit/phpunit": ">=4.3 <5.8" } } diff --git a/system/vendor/michelf/php-markdown/phpunit.xml.dist b/system/vendor/michelf/php-markdown/phpunit.xml.dist new file mode 100644 index 0000000..8f2dab5 --- /dev/null +++ b/system/vendor/michelf/php-markdown/phpunit.xml.dist @@ -0,0 +1,24 @@ + + + + + ./test/unit/ + + + ./test/integration/ + + + + + + Michelf + + + diff --git a/system/vendor/michelf/php-markdown/test/bootstrap.php b/system/vendor/michelf/php-markdown/test/bootstrap.php new file mode 100644 index 0000000..a7b3507 --- /dev/null +++ b/system/vendor/michelf/php-markdown/test/bootstrap.php @@ -0,0 +1,6 @@ +loadXML('' . + "" . + "$t_result"); + + $document2 = new DOMDocument(); + $doc_output = $document2->loadXML('' . + "" . + "$t_output"); + + if ($doc_result) { + static::normalizeElementContent($document->documentElement, false); + $n_result = $document->saveXML(); + } else { + $n_result = '--- Expected Result: XML Parse Error ---'; + } + if ($doc_output) { + static::normalizeElementContent($document2->documentElement, false); + $n_output = $document2->saveXML(); + } else { + $n_output = '--- Output: XML Parse Error ---'; + } + } else { + + // '@' suppressors used because some tests have invalid HTML (multiple elements with the same id attribute) + // Perhaps isolate to a separate test and remove this? + + $document = new DOMDocument(); + $doc_result = @$document->loadHTML($t_result); + + $document2 = new DOMDocument(); + $doc_output = @$document2->loadHTML($t_output); + + if ($doc_result) { + static::normalizeElementContent($document->documentElement, false); + $n_result = $document->saveHTML(); + } else { + $n_result = '--- Expected Result: HTML Parse Error ---'; + } + + if ($doc_output) { + static::normalizeElementContent($document2->documentElement, false); + $n_output = $document2->saveHTML(); + } else { + $n_output = '--- Output: HTML Parse Error ---'; + } + } + + $n_result = preg_replace('{^.*?|.*?$}is', '', $n_result); + $n_output = preg_replace('{^.*?|.*?$}is', '', $n_output); + + $c_result = $n_result; + $c_output = $n_output; + + $c_result = trim($c_result) . "\n"; + $c_output = trim($c_output) . "\n"; + + // This will throw a test exception if the strings don't exactly match + TestCase::assertSame($c_result, $c_output, $message); + } + + /** + * @param DOMElement $element Modifies this element by reference + * @param bool $whitespace_preserve Preserve Whitespace + * @return void + */ + protected static function normalizeElementContent($element, $whitespace_preserve) { + # + # Normalize content of HTML DOM $element. The $whitespace_preserve + # argument indicates that whitespace is significant and shouldn't be + # normalized; it should be used for the content of certain elements like + #

     or