Problems aligning unicode characters in python

Viewed 343

I am trying the get the vertical bars to be aligned in the output of the following program

print('  |\n   |')

The special 'N' is U+1D4A9.

Using ipython in my terminal (I am using Ubuntu) the alignment is fine:

enter image description here

But if I run the exact same code in spyder the output will not be aligned:

enter image description here

Note that I am using the exact same font and font size in both examples (Ubuntu Mono 12). I have also tried to get it aligned by inserting all types of varying size unicode spaces without success. I have also tested jupyter and it doesn't align there either.

My main question is how can I get this to align in both the terminal and in spyder/jupyter. It would also be interesting to know why it doesn't align now as I am using the exact same font. Differences in the font renderers?

Here is also the output from the terminal in text (looks slightliy misaligned in my browser):

In [1]: print('  |\n   |')                                                                                                                                               
  |
   |
1 Answers

it s a problem in current Qt output for cell-based terminals in that different width characters are not properly aligned with the cell-grid used by the terminal. One workaround is to try to enforce the alignment by using other positioning characters than simply printing the non-standard characters. Two such characters are \t and \b - \t - the "tab" character will forward the printing to the next "tab stop" - by default, multiples of 8 "single width character cells". That is, use: print('\t|\n\t|') - here is what I get in Konsole (another Qt based terminal):

Ipython session on konsole depicting  the use of <code>\t</code> for alignment

(The \b character means "backspace" - so I printed 4 of them to walk "back" 4 single-width cells to get close to the arrangement you had in mind)

use a terminal library

Another option, very appropriate if you want an interactive app with a sophisticated layout (like displaying colors, accepting user input without having to wait for "enter" to be pressed) if to use the terminedia library (disclaimer: I am the author of this project).

It allows you to deal with the terminal explicly as a grid, and will "know" when non-standard width characters are printed and 'round' their width to two cells.

So, to display the samething using terminedia, I instantiated a "Screen" object, which allows me to use print_at at an exact location - the full code I used was:

import terminedia as TM
sc = TM.Screen()
sc.print_at((0, 10),'  |', color="red")
sc.print_at((0,11), '    | ', color="red")
sc.update()

To install terminedia, use pip install git+https://github.com/jsbueno/terminedia.git (sorry, I am at fault for not making a new release)

Output created using terminedia

Related