Merge branch 'bleed'

This commit is contained in:
chrys 2018-07-15 16:46:32 +02:00
commit 085621bbe9
22 changed files with 283 additions and 46 deletions

View File

@ -34,13 +34,6 @@ Imporove attribute handling
[] configurable (by char, by word, none) (Easy for contribution) [] configurable (by char, by word, none) (Easy for contribution)
https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
[W] Barrier Mode
- [X] Initial barrier mode
- [X] add command to toggle barrier mode
- [X] Soundicon on barrier detection
- [] Barrier detection in hilight tracking
- [] valid barriers by window edges
Improved Say all Improved Say all
[] speech callbacks [] speech callbacks
[] speech process by word [] speech process by word

View File

@ -88,6 +88,7 @@ KEY_FENRIR,KEY_T=time
2,KEY_FENRIR,KEY_T=date 2,KEY_FENRIR,KEY_T=date
KEY_KPSLASH=toggle_auto_indent KEY_KPSLASH=toggle_auto_indent
KEY_KPMINUS=attribute_cursor KEY_KPMINUS=attribute_cursor
#=toggle_has_attribute
KEY_FENRIR,KEY_S=spell_check KEY_FENRIR,KEY_S=spell_check
2,KEY_FENRIR,KEY_S=add_word_to_spell_check 2,KEY_FENRIR,KEY_S=add_word_to_spell_check
KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check

View File

@ -88,6 +88,7 @@ KEY_FENRIR,KEY_T=time
2,KEY_FENRIR,KEY_T=date 2,KEY_FENRIR,KEY_T=date
KEY_FENRIR,KEY_BACKSLASH=toggle_auto_indent KEY_FENRIR,KEY_BACKSLASH=toggle_auto_indent
KEY_FENRIR,KEY_MINUS=attribute_cursor KEY_FENRIR,KEY_MINUS=attribute_cursor
#=toggle_has_attribute
KEY_FENRIR,KEY_S=spell_check KEY_FENRIR,KEY_S=spell_check
2,KEY_FENRIR,KEY_S=add_word_to_spell_check 2,KEY_FENRIR,KEY_S=add_word_to_spell_check
KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check

View File

@ -2,6 +2,7 @@
^[OP=toggle_tutorial_mode ^[OP=toggle_tutorial_mode
# double tap control+end read attributes # double tap control+end read attributes
2,^[[1;5F=attribute_cursor 2,^[[1;5F=attribute_cursor
#=toggle_has_attribute
# escape - stop speech # escape - stop speech
^[=shut_up ^[=shut_up
# context menu key - stop speech # context menu key - stop speech

View File

@ -186,7 +186,11 @@ shell=
[focus] [focus]
cursor=True cursor=True
highlight=False highlight=False
barrier=True
[barrier]
enabled=True
leftBarriers=│└┌─
rightBarriers=│┘┐─
[review] [review]
lineBreak=True lineBreak=True

View File

@ -196,7 +196,11 @@ shell=
cursor=True cursor=True
#follow highlighted text changes #follow highlighted text changes
highlight=False highlight=False
barrier=True
[barrier]
enabled=True
leftBarriers=│└┌─
rightBarriers=│┘┐─
[review] [review]
lineBreak=True lineBreak=True

View File

@ -197,7 +197,11 @@ shell=
cursor=True cursor=True
#follow highlighted text changes #follow highlighted text changes
highlight=False highlight=False
barrier=True
[barrier]
enabled=True
leftBarriers=│└┌─
rightBarriers=│┘┐─
[review] [review]
lineBreak=True lineBreak=True

View File

@ -9,10 +9,10 @@ genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine
[speech] [speech]
enabled=True enabled=True
driver=speechdDriver #driver=speechdDriver
#driver=genericDriver driver=genericDriver
serverPath= serverPath=
rate=0.95 rate=0.80
pitch=0.5 pitch=0.5
# Pitch for capital letters # Pitch for capital letters
capitalPitch=0.9 capitalPitch=0.9
@ -133,7 +133,7 @@ commandPath=
attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize
autoPresentIndent=False autoPresentIndent=False
# play a sound when attributes are changeing # play a sound when attributes are changeing
hasAttributes=True hasAttributes=False
# shell for PTY emulatiun (empty = default shell) # shell for PTY emulatiun (empty = default shell)
shell= shell=
@ -142,7 +142,11 @@ shell=
cursor=True cursor=True
#follow highlighted text changes #follow highlighted text changes
highlight=False highlight=False
barrier=True
[barrier]
enabled=True
leftBarriers=│└┌─
rightBarriers=│┘┐─
[review] [review]
lineBreak=True lineBreak=True

View File

@ -196,7 +196,11 @@ shell=
cursor=True cursor=True
#follow highlighted text changes #follow highlighted text changes
highlight=False highlight=False
barrier=True
[barrier]
enabled=True
leftBarriers=│└┌─
rightBarriers=│┘┐─
[review] [review]
lineBreak=True lineBreak=True

View File

@ -15,6 +15,10 @@ StartOfLine='StartOfLine.wav'
EndOfLine='EndOfLine.wav' EndOfLine='EndOfLine.wav'
# barrier was detected # barrier was detected
BarrierFound='barrier.wav' BarrierFound='barrier.wav'
# barrier mode starts
BarrierStart='barrier_start.wav'
# barrier mode ends
BarrierEnd='barrier_end.wav'
# the Line is empty # the Line is empty
EmptyLine='EmptyLine.wav' EmptyLine='EmptyLine.wav'
# Is the first line on the screen. # Is the first line on the screen.

View File

@ -15,6 +15,10 @@ StartOfLine=''
EndOfLine='' EndOfLine=''
# barrier was detected # barrier was detected
BarrierFound='' BarrierFound=''
# barrier mode starts
BarrierStart=''
# barrier mode ends
BarrierEnd=''
# the Line is empty # the Line is empty
EmptyLine='' EmptyLine=''
# Is the first line on the screen. # Is the first line on the screen.

34
play zone/split.txt Normal file
View File

@ -0,0 +1,34 @@
./play zone/wrapWord.py:21: wrappedLines = currText.split('\n')
./play zone/wrapWord.py:50: wrappedLines = currText.split('\n')
./play zone/wrapWord.py:93: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/screenDriver/vcsaDriver.py:281: apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
./src/fenrirscreenreader/utils/line_utils.py:14: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/line_utils.py:30: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/line_utils.py:41: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:14: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:35: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:43: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:58: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:73: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:85: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/mark_utils.py:13: inText = inText.split('\n')
./src/fenrirscreenreader/utils/mark_utils.py:59: inText = inText.split('\n')
./src/fenrirscreenreader/utils/word_utils.py:20: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/word_utils.py:62: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/word_utils.py:91: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/core/outputManager.py:173: currline = text.split('\n')[offset['y']]
./src/fenrirscreenreader/core/attributeManager.py:250: textLines = text.split('\n')
./src/fenrirscreenreader/core/screenManager.py:166: diffList = ['+ ' + self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +'\n']
./src/fenrirscreenreader/core/screenManager.py:169: diff = self.differ.compare(oldScreenText.split('\n'),\
./src/fenrirscreenreader/core/screenManager.py:170: newScreenText.split('\n'))
./src/fenrirscreenreader/core/screenManager.py:225: windowList = text.split('\n')
./src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py:66: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py:39: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py:41: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/onCursorChange/61000-word_echo_navigation.py:37: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/commands/spell_check.py:47: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
./src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:45: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
./src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:43: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:38: prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:39: currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./TODO v2.0:72: w.fill(i).split('\n')

View File

@ -1,4 +1,5 @@
- import clipboard from x (xclip) - import clipboard from x (xclip)
- initial barrier mode - barrier mode (respect pseudo cli window borders like used in dialog or pdmenu)
- toggle for barrier mode - toggle for barrier mode
- soundicon for barrier mode when enter and leave the barrier detection
- imporove accuracy of speak history (arrow up/ down in bash) - imporove accuracy of speak history (arrow up/ down in bash)

34
splits.txt Normal file
View File

@ -0,0 +1,34 @@
./play zone/wrapWord.py:21: wrappedLines = currText.split('\n')
./play zone/wrapWord.py:50: wrappedLines = currText.split('\n')
./play zone/wrapWord.py:93: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/screenDriver/vcsaDriver.py:281: apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
./src/fenrirscreenreader/utils/line_utils.py:14: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/line_utils.py:30: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/line_utils.py:41: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:14: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:35: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:43: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:58: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:73: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/char_utils.py:85: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/mark_utils.py:13: inText = inText.split('\n')
./src/fenrirscreenreader/utils/mark_utils.py:59: inText = inText.split('\n')
./src/fenrirscreenreader/utils/word_utils.py:20: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/word_utils.py:62: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/utils/word_utils.py:91: wrappedLines = currText.split('\n')
./src/fenrirscreenreader/core/outputManager.py:173: currline = text.split('\n')[offset['y']]
./src/fenrirscreenreader/core/attributeManager.py:250: textLines = text.split('\n')
./src/fenrirscreenreader/core/screenManager.py:166: diffList = ['+ ' + self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +'\n']
./src/fenrirscreenreader/core/screenManager.py:169: diff = self.differ.compare(oldScreenText.split('\n'),\
./src/fenrirscreenreader/core/screenManager.py:170: newScreenText.split('\n'))
./src/fenrirscreenreader/core/screenManager.py:225: windowList = text.split('\n')
./src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py:66: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py:39: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py:41: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/onCursorChange/61000-word_echo_navigation.py:37: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/commands/spell_check.py:47: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
./src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:45: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
./src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:43: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:38: prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:39: currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
./TODO v2.0:72: w.fill(i).split('\n')

View File

@ -16,8 +16,8 @@ class command():
return _('enables or disables the barrier mode') return _('enables or disables the barrier mode')
def run(self): def run(self):
self.env['runtime']['settingsManager'].setSetting('focus', 'barrier', str(not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'barrier'))) self.env['runtime']['settingsManager'].setSetting('barrier', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('barrier', 'enabled')))
if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'barrier'): if self.env['runtime']['settingsManager'].getSettingAsBool('barrier', 'enabled'):
self.env['runtime']['outputManager'].presentText(_("barrier mode enabled"), soundIcon='', interrupt=True) self.env['runtime']['outputManager'].presentText(_("barrier mode enabled"), soundIcon='', interrupt=True)
else: else:
self.env['runtime']['outputManager'].presentText(_("barrier mode disabled"), soundIcon='', interrupt=True) self.env['runtime']['outputManager'].presentText(_("barrier mode disabled"), soundIcon='', interrupt=True)

View File

@ -0,0 +1,26 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return _('enables or disables the announcement of attributes')
def run(self):
self.env['runtime']['settingsManager'].setSetting('general', 'hasAttributes', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes')))
if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'):
self.env['runtime']['outputManager'].presentText(_("announcement of attributes enabled"), soundIcon='', interrupt=True)
else:
self.env['runtime']['outputManager'].presentText(_("announcement of attributes disabled"), soundIcon='', interrupt=True)
def setCallback(self, callback):
pass

View File

@ -47,8 +47,10 @@ class command():
doInterrupt = False doInterrupt = False
# barrier # barrier
sayLine = currLine sayLine = currLine
if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'barrier'): if self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'):
sayLine = self.env['runtime']['barrierManager'].handleLineBarrier(sayLine, self.env['screen']['newCursor']['x']) isBarrier, barrierLine = self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y'])
if isBarrier:
sayLine = barrierLine
# output # output
self.env['runtime']['outputManager'].presentText(sayLine, interrupt=doInterrupt, flush=False) self.env['runtime']['outputManager'].presentText(sayLine, interrupt=doInterrupt, flush=False)
self.lastIdent = currIdent self.lastIdent = currIdent

View File

@ -0,0 +1,27 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return 'No Description found'
def run(self):
if not self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'):
return
self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y'])
def setCallback(self, callback):
pass

View File

@ -0,0 +1,29 @@
#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return 'No Description found'
def run(self):
if not self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'):
return
if not self.env['runtime']['screenManager'].isDelta(ignoreSpace=True):
return
self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y'])
def setCallback(self, callback):
pass

View File

@ -24,36 +24,90 @@ class barrierManager():
self.prefIsBarrier = False self.prefIsBarrier = False
def isBarrierChange(self): def isBarrierChange(self):
return self.currIsBarrier != self.prefIsBarrier return self.currIsBarrier != self.prefIsBarrier
def handleLineBarrier(self, line, xCursor, output=True, doInterrupt=True): def handleLineBarrier(self, text, xCursor, yCursor, output=True, doInterrupt=True):
isBarrier, sayLine = self.getBarrierText(line, xCursor) isBarrier = False
self.updateBarrierChange(isBarrier) try:
#if self.isBarrierChange(): isBarrier, sayLine = self.getBarrierText(text, xCursor, yCursor)
if isBarrier: except Exception as e:
if output: return False, ''
self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierFound', interrupt=doInterrupt)
return sayLine
def hasBarrier(self, start, end): self.updateBarrierChange(isBarrier)
if self.isBarrierChange():
if output:
if isBarrier:
self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierStart', interrupt=doInterrupt)
else:
self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierEnd', interrupt=doInterrupt)
if not isBarrier:
sayLine = ''
return isBarrier, sayLine
def hasBorder(self, text, xCursor, yCursor, validBorder, barrierPos):
# check for corners here # check for corners here
lastLineNo = len(text) - 1
if yCursor <= 0:
if not (text[0][barrierPos] in validBorder):
return False
if len(text) > 1:
if not (text[1][barrierPos] in validBorder):
return False
if len(text) > 2:
if not (text[2][barrierPos] in validBorder):
return False
elif yCursor >= lastLineNo:
if not (text[lastLineNo][barrierPos] in validBorder):
return False
if len(text) > 1:
if not (text[lastLineNo - 1][barrierPos] in validBorder):
return False
if len(text) > 2:
if not (text[lastLineNo - 2][barrierPos] in validBorder):
return False
else:
if not (text[yCursor][barrierPos] in validBorder):
return False
if not (text[yCursor - 1][barrierPos] in validBorder):
return False
if not (text[yCursor + 1][barrierPos] in validBorder):
return False
return True return True
def getBarrierText(self, line, xCursor): def getBarrierText(self, text, xCursor, yCursor):
line = text[yCursor]
if not self.env['runtime']['settingsManager'].getSettingAsBool('barrier', 'enabled'):
return False, line
offset = xCursor offset = xCursor
leftBarriers = self.env['runtime']['settingsManager'].getSetting('barrier', 'leftBarriers')
rightBarriers = self.env['runtime']['settingsManager'].getSetting('barrier', 'rightBarriers')
# is the cursor at the begin or end of an entry: # is the cursor at the begin or end of an entry:
#print(line[:offset + 1].count('│'),line[offset:].count('│')) #print(line[:offset + 1].count('│'),line[offset:].count('│'))
if line[:offset + 1].count('') > line[offset:].count(''): # start
offset = xCursor - 1
start = line[:offset + 1].rfind('') + 1 for b in leftBarriers:
end = line[offset + 1:].find('') if line[:offset + 1].count(b) > line[offset:].count(b):
if start == end: offset = xCursor - 1
return False, line start = line[:offset].rfind(b)
if start != -1:
if not self.hasBorder(text, xCursor, yCursor, leftBarriers, start):
start = -1
else:
start += 1
break
if start == -1: if start == -1:
return False, line return False, line
# end
for b in rightBarriers:
end = line[start:].find(b)
if end != -1:
end = start + end
if not self.hasBorder(text, xCursor, yCursor,rightBarriers, end):
end = -1
break
if end == -1: if end == -1:
return False, line return False, line
else: if start == end:
end += offset + 1
if not self.hasBarrier(start, end):
return False, line return False, line
return True, line[start:end] return True, line[start:end]

View File

@ -80,7 +80,12 @@ settingsData = {
'focus':{ 'focus':{
'cursor': True, 'cursor': True,
'highlight': False, 'highlight': False,
'barrier': True,
},
'barrier':{
'enabled': True,
'leftBarriers': '│└┌─',
'rightBarriers': '│┘┐─',
}, },
'review':{ 'review':{
'lineBreak': True, 'lineBreak': True,

View File

@ -9,6 +9,7 @@ import re, string
class textManager(): class textManager():
def __init__(self): def __init__(self):
# https://regex101.com/
self.regExSingle = re.compile(r'(([^\w\s])\2{5,})') self.regExSingle = re.compile(r'(([^\w\s])\2{5,})')
self.regExDouble = re.compile(r'([^\w\s]{2,}){5,}') self.regExDouble = re.compile(r'([^\w\s]{2,}){5,}')
def initialize(self, environment): def initialize(self, environment):