Browse Source

implement filesystem, update api version

main
ghost 9 months ago
parent
commit
1bb20c2f18
  1. 110
      README.md
  2. 116
      src/Dokuwiki.php
  3. 129
      src/Dokuwiki/Filesystem.php
  4. 138
      src/Dokuwiki/Reader.php

110
README.md

@ -4,14 +4,116 @@ PHP 8 Library for Gemini Protocol
## DokuWiki ## 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
```
$reader = new \Yggverse\Gemini\Dokuwiki\Reader(
// optional regex rule set array
);
``` ```
$dokuwiki = new \Yggverse\Gemini\Dokuwiki();
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( 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

@ -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

@ -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

@ -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…
Cancel
Save