summaryrefslogtreecommitdiff
path: root/index.php
blob: 1c7f55cfdc04cf44f82d85170a7f043b7b81c68e (plain)
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>