diff --git a/markdown.php b/markdown.php index 5402a14..6f50985 100644 --- a/markdown.php +++ b/markdown.php @@ -5,7 +5,7 @@ function debugMKD ($msg) { - //return; + return; $trace = debug_backtrace(); $back = reset ($trace); file_put_contents ("/tmp/debug", "[".$back["line"]."] $msg\n", FILE_APPEND); @@ -23,6 +23,8 @@ class markdown $search = array (); $replace = array (); + $mark = htmlentities ($mark, ENT_QUOTES); + // SEPARATORS : *** --- ___ * * * - - - _ _ _ // Must be placed before EMPHASIS $search[] = "/\\n^[*_-] ?[*_-] ?[*_-]$/Um"; @@ -38,7 +40,7 @@ class markdown $search[] = "/\\n?\`((\\n|.)+)\`/Um"; $replace[] = " \\1"; - // LINKS + // LINKS // [Google Site](http://google.fr/ "With help bubble") $search[] = "(\[(.+)\]\((https?://.+) \"(.+)\"\))"; $replace[] = "\\1"; @@ -80,15 +82,17 @@ class markdown $replace[] = "

\n

\\1

\n

"; // Titre2 // ------ - $search[] = "/\\n^(.+)\\n--+$\\n/Um"; - $replace[] = "

\n

\\1

\n

"; + $search[] = "/^(.+)\\n--+$\\n/Um"; + $replace[] = "\n

\\1

\n"; // End of line with double space :
$search[] = "/( )$/Um"; $replace[] = "
"; + // End of line with continuous on second line : add blank +// $search[] = "/(.)\\n([A-Za-z0-9])/Um"; $replace[] = "\\1 \\2"; $res = preg_replace ($search, $replace, $mark); - $res = $this->paragraph ($res); + return $res; } @@ -100,6 +104,7 @@ class markdown $mark = trim ($mark); if ($mark === "") return ""; + $spacer = " "; $res = ""; // P, OL, UL (but not LI !) @@ -110,32 +115,45 @@ class markdown // All the HTML stack (with LI) $htmlStack = array (); $lines = explode ("\n", $mark); - foreach ($lines as $line) + foreach ($lines as $nb=>$line) { - debugMKD ( "DEBUT:$line"); + debugMKD ("DEBUT:$line"); + if (substr (ltrim ($line), 0, 1) === "<") + { + debugMKD ("HTML : Skipped"); + $res .= $line; + continue; + } $type = $this->paragraphType ($line); - debugMKD ( "DEBUT: Type='$type'"); + debugMKD ("DEBUT: Type='$type'"); $matches = array (); switch ($type) { case "ol" : preg_match ("/^( *)[0-9]+\. +(.*)/", $line, $matches); - $lineTxt = $matches[2]; + if (!isset ($matches[2])) + $lineTxt = $line; + else + $lineTxt = $matches[2]; break ; case "ul" : preg_match ("/^( *)[-+*] +(.*)/", $line, $matches); - $lineTxt = $matches[2]; + if (!isset ($matches[2])) + $lineTxt = $line; + else + $lineTxt = $matches[2]; break ; default: $lineTxt = $line; } + $indent = strspn ($line, " "); - debugMKD ( "DEBUT: Indent='$indent'"); + debugMKD ("DEBUT: Indent='$indent'"); // Spacing if ($indent < end ($indentStack)) { - debugMKD ( "DEB1 : Ending of block"); + debugMKD ("DEB1 : Ending of block"); if (end ($htmlStack) === "li") { debugMKD ("Pending
  • : closing"); @@ -143,9 +161,19 @@ class markdown $res .= "
  • "; array_pop ($htmlStack); } - $oldType = array_pop ($typeStack); - debugMKD (str_repeat (" ", end ($indentStack)).""); - $res .= "\n".str_repeat (" ", end ($indentStack)).""; + + $oldType = array_pop ($typeStack); + if ($oldType === "code") + { + debugMKD (str_repeat (" ", end ($indentStack)).""); + $res .= str_repeat (" ", end ($indentStack))."\n"; + array_pop ($htmlStack); + } + else + { + debugMKD (str_repeat (" ", end ($indentStack)).""); + $res .= str_repeat (" ", end ($indentStack))."\n"; + } array_pop ($htmlStack); array_pop ($indentStack); if ($type === "ol" || $type === "ul") @@ -155,6 +183,7 @@ class markdown $res .= "\n"; array_pop ($htmlStack); } + if ($type === "") { debugMKD ("DEB3 : End of block"); @@ -164,9 +193,9 @@ class markdown } } - if ($indent == end ($indentStack)) + if ($indent == end ($indentStack) && $type !== "" && end ($typeStack)) { - debugMKD ( "DEB1 : Continuous block $type/".end ($typeStack)); + debugMKD ("DEB1 : Continuous block $type/".end ($typeStack)); if (end ($htmlStack) === "li") { debugMKD ("Pending
  • : closing"); @@ -174,11 +203,11 @@ class markdown $res .= "
  • "; array_pop ($htmlStack); } - debugMKD ( "DEB1 : Continuous block $type/".end ($typeStack)." SECOND"); + if ($type !== end ($typeStack)) { - debugMKD ( "DEB2 : Continuous Block but type change"); - $oldType = array_pop ($typeStack); + debugMKD ("DEB2 : Continuous Block but type change"); + $oldType = array_pop ($typeStack); debugMKD (str_repeat (" ", end ($indentStack)).""); $res .= "\n".str_repeat (" ", end ($indentStack)).""; array_pop ($htmlStack); @@ -194,59 +223,95 @@ class markdown { debugMKD ("DEB2 : Adding li"); $htmlStack[] = "li"; - debugMKD ( str_repeat (" ", $indent)."
  • "); + debugMKD (str_repeat (" ", $indent)."
  • "); $res .= "\n".str_repeat (" ", $indent)."
  • "; } } - if ($indent > end ($indentStack)) + if ($indent > end ($indentStack) && end ($typeStack) !== "code") { - debugMKD ( "DEB1 : Starting a new block"); + // The code indentation should not be parsed as a new code : the + // continue until the end of paragraph + debugMKD ("DEB1 : Starting a new block"); + if ($type === "") + { + debugMKD ("No type : skipped"); + continue; + } + if (end ($indentStack)) array_pop ($indentStack); + if ($type === "code") + { + // Code need a pre before code + if (end ($typeStack)) + { + debugMKD ("DEB2 : CODE : Close older HTML"); + $oldType = array_pop ($typeStack); + debugMKD (str_repeat (" ", end ($indentStack)).""); + $res .= str_repeat (" ", end ($indentStack)).""; + array_pop ($htmlStack); + } + $type = "pre>"); + debugMKD (str_repeat (" ", $indent)."<$type>"); $res .= "\n".str_repeat (" ", $indent)."<$type>"; - $htmlStack[] = $type; if ($type === "ol" || $type === "ul") { debugMKD ("DEB2 : Adding li"); $htmlStack[] = "li"; - debugMKD ( str_repeat (" ", $indent)."
  • "); + debugMKD (str_repeat (" ", $indent)."
  • "); $res .= "\n".str_repeat (" ", $indent)."
  • "; } } - debugMKD ("$lineTxt"); - $res .= "$lineTxt"; + if ($type === "" && end ($indentStack)) + { + debugMKD ("DEB2 : Empty type"); + $oldType = array_pop ($typeStack); + debugMKD (str_repeat (" ", end ($indentStack)).""); + $res .= "\n".str_repeat (" ", end ($indentStack)).""; + array_pop ($htmlStack); + } + debugMKD ("$lineTxt"); + $res .= "$lineTxt\n"; } - debugMKD ( "DEB1 : End of loop"); + debugMKD ("DEB1 : End of loop"); $htmlStack = array_reverse ($htmlStack); foreach ($htmlStack as $type) { - debugMKD ( "FIN"); + debugMKD ("FIN"); $res .= "\n"; } - debugMKD ( "-----------\n"); + debugMKD ("-----------\n"); return $res; } - /** Return the Type of object in the provided line + /** Return the Type of object in the provided line p, ul, ol, code */ private function paragraphType ($line) { - $line = ltrim ($line); if (! isset ($line{0})) return ""; - if ($line{0} === "*" || $line{0} === "-" || $line{0} === "+") + if (preg_match ("/^[ \t]*[+*-] /", $line) === 1) return "ul"; - if (preg_match ("/^[0-9]+\. /", $line) === 1) + if (preg_match ("/^[ \t]*[0-9]+\. /", $line) === 1) return "ol"; + if (preg_match ("/^( |\t)+/", $line) === 1) + return "code"; return "p"; } }