Skip to content
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
58 changes: 34 additions & 24 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
0.3.2 /
- Adjusted is1D and is2D to support int|float|string|bool|null
- Extracted some functions to separate helper class
- Created test class for Helper
0.4.0 / 2025-11-28
- Renamed `Helper` to `Validator` and moved formatting logic to new `Formatter` class
- Added `is3D` support in `Validator`
- Updated tests for `Validator` and introduced `FormatterTest`
- Adjusted autoload configuration in `composer.json`
- Improved `PrettyPrintTest` with proper `ob` level handling
- Updated `CHANGELOG` for version `0.4.0`
- Refactor PrettyPrint: remove unused `is2DNumeric` method and simplify array handling logic
- Refactor PrettyPrint: delegate 2D matrix formatting to `Formatter::format2DAligned`, added tests in `FormatterTest`

0.3.2 / 2025-11-28
- Adjusted is1D and is2D to support `int|float|string|bool|null`
- Extracted some functions to separate helper class
- Created test class for Helper

0.3.1 / 2025-11-27
- Adjust default formatting dimensions in PrettyPrint tensor methods
- README.md example updates
- Add precision option to PrettyPrint for float formatting
- Refactor PrettyPrint for coding standards compliance and improve script configurations in composer.json
- Added MAX limitation for arguments
- Allowed formatted printing of numbers and strings together
- Adjust default formatting dimensions in `PrettyPrint` tensor methods
- `README.md` example updates
- Add precision option to PrettyPrint for float formatting
- Refactor `PrettyPrint` for coding standards compliance and improve script configurations in composer.json
- Added MAX limitation for arguments
- Allowed formatted printing of numbers and strings together

0.3.0 / 2025-11-24
- Improved documentation
- Added "start" option to PrettyPrint for prefix control
- Added custom "label" support for tensor formatting in PrettyPrint
- Added web environment `<pre>` wrapping support
- Improved documentation
- Added "start" option to PrettyPrint for prefix control
- Added custom "label" support for tensor formatting in PrettyPrint
- Added web environment `<pre>` wrapping support

0.2.1 / 2025-11-22
- Added Github Actions
- Added PHP Lint
- Add usage examples and options reference to README.md
- Added Github Actions
- Added PHP Lint
- Add usage examples and options reference to `README.md`

0.2.0 / 2025-11-22
- Added Unit Tests
- Improved documentation
- Added Unit Tests
- Improved documentation

0.1.0 / 2025-11-21
- Updated project structure
- Added README and License
- Implemented basic functionality
- Extracted pprint, pp and ppd function to separate functions.php file
- Updated project structure
- Added README and License
- Implemented basic functionality
- Extracted `pprint`, `pp` and `ppd` function to separate functions.php file

0.0.1 / 2025-11-12
- Initial commit
- Initial commit
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
],
"autoload": {
"psr-4": {
"Apphp\\PrettyPrint\\": "src/"
"Apphp\\PrettyPrint\\": "src/",
"Apphp\\PrettyPrint\\Tests\\": "tests/"
},
"files": [
"src/functions.php"
Expand Down
98 changes: 98 additions & 0 deletions src/Formatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace Apphp\PrettyPrint;

/**
* Formatter for pretty-printing arrays.
*/
class Formatter
{
/**
* Format a value as a number when possible.
*
* Integers are returned verbatim; floats are rendered with 4 decimal places;
* non-numeric values are cast to string.
*
* @param mixed $v
* @param int $precision
* @return string
*/
public static function formatNumber(mixed $v, int $precision = 2): string
{
if (is_int($v)) {
return (string)$v;
}
if (is_float($v)) {
return number_format($v, $precision, '.', '');
}
return (string)$v;
}

/**
* Format a 2D matrix with aligned columns.
*
* @param array $matrix 2D array.
* @param int $precision Number of decimal places to use for floats.
* @return string
*/
public static function format2DAligned(array $matrix, int $precision = 2): string
{
$cols = 0;
foreach ($matrix as $row) {
if (is_array($row)) {
$cols = max($cols, count($row));
}
}
if ($cols === 0) {
return '[]';
}

// Pre-format all cells (numbers and strings) and compute widths in one pass
$widths = array_fill(0, $cols, 0);
$formatted = [];
foreach ($matrix as $r => $row) {
$frow = [];
for ($c = 0; $c < $cols; $c++) {
$s = '';
if (array_key_exists($c, $row)) {
$cell = $row[$c];
if (is_int($cell) || is_float($cell)) {
$s = self::formatNumber($cell, $precision);
} elseif (is_string($cell)) {
$s = "'" . addslashes($cell) . "'";
} elseif (is_bool($cell)) {
$s = $cell ? 'True' : 'False';
} elseif (is_null($cell)) {
$s = 'None';
} elseif (is_array($cell)) {
$s = 'Array';
} elseif (is_object($cell)) {
$s = 'Object';
} elseif (is_resource($cell)) {
$s = 'Resource';
} else {
$s = 'Unknown';
}
}
$frow[$c] = $s;
$widths[$c] = max($widths[$c], strlen($s));
}
$formatted[$r] = $frow;
}

// Build lines using precomputed widths
$lines = [];
foreach ($formatted as $frow) {
$cells = [];
for ($c = 0; $c < $cols; $c++) {
$cells[] = str_pad($frow[$c] ?? '', $widths[$c], ' ', STR_PAD_LEFT);
}
$lines[] = '[' . implode(', ', $cells) . ']';
}

if (count($lines) === 1) {
return '[' . $lines[0] . ']';
}
return '[' . implode(",\n ", $lines) . ']';
}
}
Loading