1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
<?php
use GeminiFoundation\Client;
use GeminiFoundation\Gemtext;
require __DIR__ . '/vendor/autoload.php';
$geminiHost = $_ENV['GEMINI_HOST'];
$url = parse_url(
"//$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"
);
$url['query'] ??= '';
$client = new Client($geminiHost);
$response = $client->request("$url[path]$url[query]");
$title = '';
if ($response->getStatusCode()->value == 20) {
ob_start();
$mime = explode(';', $response->getMeta())[0];
if (strpos($mime, 'text/gemini') === 0) {
$parser = new Gemtext($response->getBody());
$lines = $parser->parse();
$wasListItem = false;
$currentListItems = [];
foreach ($lines as $line) {
if ($wasListItem && $line['type'] !== 'listitem') {
echo "<ul>";
foreach ($currentListItems as $listItem) {
echo "<li>$listItem[text]</li>";
}
echo "</ul>";
$wasListItem = false;
$currentListItems = [];
}
if ($line['type'] === 'preformatted_on') {
echo "<div>$line[alt]</div><pre>";
}
else if ($line['type'] === 'preformatted') {
echo htmlentities($line['raw']);
}
else if ($line['type'] === 'preformatted_off') {
echo "</pre>";
}
else if ($line['type'] === 'heading') {
if (empty($title)) {
$title = $line['text'];
}
echo "<h$line[size]>$line[text]</h$line[size]>";
}
else if ($line['type'] === 'listitem') {
$currentListItems[] = $line;
$wasListItem = true;
}
else if ($line['type'] === 'quote') {
echo "<blockquote>$line[text]</blockquote>";
}
else if ($line['type'] === 'link') {
$line['link'] = str_replace(["gemini://$geminiHost", $geminiHost], "https://$geminiHost", $line['link']);
$line['text'] = $line['text'] ?: $line['link'];
echo "<a href=\"$line[link]\" style=\"display: block;\">$line[text]</a>";
}
else if ($line['type'] === 'text') {
echo "<p>$line[text]</p>";
}
}
}
else if (strpos($mime, 'text') === 0) {
echo $response->getBody();
}
else if (strpos($mime, 'image') === 0) {
$src = "data:{$mime};base64," . base64_encode($response->getBody());
?>
<img src="<?php echo $src; ?>">
<?php
}
else if (strpos($mime, 'video') === 0) {
$src = "data:{$mime};base64," . base64_encode($response->getBody());
?>
<video controls>
<source src="<?php echo $src; ?>" type="<?php echo $mime; ?>">
</video>
<?php
}
else if (strpos($mime, 'audio') === 0) {
$src = "data:{$mime};base64," . base64_encode($response->getBody());
?>
<audio controls>
<source src="<?php echo $src; ?>" type="<?php echo $mime; ?>">
</audio>
<?php
}
else {
echo "Unhandled MIME type: $mime";
}
} else {
$title = $response->getHeader();
echo $response->getHeader();
}
echo "<hr>";
echo "Original document at <a href=\"gemini://$geminiHost$url[path]$url[query]\">gemini://$geminiHost$url[path]$url[query]</a>";
$content = ob_get_clean();
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo $title; ?></title>
<?php if (! empty($_ENV['CSS'])): ?>
<style><?php echo $_ENV['CSS']; ?></style>
<?php endif; ?>
</head>
<body>
<?php echo $content; ?>
</body>
</html>
|