Skip to content

Generators/[HTML|Markdown|Text]::getFormattedCodeComparisonBlock(): minor refactor #836

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 3, 2025
Merged
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
62 changes: 45 additions & 17 deletions src/Generators/HTML.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
namespace PHP_CodeSniffer\Generators;

use DOMDocument;
use DOMElement;
use DOMNode;
use PHP_CodeSniffer\Config;

Expand Down Expand Up @@ -400,23 +401,11 @@ protected function getFormattedCodeComparisonBlock(DOMNode $node)
return '';
}

$firstTitle = trim($firstCodeElm->getAttribute('title'));
$firstTitle = str_replace(' ', '  ', $firstTitle);
$first = trim($firstCodeElm->nodeValue);
$first = str_replace('<?php', '&lt;?php', $first);
$first = str_replace("\n", '</br>', $first);
$first = str_replace(' ', '&nbsp;', $first);
$first = str_replace('<em>', '<span class="code-comparison-highlight">', $first);
$first = str_replace('</em>', '</span>', $first);

$secondTitle = trim($secondCodeElm->getAttribute('title'));
$secondTitle = str_replace(' ', '&nbsp;&nbsp;', $secondTitle);
$second = trim($secondCodeElm->nodeValue);
$second = str_replace('<?php', '&lt;?php', $second);
$second = str_replace("\n", '</br>', $second);
$second = str_replace(' ', '&nbsp;', $second);
$second = str_replace('<em>', '<span class="code-comparison-highlight">', $second);
$second = str_replace('</em>', '</span>', $second);
$firstTitle = $this->formatCodeTitle($firstCodeElm);
$first = $this->formatCodeSample($firstCodeElm);

$secondTitle = $this->formatCodeTitle($secondCodeElm);
$second = $this->formatCodeSample($secondCodeElm);

$titleRow = '';
if ($firstTitle !== '' || $secondTitle !== '') {
Expand Down Expand Up @@ -447,4 +436,43 @@ protected function getFormattedCodeComparisonBlock(DOMNode $node)
}//end getFormattedCodeComparisonBlock()


/**
* Retrieve a code block title and prepare it for output as HTML.
*
* @param \DOMElement $codeElm The DOMElement object for a code block.
*
* @since 3.12.0
*
* @return string
*/
private function formatCodeTitle(DOMElement $codeElm)
{
$title = trim($codeElm->getAttribute('title'));
return str_replace(' ', '&nbsp;&nbsp;', $title);

}//end formatCodeTitle()


/**
* Retrieve a code block contents and prepare it for output as HTML.
*
* @param \DOMElement $codeElm The DOMElement object for a code block.
*
* @since 3.12.0
*
* @return string
*/
private function formatCodeSample(DOMElement $codeElm)
{
$code = (string) $codeElm->nodeValue;
$code = trim($code);
$code = str_replace('<?php', '&lt;?php', $code);
$code = str_replace(["\n", ' '], ['</br>', '&nbsp;'], $code);
$code = str_replace(['<em>', '</em>'], ['<span class="code-comparison-highlight">', '</span>'], $code);

return $code;

}//end formatCodeSample()


}//end class
55 changes: 43 additions & 12 deletions src/Generators/Markdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace PHP_CodeSniffer\Generators;

use DOMElement;
use DOMNode;
use PHP_CodeSniffer\Config;

Expand Down Expand Up @@ -249,19 +250,11 @@ protected function getFormattedCodeComparisonBlock(DOMNode $node)
return '';
}

$firstTitle = trim($firstCodeElm->getAttribute('title'));
$firstTitle = str_replace(' ', '&nbsp;&nbsp;', $firstTitle);
$first = trim($firstCodeElm->nodeValue);
$first = str_replace("\n", PHP_EOL.' ', $first);
$first = str_replace('<em>', '', $first);
$first = str_replace('</em>', '', $first);
$firstTitle = $this->formatCodeTitle($firstCodeElm);
$first = $this->formatCodeSample($firstCodeElm);

$secondTitle = trim($secondCodeElm->getAttribute('title'));
$secondTitle = str_replace(' ', '&nbsp;&nbsp;', $secondTitle);
$second = trim($secondCodeElm->nodeValue);
$second = str_replace("\n", PHP_EOL.' ', $second);
$second = str_replace('<em>', '', $second);
$second = str_replace('</em>', '', $second);
$secondTitle = $this->formatCodeTitle($secondCodeElm);
$second = $this->formatCodeSample($secondCodeElm);

$titleRow = '';
if ($firstTitle !== '' || $secondTitle !== '') {
Expand Down Expand Up @@ -296,4 +289,42 @@ protected function getFormattedCodeComparisonBlock(DOMNode $node)
}//end getFormattedCodeComparisonBlock()


/**
* Retrieve a code block title and prepare it for output as HTML.
*
* @param \DOMElement $codeElm The DOMElement object for a code block.
*
* @since 3.12.0
*
* @return string
*/
private function formatCodeTitle(DOMElement $codeElm)
{
$title = trim($codeElm->getAttribute('title'));
return str_replace(' ', '&nbsp;&nbsp;', $title);

}//end formatCodeTitle()


/**
* Retrieve a code block contents and prepare it for output as HTML.
*
* @param \DOMElement $codeElm The DOMElement object for a code block.
*
* @since 3.12.0
*
* @return string
*/
private function formatCodeSample(DOMElement $codeElm)
{
$code = (string) $codeElm->nodeValue;
$code = trim($code);
$code = str_replace("\n", PHP_EOL.' ', $code);
$code = str_replace(['<em>', '</em>'], '', $code);

return $code;

}//end formatCodeSample()


}//end class
202 changes: 92 additions & 110 deletions src/Generators/Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace PHP_CodeSniffer\Generators;

use DOMElement;
use DOMNode;

class Text extends Generator
Expand Down Expand Up @@ -179,123 +180,21 @@ protected function getFormattedCodeComparisonBlock(DOMNode $node)
return '';
}

$first = trim($firstCodeElm->nodeValue);
$firstTitle = trim($firstCodeElm->getAttribute('title'));

$firstTitleLines = [];
$tempTitle = '';
$words = explode(' ', $firstTitle);

foreach ($words as $word) {
if (strlen($tempTitle.$word) >= 45) {
if (strlen($tempTitle.$word) === 45) {
// Adding the extra space will push us to the edge
// so we are done.
$firstTitleLines[] = $tempTitle.$word;
$tempTitle = '';
} else if (strlen($tempTitle.$word) === 46) {
// We are already at the edge, so we are done.
$firstTitleLines[] = $tempTitle.$word;
$tempTitle = '';
} else {
$firstTitleLines[] = $tempTitle;
$tempTitle = $word.' ';
}
} else {
$tempTitle .= $word.' ';
}
}//end foreach

if ($tempTitle !== '') {
$firstTitleLines[] = $tempTitle;
}

$first = str_replace(['<em>', '</em>'], '', $first);
$firstLines = explode("\n", $first);

$second = trim($secondCodeElm->nodeValue);
$secondTitle = trim($secondCodeElm->getAttribute('title'));

$secondTitleLines = [];
$tempTitle = '';
$words = explode(' ', $secondTitle);

foreach ($words as $word) {
if (strlen($tempTitle.$word) >= 45) {
if (strlen($tempTitle.$word) === 45) {
// Adding the extra space will push us to the edge
// so we are done.
$secondTitleLines[] = $tempTitle.$word;
$tempTitle = '';
} else if (strlen($tempTitle.$word) === 46) {
// We are already at the edge, so we are done.
$secondTitleLines[] = $tempTitle.$word;
$tempTitle = '';
} else {
$secondTitleLines[] = $tempTitle;
$tempTitle = $word.' ';
}
} else {
$tempTitle .= $word.' ';
}
}//end foreach

if ($tempTitle !== '') {
$secondTitleLines[] = $tempTitle;
}
$firstTitleLines = $this->codeTitleToLines($firstCodeElm);
$firstLines = $this->codeToLines($firstCodeElm);

$second = str_replace(['<em>', '</em>'], '', $second);
$secondLines = explode("\n", $second);
$secondTitleLines = $this->codeTitleToLines($secondCodeElm);
$secondLines = $this->codeToLines($secondCodeElm);

$titleRow = '';
if ($firstTitle !== '' || $secondTitle !== '') {
$maxTitleLines = max(count($firstTitleLines), count($secondTitleLines));
for ($i = 0; $i < $maxTitleLines; $i++) {
if (isset($firstTitleLines[$i]) === true) {
$firstLineText = $firstTitleLines[$i];
} else {
$firstLineText = '';
}

if (isset($secondTitleLines[$i]) === true) {
$secondLineText = $secondTitleLines[$i];
} else {
$secondLineText = '';
}

$titleRow .= '| ';
$titleRow .= $firstLineText.str_repeat(' ', (46 - strlen($firstLineText)));
$titleRow .= ' | ';
$titleRow .= $secondLineText.str_repeat(' ', (47 - strlen($secondLineText)));
$titleRow .= ' |'.PHP_EOL;
}//end for

if ($firstTitleLines !== [] || $secondTitleLines !== []) {
$titleRow = $this->linesToTableRows($firstTitleLines, $secondTitleLines);
$titleRow .= str_repeat('-', 100).PHP_EOL;
}//end if

$codeRow = '';
if ($first !== '' || $second !== '') {
$maxCodeLines = max(count($firstLines), count($secondLines));
for ($i = 0; $i < $maxCodeLines; $i++) {
if (isset($firstLines[$i]) === true) {
$firstLineText = $firstLines[$i];
} else {
$firstLineText = '';
}

if (isset($secondLines[$i]) === true) {
$secondLineText = $secondLines[$i];
} else {
$secondLineText = '';
}

$codeRow .= '| ';
$codeRow .= $firstLineText.str_repeat(' ', max(0, (47 - strlen($firstLineText))));
$codeRow .= '| ';
$codeRow .= $secondLineText.str_repeat(' ', max(0, (48 - strlen($secondLineText))));
$codeRow .= '|'.PHP_EOL;
}//end for

if ($firstLines !== [] || $secondLines !== []) {
$codeRow = $this->linesToTableRows($firstLines, $secondLines);
$codeRow .= str_repeat('-', 100).PHP_EOL.PHP_EOL;
}//end if

Expand All @@ -313,4 +212,87 @@ protected function getFormattedCodeComparisonBlock(DOMNode $node)
}//end getFormattedCodeComparisonBlock()


/**
* Retrieve a code block title and split it into lines for use in an ASCII table.
*
* @param \DOMElement $codeElm The DOMElement object for a code block.
*
* @since 3.12.0
*
* @return array<string>
*/
private function codeTitleToLines(DOMElement $codeElm)
{
$title = trim($codeElm->getAttribute('title'));
if ($title === '') {
return [];
}

$title = wordwrap($title, 46, "\n");

return explode("\n", $title);

}//end codeTitleToLines()


/**
* Retrieve a code block contents and split it into lines for use in an ASCII table.
*
* @param \DOMElement $codeElm The DOMElement object for a code block.
*
* @since 3.12.0
*
* @return array<string>
*/
private function codeToLines(DOMElement $codeElm)
{
$code = trim($codeElm->nodeValue);
if ($code === '') {
return [];
}

$code = str_replace(['<em>', '</em>'], '', $code);
return explode("\n", $code);

}//end codeToLines()


/**
* Transform two sets of text lines into rows for use in an ASCII table.
*
* The sets may not contains an equal amount of lines, while the resulting rows should.
*
* @param array<string> $column1Lines Lines of text to place in column 1.
* @param array<string> $column2Lines Lines of text to place in column 2.
*
* @return string
*/
private function linesToTableRows(array $column1Lines, array $column2Lines)
{
$maxLines = max(count($column1Lines), count($column2Lines));

$rows = '';
for ($i = 0; $i < $maxLines; $i++) {
$column1Text = '';
if (isset($column1Lines[$i]) === true) {
$column1Text = $column1Lines[$i];
}

$column2Text = '';
if (isset($column2Lines[$i]) === true) {
$column2Text = $column2Lines[$i];
}

$rows .= '| ';
$rows .= $column1Text.str_repeat(' ', max(0, (47 - strlen($column1Text))));
$rows .= '| ';
$rows .= $column2Text.str_repeat(' ', max(0, (48 - strlen($column2Text))));
$rows .= '|'.PHP_EOL;
}//end for

return $rows;

}//end linesToTableRows()


}//end class