refactor: susun semula struktur folder — Laravel source ke src/

This commit is contained in:
Saufi
2026-05-19 15:58:35 +08:00
parent f052251b94
commit bf53c71b45
10806 changed files with 1385379 additions and 121 deletions

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Extension\SmartPunct;
use League\CommonMark\Node\Inline\Text;
use League\CommonMark\Parser\Inline\InlineParserInterface;
use League\CommonMark\Parser\Inline\InlineParserMatch;
use League\CommonMark\Parser\InlineParserContext;
final class DashParser implements InlineParserInterface
{
private const EN_DASH = '';
private const EM_DASH = '—';
public function getMatchDefinition(): InlineParserMatch
{
return InlineParserMatch::regex('(?<!-)(-{2,})');
}
public function parse(InlineParserContext $inlineContext): bool
{
$count = $inlineContext->getFullMatchLength();
$inlineContext->getCursor()->advanceBy($count);
$enCount = 0;
$emCount = 0;
if ($count % 3 === 0) { // If divisible by 3, use all em dashes
$emCount = (int) ($count / 3);
} elseif ($count % 2 === 0) { // If divisible by 2, use all en dashes
$enCount = (int) ($count / 2);
} elseif ($count % 3 === 2) { // If 2 extra dashes, use en dash for last 2; em dashes for rest
$emCount = (int) (($count - 2) / 3);
$enCount = 1;
} else { // Use en dashes for last 4 hyphens; em dashes for rest
$emCount = (int) (($count - 4) / 3);
$enCount = 2;
}
$inlineContext->getContainer()->appendChild(new Text(
\str_repeat(self::EM_DASH, $emCount) . \str_repeat(self::EN_DASH, $enCount)
));
return true;
}
}

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Extension\SmartPunct;
use League\CommonMark\Node\Inline\Text;
use League\CommonMark\Parser\Inline\InlineParserInterface;
use League\CommonMark\Parser\Inline\InlineParserMatch;
use League\CommonMark\Parser\InlineParserContext;
final class EllipsesParser implements InlineParserInterface
{
public function getMatchDefinition(): InlineParserMatch
{
return InlineParserMatch::oneOf('...', '. . .');
}
public function parse(InlineParserContext $inlineContext): bool
{
$inlineContext->getCursor()->advanceBy($inlineContext->getFullMatchLength());
$inlineContext->getContainer()->appendChild(new Text('…'));
return true;
}
}

View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Extension\SmartPunct;
use League\CommonMark\Node\Inline\AbstractStringContainer;
final class Quote extends AbstractStringContainer
{
public const DOUBLE_QUOTE = '"';
public const DOUBLE_QUOTE_OPENER = '“';
public const DOUBLE_QUOTE_CLOSER = '”';
public const SINGLE_QUOTE = "'";
public const SINGLE_QUOTE_OPENER = '';
public const SINGLE_QUOTE_CLOSER = '';
}

View File

@@ -0,0 +1,98 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Extension\SmartPunct;
use League\CommonMark\Delimiter\Delimiter;
use League\CommonMark\Parser\Inline\InlineParserInterface;
use League\CommonMark\Parser\Inline\InlineParserMatch;
use League\CommonMark\Parser\InlineParserContext;
use League\CommonMark\Util\RegexHelper;
final class QuoteParser implements InlineParserInterface
{
/**
* @deprecated This constant is no longer used and will be removed in a future major release
*/
public const DOUBLE_QUOTES = [Quote::DOUBLE_QUOTE, Quote::DOUBLE_QUOTE_OPENER, Quote::DOUBLE_QUOTE_CLOSER];
/**
* @deprecated This constant is no longer used and will be removed in a future major release
*/
public const SINGLE_QUOTES = [Quote::SINGLE_QUOTE, Quote::SINGLE_QUOTE_OPENER, Quote::SINGLE_QUOTE_CLOSER];
public function getMatchDefinition(): InlineParserMatch
{
return InlineParserMatch::oneOf(Quote::SINGLE_QUOTE, Quote::DOUBLE_QUOTE);
}
/**
* Normalizes any quote characters found and manually adds them to the delimiter stack
*/
public function parse(InlineParserContext $inlineContext): bool
{
$char = $inlineContext->getFullMatch();
$cursor = $inlineContext->getCursor();
$index = $cursor->getPosition();
$charBefore = $cursor->peek(-1);
if ($charBefore === null) {
$charBefore = "\n";
}
$cursor->advance();
$charAfter = $cursor->getCurrentCharacter();
if ($charAfter === null) {
$charAfter = "\n";
}
[$leftFlanking, $rightFlanking] = $this->determineFlanking($charBefore, $charAfter);
$canOpen = $leftFlanking && ! $rightFlanking;
$canClose = $rightFlanking;
$node = new Quote($char, ['delim' => true]);
$inlineContext->getContainer()->appendChild($node);
// Add entry to stack to this opener
$inlineContext->getDelimiterStack()->push(new Delimiter($char, 1, $node, $canOpen, $canClose, $index));
return true;
}
/**
* @return bool[]
*/
private function determineFlanking(string $charBefore, string $charAfter): array
{
$afterIsWhitespace = \preg_match('/\pZ|\s/u', $charAfter);
$afterIsPunctuation = \preg_match(RegexHelper::REGEX_PUNCTUATION, $charAfter);
$beforeIsWhitespace = \preg_match('/\pZ|\s/u', $charBefore);
$beforeIsPunctuation = \preg_match(RegexHelper::REGEX_PUNCTUATION, $charBefore);
$leftFlanking = ! $afterIsWhitespace &&
! ($afterIsPunctuation &&
! $beforeIsWhitespace &&
! $beforeIsPunctuation);
$rightFlanking = ! $beforeIsWhitespace &&
! ($beforeIsPunctuation &&
! $afterIsWhitespace &&
! $afterIsPunctuation);
return [$leftFlanking, $rightFlanking];
}
}

View File

@@ -0,0 +1,82 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Extension\SmartPunct;
use League\CommonMark\Delimiter\DelimiterInterface;
use League\CommonMark\Delimiter\Processor\DelimiterProcessorInterface;
use League\CommonMark\Node\Inline\AbstractStringContainer;
final class QuoteProcessor implements DelimiterProcessorInterface
{
/** @psalm-readonly */
private string $normalizedCharacter;
/** @psalm-readonly */
private string $openerCharacter;
/** @psalm-readonly */
private string $closerCharacter;
private function __construct(string $char, string $opener, string $closer)
{
$this->normalizedCharacter = $char;
$this->openerCharacter = $opener;
$this->closerCharacter = $closer;
}
public function getOpeningCharacter(): string
{
return $this->normalizedCharacter;
}
public function getClosingCharacter(): string
{
return $this->normalizedCharacter;
}
public function getMinLength(): int
{
return 1;
}
public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int
{
return 1;
}
public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse): void
{
$opener->insertAfter(new Quote($this->openerCharacter));
$closer->insertBefore(new Quote($this->closerCharacter));
}
/**
* Create a double-quote processor
*/
public static function createDoubleQuoteProcessor(string $opener = Quote::DOUBLE_QUOTE_OPENER, string $closer = Quote::DOUBLE_QUOTE_CLOSER): self
{
return new self(Quote::DOUBLE_QUOTE, $opener, $closer);
}
/**
* Create a single-quote processor
*/
public static function createSingleQuoteProcessor(string $opener = Quote::SINGLE_QUOTE_OPENER, string $closer = Quote::SINGLE_QUOTE_CLOSER): self
{
return new self(Quote::SINGLE_QUOTE, $opener, $closer);
}
}

View File

@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Extension\SmartPunct;
use League\CommonMark\Event\DocumentParsedEvent;
use League\CommonMark\Node\Inline\AdjacentTextMerger;
use League\CommonMark\Node\Inline\Text;
use League\CommonMark\Node\Query;
/**
* Identifies any lingering Quote nodes that were missing pairs and converts them into Text nodes
*/
final class ReplaceUnpairedQuotesListener
{
public function __invoke(DocumentParsedEvent $event): void
{
$query = (new Query())->where(Query::type(Quote::class));
foreach ($query->findAll($event->getDocument()) as $quote) {
\assert($quote instanceof Quote);
$literal = $quote->getLiteral();
if ($literal === Quote::SINGLE_QUOTE) {
$literal = Quote::SINGLE_QUOTE_CLOSER;
} elseif ($literal === Quote::DOUBLE_QUOTE) {
$literal = Quote::DOUBLE_QUOTE_OPENER;
}
$quote->replaceWith($new = new Text($literal));
AdjacentTextMerger::mergeWithDirectlyAdjacentNodes($new);
}
}
}

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
/*
* This file is part of the league/commonmark package.
*
* (c) Colin O'Dell <colinodell@gmail.com>
*
* Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
* - (c) John MacFarlane
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace League\CommonMark\Extension\SmartPunct;
use League\CommonMark\Environment\EnvironmentBuilderInterface;
use League\CommonMark\Event\DocumentParsedEvent;
use League\CommonMark\Extension\ConfigurableExtensionInterface;
use League\CommonMark\Node\Block\Document;
use League\CommonMark\Node\Block\Paragraph;
use League\CommonMark\Node\Inline\Text;
use League\CommonMark\Renderer\Block as CoreBlockRenderer;
use League\CommonMark\Renderer\Inline as CoreInlineRenderer;
use League\Config\ConfigurationBuilderInterface;
use Nette\Schema\Expect;
final class SmartPunctExtension implements ConfigurableExtensionInterface
{
public function configureSchema(ConfigurationBuilderInterface $builder): void
{
$builder->addSchema('smartpunct', Expect::structure([
'double_quote_opener' => Expect::string(Quote::DOUBLE_QUOTE_OPENER),
'double_quote_closer' => Expect::string(Quote::DOUBLE_QUOTE_CLOSER),
'single_quote_opener' => Expect::string(Quote::SINGLE_QUOTE_OPENER),
'single_quote_closer' => Expect::string(Quote::SINGLE_QUOTE_CLOSER),
]));
}
public function register(EnvironmentBuilderInterface $environment): void
{
$environment
->addInlineParser(new QuoteParser(), 10)
->addInlineParser(new DashParser(), 0)
->addInlineParser(new EllipsesParser(), 0)
->addDelimiterProcessor(QuoteProcessor::createDoubleQuoteProcessor(
$environment->getConfiguration()->get('smartpunct/double_quote_opener'),
$environment->getConfiguration()->get('smartpunct/double_quote_closer')
))
->addDelimiterProcessor(QuoteProcessor::createSingleQuoteProcessor(
$environment->getConfiguration()->get('smartpunct/single_quote_opener'),
$environment->getConfiguration()->get('smartpunct/single_quote_closer')
))
->addEventListener(DocumentParsedEvent::class, new ReplaceUnpairedQuotesListener())
->addRenderer(Document::class, new CoreBlockRenderer\DocumentRenderer(), 0)
->addRenderer(Paragraph::class, new CoreBlockRenderer\ParagraphRenderer(), 0)
->addRenderer(Text::class, new CoreInlineRenderer\TextRenderer(), 0);
}
}