From 9de322bea3fe5e9431fd1a5aeef8841ef27b19c1 Mon Sep 17 00:00:00 2001
From: mathieui
Date: Tue, 14 May 2013 22:29:45 +0200
Subject: Rewrite the poezio colors parser (also Fix #2279)
The parser now handles text with multiple style attributes
(e.g. bold, underlined and red text).
---
src/xhtml.py | 93 +++++++++++++++++++++++++++++++-----------------------------
1 file changed, 48 insertions(+), 45 deletions(-)
(limited to 'src')
diff --git a/src/xhtml.py b/src/xhtml.py
index cae3e8f4..11435ab3 100644
--- a/src/xhtml.py
+++ b/src/xhtml.py
@@ -398,61 +398,64 @@ number_to_color_names = {
7: 'white'
}
+def format_inline_css(_dict):
+ return ''.join(('%s: %s;' % (key, value) for key, value in _dict.items()))
+
def poezio_colors_to_html(string):
"""
- Convert poezio colors to html makups
- (e.g. \x191: )
+ Convert poezio colors to html
+ (e.g. \x191}: )
"""
- # XXX: You cannot underline AND use color on the same portion of your
- # message (because both these things use a element, and the
- # current way it is done, when you open a element, you close the
- # previous one). Dectecting if a span is already opened, close it and
- # reopen it with the same style PLUS the new style seems complicated.
- # I'll keep it that way unless someone fixes that properly.
-
- # a list of all opened elements, e.g. ['strong', 'span']
- # So that we know what we need to close
- opened_elements = []
- res = ""
+ # Maintain a list of the current css attributes used
+ # And check if a tag is open (by design, we only open
+ # spans tag, and they cannot be nested.
+ current_attrs = {}
+ tag_open = False
next_attr_char = string.find('\x19')
+ build = ["
"]
+
+ def check_property(key, value):
+ nonlocal tag_open
+ if current_attrs.get(key, None) == value:
+ return
+ current_attrs[key] = value
+ if tag_open:
+ tag_open = False
+ build.append('
')
+
while next_attr_char != -1:
attr_char = string[next_attr_char+1].lower()
- if next_attr_char != 0:
- res += xml.sax.saxutils.escape(string[:next_attr_char])
+
+ if next_attr_char != 0 and string[:next_attr_char]:
+ if current_attrs and not tag_open:
+ build.append('' % format_inline_css(current_attrs))
+ tag_open = True
+ build.append(xml.sax.saxutils.escape(string[:next_attr_char]))
+
if attr_char == 'o':
- for elem in opened_elements[::-1]:
- res += '%s>' % (elem,)
- opened_elements = []
+ if tag_open:
+ build.append('')
+ tag_open = False
+ current_attrs = {}
elif attr_char == 'b':
- if 'strong' not in opened_elements:
- opened_elements.append('strong')
- res += ''
+ check_property('font-weight', 'bold')
elif attr_char == 'u':
- if 'strong' in opened_elements:
- res += ''
- opened_elements.remove('strong')
- if 'span' in opened_elements:
- res += ''
- else:
- opened_elements.append('span')
- res += ""
+ check_property('text-decoration', 'underline')
+
if attr_char in digits:
- number_str = string[next_attr_char+1:string.find('}', next_attr_char)]
- number = int(number_str)
- if 'strong' in opened_elements:
- res += ''
- opened_elements.remove('strong')
- if 'span' in opened_elements:
- res += ''
- else:
- opened_elements.append('span')
- res += "" % (ncurses_color_to_html(number),)
- string = string[next_attr_char+len(number_str)+2:]
+ number = int(attr_char)
+ check_property('color', number_to_color_names.get(number, 'black'))
+ string = string[next_attr_char+3:]
else:
string = string[next_attr_char+2:]
next_attr_char = string.find('\x19')
- res += xml.sax.saxutils.escape(string)
- for elem in opened_elements[::-1]:
- res += '%s>' % (elem,)
- res += "
"
- return res.replace('\n', '
')
+
+ if current_attrs and not tag_open and string:
+ build.append('' % format_inline_css(current_attrs))
+ tag_open = True
+ build.append(xml.sax.saxutils.escape(string))
+ if tag_open:
+ build.append('')
+ build.append("")
+ text = ''.join(build)
+ return text.replace('\n', '
')
--
cgit v1.2.3