From a28345266b544db239c5cc6df14e4cc00ad684de Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 10 Apr 2026 15:52:47 +0000 Subject: [PATCH 1/2] Initial plan From 5249658450c0807323cde4f7c3c37ee40185de9e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 10 Apr 2026 16:11:11 +0000 Subject: [PATCH 2/2] Add narrow no-break space before en/em dashes (incise support) Agent-Logs-Url: https://github.com/jolicode/JoliTypo/sessions/4a5fb82b-8014-44c6-a0ba-98bf41ab4ed9 Co-authored-by: damienalexandre <225704+damienalexandre@users.noreply.github.com> --- src/JoliTypo/Fixer/Dash.php | 15 ++++++++++++- tests/JoliTypo/Tests/Fixer/DashTest.php | 28 +++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/JoliTypo/Fixer/Dash.php b/src/JoliTypo/Fixer/Dash.php index ecb46d3..aeaae23 100644 --- a/src/JoliTypo/Fixer/Dash.php +++ b/src/JoliTypo/Fixer/Dash.php @@ -17,8 +17,21 @@ class Dash implements FixerInterface { public function fix(string $content, ?StateBag $stateBag = null) { + // Convert hyphen between numbers/spaces to en dash (date/number ranges) $content = preg_replace('@(?<=[0-9 ]|^)-(?=[0-9 ]|$)@', Fixer::NDASH, $content); - return preg_replace('@ ?-- ?([^-]|$)@s', Fixer::MDASH . '$1', $content); + // Convert double hyphens to em dash + $content = preg_replace('@ ?-- ?([^-]|$)@s', Fixer::MDASH . '$1', $content); + + // Replace any space before an en or em dash with a narrow no-break space. + // This prevents line breaks before dashes used as text separators (incises), + // while still allowing a break after the dash. + $content = preg_replace( + '@[ ' . Fixer::NO_BREAK_SPACE . Fixer::NO_BREAK_THIN_SPACE . '](' . Fixer::NDASH . '|' . Fixer::MDASH . ')@u', + Fixer::NO_BREAK_THIN_SPACE . '$1', + $content + ); + + return $content; } } diff --git a/tests/JoliTypo/Tests/Fixer/DashTest.php b/tests/JoliTypo/Tests/Fixer/DashTest.php index 9201231..c28df3a 100644 --- a/tests/JoliTypo/Tests/Fixer/DashTest.php +++ b/tests/JoliTypo/Tests/Fixer/DashTest.php @@ -20,13 +20,37 @@ public function testSimpleString(): void $this->assertInstanceOf('JoliTypo\Fixer\Dash', $fixer); $this->assertSame('Test', $fixer->fix('Test')); + // Hyphen between numbers: converted to en dash, no spaces added $this->assertSame('M. Jackson: 1964' . Fixer::NDASH . '2009', $fixer->fix('M. Jackson: 1964-2009')); - $this->assertSame('M. Jackson: 1964 ' . Fixer::NDASH . ' 2009', $fixer->fix('M. Jackson: 1964 - 2009')); - $this->assertSame('Style ' . Fixer::NDASH . ' not sincerity ' . Fixer::NDASH . ' is the vital thing.', $fixer->fix('Style - not sincerity - is the vital thing.')); + // Space before en dash becomes narrow no-break space; space after remains breakable + $this->assertSame('M. Jackson: 1964' . Fixer::NO_BREAK_THIN_SPACE . Fixer::NDASH . ' 2009', $fixer->fix('M. Jackson: 1964 - 2009')); + $this->assertSame('Style' . Fixer::NO_BREAK_THIN_SPACE . Fixer::NDASH . ' not sincerity' . Fixer::NO_BREAK_THIN_SPACE . Fixer::NDASH . ' is the vital thing.', $fixer->fix('Style - not sincerity - is the vital thing.')); // $this->assertSame("Style ".Fixer::MDASH." not sincerity ".Fixer::MDASH." is the vital thing.", $fixer->fix("Style -not sincerity- is the vital thing.")); + // Double hyphens: converted to em dash (spaces stripped by the conversion rule) $this->assertSame('Style' . Fixer::MDASH . 'you have it.', $fixer->fix('Style -- you have it.')); $this->assertSame('Style' . Fixer::MDASH . 'you have it.', $fixer->fix('Style--you have it.')); $this->assertSame('Style' . Fixer::MDASH . 'you have it.', $fixer->fix('Style-- you have it.')); } + + public function testDashSpacing(): void + { + $fixer = new Fixer\Dash(); + + // En dash already in text with a space before: space becomes narrow no-break space + $this->assertSame('text' . Fixer::NO_BREAK_THIN_SPACE . Fixer::NDASH . ' more text', $fixer->fix('text ' . Fixer::NDASH . ' more text')); + + // Em dash already in text with a space before: space becomes narrow no-break space + $this->assertSame('text' . Fixer::NO_BREAK_THIN_SPACE . Fixer::MDASH . ' more text', $fixer->fix('text ' . Fixer::MDASH . ' more text')); + + // No space before dash: not changed + $this->assertSame('text' . Fixer::NDASH . 'more', $fixer->fix('text' . Fixer::NDASH . 'more')); + $this->assertSame('text' . Fixer::MDASH . 'more', $fixer->fix('text' . Fixer::MDASH . 'more')); + + // Already a narrow no-break space before dash: normalised (no double space) + $this->assertSame('text' . Fixer::NO_BREAK_THIN_SPACE . Fixer::NDASH . ' more', $fixer->fix('text' . Fixer::NO_BREAK_THIN_SPACE . Fixer::NDASH . ' more')); + + // Already a no-break space before dash: replaced with narrow no-break space + $this->assertSame('text' . Fixer::NO_BREAK_THIN_SPACE . Fixer::NDASH . ' more', $fixer->fix('text' . Fixer::NO_BREAK_SPACE . Fixer::NDASH . ' more')); + } }