HtmGem/htmgem.php

232 lines
8.0 KiB
PHP
Raw Permalink Normal View History

2021-03-01 14:22:22 +00:00
<?php
2021-03-05 08:32:54 +00:00
mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");
2021-03-01 14:22:22 +00:00
if (isset($_REQUEST["url"]))
$url = $_REQUEST["url"];
elseif (isset($_SERVER["QUERY_STRING"]))
$url = "/".$_SERVER["QUERY_STRING"];
else
$url = "/index.gmi";
$GMI_DIR = $_SERVER['DOCUMENT_ROOT'];
$filePath = $GMI_DIR.$url;
2021-03-05 14:55:57 +00:00
$fileContents = @file_get_contents($filePath);
if (!$fileContents) {
2021-03-01 14:22:22 +00:00
http_response_code(404);
2021-03-02 22:05:30 +00:00
die("404: $url");
2021-03-01 14:22:22 +00:00
}
2021-03-05 14:55:57 +00:00
# Removes the Byte Order Mark
$fileContents = preg_replace("/\xEF\xBB\xBF/", "", $fileContents);
2021-03-01 14:22:22 +00:00
2021-03-05 14:55:57 +00:00
$fileLines = preg_split("/\n/", $fileContents);
2021-03-01 14:22:22 +00:00
2021-03-03 15:07:56 +00:00
/**
* Replaces markups things like __underlined__ to <u>underlined</u>.
* @param $instruction the characters to replace, ex. _
* @param $markup the markup to replace to, ex. "u" to get <u></u>
* @param &$text where to replace.
*/
function markupPreg($instruction, $markup, &$text) {
$output = $text;
# Replaces couples "__word__" into "<i>word</i>".
$output = mb_ereg_replace("${instruction}(.+?)${instruction}", "<{$markup}>\\1</{$markup}>", $output);
2021-03-03 15:07:56 +00:00
# Replaces a remaining __ into "<i>…</i>" to the end of the line.
$output = mb_ereg_replace("${instruction}(.+)?", "<{$markup}>\\1</{$markup}>", $output);
2021-03-03 15:07:56 +00:00
$text = $output;
}
/**
* Adds text attributes sucj as underline, bold, to $line
* @param $line the line to process
*/
function addTextAttributes(&$line) {
markupPreg("__", "u", $line);
2021-03-04 19:39:54 +00:00
markupPreg("\*\*", "strong", $line);
markupPreg("//", "em", $line);
2021-03-03 15:07:56 +00:00
markupPreg("~~", "del", $line);
}
2021-03-05 14:55:57 +00:00
define("NARROW_NO_BREAK_SPACE", "&#8239;");
2021-03-03 15:07:56 +00:00
/**
2021-03-05 14:55:57 +00:00
* 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.
2021-03-03 15:07:56 +00:00
* @param $text1, $text2 texts to process
*/
2021-03-05 14:55:57 +00:00
function htmlPrepare(&$text) {
2021-03-04 20:59:57 +00:00
$text = htmlspecialchars($text, ENT_HTML5|ENT_NOQUOTES, "UTF-8", false);
2021-03-05 14:55:57 +00:00
$text = mb_ereg_replace("\ ([?!:;»€$])", NARROW_NO_BREAK_SPACE."\\1", $text);
$text = mb_ereg_replace("([«])\ ", "\\1".NARROW_NO_BREAK_SPACE, $text); # Espace fine insécable
# Below, "Em Dash" (U+2014, —) and "En Dash" (U+2013, ) make —–
#$text = mb_ereg_replace("([—–]) ([^—–.]+)( [—–]|\.)", "\\1".NARROW_NO_BREAK_SPACE."\\2".NARROW_NO_BREAK_SPACE."\\3", $text);
# Adds no-break spaces to stick the (EM/EN dashes) to words : aaaaaa bb ccccc ==> aaaaaa $bb$ ccccc
$text = mb_ereg_replace("([—–]) ([^—–.]+) ([—–])", "\\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);
2021-03-02 22:35:53 +00:00
}
2021-03-05 14:55:57 +00:00
ob_start();
2021-03-01 14:22:22 +00:00
$mode = null;
2021-03-03 15:07:56 +00:00
$mode_textAttributes = true;
2021-03-01 14:22:22 +00:00
foreach ($fileLines as $line) {
2021-03-03 22:37:20 +00:00
$reDoCount = 0;
2021-03-05 21:38:43 +00:00
$mode_textAttributes_temp = false;
2021-03-03 22:37:20 +00:00
while (true) {
2021-03-05 21:38:43 +00:00
if ($reDoCount>2) die("Too many loops: ".$mode);
2021-03-03 22:37:20 +00:00
$reDoCount += 1;
$line1 = substr($line, 0, 1); // $line can be modified
$line2 = substr($line, 0, 2); // in the meantime.
$line3 = substr($line, 0, 3);
2021-03-01 14:22:22 +00:00
if (is_null($mode)) {
if (empty($line)) {
2021-03-05 14:55:57 +00:00
echo "<p>&nbsp;</p>\n";
2021-03-05 21:38:43 +00:00
} elseif ('^^^' == $line3) {
$mode_textAttributes = !$mode_textAttributes;
} elseif ('^' == $line1) {
if (preg_match("/^\^\s*(.*)$/", $line, $parts)) {
$line = $parts[1];
$mode_textAttributes_temp = true;
} else {
$mode = "raw";
}
continue;
2021-03-01 14:22:22 +00:00
} elseif ("#" == $line1) {
preg_match("/^(#{1,3})\s*(.*)/", $line, $sharps);
$h_level = strlen($sharps[1]);
$text = $sharps[2];
2021-03-05 14:55:57 +00:00
htmlPrepare($text);
2021-03-01 14:22:22 +00:00
switch ($h_level) {
2021-03-05 14:55:57 +00:00
case 1: echo "<h1>".$text."</h1>\n"; break;
case 2: echo "<h2>".$text."</h2>\n"; break;
case 3: echo "<h3>".$text."</h3>\n"; break;
2021-03-01 14:22:22 +00:00
}
} elseif ("=>" == $line2) {
2021-03-05 21:38:43 +00:00
if (preg_match("/^=>\s*([^\s]+)(?:\s+(.*))?$/", $line, $linkParts)) {
$url_link = $linkParts[1];
$url_label = @$linkParts[2];
if (empty(trim($url_label))) {
$url_label = $url_link;
} else {
// the label is humain-made, apply formatting
htmlPrepare($url_label);
}
echo "<p><a href='".$url_link."'>".$url_label."</a></p>\n";
} else {
2021-03-05 21:38:43 +00:00
$mode = "raw";
continue;
}
2021-03-01 14:22:22 +00:00
} elseif ("```" == $line3) {
$mode="pre";
2021-03-05 14:55:57 +00:00
echo "<pre>\n";
2021-03-01 14:22:22 +00:00
} elseif (">" == $line1) {
$mode = "quote";
preg_match("/^>\s*(.*)$/", $line, $quoteParts);
$quote = $quoteParts[1];
2021-03-05 14:55:57 +00:00
echo "<blockquote>\n";
2021-03-01 14:22:22 +00:00
if (empty($quote))
2021-03-05 14:55:57 +00:00
echo "<p>&nbsp;</p>\n";
2021-03-01 14:22:22 +00:00
else
2021-03-05 14:55:57 +00:00
htmlPrepare($quote);
2021-03-05 21:38:43 +00:00
if ($mode_textAttributes xor $mode_textAttributes_temp) addTextAttributes($line);
2021-03-05 14:55:57 +00:00
echo "<p>".$quote."</p>\n";
2021-03-05 21:38:43 +00:00
} elseif ("* " == $line2) {
2021-03-05 14:55:57 +00:00
echo "<ul>\n";
2021-03-05 21:38:43 +00:00
$mode = "ul";
2021-03-03 22:37:20 +00:00
continue;
2021-03-01 14:22:22 +00:00
} else {
2021-03-05 21:38:43 +00:00
$mode = "raw";
2021-03-03 22:37:20 +00:00
continue;
2021-03-01 14:22:22 +00:00
}
2021-03-05 21:38:43 +00:00
} else {
if ("raw"==$mode) {
htmlPrepare($line);
if ($mode_textAttributes xor $mode_textAttributes_temp) addTextAttributes($line);
if (empty($line)) $line = "&nbsp;";
echo "<p>$line</p>\n";
2021-03-01 14:22:22 +00:00
$mode = null;
2021-03-05 21:38:43 +00:00
} elseif ("pre"==$mode) {
if ("```" == $line3) {
echo "</pre>\n";
$mode = null;
} else {
htmlPrepare($line);
echo $line."\n";
}
} elseif ("quote"==$mode) {
if (">" == $line1) {
preg_match("/^>\s*(.*)$/", $line, $quoteParts);
$quote = $quoteParts[1];
if (empty($quote))
echo "<p>&nbsp;</p>\n";
else
htmlPrepare($quote);
echo "<p>".$quote."</p>\n";
} else {
echo "</blockquote>\n";
$mode = null;
continue;
}
} elseif ("ul"==$mode) {
if ("* " == $line2) {
preg_match("/^\*\s*(.*)$/", $line, $ulParts);
$li = $ulParts[1];
if (empty($li)) {
echo "<li>&nbsp;\n";
} else {
htmlPrepare($li);
2021-03-05 23:34:16 +00:00
if ($mode_textAttributes xor $mode_textAttributes_temp) addTextAttributes($li);
2021-03-05 21:38:43 +00:00
echo "<li>".$li."\n";
}
} else {
echo "</ul>\n";
$mode = null;
continue;
}
} else {
die("Unexpected mode: $mode!");
2021-03-01 14:22:22 +00:00
}
}
2021-03-05 21:38:43 +00:00
break; // exits the while(true) as no continue occured
2021-03-01 14:22:22 +00:00
}
}
2021-03-05 14:55:57 +00:00
$body = ob_get_contents();
ob_clean();
# Gets the page title: the first occurrence with # at the line start
mb_ereg("#\s*([^\n]+)\n", $fileContents, $matches);
$page_title = @$matches[1];
# <!-- link type="text/css" rel="StyleSheet" href="/htmgem.css" -->
echo <<<EOL
<!DOCTYPE html>
<html lang="fr">
<head>
<title>$page_title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
EOL;
include("htmgem.css");
echo <<<EOL
</style>
</head>
<body>
EOL;
2021-03-01 14:22:22 +00:00
2021-03-05 14:55:57 +00:00
echo "\n".$body;
2021-03-03 15:07:56 +00:00
echo "</body>\n</html>\n";
2021-03-01 14:22:22 +00:00
ob_end_flush();
2021-03-05 14:55:57 +00:00
2021-03-01 14:22:22 +00:00
?>