mirror of
https://github.com/YGGverse/gemini-php.git
synced 2025-02-05 11:44:34 +00:00
implement filesystem, update api version
This commit is contained in:
parent
9ea658a3fc
commit
1bb20c2f18
110
README.md
110
README.md
@ -4,14 +4,116 @@ PHP 8 Library for Gemini Protocol
|
||||
|
||||
## DokuWiki
|
||||
|
||||
### Convert
|
||||
Toolkit provides DokuWiki integration API for Gemini.
|
||||
|
||||
Allows to simple deploy new apps or make existing website mirror.
|
||||
|
||||
### Examples
|
||||
|
||||
* [DokuWiki Server for Gemini Protocol](https://github.com/YGGverse/dokuwiki-gemini-server)
|
||||
|
||||
### Reader
|
||||
|
||||
Read DokuWiki and convert to Gemini
|
||||
|
||||
```
|
||||
$dokuwiki = new \Yggverse\Gemini\Dokuwiki();
|
||||
$reader = new \Yggverse\Gemini\Dokuwiki\Reader(
|
||||
// optional regex rule set array
|
||||
);
|
||||
```
|
||||
|
||||
echo $dokuwiki->toGemini(
|
||||
#### Reader::getRules
|
||||
#### Reader::setRules
|
||||
#### Reader::getRule
|
||||
#### Reader::setRule
|
||||
|
||||
Get or change existing regex rule (or just skip by using build-in set)
|
||||
|
||||
```
|
||||
echo $reader->setRule(
|
||||
'/subject/ui',
|
||||
'replacement'
|
||||
);
|
||||
```
|
||||
|
||||
#### Reader::toGemini
|
||||
|
||||
Convert DokuWiki to Gemini markup
|
||||
|
||||
```
|
||||
echo $reader->toGemini(
|
||||
file_get_contents(
|
||||
'data/pages/index.txt'
|
||||
'/host/data/pages/index.txt'
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
#### Reader::getH1
|
||||
|
||||
Get document title
|
||||
|
||||
```
|
||||
echo $reader->getH1(
|
||||
file_get_contents(
|
||||
'/host/data/pages/index.txt'
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
### Filesystem
|
||||
|
||||
Provides methods for simple and secure interaction with DokuWiki file storage
|
||||
|
||||
```
|
||||
$filesystem = new \Yggverse\Gemini\Dokuwiki\Filesystem(
|
||||
'/host/data' // storage location
|
||||
);
|
||||
```
|
||||
|
||||
#### Filesystem::getList
|
||||
|
||||
Return simple array of all files in storage
|
||||
|
||||
```
|
||||
var_dump (
|
||||
$filesystem->getList(
|
||||
'hello:world'
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
#### Filesystem::getTree
|
||||
|
||||
Return all files under the storage folder in tree format
|
||||
|
||||
```
|
||||
var_dump (
|
||||
$filesystem->getTree(
|
||||
'hello:world'
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
#### Filesystem::getPagePathByUri
|
||||
|
||||
Return absolute path to stored page file
|
||||
|
||||
```
|
||||
var_dump (
|
||||
$filesystem->getPagePathByUri(
|
||||
'hello:world'
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
#### Filesystem::getPageUriByPath
|
||||
|
||||
Return page URI in `dokuwiki:format`
|
||||
|
||||
```
|
||||
var_dump (
|
||||
$filesystem->getPageUriByPath(
|
||||
'/full/path/to/page.txt'
|
||||
)
|
||||
)
|
||||
```
|
116
src/Dokuwiki.php
116
src/Dokuwiki.php
@ -1,116 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yggverse\Gemini;
|
||||
|
||||
class Dokuwiki
|
||||
{
|
||||
private array $_dictionary =
|
||||
[
|
||||
// Headers
|
||||
'/^([\s]?)#([^#]+)/' => '$1#$2' . PHP_EOL,
|
||||
'/^([\s]?)##([^#]+)/' => '$1##$2' . PHP_EOL,
|
||||
'/^([\s]?)###([^#]+)/' => '$1###$2' . PHP_EOL,
|
||||
'/^([\s]?)####([^#]+)/' => '$1###$2' . PHP_EOL,
|
||||
'/^([\s]?)#####([^#]+)/' => '$1###$2' . PHP_EOL,
|
||||
'/^([\s]?)######([^#]+)/' => '$1###$2' . PHP_EOL,
|
||||
|
||||
'/^[\s]?[=]{6}([^=]+)[=]{6}/' => '# $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{5}([^=]+)[=]{5}/' => '## $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{4}([^=]+)[=]{4}/' => '### $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{3}([^=]+)[=]{3}/' => '### $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{2}([^=]+)[=]{2}/' => '### $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{1}([^=]+)[=]{1}/' => '### $1' . PHP_EOL,
|
||||
|
||||
// Links
|
||||
'/\{\{([^:]+):([^\}]+)\}\}/' => PHP_EOL . '=> $1 $1' . PHP_EOL, // @TODO
|
||||
'/\{\{indexmenu\>:([^\}]+)\}\}/' => PHP_EOL . '=> $1 $1' . PHP_EOL, // @TODO
|
||||
'/\[\[wp([A-z]{2})\>([^\|]+)\|([^\]\]]+)\]\]/' => PHP_EOL . '=> https://$1.wikipedia.org/wiki/$2 $3' . PHP_EOL,
|
||||
'/\[\[wp\>([^\|]+)\|([^\]\]]+)\]\]/' => PHP_EOL . '=> https://en.wikipedia.org/wiki/$1 $2' . PHP_EOL,
|
||||
'/\[\[([^|]+)\|([^\]\]]+)\]\]/' => PHP_EOL . '=> $1 $2' . PHP_EOL,
|
||||
|
||||
// Tags
|
||||
'/<code>/i' => '```',
|
||||
'/<\/code>/i' => '```',
|
||||
'/<wrap[^>]+>([^<]?)/i' => '$1',
|
||||
'/<\/wrap>/i' => '$1',
|
||||
|
||||
'/<file>/i' => '```',
|
||||
'/<file[\s]+-[\s]+([^>]+)>/i' => '$1```',
|
||||
'/<\/file>/i' => '```',
|
||||
|
||||
//'/[*]+([^*]+)[*]+/' => '$1', // @TODO bugged, e.g. crontab tasks
|
||||
'/\'\'([^\']+)\'\'/' => '$1',
|
||||
'/%%([^%]+)%%/' => '$1',
|
||||
'/\/\/^:([^\/]+)\/\//' => '$1',
|
||||
|
||||
// List
|
||||
'/^[\s]?-/' => '* ',
|
||||
'/^[\s]+\*/' => '*',
|
||||
|
||||
// Separators
|
||||
'/[\\\]{2}/' => PHP_EOL,
|
||||
|
||||
// Plugins
|
||||
'/~~DISCUSSION~~/' => '', // @TODO
|
||||
|
||||
// Final corrections
|
||||
'/[\n\r]+[.,;:]+/' => PHP_EOL
|
||||
];
|
||||
|
||||
public function __construct(?array $dictionary = null)
|
||||
{
|
||||
if ($dictionary)
|
||||
{
|
||||
$this->_dictionary = $dictionary;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDictionary(): array
|
||||
{
|
||||
$this->_dictionary;
|
||||
}
|
||||
|
||||
public function setDictionary(array $dictionary)
|
||||
{
|
||||
$this->_dictionary = $dictionary;
|
||||
}
|
||||
|
||||
public function getRule(string $key, string $value): ?string
|
||||
{
|
||||
$this->_dictionary[$key] = isset($this->_dictionary[$key]) ? $value : null;
|
||||
}
|
||||
|
||||
public function setRule(string $key, string $value): void
|
||||
{
|
||||
$this->_dictionary[$key] = $value;
|
||||
}
|
||||
|
||||
public function toGemini(string $data): string
|
||||
{
|
||||
$lines = [];
|
||||
|
||||
foreach ((array) explode(PHP_EOL, $data) as $line)
|
||||
{
|
||||
$lines[] = preg_replace(
|
||||
array_keys(
|
||||
$this->_dictionary
|
||||
),
|
||||
array_values(
|
||||
$this->_dictionary
|
||||
),
|
||||
$line
|
||||
);
|
||||
}
|
||||
|
||||
return preg_replace(
|
||||
'/[\n\r]{2,}/',
|
||||
PHP_EOL . PHP_EOL,
|
||||
implode(
|
||||
PHP_EOL,
|
||||
$lines
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
129
src/Dokuwiki/Filesystem.php
Normal file
129
src/Dokuwiki/Filesystem.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yggverse\Gemini\Dokuwiki;
|
||||
|
||||
class Filesystem
|
||||
{
|
||||
private $_path;
|
||||
private $_tree = [];
|
||||
private $_list = [];
|
||||
|
||||
public function __construct(string $path)
|
||||
{
|
||||
$this->_path = rtrim(
|
||||
$path,
|
||||
'/'
|
||||
);
|
||||
|
||||
$this->_index(
|
||||
$this->_path
|
||||
);
|
||||
}
|
||||
|
||||
public function getTree(): array
|
||||
{
|
||||
return $this->_tree;
|
||||
}
|
||||
|
||||
public function getList(): array
|
||||
{
|
||||
return $this->_list;
|
||||
}
|
||||
|
||||
public function getPagePathByUri(string $uri): ?string
|
||||
{
|
||||
$uri = urldecode(
|
||||
$uri
|
||||
);
|
||||
|
||||
$path = sprintf(
|
||||
'%s/pages/%s.txt',
|
||||
$this->_path,
|
||||
str_replace(
|
||||
':',
|
||||
'/',
|
||||
$uri
|
||||
)
|
||||
);
|
||||
|
||||
if (!in_array($path, $this->_list) || !is_file($path) || !is_readable($path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function getPageUriByPath(string $path): ?string
|
||||
{
|
||||
$path = str_replace(
|
||||
sprintf(
|
||||
'%s/pages/',
|
||||
$this->_path
|
||||
),
|
||||
null,
|
||||
$path
|
||||
);
|
||||
|
||||
$path = trim(
|
||||
$path,
|
||||
'/'
|
||||
);
|
||||
|
||||
$path = basename(
|
||||
$path
|
||||
);
|
||||
|
||||
$path = str_replace(
|
||||
[
|
||||
'/',
|
||||
'.txt'
|
||||
],
|
||||
[
|
||||
':',
|
||||
null
|
||||
],
|
||||
$path
|
||||
);
|
||||
|
||||
return urlencode(
|
||||
$path
|
||||
);
|
||||
}
|
||||
|
||||
private function _index(string $path): void
|
||||
{
|
||||
foreach ((array) scandir($path) as $file)
|
||||
{
|
||||
if (in_array($file, ['.', '..']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$file = sprintf(
|
||||
'%s/%s',
|
||||
$path,
|
||||
$file
|
||||
);
|
||||
|
||||
switch (true)
|
||||
{
|
||||
case is_dir($file):
|
||||
|
||||
$this->_index($file);
|
||||
|
||||
break;
|
||||
|
||||
case is_file($file):
|
||||
|
||||
$this->_tree[$path][] = $file;
|
||||
|
||||
$this->_list[] = $file;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
138
src/Dokuwiki/Reader.php
Normal file
138
src/Dokuwiki/Reader.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yggverse\Gemini\Dokuwiki;
|
||||
|
||||
class Reader
|
||||
{
|
||||
private array $_rules =
|
||||
[
|
||||
// Headers
|
||||
'/^([\s]?)#([^#]+)/' => '$1#$2' . PHP_EOL,
|
||||
'/^([\s]?)##([^#]+)/' => '$1##$2' . PHP_EOL,
|
||||
'/^([\s]?)###([^#]+)/' => '$1###$2' . PHP_EOL,
|
||||
'/^([\s]?)####([^#]+)/' => '$1###$2' . PHP_EOL,
|
||||
'/^([\s]?)#####([^#]+)/' => '$1###$2' . PHP_EOL,
|
||||
'/^([\s]?)######([^#]+)/' => '$1###$2' . PHP_EOL,
|
||||
|
||||
'/^[\s]?[=]{6}([^=]+)[=]{6}/' => '# $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{5}([^=]+)[=]{5}/' => '## $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{4}([^=]+)[=]{4}/' => '### $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{3}([^=]+)[=]{3}/' => '### $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{2}([^=]+)[=]{2}/' => '### $1' . PHP_EOL,
|
||||
'/^[\s]?[=]{1}([^=]+)[=]{1}/' => '### $1' . PHP_EOL,
|
||||
|
||||
// Tags
|
||||
'/<code>/i' => PHP_EOL . '```' . PHP_EOL,
|
||||
'/<\/code>/i' => PHP_EOL . '```' . PHP_EOL,
|
||||
|
||||
'/<file>/i' => PHP_EOL . '```' . PHP_EOL,
|
||||
'/<file[\s]?[-]?[\s]?([^>]+)>/i' => '$1' . PHP_EOL . '```' . PHP_EOL,
|
||||
'/<\/file>/i' => '```',
|
||||
|
||||
'/\*\*([^\*]{2,})\*\*/' => '$1',
|
||||
'/\'\'([^\']{2,})\'\'/' => '$1',
|
||||
'/\%\%([^\%]{2,})\%\%/' => '$1',
|
||||
'/[^:]{1}\/\/([^\/]{2,})\/\//' => '$1',
|
||||
|
||||
// Links
|
||||
'/\{\{([^:]+):([^\}]{2,})\}\}/' => PHP_EOL . '=> $1 $1' . PHP_EOL, // @TODO
|
||||
'/\{\{indexmenu\>:([^\}]{2,})\}\}/' => PHP_EOL . '=> $1 $1' . PHP_EOL, // @TODO
|
||||
'/\[\[wp([A-z]{2})\>([^\|]+)\|([^\]]{2,})\]\]/' => PHP_EOL . '=> https://$1.wikipedia.org/wiki/$2 $3' . PHP_EOL,
|
||||
'/\[\[wp\>([^\|]+)\|([^\]]{2,})\]\]/' => PHP_EOL . '=> https://en.wikipedia.org/wiki/$1 $2' . PHP_EOL,
|
||||
'/\[\[([^|]+)\|([^\]]{2,})\]\]/' => PHP_EOL . '=> $1 $2' . PHP_EOL,
|
||||
//'/((gemini|https?):\/\/[^\s]+)/' => PHP_EOL . '=> $1' . PHP_EOL, // @TODO incorrect
|
||||
|
||||
// List
|
||||
'/^[\s]?-/' => '* ',
|
||||
'/^[\s]+\*/' => '*',
|
||||
|
||||
// Separators
|
||||
'/[\\\]{2}/' => PHP_EOL,
|
||||
|
||||
// Plugins
|
||||
'/~~DISCUSSION~~/' => '', // @TODO
|
||||
|
||||
// Final corrections
|
||||
'/[\n\r]+[.,;:]+/' => PHP_EOL
|
||||
];
|
||||
|
||||
public function __construct(?array $rules = null)
|
||||
{
|
||||
if ($rules)
|
||||
{
|
||||
$this->_rules = $rules;
|
||||
}
|
||||
}
|
||||
|
||||
public function getRules(): array
|
||||
{
|
||||
$this->_rules;
|
||||
}
|
||||
|
||||
public function setRules(array $rules)
|
||||
{
|
||||
$this->_rules = $rules;
|
||||
}
|
||||
|
||||
public function getRule(string $key, string $value): ?string
|
||||
{
|
||||
$this->_rules[$key] = isset($this->_rules[$key]) ? $value : null;
|
||||
}
|
||||
|
||||
public function setRule(string $key, string $value): void
|
||||
{
|
||||
$this->_rules[$key] = $value;
|
||||
}
|
||||
|
||||
public function toGemini(string $data): string
|
||||
{
|
||||
$lines = [];
|
||||
|
||||
foreach ((array) explode(PHP_EOL, $data) as $line)
|
||||
{
|
||||
$lines[] = preg_replace(
|
||||
array_keys(
|
||||
$this->_rules
|
||||
),
|
||||
array_values(
|
||||
$this->_rules
|
||||
),
|
||||
$line
|
||||
);
|
||||
}
|
||||
|
||||
return preg_replace(
|
||||
'/[\n\r]{2,}/',
|
||||
PHP_EOL . PHP_EOL,
|
||||
strip_tags(
|
||||
implode(
|
||||
PHP_EOL,
|
||||
$lines
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getH1(string $data): ?string
|
||||
{
|
||||
foreach ((array) explode(PHP_EOL, $data) as $line)
|
||||
{
|
||||
preg_match_all(
|
||||
'/^[\s]?#([^#]+)/',
|
||||
$line,
|
||||
$matches
|
||||
);
|
||||
|
||||
if (!empty($matches[1]))
|
||||
{
|
||||
return trim(
|
||||
$matches[1]
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user