mirror of
https://github.com/tromey/gdb-gui.git
synced 2025-07-21 04:51:20 +02:00
attempt to parse pango markup to put into a text buffer
This can't easily be done at present, see the new files for some links. Meanwhile I decided to take another route.
This commit is contained in:
109
gui/markup.py
Normal file
109
gui/markup.py
Normal file
@@ -0,0 +1,109 @@
|
||||
# Originally from https://github.com/wrhansen/MarkupToTextTag
|
||||
# Then modified a bit to suit.
|
||||
# This will be obsolete at some point in the future -- see
|
||||
# https://bugzilla.gnome.org/show_bug.cgi?id=59390.
|
||||
|
||||
# This package is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from gi.repository import Gtk, Pango
|
||||
|
||||
import gui.pangohack
|
||||
|
||||
__author__ = "Wesley Hansen"
|
||||
__date__ = "07/06/2012 11:29:17 PM"
|
||||
'''
|
||||
The markuptotexttag package contains the function `convertMarkup` that
|
||||
will parse a string that is formatted with pango markup and convert
|
||||
it into GtkTextTags that can be retrieved via the MarkupProps iterator.
|
||||
'''
|
||||
|
||||
def convertMarkup(string):
|
||||
'''
|
||||
Parses the string and returns a MarkupProps instance
|
||||
'''
|
||||
attr_values = ('value', 'ink_rect', 'logical_rect', 'desc', 'color')
|
||||
# This seems like a rather lame API.
|
||||
ok, attr_list, text, accel = Pango.parse_markup( string, len(string), '\0' )
|
||||
|
||||
props = MarkupProps()
|
||||
props.text = text
|
||||
|
||||
val = True
|
||||
for attr in attr_list.get_iterator():
|
||||
name = attr.type
|
||||
start = attr.start_index
|
||||
end = attr.end_index
|
||||
name = Pango.AttrType(name).value_nick
|
||||
|
||||
value = None
|
||||
for attr_value in attr_values:
|
||||
if hasattr( attr, attr_value ):
|
||||
value = getattr( attr, attr_value )
|
||||
break
|
||||
if name == 'font_desc':
|
||||
name = 'font'
|
||||
props.add( name, value, start, end )
|
||||
|
||||
return props
|
||||
|
||||
class MarkupProps(object):
|
||||
'''
|
||||
Stores properties that contain indices and appropriate values for that property.
|
||||
Includes an iterator that generates GtkTextTags with the start and end indices to
|
||||
apply them to
|
||||
'''
|
||||
def __init__(self):
|
||||
'''
|
||||
properties = ( {
|
||||
'properties': {'foreground': 'green', 'background': 'red'}
|
||||
'start': 0,
|
||||
'end': 3
|
||||
},
|
||||
{
|
||||
'properties': {'font': 'Lucida Sans 10'},
|
||||
'start': 1,
|
||||
'end':2,
|
||||
|
||||
},
|
||||
)
|
||||
'''
|
||||
self.properties = []#Sequence containing all the properties, and values, organized by like start and end indices
|
||||
self.text = ""#The raw text without any markup
|
||||
|
||||
def add( self, label, value, start, end ):
|
||||
'''
|
||||
Add a property to MarkupProps. If the start and end indices are already in
|
||||
a property dictionary, then add the property:value entry into
|
||||
that property, otherwise create a new one
|
||||
'''
|
||||
for prop in self.properties:
|
||||
if prop['start'] == start and prop['end'] == end:
|
||||
prop['properties'].update({label:value})
|
||||
else:
|
||||
new_prop = {
|
||||
'properties': {label:value},
|
||||
'start': start,
|
||||
'end':end,
|
||||
}
|
||||
self.properties.append( new_prop )
|
||||
|
||||
|
||||
def __iter__(self):
|
||||
'''
|
||||
Yields (TextTag, start, end)
|
||||
'''
|
||||
for prop in self.properties:
|
||||
tag = Gtk.TextTag()
|
||||
tag.set_properties( **prop['properties'] )
|
||||
yield (tag, prop['start'], prop['end'])
|
131
gui/pangohack.py
Normal file
131
gui/pangohack.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# From
|
||||
# https://bug646788.bugzilla-attachments.gnome.org/attachment.cgi?id=221735
|
||||
|
||||
from gi.repository import Pango
|
||||
|
||||
#Pango.AttrList
|
||||
class AttrIterator():
|
||||
def __init__ (self, attributes=[]):
|
||||
self.attributes = attributes
|
||||
self.attribute_stack = []
|
||||
self.start_index = 0
|
||||
self.end_index = 0
|
||||
if not self.next():
|
||||
self.end_index = 2**32 -1
|
||||
|
||||
def __next__(self):
|
||||
return self.next()
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
if len(self.attributes) == 0 and len(self.attribute_stack) == 0:
|
||||
return False
|
||||
self.start_index = self.end_index
|
||||
self.end_index = 2**32 - 1
|
||||
|
||||
to_remove = []
|
||||
for attr in self.attribute_stack:
|
||||
if attr.end_index == self.start_index:
|
||||
to_remove.append(attr)
|
||||
else:
|
||||
self.end_index = min(self.end_index, attr.end_index)
|
||||
|
||||
while len(to_remove) > 0:
|
||||
attr = to_remove[0]
|
||||
self.attribute_stack.remove(to_remove[0])
|
||||
try:
|
||||
to_remove.remove(attr)
|
||||
except:
|
||||
pass
|
||||
|
||||
while len(self.attributes) != 0 and \
|
||||
self.attributes[0].start_index == self.start_index:
|
||||
if self.attributes[0].end_index > self.start_index:
|
||||
self.attribute_stack.append(self.attributes[0])
|
||||
self.end_index = min(self.end_index, self.attributes[0].end_index)
|
||||
self.attributes = self.attributes[1:]
|
||||
if len(self.attributes) > 0:
|
||||
self.end_index = min(self.end_index, self.attributes[0].start_index)
|
||||
return True
|
||||
|
||||
def range(self):
|
||||
return (self.start_index, self.end_index)
|
||||
|
||||
#Dont create pango.fontdesc as it should. But half working.
|
||||
def get_font(self):
|
||||
tmp_list1 = self.attribute_stack
|
||||
fontdesc = Pango.FontDescription()
|
||||
for attr in self.attribute_stack:
|
||||
if attr.klass.type == Pango.ATTR_FONT_DESC:
|
||||
tmp_list1.remove(attr)
|
||||
attr.__class__ = gi.repository.Pango.AttrFontDesc
|
||||
fontdesc = attr.desc
|
||||
return (fontdesc, None, self.attribute_stack)
|
||||
|
||||
|
||||
|
||||
def get_iterator(self):
|
||||
tmplist = []
|
||||
def fil(val, data):
|
||||
tmplist.append(val)
|
||||
return False
|
||||
self.filter(fil, None)
|
||||
return AttrIterator(tmplist)
|
||||
|
||||
|
||||
setattr(Pango.AttrList, 'get_iterator', get_iterator)
|
||||
class AttrFamily(Pango.Attribute):
|
||||
pass
|
||||
Pango.AttrFamily = AttrFamily
|
||||
|
||||
class AttrStyle(Pango.Attribute):
|
||||
pass
|
||||
Pango.AttrStyle = AttrStyle
|
||||
|
||||
class AttrVariant(Pango.Attribute):
|
||||
pass
|
||||
Pango.AttrVariant = AttrVariant
|
||||
|
||||
class AttrWeight(Pango.Attribute):
|
||||
pass
|
||||
Pango.AttrWeight = AttrWeight
|
||||
|
||||
class AttrVariant(Pango.Attribute):
|
||||
pass
|
||||
Pango.AttrVariant = AttrVariant
|
||||
|
||||
class AttrStretch(Pango.Attribute):
|
||||
pass
|
||||
Pango.AttrStretch = AttrStretch
|
||||
|
||||
|
||||
# And to access values
|
||||
# pango_type_table = {
|
||||
# pango.ATTR_SIZE: gi.repository.Pango.AttrInt,
|
||||
# pango.ATTR_WEIGHT: gi.repository.Pango.AttrInt,
|
||||
# pango.ATTR_UNDERLINE: gi.repository.Pango.AttrInt,
|
||||
# pango.ATTR_STRETCH: gi.repository.Pango.AttrInt,
|
||||
# pango.ATTR_VARIANT: gi.repository.Pango.AttrInt,
|
||||
# pango.ATTR_STYLE: gi.repository.Pango.AttrInt,
|
||||
# pango.ATTR_SCALE: gi.repository.Pango.AttrFloat,
|
||||
# pango.ATTR_FAMILY: gi.repository.Pango.AttrString,
|
||||
# pango.ATTR_FONT_DESC: gi.repository.Pango.AttrFontDesc,
|
||||
# pango.ATTR_STRIKETHROUGH: gi.repository.Pango.AttrInt,
|
||||
# pango.ATTR_BACKGROUND: gi.repository.Pango.AttrColor,
|
||||
# pango.ATTR_FOREGROUND: gi.repository.Pango.AttrColor,
|
||||
# pango.ATTR_RISE: gi.repository.Pango.AttrInt}
|
||||
|
||||
# def make_with_value(a):
|
||||
# type_ = a.klass.type
|
||||
# klass = a.klass
|
||||
# start_index = a.start_index
|
||||
# end_index = a.end_index
|
||||
# #Nasty workaround, but then python object gets value field.
|
||||
# a.__class__ = self.pango_type_table[type_]
|
||||
# a.type = type_
|
||||
# a.start_index = start_index
|
||||
# a.end_index = end_index
|
||||
# a.klass = klass
|
||||
# return a
|
Reference in New Issue
Block a user