Skip to content
Draft
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
15 changes: 14 additions & 1 deletion src/JoliTypo/Fixer/Dash.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
28 changes: 26 additions & 2 deletions tests/JoliTypo/Tests/Fixer/DashTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
}
}
Loading