Installation de HtmGem
\n\n";
die();
}
######################################## /Installation page
# Removes the headling and trailling slashes, to be sure there's not any.
$filePath = rtrim($_SERVER['DOCUMENT_ROOT'], "/")."/".ltrim($url, "/");
$fileContents = @file_get_contents($filePath);
######################################## 404 page
if (empty($fileContents)) {
error_log("HtmGem: 404 $url $filePath");
http_response_code(404); ?>
$url 🔄
=> /
EOF;
echo translateGemToHtml($text404);
echo "\n";
die();
}
######################################## /404 page
# Removes the Byte Order Mark
$fileContents = preg_replace("/\xEF\xBB\xBF/", "", $fileContents);
/**
* Replaces markups things like __underlined__ to underlined.
* @param $instruction the characters to replace, ex. _
* @param $markup the markup to replace to, ex. "u" to get …
* @param &$text where to replace.
*/
function markupPreg($instruction, $markup, &$text) {
$output = $text;
# Replaces couples "__word__" into "word".
$output = mb_ereg_replace("${instruction}(.+?)${instruction}", "<{$markup}>\\1{$markup}>", $output);
# Replaces a remaining __ into "…" to the end of the line.
$output = mb_ereg_replace("${instruction}(.+)?", "<{$markup}>\\1{$markup}>", $output);
$text = $output;
}
/**
* Adds text attributes sucj as underline, bold, … to $line
* @param $line the line to process
*/
function addTextAttributes(&$line) {
global $textDecoration;
if (!$textDecoration) return;
markupPreg("__", "u", $line);
markupPreg("\*\*", "strong", $line);
markupPreg("//", "em", $line);
markupPreg("~~", "del", $line);
}
/**
* Prepares the raw text to be displayed in HTML environment:
* * Escapes the HTML entities yet contained in the Gemtext.
* * Puts thin unbrakable spaces before some characters.
* @param $text1, $text2 texts to process
*/
function htmlPrepare(&$text) {
$text = htmlspecialchars($text, ENT_HTML5|ENT_NOQUOTES, "UTF-8", false);
$text = mb_ereg_replace("\ ([?!:;»€$])", NARROW_NO_BREAK_SPACE."\\1", $text);
$text = mb_ereg_replace("([«])\ ", "\\1".NARROW_NO_BREAK_SPACE, $text); # Espace fine insécable
# Warning: using a monospace font editor may not display dashes as they should be!
# Adds no-break spaces to stick the (EM/EN dashes) to words : aaaaaa – bb – ccccc ==> aaaaaa –$bb$– ccccc
$text = mb_ereg_replace("([".DASHES."]) ([^".DASHES.".]+) ([".DASHES."])", "\\1".NARROW_NO_BREAK_SPACE."\\2".NARROW_NO_BREAK_SPACE."\\3", $text);
# Adds no-break space to stick the (EM/EN dashes) to words : aaaaaa – bb. ==> aaaaaa –$bb.
$text = mb_ereg_replace("([—–]) ([^.]+)\.", "\\1".NARROW_NO_BREAK_SPACE."\\2.", $text);
}
function translateGemToHtml($fileContents) {
$fileLines = preg_split("/\n/", $fileContents);
if (empty($fileLines[-1])) array_pop($fileLines); # Don't output a last empty line
ob_start();
$mode = null;
$mode_textAttributes = true;
foreach ($fileLines as $line) {
$reDoCount = 0;
$mode_textAttributes_temp = false;
while (true) {
if ($reDoCount>2) {
error_log("HtmGem: Too many loops, mode == '$mode'");
$mode = null;
$reDoCount = 0;
break;
}
$reDoCount += 1;
$line1 = substr($line, 0, 1); // $line can be modified
$line2 = substr($line, 0, 2); // in the meantime.
$line3 = substr($line, 0, 3);
if (is_null($mode)) {
if (empty($line)) {
echo "
".$li."\n";
}
} else {
echo "\n";
$mode = null;
continue;
}
} else {
die("Unexpected mode: $mode!");
}
}
break; // exits the while(true) as no continue occured
} // while(true)
}
$html = ob_get_contents();
ob_clean();
return $html;
}
# Gets the page title: the first occurrence with # at the line start
mb_ereg("#\s*([^\n]+)\n", $fileContents, $matches);
$page_title = @$matches[1];
###################################### CSS Management
/**
* if &style=source displays the source directly and stops.
* if there's a filename.css besides filename.gmi, use the css and stops.
* if &style= then embbed the default style, and stops.
* if &style= then use htmgem/word.css
* if &style=/… then use the … as as stylesheet.
**/
if ("source" == $style) {
$basename = basename($filePath);
header("Cache-Control: public");
header("Content-Disposition: attachment; filename=$basename");
header("Content-Type: text/plain");
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
exit();
} elseif ("pre" == $style) {
$fileContents = htmlspecialchars($fileContents, ENT_HTML5|ENT_NOQUOTES, "UTF-8", false);
echo <<$page_title
$fileContents
EOL;
} else {
$parts = pathinfo($filePath);
$localCss = $parts["filename"].".css";
$localCssFilePath = $parts["dirname"]."/".$localCss;
if (file_exists($localCssFilePath)) {
# Warning, using htmhem.php?url=… will make $localCss not found
# as the path is relative to htmgem.php and not / !
$cssContent = "";
} else {
if (empty($style)) {
$cssContent =
"\n";
} else {
if ("none" == $style) {
$cssContent = "";
} else {
if ("/" == $style[0])
$href = $style;
else
$href = "/htmgem/css/$style.css";
$cssContent = "";
}
}
}
echo <<$page_title
$cssContent
EOL;
echo "\n".translateGemToHtml($fileContents);
echo "\n\n";
}
ob_end_flush();
?>