From 6ed9dc84a94e9ffe02af4a7e43d284bb511d3a00 Mon Sep 17 00:00:00 2001
From: Dominique Fournier
Date: Sat, 10 May 2014 21:10:30 +0000
Subject: [PATCH] First quasi-fonctionnal markdown version
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@1284 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
---
markdown.php | 137 +++++++++++++++++++++++++++++++++++++--------------
1 file changed, 101 insertions(+), 36 deletions(-)
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))."$oldType>");
- $res .= "\n".str_repeat (" ", end ($indentStack))."$oldType>";
+
+ $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))."$oldType>");
+ $res .= str_repeat (" ", end ($indentStack))."$oldType>\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))."$oldType>");
$res .= "\n".str_repeat (" ", end ($indentStack))."$oldType>";
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))."$oldType>");
+ $res .= str_repeat (" ", end ($indentStack))."$oldType>";
+ 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))."$oldType>");
+ $res .= "\n".str_repeat (" ", end ($indentStack))."$oldType>";
+ 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$type>");
+ debugMKD ("FIN$type>");
$res .= "$type>\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";
}
}