Вход Регистрация
Файл: vendor/laravel/prompts/src/Themes/Default/CalloutRenderer.php
Строк: 222
<?php

namespace LaravelPromptsThemesDefault;

use 
InvalidArgumentException;
use 
LaravelPromptsCallout;
use 
LaravelPromptsElementsBulletedList;
use 
LaravelPromptsElementsElementContract;
use 
LaravelPromptsElementsHeading;
use 
LaravelPromptsElementsKeyValueList;
use 
LaravelPromptsElementsLink;
use 
LaravelPromptsElementsNumberedList;

class 
CalloutRenderer extends Renderer
{
    use 
ConcernsDrawsBoxes;

    
/**
     * Render the text prompt.
     */
    
public function __invoke(Callout $prompt): string
    
{
        
$content is_array($prompt->content) ? $prompt->content : [$prompt->content];

        
$sections = [];

        foreach (
$content as $part) {
            
$result $this->resolvePart($part);

            if (
is_array($result)) {
                
$sections[] = implode(PHP_EOL$result);
            } else {
                
$sections[] = implode(PHP_EOL$this->ansiWordwrap($result$this->minWidth));
            }
        }

        
$message implode(PHP_EOL.PHP_EOL$sections);

        return 
match ($prompt->type) {
            
'error' => $this
                
->box(
                    
$this->red($this->truncate('⚠ '.$prompt->label$prompt->terminal()->cols() - 6)),
                    
$message,
                    
color'red',
                    
info$prompt->info,
                ),

            
'warning' => $this
                
->box(
                    
$this->yellow($this->truncate('⚠ '.$prompt->label$prompt->terminal()->cols() - 6)),
                    
$message,
                    
color'yellow',
                    
info$prompt->info,
                ),

            default => 
$this
                
->box(
                    
$this->cyan($this->truncate($prompt->label$prompt->terminal()->cols() - 6)),
                    
$message,
                    
info$prompt->info,
                ),
        };
    }

    
/**
     * Resolve a part of the callout content into a string or array of strings.
     */
    /**
     * @return string|array<int, string>
     */
    
protected function resolvePart(string|ElementContract $part): string|array
    {
        return 
match (true) {
            
is_string($part) => $this->autoFormat($part),
            
$part instanceof Heading => $this->bold($this->autoFormat($part->text)),
            
$part instanceof BulletedList => $this->renderBulletedList($part),
            
$part instanceof NumberedList => $this->renderNumberedList($part),
            
$part instanceof KeyValueList => $this->renderKeyValueList($part),
            
$part instanceof Link => $this->renderLink($part),
            default => throw new 
InvalidArgumentException('Unsupported callout content part: '.get_debug_type($part)),
        };
    }

    
/**
     * Render a bulleted list element.
     *
     * @return array<int, string>
     */
    
protected function renderBulletedList(BulletedList $part): array
    {
        
$finalLines = [];

        foreach (
$part->items as $i => $p) {
            
$p $this->autoFormat($p);
            
$lines $this->ansiWordwrap($p$this->minWidth 2);
            
$partLines = [];

            if (
$part->spaced && $i !== 0) {
                
$partLines[] = '';
            }

            foreach (
$lines as $index => $line) {
                if (
$index === 0) {
                    
$partLines[] = $this->dim('·').' '.$line;
                } else {
                    
$partLines[] = '  '.$line;
                }
            }

            
$finalLines[] = implode(PHP_EOL$partLines);
        }

        return 
$finalLines;
    }

    
/**
     * Render a numbered list element.
     *
     * @return array<int, string>
     */
    
protected function renderNumberedList(NumberedList $part): array
    {
        
$finalLines = [];
        
// +1 for "."
        
$widestNumber mb_strwidth((string) count($part->items)) + 1;

        foreach (
$part->items as $i => $p) {
            
$partLines = [];
            
// -1 for ' ' after number
            
$p $this->autoFormat($p);
            
$lines $this->ansiWordwrap($p$this->minWidth $widestNumber 1);

            if (
$part->spaced && $i !== 0) {
                
$partLines[] = '';
            }

            foreach (
$lines as $index => $line) {
                if (
$index === 0) {
                    
$partLines[] = $this->dim(mb_str_pad(($i 1).'.'$widestNumberpad_typeSTR_PAD_LEFT)).' '.$line;
                } else {
                    
// +1 for ' ' after number
                    
$partLines[] = str_repeat(' '$widestNumber 1).$line;
                }
            }

            
$finalLines[] = implode(PHP_EOL$partLines);
        }

        return 
$finalLines;
    }

    
/**
     * Render a key-value list element.
     *
     * @return array<int, string>
     */
    
protected function renderKeyValueList(KeyValueList $part): array
    {
        
$items $part->items;
        
$keys array_keys($items);
        
$widestKey max(array_map(fn ($key) => mb_strwidth($key), $keys));

        
$finalLines = [];

        foreach (
$items as $key => $value) {
            
$paddedKey mb_str_pad($key$widestKey);
            
$value $this->autoFormat($value);
            
$lines $this->ansiWordwrap($value$this->minWidth $widestKey 2);

            foreach (
$lines as $index => $line) {
                if (
$index === 0) {
                    
$finalLines[] = $this->dim($paddedKey).'  '.$line;
                } else {
                    
$finalLines[] = str_repeat(' '$widestKey 2).$line;
                }
            }
        }

        return 
$finalLines;
    }

    
/**
     * Render a link element.
     */
    
protected function renderLink(Link $part): string
    
{
        
$text $part->underline
            
"e[4;36m{$part->label}e[0m"
            
$this->cyan($part->label);

        return 
"e]8;;{$part->url}e\{$text}e]8;;e\";
    }

    /**
     * Auto-format the text by applying styles to specific patterns, such as inline code blocks.
     */
    protected function autoFormat(string 
$text): string
    {
        
$text = preg_replace('/`([^`]+)`/', $this->cyan('`$1`'), $text);

        
$text = preg_replace_callback('/e]8;;(.+?)e\\(.*?)e]8;;e\\/', function ($matches) {
            
$visibleText = $this->stripEscapeSequences($matches[2]);
            
$hadUnderline = str_contains($matches[2], "e[4m");
            
$styled = $hadUnderline
                ? "
e[4;36m{$visibleText}e[0m"
                : 
$this->cyan($visibleText);

            return "
e]8;;{$matches[1]}e\{$styled}e]8;;e\";
        }, 
$text);

        return 
$text;
    }
}
Онлайн: 1
Реклама