Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
33.33% |
1 / 3 |
|
81.82% |
27 / 33 |
CRAP | |
90.65% |
291 / 321 |
| Markdown | |
0.00% |
0 / 1 |
|
83.33% |
25 / 30 |
73.20 | |
90.41% |
245 / 271 |
| __construct($settings = false) | |
0.00% |
0 / 1 |
3.10 | |
77.78% |
7 / 9 |
|||
| displayAttribution() | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| getHTML($markdownText) | |
100.00% |
1 / 1 |
2 | |
100.00% |
20 / 20 |
|||
| fileGetContentsAsHtml($fileName) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
| _insertAttribution($markdownText) | |
0.00% |
0 / 1 |
22.17 | |
11.76% |
2 / 17 |
|||
| _removeEmptyParagraphs($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| _replaceNewLines($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| _removeTrailingSpaces($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
| _removeHtml($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| _replaceBold($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| _insertCssIdSpan($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
| anonymous function ($matches) | |
100.00% |
1 / 1 |
7 | |
100.00% |
31 / 31 |
|||
| _insertCssClassSpan($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
| _replaceItalic($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| _insertParagraphs($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| _extractLinks(&$markdownText) | |
100.00% |
1 / 1 |
2 | |
100.00% |
9 / 9 |
|||
| _replaceLinks($markdownText, $links) | |
0.00% |
0 / 1 |
9.18 | |
86.96% |
20 / 23 |
|||
| _replaceExplicitLinks($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| _replaceHyperLink($markdownText, $linkNbr, $link) | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| _replaceImages($markdownText, $linkNbr, $link) | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| _replaceImbedded($markdownText, $linkNbr, $link) | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| _getLinkAttributes($link, $defaultWidth = null, $defaultHeight = null) | |
100.00% |
1 / 1 |
6 | |
100.00% |
23 / 23 |
|||
| _replaceHeadings($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
| _insertCodeTags($markdownText) | |
100.00% |
1 / 1 |
3 | |
100.00% |
13 / 13 |
|||
| _resolveEscapeCharacters($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
| _replaceHorizontalLine($markdownText) | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| _replaceLists($markdownText) | |
100.00% |
1 / 1 |
5 | |
100.00% |
41 / 41 |
|||
| _getTableHeader($markdownTable) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| _getTableBody($markdownTable) | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| _buildTables($markdownText) | |
100.00% |
1 / 1 |
7 | |
100.00% |
1 / 1 |
|||
| TableHeader | |
0.00% |
0 / 1 |
|
50.00% |
1 / 2 |
14.13 | |
91.30% |
42 / 46 |
| __construct($markdownTable) | |
0.00% |
0 / 1 |
8.21 | |
85.19% |
23 / 27 |
|||
| getAlignAttribute($columnNbr) | |
100.00% |
1 / 1 |
6 | |
100.00% |
19 / 19 |
|||
| ListType | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
| __construct($listRegexIdentifyer, $listTagOpen, $listTagClose) | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| <?php | |
| /** | |
| * | |
| */ | |
| namespace aae\ui { | |
| /** | |
| * @author Axel Ancona Esselmann | |
| * @package aae\ui | |
| */ | |
| class Markdown { | |
| const ALLOW_HTML = 1; | |
| const DISPLAY_ATTRIBUTION = 2; | |
| private $_allowHTML = false, $_displayAttribution = false, $_fileName = false; | |
| public function __construct($settings = false) { | |
| if ($settings & Markdown::ALLOW_HTML) { | |
| $this->_allowHTML = true; | |
| } | |
| if ($settings & Markdown::DISPLAY_ATTRIBUTION) { | |
| $this->_displayAttribution = true; | |
| } | |
| $this->paragraphOpenTag = "<p>"; | |
| $this->paragraphCloseTag = "</p>"; | |
| } | |
| public function displayAttribution() { | |
| $this->_displayAttribution = true; | |
| } | |
| public function getHTML($markdownText) { | |
| if (!$this->_allowHTML) $markdownText = $this->_removeHtml($markdownText); | |
| $markdownText = $this->_resolveEscapeCharacters($markdownText); | |
| $links = $this->_extractLinks($markdownText); | |
| $markdownText = $this->_replaceLinks($markdownText, $links); | |
| $markdownText = $this->_insertCssIdSpan($markdownText); | |
| $markdownText = $this->_insertCssClassSpan($markdownText); | |
| $markdownText = $this->_replaceHorizontalLine($markdownText); | |
| $markdownText = $this->_insertCodeTags($markdownText); | |
| $markdownText = $this->_replaceHeadings($markdownText); | |
| $markdownText = $this->_replaceBold($markdownText); | |
| $markdownText = $this->_replaceItalic($markdownText); | |
| $markdownText = $this->_buildTables($markdownText); | |
| $markdownText = $this->_replaceLists($markdownText); | |
| $markdownText = $this->_insertParagraphs($markdownText); | |
| $markdownText = $this->_replaceNewLines($markdownText); | |
| $markdownText = $this->_removeTrailingSpaces($markdownText); | |
| $markdownText = $this->_removeEmptyParagraphs($markdownText); | |
| $markdownText = $this->_insertAttribution($markdownText); | |
| $this->_fileName = false; | |
| return trim($markdownText); | |
| } | |
| public function fileGetContentsAsHtml($fileName) { | |
| $contents = file_get_contents($fileName); | |
| $this->_fileName = $fileName; | |
| $html = $this->getHTML($contents); | |
| return $html; | |
| } | |
| private function _insertAttribution($markdownText) { | |
| if ($this->_displayAttribution === true) { | |
| $originalContentStatement = ""; | |
| if ($this->_fileName) { | |
| $fileName = realpath($this->_fileName); | |
| $documentRoot = $_SERVER["DOCUMENT_ROOT"]; | |
| if (substr($documentRoot, -1) != "/") { | |
| $documentRoot .= "/"; | |
| } | |
| $strPos = strpos($fileName, $documentRoot); | |
| if ($strPos !== false) { | |
| $originalContentLink = substr($fileName, strlen($documentRoot)); | |
| $originalContentStatement = " View the original file <a href=\"$originalContentLink\">here</a>."; | |
| } | |
| } | |
| $markdownText .= '<div class="attribution">This page was rendered with <a href="https://github.com/anconaesselmann/MyMark">MyMark</a>, a Markdown flavor developed by <a href="http://anconaesselmann.com">Axel Ancona Esselmann</a>.'.$originalContentStatement.'</div>'; | |
| } | |
| return $markdownText; | |
| } | |
| private function _removeEmptyParagraphs($markdownText) { | |
| $regex = "/<p[^>]*>([\s\n]*)<\\/p[^>]*>/"; | |
| return preg_replace($regex, "", $markdownText); | |
| } | |
| private function _replaceNewLines($markdownText){ | |
| $newlienTag = "<br />"; | |
| $regex = "/(\\n)/"; | |
| return preg_replace($regex, $newlienTag, $markdownText); | |
| } | |
| private function _removeTrailingSpaces($markdownText) { | |
| $markdownText = $this->paragraphOpenTag.$markdownText.$this->paragraphCloseTag; | |
| $regex = "/(\<br \/\>)*([\s\n]*)(\<\/p[^>]*>)/"; | |
| $markdownText = preg_replace($regex, "$3", $markdownText); | |
| $regex = "/(\<p[^>]*>)([\s\n]*)(\<br \/\>)*/"; | |
| $markdownText = preg_replace($regex, "$1", $markdownText); | |
| return $markdownText; | |
| } | |
| private function _removeHtml($markdownText) { | |
| $regex = "/<[^>]*>/"; | |
| return preg_replace($regex, "", $markdownText); | |
| } | |
| private function _replaceBold($markdownText) { | |
| $strongOpenTag = "<strong>"; | |
| $strongCloseTag = "</strong>"; | |
| $regex = "/(\*\*)([^\s^\*])([^\*]*)(\*\*)/"; | |
| return preg_replace($regex, $strongOpenTag."$2$3".$strongCloseTag, $markdownText); | |
| } | |
| private function _insertCssIdSpan($markdownText) { | |
| $regex = '/ | |
| (\{\#) | |
| (?<cssId>[^\s]+) | |
| (\s+) | |
| (?<body>[^\}]+) | |
| (\}) | |
| /sx'; | |
| $callback = function ($matches) { | |
| $htmlHeading = "<span id=\"".$matches["cssId"]."\">".$matches["body"]."</span>"; | |
| return $htmlHeading; | |
| }; | |
| $markdownText = preg_replace_callback($regex, $callback, $markdownText); | |
| return $markdownText; | |
| } | |
| private function _insertCssClassSpan($markdownText) { | |
| $regex = '/ | |
| (\{\.) | |
| (?<cssClass>[^\s]+) | |
| (\s+) | |
| (?<body>[^\}]+) | |
| (\}) | |
| /sx'; | |
| $callback = function ($matches) { | |
| $htmlHeading = "<span class=\"".$matches["cssClass"]."\">".$matches["body"]."</span>"; | |
| return $htmlHeading; | |
| }; | |
| $markdownText = preg_replace_callback($regex, $callback, $markdownText); | |
| return $markdownText; | |
| } | |
| private function _replaceItalic($markdownText) { | |
| $italicOpenTag = "<i>"; | |
| $italicCloseTag = "</i>"; | |
| $regex = "/(\*)([^\s^\*])([^\*]*)(\*)/"; | |
| return preg_replace($regex, $italicOpenTag."$2$3".$italicCloseTag, $markdownText); | |
| } | |
| public function _insertParagraphs($markdownText) { | |
| $regex = "/(\\n\\n)/"; | |
| return preg_replace($regex, $this->paragraphCloseTag.$this->paragraphOpenTag, $markdownText); | |
| } | |
| private function _extractLinks(&$markdownText) { | |
| $assoc = array(); | |
| $result = array(); | |
| $regex = "/(\[)([^\]]+)(\])(\:\s*)([^\n]*?)(\s*\n|\s*$)/"; | |
| preg_match_all($regex, $markdownText, $assoc); | |
| for ($i=0; $i < count($assoc[0]); $i++) { | |
| $result[$assoc[2][$i]] = $assoc[5][$i]; | |
| } | |
| $markdownText = preg_replace($regex, "", $markdownText); | |
| return $result; | |
| } | |
| private function _replaceLinks($markdownText, $links) { | |
| foreach ($links as $linkNbr => $link) { | |
| $linkParts = explode(";", $linkNbr); | |
| if (count($linkParts) > 1) { | |
| $linkNbr = $linkParts[0]; | |
| $linkType = $linkParts[1]; | |
| switch ($linkType) { | |
| case 'i': | |
| case 'img': | |
| $markdownText = $this->_replaceImages($markdownText, $linkNbr, $link); | |
| break; | |
| case 'v': | |
| case 'youtube': | |
| case 'flickr': | |
| case 'iframe': | |
| $markdownText = $this->_replaceImbedded($markdownText, $linkNbr, $link); | |
| break; | |
| default: | |
| break; | |
| } | |
| } else { | |
| $markdownText = $this->_replaceHyperLink($markdownText, $linkNbr, $link); | |
| } | |
| } | |
| $markdownText = $this->_replaceExplicitLinks($markdownText); | |
| return $markdownText; | |
| } | |
| private function _replaceExplicitLinks($markdownText) { | |
| $patternExplicitLink = "/ | |
| (?<=^|[^w]) | |
| (\[) | |
| (?P<link>[^\]]+) | |
| (\]) | |
| (?=[^w]|$) | |
| /x"; | |
| $explicitLinkCallback = function ($matches) { | |
| return "<a href=\"".$matches["link"]."\">".$matches["link"]."</a>"; | |
| }; | |
| return preg_replace_callback($patternExplicitLink, $explicitLinkCallback, $markdownText); | |
| } | |
| private function _replaceHyperLink($markdownText, $linkNbr, $link) { | |
| $regex = "/([^\s^\]]+)(\[$linkNbr\])/"; | |
| $markdownText = preg_replace($regex, "<a href=\"$link\">$1</a>", $markdownText); | |
| $regex = "/(\[)([^\]]+)([\]])(\[$linkNbr\])/"; | |
| return preg_replace($regex, "<a href=\"$link\">$2</a>", $markdownText); | |
| } | |
| private function _replaceImages($markdownText, $linkNbr, $link) { | |
| $linkAttributes = $this->_getLinkAttributes($link); | |
| $regex = "/(\[)([^\]]+)([\]])(\[$linkNbr\])/"; | |
| $markdownText = preg_replace($regex, "<img$linkAttributes alt=\"$2\">", $markdownText); | |
| return $markdownText; | |
| } | |
| private function _replaceImbedded($markdownText, $linkNbr, $link) { | |
| $linkAttributes = $this->_getLinkAttributes($link, 420, 315); | |
| $regex = "/(\[)([^\]]+)([\]])(\[$linkNbr\])/"; | |
| $markdownText = preg_replace($regex, "<iframe$linkAttributes frameborder=\"0\" allowfullscreen webkitallowfullscreen mozallowfullscreen oallowfullscreen msallowfullscreen></iframe>", $markdownText); | |
| return $markdownText; | |
| } | |
| private function _getLinkAttributes($link, $defaultWidth = null, $defaultHeight = null) { | |
| if (!is_null($defaultHeight) && !is_null($defaultWidth)) { | |
| $height = " height=\"$defaultHeight\""; | |
| $width = " width=\"$defaultWidth\""; | |
| } else { | |
| $height = ""; | |
| $width = ""; | |
| } | |
| $class = ""; | |
| $array = explode("|", $link); | |
| if (count($array) > 1) { | |
| $link = $array[1]; | |
| $parts = explode(";", $array[0]); | |
| $dimensions = explode("x", $parts[0]); | |
| if (count($dimensions) > 1) { | |
| $height = " height=\"".$dimensions[0]."\""; | |
| $width = " width=\"".$dimensions[1]."\""; | |
| } | |
| if (count($parts) > 1) { | |
| $class = " class=\"".$parts[1]."\""; | |
| } else { | |
| $class = " class=\"".$parts[0]."\""; | |
| } | |
| } else { | |
| $link = $array[0]; | |
| } | |
| return $class.$width.$height." src=\"$link\""; | |
| } | |
| private function _replaceHeadings($markdownText) { | |
| $regex = '/ # Format: ^(1-6 hash-tags)(?: space)(heading)(?: optional space and hash-tags)$ | |
| (?<headingType> # The beginning of a header: | |
| (?<= | |
| ^|\n # the beginning of a string or a newline. | |
| )\#+ # followed by 1 to 6 # | |
| ) | |
| (?:\s*) # throw away all whitespace between hash-tags and heading | |
| (?<heading> | |
| [^\#]+? # the heading body | |
| ) | |
| (?:[\s\#]*) # throw away all whitespace and hash-tags | |
| (?= | |
| \n|$ | |
| ) | |
| /sx'; | |
| $headingCallback = function ($matches) { | |
| $headingType = (string)strlen(trim($matches["headingType"])); | |
| $headingOpening = "<h$headingType>"; | |
| $headingCosing = "</h$headingType>"; | |
| $htmlHeading = $headingOpening.$matches["heading"].$headingCosing; | |
| return "</p>".$htmlHeading."<p>"; | |
| }; | |
| $markdownText = preg_replace_callback($regex, $headingCallback, $markdownText); | |
| return $markdownText; | |
| } | |
| public function _insertCodeTags($markdownText) { | |
| $regex = "/(\n\s*\n)( )(.+?)(\n\n+(?=[^\s])|$)/s"; | |
| $matches = array(); | |
| $hasMatches = preg_match_all($regex, $markdownText, $matches); | |
| if ($hasMatches) { | |
| for ($i=0; $i < count($matches[0]); $i++) { | |
| $markdownCodeBlock = $matches[3][$i]; | |
| $replacementRegex = "/\n /"; | |
| $codeBlock = preg_replace($replacementRegex, "<br />", $markdownCodeBlock); | |
| $htmlCodeBlock = "\n".$this->paragraphCloseTag."<pre class=\"prettyprint\"><code>".$codeBlock."</code></pre>".$this->paragraphOpenTag; | |
| $markdownText = str_replace($matches[0][$i], $htmlCodeBlock, $markdownText); | |
| } | |
| } | |
| return $markdownText; | |
| } | |
| public function _resolveEscapeCharacters($markdownText) { | |
| $markdownText = str_replace("\\*", "*", $markdownText); | |
| $markdownText = str_replace("\\<", "<", $markdownText); | |
| $markdownText = str_replace("\\>", ">", $markdownText); | |
| $markdownText = str_replace("\\[", "[", $markdownText); | |
| $markdownText = str_replace("\\]", "]", $markdownText); | |
| $markdownText = str_replace("\\-", "—", $markdownText); | |
| return $markdownText; | |
| } | |
| public function _replaceHorizontalLine($markdownText) { | |
| $regex = "/-{3,}/"; | |
| $markdownText = preg_replace($regex, $this->paragraphCloseTag."<hr />".$this->paragraphOpenTag, $markdownText); | |
| return $markdownText; | |
| } | |
| public function _replaceLists($markdownText) { | |
| $listTypes = array( | |
| new ListType("[\?]+\s", "<dl>", "</dl>"), | |
| new ListType("[IVX]+[\.\)]\s", "<ol type=\"I\">", "</ol>"), | |
| new ListType("[ivx]+[\.\)]\s", "<ol type=\"i\">", "</ol>"), | |
| new ListType("[\d]+[\.\)]\s" , "<ol>" , "</ol>"), | |
| new ListType("[a-h][\.\)]\s" , "<ol type=\"a\">", "</ol>"), | |
| new ListType("[A-H][\.\)]\s" , "<ol type=\"A\">", "</ol>"), | |
| #new ListType("[\-]\s|[\+]\s" , "<ul>" , "</ul>"), | |
| new ListType("[\-]\s" , "<ul>" , "</ul>"), | |
| new ListType("[\+]\s" , "<ul>" , "</ul>"), | |
| ); | |
| foreach ($listTypes as $listType) { | |
| $rxListStart = "(\s*".$listType->listRegexIdentifyer."\s*)"; | |
| $regex = '/ # matches the whole list | |
| ( # group 1 | |
| \n # the beginning of a line | |
| | # or | |
| ^ # the beginning of the string | |
| | | |
| \<p\> # this could introduce error... | |
| ) | |
| (?P<list> # group 2 | |
| '.$rxListStart.'# a number followed by a period and a space | |
| .*? # everything after that | |
| ) | |
| (?= # group 3 | |
| \n( # until a new line is encountered that does not start with a new list item or space | |
| [^\s\d\-\+a-hA-HIiVvXx\?] | |
| | | |
| [\d]+[^\.\)] # not a numbered list | |
| | # | |
| [IVX]+[^\.\)] # not an uppercase list of roman numerals | |
| | # | |
| [ivx]+[^\.\)] # not a lowercase list of roman numerals | |
| | # | |
| [a-h][^\.\)] # not a list of lowercase alphabetic characters | |
| | # | |
| [A-H][^\.\)] # not a list of uppercase alphabetic characters | |
| | # | |
| \n # two line-breaks terminates any list | |
| ) | |
| | | |
| $ | |
| | | |
| \<\/p\>(?!\<table\>) # this could introduce error... | |
| ) | |
| /sx'; | |
| $list = array(); | |
| $match = preg_match_all($regex, $markdownText, $list); | |
| if ($match) { | |
| #print_r($list); | |
| for ($i=0; $i < count($list[0]); $i++) { | |
| $markdownList = $list[2][$i]; | |
| $regex = '/ # matches a list item | |
| ( # group 1 | |
| \n # the beginning of a line | |
| | # or | |
| ^ # the beginning of the string | |
| ) | |
| (?P<listType> # group listType | |
| '.$rxListStart.'# a number followed by a period and a space | |
| ) | |
| (?P<listItem> # group listItem | |
| .*? # the list item content | |
| ) | |
| (?= # lookahead | |
| \n'.$rxListStart.'# terminates when a newline and a list item at the same level is encountered | |
| | # or | |
| $ # terminates at the end of the string | |
| ) | |
| /sx'; | |
| $listItemCallback = function ($matches) { | |
| $regex = "/\n\s/"; | |
| $listItem = preg_replace($regex, "\n", $matches['listItem']); | |
| if ($matches["listType"] == "? ") { | |
| $dashPos = strpos($listItem, "-"); | |
| $term = trim(substr($listItem, 0, $dashPos)); | |
| $definition = trim(substr($listItem, $dashPos+1)); | |
| $listItem = "<dt>$term</dt><dd><p>$definition</p></dd>"; | |
| } else { | |
| $listItem = "<li><p>".$listItem."</p></li>"; | |
| } | |
| return $listItem; | |
| }; | |
| $htmlList = $listType->listTagOpen. | |
| preg_replace_callback($regex, $listItemCallback, $markdownList). | |
| $listType->listTagClose; | |
| $replacement = $this->paragraphCloseTag.$htmlList.$this->paragraphOpenTag; | |
| $markdownText = str_replace($markdownList, $replacement, $markdownText); | |
| } | |
| } | |
| } | |
| return $markdownText; | |
| } | |
| public function _getTableHeader($markdownTable) { | |
| $tableHeader = new TableHeader($markdownTable); | |
| #print_r($tableHeader->columnNames); | |
| #print_r($tableHeader->columnFormat); | |
| return $tableHeader; | |
| } | |
| public function _getTableBody($markdownTable) { | |
| $firstLB = strpos($markdownTable, "\n" ); | |
| $columnNamesString = substr($markdownTable, 0, $firstLB); | |
| $secondLb = strpos($markdownTable, "\n", $firstLB+1); | |
| return substr($markdownTable, $secondLb+1); | |
| } | |
| public function _buildTables($markdownText) { | |
| $patternTable = '/ | |
| ( | |
| (^|\n)\s*\| | |
| ) | |
| (?P<table> | |
| .*? | |
| ) | |
| (?= | |
| \n\s*[^\|\s] | |
| | | |
| $ | |
| ) | |
| /sx'; | |
| $tableCallback = function ($matches) { | |
| $markdownTable = $matches["table"]; | |
| $tableHeader = $this->_getTableHeader($markdownTable); | |
| $tableBody = $this->_getTableBody($markdownTable); | |
| #echo "\n+".$matches["table"]."+\n"; | |
| $rows = explode("\n", $tableBody); | |
| $table = array(); | |
| for ($i=0; $i < count($rows); $i++) { | |
| $table[$i] = array_map('trim', explode("|", $rows[$i])); | |
| if ($table[$i][count($table[$i]) - 1] == "") { | |
| array_pop($table[$i]); | |
| } | |
| if ($table[$i][0] == "") { | |
| array_shift($table[$i]); | |
| } | |
| } | |
| $htmlTable = "<table><thead><tr>"; | |
| for ($i=0; $i < count($tableHeader->columnNames); $i++) { | |
| $format = $tableHeader->getAlignAttribute($i); | |
| $htmlTable .= "<th$format>".$tableHeader->columnNames[$i]."</th>"; | |
| } | |
| $htmlTable .= "</tr></thead><tbody>"; | |
| foreach ($table as $row) { | |
| $htmlTable .= "<tr>"; | |
| for ($i=0; $i < count($row); $i++) { | |
| $format = $tableHeader->getAlignAttribute($i); | |
| $htmlTable .= "<td$format>".$row[$i]."</td>"; | |
| } | |
| $htmlTable .= "</tr>"; | |
| } | |
| $htmlTable .= "</table>"; | |
| return "\n".$tableHeader->indent."</p>".$htmlTable."<p>"; | |
| }; | |
| $markdownText = preg_replace_callback($patternTable, $tableCallback, $markdownText); | |
| #echo "\n+".$markdownText."+\n"; | |
| return $markdownText; | |
| } | |
| } | |
| class TableHeader { | |
| const ALIGN_DEFAULT = 0; | |
| const ALIGN_LEFT = 1; | |
| const ALIGN_RIGHT = 2; | |
| const ALIGN_CENTER = 3; | |
| public $columnNames, $columnFormat; | |
| public function __construct($markdownTable) { | |
| $firstLB = strpos($markdownTable, "\n" ); | |
| $columnNamesString = substr($markdownTable, 0, $firstLB); | |
| $secondLb = strpos($markdownTable, "\n", $firstLB+1); | |
| $columnFormatString = substr($markdownTable, $firstLB+1, $secondLb - $firstLB-2); | |
| $this->indent = substr($columnFormatString, 0, strlen($columnFormatString) - strlen(ltrim($columnFormatString))); | |
| #echo "-".$this->indent."-\n"; | |
| $this->columnNames = array_map('trim', explode("|", $columnNamesString)); | |
| $this->columnFormat = explode("|", $columnFormatString); | |
| if ($this->columnNames[count($this->columnNames)-1] == "") { | |
| array_pop($this->columnNames); | |
| } | |
| if ($this->columnNames[0] == "") { | |
| array_shift($this->columnNames); | |
| } | |
| if ($this->columnFormat[count($this->columnFormat)-1] == "") { | |
| array_pop($this->columnFormat); | |
| } | |
| if ($this->columnFormat[0] == "") { | |
| array_shift($this->columnFormat); | |
| } | |
| for ($i=0; $i < count($this->columnFormat); $i++) { | |
| $firstChar = $this->columnFormat[$i][0]; | |
| $lastChar = $this->columnFormat[$i][strlen($this->columnFormat[$i])-1]; | |
| $firstVal = ($firstChar == ":") ? 1 : 0; | |
| $lastVal = ($lastChar == ":") ? 2 : 0; | |
| $this->columnFormat[$i] = $firstVal + $lastVal; | |
| } | |
| #print_r($this->columnNames); | |
| } | |
| public function getAlignAttribute($columnNbr) { | |
| $format = ""; | |
| if ($columnNbr < count($this->columnFormat)) { | |
| switch ($this->columnFormat[$columnNbr]) { | |
| case 1: | |
| $format = " align=\"left\""; | |
| break; | |
| case 2: | |
| $format = " align=\"right\""; | |
| break; | |
| case 3: | |
| $format = " align=\"center\""; | |
| break; | |
| case 0: | |
| default: | |
| $format = ""; | |
| break; | |
| } | |
| } | |
| return $format; | |
| } | |
| } | |
| class ListType { | |
| public function __construct($listRegexIdentifyer, $listTagOpen, $listTagClose) { | |
| $this->listTagOpen = $listTagOpen; | |
| $this->listTagClose = $listTagClose; | |
| $this->listRegexIdentifyer = $listRegexIdentifyer; | |
| } | |
| } | |
| } |