Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

final class Buffer
{
/** @var bool Whether unIndent() has already been called */
private bool $unindented = false;

/** @param string[] $lines */
public function __construct(
private array $lines = [],
Expand Down Expand Up @@ -56,11 +59,13 @@ public function get(int $key): string

public function push(string $line): void
{
$this->unindented = false;
$this->lines[] = $line;
}

public function set(int $key, string $line): void
{
$this->unindented = false;
$this->lines[$key] = $line;
}

Expand All @@ -81,6 +86,8 @@ public function getLinesString(): string

public function pop(): string|null
{
$this->unindented = false;

return array_pop($this->lines);
}

Expand All @@ -97,6 +104,7 @@ public function getLastLine(): string|null

public function clear(): void
{
$this->unindented = false;
$this->lines = [];
}

Expand All @@ -109,12 +117,18 @@ public function trimLines(): void

private function unIndent(): void
{
if ($this->unindented) {
return;
}

if ($this->unindentStrategy === UnindentStrategy::NONE) {
return;
}

$indentation = $this->detectIndentation();
if ($indentation === 0) {
$this->unindented = true;

return;
}

Expand All @@ -125,6 +139,8 @@ private function unIndent(): void

$this->lines[$i] = substr($line, $indentation);
}

$this->unindented = true;
}

private function detectIndentation(): int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ protected function getType(string &$value)
return self::LITERAL;
}

if (preg_match('/' . ExternalReferenceResolver::SUPPORTED_SCHEMAS . ':[-a-zA-Z0-9()@:%_\\+.~#?&\\/=]*[-a-zA-Z0-9()@%_\\+~#&\\/=]/', $value) && parse_url($value, PHP_URL_SCHEME) !== null) {
// O(1) hash set lookup instead of 5600+ char regex (~6x faster)
$scheme = parse_url($value, PHP_URL_SCHEME);
if ($scheme !== null && $scheme !== false && ExternalReferenceResolver::isSupportedScheme($scheme)) {
return self::HYPERLINK;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,18 @@ class InlineParser
/** @var InlineRule[] */
private array $rules;

/** @var array<InlineLexer::*, CachableInlineRule> */
/** @var array<int, CachableInlineRule> */
private array $cache = [];

/**
* Reusable lexer instance to avoid repeated instantiation.
*
* Note: This assumes single-threaded parsing. The lexer state is fully
* reset via setInput() before each parse, but concurrent parsing would
* cause race conditions.
*/
private InlineLexer $lexer;

/** @param iterable<InlineRule> $inlineRules */
public function __construct(iterable $inlineRules)
{
Expand All @@ -44,11 +53,13 @@ public function __construct(iterable $inlineRules)

$this->cache[$rule->getToken()] = $rule;
}

$this->lexer = new InlineLexer();
}

public function parse(string $content, BlockContext $blockContext): InlineCompoundNode
{
$lexer = new InlineLexer();
$lexer = $this->lexer;
$lexer->setInput($content);
$lexer->moveNext();
$lexer->moveNext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@

final class LineChecker
{
/** @var array<string, bool> Cache for isDirective results */
private static array $directiveCache = [];

/** @var array<string, bool> Cache for isLink results */
private static array $linkCache = [];

/** @var array<string, bool> Cache for isAnnotation results */
private static array $annotationCache = [];

private const HEADER_LETTERS = [
'!',
'"',
Expand Down Expand Up @@ -79,16 +88,38 @@ public static function isSpecialLine(string $line, int $minimumLength = 2): stri

public static function isDirective(string $line): bool
{
return preg_match('/^\.\.\s+(\|(.+)\| |)([^\s]+)::( (.*)|)$/mUsi', $line) > 0;
if (isset(self::$directiveCache[$line])) {
return self::$directiveCache[$line];
}

$result = preg_match('/^\.\.\s+(\|(.+)\| |)([^\s]+)::( (.*)|)$/mUsi', $line) > 0;
self::$directiveCache[$line] = $result;

return $result;
}

public static function isLink(string $line): bool
{
return preg_match('/^\.\.\s+_(.+):.*$/mUsi', trim($line)) > 0;
$trimmedLine = trim($line);
if (isset(self::$linkCache[$trimmedLine])) {
return self::$linkCache[$trimmedLine];
}

$result = preg_match('/^\.\.\s+_(.+):.*$/mUsi', $trimmedLine) > 0;
self::$linkCache[$trimmedLine] = $result;

return $result;
}

public static function isAnnotation(string $line): bool
{
return preg_match('/^\.\.\s+\[([#a-zA-Z0-9]*)\]\s(.*)$$/mUsi', $line) > 0;
if (isset(self::$annotationCache[$line])) {
return self::$annotationCache[$line];
}

$result = preg_match('/^\.\.\s+\[([#a-zA-Z0-9]*)\]\s(.*)$$/mUsi', $line) > 0;
self::$annotationCache[$line] = $result;

return $result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@

namespace phpDocumentor\Guides\RestructuredText\Parser\Productions\InlineRules;

use phpDocumentor\Guides\RestructuredText\Parser\InlineLexer;

interface CachableInlineRule extends InlineRule
{
/** @return InlineLexer::* */
public function getToken(): int;
}
Loading