Edgewall Software

Ticket #4717: t4717-using-east-asian-width-r10051.diff

File t4717-using-east-asian-width-r10051.diff, 4.6 KB (added by jomae, 19 months ago)

Refreshed t4717.diff to [10051/branches/0.12-stable]

  • trac/ticket/notification.py

    diff --git a/trac/ticket/notification.py b/trac/ticket/notification.py
    index 7602393..5e1eca0 100644
    a b from trac.notification import NotifyEmail 
    2222from trac.ticket.api import TicketSystem 
    2323from trac.util import md5 
    2424from trac.util.datefmt import to_utimestamp 
    25 from trac.util.text import CRLF, wrap, obfuscate_email_address 
     25from trac.util.text import CRLF, wrap, obfuscate_email_address, to_unicode 
    2626from trac.util.translation import deactivate, reactivate 
    2727 
    2828from genshi.template.text import NewTextTemplate 
     29from unicodedata import east_asian_width 
    2930 
    3031class TicketNotificationSystem(Component): 
    3132 
    class TicketNotificationSystem(Component): 
    5152        `$prefix` being the value of the `smtp_subject_prefix` option. 
    5253        ''(since 0.11)''""") 
    5354 
     55    ambiguous_char_width = Option('notification', 'ambiguous_char_width', 
     56                                  'single', 
     57        """Which width of ambiguous characters (e.g. 'single' or 'double') 
     58        should be used in the table of notification mail. 
     59 
     60        If 'single', the same width as characters in US-ASCII. This is expected 
     61        by most users. If 'double', twice the width of US-ASCII characters. 
     62        This is expected by CJK users.""") 
     63 
    5464 
    5565class TicketNotifyEmail(NotifyEmail): 
    5666    """Notification of ticket changes.""" 
    class TicketNotifyEmail(NotifyEmail): 
    6575    def __init__(self, env): 
    6676        NotifyEmail.__init__(self, env) 
    6777        self.prev_cc = [] 
     78        self.ambiguous_char_width = env.config.get('notification', 
     79                                                   'ambiguous_char_width', 
     80                                                   'single') 
     81        self.text_widths = {} 
    6882 
    6983    def notify(self, ticket, newticket=True, modtime=None): 
    7084        """Send ticket change notification e-mail (untranslated)""" 
    class TicketNotifyEmail(NotifyEmail): 
    192206            fval = tkt[fname] or '' 
    193207            if fval.find('\n') != -1: 
    194208                continue 
     209            if fname in ['owner', 'reporter']: 
     210                fval = obfuscate_email_address(fval) 
    195211            idx = 2 * (i % 2) 
    196             width[idx] = max(len(f['label']), width[idx]) 
    197             width[idx + 1] = max(len(fval), width[idx + 1]) 
     212            width[idx] = max(self.get_text_width(f['label']), width[idx]) 
     213            width[idx + 1] = max(self.get_text_width(fval), width[idx + 1]) 
    198214            i += 1 
    199215        width_l = width[0] + width[1] + 5 
    200216        width_r = width[2] + width[3] + 5 
    class TicketNotifyEmail(NotifyEmail): 
    231247                str_tmp = u'%s:  %s' % (f['label'], unicode(fval)) 
    232248                idx = i % 2 
    233249                cell_tmp[idx] += wrap(str_tmp, width_lr[idx] - 2 + 2 * idx, 
    234                                       (width[2 * idx] - len(f['label']) 
     250                                      (width[2 * idx] 
     251                                       - self.get_text_width(f['label']) 
    235252                                       + 2 * idx) * ' ', 
    236253                                      2 * ' ', CRLF) 
    237254                cell_tmp[idx] += CRLF 
    238255                i += 1 
    239256        cell_l = cell_tmp[0].splitlines() 
    240257        cell_r = cell_tmp[1].splitlines() 
    241         format = u'%%-%is|%%s%%s' % width_l 
    242258        for i in range(max(len(cell_l), len(cell_r))): 
    243259            if i >= len(cell_l): 
    244260                cell_l.append(width_l * ' ') 
    245261            elif i >= len(cell_r): 
    246262                cell_r.append('') 
    247             txt += format % (cell_l[i], cell_r[i], CRLF) 
     263            fmt_width = width_l - self.get_text_width(cell_l[i]) \ 
     264                        + len(cell_l[i]) 
     265            txt += u'%-*s|%s%s' % (fmt_width, cell_l[i], cell_r[i], CRLF) 
    248266        if big: 
    249267            txt += sep 
    250268            for name, value in big: 
    class TicketNotifyEmail(NotifyEmail): 
    364382            hdrs['References'] = msgid 
    365383        NotifyEmail.send(self, torcpts, ccrcpts, hdrs) 
    366384 
     385    def get_text_width(self, text): 
     386        if self.ambiguous_char_width == 'double': 
     387            ambiwidth = 2 
     388        else: 
     389            ambiwidth = 1 
     390 
     391        if not isinstance(text, unicode): 
     392            text = to_unicode(text) 
     393 
     394        if text in self.text_widths: 
     395            return self.text_widths[text] 
     396 
     397        width = 0 
     398        for ch in text: 
     399            eaw = east_asian_width(ch) 
     400            if eaw == 'W' or eaw == 'F': 
     401                width += 2 
     402            elif eaw == 'A': 
     403                width += ambiwidth 
     404            else: 
     405                width += 1 
     406        self.text_widths[text] = width 
     407        return width 
     408