Imported from archive.
[mudpy.git] / lib / muff / muffmisc.py
1 """Miscellaneous objects for the MUFF Engine"""
2
3 # Copyright (c) 2005 mudpy, Jeremy Stanley <fungi@yuggoth.org>, all rights reserved.
4 # Licensed per terms in the LICENSE file distributed with this software.
5
6 # hack to load all modules in the muff package
7 import muff
8 for module in muff.__all__:
9         exec("import " + module)
10
11 def broadcast(output):
12         """Send a message to all connected users."""
13         for each_user in muffvars.userlist:
14                 each_user.send(output)
15
16 def wrap_ansi_text(text, width):
17         """Wrap text with arbitrary width while ignoring ANSI colors."""
18
19         # the current position in the entire text string, including all
20         # characters, printable or otherwise
21         absolute_position = 0
22
23         # the current text position relative to the begining of the line,
24         # ignoring color escape sequences
25         relative_position = 0
26
27         # whether the current character is part of a color escape sequence
28         escape = False
29
30         # iterate over each character from the begining of the text
31         for each_character in text:
32
33                 # the current character is the escape character
34                 if each_character == chr(27):
35                         escape = True
36
37                 # the current character is within an escape sequence
38                 elif escape:
39
40                         # the current character is m, which terminates the
41                         # current escape sequence
42                         if each_character == "m":
43                                 escape = False
44
45                 # the current character is a newline, so reset the relative
46                 # position (start a new line)
47                 elif each_character == "\n":
48                         relative_position = 0
49
50                 # the current character meets the requested maximum line width,
51                 # so we need to backtrack and find a space at which to wrap
52                 elif relative_position == width:
53
54                         # distance of the current character examined from the
55                         # relative position
56                         wrap_offset = 0
57
58                         # count backwards until we find a space
59                         while text[absolute_position - wrap_offset] != " ":
60                                 wrap_offset += 1
61
62                         # insert an eol in place of the space
63                         text = text[:absolute_position - wrap_offset] + "\r\n" + text[absolute_position - wrap_offset + 1:]
64
65                         # increase the absolute position because an eol is two
66                         # characters but the space it replaced was only one
67                         absolute_position += 1
68
69                         # now we're at the begining of a new line, plus the
70                         # number of characters wrapped from the previous line
71                         relative_position = wrap_offset
72
73                 # as long as the character is not a carriage return and the
74                 # other above conditions haven't been met, count it as a
75                 # printable character
76                 elif each_character != "\r":
77                         relative_position += 1
78
79                 # increase the absolute position for every character
80                 absolute_position += 1
81
82         # return the newly-wrapped text
83         return text
84