Python: Create strikethrough / strikeout / overstrike string type

Question:

I would appreciate some help in creating a function that iterates through a string and combines each character with a strikethrough character (u0336). With the output being a striked out version of the original string. Like this..

Something like.

def strike(text):
    i = 0
    new_text = ''
    while i < len(text):
        new_text = new_text + (text[i] + u'u0336')
        i = i + 1
    return(new_text)

So far I’ve only been able to concatenate rather than combine.

Asked By: I_do_python

||

Answers:

def strike(text):
    result = ''
    for c in text:
        result = result + c + 'u0336'
    return result

Cool effect.

Answered By: pdw

How about:

from itertools import repeat, chain

''.join(chain.from_iterable(zip(text, repeat('u0336'))))

or even more simply,

'u0336'.join(text) + 'u0336'
Answered By: roippi

Edited

As pointed out by roippi other answers so far are actually correct, and this one below is wrong. Leaving it here in case others get the same wrong idea that I did.


Other answers so far are wrong – they do not strike out the first character of the string. Try this instead:

def strike(text):
    return ''.join([u'u0336{}'.format(c) for c in text])

>>> print(strike('this should do the trick'))
'̶t̶h̶i̶s̶ ̶s̶h̶o̶u̶l̶d̶ ̶d̶o̶ ̶t̶h̶e̶ ̶t̶r̶i̶c̶k'

This will work in Python 2 and Python 3.

Answered By: mhawke

If you want to include spaces in the strikethrough, you’ll have to replace normal spaces with non-break spaces:

def strikethrough(mytext):
    ''' replacing space with 'non-break space' and striking through'''
    return("u0336".join(mytext.replace(" ","u00a0"))+ "u0336")
Answered By: multitink

Although 'u0336' can solve some problems, it may not work in different language situations.

Like: 我是誰 → ̶我̶是̶誰.

As you can see, the otherwise good text has turned into strange symbols that we can’t read.

So I write the code below:

import tkinter as tk
root = tk.Tk()
root.state('zoomed')

class strikethrough(tk.Frame):
    def __init__(self, frame, text, **options):
        super().__init__(frame)
        c = tk.Canvas(self, **options)
        textId = c.create_text(0, 0, text = text, fill = "#FFFFFF", font = ("", 30, "bold"))
        x1, y1, x2, y2 = c.bbox(textId)
        linewidth = 3
        lineXOffset = 3
        lineId = c.create_line(x1, 0, x2, 0, width=linewidth)
        c.pack(fill="both", expand=1)
        c.bind("<Configure>", lambda event: TextPositionChange(c, textId, lineId, linewidth, lineXOffset))
        self.canvas, self.textId = c, textId


def TextPositionChange(canvas, TextId, LineId, LineWidth, LineXOffset):
    x1, y1, x2, y2 = canvas.bbox(TextId)
    xOffSet, yOffSet = (x2-x1)/2, (y2-y1)/2
    x, y = canvas.winfo_width()/2-xOffSet, canvas.winfo_height()/2-yOffSet #left_top_position
    canvas.moveto(TextId, x, y)
    canvas.moveto(LineId, x-LineXOffset, y+(y2-y1)/2-LineWidth/2)

frame = strikethrough(root, "我是誰", bg="#777777")
frame.place(relx=0.5, rely=0.5, relwidth=0.5, anchor="center")

root.mainloop()
Answered By: 謝咏辰
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.