Open Renji-FR opened 4 months ago
Just for the issue, this is my class ShellElement
<?php
declare(strict_types=1);
namespace Core\Markdown\Util;
final class ShellElement implements \Stringable
{
/**
* @var array<string, string|bool>
*/
private array $attributes = [];
/**
* @var \Stringable|\Stringable[]|string
*/
private mixed $contents;
/**
* @psalm-readonly
*/
private bool $resetClosing;
/**
* @param array<string, string|string[]|bool> $attributes Array of attributes (values should be unescaped)
* @param \Stringable|\Stringable[]|string|null $contents Inner contents, pre-escaped if needed
* @param bool $resetClosing Append reset statement at the end
*/
public function __construct(
array $attributes = [],
mixed $contents = '',
bool $resetClosing = false
) {
$this->resetClosing = $resetClosing;
foreach ($attributes as $name => $value) {
$this->setAttribute($name, $value);
}
$this->setContents($contents ?? '');
}
/**
* @return array<string, string|bool>
*
* @psalm-immutable
*/
public function getAllAttributes(): array
{
return $this->attributes;
}
/**
* @return string|bool|null
*
* @psalm-immutable
*/
public function getAttribute(string $key): mixed
{
return $this->attributes[$key] ?? null;
}
/**
* @param string|string[]|bool $value
*/
public function setAttribute(string $key, mixed $value = true): self
{
if (\is_array($value)) {
$this->attributes[$key] = \array_unique($value);
} else {
$this->attributes[$key] = $value;
}
return $this;
}
/**
* @return \Stringable|\Stringable[]|string
*
* @psalm-immutable
*/
public function getContents(bool $asString = true): mixed
{
if (!$asString) {
return $this->contents;
}
return $this->_getContentsAsString();
}
/**
* Sets the inner contents of the tag (must be pre-escaped if needed)
*
* @param \Stringable|\Stringable[]|string $contents
*/
public function setContents(mixed $contents): self
{
$this->contents = $contents ?? ''; // @phpstan-ignore-line
return $this;
}
/**
* @psalm-immutable
*/
private function _getContentsAsString(): string
{
if (\is_string($this->contents)) {
return $this->contents;
}
elseif (\is_array($this->contents)) {
return \implode('', $this->contents);
}
else {
return (string) $this->contents;
}
}
/**
* @psalm-immutable
*/
public function __toString(): string
{
if ($this->contents === '') {
return '';
}
$result = '';
$styles = $this->attributes['styles'] ?? [];
if (is_array($styles) && ($style = implode(';', $styles)) !== '') {
$result .= "\033[" . $style . "m";
}
$result .= $this->_getContentsAsString();
if ($this->resetClosing) {
$result .= "\033[0m";
}
else
{
$resetStyles = [];
foreach ($styles as $style)
{
if ($style >= 1 && $style <= 9) {
$resetStyles[] = $style + 20;
}
elseif ($style >= 30 && $style < 39 || $style >= 90 && $style <= 99) {
$resetStyles[] = 39;
}
elseif ($style >= 40 && $style < 49 || $style >= 100 && $style <= 109) {
$resetStyles[] = 49;
}
}
if (($resetStyle = implode(';', $resetStyles)) !== '') {
$result .= "\033[" . $resetStyle . "m";
}
}
return $result;
}
}
Another solution is to use the Termwind project:
<?php
declare(strict_types=1);
namespace PhpCliShell\Core\Markdown;
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Exception\CommonMarkException;
use Termwind\HtmlRenderer;
/**
* Converts CommonMark-compatible Markdown to Shell output.
*/
final class HtmlConverter
{
/**
* @psalm-readonly
*/
private CommonMarkConverter $converter;
/**
* Create a new Markdown converter pre-configured for CommonMark
*
* @param array<string, mixed> $config
*/
public function __construct(array $config = [])
{
$this->converter = new CommonMarkConverter($config);
}
public function getEnvironment(): Environment
{
return $this->converter->getEnvironment();
}
/**
* Converts Markdown to Shell output.
*
* @param string $input Markdown input
* @return string Rendered Shell output
*/
public function convert(string $input): string
{
$htmlContent = $this->converter->convert($input);
return (new HtmlRenderer)->parse((string) $htmlContent)->toString();
}
/**
* Converts CommonMark to Shell output.
*
* @see HtmlConverter::convert()
*
* @throws CommonMarkException
*/
public function __invoke(string $markdown): string
{
return $this->convert($markdown);
}
}
Description
For CLI application using PHP CLI, the goal is to render Markdown to Shell output
We must use the Shell statements like this one:
I already have code that work for my project/application.
I used this schema in order to custom some renderer:
Example
Let me know if you want to implement this feature in your project.
I would like to create a pull request / merge request if this feature is useful for your project.
These are the classes that I created to implement this feature:
I already created my unit tests too.
Did this project help you today? Did it make you happy in any way?
Yes, I created all classes allowing to render Markdown to Shell output.