Source code for GLXCurses.libs.TextUtils

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# It script it publish under GNU GENERAL PUBLIC LICENSE
# http://www.gnu.org/licenses/gpl-3.0.en.html
# Author: the Galaxie Curses Team, all rights reserved

from GLXCurses import GLXC
import textwrap
import re

NEWLINE = re.compile(r"\n+")


[docs]class TextUtils(object): def __init__(self): self.__height = None self.__lines = None self.__text = None self.__width = None self.__wrap = None self.__wrap_mode = None self.height = None self.lines = None self.text = None self.width = None self.wrap = None self.wrap_mode = None @property def height(self): """ Get :py:obj:`height` property value. :return: :py:obj:`height` property :rtype: int or None """ return self.__height @height.setter def height(self, height=None): """ Set ``height`` property value. :param height: :py:obj:`height` property value :type height: int or None :raise TypeError: if ``height`` parameter is not a :py:data:`int` type or None """ if height is None: height = 24 if height is not None and type(height) != int: raise TypeError("'height' argument must be a int type or None") if self.height != height: self.__height = height @property def lines(self): """ The lines This property has no effect if the text is not wrapping . :return: Lines dispatch on by list item :rtype: list """ return self.__lines @lines.setter def lines(self, lines=None): """ Set the ``lines`` property value :param lines: Lines dispatch on by list item :type lines: list :raise TypeError: When ``lines`` property is not a list type or None """ if lines is None: lines = [] if type(lines) != list: raise TypeError("'lines' property value must be list type or None") if self.lines != lines: self.__lines = lines @property def text(self): """ The contents of the label. If the string contains TXT MarkDown, you will have to set the ``use_markdown`` property to True in order for the label to display the MarkDown attributes. See also set_markdown() for a convenience function that sets both this property and the ``use_markdown`` property at the same time. If the string contains underlines acting as mnemonics, you will have to set the ``use_underline`` property to True in order for the label to display them. :return: The content of the label :rtype: str """ return self.__text @text.setter def text(self, text=None): """ Set the ``text`` property value :param text: Contents of the label :type text: str or None :raise TypeError: When ``text`` property value is not str type or None """ if text is None: text = "" if type(text) != str: raise TypeError('"text" must be a str type or None') if self.text != text: self.__text = text @property def width(self): """ Get :py:obj:`width` property value. :return: :py:obj:`width` property :rtype: int or None """ return self.__width @width.setter def width(self, width=None): """ Set :py:obj:`width` property value. :param width: :py:obj:`width` property value :type width: int or None :raise TypeError: if ``width`` parameter is not a :py:data:`int` type or None """ if width is None: width = 80 if width is not None and not isinstance(width, int): raise TypeError("'width' argument must be a int type or None") if self.width != width: self.__width = width @property def wrap(self): """ If set, wrap lines if the text becomes too wide. :return: True if wrap is in use :rtype: bool """ return self.__wrap @wrap.setter def wrap(self, wrap=None): """ Set the ``wrap`` property value :param wrap: True if wrap is in use :type wrap: bool or None :raise TypeError: When ``wrap`` property value is not bool type or None """ if wrap is None: wrap = False if type(wrap) != bool: raise TypeError("'wrap' property value must be bool type or None") if self.wrap != wrap: self.__wrap = wrap @property def wrap_mode(self): """ If line wrapping is on (see the ``wrap`` property) this controls how the line wrapping is done. The default is GLXC.WRAP_WORD, which means wrap on word boundaries. :return: How the line wrapping is done :rtype: GLXC.WrapMode """ return self.__wrap_mode @wrap_mode.setter def wrap_mode(self, wrap_mode=None): """ Set the ``wrap_mode`` property value :param wrap_mode: How the line wrapping is done or None :type wrap_mode: GLXC.WrapMode """ if wrap_mode is None: wrap_mode = GLXC.WRAP_WORD if type(wrap_mode) != str: raise TypeError("'wrap_mode' property value must be a str type or None") if str(wrap_mode).upper() not in GLXC.WrapMode: raise ValueError("'wrap_mode' must be a valid GLXC.WrapMode") if self.wrap_mode != wrap_mode: self.__wrap_mode = wrap_mode
[docs] def scan(self): pass
[docs] def text_wrap(self, height=None, width=None): if height is None: height = self.height if width is None: width = self.width self.lines = None if self.wrap: for line in re.split(NEWLINE, self.text)[:-1]: len_line = 0 if self.wrap_mode == GLXC.WRAP_WORD_CHAR: # Wrap this text. wrapped = textwrap.wrap( line, width=width, fix_sentence_endings=True, break_long_words=True, break_on_hyphens=True, ) if len(self.lines) <= height: self.lines += wrapped elif self.wrap_mode == GLXC.WRAP_CHAR: if len(line) < self.width: if len(self.lines) < height: self.lines.append(line) else: if len(self.lines) < height: self.lines += [ line[ind : ind + width] for ind in range(0, len(line), width) ] else: final_line = [] for word in line.split(" "): len_word = len(word) if len_line + len_word <= width: final_line.append(word) len_line += len_word + 1 # else: # final_line.append("".join(line)) # line = [word] # len_line = len_word + 1 if len(self.lines) < height: self.lines.append(" ".join(final_line)) else: # This is the default display/view for line in re.split(NEWLINE, self.text)[:-1]: self.lines.append(line) return self.lines