From 182b9a7bf5371960d0df3fe56943a4bdb7eabb2f Mon Sep 17 00:00:00 2001 From: puklipo Date: Wed, 20 Nov 2024 09:21:35 +0900 Subject: [PATCH] Update DetectFacets.php (#5) --- src/RichText/DetectFacets.php | 200 ++++++++++++++++------------------ 1 file changed, 91 insertions(+), 109 deletions(-) diff --git a/src/RichText/DetectFacets.php b/src/RichText/DetectFacets.php index 9ae6d806..ff6f5765 100644 --- a/src/RichText/DetectFacets.php +++ b/src/RichText/DetectFacets.php @@ -45,125 +45,107 @@ public function detect(string $text): static protected function mention(): void { - $start = 0; - - while (preg_match(self::MENTION_REGEX, $this->text, $matches, offset: $start) !== 0) { - $handle = data_get($matches, 3); - - if (empty($handle)) { - break; - } - - $start = strpos($this->text, $handle, offset: $start + 1) - 1; - - if (! Identity::isHandle($handle)) { - $start++; - continue; - } - - $did = Bluesky::resolveHandle($handle)->json('did'); - - if (! Identity::isDID($did)) { - $start++; - continue; - } - - $this->facets[] = [ - '$type' => self::TYPE, - 'index' => [ - 'byteStart' => $start, - 'byteEnd' => $start + strlen($handle) + 1, - ], - 'features' => [ - [ - '$type' => Facet::Mention->value, - 'did' => $did, - ], - ], - ]; + preg_match_all(self::MENTION_REGEX, $this->text, $matches, flags: PREG_OFFSET_CAPTURE); + + collect(data_get($matches, 3)) + ->each(function ($match) { + $handle = data_get($match, 0); + $start = data_get($match, 1); + + if (empty($handle) || ! Identity::isHandle($handle)) { + return; + } + + $did = Bluesky::resolveHandle($handle)->json('did'); - $start++; - } + if (! Identity::isDID($did)) { + return; + } + + $this->facets[] = [ + '$type' => self::TYPE, + 'index' => [ + 'byteStart' => $start - 1, + 'byteEnd' => $start + strlen($handle), + ], + 'features' => [ + [ + '$type' => Facet::Mention->value, + 'did' => $did, + ], + ], + ]; + }); } protected function link(): void { - $start = 0; - - while (preg_match(self::URL_REGEX, $this->text, $matches, offset: $start) !== 0) { - $uri = data_get($matches, 2); - - if (empty($uri)) { - break; - } - - $start = strpos($this->text, $uri, offset: $start); - $end = $start + strlen($uri); - - if (! Str::startsWith($uri, 'http')) { - $start++; - continue; - } - - $uri = Str::of($uri)->whenTest('/[.,;:!?]$/', function (Stringable $string) use (&$end) { - $end--; - return $string->rtrim('.,;:!?'); - })->toString(); - - $uri = Str::of($uri)->whenTest('/[)]$/', function (Stringable $string) use (&$end) { - $end--; - return $string->rtrim(')'); - })->toString(); - - $this->facets[] = [ - '$type' => self::TYPE, - 'index' => [ - 'byteStart' => $start, - 'byteEnd' => $end, - ], - 'features' => [ - [ - '$type' => Facet::Link->value, - 'uri' => $uri, + preg_match_all(self::URL_REGEX, $this->text, $matches, flags: PREG_OFFSET_CAPTURE); + + collect(data_get($matches, 2)) + ->each(function ($match) { + $uri = data_get($match, 0); + $start = data_get($match, 1); + $end = $start + strlen($uri); + + if (! Str::startsWith($uri, 'http')) { + return; + } + + $uri = Str::of($uri)->whenTest('/[.,;:!?]$/', function (Stringable $string) use (&$end) { + $end--; + return $string->rtrim('.,;:!?'); + })->toString(); + + $uri = Str::of($uri)->whenTest('/[)]$/', function (Stringable $string) use (&$end) { + $end--; + return $string->rtrim(')'); + })->toString(); + + $this->facets[] = [ + '$type' => self::TYPE, + 'index' => [ + 'byteStart' => $start, + 'byteEnd' => $end, ], - ], - ]; - - $start++; - } + 'features' => [ + [ + '$type' => Facet::Link->value, + 'uri' => $uri, + ], + ], + ]; + }); } protected function tag(): void { - $start = 0; - - while (preg_match(self::TAG_REGEX, $this->text, $matches, offset: $start) !== 0) { - $tag = data_get($matches, 2); - - $tag = Str::of($tag)->replaceMatches(self::TRAILING_PUNCTUATION_REGEX, '')->toString(); - - if (empty($tag) || strlen($tag) > 64) { - $start++; - continue; - } - - $start = strpos($this->text, '#'.$tag, offset: $start); - - $this->facets[] = [ - '$type' => self::TYPE, - 'index' => [ - 'byteStart' => $start, - 'byteEnd' => $start + 1 + strlen($tag), - ], - 'features' => [ - [ - '$type' => Facet::Tag->value, - 'tag' => $tag, - ], - ], - ]; + preg_match_all(self::TAG_REGEX, $this->text, $matches, flags: PREG_OFFSET_CAPTURE); + + collect(data_get($matches, 2)) + ->each(function ($match) { + $tag = data_get($match, 0); + $start = data_get($match, 1) - 1; + + $tag = Str::of($tag)->replaceMatches(self::TRAILING_PUNCTUATION_REGEX, '')->toString(); - $start++; - } + if (empty($tag) || strlen($tag) > 64) { + return; + } + + $this->facets[] = [ + '$type' => self::TYPE, + 'index' => [ + 'byteStart' => $start, + 'byteEnd' => $start + 1 + strlen($tag), + ], + 'features' => [ + [ + '$type' => Facet::Tag->value, + 'tag' => $tag, + ], + ], + ]; + }); } }