Update website
This commit is contained in:
parent
4413528994
commit
1d90fbf296
6865 changed files with 1091082 additions and 0 deletions
21
vendor/doctrine/rst-parser/lib/Nodes/AnchorNode.php
vendored
Normal file
21
vendor/doctrine/rst-parser/lib/Nodes/AnchorNode.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
class AnchorNode extends Node
|
||||
{
|
||||
/** @var string */
|
||||
protected $value;
|
||||
|
||||
public function __construct(string $value)
|
||||
{
|
||||
parent::__construct($value);
|
||||
}
|
||||
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
22
vendor/doctrine/rst-parser/lib/Nodes/BlockNode.php
vendored
Normal file
22
vendor/doctrine/rst-parser/lib/Nodes/BlockNode.php
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class BlockNode extends Node
|
||||
{
|
||||
/** @var string */
|
||||
protected $value;
|
||||
|
||||
/** @param string[] $lines */
|
||||
public function __construct(array $lines)
|
||||
{
|
||||
parent::__construct($this->normalizeLines($lines));
|
||||
}
|
||||
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
23
vendor/doctrine/rst-parser/lib/Nodes/CallableNode.php
vendored
Normal file
23
vendor/doctrine/rst-parser/lib/Nodes/CallableNode.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class CallableNode extends Node
|
||||
{
|
||||
/** @var callable */
|
||||
private $callable;
|
||||
|
||||
public function __construct(callable $callable)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->callable = $callable;
|
||||
}
|
||||
|
||||
public function getCallable(): callable
|
||||
{
|
||||
return $this->callable;
|
||||
}
|
||||
}
|
70
vendor/doctrine/rst-parser/lib/Nodes/CodeNode.php
vendored
Normal file
70
vendor/doctrine/rst-parser/lib/Nodes/CodeNode.php
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
/**
|
||||
* Represents a "code node", which *sometimes* encompasses more than "code blocks".
|
||||
*
|
||||
* The intention of this class is for it to be used for "code blocks".
|
||||
* However, if a directive returns true from wantCode(), they will
|
||||
* be passed a CodeNode.
|
||||
*/
|
||||
class CodeNode extends Node
|
||||
{
|
||||
/** @var string */
|
||||
protected $value;
|
||||
|
||||
/** @var bool */
|
||||
private $raw = false;
|
||||
|
||||
/** @var string|null */
|
||||
private $language = null;
|
||||
|
||||
/** @var string[] */
|
||||
private $options = [];
|
||||
|
||||
/** @param string[] $lines */
|
||||
public function __construct(array $lines)
|
||||
{
|
||||
parent::__construct($this->normalizeLines($lines));
|
||||
}
|
||||
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function setLanguage(?string $language = null): void
|
||||
{
|
||||
$this->language = $language;
|
||||
}
|
||||
|
||||
public function getLanguage(): ?string
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
public function setRaw(bool $raw): void
|
||||
{
|
||||
$this->raw = $raw;
|
||||
}
|
||||
|
||||
public function isRaw(): bool
|
||||
{
|
||||
return $this->raw;
|
||||
}
|
||||
|
||||
/** @param string[] $options */
|
||||
public function setOptions(array $options = []): void
|
||||
{
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
}
|
25
vendor/doctrine/rst-parser/lib/Nodes/DefinitionListNode.php
vendored
Normal file
25
vendor/doctrine/rst-parser/lib/Nodes/DefinitionListNode.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
use Doctrine\RST\Parser\DefinitionList;
|
||||
|
||||
final class DefinitionListNode extends Node
|
||||
{
|
||||
/** @var DefinitionList */
|
||||
private $definitionList;
|
||||
|
||||
public function __construct(DefinitionList $definitionList)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->definitionList = $definitionList;
|
||||
}
|
||||
|
||||
public function getDefinitionList(): DefinitionList
|
||||
{
|
||||
return $this->definitionList;
|
||||
}
|
||||
}
|
235
vendor/doctrine/rst-parser/lib/Nodes/DocumentNode.php
vendored
Normal file
235
vendor/doctrine/rst-parser/lib/Nodes/DocumentNode.php
vendored
Normal file
|
@ -0,0 +1,235 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
use Doctrine\RST\Configuration;
|
||||
use Doctrine\RST\Environment;
|
||||
use Doctrine\RST\ErrorManager;
|
||||
use Doctrine\RST\Renderers\FullDocumentNodeRenderer;
|
||||
use Exception;
|
||||
|
||||
use function array_unshift;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function is_string;
|
||||
use function sprintf;
|
||||
|
||||
class DocumentNode extends Node
|
||||
{
|
||||
/** @var Environment */
|
||||
protected $environment;
|
||||
|
||||
/** @var Configuration */
|
||||
private $configuration;
|
||||
|
||||
/** @var ErrorManager */
|
||||
private $errorManager;
|
||||
|
||||
/** @var Node[] */
|
||||
private $headerNodes = [];
|
||||
|
||||
/** @var Node[] */
|
||||
private $nodes = [];
|
||||
|
||||
public function __construct(Environment $environment)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->environment = $environment;
|
||||
$this->configuration = $environment->getConfiguration();
|
||||
$this->errorManager = $environment->getErrorManager();
|
||||
}
|
||||
|
||||
public function getEnvironment(): Environment
|
||||
{
|
||||
return $this->environment;
|
||||
}
|
||||
|
||||
public function getConfiguration(): Configuration
|
||||
{
|
||||
return $this->configuration;
|
||||
}
|
||||
|
||||
/** @return Node[] */
|
||||
public function getHeaderNodes(): array
|
||||
{
|
||||
return $this->headerNodes;
|
||||
}
|
||||
|
||||
public function renderDocument(): string
|
||||
{
|
||||
$renderedDocument = $this->doRenderDocument();
|
||||
|
||||
$this->postRenderValidate();
|
||||
|
||||
return $renderedDocument;
|
||||
}
|
||||
|
||||
/** @return Node[] */
|
||||
public function getNodes(?callable $function = null): array
|
||||
{
|
||||
$nodes = [];
|
||||
|
||||
if ($function === null) {
|
||||
return $this->nodes;
|
||||
}
|
||||
|
||||
foreach ($this->nodes as $node) {
|
||||
if (! $function($node)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$nodes[] = $node;
|
||||
}
|
||||
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
foreach ($this->nodes as $node) {
|
||||
if ($node instanceof TitleNode && $node->getLevel() === 1) {
|
||||
return $node->getValue()->render() . '';
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return mixed[] */
|
||||
public function getTocs(): array
|
||||
{
|
||||
$tocs = [];
|
||||
|
||||
$nodes = $this->getNodes(static function ($node): bool {
|
||||
return $node instanceof TocNode;
|
||||
});
|
||||
|
||||
foreach ($nodes as $toc) {
|
||||
assert($toc instanceof TocNode);
|
||||
$files = $toc->getFiles();
|
||||
|
||||
foreach ($files as &$file) {
|
||||
$file = $this->environment->canonicalUrl($file);
|
||||
}
|
||||
|
||||
$tocs[] = $files;
|
||||
}
|
||||
|
||||
return $tocs;
|
||||
}
|
||||
|
||||
/** @return string[][] */
|
||||
public function getTitles(): array
|
||||
{
|
||||
$titles = [];
|
||||
$levels = [&$titles];
|
||||
|
||||
foreach ($this->nodes as $node) {
|
||||
if (! ($node instanceof TitleNode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$level = $node->getLevel();
|
||||
$text = $node->getValue()->getText();
|
||||
$redirection = $node->getTarget();
|
||||
$value = $redirection !== '' ? [$text, $redirection] : $text;
|
||||
|
||||
if (! isset($levels[$level - 1])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parent = &$levels[$level - 1];
|
||||
$element = [$value, []];
|
||||
$parent[] = $element;
|
||||
$levels[$level] = &$parent[count($parent) - 1][1];
|
||||
}
|
||||
|
||||
return $titles;
|
||||
}
|
||||
|
||||
/** @param string|Node $node */
|
||||
public function addNode($node): void
|
||||
{
|
||||
if (is_string($node)) {
|
||||
$node = new RawNode($node);
|
||||
}
|
||||
|
||||
$this->nodes[] = $node;
|
||||
}
|
||||
|
||||
public function prependNode(Node $node): void
|
||||
{
|
||||
array_unshift($this->nodes, $node);
|
||||
}
|
||||
|
||||
public function addHeaderNode(Node $node): void
|
||||
{
|
||||
$this->headerNodes[] = $node;
|
||||
}
|
||||
|
||||
public function addCss(string $css): void
|
||||
{
|
||||
$css = $this->environment->relativeUrl($css);
|
||||
|
||||
if ($css === null) {
|
||||
throw new Exception(sprintf('Could not get relative url for css %s', $css));
|
||||
}
|
||||
|
||||
$this->addHeaderNode($this->environment->getNodeFactory()->createRawNode(
|
||||
$this->environment->getTemplateRenderer()->render('stylesheet-link.html.twig', ['css' => $css])
|
||||
));
|
||||
}
|
||||
|
||||
public function addJs(string $js): void
|
||||
{
|
||||
$js = $this->environment->relativeUrl($js);
|
||||
|
||||
if ($js === null) {
|
||||
throw new Exception(sprintf('Could not get relative url for js %s', $js));
|
||||
}
|
||||
|
||||
$this->addHeaderNode($this->environment->getNodeFactory()->createRawNode(
|
||||
$this->environment->getTemplateRenderer()->render('javascript.html.twig', ['js' => $js])
|
||||
));
|
||||
}
|
||||
|
||||
public function addFavicon(string $url = '/favicon.ico'): void
|
||||
{
|
||||
$url = $this->environment->relativeUrl($url);
|
||||
|
||||
if ($url === null) {
|
||||
throw new Exception(sprintf('Could not get relative url for favicon %s', $url));
|
||||
}
|
||||
|
||||
$this->addHeaderNode($this->environment->getNodeFactory()->createRawNode(
|
||||
$this->environment->getTemplateRenderer()->render('favicon.html.twig', ['url' => $url])
|
||||
));
|
||||
}
|
||||
|
||||
protected function doRenderDocument(): string
|
||||
{
|
||||
$renderer = $this->getRenderer();
|
||||
assert($renderer instanceof FullDocumentNodeRenderer);
|
||||
|
||||
return $renderer->renderDocument();
|
||||
}
|
||||
|
||||
private function postRenderValidate(): void
|
||||
{
|
||||
if ($this->configuration->getIgnoreInvalidReferences() !== false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$currentFileName = $this->environment->getCurrentFileName();
|
||||
|
||||
foreach ($this->environment->getInvalidLinks() as $invalidLink) {
|
||||
$this->errorManager->error(
|
||||
sprintf('Found invalid reference "%s"', $invalidLink->getName()),
|
||||
$currentFileName
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
24
vendor/doctrine/rst-parser/lib/Nodes/DummyNode.php
vendored
Normal file
24
vendor/doctrine/rst-parser/lib/Nodes/DummyNode.php
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class DummyNode extends Node
|
||||
{
|
||||
/** @var mixed[] */
|
||||
public $data;
|
||||
|
||||
/** @param mixed[] $data */
|
||||
public function __construct(array $data)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
protected function doRender(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
32
vendor/doctrine/rst-parser/lib/Nodes/FigureNode.php
vendored
Normal file
32
vendor/doctrine/rst-parser/lib/Nodes/FigureNode.php
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class FigureNode extends Node
|
||||
{
|
||||
/** @var ImageNode */
|
||||
private $image;
|
||||
|
||||
/** @var Node|null */
|
||||
private $document;
|
||||
|
||||
public function __construct(ImageNode $image, ?Node $document = null)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->image = $image;
|
||||
$this->document = $document;
|
||||
}
|
||||
|
||||
public function getImage(): ImageNode
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
public function getDocument(): ?Node
|
||||
{
|
||||
return $this->document;
|
||||
}
|
||||
}
|
34
vendor/doctrine/rst-parser/lib/Nodes/ImageNode.php
vendored
Normal file
34
vendor/doctrine/rst-parser/lib/Nodes/ImageNode.php
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class ImageNode extends Node
|
||||
{
|
||||
/** @var string */
|
||||
private $url;
|
||||
|
||||
/** @var string[] */
|
||||
private $options;
|
||||
|
||||
/** @param string[] $options */
|
||||
public function __construct(string $url, array $options = [])
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->url = $url;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
public function getUrl(): string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
}
|
36
vendor/doctrine/rst-parser/lib/Nodes/ListNode.php
vendored
Normal file
36
vendor/doctrine/rst-parser/lib/Nodes/ListNode.php
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
use Doctrine\RST\Parser\ListItem;
|
||||
|
||||
class ListNode extends Node
|
||||
{
|
||||
/** @var bool */
|
||||
private $ordered;
|
||||
|
||||
/** @var ListItem[] */
|
||||
private $items;
|
||||
|
||||
/** @param ListItem[] $items */
|
||||
public function __construct(array $items, bool $ordered)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->items = $items;
|
||||
$this->ordered = $ordered;
|
||||
}
|
||||
|
||||
/** @return ListItem[] */
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
public function isOrdered(): bool
|
||||
{
|
||||
return $this->ordered;
|
||||
}
|
||||
}
|
9
vendor/doctrine/rst-parser/lib/Nodes/MainNode.php
vendored
Normal file
9
vendor/doctrine/rst-parser/lib/Nodes/MainNode.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class MainNode extends Node
|
||||
{
|
||||
}
|
32
vendor/doctrine/rst-parser/lib/Nodes/MetaNode.php
vendored
Normal file
32
vendor/doctrine/rst-parser/lib/Nodes/MetaNode.php
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class MetaNode extends Node
|
||||
{
|
||||
/** @var string */
|
||||
private $key;
|
||||
|
||||
/** @var string */
|
||||
protected $value;
|
||||
|
||||
public function __construct(string $key, string $value)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->key = $key;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
192
vendor/doctrine/rst-parser/lib/Nodes/Node.php
vendored
Normal file
192
vendor/doctrine/rst-parser/lib/Nodes/Node.php
vendored
Normal file
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
use Doctrine\Common\EventArgs;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\RST\Environment;
|
||||
use Doctrine\RST\Event\PostNodeRenderEvent;
|
||||
use Doctrine\RST\Event\PreNodeRenderEvent;
|
||||
use Doctrine\RST\Renderers\DefaultNodeRenderer;
|
||||
use Doctrine\RST\Renderers\NodeRenderer;
|
||||
use Doctrine\RST\Renderers\NodeRendererFactory;
|
||||
use Doctrine\RST\Renderers\RenderedNode;
|
||||
|
||||
use function implode;
|
||||
use function ltrim;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use function trim;
|
||||
|
||||
abstract class Node
|
||||
{
|
||||
/** @var NodeRendererFactory|null */
|
||||
private $nodeRendererFactory;
|
||||
|
||||
/** @var EventManager|null */
|
||||
private $eventManager;
|
||||
|
||||
/** @var Environment|null */
|
||||
protected $environment;
|
||||
|
||||
/** @var Node|string|null */
|
||||
protected $value;
|
||||
|
||||
/** @var string[] */
|
||||
private $classes = [];
|
||||
|
||||
/** @param Node|string|null $value */
|
||||
public function __construct($value = null)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function setNodeRendererFactory(NodeRendererFactory $nodeRendererFactory): void
|
||||
{
|
||||
$this->nodeRendererFactory = $nodeRendererFactory;
|
||||
}
|
||||
|
||||
public function setEventManager(EventManager $eventManager): void
|
||||
{
|
||||
$this->eventManager = $eventManager;
|
||||
}
|
||||
|
||||
public function setEnvironment(Environment $environment): void
|
||||
{
|
||||
$this->environment = $environment;
|
||||
}
|
||||
|
||||
public function getEnvironment(): ?Environment
|
||||
{
|
||||
return $this->environment;
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$this->dispatchEvent(
|
||||
PreNodeRenderEvent::PRE_NODE_RENDER,
|
||||
new PreNodeRenderEvent($this)
|
||||
);
|
||||
|
||||
$renderedNode = new RenderedNode($this, $this->doRender());
|
||||
|
||||
$this->dispatchEvent(
|
||||
PostNodeRenderEvent::POST_NODE_RENDER,
|
||||
new PostNodeRenderEvent($renderedNode)
|
||||
);
|
||||
|
||||
return $renderedNode->getRendered();
|
||||
}
|
||||
|
||||
/** @return Node|string|null */
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/** @param Node|string|null $value */
|
||||
public function setValue($value): void
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getClasses(): array
|
||||
{
|
||||
return $this->classes;
|
||||
}
|
||||
|
||||
public function getClassesString(): string
|
||||
{
|
||||
return implode(' ', $this->classes);
|
||||
}
|
||||
|
||||
/** @param string[] $classes */
|
||||
public function setClasses(array $classes): void
|
||||
{
|
||||
$this->classes = $classes;
|
||||
}
|
||||
|
||||
public function getValueString(): string
|
||||
{
|
||||
if ($this->value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($this->value instanceof Node) {
|
||||
return $this->value->getValueString();
|
||||
}
|
||||
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/** @param string[] $lines */
|
||||
protected function normalizeLines(array $lines): string
|
||||
{
|
||||
if ($lines !== []) {
|
||||
$indentLevel = null;
|
||||
|
||||
// find the indentation by locating the line with the fewest preceding whitespace
|
||||
foreach ($lines as $line) {
|
||||
// skip empty lines
|
||||
if (trim($line) === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$startingWhitespace = strlen($line) - strlen(ltrim($line));
|
||||
if ($indentLevel !== null && $startingWhitespace > $indentLevel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$indentLevel = $startingWhitespace;
|
||||
}
|
||||
|
||||
foreach ($lines as &$line) {
|
||||
$line = substr($line, $indentLevel);
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
protected function doRender(): string
|
||||
{
|
||||
return $this->getRenderer()->render();
|
||||
}
|
||||
|
||||
protected function getRenderer(): NodeRenderer
|
||||
{
|
||||
$renderer = $this->createRenderer();
|
||||
|
||||
if ($renderer !== null) {
|
||||
return $renderer;
|
||||
}
|
||||
|
||||
return $this->createDefaultRenderer();
|
||||
}
|
||||
|
||||
private function createRenderer(): ?NodeRenderer
|
||||
{
|
||||
if ($this->nodeRendererFactory !== null) {
|
||||
return $this->nodeRendererFactory->create($this);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function createDefaultRenderer(): NodeRenderer
|
||||
{
|
||||
return new DefaultNodeRenderer($this);
|
||||
}
|
||||
|
||||
public function dispatchEvent(string $eventName, ?EventArgs $eventArgs = null): void
|
||||
{
|
||||
if ($this->eventManager === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->eventManager->dispatchEvent($eventName, $eventArgs);
|
||||
}
|
||||
}
|
64
vendor/doctrine/rst-parser/lib/Nodes/NodeTypes.php
vendored
Normal file
64
vendor/doctrine/rst-parser/lib/Nodes/NodeTypes.php
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class NodeTypes
|
||||
{
|
||||
public const DOCUMENT = 'document';
|
||||
public const DOCUMENT_NODE = 'document_node';
|
||||
public const TOC = 'toc';
|
||||
public const TITLE = 'title';
|
||||
public const SEPARATOR = 'separator';
|
||||
public const CODE = 'code';
|
||||
public const QUOTE = 'quote';
|
||||
public const PARAGRAPH = 'paragraph';
|
||||
public const ANCHOR = 'anchor';
|
||||
public const LIST = 'list';
|
||||
public const TABLE = 'table';
|
||||
public const SPAN = 'span';
|
||||
public const DEFINITION_LIST = 'definition_list';
|
||||
public const WRAPPER = 'wrapper';
|
||||
public const FIGURE = 'figure';
|
||||
public const IMAGE = 'image';
|
||||
public const META = 'meta';
|
||||
public const RAW = 'raw';
|
||||
public const DUMMY = 'dummy';
|
||||
public const MAIN = 'main';
|
||||
public const BLOCK = 'block';
|
||||
public const CALLABLE = 'callable';
|
||||
public const SECTION_BEGIN = 'section_begin';
|
||||
public const SECTION_END = 'section_end';
|
||||
|
||||
public const NODES = [
|
||||
self::DOCUMENT,
|
||||
self::DOCUMENT_NODE,
|
||||
self::TOC,
|
||||
self::TITLE,
|
||||
self::SEPARATOR,
|
||||
self::CODE,
|
||||
self::QUOTE,
|
||||
self::PARAGRAPH,
|
||||
self::ANCHOR,
|
||||
self::LIST,
|
||||
self::TABLE,
|
||||
self::SPAN,
|
||||
self::DEFINITION_LIST,
|
||||
self::WRAPPER,
|
||||
self::FIGURE,
|
||||
self::IMAGE,
|
||||
self::META,
|
||||
self::RAW,
|
||||
self::DUMMY,
|
||||
self::MAIN,
|
||||
self::BLOCK,
|
||||
self::CALLABLE,
|
||||
self::SECTION_BEGIN,
|
||||
self::SECTION_END,
|
||||
];
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
}
|
21
vendor/doctrine/rst-parser/lib/Nodes/ParagraphNode.php
vendored
Normal file
21
vendor/doctrine/rst-parser/lib/Nodes/ParagraphNode.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
class ParagraphNode extends Node
|
||||
{
|
||||
/** @var SpanNode */
|
||||
protected $value;
|
||||
|
||||
public function __construct(SpanNode $value)
|
||||
{
|
||||
parent::__construct($value);
|
||||
}
|
||||
|
||||
public function getValue(): SpanNode
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
26
vendor/doctrine/rst-parser/lib/Nodes/QuoteNode.php
vendored
Normal file
26
vendor/doctrine/rst-parser/lib/Nodes/QuoteNode.php
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
/**
|
||||
* Represents a "Block Quote"
|
||||
*
|
||||
* @see https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#block-quotes
|
||||
*/
|
||||
class QuoteNode extends Node
|
||||
{
|
||||
/** @var DocumentNode */
|
||||
protected $value;
|
||||
|
||||
public function __construct(DocumentNode $documentNode)
|
||||
{
|
||||
parent::__construct($documentNode);
|
||||
}
|
||||
|
||||
public function getValue(): DocumentNode
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
9
vendor/doctrine/rst-parser/lib/Nodes/RawNode.php
vendored
Normal file
9
vendor/doctrine/rst-parser/lib/Nodes/RawNode.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class RawNode extends Node
|
||||
{
|
||||
}
|
23
vendor/doctrine/rst-parser/lib/Nodes/SectionBeginNode.php
vendored
Normal file
23
vendor/doctrine/rst-parser/lib/Nodes/SectionBeginNode.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class SectionBeginNode extends Node
|
||||
{
|
||||
/** @var TitleNode */
|
||||
private $titleNode;
|
||||
|
||||
public function __construct(TitleNode $titleNode)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->titleNode = $titleNode;
|
||||
}
|
||||
|
||||
public function getTitleNode(): TitleNode
|
||||
{
|
||||
return $this->titleNode;
|
||||
}
|
||||
}
|
23
vendor/doctrine/rst-parser/lib/Nodes/SectionEndNode.php
vendored
Normal file
23
vendor/doctrine/rst-parser/lib/Nodes/SectionEndNode.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class SectionEndNode extends Node
|
||||
{
|
||||
/** @var TitleNode */
|
||||
private $titleNode;
|
||||
|
||||
public function __construct(TitleNode $titleNode)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->titleNode = $titleNode;
|
||||
}
|
||||
|
||||
public function getTitleNode(): TitleNode
|
||||
{
|
||||
return $this->titleNode;
|
||||
}
|
||||
}
|
23
vendor/doctrine/rst-parser/lib/Nodes/SeparatorNode.php
vendored
Normal file
23
vendor/doctrine/rst-parser/lib/Nodes/SeparatorNode.php
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
class SeparatorNode extends Node
|
||||
{
|
||||
/** @var int */
|
||||
private $level;
|
||||
|
||||
public function __construct(int $level)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
public function getLevel(): int
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
}
|
71
vendor/doctrine/rst-parser/lib/Nodes/SpanNode.php
vendored
Normal file
71
vendor/doctrine/rst-parser/lib/Nodes/SpanNode.php
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
use Doctrine\RST\Environment;
|
||||
use Doctrine\RST\Parser;
|
||||
use Doctrine\RST\Span\SpanProcessor;
|
||||
use Doctrine\RST\Span\SpanToken;
|
||||
|
||||
use function implode;
|
||||
use function is_array;
|
||||
|
||||
class SpanNode extends Node
|
||||
{
|
||||
/** @var string */
|
||||
protected $value;
|
||||
|
||||
/** @var string */
|
||||
private $text;
|
||||
|
||||
/** @var Environment */
|
||||
protected $environment;
|
||||
|
||||
/** @var SpanToken[] */
|
||||
private $tokens;
|
||||
|
||||
/** @param string|string[]|SpanNode $span */
|
||||
public function __construct(Parser $parser, $span)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->environment = $parser->getEnvironment();
|
||||
|
||||
if (is_array($span)) {
|
||||
$span = implode("\n", $span);
|
||||
}
|
||||
|
||||
if ($span instanceof SpanNode) {
|
||||
$span = $span->render();
|
||||
}
|
||||
|
||||
$spanProcessor = new SpanProcessor($this->environment, $span);
|
||||
|
||||
$this->value = $spanProcessor->process();
|
||||
$this->text = $spanProcessor->getText($this->value);
|
||||
$this->tokens = $spanProcessor->getTokens();
|
||||
}
|
||||
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/** @return SpanToken[] */
|
||||
public function getTokens(): array
|
||||
{
|
||||
return $this->tokens;
|
||||
}
|
||||
|
||||
public function getEnvironment(): Environment
|
||||
{
|
||||
return $this->environment;
|
||||
}
|
||||
|
||||
public function getText(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
}
|
97
vendor/doctrine/rst-parser/lib/Nodes/Table/TableColumn.php
vendored
Normal file
97
vendor/doctrine/rst-parser/lib/Nodes/Table/TableColumn.php
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes\Table;
|
||||
|
||||
use Doctrine\RST\Nodes\Node;
|
||||
use LogicException;
|
||||
|
||||
use function mb_convert_encoding;
|
||||
use function strlen;
|
||||
use function trim;
|
||||
|
||||
final class TableColumn
|
||||
{
|
||||
/** @var string */
|
||||
private $content;
|
||||
|
||||
/** @var int */
|
||||
private $colSpan;
|
||||
|
||||
/** @var int */
|
||||
private $rowSpan = 1;
|
||||
|
||||
/** @var Node|null */
|
||||
private $node;
|
||||
|
||||
public function __construct(string $content, int $colSpan)
|
||||
{
|
||||
$this->content = mb_convert_encoding(trim($content), 'UTF-8', 'ISO-8859-1');
|
||||
$this->colSpan = $colSpan;
|
||||
}
|
||||
|
||||
public function getContent(): string
|
||||
{
|
||||
// "\" is a special way to make a column "empty", but
|
||||
// still indicate that you *want* that column
|
||||
if ($this->content === '\\') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function getColSpan(): int
|
||||
{
|
||||
return $this->colSpan;
|
||||
}
|
||||
|
||||
public function getRowSpan(): int
|
||||
{
|
||||
return $this->rowSpan;
|
||||
}
|
||||
|
||||
public function addContent(string $content): void
|
||||
{
|
||||
$this->content = trim($this->content . $content);
|
||||
}
|
||||
|
||||
public function incrementRowSpan(): void
|
||||
{
|
||||
$this->rowSpan++;
|
||||
}
|
||||
|
||||
public function getNode(): Node
|
||||
{
|
||||
if ($this->node === null) {
|
||||
throw new LogicException('The node is not yet set.');
|
||||
}
|
||||
|
||||
return $this->node;
|
||||
}
|
||||
|
||||
public function setNode(Node $node): void
|
||||
{
|
||||
$this->node = $node;
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
$rendered = $this->getNode()->render();
|
||||
|
||||
if ($rendered === '' && $this->content !== '\\') {
|
||||
$rendered = ' ';
|
||||
}
|
||||
|
||||
return $rendered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that a column is empty, and could be skipped entirely.
|
||||
*/
|
||||
public function isCompletelyEmpty(): bool
|
||||
{
|
||||
return strlen($this->content) === 0;
|
||||
}
|
||||
}
|
84
vendor/doctrine/rst-parser/lib/Nodes/Table/TableRow.php
vendored
Normal file
84
vendor/doctrine/rst-parser/lib/Nodes/Table/TableRow.php
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes\Table;
|
||||
|
||||
use Doctrine\RST\Exception\InvalidTableStructure;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
|
||||
use function array_map;
|
||||
use function implode;
|
||||
use function sprintf;
|
||||
|
||||
final class TableRow
|
||||
{
|
||||
/** @var TableColumn[] */
|
||||
private $columns = [];
|
||||
|
||||
public function addColumn(string $content, int $colSpan): void
|
||||
{
|
||||
$this->columns[] = new TableColumn($content, $colSpan);
|
||||
}
|
||||
|
||||
/** @return TableColumn[] */
|
||||
public function getColumns(): array
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
public function getColumn(int $index): ?TableColumn
|
||||
{
|
||||
return $this->columns[$index] ?? null;
|
||||
}
|
||||
|
||||
public function getFirstColumn(): TableColumn
|
||||
{
|
||||
$column = $this->getColumn(0);
|
||||
|
||||
if ($column === null) {
|
||||
throw new LogicException('Row has no columns');
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push the content from the columns of a row onto this row.
|
||||
*
|
||||
* Useful when we discover that a row is actually just a continuation
|
||||
* of this row, and so we want to copy the content to this row's
|
||||
* columns before removing the row.
|
||||
*
|
||||
* @throws InvalidTableStructure
|
||||
*/
|
||||
public function absorbRowContent(TableRow $targetRow): void
|
||||
{
|
||||
// iterate over each column and combine the content
|
||||
foreach ($this->getColumns() as $columnIndex => $column) {
|
||||
$targetColumn = $targetRow->getColumn($columnIndex);
|
||||
if ($targetColumn === null) {
|
||||
throw new InvalidTableStructure(sprintf('Malformed table: lines "%s" and "%s" appear to be in the same row, but don\'t share the same number of columns.', $this->toString(), $targetRow->toString()));
|
||||
}
|
||||
|
||||
$column->addContent("\n" . $targetColumn->getContent());
|
||||
}
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return implode(' | ', array_map(static function (TableColumn $column): string {
|
||||
return $column->getContent();
|
||||
}, $this->columns));
|
||||
}
|
||||
|
||||
public function removeColumn(int $columnIndex): void
|
||||
{
|
||||
if ($this->getColumn($columnIndex) === null) {
|
||||
throw new InvalidArgumentException(sprintf('Bad column index "%d"', $columnIndex));
|
||||
}
|
||||
|
||||
unset($this->columns[$columnIndex]);
|
||||
}
|
||||
}
|
534
vendor/doctrine/rst-parser/lib/Nodes/TableNode.php
vendored
Normal file
534
vendor/doctrine/rst-parser/lib/Nodes/TableNode.php
vendored
Normal file
|
@ -0,0 +1,534 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
use Doctrine\RST\Exception\InvalidTableStructure;
|
||||
use Doctrine\RST\Nodes\Table\TableColumn;
|
||||
use Doctrine\RST\Nodes\Table\TableRow;
|
||||
use Doctrine\RST\Parser;
|
||||
use Doctrine\RST\Parser\LineChecker;
|
||||
use Doctrine\RST\Parser\TableSeparatorLineConfig;
|
||||
use Exception;
|
||||
use LogicException;
|
||||
|
||||
use function array_keys;
|
||||
use function array_reverse;
|
||||
use function array_values;
|
||||
use function count;
|
||||
use function explode;
|
||||
use function implode;
|
||||
use function ksort;
|
||||
use function max;
|
||||
use function mb_convert_encoding;
|
||||
use function preg_match;
|
||||
use function sprintf;
|
||||
use function str_repeat;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
use function trim;
|
||||
|
||||
class TableNode extends Node
|
||||
{
|
||||
public const TYPE_SIMPLE = 'simple';
|
||||
public const TYPE_PRETTY = 'pretty';
|
||||
|
||||
/** @var TableSeparatorLineConfig[] */
|
||||
private $separatorLineConfigs = [];
|
||||
|
||||
/** @var string[] */
|
||||
private $rawDataLines = [];
|
||||
|
||||
/** @var int */
|
||||
private $currentLineNumber = 0;
|
||||
|
||||
/** @var bool */
|
||||
private $isCompiled = false;
|
||||
|
||||
/** @var TableRow[] */
|
||||
protected $data = [];
|
||||
|
||||
/** @var bool[] */
|
||||
protected $headers = [];
|
||||
|
||||
/** @var string[] */
|
||||
private $errors = [];
|
||||
|
||||
/** @var string */
|
||||
protected $type;
|
||||
|
||||
/** @var LineChecker */
|
||||
private $lineChecker;
|
||||
|
||||
public function __construct(TableSeparatorLineConfig $separatorLineConfig, string $type, LineChecker $lineChecker)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->pushSeparatorLine($separatorLineConfig);
|
||||
$this->type = $type;
|
||||
$this->lineChecker = $lineChecker;
|
||||
}
|
||||
|
||||
public function getCols(): int
|
||||
{
|
||||
if ($this->isCompiled === false) {
|
||||
throw new LogicException('Call compile() first.');
|
||||
}
|
||||
|
||||
$columns = 0;
|
||||
foreach ($this->data as $row) {
|
||||
$columns = max($columns, count($row->getColumns()));
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function getRows(): int
|
||||
{
|
||||
if ($this->isCompiled === false) {
|
||||
throw new LogicException('Call compile() first.');
|
||||
}
|
||||
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/** @return TableRow[] */
|
||||
public function getData(): array
|
||||
{
|
||||
if ($this->isCompiled === false) {
|
||||
throw new LogicException('Call compile() first.');
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an of array of which rows should be headers,
|
||||
* where the row index is the key of the array and
|
||||
* the value is always true.
|
||||
*
|
||||
* @return bool[]
|
||||
*/
|
||||
public function getHeaders(): array
|
||||
{
|
||||
if ($this->isCompiled === false) {
|
||||
throw new LogicException('Call compile() first.');
|
||||
}
|
||||
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
public function pushSeparatorLine(TableSeparatorLineConfig $separatorLineConfig): void
|
||||
{
|
||||
if ($this->isCompiled === true) {
|
||||
throw new LogicException('Cannot push data after TableNode is compiled');
|
||||
}
|
||||
|
||||
$this->separatorLineConfigs[$this->currentLineNumber] = $separatorLineConfig;
|
||||
$this->currentLineNumber++;
|
||||
}
|
||||
|
||||
public function pushContentLine(string $line): void
|
||||
{
|
||||
if ($this->isCompiled === true) {
|
||||
throw new LogicException('Cannot push data after TableNode is compiled');
|
||||
}
|
||||
|
||||
$this->rawDataLines[$this->currentLineNumber] = mb_convert_encoding($line, 'ISO-8859-1', 'UTF-8');
|
||||
$this->currentLineNumber++;
|
||||
}
|
||||
|
||||
public function finalize(Parser $parser): void
|
||||
{
|
||||
if ($this->isCompiled === false) {
|
||||
$this->compile();
|
||||
}
|
||||
|
||||
$tableAsString = $this->getTableAsString();
|
||||
|
||||
if (count($this->errors) > 0) {
|
||||
$parser->getEnvironment()
|
||||
->getErrorManager()
|
||||
->error(sprintf("%s\n\n%s", $this->errors[0], $tableAsString), $parser->getFilename());
|
||||
|
||||
$this->data = [];
|
||||
$this->headers = [];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->data as $i => $row) {
|
||||
foreach ($row->getColumns() as $col) {
|
||||
$lines = explode("\n", $col->getContent());
|
||||
|
||||
if ($this->lineChecker->isListLine($lines[0])) {
|
||||
$node = $parser->parseFragment($col->getContent())->getNodes()[0];
|
||||
} else {
|
||||
$node = $parser->createSpanNode($col->getContent());
|
||||
}
|
||||
|
||||
$col->setNode($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks at all the raw data and finally populates the data
|
||||
* and headers.
|
||||
*/
|
||||
private function compile(): void
|
||||
{
|
||||
$this->isCompiled = true;
|
||||
|
||||
if ($this->type === self::TYPE_SIMPLE) {
|
||||
$this->compileSimpleTable();
|
||||
} else {
|
||||
$this->compilePrettyTable();
|
||||
}
|
||||
}
|
||||
|
||||
private function compileSimpleTable(): void
|
||||
{
|
||||
// determine if there is second === separator line (other than
|
||||
// the last line): this would mean there are header rows
|
||||
$finalHeadersRow = 0;
|
||||
foreach ($this->separatorLineConfigs as $i => $separatorLine) {
|
||||
// skip the first line: we're looking for the *next* line
|
||||
if ($i === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// we found the next ==== line
|
||||
if ($separatorLine->getLineCharacter() === '=') {
|
||||
// found the end of the header rows
|
||||
$finalHeadersRow = $i;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the final header row is *after* the last data line, it's not
|
||||
// really a header "ending" and so there are no headers
|
||||
$lastDataLineNumber = array_keys($this->rawDataLines)[count($this->rawDataLines) - 1];
|
||||
if ($finalHeadersRow > $lastDataLineNumber) {
|
||||
$finalHeadersRow = 0;
|
||||
}
|
||||
|
||||
// todo - support "---" in the future for colspan
|
||||
$columnRanges = $this->separatorLineConfigs[0]->getPartRanges();
|
||||
$lastColumnRangeEnd = array_values($columnRanges)[count($columnRanges) - 1][1];
|
||||
foreach ($this->rawDataLines as $i => $line) {
|
||||
$row = new TableRow();
|
||||
// loop over where all the columns should be
|
||||
|
||||
$previousColumnEnd = null;
|
||||
foreach ($columnRanges as $columnRange) {
|
||||
$isRangeBeyondText = $columnRange[0] >= strlen($line);
|
||||
// check for content in the "gap"
|
||||
if ($previousColumnEnd !== null && ! $isRangeBeyondText) {
|
||||
$gapText = substr($line, $previousColumnEnd, $columnRange[0] - $previousColumnEnd);
|
||||
if (strlen(trim($gapText)) !== 0) {
|
||||
$this->addError(sprintf('Malformed table: content "%s" appears in the "gap" on row "%s"', $gapText, $line));
|
||||
}
|
||||
}
|
||||
|
||||
if ($isRangeBeyondText) {
|
||||
// the text for this line ended earlier. This column should be blank
|
||||
|
||||
$content = '';
|
||||
} elseif ($lastColumnRangeEnd === $columnRange[1]) {
|
||||
// this is the last column, so get the rest of the line
|
||||
// this is because content can go *beyond* the table legally
|
||||
$content = substr(
|
||||
$line,
|
||||
$columnRange[0]
|
||||
);
|
||||
} else {
|
||||
$content = substr(
|
||||
$line,
|
||||
$columnRange[0],
|
||||
$columnRange[1] - $columnRange[0]
|
||||
);
|
||||
}
|
||||
|
||||
$content = trim($content);
|
||||
$row->addColumn($content, 1);
|
||||
|
||||
$previousColumnEnd = $columnRange[1];
|
||||
}
|
||||
|
||||
// is header row?
|
||||
if ($i <= $finalHeadersRow) {
|
||||
$this->headers[$i] = true;
|
||||
}
|
||||
|
||||
$this->data[$i] = $row;
|
||||
}
|
||||
|
||||
$previousRow = null;
|
||||
// check for empty first columns, which means this is
|
||||
// not a new row, but the continuation of the previous row
|
||||
foreach ($this->data as $i => $row) {
|
||||
if ($row->getFirstColumn()->isCompletelyEmpty() && $previousRow !== null) {
|
||||
try {
|
||||
$previousRow->absorbRowContent($row);
|
||||
} catch (InvalidTableStructure $e) {
|
||||
$this->addError($e->getMessage());
|
||||
}
|
||||
|
||||
unset($this->data[$i]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$previousRow = $row;
|
||||
}
|
||||
}
|
||||
|
||||
private function compilePrettyTable(): void
|
||||
{
|
||||
// loop over ALL separator lines to find ALL of the column ranges
|
||||
$columnRanges = [];
|
||||
$finalHeadersRow = 0;
|
||||
foreach ($this->separatorLineConfigs as $rowIndex => $separatorLine) {
|
||||
if ($separatorLine->isHeader()) {
|
||||
if ($finalHeadersRow !== 0) {
|
||||
$this->addError(sprintf('Malformed table: multiple "header rows" using "===" were found. See table lines "%d" and "%d"', $finalHeadersRow + 1, $rowIndex));
|
||||
}
|
||||
|
||||
// indicates that "=" was used
|
||||
$finalHeadersRow = $rowIndex - 1;
|
||||
}
|
||||
|
||||
foreach ($separatorLine->getPartRanges() as $columnRange) {
|
||||
$colStart = $columnRange[0];
|
||||
$colEnd = $columnRange[1];
|
||||
|
||||
// we don't have this "start" yet? just add it
|
||||
// in theory, should only happen for the first row
|
||||
if (! isset($columnRanges[$colStart])) {
|
||||
$columnRanges[$colStart] = $colEnd;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// an exact column range we've already seen
|
||||
// OR, this new column goes beyond what we currently
|
||||
// have recorded, which means its a colspan, and so
|
||||
// we already have correctly recorded the "smallest"
|
||||
// current column ranges
|
||||
if ($columnRanges[$colStart] <= $colEnd) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// this is not a new "start", but it is a new "end"
|
||||
// this means that we've found a "shorter" column that
|
||||
// we've seen before. We need to update the "end" of
|
||||
// the existing column, and add a "new" column
|
||||
$previousEnd = $columnRanges[$colStart];
|
||||
|
||||
// A) update the end of this column to the new end
|
||||
$columnRanges[$colStart] = $colEnd;
|
||||
// B) add a new column from this new end, to the previous end
|
||||
$columnRanges[$colEnd + 1] = $previousEnd;
|
||||
ksort($columnRanges);
|
||||
}
|
||||
}
|
||||
|
||||
/** @var TableRow[] $rows */
|
||||
$rows = [];
|
||||
$partialSeparatorRows = [];
|
||||
foreach ($this->rawDataLines as $rowIndex => $line) {
|
||||
$row = new TableRow();
|
||||
|
||||
// if the row is part separator row, part content, this
|
||||
// is a rowspan situation - e.g.
|
||||
// | +----------------+----------------------------+
|
||||
// look for +-----+ pattern
|
||||
if (preg_match('/\+[-]+\+/', $this->rawDataLines[$rowIndex]) === 1) {
|
||||
$partialSeparatorRows[$rowIndex] = true;
|
||||
}
|
||||
|
||||
$currentColumnStart = null;
|
||||
$currentSpan = 1;
|
||||
$previousColumnEnd = null;
|
||||
foreach ($columnRanges as $start => $end) {
|
||||
// a content line that ends before it should
|
||||
if ($end >= strlen($line)) {
|
||||
$this->errors[] = sprintf("Malformed table: Line\n\n%s\n\ndoes not appear to be a complete table row", $line);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ($currentColumnStart !== null) {
|
||||
$gapText = substr($line, $previousColumnEnd, $start - $previousColumnEnd);
|
||||
if (strpos($gapText, '|') === false && strpos($gapText, '+') === false) {
|
||||
// text continued through the "gap". This is a colspan
|
||||
// "+" is an odd character - it's usually "|", but "+" can
|
||||
// happen in row-span situations
|
||||
$currentSpan++;
|
||||
} else {
|
||||
// we just hit a proper "gap" record the line up until now
|
||||
$row->addColumn(
|
||||
substr($line, $currentColumnStart, $previousColumnEnd - $currentColumnStart),
|
||||
$currentSpan
|
||||
);
|
||||
$currentSpan = 1;
|
||||
$currentColumnStart = null;
|
||||
}
|
||||
}
|
||||
|
||||
// if the current column start is null, then set it
|
||||
// other wise, leave it - this is a colspan, and eventually
|
||||
// we want to get all the text starting here
|
||||
if ($currentColumnStart === null) {
|
||||
$currentColumnStart = $start;
|
||||
}
|
||||
|
||||
$previousColumnEnd = $end;
|
||||
}
|
||||
|
||||
// record the last column
|
||||
if ($currentColumnStart !== null) {
|
||||
if ($previousColumnEnd === null) {
|
||||
throw new LogicException('The previous column end is not set yet');
|
||||
}
|
||||
|
||||
$row->addColumn(
|
||||
substr($line, $currentColumnStart, $previousColumnEnd - $currentColumnStart),
|
||||
$currentSpan
|
||||
);
|
||||
}
|
||||
|
||||
$rows[$rowIndex] = $row;
|
||||
}
|
||||
|
||||
$columnIndexesCurrentlyInRowspan = [];
|
||||
foreach ($rows as $rowIndex => $row) {
|
||||
if (isset($partialSeparatorRows[$rowIndex])) {
|
||||
// this row is part content, part separator due to a rowspan
|
||||
// for each column that contains content, we need to
|
||||
// push it onto the last real row's content and record
|
||||
// that this column in the next row should also be
|
||||
// included in that previous row's content
|
||||
foreach ($row->getColumns() as $columnIndex => $column) {
|
||||
if (! $column->isCompletelyEmpty() && str_repeat('-', strlen($column->getContent())) === $column->getContent()) {
|
||||
// only a line separator in this column - not content!
|
||||
continue;
|
||||
}
|
||||
|
||||
$prevTargetColumn = $this->findColumnInPreviousRows((int) $columnIndex, $rows, (int) $rowIndex);
|
||||
$prevTargetColumn->addContent("\n" . $column->getContent());
|
||||
$prevTargetColumn->incrementRowSpan();
|
||||
// mark that this column on the next row should also be added
|
||||
// to the previous row
|
||||
$columnIndexesCurrentlyInRowspan[] = $columnIndex;
|
||||
}
|
||||
|
||||
// remove the row - it's not real
|
||||
unset($rows[$rowIndex]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if the previous row was a partial separator row, and
|
||||
// we need to take some columns and add them to a previous row's content
|
||||
foreach ($columnIndexesCurrentlyInRowspan as $columnIndex) {
|
||||
$prevTargetColumn = $this->findColumnInPreviousRows($columnIndex, $rows, (int) $rowIndex);
|
||||
$columnInRowspan = $row->getColumn($columnIndex);
|
||||
if ($columnInRowspan === null) {
|
||||
throw new LogicException(sprintf('Cannot find column for index "%s"', $columnIndex));
|
||||
}
|
||||
|
||||
$prevTargetColumn->addContent("\n" . $columnInRowspan->getContent());
|
||||
|
||||
// now this column actually needs to be removed from this row,
|
||||
// as it's not a real column that needs to be printed
|
||||
$row->removeColumn($columnIndex);
|
||||
}
|
||||
|
||||
$columnIndexesCurrentlyInRowspan = [];
|
||||
|
||||
// if the next row is just $i+1, it means there
|
||||
// was no "separator" and this is really just a
|
||||
// continuation of this row.
|
||||
$nextRowCounter = 1;
|
||||
while (isset($rows[(int) $rowIndex + $nextRowCounter])) {
|
||||
// but if the next line is actually a partial separator, then
|
||||
// it is not a continuation of the content - quit now
|
||||
if (isset($partialSeparatorRows[(int) $rowIndex + $nextRowCounter])) {
|
||||
break;
|
||||
}
|
||||
|
||||
$targetRow = $rows[(int) $rowIndex + $nextRowCounter];
|
||||
unset($rows[(int) $rowIndex + $nextRowCounter]);
|
||||
|
||||
try {
|
||||
$row->absorbRowContent($targetRow);
|
||||
} catch (InvalidTableStructure $e) {
|
||||
$this->addError($e->getMessage());
|
||||
}
|
||||
|
||||
$nextRowCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
// one more loop to set headers
|
||||
foreach ($rows as $rowIndex => $row) {
|
||||
if ($rowIndex > $finalHeadersRow) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->headers[$rowIndex] = true;
|
||||
}
|
||||
|
||||
$this->data = $rows;
|
||||
}
|
||||
|
||||
private function getTableAsString(): string
|
||||
{
|
||||
$lines = [];
|
||||
$i = 0;
|
||||
while (isset($this->separatorLineConfigs[$i]) || isset($this->rawDataLines[$i])) {
|
||||
if (isset($this->separatorLineConfigs[$i])) {
|
||||
$lines[] = $this->separatorLineConfigs[$i]->getRawContent();
|
||||
} else {
|
||||
$lines[] = $this->rawDataLines[$i];
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
private function addError(string $message): void
|
||||
{
|
||||
$this->errors[] = $message;
|
||||
}
|
||||
|
||||
/** @param TableRow[] $rows */
|
||||
private function findColumnInPreviousRows(int $columnIndex, array $rows, int $currentRowIndex): TableColumn
|
||||
{
|
||||
/** @var TableRow[] $reversedRows */
|
||||
$reversedRows = array_reverse($rows, true);
|
||||
|
||||
// go through the rows backwards to find the last/previous
|
||||
// row that actually had a real column at this position
|
||||
foreach ($reversedRows as $k => $row) {
|
||||
// start by skipping any future rows, as we go backward
|
||||
if ($k >= $currentRowIndex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$prevTargetColumn = $row->getColumn($columnIndex);
|
||||
if ($prevTargetColumn !== null) {
|
||||
return $prevTargetColumn;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception('Could not find column in any previous rows');
|
||||
}
|
||||
}
|
59
vendor/doctrine/rst-parser/lib/Nodes/TitleNode.php
vendored
Normal file
59
vendor/doctrine/rst-parser/lib/Nodes/TitleNode.php
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
use Doctrine\RST\Environment;
|
||||
|
||||
class TitleNode extends Node
|
||||
{
|
||||
/** @var SpanNode */
|
||||
protected $value;
|
||||
|
||||
/** @var int */
|
||||
private $level;
|
||||
|
||||
/** @var string */
|
||||
protected $token;
|
||||
|
||||
/** @var string */
|
||||
private $id;
|
||||
|
||||
/** @var string */
|
||||
private $target = '';
|
||||
|
||||
public function __construct(Node $value, int $level, string $token)
|
||||
{
|
||||
parent::__construct($value);
|
||||
|
||||
$this->level = $level;
|
||||
$this->token = $token;
|
||||
$this->id = Environment::slugify($this->value->getText());
|
||||
}
|
||||
|
||||
public function getValue(): SpanNode
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function getLevel(): int
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
public function setTarget(string $target): void
|
||||
{
|
||||
$this->target = $target;
|
||||
}
|
||||
|
||||
public function getTarget(): string
|
||||
{
|
||||
return $this->target;
|
||||
}
|
||||
|
||||
public function getId(): string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
69
vendor/doctrine/rst-parser/lib/Nodes/TocNode.php
vendored
Normal file
69
vendor/doctrine/rst-parser/lib/Nodes/TocNode.php
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
use Doctrine\RST\Environment;
|
||||
|
||||
class TocNode extends Node
|
||||
{
|
||||
private const DEFAULT_DEPTH = 2;
|
||||
|
||||
/** @var Environment */
|
||||
protected $environment;
|
||||
|
||||
/** @var string[] */
|
||||
private $files;
|
||||
|
||||
/** @var string[] */
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @param string[] $files
|
||||
* @param string[] $options
|
||||
*/
|
||||
public function __construct(Environment $environment, array $files, array $options)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->files = $files;
|
||||
$this->environment = $environment;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
public function getEnvironment(): Environment
|
||||
{
|
||||
return $this->environment;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getFiles(): array
|
||||
{
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public function getOptions(): array
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
public function getDepth(): int
|
||||
{
|
||||
if (isset($this->options['depth'])) {
|
||||
return (int) $this->options['depth'];
|
||||
}
|
||||
|
||||
if (isset($this->options['maxdepth'])) {
|
||||
return (int) $this->options['maxdepth'];
|
||||
}
|
||||
|
||||
return self::DEFAULT_DEPTH;
|
||||
}
|
||||
|
||||
public function isTitlesOnly(): bool
|
||||
{
|
||||
return isset($this->options['titlesonly']);
|
||||
}
|
||||
}
|
33
vendor/doctrine/rst-parser/lib/Nodes/WrapperNode.php
vendored
Normal file
33
vendor/doctrine/rst-parser/lib/Nodes/WrapperNode.php
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\RST\Nodes;
|
||||
|
||||
final class WrapperNode extends Node
|
||||
{
|
||||
/** @var Node|null */
|
||||
private $node;
|
||||
|
||||
/** @var string */
|
||||
private $before;
|
||||
|
||||
/** @var string */
|
||||
private $after;
|
||||
|
||||
public function __construct(?Node $node, string $before = '', string $after = '')
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->node = $node;
|
||||
$this->before = $before;
|
||||
$this->after = $after;
|
||||
}
|
||||
|
||||
protected function doRender(): string
|
||||
{
|
||||
$contents = $this->node !== null ? $this->node->render() : '';
|
||||
|
||||
return $this->before . $contents . $this->after;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue