Skip to content

Commit

Permalink
Widont adds spaces for all paragraphs, and fix words param (#3303)
Browse files Browse the repository at this point in the history
  • Loading branch information
berdjabrahamian authored Mar 23, 2021
1 parent a58abd1 commit 1899d3b
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 7 deletions.
6 changes: 4 additions & 2 deletions src/Modifiers/CoreModifiers.php
Original file line number Diff line number Diff line change
Expand Up @@ -2385,9 +2385,11 @@ public function where($value, $params)
* @param $value
* @return string
*/
public function widont($value)
public function widont($value, $params)
{
return Str::widont($value);
$params = Arr::get($params, 0, '1');

return Str::widont($value, $params);
}

/**
Expand Down
13 changes: 8 additions & 5 deletions src/Support/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,27 +165,30 @@ public static function timeForHumans($ms)
* @param string $value
* @return string
*/
public static function widont($value)
public static function widont($value, $words = 1)
{
// thanks to Shaun Inman for inspiration here
// http://www.shauninman.com/archive/2008/08/25/widont_2_1_1

// if there are content tags
if (preg_match("/<\/(?:p|li|h1|h2|h3|h4|h5|h6|figcaption)>/ism", $value)) {
// step 1, replace spaces in HTML tags with a code
$value = preg_replace_callback('/<.*?>/ism', function ($matches) {
return str_replace(' ', '%###%##%', $matches[0]);
}, $value);

// step 2, replace last space with &nbsp;
$value = preg_replace("/(?<!<[p|li|h1|h2|h3|h4|h5|h6|div|figcaption])([^\s])[ \t]+([^\s]+(?:[\s]*<\/(?:p|li|h1|h2|h3|h4|h5|h6|div|figcaption)>))$/im", '$1&nbsp;$2', rtrim($value));
// step 2, replace all spaces based on params with &nbsp;
$value = preg_replace_callback("/(?<!<[p|li|h1|h2|h3|h4|h5|h6|div|figcaption])([^\s]\s)([^\s]*\s?){{$words}}(<\/(?:p|li|h1|h2|h3|h4|h5|h6|div|figcaption)>)/", function ($matches) {
return preg_replace("/([\s])/", '&nbsp;', rtrim($matches[0]));
}, $value);

// step 3, re-replace the code from step 1 with spaces
return str_replace('%###%##%', ' ', $value);

// otherwise
} else {
return preg_replace("/([^\s])\s+([^\s]+)\s*$/im", '$1&nbsp;$2', rtrim($value));
return preg_replace_callback("/([^\s]\s)([^\s]*\s?){{$words}}$/im", function ($matches) {
return preg_replace("/([\s])/", '&nbsp;', rtrim($matches[0]));
}, $value);
}
}

Expand Down
98 changes: 98 additions & 0 deletions tests/Modifiers/WidontTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace Tests\Modifiers;

use Statamic\Modifiers\Modify;
use Tests\TestCase;

class WidontTest extends TestCase
{
/**
* @test
*/
public function it_adds_space_to_plain_text()
{
$value = 'Lorem ipsum dolor sit amet.';

$this->assertEquals('Lorem ipsum dolor sit&nbsp;amet.', $this->modify($value));
}

/** @test */
public function it_uses_params_to_add_space_to_plain_text()
{
$value = 'Lorem ipsum dolor sit amet.';

$this->assertEquals('Lorem ipsum dolor&nbsp;sit&nbsp;amet.', $this->modify($value, 2));
}

/** @test */
public function it_uses_params_to_add_space_to_long_broken_text()
{
$value = <<<'EOD'
Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet.
Lorem ipsum dolor sit amet.
EOD;

$expected = <<<'EOD'
Lorem ipsum dolor sit&nbsp;amet.
Lorem ipsum dolor sit&nbsp;amet.
Lorem ipsum dolor sit&nbsp;amet.
EOD;

$this->assertEquals($expected, $this->modify($value));
}

/** @test */
public function it_adds_space_to_text_within_html_tags()
{
$value1 = '<p>Lorem ipsum dolor sit amet.</p>';
$value2 = '<h1>Lorem ipsum dolor sit amet.</h1>';
$value3 = '<h2>Lorem ipsum dolor sit amet.</h2>';

$this->assertEquals('<p>Lorem ipsum dolor sit&nbsp;amet.</p>', $this->modify($value1));
$this->assertEquals('<h1>Lorem ipsum dolor sit&nbsp;amet.</h1>', $this->modify($value2));
$this->assertEquals('<h2>Lorem ipsum dolor sit&nbsp;amet.</h2>', $this->modify($value3));
}

/** @test */
public function it_adds_space_to_text_within_multiple_html_tags()
{
$value = '<p>Lorem ipsum dolor sit amet.</p><p>Consectetur adipiscing elit.</p>';

$this->assertEquals('<p>Lorem ipsum dolor sit&nbsp;amet.</p><p>Consectetur adipiscing&nbsp;elit.</p>', $this->modify($value));
}

/** @test */
public function it_uses_params_to_add_space_to_text_within_html_tags()
{
$value1 = '<p>Lorem ipsum dolor sit amet.</p>';
$value2 = '<h1>Lorem ipsum dolor sit amet.</h1>';
$value3 = '<h2>Lorem ipsum dolor sit amet.</h2>';

$this->assertEquals('<p>Lorem ipsum dolor&nbsp;sit&nbsp;amet.</p>', $this->modify($value1, 2));
$this->assertEquals('<h1>Lorem ipsum&nbsp;dolor&nbsp;sit&nbsp;amet.</h1>', $this->modify($value2, 3));
$this->assertEquals('<h2>Lorem&nbsp;ipsum&nbsp;dolor&nbsp;sit&nbsp;amet.</h2>', $this->modify($value3, 4));
}

/** @test */
public function it_uses_params_to_add_space_to_text_within_multiple_html_tags()
{
$value = '<p>Lorem ipsum dolor sit amet.</p><p>Consectetur adipiscing elit.</p>';

$this->assertEquals('<p>Lorem ipsum dolor&nbsp;sit&nbsp;amet.</p><p>Consectetur&nbsp;adipiscing&nbsp;elit.</p>', $this->modify($value, 2));
}

/** @test */
public function it_pases_bard_test()
{
$value = '<p>Lorem ipsum dolor sit amet.</p><p></p><p>Consectetur adipiscing elit.</p>';

$this->assertEquals('<p>Lorem ipsum dolor sit&nbsp;amet.</p><p></p><p>Consectetur adipiscing&nbsp;elit.</p>', $this->modify($value));
}

public function modify($value, $params = [])
{
return Modify::value($value)->widont($params)->fetch();
}
}

0 comments on commit 1899d3b

Please sign in to comment.