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
|
<?php
namespace GeminiFoundation;
class Gemtext
{
protected string $input;
protected array $output;
protected string $preformattedMode = 'off';
public function __construct(string $input)
{
$this->input = $input;
}
public function parse(): array
{
$input = fopen('php://temp', 'r+');
fputs($input, $this->input);
rewind($input);
$output = [];
while ($line = fgets($input)) {
$output[] = $this->parseLine($line);
}
fclose($input);
return $this->output = $output;
}
private function parseLine(string $input)
{
$line = [
'raw' => $input,
];
$input = ltrim($input);
if (str_starts_with($input, '```')) {
$this->preformattedMode = $this->preformattedMode === 'on' ? 'off' : 'on';
$line['type'] = $this->preformattedMode === 'on' ? 'preformatted_on' : 'preformatted_off';
$line['text'] = $line['alt'] = trim(substr($input, 3));
}
else if ($this->preformattedMode === 'on') {
$line['type'] = 'preformatted';
$line['text'] = $line['raw'];
}
else if (str_starts_with($input, '#')) {
$firstWhitespacePosition = $this->findWhitespace($input);
$line['type'] = 'heading';
$line['size'] = substr_count(
haystack: $input,
needle: '#',
length: min($firstWhitespacePosition, 3)
);
$line['text'] = trim(substr(
string: $input,
offset: min($firstWhitespacePosition, 3)
));
}
else if (str_starts_with($input, '*')) {
$line['type'] = 'listitem';
$line['text'] = trim(substr($input, 1));
}
else if (str_starts_with($input, '>')) {
$line['type'] = 'quote';
$line['text'] = trim(substr($input, 1));
}
else if (str_starts_with($input, '=>')) {
$whitespacePosition = $this->findWhitespace($input, 3);
$link = substr(string: $input, offset: 2, length: $whitespacePosition - 2);
$text = substr(string: $input, offset: $whitespacePosition);
$line['type'] = 'link';
$line['link'] = trim($link);
$line['text'] = trim($text);
}
else {
$line['type'] = 'text';
$line['text'] = rtrim($input);
}
return $line;
}
private function findWhitespace(string $input, int $offset = 0): int
{
$space = strpos($input, ' ', $offset);
$tab = strpos($input, "\t", $offset);
return $space === false ? ($tab === false ? PHP_INT_MAX : $tab) : $space;
}
}
|