First quasi-fonctionnal markdown version
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@1284 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
137
markdown.php
137
markdown.php
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
function debugMKD ($msg)
|
function debugMKD ($msg)
|
||||||
{
|
{
|
||||||
//return;
|
return;
|
||||||
$trace = debug_backtrace();
|
$trace = debug_backtrace();
|
||||||
$back = reset ($trace);
|
$back = reset ($trace);
|
||||||
file_put_contents ("/tmp/debug", "[".$back["line"]."] $msg\n", FILE_APPEND);
|
file_put_contents ("/tmp/debug", "[".$back["line"]."] $msg\n", FILE_APPEND);
|
||||||
@@ -23,6 +23,8 @@ class markdown
|
|||||||
$search = array ();
|
$search = array ();
|
||||||
$replace = array ();
|
$replace = array ();
|
||||||
|
|
||||||
|
$mark = htmlentities ($mark, ENT_QUOTES);
|
||||||
|
|
||||||
// SEPARATORS : *** --- ___ * * * - - - _ _ _
|
// SEPARATORS : *** --- ___ * * * - - - _ _ _
|
||||||
// Must be placed before EMPHASIS
|
// Must be placed before EMPHASIS
|
||||||
$search[] = "/\\n^[*_-] ?[*_-] ?[*_-]$/Um";
|
$search[] = "/\\n^[*_-] ?[*_-] ?[*_-]$/Um";
|
||||||
@@ -38,7 +40,7 @@ class markdown
|
|||||||
$search[] = "/\\n?\`((\\n|.)+)\`/Um";
|
$search[] = "/\\n?\`((\\n|.)+)\`/Um";
|
||||||
$replace[] = " <code>\\1</code>";
|
$replace[] = " <code>\\1</code>";
|
||||||
|
|
||||||
// LINKS
|
// LINKS
|
||||||
// [Google Site](http://google.fr/ "With help bubble")
|
// [Google Site](http://google.fr/ "With help bubble")
|
||||||
$search[] = "(\[(.+)\]\((https?://.+) \"(.+)\"\))";
|
$search[] = "(\[(.+)\]\((https?://.+) \"(.+)\"\))";
|
||||||
$replace[] = "<a href='\\2' title='\\3'>\\1</a>";
|
$replace[] = "<a href='\\2' title='\\3'>\\1</a>";
|
||||||
@@ -80,15 +82,17 @@ class markdown
|
|||||||
$replace[] = "</p>\n<h1>\\1</h1>\n<p>";
|
$replace[] = "</p>\n<h1>\\1</h1>\n<p>";
|
||||||
// Titre2
|
// Titre2
|
||||||
// ------
|
// ------
|
||||||
$search[] = "/\\n^(.+)\\n--+$\\n/Um";
|
$search[] = "/^(.+)\\n--+$\\n/Um";
|
||||||
$replace[] = "</p>\n<h2>\\1</h2>\n<p>";
|
$replace[] = "\n<h2>\\1</h2>\n";
|
||||||
|
|
||||||
// End of line with double space : <br/>
|
// End of line with double space : <br/>
|
||||||
$search[] = "/( )$/Um"; $replace[] = "<br/>";
|
$search[] = "/( )$/Um"; $replace[] = "<br/>";
|
||||||
|
|
||||||
|
// 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 = preg_replace ($search, $replace, $mark);
|
||||||
|
|
||||||
$res = $this->paragraph ($res);
|
$res = $this->paragraph ($res);
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +104,7 @@ class markdown
|
|||||||
$mark = trim ($mark);
|
$mark = trim ($mark);
|
||||||
if ($mark === "")
|
if ($mark === "")
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
$spacer = " ";
|
$spacer = " ";
|
||||||
$res = "";
|
$res = "";
|
||||||
// P, OL, UL (but not LI !)
|
// P, OL, UL (but not LI !)
|
||||||
@@ -110,32 +115,45 @@ class markdown
|
|||||||
// All the HTML stack (with LI)
|
// All the HTML stack (with LI)
|
||||||
$htmlStack = array ();
|
$htmlStack = array ();
|
||||||
$lines = explode ("\n", $mark);
|
$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);
|
$type = $this->paragraphType ($line);
|
||||||
debugMKD ( "DEBUT: Type='$type'");
|
debugMKD ("DEBUT: Type='$type'");
|
||||||
$matches = array ();
|
$matches = array ();
|
||||||
switch ($type)
|
switch ($type)
|
||||||
{
|
{
|
||||||
case "ol" :
|
case "ol" :
|
||||||
preg_match ("/^( *)[0-9]+\. +(.*)/", $line, $matches);
|
preg_match ("/^( *)[0-9]+\. +(.*)/", $line, $matches);
|
||||||
$lineTxt = $matches[2];
|
if (!isset ($matches[2]))
|
||||||
|
$lineTxt = $line;
|
||||||
|
else
|
||||||
|
$lineTxt = $matches[2];
|
||||||
break ;
|
break ;
|
||||||
case "ul" :
|
case "ul" :
|
||||||
preg_match ("/^( *)[-+*] +(.*)/", $line, $matches);
|
preg_match ("/^( *)[-+*] +(.*)/", $line, $matches);
|
||||||
$lineTxt = $matches[2];
|
if (!isset ($matches[2]))
|
||||||
|
$lineTxt = $line;
|
||||||
|
else
|
||||||
|
$lineTxt = $matches[2];
|
||||||
break ;
|
break ;
|
||||||
default:
|
default:
|
||||||
$lineTxt = $line;
|
$lineTxt = $line;
|
||||||
}
|
}
|
||||||
|
|
||||||
$indent = strspn ($line, " ");
|
$indent = strspn ($line, " ");
|
||||||
debugMKD ( "DEBUT: Indent='$indent'");
|
debugMKD ("DEBUT: Indent='$indent'");
|
||||||
|
|
||||||
// Spacing
|
// Spacing
|
||||||
if ($indent < end ($indentStack))
|
if ($indent < end ($indentStack))
|
||||||
{
|
{
|
||||||
debugMKD ( "DEB1 : Ending of block");
|
debugMKD ("DEB1 : Ending of block");
|
||||||
if (end ($htmlStack) === "li")
|
if (end ($htmlStack) === "li")
|
||||||
{
|
{
|
||||||
debugMKD ("Pending <Li> : closing");
|
debugMKD ("Pending <Li> : closing");
|
||||||
@@ -143,9 +161,19 @@ class markdown
|
|||||||
$res .= "</li>";
|
$res .= "</li>";
|
||||||
array_pop ($htmlStack);
|
array_pop ($htmlStack);
|
||||||
}
|
}
|
||||||
$oldType = array_pop ($typeStack);
|
|
||||||
debugMKD (str_repeat (" ", end ($indentStack))."</$oldType>");
|
$oldType = array_pop ($typeStack);
|
||||||
$res .= "\n".str_repeat (" ", end ($indentStack))."</$oldType>";
|
if ($oldType === "code")
|
||||||
|
{
|
||||||
|
debugMKD (str_repeat (" ", end ($indentStack))."</code></pre>");
|
||||||
|
$res .= str_repeat (" ", end ($indentStack))."</code></pre>\n";
|
||||||
|
array_pop ($htmlStack);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugMKD (str_repeat (" ", end ($indentStack))."</$oldType>");
|
||||||
|
$res .= str_repeat (" ", end ($indentStack))."</$oldType>\n";
|
||||||
|
}
|
||||||
array_pop ($htmlStack);
|
array_pop ($htmlStack);
|
||||||
array_pop ($indentStack);
|
array_pop ($indentStack);
|
||||||
if ($type === "ol" || $type === "ul")
|
if ($type === "ol" || $type === "ul")
|
||||||
@@ -155,6 +183,7 @@ class markdown
|
|||||||
$res .= "\n</li>";
|
$res .= "\n</li>";
|
||||||
array_pop ($htmlStack);
|
array_pop ($htmlStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type === "")
|
if ($type === "")
|
||||||
{
|
{
|
||||||
debugMKD ("DEB3 : End of block");
|
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")
|
if (end ($htmlStack) === "li")
|
||||||
{
|
{
|
||||||
debugMKD ("Pending <Li> : closing");
|
debugMKD ("Pending <Li> : closing");
|
||||||
@@ -174,11 +203,11 @@ class markdown
|
|||||||
$res .= "</li>";
|
$res .= "</li>";
|
||||||
array_pop ($htmlStack);
|
array_pop ($htmlStack);
|
||||||
}
|
}
|
||||||
debugMKD ( "DEB1 : Continuous block $type/".end ($typeStack)." SECOND");
|
|
||||||
if ($type !== end ($typeStack))
|
if ($type !== end ($typeStack))
|
||||||
{
|
{
|
||||||
debugMKD ( "DEB2 : Continuous Block but type change");
|
debugMKD ("DEB2 : Continuous Block but type change");
|
||||||
$oldType = array_pop ($typeStack);
|
$oldType = array_pop ($typeStack);
|
||||||
debugMKD (str_repeat (" ", end ($indentStack))."</$oldType>");
|
debugMKD (str_repeat (" ", end ($indentStack))."</$oldType>");
|
||||||
$res .= "\n".str_repeat (" ", end ($indentStack))."</$oldType>";
|
$res .= "\n".str_repeat (" ", end ($indentStack))."</$oldType>";
|
||||||
array_pop ($htmlStack);
|
array_pop ($htmlStack);
|
||||||
@@ -194,59 +223,95 @@ class markdown
|
|||||||
{
|
{
|
||||||
debugMKD ("DEB2 : Adding li");
|
debugMKD ("DEB2 : Adding li");
|
||||||
$htmlStack[] = "li";
|
$htmlStack[] = "li";
|
||||||
debugMKD ( str_repeat (" ", $indent)."<li>");
|
debugMKD (str_repeat (" ", $indent)."<li>");
|
||||||
$res .= "\n".str_repeat (" ", $indent)."<li>";
|
$res .= "\n".str_repeat (" ", $indent)."<li>";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
// <code></code> continue until the end of paragraph
|
||||||
|
debugMKD ("DEB1 : Starting a new block");
|
||||||
|
if ($type === "")
|
||||||
|
{
|
||||||
|
debugMKD ("No type : skipped");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (end ($indentStack))
|
if (end ($indentStack))
|
||||||
array_pop ($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><code";
|
||||||
|
$htmlStack[] = "pre";
|
||||||
|
$htmlStack[] = "code";
|
||||||
|
array_push ($typeStack, "code");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$htmlStack[] = $type;
|
||||||
|
array_push ($typeStack, $type);
|
||||||
|
}
|
||||||
array_push ($indentStack, $indent);
|
array_push ($indentStack, $indent);
|
||||||
array_push ($typeStack, $type);
|
debugMKD (str_repeat (" ", $indent)."<$type>");
|
||||||
debugMKD ( str_repeat (" ", $indent)."<$type>");
|
|
||||||
$res .= "\n".str_repeat (" ", $indent)."<$type>";
|
$res .= "\n".str_repeat (" ", $indent)."<$type>";
|
||||||
$htmlStack[] = $type;
|
|
||||||
if ($type === "ol" || $type === "ul")
|
if ($type === "ol" || $type === "ul")
|
||||||
{
|
{
|
||||||
debugMKD ("DEB2 : Adding li");
|
debugMKD ("DEB2 : Adding li");
|
||||||
$htmlStack[] = "li";
|
$htmlStack[] = "li";
|
||||||
debugMKD ( str_repeat (" ", $indent)."<li>");
|
debugMKD (str_repeat (" ", $indent)."<li>");
|
||||||
$res .= "\n".str_repeat (" ", $indent)."<li>";
|
$res .= "\n".str_repeat (" ", $indent)."<li>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debugMKD ("$lineTxt");
|
if ($type === "" && end ($indentStack))
|
||||||
$res .= "$lineTxt";
|
{
|
||||||
|
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);
|
$htmlStack = array_reverse ($htmlStack);
|
||||||
foreach ($htmlStack as $type)
|
foreach ($htmlStack as $type)
|
||||||
{
|
{
|
||||||
debugMKD ( "FIN</$type>");
|
debugMKD ("FIN</$type>");
|
||||||
$res .= "</$type>\n";
|
$res .= "</$type>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
debugMKD ( "-----------\n");
|
debugMKD ("-----------\n");
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the Type of object in the provided line
|
/** Return the Type of object in the provided line
|
||||||
p, ul, ol, code */
|
p, ul, ol, code */
|
||||||
private function paragraphType ($line)
|
private function paragraphType ($line)
|
||||||
{
|
{
|
||||||
$line = ltrim ($line);
|
|
||||||
if (! isset ($line{0}))
|
if (! isset ($line{0}))
|
||||||
return "";
|
return "";
|
||||||
if ($line{0} === "*" || $line{0} === "-" || $line{0} === "+")
|
if (preg_match ("/^[ \t]*[+*-] /", $line) === 1)
|
||||||
return "ul";
|
return "ul";
|
||||||
if (preg_match ("/^[0-9]+\. /", $line) === 1)
|
if (preg_match ("/^[ \t]*[0-9]+\. /", $line) === 1)
|
||||||
return "ol";
|
return "ol";
|
||||||
|
if (preg_match ("/^( |\t)+/", $line) === 1)
|
||||||
|
return "code";
|
||||||
return "p";
|
return "p";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user