improved documentation for the diff generation.

This commit is contained in:
Storm Dragon
2025-06-09 16:53:05 -04:00
parent 6998706934
commit b0ac6e1409
2 changed files with 112 additions and 12 deletions

View File

@ -233,57 +233,110 @@ class attributeManager():
return attributeFormatString
def trackHighlights(self):
"""
Detects text with changed attributes (highlighting) between screen updates.
This is crucial for screen readers to announce when text becomes highlighted,
selected, or changes visual emphasis (bold, reverse video, color changes, etc.)
Returns:
tuple: (highlighted_text, cursor_position)
- highlighted_text: string of characters that gained highlighting
- cursor_position: dict {'x': col, 'y': row} of first highlighted char
"""
result = ''
currCursor = None
# screen change
# Early exit conditions - no attribute comparison possible
if self.prevAttributes == None:
# First screen load - no previous attributes to compare against
return result, currCursor
# no change
if self.prevAttributes == self.currAttributes:
# No attribute changes detected
return result, currCursor
# error case
if self.currAttributes == None:
# Error condition - current attributes missing
return result, currCursor
# special case for pty if not text exists.
if len(self.currAttributes) == 0:
# Special case for PTY environments with no text content
return result, currCursor
# Get current screen text to correlate with attribute changes
text = self.env['runtime']['screenManager'].getScreenText()
textLines = text.split('\n')
# Sanity check: text lines must match attribute array dimensions
if len(textLines) != len(self.currAttributes):
return result, currCursor
# Compare attributes line by line, character by character
for line in range(len(self.prevAttributes)):
if self.prevAttributes[line] != self.currAttributes[line]:
# This line has attribute changes - examine each character position
for column in range(len(self.prevAttributes[line])):
if self.prevAttributes[line][column] == self.currAttributes[line][column]:
# No change at this position
continue
# Attribute changed at this position - check if it's worth announcing
if self.isUsefulForTracking(line, column, self.currAttributes, self.prevAttributes):
# First highlighted character becomes cursor position for navigation
if not currCursor:
currCursor = {'x': column, 'y': line}
# Accumulate highlighted characters
result += textLines[line][column]
# Add space between lines of highlighted text for speech clarity
result += ' '
return result, currCursor
def isUsefulForTracking(self, line, column, currAttributes, prevAttributes, attribute=1 , mode = 'zaxe'):
"""
Determines if an attribute change at a specific position is worth announcing.
This prevents announcing every minor attribute change and focuses on meaningful
highlighting that indicates user selections, focus changes, or important emphasis.
Args:
line, column: Position of the attribute change
currAttributes, prevAttributes: Current and previous attribute arrays
attribute: Which attribute to examine (1=background color by default)
mode: Detection algorithm ('zaxe', 'default', 'barrier')
Returns:
bool: True if this attribute change should be announced to user
"""
# Sanity checks for valid position and sufficient screen content
if len(currAttributes) <= 3:
return False
if line < 0:
return False
if line > len(currAttributes):
return False
useful = False
if mode == 'default':
# non default tracking
# Simple mode: announce any non-default attribute
useful = not self.isDefaultAttribute(currAttributes[line][column])
elif (mode == 'zaxe') or (mode == ''):
# arround me tracking for bg
# Context-aware mode: only announce attributes that stand out from surroundings
# This prevents announcing entire blocks of highlighted text character by character
# by checking if the attribute differs from adjacent lines
if line == 0:
useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and (currAttributes[line][column][attribute] != currAttributes[line + 2][column][attribute])
# Top line: compare against lines below
useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and \
(currAttributes[line][column][attribute] != currAttributes[line + 2][column][attribute])
elif line >= len(prevAttributes):
useful = (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute]) and (currAttributes[line][column][attribute] != currAttributes[line - 2][column][attribute])
# Bottom line: compare against lines above
useful = (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute]) and \
(currAttributes[line][column][attribute] != currAttributes[line - 2][column][attribute])
else:
useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute])
# Middle lines: compare against both directions
useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and \
(currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute])
elif mode == 'barrier':
# to be implement
# Barrier mode: future enhancement for detecting screen boundaries/separators
useful = True
return useful