mirror of https://tildegit.org/sbgodin/HtmGem.git
Compare commits
No commits in common. "26ad4f7d981c6d2201430dae145e938a57587f6c" and "a4a647d8e83f714364f4fe9a5e215070d0223c81" have entirely different histories.
26ad4f7d98
...
a4a647d8e8
41
index.php
41
index.php
|
@ -1,14 +1,12 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
require_once "lib-htmgem.inc.php";
|
require_once "lib-htmgem.php";
|
||||||
require_once "lib-html.inc.php";
|
|
||||||
|
|
||||||
# The url argument is always absolute compared to the document root.
|
# The url argument is always absolute compared to the document root.
|
||||||
$url = @$_REQUEST["url"];
|
$url = @$_REQUEST["url"];
|
||||||
$urlRewriting = @$_REQUEST["rw"]=="1";
|
$urlRewriting = @$_REQUEST["rw"]=="1";
|
||||||
|
|
||||||
/**
|
/* Installation page
|
||||||
* Installation page
|
|
||||||
*
|
*
|
||||||
* Accessing directly /htmgem will make display the self-hosted documentation
|
* Accessing directly /htmgem will make display the self-hosted documentation
|
||||||
* contained in "index.gmi". If it's removed, display an empty page with a
|
* contained in "index.gmi". If it's removed, display an empty page with a
|
||||||
|
@ -19,16 +17,13 @@ if (empty($url)) {
|
||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
die("<!-- index.gmi missing -->");
|
die("<!-- index.gmi missing -->");
|
||||||
}
|
}
|
||||||
$gt_html = new \htmgem\GemTextTranslate_html(@file_get_contents("index.gmi"), true, "/htmgem");
|
$t = new \htmgem\GemTextTranslate_html(@file_get_contents("index.gmi"), true, "/htmgem");
|
||||||
echo \htmgem\html\getFullHtml($gt_html);
|
echo $t->getFullHtml();
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$documentRoot = $_SERVER['DOCUMENT_ROOT'];
|
$documentRoot = $_SERVER['DOCUMENT_ROOT'];
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides index.gmi if no page given
|
|
||||||
*/
|
|
||||||
if (!preg_match("/\.gmi$/", $url)) {
|
if (!preg_match("/\.gmi$/", $url)) {
|
||||||
if ($url[-1] == "/")
|
if ($url[-1] == "/")
|
||||||
$url = $url."index.gmi";
|
$url = $url."index.gmi";
|
||||||
|
@ -54,14 +49,20 @@ switch(true) {
|
||||||
if ($go404) {
|
if ($go404) {
|
||||||
error_log("HtmGem: 404 $url $filePath");
|
error_log("HtmGem: 404 $url $filePath");
|
||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
$page404 = \htmgem\html\get404GmiPage("Page not found", $url);
|
$page404 = <<<EOF
|
||||||
$gt_html = new \htmgem\GemTextTranslate_html($page404);
|
# ⚠ Page non trouvée
|
||||||
echo \htmgem\html\getFullHtml($gt_html);
|
|
||||||
|
**$url**
|
||||||
|
|
||||||
|
=> .. 🔄 🔄
|
||||||
|
EOF;
|
||||||
|
$t = new \htmgem\GemTextTranslate_html($page404);
|
||||||
|
echo $t->getFullHtml();
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
# to false only if textDecoration=0 in the URL
|
# to false only if textDecoration=0 in the URL
|
||||||
$gt_htmlextDecoration = "0" != @$_REQUEST['textDecoration'];
|
$textDecoration = "0" != @$_REQUEST['textDecoration'];
|
||||||
|
|
||||||
$fileContents = @file_get_contents($filePath);
|
$fileContents = @file_get_contents($filePath);
|
||||||
# Removes the Byte Order Mark
|
# Removes the Byte Order Mark
|
||||||
|
@ -105,11 +106,11 @@ if ($urlRewriting)
|
||||||
$baseUrl = null;
|
$baseUrl = null;
|
||||||
else
|
else
|
||||||
$baseUrl = dirname($url);
|
$baseUrl = dirname($url);
|
||||||
$gt_html = new \htmgem\GemTextTranslate_html($fileContents, $gt_htmlextDecoration, $baseUrl);
|
$t = new \htmgem\GemTextTranslate_html($fileContents, $textDecoration, $baseUrl);
|
||||||
if ("none" == $style) {
|
if ("none" == $style) {
|
||||||
$gt_html->addCss("");
|
$t->addCss("");
|
||||||
} elseif ("/" == @$style[0]) {
|
} elseif ("/" == @$style[0]) {
|
||||||
$gt_html->addCss($style);
|
$t->addCss($style);
|
||||||
} elseif (empty($style)) {
|
} elseif (empty($style)) {
|
||||||
$parts = pathinfo($filePath);
|
$parts = pathinfo($filePath);
|
||||||
$localCss = $parts["filename"].".css";
|
$localCss = $parts["filename"].".css";
|
||||||
|
@ -117,12 +118,12 @@ if ("none" == $style) {
|
||||||
if (file_exists($localCssFilePath)) {
|
if (file_exists($localCssFilePath)) {
|
||||||
# Warning, using htmhem.php?url=… will make $localCss not found
|
# Warning, using htmhem.php?url=… will make $localCss not found
|
||||||
# as the path is relative to htmgem.php and not / !
|
# as the path is relative to htmgem.php and not / !
|
||||||
$gt_html->addCss($localCss);
|
$t->addCss($localCss);
|
||||||
}
|
}
|
||||||
} else { #TODO: regex check for $style
|
} else { #TODO: regex check for $style
|
||||||
$gt_html->addCss("/htmgem/css/$style.css");
|
$t->addCss("/htmgem/css/$style.css");
|
||||||
}
|
}
|
||||||
|
|
||||||
echo \htmgem\html\getFullHtml($gt_html);
|
echo $t->getFullHtml();
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?php declare(strict_types=1);
|
<?php
|
||||||
|
|
||||||
namespace htmgem;
|
namespace htmgem;
|
||||||
|
|
||||||
|
@ -33,10 +33,10 @@ function gemtextParser($fileContents) {
|
||||||
yield array("mode" => "^^^");
|
yield array("mode" => "^^^");
|
||||||
} elseif ("#" == $line1) {
|
} elseif ("#" == $line1) {
|
||||||
preg_match("/^(#{1,3})\s*(.+)?/", $line, $matches);
|
preg_match("/^(#{1,3})\s*(.+)?/", $line, $matches);
|
||||||
yield array("mode" => $matches[1], "title" => trim($matches[2]??""));
|
yield array("mode" => $matches[1], "title" => trim(@$matches[2]));
|
||||||
} elseif ("=>" == $line2) {
|
} elseif ("=>" == $line2) {
|
||||||
preg_match("/^=>\s*([^\s]+)(?:\s+(.*))?$/", $line, $matches);
|
preg_match("/^=>\s*([^\s]+)(?:\s+(.*))?$/", $line, $matches);
|
||||||
yield array("mode" => "=>", "link" => trim($matches[1]??""), "text" => trim($matches[2]??""));
|
yield array("mode" => "=>", "link" => trim(@$matches[1]), "text" => trim(@$matches[2]));
|
||||||
} elseif ("```" == $line3) {
|
} elseif ("```" == $line3) {
|
||||||
preg_match("/^```\s*(.*)$/", $line, $matches);
|
preg_match("/^```\s*(.*)$/", $line, $matches);
|
||||||
$current = array("mode" => "```", "alt" => trim($matches[1]), "texts" => array());
|
$current = array("mode" => "```", "alt" => trim($matches[1]), "texts" => array());
|
||||||
|
@ -197,9 +197,6 @@ class GemtextTranslate_html {
|
||||||
$this->cssList []= $css;
|
$this->cssList []= $css;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCss() { return $this->cssList; }
|
|
||||||
function getTitle() { return $this->pageTitle; }
|
|
||||||
|
|
||||||
const NARROW_NO_BREAK_SPACE = " ";
|
const NARROW_NO_BREAK_SPACE = " ";
|
||||||
const DASHES
|
const DASHES
|
||||||
="‒" # U+2012 Figure Dash
|
="‒" # U+2012 Figure Dash
|
||||||
|
@ -266,20 +263,14 @@ class GemtextTranslate_html {
|
||||||
$text = preg_replace("/ +/", " ", $text);
|
$text = preg_replace("/ +/", " ", $text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected static function resolve_path($path) {
|
||||||
* Resolve $path interpretating / . and ..
|
|
||||||
* @param $path str
|
|
||||||
* @returns "/" if .. goes above the limit
|
|
||||||
*/
|
|
||||||
public static function resolve_path($path) {
|
|
||||||
if (empty($path)) return "";
|
|
||||||
$absolute = "/"==$path[0];
|
$absolute = "/"==$path[0];
|
||||||
$parts = array_filter(explode("/", $path), 'strlen');
|
$parts = array_filter(explode("/", $path), 'strlen');
|
||||||
$chuncks = array();
|
$chuncks = array();
|
||||||
foreach ($parts as $part) {
|
foreach ($parts as $part) {
|
||||||
if ('.' == $part) continue;
|
if ('.' == $part) continue;
|
||||||
if ('..' == $part) {
|
if ('..' == $part) {
|
||||||
if (is_null(array_pop($chuncks))) return "/";
|
array_pop($chuncks);
|
||||||
} else {
|
} else {
|
||||||
$chuncks[] = $part;
|
$chuncks[] = $part;
|
||||||
}
|
}
|
||||||
|
@ -383,6 +374,34 @@ class GemtextTranslate_html {
|
||||||
$this->translatedGemtext = $output;
|
$this->translatedGemtext = $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFullHtml() {
|
||||||
|
if (!$this->cssList)
|
||||||
|
$css = array("/htmgem/css/htmgem.css");
|
||||||
|
else
|
||||||
|
$css = $this->cssList;
|
||||||
|
$output = <<<EOL
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{$this->pageTitle}</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
EOL;
|
||||||
|
foreach ($css as $c) {
|
||||||
|
$output .= "\n<link type='text/css' rel='StyleSheet' href='$c'>\n";
|
||||||
|
}
|
||||||
|
$output .= <<<EOL
|
||||||
|
</head>
|
||||||
|
<body>\n
|
||||||
|
EOL;
|
||||||
|
$output .= $this->translatedGemtext;
|
||||||
|
$output .= "</body>\n</html>\n";
|
||||||
|
|
||||||
|
echo $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString() {
|
||||||
|
return $this->translatedGemtext;
|
||||||
|
}
|
||||||
} // GemTextTranslate_html
|
} // GemTextTranslate_html
|
||||||
|
|
||||||
?>
|
?>
|
|
@ -1,44 +0,0 @@
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace htmgem\html;
|
|
||||||
|
|
||||||
mb_internal_encoding("UTF-8");
|
|
||||||
mb_regex_encoding("UTF-8");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a full HTML page base
|
|
||||||
*/
|
|
||||||
function getFullHtml(\htmgem\GemtextTranslate_html $gt_html) {
|
|
||||||
$css = $gt_html->getCss();
|
|
||||||
if (!$css) $css = array("/htmgem/css/htmgem.css");
|
|
||||||
$output = <<<EOL
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="">
|
|
||||||
<head>
|
|
||||||
<title>{$gt_html->getTitle()}</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
EOL;
|
|
||||||
foreach ($css as $c) {
|
|
||||||
$output .= "\n<link type='text/css' rel='StyleSheet' href='$c'>\n";
|
|
||||||
}
|
|
||||||
$output .= <<<EOL
|
|
||||||
</head>
|
|
||||||
<body>\n
|
|
||||||
EOL;
|
|
||||||
$output .= $gt_html->translatedGemtext;
|
|
||||||
$output .= "</body>\n</html>\n";
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
function get404Gmipage($message, $url) {
|
|
||||||
return <<<EOF
|
|
||||||
# ⚠ $message
|
|
||||||
|
|
||||||
**$url**
|
|
||||||
|
|
||||||
=> .. 🔄 🔄
|
|
||||||
EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
$fileName = $argv[1];
|
$fileName = $argv[1];
|
||||||
|
|
||||||
require_once dirname(__FILE__)."/../lib-htmgem.inc.php";
|
require_once dirname(__FILE__)."/../lib-htmgem.php";
|
||||||
|
|
||||||
$text = file_get_contents($fileName);
|
$text = file_get_contents($fileName);
|
||||||
$parsedGemtext = \htmgem\gemtextParser($text);
|
$parsedGemtext = \htmgem\gemtextParser($text);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
$fileName = $argv[1];
|
$fileName = $argv[1];
|
||||||
|
|
||||||
require_once dirname(__FILE__)."/../../lib-htmgem.inc.php";
|
require_once dirname(__FILE__)."/../../lib-htmgem.php";
|
||||||
|
|
||||||
$text = file_get_contents($fileName);
|
$text = file_get_contents($fileName);
|
||||||
$gt_gemtext = new \htmgem\GemtextTranslate_gemtext($text);
|
$gt_gemtext = new \htmgem\GemtextTranslate_gemtext($text);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
$fileName = $argv[1];
|
$fileName = $argv[1];
|
||||||
|
|
||||||
require_once dirname(__FILE__)."/../../lib-htmgem.inc.php";
|
require_once dirname(__FILE__)."/../../lib-htmgem.php";
|
||||||
|
|
||||||
$text = file_get_contents($fileName);
|
$text = file_get_contents($fileName);
|
||||||
$gt_gemtext = new \htmgem\GemtextTranslate_html($text);
|
$gt_gemtext = new \htmgem\GemtextTranslate_html($text);
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
<?php declare(strict_types=1);
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
|
|
||||||
require_once dirname(__FILE__)."/../lib-htmgem.inc.php";
|
|
||||||
|
|
||||||
final class miscTest extends TestCase {
|
|
||||||
|
|
||||||
public function test_resolveLink(): void {
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path(""),
|
|
||||||
"",
|
|
||||||
"empty link"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("test"),
|
|
||||||
"test",
|
|
||||||
"single word"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path(" "),
|
|
||||||
" ",
|
|
||||||
"single space"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path(" A B "),
|
|
||||||
" A B ",
|
|
||||||
"several space"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("/"),
|
|
||||||
"/",
|
|
||||||
"one slash"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("//"),
|
|
||||||
"/",
|
|
||||||
"two slashes"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("/////"),
|
|
||||||
"/",
|
|
||||||
"five slashes"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("one/"),
|
|
||||||
"one",
|
|
||||||
"strip the last slash"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("/two"),
|
|
||||||
"/two",
|
|
||||||
"slash at the beginning"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("/two/"),
|
|
||||||
"/two",
|
|
||||||
"slash at the beginning and the end"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("one/two/"),
|
|
||||||
"one/two",
|
|
||||||
"only the last slash remains"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("one/two/three//"),
|
|
||||||
"one/two/three",
|
|
||||||
"strip the last slashes"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("one/../"),
|
|
||||||
"",
|
|
||||||
"empty one"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("one/two/../"),
|
|
||||||
"one",
|
|
||||||
"empty one two"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("one/two/../.."),
|
|
||||||
"",
|
|
||||||
"empty one two twice"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("one/../two/./../three"),
|
|
||||||
"three",
|
|
||||||
"waltz"
|
|
||||||
);
|
|
||||||
$this->assertSame(
|
|
||||||
\htmgem\GemtextTranslate_html::resolve_path("one/../.."),
|
|
||||||
"/",
|
|
||||||
"directory traversal"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
require_once dirname(__FILE__)."/../lib-htmgem.inc.php";
|
require_once dirname(__FILE__)."/../lib-htmgem.php";
|
||||||
|
|
||||||
function parse($text): array {
|
function parse($text): array {
|
||||||
return iterator_to_array(\htmgem\gemtextParser($text));
|
return iterator_to_array(\htmgem\gemtextParser($text));
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
$dirname_file = dirname(__FILE__);
|
$dirname_file = dirname(__FILE__);
|
||||||
require_once "$dirname_file/../lib-htmgem.inc.php";
|
require_once "$dirname_file/../lib-htmgem.php";
|
||||||
require_once "$dirname_file/utils.inc.php";
|
require_once "$dirname_file/utils.inc.php";
|
||||||
|
|
||||||
function translate($text): string {
|
function translate($text): string {
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
$dirname_file = dirname(__FILE__);
|
$dirname_file = dirname(__FILE__);
|
||||||
require_once "$dirname_file/../lib-htmgem.inc.php";
|
require_once "$dirname_file/../lib-htmgem.php";
|
||||||
require_once "$dirname_file/utils.inc.php";
|
require_once "$dirname_file/utils.inc.php";
|
||||||
|
|
||||||
function translateHtml($text): string {
|
function translateHtml($text): string {
|
||||||
$gt_html = new htmgem\GemtextTranslate_html($text);
|
return strval(new htmgem\GemtextTranslate_html($text));
|
||||||
return strval($gt_html->translatedGemtext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final class translateToHtmlTest extends TestCase {
|
final class translateToHtmlTest extends TestCase {
|
||||||
|
|
Loading…
Reference in New Issue