Awesome PHP-based Git frontend.
Commited on by Robin.
diff --git a/ext/sitdown.php b/ext/sitdown.php
new file mode 100644
index 0000000..63bfa3e
--- /dev/null
+++ b/ext/sitdown.php
@@ -0,0 +1,28 @@
+<?php
+
+class Sitdown extends Parsedown {
+ function __construct($repo, $hash, $base) {
+ $this->repo = $repo;
+ $this->hash = $hash;
+ $this->base = $base;
+ }
+
+ function inlineImage($excerpt) {
+ $image = parent::inlineImage($excerpt);
+
+ if (!isset($image)) return null;
+
+ $path = $image['element']['attributes']['src'];
+
+ if(!is_absolute($path)) {
+ $path = trim(path_join($this->base, $path), '/');
+ $blob = \core\getBlob($this->repo, $path, $this->hash);
+ $mime = \core\detectMimeType($this->repo, $path, $this->hash);
+
+ $image['element']['attributes']['src'] =
+ "data:{$mime};base64," . base64_encode($blob);
+ }
+
+ return $image;
+ }
+}
\ No newline at end of file
diff --git a/gui/blob.php b/gui/blob.php
index 7bd9fc6..d38ae26 100644
--- a/gui/blob.php
+++ b/gui/blob.php
@@ -20,28 +20,7 @@
<?php
$blob = \core\getBlob($repo, $request_path, $hash);
$ext = pathinfo($request_path, PATHINFO_EXTENSION);
- $mime = \core\getMimeType($repo, $request_path, $hash);
-
- // CodeMirror doesn't like text/x-shellscript :|
- if($mime == 'text/x-shellscript') $mode = 'text/x-sh';
-
- // If the file info is being useless, try to match using
- // file extension instead.
- else if($mime == 'text/plain') {
- $mode = match($ext) {
- 'md' => 'text/x-markdown',
- 'json' => 'application/json',
- 'jsonld' => 'application/ld+json',
- 'ts' => 'application/typescript',
- default => $ext
- };
-
- if(str_ends_with($ext, 'js')) $mode = 'text/javascript';
- if(str_ends_with($ext, 'html')) $mode = 'text/html';
- }
-
- // For all other cases, let CodeMirror decide.
- else $mode = $mime;
+ $mime = \core\detectMimeType($repo, $request_path, $hash);
?>
<div class="container blob">
@@ -49,9 +28,21 @@
<img src="data:<?= $mime ?>;base64,<?= base64_encode($blob) ?>">
<?php elseif($mime == 'application/octet-stream'): ?>
<p>Cannot render binary data.</p>
+ <?php elseif($ext == 'md'): ?>
+ <article class="readme">
+ <?php
+ $parser = new Sitdown($repo, $hash, path_parent($request_path));
+ echo $parser->text($blob);
+ ?>
+ </article>
<?php else: ?>
<pre class="code"><code><?= htmlspecialchars($blob) ?></code></pre>
+ <?php
+ // CodeMirror is not a fan of text/x-shellscript.
+ $mode = $mime == 'text/x-shellscript' ? 'text/x-sh' : $mime;
+ ?>
+
<script>
// Mime-Type: <?= $mime ?>
// Extension: <?= $ext ?>
diff --git a/gui/raw.php b/gui/raw.php
new file mode 100644
index 0000000..e69de29
diff --git a/gui/summary.php b/gui/summary.php
index 5dc6208..db85d01 100644
--- a/gui/summary.php
+++ b/gui/summary.php
@@ -45,10 +45,12 @@
<main class="container">
<article class="readme">
<?php
- $markdown = \core\getREADME($repo);
- $parser = new Parsedown();
+ $blob = \core\getREADME($repo);
+ $hash = \core\getLatestHash($repo, $branch);
- echo $parser->text($markdown);
+ $parser = new Sitdown($repo, $hash, '/');
+
+ echo $parser->text($blob);
?>
</article>
</main>
\ No newline at end of file
diff --git a/index.php b/index.php
index a73fb1f..4e1dbc6 100644
--- a/index.php
+++ b/index.php
@@ -3,6 +3,7 @@
require_once __DIR__ . "/src/core.php";
require_once __DIR__ . '/vendor/autoload.php';
+require_once __DIR__ . "/ext/sitdown.php";
$git = new CzProject\GitPhp\Git;
@@ -82,12 +83,8 @@ switch(true) {
case route("@/tree/{$alnum}(.*)$@"):
$page ??= "tree";
- if(\core\isCommitHash($params[1])) {
- $hash = $params[1];
- } else {
- $branch = $params[1];
- $hash = \core\getLatestCommits($repo, $branch, 1)[0]['hash'];
- }
+ if(\core\isCommitHash($params[1])) $hash = $params[1];
+ else $hash = \core\getLatestHash($repo, $params[1]);
$request_path = trim($params[2], "/");
break;
@@ -95,32 +92,11 @@ switch(true) {
case route("@/blob/{$alnum}(.*)$@"):
$page ??= "blob";
- if(\core\isCommitHash($params[1])) {
- $hash = $params[1];
- } else {
- $branch = $params[1];
- $hash = \core\getLatestCommits($repo, $branch, 1)[0]['hash'];
- }
+ if(\core\isCommitHash($params[1])) $hash = $params[1];
+ else $hash = \core\getLatestHash($repo, $params[1]);
$request_path = trim($params[2], "/");
break;
-
- case route("@/raw/{$alnum}(.*)$@"):
- if(\core\isCommitHash($params[1])) {
- $hash = $params[1];
- } else {
- $branch = $params[1];
- $hash = \core\getLatestCommits($repo, $branch, 1)[0]['hash'];
- }
-
- $request_path = trim($params[2], "/");
-
- $blob = \core\getBlob($repo, $request_path, $hash);
- $mime = \core\detectMimeType($repo, $request_path, $hash);
-
- header("Content-Type: {$mime}");
- echo $blob;
- exit;
}
if(isset($page)) break;
diff --git a/src/core.php b/src/core.php
index e82cf91..7cad4c4 100644
--- a/src/core.php
+++ b/src/core.php
@@ -177,6 +177,10 @@ function lookupRemoteDomain($remote) {
};
}
+function getLatestHash($repo, $branch) {
+ return getLatestCommits($repo, $branch, 1)[0]['hash'];
+}
+
function getDefaultBranch($repo) {
return str_replace("refs/heads/", "", $repo->execute('symbolic-ref', 'HEAD')[0]);
}
@@ -198,7 +202,7 @@ function getType($repo, $path, $hash) {
return false;
}
-function getMimeType($repo, $path, $hash) {
+function detectMimeType($repo, $path, $hash) {
$finfo = new \finfo(FILEINFO_MIME_TYPE);
[$line] = $repo->execute('ls-tree', $hash, $path);
diff --git a/src/utils.php b/src/utils.php
index 403ce53..a47520a 100644
--- a/src/utils.php
+++ b/src/utils.php
@@ -78,4 +78,10 @@ function has_tld($str) {
$TLDs = [".nl", ".com", ".org", ".eu"];
$matches = array_filter($TLDs, fn ($tld) => str_ends_with($str, $tld));
return !empty($matches);
+}
+
+function is_absolute($url) {
+ return str_starts_with($url, "http://")
+ || str_starts_with($url, "https://")
+ || str_starts_with($url, "//");
}
\ No newline at end of file