mirror of
https://github.com/YGGverse/gemini-php.git
synced 2025-01-13 00:27:57 +00:00
219 lines
5.2 KiB
PHP
219 lines
5.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Yggverse\Gemini;
|
|
|
|
class Pango
|
|
{
|
|
public static function fromGemtext(
|
|
string $gemtext
|
|
): string
|
|
{
|
|
return self::fromGemtextBody(
|
|
new \Yggverse\Gemini\Gemtext\Body(
|
|
$gemtext
|
|
)
|
|
);
|
|
}
|
|
|
|
public static function fromGemtextBody(
|
|
\Yggverse\Gemini\Gemtext\Body $body
|
|
): string
|
|
{
|
|
$lines = $body->getLines();
|
|
|
|
$raw = [];
|
|
|
|
$escaped = [];
|
|
|
|
// Code
|
|
$code = $body->getCode();
|
|
|
|
if (count($code) % 2 == 0) // make sure tags has pairs
|
|
{
|
|
$i = 1;
|
|
|
|
foreach ($code as $index => $capture)
|
|
{
|
|
// Replace code tags
|
|
if ($i % 2 == 0)
|
|
{
|
|
$lines[$index] = '</tt>';
|
|
|
|
// Skip code format inside the tags by raw registry
|
|
foreach (array_slice($lines, $offset, $index - $offset) as $start => $line)
|
|
{
|
|
$raw[$start + $offset] = $line;
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
if ($capture)
|
|
{
|
|
$lines[$index] = sprintf(
|
|
'<b>%s</b><tt>',
|
|
self::escape(
|
|
$capture
|
|
)
|
|
);
|
|
}
|
|
|
|
else
|
|
{
|
|
$lines[$index] = '<tt>';
|
|
}
|
|
|
|
$offset = $index + 1;
|
|
}
|
|
|
|
$escaped[] = $index;
|
|
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
// H1
|
|
foreach ($body->getH1() as $index => $value)
|
|
{
|
|
if (!isset($raw[$index]))
|
|
{
|
|
$lines[$index] = sprintf(
|
|
'<span size="xx-large">%s</span>',
|
|
self::escape(
|
|
$value
|
|
)
|
|
);
|
|
|
|
$escaped[] = $index;
|
|
}
|
|
}
|
|
|
|
// H2
|
|
foreach ($body->getH2() as $index => $value)
|
|
{
|
|
if (!isset($raw[$index]))
|
|
{
|
|
$lines[$index] = sprintf(
|
|
'<span size="x-large">%s</span>',
|
|
self::escape(
|
|
$value
|
|
)
|
|
);
|
|
|
|
$escaped[] = $index;
|
|
}
|
|
}
|
|
|
|
// H3
|
|
foreach ($body->getH3() as $index => $value)
|
|
{
|
|
if (!isset($raw[$index]))
|
|
{
|
|
$lines[$index] = sprintf(
|
|
'<span size="large">%s</span>',
|
|
self::escape(
|
|
$value
|
|
)
|
|
);
|
|
|
|
$escaped[] = $index;
|
|
}
|
|
}
|
|
|
|
// Quote
|
|
foreach ($body->getQuote() as $index => $value)
|
|
{
|
|
if (!isset($raw[$index]))
|
|
{
|
|
$lines[$index] = sprintf(
|
|
'<i>%s</i>',
|
|
self::escape(
|
|
$value
|
|
)
|
|
);
|
|
|
|
$escaped[] = $index;
|
|
}
|
|
}
|
|
|
|
// Links
|
|
foreach ($body->getLinks() as $index => $line)
|
|
{
|
|
if (!isset($raw[$index]))
|
|
{
|
|
$link = new \Yggverse\Gemini\Gemtext\Link(
|
|
$line
|
|
);
|
|
|
|
if (!$address = $link->getAddress())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!$alt = $link->getAlt())
|
|
{
|
|
if (!$alt = $link->getDate())
|
|
{
|
|
$alt = $address;
|
|
}
|
|
}
|
|
|
|
if ($alt == $address)
|
|
{
|
|
$lines[$index] = sprintf(
|
|
'<a href="%s">%s</a>',
|
|
$address,
|
|
self::escape(
|
|
$alt
|
|
)
|
|
);
|
|
}
|
|
|
|
else
|
|
{
|
|
$lines[$index] = sprintf(
|
|
'<a href="%s" title="%s">%s</a>',
|
|
$address,
|
|
self::escape(
|
|
urldecode(
|
|
$address
|
|
)
|
|
),
|
|
self::escape(
|
|
$alt
|
|
)
|
|
);
|
|
}
|
|
|
|
$escaped[] = $index;
|
|
}
|
|
}
|
|
|
|
// Escape special chars for non escaped lines
|
|
foreach ($body->getLines() as $index => $value)
|
|
{
|
|
if (!in_array($index, $escaped))
|
|
{
|
|
$lines[$index] = self::escape(
|
|
$value
|
|
);
|
|
}
|
|
}
|
|
|
|
return implode(
|
|
PHP_EOL,
|
|
$lines
|
|
);
|
|
}
|
|
|
|
public static function escape(
|
|
string $value
|
|
): string
|
|
{
|
|
return htmlspecialchars(
|
|
$value
|
|
);
|
|
}
|
|
} |