Skip to content

Commit acdc8d3

Browse files
authored
Merge e6744be into 54a4ec5
2 parents 54a4ec5 + e6744be commit acdc8d3

7 files changed

Lines changed: 132 additions & 12 deletions

File tree

source/config/configSpec.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@
213213
reportLineNumber = boolean(default=False)
214214
# 0: Off, 1: Speech, 2: Tones, 3: Both Speech and Tones
215215
reportLineIndentation = integer(0, 3, default=0)
216+
ignoreBlankLinesForRLI = boolean(default=False)
216217
reportParagraphIndentation = boolean(default=False)
217218
reportTables = boolean(default=true)
218219
includeLayoutTables = boolean(default=False)

source/globalCommands.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ def script_reportCurrentSelection(self,gesture):
273273
speech.speakMessage(_("No selection"))
274274
else:
275275
speech.speakTextSelected(info.text)
276-
276+
277277
@script(
278278
# Translators: Input help mode message for report date and time command.
279279
description=_("If pressed once, reports the current time. If pressed twice, reports the current date"),
@@ -622,6 +622,23 @@ def script_toggleReportLineIndentation(self, gesture: inputCore.InputGesture):
622622
# {mode} will be replaced with the mode; i.e. Off, Speech, Tones or Both Speech and Tones.
623623
ui.message(_("Report line indentation {mode}").format(mode=state.displayString))
624624

625+
@script(
626+
# Translators: Input help mode message for toggle ignore blank lines for line indentation reporting command.
627+
description=_("Toggles on and off the ignoring of blank lines for line indentation reporting"),
628+
category=SCRCAT_DOCUMENTFORMATTING
629+
)
630+
def script_toggleIgnoreBlankLinesForReportLineIndentation(self, gesture: inputCore.InputGesture) -> None:
631+
ignore = config.conf['documentFormatting']['ignoreBlankLinesForRLI']
632+
config.conf['documentFormatting']['ignoreBlankLinesForRLI'] = not ignore
633+
if ignore:
634+
# Translators: The message announced when toggling off the ignore blank lines for line indentation
635+
# reporting document formatting setting.
636+
ui.message(_("Ignore blank lines for line indentation reporting off"))
637+
else:
638+
# Translators: The message announced when toggling on the ignore blank lines for line indentation
639+
# reporting document formatting setting.
640+
ui.message(_("Ignore blank lines for line indentation reporting on"))
641+
625642
@script(
626643
# Translators: Input help mode message for toggle report paragraph indentation command.
627644
description=_("Toggles on and off the reporting of paragraph indentation"),

source/gui/settingsDialogs.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,15 +2389,22 @@ def makeSettings(self, settingsSizer):
23892389
self.lineIndentationCombo
23902390
)
23912391
self.lineIndentationCombo.SetSelection(config.conf['documentFormatting']['reportLineIndentation'])
2392+
2393+
# Translators: This is the label of a checkbox in the document formatting settings panel
2394+
# If this option is selected, NVDA will ignore blank lines for line indentation reporting
2395+
ignoreBlankLinesText = _("Ignore &blank lines for line indentation reporting")
2396+
ignoreBlankLinesCheckBox = wx.CheckBox(pageAndSpaceBox, label=ignoreBlankLinesText)
2397+
self.ignoreBlankLinesRLICheckbox = pageAndSpaceGroup.addItem(ignoreBlankLinesCheckBox)
2398+
self.ignoreBlankLinesRLICheckbox.SetValue(config.conf["documentFormatting"]["ignoreBlankLinesForRLI"])
23922399

2393-
# Translators: This message is presented in the document formatting settings panelue
2400+
# Translators: This message is presented in the document formatting settings panel
23942401
# If this option is selected, NVDA will report paragraph indentation if available.
23952402
paragraphIndentationText = _("&Paragraph indentation")
23962403
_paragraphIndentationCheckBox = wx.CheckBox(pageAndSpaceBox, label=paragraphIndentationText)
23972404
self.paragraphIndentationCheckBox = pageAndSpaceGroup.addItem(_paragraphIndentationCheckBox)
23982405
self.paragraphIndentationCheckBox.SetValue(config.conf["documentFormatting"]["reportParagraphIndentation"])
23992406

2400-
# Translators: This message is presented in the document formatting settings panelue
2407+
# Translators: This message is presented in the document formatting settings panel
24012408
# If this option is selected, NVDA will report line spacing if available.
24022409
lineSpacingText=_("&Line spacing")
24032410
_lineSpacingCheckBox = wx.CheckBox(pageAndSpaceBox, label=lineSpacingText)
@@ -2541,6 +2548,7 @@ def onSave(self):
25412548
config.conf["documentFormatting"]["reportPage"]=self.pageCheckBox.IsChecked()
25422549
config.conf["documentFormatting"]["reportLineNumber"]=self.lineNumberCheckBox.IsChecked()
25432550
config.conf["documentFormatting"]["reportLineIndentation"] = self.lineIndentationCombo.GetSelection()
2551+
config.conf["documentFormatting"]["ignoreBlankLinesForRLI"] = self.ignoreBlankLinesRLICheckbox.IsChecked()
25442552
config.conf["documentFormatting"]["reportParagraphIndentation"]=self.paragraphIndentationCheckBox.IsChecked()
25452553
config.conf["documentFormatting"]["reportLineSpacing"]=self.lineSpacingCheckBox.IsChecked()
25462554
config.conf["documentFormatting"]["reportTables"]=self.tablesCheckBox.IsChecked()

source/speech/speech.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,17 @@ def getTextInfoSpeech( # noqa: C901
15401540
if autoLanguageSwitching and newLanguage!=lastLanguage:
15411541
relativeSpeechSequence.append(LangChangeCommand(newLanguage))
15421542
lastLanguage=newLanguage
1543-
if reportIndentation and speakTextInfoState and allIndentation!=speakTextInfoState.indentationCache:
1543+
if (
1544+
reportIndentation
1545+
and speakTextInfoState
1546+
and (
1547+
# either not ignoring blank lines
1548+
not formatConfig['ignoreBlankLinesForRLI']
1549+
# or line isn't completely blank
1550+
or any(isinstance(t, str) and not all(c in LINE_END_CHARS for c in t) for t in textWithFields)
1551+
)
1552+
and allIndentation != speakTextInfoState.indentationCache
1553+
):
15441554
indentationSpeech=getIndentationSpeech(allIndentation, formatConfig)
15451555
if autoLanguageSwitching and speechSequence[-1].lang is not None:
15461556
# Indentation must be spoken in the default language,
@@ -1604,6 +1614,10 @@ def getTextInfoSpeech( # noqa: C901
16041614
return True
16051615

16061616

1617+
# for checking a line is completely blank, i.e. doesn't even contain spaces
1618+
LINE_END_CHARS = frozenset(('\r', '\n'))
1619+
1620+
16071621
def _isControlEndFieldCommand(command: Union[str, textInfos.FieldCommand]):
16081622
return isinstance(command, textInfos.FieldCommand) and command.command == "controlEnd"
16091623

tests/system/robot/symbolPronunciationTests.py

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ class EndSpeech(_enum.Enum):
7676
NONE = None
7777

7878

79+
class ReportLineIndentation(_enum.Enum):
80+
"""Line indentation reporting options. Should match config.configFlags.ReportLineIndentation
81+
"""
82+
OFF = 0
83+
SPEECH = 1
84+
85+
7986
def _pressKeyAndCollectSpeech(key: str, numberOfTimes: int) -> _typing.List[str]:
8087
actual = []
8188
for _ in range(numberOfTimes):
@@ -500,7 +507,7 @@ def test_symbolInSpeechUI():
500507
_notepad.prepareNotepad((
501508
"t" # Character doesn't matter, we just want to invoke "Right" speech UI.
502509
))
503-
_setSymbolLevel(SymLevel.ALL)
510+
_setConfig(SymLevel.ALL)
504511
spy = _NvdaLib.getSpyLib()
505512
expected = "shouldn't sub tick symbol"
506513
spy.override_translationString(EndSpeech.RIGHT.value, expected)
@@ -527,7 +534,7 @@ def test_symbolInSpeechUI():
527534
)
528535

529536
# Show that with symbol level None, the speech UI symbols are not substituted.
530-
_setSymbolLevel(SymLevel.NONE)
537+
_setConfig(SymLevel.NONE)
531538
actual = _pressKeyAndCollectSpeech(Move.REVIEW_CHAR.value, numberOfTimes=1)
532539
_builtIn.should_be_equal(
533540
actual,
@@ -536,20 +543,32 @@ def test_symbolInSpeechUI():
536543
)
537544

538545

539-
def _setSymbolLevel(symbolLevel: SymLevel) -> None:
546+
def _setConfig(
547+
symbolLevel: SymLevel,
548+
reportLineIndentation: ReportLineIndentation = ReportLineIndentation.OFF,
549+
ignoreBlankLines: bool = False
550+
) -> None:
540551
spy = _NvdaLib.getSpyLib()
541-
SYMBOL_LEVEL_KEY = ["speech", "symbolLevel"]
542-
spy.set_configValue(SYMBOL_LEVEL_KEY, symbolLevel.value)
543-
_builtIn.log(message=f"Doing test at symbol level: {symbolLevel}")
552+
spy.set_configValue(["documentFormatting", "reportLineIndentation"], reportLineIndentation.value)
553+
spy.set_configValue(["documentFormatting", "ignoreBlankLinesForRLI"], ignoreBlankLines)
554+
spy.set_configValue(["speech", "symbolLevel"], symbolLevel.value)
555+
message = (
556+
f"Doing test at symbol level: {symbolLevel}"
557+
f", line indentation reporting: {reportLineIndentation}"
558+
f", ignore blank lines for line indentation reporting: {ignoreBlankLines}"
559+
)
560+
_builtIn.log(message=message)
544561

545562

546563
def _doTest(
547564
navKey: Move,
548565
expectedSpeech: _typing.List[str],
549566
reportedAfterLast: EndSpeech,
550567
symbolLevel: SymLevel,
568+
reportLineIndentation: ReportLineIndentation = ReportLineIndentation.OFF,
569+
ignoreBlankLines: bool = False
551570
) -> None:
552-
_setSymbolLevel(symbolLevel)
571+
_setConfig(symbolLevel, reportLineIndentation, ignoreBlankLines)
553572

554573
actual = _pressKeyAndCollectSpeech(navKey.value, numberOfTimes=len(expectedSpeech))
555574
_builtIn.should_be_equal(
@@ -600,7 +619,7 @@ def test_tableHeaders():
600619
</table>
601620
"""
602621
)
603-
_setSymbolLevel(SymLevel.ALL)
622+
_setConfig(SymLevel.ALL)
604623
# Expected to be in browse mode
605624
actualSpeech = _chrome.getSpeechAfterKey("downArrow")
606625
_asserts.strings_match(
@@ -669,3 +688,56 @@ def test_tableHeaders():
669688
"Don tick t column 3\nc", # note symbols ARE replaced in column name
670689
]
671690
)
691+
692+
693+
def test_ignoreBlankLinesForReportLineIndentation():
694+
""" Test line indentation reporting with ignoreBlankLinesForReportLineIndentation off and then on
695+
"""
696+
_notepad.prepareNotepad('\n'.join([
697+
'', # blank line
698+
'def foo',
699+
'\thello',
700+
'', # blank line
701+
'\tworld',
702+
'', # blank line
703+
'def bar',
704+
'', # blank line
705+
]))
706+
707+
def _doTestIgnoreBlankLines(ignoreBlankLines: bool, expectedSpeech: _typing.List[str]) -> None:
708+
_doTest(
709+
navKey=Move.REVIEW_LINE,
710+
reportedAfterLast=EndSpeech.BOTTOM,
711+
symbolLevel=SymLevel.ALL,
712+
reportLineIndentation=ReportLineIndentation.SPEECH,
713+
ignoreBlankLines=ignoreBlankLines,
714+
expectedSpeech=expectedSpeech
715+
)
716+
717+
_doTestIgnoreBlankLines(
718+
ignoreBlankLines=False,
719+
expectedSpeech=[
720+
'def foo',
721+
'tab hello',
722+
'no indent blank',
723+
'tab world',
724+
'no indent blank',
725+
'def bar',
726+
'blank'
727+
]
728+
)
729+
730+
_NvdaLib.getSpeechAfterKey(Move.REVIEW_HOME.value) # reset to start position
731+
732+
_doTestIgnoreBlankLines(
733+
ignoreBlankLines=True,
734+
expectedSpeech=[
735+
'def foo',
736+
'tab hello',
737+
'blank',
738+
'world',
739+
'blank',
740+
'no indent def bar',
741+
'blank'
742+
]
743+
)

tests/system/robot/symbolPronunciationTests.robot

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,7 @@ tableHeaderSymbols
6767
[Documentation] Ensure symbols announced as expected in table headers.
6868
[Tags] table
6969
test_tableHeaders
70+
71+
ignoreBlankLinesForReportLineIndentation
72+
[Documentation] Ensure indentation announced as expected when ignore blank lines for line indentation reporting is on/off.
73+
test_ignoreBlankLinesForReportLineIndentation

user_docs/en/userGuide.t2t

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,7 @@ You can configure reporting of:
20832083
- Page numbers
20842084
- Line numbers
20852085
- Line indentation reporting [(Off, Speech, Tones, Both Speech and Tones) #DocumentFormattingSettingsLineIndentation]
2086+
- Ignore blank lines for line indentation reporting
20862087
- Paragraph indentation (e.g. hanging indent, first line indent)
20872088
- Line spacing (single, double, etc.)
20882089
- Alignment
@@ -2125,6 +2126,9 @@ The tone will increase in pitch every space, and for a tab, it will increase in
21252126
- Both Speech and Tones: This option reads indentation using both of the above methods.
21262127
-
21272128

2129+
If you tick the "Ignore blank lines for line indentation reporting" checkbox, then indentation changes won't be reported for blank lines.
2130+
This may be useful when reading a document where blank lines are used to separate indented blocks of text, such as in programming source code.
2131+
21282132
+++ Document Navigation +++[DocumentNavigation]
21292133
This category allows you to adjust various aspects of document navigation.
21302134

0 commit comments

Comments
 (0)