mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
calibredb list: Handle multibyte chars
calibredb list: When outputting data in columns, handle multibyte and east asian characters correctly. Fixes #1190476 [calibredb list series result into multilines when series length > 4](https://bugs.launchpad.net/calibre/+bug/1190476)
This commit is contained in:
parent
9992d4f1cb
commit
836b955571
@ -8,6 +8,7 @@ Command line interface to the calibre database.
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
import sys, os, cStringIO, re
|
import sys, os, cStringIO, re
|
||||||
|
import unicodedata
|
||||||
from textwrap import TextWrapper
|
from textwrap import TextWrapper
|
||||||
|
|
||||||
from calibre import preferred_encoding, prints, isbytestring
|
from calibre import preferred_encoding, prints, isbytestring
|
||||||
@ -98,9 +99,14 @@ def do_list(db, fields, afields, sort_by, ascending, search_text, line_width, se
|
|||||||
else:
|
else:
|
||||||
record[f] = unicode(record[f])
|
record[f] = unicode(record[f])
|
||||||
record[f] = record[f].replace('\n', ' ')
|
record[f] = record[f].replace('\n', ' ')
|
||||||
|
def chr_width(x):
|
||||||
|
return 1 + unicodedata.east_asian_width(x).startswith('W')
|
||||||
|
def str_width(x):
|
||||||
|
return sum(map(chr_width, x))
|
||||||
|
|
||||||
for i in data:
|
for i in data:
|
||||||
for j, field in enumerate(fields):
|
for j, field in enumerate(fields):
|
||||||
widths[j] = max(widths[j], len(unicode(i[field])))
|
widths[j] = max(widths[j], str_width(i[field]))
|
||||||
|
|
||||||
screen_width = geometry()[0] if line_width < 0 else line_width
|
screen_width = geometry()[0] if line_width < 0 else line_width
|
||||||
if not screen_width:
|
if not screen_width:
|
||||||
@ -128,14 +134,14 @@ def do_list(db, fields, afields, sort_by, ascending, search_text, line_width, se
|
|||||||
o = cStringIO.StringIO()
|
o = cStringIO.StringIO()
|
||||||
|
|
||||||
for record in data:
|
for record in data:
|
||||||
text = [wrappers[i].wrap(unicode(record[field]).encode('utf-8')) for i, field in enumerate(fields)]
|
text = [wrappers[i].wrap(unicode(record[field])) for i, field in enumerate(fields)]
|
||||||
lines = max(map(len, text))
|
lines = max(map(len, text))
|
||||||
for l in range(lines):
|
for l in range(lines):
|
||||||
for i, field in enumerate(text):
|
for i, field in enumerate(text):
|
||||||
ft = text[i][l] if l < len(text[i]) else ''
|
ft = text[i][l] if l < len(text[i]) else u''
|
||||||
filler = '%*s'%(widths[i]-len(ft)-1, '')
|
filler = u'%*s'%(widths[i]-str_width(ft)-1, u'')
|
||||||
o.write(ft)
|
o.write(ft.encode('utf-8'))
|
||||||
o.write(filler+separator)
|
o.write((filler+separator).encode('utf-8'))
|
||||||
print >>o
|
print >>o
|
||||||
return o.getvalue()
|
return o.getvalue()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user