Compare commits

...

8 Commits

Author SHA1 Message Date
Christophe HENRY b7276e12e3 Removes unuseful case 2021-03-20 23:58:43 +01:00
Christophe HENRY 0e508a7d57 Removes ob_* functions 2021-03-19 17:54:24 +01:00
Christophe HENRY 66720ed63f Changes some items in CHANGELOG 2021-03-19 17:54:21 +01:00
Christophe HENRY 5df9d5ff15 FIX: textDecoration switch not updated 2021-03-19 17:49:21 +01:00
Christophe HENRY cef2417f91
v1.2.0
* Removes "^" to disable text decoration line-wise.
* CSS is no longer incorporated in the HTML page.
* Perform sanity checks against unauthorized file access.
* Properly close tags when the page exists in a non-null mode.
* Split HTML generation in two: parsing and translating.
* Create classes to handle gemtext parsing and translating.
* Create class to generate back gemtext (for future test cases).
* Fix: 404 doesn't occur for an empty file.
* Page 404 fully generated by HtmGem itself.
2021-03-19 10:41:25 +01:00
Christophe HENRY b2e09c54f5 FIX empty 404 and source file access
An empty existing file triggered 404 error.

It was possible to get the source of any file (including .php).
2021-03-18 15:55:49 +01:00
Christophe HENRY 087c2b5e6c Changes the repository from Framasoft to Tildegit
The framasoft Git service will soon disappear.
2021-03-17 22:53:12 +01:00
Christophe HENRY 8710552d27 Removes margin of PRE 2021-03-14 10:48:25 +00:00
5 changed files with 36 additions and 43 deletions

View File

@ -6,16 +6,12 @@ All notable changes to this project will be documented in this file.
## [Unreleased] v3 ## [Unreleased] v3
* cgi-bin? Handle user input * cgi-bin? Handle user input
* Handle client certificates?
* Page caching: dont generate twice an unmodified file. * Page caching: dont generate twice an unmodified file.
* Separate project? Blog infrastructure with templates, style and RSS generator.
* Proxy for remote and local servers.
* Be able to move /htmgem anywhere and (for the Php part) outside the webbrowser scope. * Be able to move /htmgem anywhere and (for the Php part) outside the webbrowser scope.
## [Unreleased] v2 ## [Unreleased] v2
### Security ### Security
* Check url encoding: The filename fetched on disk may differ from that was asked by URL.
* Check unicode capability, UTF16 input, RTL/LTR, etc… * Check unicode capability, UTF16 input, RTL/LTR, etc…
* Manage different type of carriage return: CR CR/LF LF. * Manage different type of carriage return: CR CR/LF LF.
@ -30,10 +26,9 @@ All notable changes to this project will be documented in this file.
## [Unreleased] v1 ## [Unreleased] v1
### Security ### Security
* Check url encoding: The filename fetched on disk may differ from that was asked by URL.
### Development ### Development
* Command line API for script, testing, CI…
* Automated tests like phpunit * Automated tests like phpunit
### User interface ### User interface

View File

@ -95,7 +95,6 @@ a.mailto:before {
} }
pre { pre {
margin: 0 -1rem;
overflow-x: auto; overflow-x: auto;
} }

View File

@ -15,8 +15,8 @@ Gemini est un nouveau protocole internet qui :
``` ```
=> https://gemini.circumlunar.space/ => https://gemini.circumlunar.space/
=> https://framagit.org/Sbgodin/htmgem/-/archive/master/htmgem-master.zip Téléchargez htmgem-master.zip pour linstaller => https://tildegit.org/sbgodin/HtmGem/archive/master.zip Téléchargez la branche courante pour linstaller
=> https://framagit.org/Sbgodin/htmgem Code source, rapports de bug, commentaires… => https://tildegit.org/Sbgodin/htmgem Code source, rapports de bug, commentaires…
=> https://gmi.sbgodin.fr/htmgem Page principale de HtmGem via le web => https://gmi.sbgodin.fr/htmgem Page principale de HtmGem via le web
=> gemini://gmi.sbgodin.fr/htmgem Page principale de HtmGem via Gemini => gemini://gmi.sbgodin.fr/htmgem Page principale de HtmGem via Gemini

View File

@ -27,7 +27,6 @@ $documentRoot = $_SERVER['DOCUMENT_ROOT'];
$filePath = rtrim($_SERVER['DOCUMENT_ROOT'], "/")."/".ltrim($url, "/"); $filePath = rtrim($_SERVER['DOCUMENT_ROOT'], "/")."/".ltrim($url, "/");
switch(true) { switch(true) {
case false:
case !realPath($filePath): case !realPath($filePath):
case !preg_match("/\.gmi$/", $url): # not finishing by .gmi case !preg_match("/\.gmi$/", $url): # not finishing by .gmi
case strpos($filePath, $documentRoot)!==0: # not in web directory case strpos($filePath, $documentRoot)!==0: # not in web directory

View File

@ -107,50 +107,49 @@ class GemtextTranslate_gemtext {
} }
protected function translate() { protected function translate() {
ob_start(); $output = "";
foreach ($this->parsedGemtext as $node) { foreach ($this->parsedGemtext as $node) {
$mode = $node["mode"]; $mode = $node["mode"];
switch($mode) { switch($mode) {
case "": case "":
echo $node["text"]."\n"; $output .= $node["text"]."\n";
break; break;
case "*": case "*":
foreach ($node["texts"] as $text) { foreach ($node["texts"] as $text) {
echo "* $text\n"; $output .= "* $text\n";
} }
break; break;
case "```": case "```":
print("```\n"); $output .= "```\n";
foreach ($node["texts"] as $text) { foreach ($node["texts"] as $text) {
echo "$text\n"; $output .= "$text\n";
} }
print("```\n"); $output .= "```\n";
break; break;
case ">": case ">":
foreach ($node["texts"] as $text) { foreach ($node["texts"] as $text) {
echo "> $text\n"; $output .= "> $text\n";
} }
break; break;
case "=>": case "=>":
$linkText = $node["text"]; $linkText = $node["text"];
if (!empty($linkText)) $linkText = " $linkText"; if (!empty($linkText)) $linkText = " $linkText";
print("=> ".$node["link"].$linkText."\n"); $output .= "=> ".$node["link"].$linkText."\n";
break; break;
case "#": case "#":
case "##": case "##":
case "###": case "###":
print("$mode ".$node["title"]."\n"); $output .= "$mode ".$node["title"]."\n";
break; break;
case "^^^": case "^^^":
print("^^^\n"); $output .= "^^^\n";
break; break;
default: default:
die("Unknown mode: '{$node["mode"]}'\n"); die("Unknown mode: '{$node["mode"]}'\n");
} }
} }
$this->translatedGemtext = ob_get_contents(); $this->translatedGemtext = $output;
ob_end_clean();
} }
public function __toString() { public function __toString() {
@ -168,7 +167,7 @@ class GemtextTranslate_html {
protected $pageTitle = ""; protected $pageTitle = "";
public $translatedGemtext; public $translatedGemtext;
function __construct($parsedGemtext, $textDecorationEnabled=true) { function __construct($parsedGemtext, $textDecoration=true) {
if (empty($parsedGemtext)) if (empty($parsedGemtext))
$parsedGemtext = ""; $parsedGemtext = "";
elseif (is_string($parsedGemtext)) elseif (is_string($parsedGemtext))
@ -177,7 +176,7 @@ class GemtextTranslate_html {
// The text must be parsed // The text must be parsed
$parsedGemtext = gemtextParser($parsedGemtext); $parsedGemtext = gemtextParser($parsedGemtext);
$this->parsedGemtext = $parsedGemtext; $this->parsedGemtext = $parsedGemtext;
$this->translate($textDecorationEnabled); $this->translate($textDecoration);
} }
function addCss($css) { function addCss($css) {
@ -246,7 +245,7 @@ class GemtextTranslate_html {
} }
public function translate($textDecoration=true) { public function translate($textDecoration=true) {
ob_start(); $output = "";
foreach ($this->parsedGemtext as $node) { foreach ($this->parsedGemtext as $node) {
$mode = $node["mode"]; $mode = $node["mode"];
switch($mode) { switch($mode) {
@ -254,27 +253,27 @@ class GemtextTranslate_html {
$text = $node["text"]; $text = $node["text"];
self::htmlPrepare($text); self::htmlPrepare($text);
if ($textDecoration) self::addTextDecoration($text); if ($textDecoration) self::addTextDecoration($text);
echo "<p>$text</p>\n"; $output .= "<p>$text</p>\n";
break; break;
case "*": case "*":
echo "<ul>\n"; $output .= "<ul>\n";
foreach ($node["texts"] as $text) { foreach ($node["texts"] as $text) {
self::htmlPrepare($text); self::htmlPrepare($text);
if ($textDecoration) self::addTextDecoration($text); if ($textDecoration) self::addTextDecoration($text);
print("<li>$text\n"); $output .= "<li>$text\n";
} }
echo "</ul>\n"; $output .= "</ul>\n";
break; break;
case "```": case "```":
$text = implode("\n", $node["texts"]); $text = implode("\n", $node["texts"]);
self::htmlPrepare($text); self::htmlPrepare($text);
echo "<pre>\n$text\n</pre>\n"; $output .= "<pre>\n$text\n</pre>\n";
break; break;
case ">": case ">":
$text = implode("\n", $node["texts"]); $text = implode("\n", $node["texts"]);
self::htmlPrepare($text); self::htmlPrepare($text);
if ($textDecoration) self::addTextDecoration($text); if ($textDecoration) self::addTextDecoration($text);
echo "<blockquote>\n$text\n</blockquote>\n"; $output .= "<blockquote>\n$text\n</blockquote>\n";
break; break;
case "=>": case "=>":
$link = $node["link"]; $link = $node["link"];
@ -289,34 +288,33 @@ class GemtextTranslate_html {
preg_match("/^([^:]+):/", $link, $matches); preg_match("/^([^:]+):/", $link, $matches);
$protocol = @$matches[1]; $protocol = @$matches[1];
if (empty($protocol)) $protocol = "local"; if (empty($protocol)) $protocol = "local";
echo "<p><a class='$protocol' href='$link'>$linkText</a></p>\n"; $output .= "<p><a class='$protocol' href='$link'>$linkText</a></p>\n";
break; break;
case "#": case "#":
$title = $node["title"]; $title = $node["title"];
self::htmlPrepare($title); self::htmlPrepare($title);
if (empty($this->pageTitle)) $this->pageTitle = $title; if (empty($this->pageTitle)) $this->pageTitle = $title;
echo "<h1>$title</h1>\n"; $output .= "<h1>$title</h1>\n";
break; break;
case "##": case "##":
$title = $node["title"]; $title = $node["title"];
self::htmlPrepare($title); self::htmlPrepare($title);
echo "<h2>$title</h2>\n"; $output .= "<h2>$title</h2>\n";
break; break;
case "###": case "###":
$title = $node["title"]; $title = $node["title"];
self::htmlPrepare($title); self::htmlPrepare($title);
echo "<h3>$title</h3>\n"; $output .= "<h3>$title</h3>\n";
break; break;
case "^^^": case "^^^":
$this->textDecorationEnabled = !$this->textDecorationEnabled; $textDecoration = !$textDecoration;
break; break;
default: default:
die("Unknown mode: '{$node["mode"]}'\n"); die("Unknown mode: '{$node["mode"]}'\n");
} }
} }
$this->translatedGemtext = ob_get_contents(); $this->translatedGemtext = $output;
ob_end_clean();
} }
function getFullHtml() { function getFullHtml() {
@ -324,7 +322,7 @@ class GemtextTranslate_html {
$css = array("/htmgem/css/htmgem.css"); $css = array("/htmgem/css/htmgem.css");
else else
$css = $this->cssList; $css = $this->cssList;
echo <<<EOL $output = <<<EOL
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@ -332,14 +330,16 @@ class GemtextTranslate_html {
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
EOL; EOL;
foreach ($css as $c) { foreach ($css as $c) {
echo "<link type='text/css' rel='StyleSheet' href='$c'>\n"; $output .= "<link type='text/css' rel='StyleSheet' href='$c'>\n";
} }
echo <<<EOL $output .= <<<EOL
</head> </head>
<body>\n <body>\n
EOL; EOL;
echo $this->translatedGemtext; $output .= $this->translatedGemtext;
echo "</body>\n</html>\n"; $output .= "</body>\n</html>\n";
echo $output;
} }
public function __toString() { public function __toString() {