Skip to content
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

Wrong formatting of vertical style tables with headers containing multi-byte characters #54433

Closed
mcpicoli opened this issue Mar 28, 2024 · 2 comments

Comments

@mcpicoli
Copy link

mcpicoli commented Mar 28, 2024

Symfony version(s) affected

6.4.2

Description

When using vertical style tables, whenever the component has to calculate the header width dynamically, the calculated width uses the total number of bytes of the string involved instead of the actual number of characters that would be rendered. That results in misaligned columns (and ugly tables) if the length of actual renderable characters is smaller than the next smallest length.

How to reproduce

Please note that I am using a Laravel console command for convenience only. The code that matters uses only Symfony objects and methods!

Create and run the following code inside any Laravel project. The console command may be created using php artisan make:command TestBrokenTable. Again, this is only by convenience, the affected code does not depend on Laravel! (I do not have any Symfony framework project available!)

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Output\BufferedOutput;

class TestBrokenTable extends Command
{
	/**
	 * The name and signature of the console command.
	 *
	 * @var string
	 */
	protected $signature = "app:test-broken-table";

	/**
	 * The console command description.
	 *
	 * @var string
	 */
	protected $description = "Command description";

	/**
	 * Execute the console command.
	 */
	public function handle()
	{
		$headers = [
			"long without MB chars",
			"áéíóú MB chars",					// <-- This will cause problems
			"Column 3 anything",
		];

		// This will NOT cause problems...

		// $headers = [
		// 	"long without MB chars",
		// 	"aeiou MB chars",
		// 	"Column 3 anything",
		// ];

		$this->line("Middle Header:");
		$this->line("Bytes: ".strlen($headers[1]));
		$this->line("Chars: ".mb_strlen($headers[1]));
		
		$data = [
			[
				"Shorter value",
				"Value with MB chars áéíóú",
				"Another Value",
			],
		];
		
		$output = new BufferedOutput(decorated: true);
		
		$table = new Table($output);
		$table->setHeaders($headers);
		$table->setRows($data);
		$table->setVertical();
		
		$table->render();
		
		$text = $output->fetch();
		
		print($text);
	}
}

The output is as follows:

image

If I remove the multi-byte characters, the output is now correct:

image

If I use a table with horizontal (standard) layout, the problem does not occur.

Possible Solution

No response

Additional Context

All of the strings are in UTF-8 format.
Using Microsoft Visual Studio Code (latest update as of 2024-03-28).
Using Windows 10 Professional (latest update as of 2024-03-28).

In the above examples, "bytes" are the result of the strlen() function and "chars" the result of mb_strlen().

@xabbuh
Copy link
Member

xabbuh commented Mar 28, 2024

Can you confirm that #54435 fixes this?

@mcpicoli
Copy link
Author

Yes I can confirm that the exact same code listed before now works correctly after applying the changes. Evidence below.

image

fabpot added a commit that referenced this issue Mar 31, 2024
…tical-style tables (xabbuh)

This PR was merged into the 6.4 branch.

Discussion
----------

[Console] respect multi-byte characters when rendering vertical-style tables

| Q             | A
| ------------- | ---
| Branch?       | 6.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #54433
| License       | MIT

Commits
-------

a98a616 respect multi-byte characters when rendering vertical-style tables
@fabpot fabpot closed this as completed Mar 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants