Skip to content
Advertisement

how do i manually parse output of .dump() file into a text widget

how do i manually parse output of .dump() from a text widget that has italic and bold text in it to a different text widget to load it along with its text format.

this is the code if it helps, the text should be saved along with text format but when the file is open the text format is gone:

from tkinter import *
from tkinter import filedialog
root = Tk()

textpad=Text(root, font='Consolas 11')
textpad.pack()

def save():
    content=textpad.get(1.0,'end')
    filename=filedialog.asksaveasfilename(title='open file',filetypes=(("text","*.txt"),("html",".html"),("all types","*.*")))
    openit=open(filename,'w')
    openit.write(content)
    openit.close()

def opens():
    textpad.delete(1.0,'end')
    filename=filedialog.askopenfilename(title='open file',filetypes=(("text","*.txt"),("html",".html"),("all types","*.*")))
    openit=open(filename,'r')
    content=openit.read()
    textpad.insert('end',content.strip())
    openit.close()

def boldtext():
    textpad.selection_get()
    textpad.tag_add('bold','sel.first','sel.last')
    textpad.tag_config('bold',font='Consolas 11 bold')

savebtn=Button(text='save',command=save)
savebtn.pack()
openbtn=Button(text='open',command=opens)
openbtn.pack()
bold=Button(text='bold',command=boldtext)
bold.pack()
root.mainloop()

Advertisement

Answer

The Text widget dump method returns a list of tuples. Each tuple will be of the form (key, value, index). key will be one of the following: text, mark, tagon, tagoff, image, or window. value will be dependent on the key. index is the location in the text. For example, with tagon and tagoff the value will be the name of the tag. For text it’s a string of text characters.

Consider a text widget with the tags “bold” for bold and “italic” for italic. It might look something like this:

screenshot of text widget with bold and italicized text

When you call the dump method you will get something like the following (line breaks added for clarity):

[('text', 'Here is a sentence with ', '1.0'),
 ('tagon', 'bold', '1.24'),
 ('text', 'bolded', '1.24'),
 ('tagoff', 'bold', '1.30'),
 ('text', ' and ', '1.30'),
 ('tagon', 'italic', '1.35'),
 ('text', 'italicized', '1.35'),
 ('tagoff', 'italic', '1.45'),
 ('text', ' text.', '1.45')]

A conversion function needs to loop over that data and process each key. For example, for every tagon you can add the tag to a list, and for every tagoff you can remove it from the list. For the text tag you just insert the text with the current list of tags.

The solution might look something like this:

def undump(dump_data, target_widget, index="1.0"):
    tags = []
    target.mark_set("paste_index", index)
    for (key, value, index) in dump_data:
        if key == "tagon":
            tags.append(value)
        elif key == "tagoff":
            tags.remove(value)
        elif key == "mark":
            target.mark_set(value, index)
        elif key == "text":
            target.insert("paste_index", value, tags)

Given a original text widget named source and a second text widget named target, you would call it like this:

undump(source.dump("1.0", "end-1c"), target)

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement