{"id":35587200,"url":"https://github.com/apphp/pretty-print","last_synced_at":"2026-01-04T22:14:09.035Z","repository":{"id":325625690,"uuid":"1101844140","full_name":"apphp/pretty-print","owner":"apphp","description":"PrettyPrint is a small, zero-dependency PHP utility that formats arrays in a clean, readable, PyTorch-inspired style. It supports aligned 2D tables, 3D tensors, summarized tensor views, and flexible output options.","archived":false,"fork":false,"pushed_at":"2025-12-17T22:00:48.000Z","size":162,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-21T09:25:24.299Z","etag":null,"topics":["array-formatting","data-formatting","matrix-format","php","pretty-print","pretty-printer","printer","tensor-formatting"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apphp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-22T10:49:03.000Z","updated_at":"2025-12-17T22:00:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/apphp/pretty-print","commit_stats":null,"previous_names":["apphp/pretty-print"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/apphp/pretty-print","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apphp%2Fpretty-print","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apphp%2Fpretty-print/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apphp%2Fpretty-print/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apphp%2Fpretty-print/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apphp","download_url":"https://codeload.github.com/apphp/pretty-print/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apphp%2Fpretty-print/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28208387,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2026-01-04T02:00:06.065Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["array-formatting","data-formatting","matrix-format","php","pretty-print","pretty-printer","printer","tensor-formatting"],"created_at":"2026-01-04T22:14:08.217Z","updated_at":"2026-01-04T22:14:09.014Z","avatar_url":"https://github.com/apphp.png","language":"PHP","funding_links":[],"categories":["Tools \u0026 Utilities"],"sub_categories":["Tokenizers \u0026 Prompt Utilities"],"readme":"# Pretty Pprint\n\n![GitHub stars](https://img.shields.io/github/stars/apphp/pretty-print?style=social)\n![Last commit](https://img.shields.io/github/last-commit/apphp/pretty-print)\n![License](https://img.shields.io/github/license/apphp/pretty-print)\n![Link Check](https://github.com/apphp/pretty-print/actions/workflows/php.yml/badge.svg)\n![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen)\n\nCallable pretty-printer for PHP arrays with Python-like formatting.\nPrettyPrint is a small, zero-dependency PHP utility that formats arrays in a clean, readable, PyTorch-inspired style. \nIt supports aligned 2D tables, 3D tensors, summarized tensor views, and flexible output options – making it ideal for ML experiments, \ndebugging, logging, and educational projects.\n\n## Installation\n```bash\ncomposer require apphp/pretty-print\n```\n\n## Usage\n\nNote: When used in web (non-CLI) environments, output is automatically wrapped in `\u003cpre\u003e` to preserve spacing. In CLI, no wrapping is applied. When you request a string to be returned (see `return` option), no auto-wrapping is applied.\n\n### Import functions\n\nAll examples below assume you have imported the helper functions from the `Apphp\\PrettyPrint` namespace, for example:\n\n```php\nuse function Apphp\\PrettyPrint\\pprint;\nuse function Apphp\\PrettyPrint\\pp;\nuse function Apphp\\PrettyPrint\\ppd;\n```\nor simply\n```php\nuse function Apphp\\PrettyPrint\\{pprint, pp, ppd, pdiff, pcompare};\n```\n\n### Global helper functions\n\nPrint scalars/strings\n```php\npprint('Hello', 123, 4.56);            \n// Hello 123 4.5600\n```\n\nPrint 1D arrays\n```php\npprint([1, 23, 456], [12, 3, 45]);\n// [1, 23, 456]\n// [12, 3, 45]\n```\n\nCompare two arrays with a difference matrix\n```php\n$a = [\n    [1, 2, 3],\n    [4, 5, 6],\n];\n\n$b = [\n    [1, 9, 3],\n    [0, 5, 7],\n];\n\npdiff($a, $b);\n// [[1, -, 3],\n//  [-, 5, -]]\n```\n\nCompare two arrays by printing both matrices (stacked) with colored cells\n```php\n$a = [\n    [1, 2, 3],\n    [4, 5, 6],\n];\n\n$b = [\n    [1, 9, 3],\n    [0, 5, 7],\n];\n\npcompare($a, $b);\n// prints $a above $b\n// - equal cells are green\n// - different/missing cells are red\n// In CLI: ANSI colors; in web: \u003cspan style=\"color: ...\"\u003e inside \u003cpre\u003e\n```\n![pcompare colored output](assets/pcompare-example.svg)\n\nLabel + 2D matrix\n```php\npprint([[1, 23], [456, 7]], label: 'Confusion matrix:');\n// Confusion matrix:([\n//   [  1, 23],\n//   [456,  7]\n// ])\n```\n\n2D tensor-style formatting\n```php\n$matrix = [\n    [1,2,3,4,5],\n    [6,7,8,9,10],\n    [11,12,13,14,15],\n];\npprint($matrix);\n// tensor([\n//   [ 1,  2,  3,  4,  5],\n//   [ 6,  7,  8,  9, 10],\n//   [11, 12, 13, 14, 15]\n// ])\n```\n\nCustom label instead of \"tensor\"\n```php\npprint($matrix, label: 'arr');\n// arr([\n//   [ 1,  2,  3,  4,  5],\n//   [ 6,  7,  8,  9, 10],\n//   [11, 12, 13, 14, 15]\n// ])\n```\n\n2D tensor-style formatting with summarization\n```php\n$matrix = [\n    [1, 2, 3, 4, 5],\n    [6, 7, 8, 9, 10],\n    [11, 12, 13, 14, 15],\n    [16, 17, 18, 19, 20],\n    [21, 22, 23, 24, 25],\n];\npprint($matrix, headRows: 2, tailRows: 1, headCols: 2, tailCols: 2);\n// tensor([\n//   [ 1,  2, ...,  4,  5],\n//   [ 6,  7, ...,  9, 10],\n//   ...,\n//   [21, 22, ..., 24, 25]\n// ])\n```\n\n3D tensor with head/tail blocks (PyTorch-like)\n```php\n$tensor3d = [\n    [[1, 2, 3],[4, 5, 6]],\n    [[7, 8, 9],[10, 11, 12]],\n    [[13, 14, 15],[16, 17, 18]],\n];\npprint($tensor3d, headB: 1, tailB: 1, headRows: 1, tailRows: 1, headCols: 1, tailCols: 1);\n// tensor([\n//  [[1, ..., 3],\n//   [4, ..., 6]],\n//  ...,\n//  [[13, ..., 15],\n//   [16, ..., 18]]\n// ])\n```\n\nSelect specific rows/columns\n```php\n$matrix = [\n    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],\n    [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22],\n    [23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33],\n];\n\n// Single row (1-based)\npprint($matrix, rowsOnly: 2);\n\n// Sparse rows and columns: rows 1,2,3,5,6 and cols 1,2,6,9,10\npprint($matrix, rowsOnly: '1-2,3,5-6', colsOnly: '1-2,6,9-10');\n\n// Works the same for 3D tensors (applied per 2D slice)\npprint($tensor3d, rowsOnly: '2-3', colsOnly: '1,3-4');\n```\n\nPostfix and prefix control\n```php\n// No newline at the end (like Python's end=\"\")\npprint('Same line', end: '');\n// Added newline at the end after printing\npprint('Add line');\npprint('Add line', end: \"\\n\");\n// Added addedional 2 newlines at the end after printing\npprint('Add 2 lines', end: \"\\n\\n\");\n\n// Add a prefix at the start of the printed string\npprint('Tabbed', start: \"\\t\");\n// Combine with end to avoid newline\npprint('Prompted', start: '\u003e\u003e\u003e ', end: '');\n\n// Custom separator between multiple values (default is a single space \" \")\npprint('A', 'B', 'C', sep: ', ', end: '');\n// A, B, C\n\n// Separator can also be provided via trailing options array\npprint('X', 'Y', sep: \"\\n\", end: '']);\n// X\n// Y\n```\n\nReturn the formatted string instead of printing\n```php\n$s = pprint([1, 2, 3], return: true);\n// $s contains: \"[1, 2, 3]\\n\" (no \u003cpre\u003e wrapping)\n```\n\nPrint and then exit the script\n```php\nppd('Fatal error');\n```\n\n### As an object\n\n```php\nuse Apphp\\PrettyPrint\\PrettyPrint;\n\n$pp = new PrettyPrint();\n$pp('Hello', 42);       // same as pprint('Hello', 42)\n\n$tensor3d = [\n    [[1, 2, 3],[4, 5, 6]],\n    [[7, 8, 9],[10, 11, 12]],\n    [[13, 14, 15],[16, 17, 18]],\n];\n\n// Named options are supported\n$pp($tensor3d, headB: 2, tailB: 1, headRows: 1, tailRows: 1, headCols: 1, tailCols: 1);\n\n// Label + 2D\n$pp('Metrics:', [[0.91, 0.02], [0.03, 0.88]]);\n```\n\n### Objects with `asArray()` / `toArray()`\n\nIf you pass an object that exposes an `asArray()` or `toArray()` method, `pprint` / `PrettyPrint` will automatically convert it to an array before formatting:\n\n```php\nclass Users\n{\n    public function asArray(): array\n    {\n        return [\n            ['id' =\u003e 1, 'name' =\u003e 'Alice'],\n            ['id' =\u003e 2, 'name' =\u003e 'Bob'],\n        ];\n    }\n}\n\n$users = new Users();\n\npprint($users);\n// Users([\n//   [1, Alice],\n//   [2,   Bob]\n// ])\n```\n\nIf `asArray()` is not present but `toArray()` is, `toArray()` will be used instead.\n\n## Running tests\n\n```bash\n# install dev dependencies\ncomposer install\n\n# run test suite\ncomposer test\n\n# run tests with coverage (requires Xdebug or PCOV)\ncomposer test:coverage\n```\n\nNotes:\n- **Coverage drivers**: You need Xdebug (xdebug.mode=coverage) or PCOV enabled for coverage reports. Without a driver, PHPUnit will warn and exit non‑zero.\n- You can also run PHPUnit directly: `vendor/bin/phpunit`.\n\n### Options reference\n\n- **start**: string. Prefix printed before the content. Example: `pprint('Hello', ['start' =\u003e \"\\t\"])`.\n- **end**: string. Line terminator, default is double lines. Example: `pprint('no newline', ['end' =\u003e '']);`\n- **sep**: string. Separator between multiple default-formatted arguments. Default is a new line. Examples: `pprint('A','B','C', sep: ', ', end: '')` or `pprint('X','Y', ['sep' =\u003e \"\\n\", 'end' =\u003e ''])`.\n- **label**: string. Prefix label for 2D/3D formatted arrays, default `tensor`. Example: `pprint($m, ['label' =\u003e 'arr'])`.\n- **precision**: int. Number of digits after the decimal point for floats. Example: `pprint(3.14159, precision: 2)` prints `3.14`.\n- **return**: bool. When true, do not echo; return the formatted string instead (no `\u003cpre\u003e` wrapping in web context). Example: `$s = pprint($m, return: true);`.\n- **headB / tailB**: ints. Number of head/tail 2D blocks shown for 3D tensors.\n- **headRows / tailRows**: ints. Rows shown per 2D slice with ellipsis between.\n- **headCols / tailCols**: ints. Columns shown per 2D slice with ellipsis between.\n- **rowsOnly / colsOnly**: int or string. Limit visible rows/columns.\n  - Single index: `3` or `'3'`.\n  - Range: `'2-4'` (inclusive).\n  - Sparse mix: `'1-2,5,9-11'` → indices `1,2,5,9,10,11`.\n  Applied to 2D arrays and to each 2D slice of 3D tensors.\n\nAll options can be passed as:\n- trailing array: `pprint($m, ['headRows' =\u003e 1, ...])`\n- named args (PHP 8+): `$pp($m, headRows: 1, ...)`\n\n#### Defaults\n- **label**: `tensor`\n- **sep**: `' '`\n- **precision**: `4`\n- **headB / tailB**: `5`\n- **headRows / tailRows**: `5`\n- **headCols / tailCols**: `5`\n\n#### Limits\n- **precision**: max `10`\n- **headB / tailB / headRows / tailRows / headCols / tailCols**: max `50`\n- **label**: max length `50` characters (longer labels are truncated)\n- **positional args (MAX_ARGS)**: up to `32` positional args are accepted; extras are ignored.\n\nPositional policy:\n- First arg can be a string label, number, or array.\n- Exactly two positional args are allowed only for `string label, array`.\n- Named/trailing options are applied only when the first arg is an array.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapphp%2Fpretty-print","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapphp%2Fpretty-print","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapphp%2Fpretty-print/lists"}