From 66fa101084c621b02cfc9bd313c9021e00819934 Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Mon, 13 Apr 2020 14:45:41 +0100 Subject: [PATCH] Markdown: use libary instead of class in code --- composer.json | 3 +- composer.lock | 79 +- htdocs/admin/content/overview.php | 5 +- htdocs/classes/parsedown.class.php | 1426 ---------------------------- htdocs/content/changelog.php | 3 +- src/Core/UtilServiceProvider.php | 18 + src/app.php | 1 + 7 files changed, 101 insertions(+), 1434 deletions(-) delete mode 100644 htdocs/classes/parsedown.class.php create mode 100644 src/Core/UtilServiceProvider.php diff --git a/composer.json b/composer.json index a62759a56..d24e653d5 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "symfony/stopwatch": "~4.2.12", "symfony/http-kernel": "~4.2.12", "symfony/http-foundation": "~4.2.12", - "twig/twig": "^2.12" + "twig/twig": "^2.12", + "league/commonmark": "^1.3" }, "require-dev": { "ergebnis/composer-normalize": "^2.0", diff --git a/composer.lock b/composer.lock index d9d5070b3..e4d19020d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "41102cf7b2753d0905680c184a24bafc", + "content-hash": "bfd77605810fd9b54f16cbbacfb26a31", "packages": [ { "name": "doctrine/annotations", @@ -871,6 +871,80 @@ ], "time": "2018-06-14T14:45:07+00:00" }, + { + "name": "league/commonmark", + "version": "1.3.3", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "5a67afc2572ec6d430526cdc9c637ef124812389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/5a67afc2572ec6d430526cdc9c637ef124812389", + "reference": "5a67afc2572ec6d430526cdc9c637ef124812389", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1" + }, + "conflict": { + "scrutinizer/ocular": "1.7.*" + }, + "require-dev": { + "cebe/markdown": "~1.0", + "commonmark/commonmark.js": "0.29.1", + "erusev/parsedown": "~1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "~1.4", + "mikehaertl/php-shellcommand": "^1.4", + "phpstan/phpstan-shim": "^0.11.5", + "phpunit/phpunit": "^7.5", + "scrutinizer/ocular": "^1.5", + "symfony/finder": "^4.2" + }, + "bin": [ + "bin/commonmark" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "time": "2020-04-05T16:01:48+00:00" + }, { "name": "littlecubiclegames/quests", "version": "1.1.0", @@ -5570,5 +5644,6 @@ "prefer-stable": true, "prefer-lowest": false, "platform": [], - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/htdocs/admin/content/overview.php b/htdocs/admin/content/overview.php index 5c06f3199..0f2bc2644 100644 --- a/htdocs/admin/content/overview.php +++ b/htdocs/admin/content/overview.php @@ -91,12 +91,11 @@ // Changelog // elseif ($sub === "changelog") { - $Parsedown = new Parsedown(); $changelogFile = "../../Changelog.md"; $changelogPublicFile = "../../Changelog_public.md"; echo $twig->render('admin/overview/changelog.html.twig', [ - 'changelog' => is_file($changelogFile) ? $Parsedown->text(file_get_contents($changelogFile)) : null, - 'changelogPublic' => is_file($changelogPublicFile) ? $Parsedown->text(file_get_contents($changelogPublicFile)) : null, + 'changelog' => is_file($changelogFile) ? $app['etoa.util.markdown']->convertToHtml(file_get_contents($changelogFile)) : null, + 'changelogPublic' => is_file($changelogPublicFile) ? $app['etoa.util.markdown']->convertToHtml(file_get_contents($changelogPublicFile)) : null, ]); exit(); } diff --git a/htdocs/classes/parsedown.class.php b/htdocs/classes/parsedown.class.php deleted file mode 100644 index f873d2660..000000000 --- a/htdocs/classes/parsedown.class.php +++ /dev/null @@ -1,1426 +0,0 @@ -Definitions = array(); - - # standardize line breaks - $text = str_replace("\r\n", "\n", $text); - $text = str_replace("\r", "\n", $text); - - # replace tabs with spaces - $text = str_replace("\t", ' ', $text); - - # remove surrounding line breaks - $text = trim($text, "\n"); - - # split text into lines - $lines = explode("\n", $text); - - # iterate through lines to identify blocks - $markup = $this->lines($lines); - - # trim line breaks - $markup = trim($markup, "\n"); - - return $markup; - } - - # - # Setters - # - - private $breaksEnabled; - - function setBreaksEnabled($breaksEnabled) - { - $this->breaksEnabled = $breaksEnabled; - - return $this; - } - - private $markupEscaped; - - function setMarkupEscaped($markupEscaped) - { - $this->markupEscaped = $markupEscaped; - - return $this; - } - - # - # Lines - # - - protected $BlockTypes = array( - '#' => array('Atx'), - '*' => array('Rule', 'List'), - '+' => array('List'), - '-' => array('Setext', 'Table', 'Rule', 'List'), - '0' => array('List'), - '1' => array('List'), - '2' => array('List'), - '3' => array('List'), - '4' => array('List'), - '5' => array('List'), - '6' => array('List'), - '7' => array('List'), - '8' => array('List'), - '9' => array('List'), - ':' => array('Table'), - '<' => array('Comment', 'Markup'), - '=' => array('Setext'), - '>' => array('Quote'), - '_' => array('Rule'), - '`' => array('FencedCode'), - '|' => array('Table'), - '~' => array('FencedCode'), - ); - - # ~ - - protected $DefinitionTypes = array( - '[' => array('Reference'), - ); - - # ~ - - protected $unmarkedBlockTypes = array( - 'CodeBlock', - ); - - # - # Blocks - # - - private function lines(array $lines) - { - $CurrentBlock = null; - - foreach ($lines as $line) - { - if (chop($line) === '') - { - if (isset($CurrentBlock)) - { - $CurrentBlock['interrupted'] = true; - } - - continue; - } - - $indent = 0; - - while (isset($line[$indent]) and $line[$indent] === ' ') - { - $indent ++; - } - - $text = $indent > 0 ? substr($line, $indent) : $line; - - # ~ - - $Line = array('body' => $line, 'indent' => $indent, 'text' => $text); - - # ~ - - if (isset($CurrentBlock['incomplete'])) - { - $Block = $this->{'addTo'.$CurrentBlock['type']}($Line, $CurrentBlock); - - if (isset($Block)) - { - $CurrentBlock = $Block; - - continue; - } - else - { - if (method_exists($this, 'complete'.$CurrentBlock['type'])) - { - $CurrentBlock = $this->{'complete'.$CurrentBlock['type']}($CurrentBlock); - } - - unset($CurrentBlock['incomplete']); - } - } - - # ~ - - $marker = $text[0]; - - if (isset($this->DefinitionTypes[$marker])) - { - foreach ($this->DefinitionTypes[$marker] as $definitionType) - { - $Definition = $this->{'identify'.$definitionType}($Line, $CurrentBlock); - - if (isset($Definition)) - { - $this->Definitions[$definitionType][$Definition['id']] = $Definition['data']; - - continue 2; - } - } - } - - # ~ - - $blockTypes = $this->unmarkedBlockTypes; - - if (isset($this->BlockTypes[$marker])) - { - foreach ($this->BlockTypes[$marker] as $blockType) - { - $blockTypes []= $blockType; - } - } - - # - # ~ - - foreach ($blockTypes as $blockType) - { - $Block = $this->{'identify'.$blockType}($Line, $CurrentBlock); - - if (isset($Block)) - { - $Block['type'] = $blockType; - - if ( ! isset($Block['identified'])) - { - $Elements []= $CurrentBlock['element']; - - $Block['identified'] = true; - } - - if (method_exists($this, 'addTo'.$blockType)) - { - $Block['incomplete'] = true; - } - - $CurrentBlock = $Block; - - continue 2; - } - } - - # ~ - - if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted'])) - { - $CurrentBlock['element']['text'] .= "\n".$text; - } - else - { - $Elements []= $CurrentBlock['element']; - - $CurrentBlock = $this->buildParagraph($Line); - - $CurrentBlock['identified'] = true; - } - } - - # ~ - - if (isset($CurrentBlock['incomplete']) and method_exists($this, 'complete'.$CurrentBlock['type'])) - { - $CurrentBlock = $this->{'complete'.$CurrentBlock['type']}($CurrentBlock); - } - - # ~ - - $Elements []= $CurrentBlock['element']; - - unset($Elements[0]); - - # ~ - - $markup = $this->elements($Elements); - - # ~ - - return $markup; - } - - # - # Atx - - protected function identifyAtx($Line) - { - if (isset($Line['text'][1])) - { - $level = 1; - - while (isset($Line['text'][$level]) and $Line['text'][$level] === '#') - { - $level ++; - } - - $text = trim($Line['text'], '# '); - - $Block = array( - 'element' => array( - 'name' => 'h' . min(6, $level), - 'text' => $text, - 'handler' => 'line', - ), - ); - - return $Block; - } - } - - # - # Code - - protected function identifyCodeBlock($Line) - { - if ($Line['indent'] >= 4) - { - $text = substr($Line['body'], 4); - - $Block = array( - 'element' => array( - 'name' => 'pre', - 'handler' => 'element', - 'text' => array( - 'name' => 'code', - 'text' => $text, - ), - ), - ); - - return $Block; - } - } - - protected function addToCodeBlock($Line, $Block) - { - if ($Line['indent'] >= 4) - { - if (isset($Block['interrupted'])) - { - $Block['element']['text']['text'] .= "\n"; - - unset($Block['interrupted']); - } - - $Block['element']['text']['text'] .= "\n"; - - $text = substr($Line['body'], 4); - - $Block['element']['text']['text'] .= $text; - - return $Block; - } - } - - protected function completeCodeBlock($Block) - { - $text = $Block['element']['text']['text']; - - $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); - - $Block['element']['text']['text'] = $text; - - return $Block; - } - - # - # Comment - - protected function identifyComment($Line) - { - if ($this->markupEscaped) - { - return; - } - - if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!') - { - $Block = array( - 'element' => $Line['body'], - ); - - if (preg_match('/-->$/', $Line['text'])) - { - $Block['closed'] = true; - } - - return $Block; - } - } - - protected function addToComment($Line, array $Block) - { - if (isset($Block['closed'])) - { - return; - } - - $Block['element'] .= "\n" . $Line['body']; - - if (preg_match('/-->$/', $Line['text'])) - { - $Block['closed'] = true; - } - - return $Block; - } - - # - # Fenced Code - - protected function identifyFencedCode($Line) - { - if (preg_match('/^(['.$Line['text'][0].']{3,})[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches)) - { - $Element = array( - 'name' => 'code', - 'text' => '', - ); - - if (isset($matches[2])) - { - $class = 'language-'.$matches[2]; - - $Element['attributes'] = array( - 'class' => $class, - ); - } - - $Block = array( - 'char' => $Line['text'][0], - 'element' => array( - 'name' => 'pre', - 'handler' => 'element', - 'text' => $Element, - ), - ); - - return $Block; - } - } - - protected function addToFencedCode($Line, $Block) - { - if (isset($Block['complete'])) - { - return; - } - - if (isset($Block['interrupted'])) - { - $Block['element']['text']['text'] .= "\n"; - - unset($Block['interrupted']); - } - - if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text'])) - { - $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1); - - $Block['complete'] = true; - - return $Block; - } - - $Block['element']['text']['text'] .= "\n".$Line['body'];; - - return $Block; - } - - protected function completeFencedCode($Block) - { - $text = $Block['element']['text']['text']; - - $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); - - $Block['element']['text']['text'] = $text; - - return $Block; - } - - # - # List - - protected function identifyList($Line) - { - list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]'); - - if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches)) - { - $Block = array( - 'indent' => $Line['indent'], - 'pattern' => $pattern, - 'element' => array( - 'name' => $name, - 'handler' => 'elements', - ), - ); - - $Block['li'] = array( - 'name' => 'li', - 'handler' => 'li', - 'text' => array( - $matches[2], - ), - ); - - $Block['element']['text'] []= & $Block['li']; - - return $Block; - } - } - - protected function addToList($Line, array $Block) - { - if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'[ ]+(.*)/', $Line['text'], $matches)) - { - if (isset($Block['interrupted'])) - { - $Block['li']['text'] []= ''; - - unset($Block['interrupted']); - } - - unset($Block['li']); - - $Block['li'] = array( - 'name' => 'li', - 'handler' => 'li', - 'text' => array( - $matches[1], - ), - ); - - $Block['element']['text'] []= & $Block['li']; - - return $Block; - } - - if ( ! isset($Block['interrupted'])) - { - $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); - - $Block['li']['text'] []= $text; - - return $Block; - } - - if ($Line['indent'] > 0) - { - $Block['li']['text'] []= ''; - - $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); - - $Block['li']['text'] []= $text; - - unset($Block['interrupted']); - - return $Block; - } - } - - # - # Quote - - protected function identifyQuote($Line) - { - if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) - { - $Block = array( - 'element' => array( - 'name' => 'blockquote', - 'handler' => 'lines', - 'text' => (array) $matches[1], - ), - ); - - return $Block; - } - } - - protected function addToQuote($Line, array $Block) - { - if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) - { - if (isset($Block['interrupted'])) - { - $Block['element']['text'] []= ''; - - unset($Block['interrupted']); - } - - $Block['element']['text'] []= $matches[1]; - - return $Block; - } - - if ( ! isset($Block['interrupted'])) - { - $Block['element']['text'] []= $Line['text']; - - return $Block; - } - } - - # - # Rule - - protected function identifyRule($Line) - { - if (preg_match('/^(['.$Line['text'][0].'])([ ]{0,2}\1){2,}[ ]*$/', $Line['text'])) - { - $Block = array( - 'element' => array( - 'name' => 'hr' - ), - ); - - return $Block; - } - } - - # - # Setext - - protected function identifySetext($Line, array $Block = null) - { - if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) - { - return; - } - - if (chop($Line['text'], $Line['text'][0]) === '') - { - $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2'; - - return $Block; - } - } - - # - # Markup - - protected function identifyMarkup($Line) - { - if ($this->markupEscaped) - { - return; - } - - if (preg_match('/^<(\w[\w\d]*)(?:[ ][^>]*)?(\/?)[ ]*>/', $Line['text'], $matches)) - { - if (in_array($matches[1], $this->textLevelElements)) - { - return; - } - - $Block = array( - 'element' => $Line['body'], - ); - - if ($matches[2] or $matches[1] === 'hr' or preg_match('/<\/'.$matches[1].'>[ ]*$/', $Line['text'])) - { - $Block['closed'] = true; - } - else - { - $Block['depth'] = 0; - $Block['name'] = $matches[1]; - } - - return $Block; - } - } - - protected function addToMarkup($Line, array $Block) - { - if (isset($Block['closed'])) - { - return; - } - - if (preg_match('/<'.$Block['name'].'([ ][^\/]+)?>/', $Line['text'])) # opening tag - { - $Block['depth'] ++; - } - - if (stripos($Line['text'], '') !== false) # closing tag - { - if ($Block['depth'] > 0) - { - $Block['depth'] --; - } - else - { - $Block['closed'] = true; - } - } - - $Block['element'] .= "\n".$Line['body']; - - return $Block; - } - - # - # Table - - protected function identifyTable($Line, array $Block = null) - { - if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) - { - return; - } - - if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '') - { - $alignments = array(); - - $divider = $Line['text']; - - $divider = trim($divider); - $divider = trim($divider, '|'); - - $dividerCells = explode('|', $divider); - - foreach ($dividerCells as $dividerCell) - { - $dividerCell = trim($dividerCell); - - if ($dividerCell === '') - { - continue; - } - - $alignment = null; - - if ($dividerCell[0] === ':') - { - $alignment = 'left'; - } - - if (substr($dividerCell, -1) === ':') - { - $alignment = $alignment === 'left' ? 'center' : 'right'; - } - - $alignments []= $alignment; - } - - # ~ - - $HeaderElements = array(); - - $header = $Block['element']['text']; - - $header = trim($header); - $header = trim($header, '|'); - - $headerCells = explode('|', $header); - - foreach ($headerCells as $index => $headerCell) - { - $headerCell = trim($headerCell); - - $HeaderElement = array( - 'name' => 'th', - 'text' => $headerCell, - 'handler' => 'line', - ); - - if (isset($alignments[$index])) - { - $alignment = $alignments[$index]; - - $HeaderElement['attributes'] = array( - 'align' => $alignment, - ); - } - - $HeaderElements []= $HeaderElement; - } - - # ~ - - $Block = array( - 'alignments' => $alignments, - 'identified' => true, - 'element' => array( - 'name' => 'table', - 'handler' => 'elements', - ), - ); - - $Block['element']['text'] []= array( - 'name' => 'thead', - 'handler' => 'elements', - ); - - $Block['element']['text'] []= array( - 'name' => 'tbody', - 'handler' => 'elements', - 'text' => array(), - ); - - $Block['element']['text'][0]['text'] []= array( - 'name' => 'tr', - 'handler' => 'elements', - 'text' => $HeaderElements, - ); - - return $Block; - } - } - - protected function addToTable($Line, array $Block) - { - if ($Line['text'][0] === '|' or strpos($Line['text'], '|')) - { - $Elements = array(); - - $row = $Line['text']; - - $row = trim($row); - $row = trim($row, '|'); - - $cells = explode('|', $row); - - foreach ($cells as $index => $cell) - { - $cell = trim($cell); - - $Element = array( - 'name' => 'td', - 'handler' => 'line', - 'text' => $cell, - ); - - if (isset($Block['alignments'][$index])) - { - $Element['attributes'] = array( - 'align' => $Block['alignments'][$index], - ); - } - - $Elements []= $Element; - } - - $Element = array( - 'name' => 'tr', - 'handler' => 'elements', - 'text' => $Elements, - ); - - $Block['element']['text'][1]['text'] []= $Element; - - return $Block; - } - } - - # - # Definitions - # - - protected function identifyReference($Line) - { - if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches)) - { - $Definition = array( - 'id' => strtolower($matches[1]), - 'data' => array( - 'url' => $matches[2], - ), - ); - - if (isset($matches[3])) - { - $Definition['data']['title'] = $matches[3]; - } - - return $Definition; - } - } - - # - # ~ - # - - protected function buildParagraph($Line) - { - $Block = array( - 'element' => array( - 'name' => 'p', - 'text' => $Line['text'], - 'handler' => 'line', - ), - ); - - return $Block; - } - - # - # ~ - # - - protected function element(array $Element) - { - $markup = '<'.$Element['name']; - - if (isset($Element['attributes'])) - { - foreach ($Element['attributes'] as $name => $value) - { - $markup .= ' '.$name.'="'.$value.'"'; - } - } - - if (isset($Element['text'])) - { - $markup .= '>'; - - if (isset($Element['handler'])) - { - $markup .= $this->{$Element['handler']}($Element['text']); - } - else - { - $markup .= $Element['text']; - } - - $markup .= ''; - } - else - { - $markup .= ' />'; - } - - return $markup; - } - - protected function elements(array $Elements) - { - $markup = ''; - - foreach ($Elements as $Element) - { - if ($Element === null) - { - continue; - } - - $markup .= "\n"; - - if (is_string($Element)) # because of Markup - { - $markup .= $Element; - - continue; - } - - $markup .= $this->element($Element); - } - - $markup .= "\n"; - - return $markup; - } - - # - # Spans - # - - protected $SpanTypes = array( - '!' => array('Link'), # ? - '&' => array('Ampersand'), - '*' => array('Emphasis'), - '/' => array('Url'), - '<' => array('UrlTag', 'EmailTag', 'Tag', 'LessThan'), - '[' => array('Link'), - '_' => array('Emphasis'), - '`' => array('InlineCode'), - '~' => array('Strikethrough'), - '\\' => array('EscapeSequence'), - ); - - # ~ - - protected $spanMarkerList = '*_!&[spanMarkerList)) - { - $marker = $excerpt[0]; - - $markerPosition += strpos($remainder, $marker); - - $Excerpt = array('text' => $excerpt, 'context' => $text); - - foreach ($this->SpanTypes[$marker] as $spanType) - { - $handler = 'identify'.$spanType; - - $Span = $this->$handler($Excerpt); - - if ( ! isset($Span)) - { - continue; - } - - # The identified span can be ahead of the marker. - - if (isset($Span['position']) and $Span['position'] > $markerPosition) - { - continue; - } - - # Spans that start at the position of their marker don't have to set a position. - - if ( ! isset($Span['position'])) - { - $Span['position'] = $markerPosition; - } - - $plainText = substr($text, 0, $Span['position']); - - $markup .= $this->readPlainText($plainText); - - $markup .= isset($Span['markup']) ? $Span['markup'] : $this->element($Span['element']); - - $text = substr($text, $Span['position'] + $Span['extent']); - - $remainder = $text; - - $markerPosition = 0; - - continue 2; - } - - $remainder = substr($excerpt, 1); - - $markerPosition ++; - } - - $markup .= $this->readPlainText($text); - - return $markup; - } - - # - # ~ - # - - protected function identifyUrl($Excerpt) - { - if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '/') - { - return; - } - - if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) - { - $url = str_replace(array('&', '<'), array('&', '<'), $matches[0][0]); - - return array( - 'extent' => strlen($matches[0][0]), - 'position' => $matches[0][1], - 'element' => array( - 'name' => 'a', - 'text' => $url, - 'attributes' => array( - 'href' => $url, - ), - ), - ); - } - } - - protected function identifyAmpersand($Excerpt) - { - if ( ! preg_match('/^&#?\w+;/', $Excerpt['text'])) - { - return array( - 'markup' => '&', - 'extent' => 1, - ); - } - } - - protected function identifyStrikethrough($Excerpt) - { - if ( ! isset($Excerpt['text'][1])) - { - return; - } - - if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches)) - { - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => 'del', - 'text' => $matches[1], - 'handler' => 'line', - ), - ); - } - } - - protected function identifyEscapeSequence($Excerpt) - { - if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters)) - { - return array( - 'markup' => $Excerpt['text'][1], - 'extent' => 2, - ); - } - } - - protected function identifyLessThan() - { - return array( - 'markup' => '<', - 'extent' => 1, - ); - } - - protected function identifyUrlTag($Excerpt) - { - if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(https?:[\/]{2}[^\s]+?)>/i', $Excerpt['text'], $matches)) - { - $url = str_replace(array('&', '<'), array('&', '<'), $matches[1]); - - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => 'a', - 'text' => $url, - 'attributes' => array( - 'href' => $url, - ), - ), - ); - } - } - - protected function identifyEmailTag($Excerpt) - { - if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\S+?@\S+?)>/', $Excerpt['text'], $matches)) - { - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => 'a', - 'text' => $matches[1], - 'attributes' => array( - 'href' => 'mailto:'.$matches[1], - ), - ), - ); - } - } - - protected function identifyTag($Excerpt) - { - if ($this->markupEscaped) - { - return; - } - - if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<\/?\w.*?>/', $Excerpt['text'], $matches)) - { - return array( - 'markup' => $matches[0], - 'extent' => strlen($matches[0]), - ); - } - } - - protected function identifyInlineCode($Excerpt) - { - $marker = $Excerpt['text'][0]; - - if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? strlen($matches[0]), - 'element' => array( - 'name' => 'code', - 'text' => $text, - ), - ); - } - } - - protected function identifyLink($Excerpt) - { - $extent = $Excerpt['text'][0] === '!' ? 1 : 0; - - if (strpos($Excerpt['text'], ']') and preg_match('/\[((?:[^][]|(?R))*)\]/', $Excerpt['text'], $matches)) - { - $Link = array('text' => $matches[1], 'label' => strtolower($matches[1])); - - $extent += strlen($matches[0]); - - $substring = substr($Excerpt['text'], $extent); - - if (preg_match('/^\s*\[([^][]+)\]/', $substring, $matches)) - { - $Link['label'] = strtolower($matches[1]); - - if (isset($this->Definitions['Reference'][$Link['label']])) - { - $Link += $this->Definitions['Reference'][$Link['label']]; - - $extent += strlen($matches[0]); - } - else - { - return; - } - } - elseif (isset($this->Definitions['Reference'][$Link['label']])) - { - $Link += $this->Definitions['Reference'][$Link['label']]; - - if (preg_match('/^[ ]*\[\]/', $substring, $matches)) - { - $extent += strlen($matches[0]); - } - } - elseif (preg_match('/^\([ ]*(.*?)(?:[ ]+[\'"](.+?)[\'"])?[ ]*\)/', $substring, $matches)) - { - $Link['url'] = $matches[1]; - - if (isset($matches[2])) - { - $Link['title'] = $matches[2]; - } - - $extent += strlen($matches[0]); - } - else - { - return; - } - } - else - { - return; - } - - $url = str_replace(array('&', '<'), array('&', '<'), $Link['url']); - - if ($Excerpt['text'][0] === '!') - { - $Element = array( - 'name' => 'img', - 'attributes' => array( - 'alt' => $Link['text'], - 'src' => $url, - ), - ); - } - else - { - $Element = array( - 'name' => 'a', - 'handler' => 'line', - 'text' => $Link['text'], - 'attributes' => array( - 'href' => $url, - ), - ); - } - - if (isset($Link['title'])) - { - $Element['attributes']['title'] = $Link['title']; - } - - return array( - 'extent' => $extent, - 'element' => $Element, - ); - } - - protected function identifyEmphasis($Excerpt) - { - if ( ! isset($Excerpt['text'][1])) - { - return; - } - - $marker = $Excerpt['text'][0]; - - if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches)) - { - $emphasis = 'strong'; - } - elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches)) - { - $emphasis = 'em'; - } - else - { - return; - } - - return array( - 'extent' => strlen($matches[0]), - 'element' => array( - 'name' => $emphasis, - 'handler' => 'line', - 'text' => $matches[1], - ), - ); - } - - # - # ~ - - protected function readPlainText($text) - { - $breakMarker = $this->breaksEnabled ? "\n" : " \n"; - - $text = str_replace($breakMarker, "
\n", $text); - - return $text; - } - - # - # ~ - # - - protected function li($lines) - { - $markup = $this->lines($lines); - - $trimmedMarkup = trim($markup); - - if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '

') - { - $markup = $trimmedMarkup; - $markup = substr($markup, 3); - - $position = strpos($markup, "

"); - - $markup = substr_replace($markup, '', $position, 4); - } - - return $markup; - } - - # - # Multiton - # - - static function instance($name = 'default') - { - if (isset(self::$instances[$name])) - { - return self::$instances[$name]; - } - - $instance = new self(); - - self::$instances[$name] = $instance; - - return $instance; - } - - private static $instances = array(); - - # - # Deprecated Methods - # - - /** - * @deprecated in favor of "text" - */ - function parse($text) - { - $markup = $this->text($text); - - return $markup; - } - - # - # Fields - # - - protected $Definitions; - - # - # Read-only - - protected $specialCharacters = array( - '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', - ); - - protected $StrongRegex = array( - '*' => '/^[*]{2}((?:[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s', - '_' => '/^__((?:[^_]|_[^_]*_)+?)__(?!_)/us', - ); - - protected $EmRegex = array( - '*' => '/^[*]((?:[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', - '_' => '/^_((?:[^_]|__[^_]*__)+?)_(?!_)\b/us', - ); - - protected $textLevelElements = array( - 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont', - 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing', - 'i', 'rp', 'del', 'code', 'strike', 'marquee', - 'q', 'rt', 'ins', 'font', 'strong', - 's', 'tt', 'sub', 'mark', - 'u', 'xm', 'sup', 'nobr', - 'var', 'ruby', - 'wbr', 'span', - 'time', - ); -} diff --git a/htdocs/content/changelog.php b/htdocs/content/changelog.php index 41fee58de..306022f04 100644 --- a/htdocs/content/changelog.php +++ b/htdocs/content/changelog.php @@ -2,8 +2,7 @@ $changelogFile = "../Changelog_public.md"; if (is_file($changelogFile)) { echo '
'; - $Parsedown = new Parsedown(); - echo $Parsedown->text(file_get_contents($changelogFile)); + echo $app['etoa.util.markdown']->convertToHtml(file_get_contents($changelogFile)); echo '
'; } else { echo "

Changelog

"; diff --git a/src/Core/UtilServiceProvider.php b/src/Core/UtilServiceProvider.php new file mode 100644 index 000000000..d12254cb4 --- /dev/null +++ b/src/Core/UtilServiceProvider.php @@ -0,0 +1,18 @@ +register(new \EtoA\Building\BuidingServiceProvider()); $app->register(new \EtoA\Core\DoctrineServiceProvider()); $app->register(new \EtoA\Core\ParamConverterServiceProvider()); +$app->register(new \EtoA\Core\UtilServiceProvider()); $app->register(new \EtoA\Core\SessionServiceProvider()); $app->register(new \EtoA\Defense\DefenseServiceProvider()); $app->register(new \EtoA\Missile\MissileServiceProvider());