I need to write a ellipsize function that will output the first three lines (preview) of HTML text, the rest of content is premium and we want it to show after click "Show more..."
If there are no lines, the function should show 50% of available content.
The issue is that the html text could be served as: First case:
<p>Lorem ipsum... </p>
<p>Lorem ipsum... </p>
<p>Lorem ipsum... </p>
<p>Lorem ipsum... </p>
The function should produce:
<p>Lorem ipsum... </p>
<p>Lorem ipsum... </p>
<p>Lorem ipsum... </p>
Second case:
<div>Lorem ... </div>
<div>Ipsum ... </div>
<div>Lorem ... </div>
<div>Ipsum ... </div>
The function should produce:
<div>Lorem ... </div>
<div>Ipsum ... </div>
<div>Lorem ... </div>
Third case:
<p>Lorem </p>
<ol>...</ol>
<ol>...</ol>
<ol>...</ol>
The function should produce:
<p>Lorem </p>
<ol>...</ol>
<ol>...</ol>
Fourth case:
<div>
<p></p>
<p></p>
<p></p>
<p></p>
</div>
The function should produce:
<div>
<p></p>
<p></p>
<p></p>
</div>
Fifth case:
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book</p>
The function should produce:
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's...</p>
Last case:
<div>
<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
</table>
</div>
The function should produce:
<div>
<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
</table>
</div>
I have tried to write following function:
public function ellipsize(string $content, Solution $solution): string
{
if ($solution->isMathSubject()) {
preg_match_all('/<p .*?>(.*?)<\/p>/s', $content, $matches);
$firstTwoParagraphsHTML = $matches[0][0] ?? '';
$firstTwoParagraphsHTML .= $matches[0][1] ?? '';
$firstTwoParagraphsHTML .= $matches[0][2] ?? '';
$newContent1 = $firstTwoParagraphsHTML;
preg_match_all('#<div>.*?</div>#s', $content, $matches);
$firstTwoParagraphsHTML = $matches[0][0] ?? '';
$firstTwoParagraphsHTML .= $matches[0][1] ?? '';
$firstTwoParagraphsHTML .= $matches[0][2] ?? '';
$newContent2 = $firstTwoParagraphsHTML;
} else {
$content = strip_tags($content);
$length = strlen($content);
$partialLength = intval($length * 0.10);
// Get the substring representing 25% of the content
$newContent1 = mb_substr($content, 0, $partialLength);
$newContent2 = '';
}
return strlen($newContent1) > strlen($newContent2) ? $newContent1 : $newContent2;
}
but it is not working in all cases.
Could someone help me in writing/improving my function? Maybe there is other way to ellipsize the content? Like render on the backend the whole html as an image and return only part of this image?