Skip to content

Commit e8e8a8b

Browse files
authored
Merge pull request #1034 from thephpleague/fix-smart-punct
Don't change already-formatted quotation marks
2 parents b7a7af3 + 1a40b1e commit e8e8a8b

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi
66

77
## [Unreleased][unreleased]
88

9+
### Fixed
10+
11+
- Fixed SmartPunct extension changing already-formatted quotation marks (#1030)
12+
913
## [2.4.3] - 2024-07-22
1014

1115
### Fixed

src/Extension/SmartPunct/QuoteParser.php

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,19 @@
2424

2525
final class QuoteParser implements InlineParserInterface
2626
{
27+
/**
28+
* @deprecated This constant is no longer used and will be removed in a future major release
29+
*/
2730
public const DOUBLE_QUOTES = [Quote::DOUBLE_QUOTE, Quote::DOUBLE_QUOTE_OPENER, Quote::DOUBLE_QUOTE_CLOSER];
31+
32+
/**
33+
* @deprecated This constant is no longer used and will be removed in a future major release
34+
*/
2835
public const SINGLE_QUOTES = [Quote::SINGLE_QUOTE, Quote::SINGLE_QUOTE_OPENER, Quote::SINGLE_QUOTE_CLOSER];
2936

3037
public function getMatchDefinition(): InlineParserMatch
3138
{
32-
return InlineParserMatch::oneOf(...[...self::DOUBLE_QUOTES, ...self::SINGLE_QUOTES]);
39+
return InlineParserMatch::oneOf(Quote::SINGLE_QUOTE, Quote::DOUBLE_QUOTE);
3340
}
3441

3542
/**
@@ -40,8 +47,6 @@ public function parse(InlineParserContext $inlineContext): bool
4047
$char = $inlineContext->getFullMatch();
4148
$cursor = $inlineContext->getCursor();
4249

43-
$normalizedCharacter = $this->getNormalizedQuoteCharacter($char);
44-
4550
$charBefore = $cursor->peek(-1);
4651
if ($charBefore === null) {
4752
$charBefore = "\n";
@@ -58,28 +63,15 @@ public function parse(InlineParserContext $inlineContext): bool
5863
$canOpen = $leftFlanking && ! $rightFlanking;
5964
$canClose = $rightFlanking;
6065

61-
$node = new Quote($normalizedCharacter, ['delim' => true]);
66+
$node = new Quote($char, ['delim' => true]);
6267
$inlineContext->getContainer()->appendChild($node);
6368

6469
// Add entry to stack to this opener
65-
$inlineContext->getDelimiterStack()->push(new Delimiter($normalizedCharacter, 1, $node, $canOpen, $canClose));
70+
$inlineContext->getDelimiterStack()->push(new Delimiter($char, 1, $node, $canOpen, $canClose));
6671

6772
return true;
6873
}
6974

70-
private function getNormalizedQuoteCharacter(string $character): string
71-
{
72-
if (\in_array($character, self::DOUBLE_QUOTES, true)) {
73-
return Quote::DOUBLE_QUOTE;
74-
}
75-
76-
if (\in_array($character, self::SINGLE_QUOTES, true)) {
77-
return Quote::SINGLE_QUOTE;
78-
}
79-
80-
return $character;
81-
}
82-
8375
/**
8476
* @return bool[]
8577
*/

tests/functional/Extension/SmartPunct/SmartPunctFunctionalTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,15 @@ protected function setUp(): void
4040
public static function dataProvider(): \Generator
4141
{
4242
yield from SpecReader::readFile(__DIR__ . '/../../../../vendor/commonmark/commonmark.js/test/smart_punct.txt');
43+
44+
yield 'Existing formatted quotes should be preserved (issue #1030)' => [
45+
'input' => 'In the middle to late ’90s, it was chaos. "We couldn\'t get out of that rut."',
46+
'output' => "<p>In the middle to late ’90s, it was chaos. “We couldn’t get out of that rut.”</p>\n",
47+
];
48+
49+
yield 'already-formatted quotes are kept as-is' => [
50+
'input' => '"Plain quotes", “normal quotes”, and ”backwards quotes“',
51+
'output' => "<p>“Plain quotes”, “normal quotes”, and ”backwards quotes“</p>\n",
52+
];
4353
}
4454
}

0 commit comments

Comments
 (0)