<?php
declare(strict_types=1);
namespace Butschster\ContextGenerator\Lib\Content;
use Butschster\ContextGenerator\Lib\Content\Block\BlockInterface;
use Butschster\ContextGenerator\Lib\Content\Block\CodeBlock;
use Butschster\ContextGenerator\Lib\Content\Block\CommentBlock;
use Butschster\ContextGenerator\Lib\Content\Block\DescriptionBlock;
use Butschster\ContextGenerator\Lib\Content\Block\SeparatorBlock;
use Butschster\ContextGenerator\Lib\Content\Block\TextBlock;
use Butschster\ContextGenerator\Lib\Content\Block\TitleBlock;
use Butschster\ContextGenerator\Lib\Content\Block\TreeViewBlock;
use Butschster\ContextGenerator\Lib\Content\Block\FileStatsBlock;
use Butschster\ContextGenerator\Lib\Content\Renderer\MarkdownRenderer;
use Butschster\ContextGenerator\Lib\Content\Renderer\RendererInterface;
/**
* Builder for creating structured content with various block types
*/
final class ContentBuilder implements \Stringable
{
private readonly ContentBlock $content;
/**
* Create a new ContentBuilder
*/
public function __construct(private RendererInterface $renderer = new MarkdownRenderer())
{
$this->content = new ContentBlock();
}
/**
* Create a new ContentBuilder instance
*
* @param RendererInterface|null $renderer The renderer to use
*/
public static function create(?RendererInterface $renderer = null): self
{
return new self($renderer);
}
/**
* Set the renderer to use
*
* @param RendererInterface $renderer The renderer to use
*/
public function setRenderer(RendererInterface $renderer): self
{
$this->renderer = $renderer;
return $this;
}
/**
* Get the renderer being used
*
*/
public function getRenderer(): RendererInterface
{
return $this->renderer;
}
/**
* Add a custom block to the content
*
* @param BlockInterface $block The block to add
*/
public function addBlock(BlockInterface $block): self
{
$this->content->addBlock($block);
return $this;
}
/**
* Add a title block
*
* @param string $title The title text
* @param int $level The heading level (1-6)
*/
public function addTitle(string $title, int $level = 1): self
{
return $this->addBlock(new TitleBlock($title, $level));
}
/**
* Add a text block
*
* @param string $text The text content
*/
public function addText(string $text): self
{
return $this->addBlock(new TextBlock($text));
}
/**
* Add a description block
*
* @param string $description The description text
*/
public function addDescription(string $description): self
{
return $this->addBlock(new DescriptionBlock($description));
}
/**
* Add a code block
*
* @param string $code The code content
* @param string|null $language The language for syntax highlighting
*/
public function addCodeBlock(string $code, ?string $language = null, ?string $path = null): self
{
return $this->addBlock(new CodeBlock($code, $language, $path));
}
/**
* Add a tree view block
*
* @param string $treeView The tree view content
*/
public function addTreeView(string $treeView): self
{
return $this->addBlock(new TreeViewBlock($treeView));
}
/**
* Add a file stats block
*
* @param int $fileSize The file size in bytes
* @param int $lineCount The number of lines in the file
* @param string|null $filePath The file path (optional)
*/
public function addFileStats(int $fileSize, int $lineCount, ?string $filePath = null): self
{
return $this->addBlock(new FileStatsBlock('', $fileSize, $lineCount, $filePath));
}
/**
* Add a separator block
*
* @param string $separator The separator character(s)
* @param int $length The length of the separator
*/
public function addSeparator(string $separator = '-', int $length = 60): self
{
return $this->addBlock(new SeparatorBlock($separator, $length));
}
/**
* Add a comment block
*
* @param string $comment The comment text
*/
public function addComment(string $comment): self
{
return $this->addBlock(new CommentBlock($comment));
}
/**
* Merge another ContentBuilder into this one
*/
public function merge(self $builder): self
{
foreach ($builder->content->getBlocks() as $block) {
$this->addBlock($block);
}
return $this;
}
/**
* Build and return the final content
*
* @return string The rendered content
*/
public function build(): string
{
return $this->content->render($this->renderer);
}
public function __toString(): string
{
return (string) \preg_replace("/(\r\n|\n)+$/", '', $this->build());
}
}