{"action":"created","issue":{"url":"https://api.github.com/repos/Robpol86/terminaltables/issues/28","repository_url":"https://api.github.com/repos/Robpol86/terminaltables","labels_url":"https://api.github.com/repos/Robpol86/terminaltables/issues/28/labels{/name}","comments_url":"https://api.github.com/repos/Robpol86/terminaltables/issues/28/comments","events_url":"https://api.github.com/repos/Robpol86/terminaltables/issues/28/events","html_url":"https://github.com/Robpol86/terminaltables/issues/28","id":156136977,"number":28,"title":"Add title_cb for truncating titles.","user":{"login":"Robpol86","id":3413339,"avatar_url":"https://avatars.githubusercontent.com/u/3413339?v=3","gravatar_id":"","url":"https://api.github.com/users/Robpol86","html_url":"https://github.com/Robpol86","followers_url":"https://api.github.com/users/Robpol86/followers","following_url":"https://api.github.com/users/Robpol86/following{/other_user}","gists_url":"https://api.github.com/users/Robpol86/gists{/gist_id}","starred_url":"https://api.github.com/users/Robpol86/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Robpol86/subscriptions","organizations_url":"https://api.github.com/users/Robpol86/orgs","repos_url":"https://api.github.com/users/Robpol86/repos","events_url":"https://api.github.com/users/Robpol86/events{/privacy}","received_events_url":"https://api.github.com/users/Robpol86/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-05-22T06:02:27Z","updated_at":"2016-10-06T08:56:10Z","closed_at":null,"body":"The default is to hide the title if it doesn't fit. I didn't remember this until I was done writing truncating code. Saving it here for future reference.\r\n\r\n```python\r\ndef build_border(column_widths, horizontal, left, intersect, right, title=None):\r\n    \"\"\"Build the top/bottom/middle row. Optionally embed the table title within the border.\r\n\r\n    Title is truncated to fit in between left/right characters.\r\n\r\n    Example return value:\r\n    ('<', '-----', '+', '------', '+', '-------', '>')\r\n    ('<', 'My Table', '----', '+', '------->')\r\n\r\n    :param iter column_widths: List of integers representing column widths.\r\n    :param str horizontal: Character to stretch across each column.\r\n    :param str left: Left border.\r\n    :param str intersect: Column separator.\r\n    :param str right: Right border.\r\n    :param str title: Overlay the title on the border between the left and right characters.\r\n\r\n    :return: Prepared border as a tuple of strings.\r\n    :rtype: tuple\r\n    \"\"\"\r\n    if not title or not column_widths or not horizontal:\r\n        return tuple(combine((horizontal * c for c in column_widths), left, intersect, right))\r\n    title, length = truncate(title, sum(column_widths) + len(intersect) * (len(column_widths) - 1))\r\n\r\n    # Handle title fitting in the first column.\r\n    if length == column_widths[0]:\r\n        return tuple(combine([title] + [horizontal * c for c in column_widths[1:]], left, intersect, right))\r\n    if length < column_widths[0]:\r\n        columns = [title + horizontal * (column_widths[0] - length)] + [horizontal * c for c in column_widths[1:]]\r\n        return tuple(combine(columns, left, intersect, right))\r\n\r\n    # Handle wide titles/narrow columns.\r\n    columns_and_intersects = [title]\r\n    for width in combine(column_widths, None, bool(intersect), None):\r\n        # If title is taken care of.\r\n        if length < 1:\r\n            columns_and_intersects.append(intersect if width is True else horizontal * width)\r\n        # If title's last character overrides an intersect character.\r\n        elif width is True and length == 1:\r\n            length = 0\r\n        # If this is an intersect character that is overridden by the title.\r\n        elif width is True:\r\n            length -= 1\r\n        # If title's last character is within a column.\r\n        elif width >= length:\r\n            columns_and_intersects[0] += horizontal * (width - length)  # Append horizontal chars to title.\r\n            length = 0\r\n        # If remainder of title won't fit in a column.\r\n        else:\r\n            length -= width\r\n\r\n    return tuple(combine(columns_and_intersects, left, None, right))\r\n```\r\n\r\n```python\r\ndef truncate(string, max_length):\r\n    \"\"\"Truncate string to a maximum length. Handles CJK characters.\r\n\r\n    :param str string: String to operate on.\r\n    :param int max_length: Truncate string to this visible size. May truncate to one shorter if CJK in the middle.\r\n\r\n    :return: Truncated string and its length (str, int).\r\n    :rtype: tuple\r\n    \"\"\"\r\n    truncated = list()\r\n    length = 0\r\n    done = False\r\n\r\n    # Convert to unicode.\r\n    try:\r\n        string = string.decode('u8')\r\n    except (AttributeError, UnicodeEncodeError):\r\n        pass\r\n\r\n    for item in RE_COLOR_ANSI.split(string):\r\n        if not item:\r\n            continue\r\n        if RE_COLOR_ANSI.match(item):\r\n            truncated.append(item)\r\n            continue\r\n        if done:\r\n            continue\r\n        for char in item:\r\n            width = 2 if unicodedata.east_asian_width(char) in ('F', 'W') else 1\r\n            if length + width > max_length:\r\n                done = True\r\n                break\r\n            truncated.append(char)\r\n            length += width\r\n\r\n    return ''.join(truncated), length\r\n```"},"comment":{"url":"https://api.github.com/repos/Robpol86/terminaltables/issues/comments/251904730","html_url":"https://github.com/Robpol86/terminaltables/issues/28#issuecomment-251904730","issue_url":"https://api.github.com/repos/Robpol86/terminaltables/issues/28","id":251904730,"user":{"login":"rschiang","id":1512231,"avatar_url":"https://avatars.githubusercontent.com/u/1512231?v=3","gravatar_id":"","url":"https://api.github.com/users/rschiang","html_url":"https://github.com/rschiang","followers_url":"https://api.github.com/users/rschiang/followers","following_url":"https://api.github.com/users/rschiang/following{/other_user}","gists_url":"https://api.github.com/users/rschiang/gists{/gist_id}","starred_url":"https://api.github.com/users/rschiang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rschiang/subscriptions","organizations_url":"https://api.github.com/users/rschiang/orgs","repos_url":"https://api.github.com/users/rschiang/repos","events_url":"https://api.github.com/users/rschiang/events{/privacy}","received_events_url":"https://api.github.com/users/rschiang/received_events","type":"User","site_admin":false},"created_at":"2016-10-06T08:56:10Z","updated_at":"2016-10-06T08:56:10Z","body":" The `truncate()` function seems almost done. \r\n@Robpol86 Is there any chance we can help with this issue? 👻 \r\n"}}
{"actor":{"display_login":"rschiang"}}