Return "blank" if text empty due to processing#13483
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
|
I would rather prefer a sound introduced via speech refactor feature in NVDA which indicates that this symbol or text is not spoken due to symbol level or missing dictionary entry. Maybe two sounds, one for symbols and one for empty text linked to dictionary rule. Speaking "blank" could introduce new confusing problems, especially during navigation or say all. |
|
@Adriani90 I don't think just a sound would be enough. It could be an alternative to the text spoken like for indentation reporting there is the option of speech or beeps, but a speech option would have to be there, since that is what some users might prefer. Thanks for bringing up say all, since I forgot to consider that. Testing it manually just now, when doing say all and there is a line that is blank due to processing, such as the line with just two tabs, then it is read as "blank" during say all. This is wrong since lines being blank shouldn't be read during say all. I will have to rethink how to implement this, so that say all is taken into account, since the last thing I want to do is fix one bug only to introduce another. I'm not closing this right away in case some other people provide feedback on things I might not have considered |
|
@SamKacer Could you take a look at the system tests: You can run just these tests by doing the following:
The system tests will launch NVDA and another application (eg chrome or notepad), interact collecting speech, then exit. Any mouse / keyboard interaction may interfere with the tests. A work around for this is running the tests in a virtual machine. I'm going to convert this PR to a draft until it is ready again, please feel free to press the "ready for review" button when this is addressed. |
|
@SamKacer You might be interested in #12710. When looking at a this area (however with a focus on symbols), my conclusion was that there is a loss of information, the initial intent of the |
|
@feerrenrut thanks for the feedback! Sorry for the late response. My life situation suddenly became quite hectic, so I've had to put this on hold, but will return to it, although might be a couple of weeks. In regards to running the system tests with the setup you outlined, does this still need me to build the NVDA project? I suspect one thing I will have to sort out before I return to this is setup the whole suite of tools for building the project including the 7 gigs or so of MS Visual Studio build tools, which is a blocker for me at the moment. But I am in the process of setting up a new laptop where I will hav enough space to install everything. |
|
@SamKacer Yes, you'll need to be able to build NVDA locally. |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
aff97ad to
d14bc61
Compare
This comment was marked as outdated.
This comment was marked as outdated.
|
One thing that could be changed in the implementation is that the only place What do others think? Keep those in there just to be extra safe or remove them to make it simpler? The one other place I would keep it is |
|
@feerrenrut Hi, I just wanted to ask since this is my first PR on this repo and so am unfamiliar with the general timelines here. I marked this ready for review a little over 2 weeks ago and haven't gotten any response yet. Is this normal an to be expected? Just asking since not sure if this PR was accidently overlooked |
|
@SamKacer It is common but not intended, unfortunately we are quite time constrained. An exception to this is when we identify that the change should target a later release. But in those cases we try to communicate it on the issue / PR. |
feerrenrut
left a comment
There was a problem hiding this comment.
I'm a bit worried about known issue 3. It would be good to know if this is a real world case that will be encountered.
| speak( | ||
| seq, | ||
| priority=priority, | ||
| suppressBlanks=suppressBlanks or reason == OutputReason.SAYALL |
There was a problem hiding this comment.
Why is there an exception for say all? Can you add a comment to explain.
There was a problem hiding this comment.
Why is there an exception for say all? Can you add a comment to explain.
This is consistent with logic in speech.speech.getTextInfoSpeech, where "blank" is added to the speech sequence only if it isn't a sayall. As I understand, blanks are not meant to be spoken during a sayall and that this was something generally known, so not requiring a comment.
snippet from speech.speech.getTextInfoSpeech:
if not suppressBlanks and reason != OutputReason.SAYALL and shouldConsiderTextInfoBlank:
# Translators: This is spoken when the line is considered blank.
speechSequence.append(_("blank"))
Also, just before asking about timeline on review, I added a comment pointing out that comparing reason == OutputReason.SAYALL is redundant since in speech\__init__.py, when SayAll is initialized, it is passed a modified speech function where suppressBlanks is overridden to be true. So, I was thinking of removing all these comparisns like this, since sayall is already handled directly at the source. But, I wanted to get feedback on that first. What do you think?
There was a problem hiding this comment.
As I understand, blanks are not meant to be spoken during a sayall and that this was something generally known, so not requiring a comment.
I'd prefer a comment. It's very easy for priors to change, reasoning helps promoting questioning the behavior. I.E. does this reason still exist / make sense in the current context. There is also the aspect of making it easy for developers with different histories to get up to speed on the reasoning.
So, I was thinking of removing all these comparisns like this, since sayall is already handled directly at the source. But, I wanted to get feedback on that first. What do you think?
Yes, I think that would be preferable.
| symbolLevel=SymLevel.NONE, | ||
| expectedSpeech=[ | ||
| 'Say', '(quietly)', 'Hello,', 'Jim .', "don't", # Expect: | ||
| '', # todo: Expect 'right-pointing arrow' |
There was a problem hiding this comment.
Don't remove these expected symbol todo comments. These tests were added when assessing the current behavior for symbols. The todo comments document what we intend the output to become.
So while "blank" is better than "", it still isn't the final goal.
There was a problem hiding this comment.
Don't remove these expected symbol todo comments. These tests were added when assessing the current behavior for symbols. The todo comments document what we intend the output to become.
So while "blank" is better than
"", it still isn't the final goal.
This was actually on purpose. I wanted to spark a discussion about this.
I would propose that this perhaps should be the final goal. If symbol level is none, then as a user I would expect no symbols would be spoken. If a speech sequence doesn't contain anything to be spoken, "blank" should be spoken instead.
Otherwise, I don't understand why "'right-pointing arrow" should be spoken when symbol level is none. Shouldn't it be considered a symbol and so not spoken? If this was discussed and this is indeed the intended final goal then at least for me it is confusing and I think the test case would benefit from having a comment with a small explanation about the justification
There was a problem hiding this comment.
Blank is misleading. It suggests there are no visible characters in the range. We've had quite some discussions about this already. The should be given the most accurate picture as a priority. This might mean announcing the name of a single symbol, or "symbols" when there are multiple, perhaps like spaces / tabs the number should be spoken "5 symbols". A mix of whitespace should perhaps be announced as "mixed whitespace".
Our last work in this area was really focusing on symbols and the inconsistency of reporting.
There was a problem hiding this comment.
hmm, okay. This reasoning was missing in those tests making it unclear why that was the expected output. I will add back those todos along with short comment on the why, as you just explained it, so others are not confused as I was.
However, what about the case of a sequence that only contains tabs? In that case isn't "blank" an appropriate final solution, since tabs are whitespace and so would generally be considered as blank?
I haven't spotted this in the wild somewhere or come across a place in the code where such a case is created. Know issue 3 is pure hypothesis on my part. The logic behind considering a speech sequence blank and appending "blank" if it is is, adapted from similar logic in |
One option if we are concerned about this, is to put the feature behind a feature flag. This makes it easy for us to change the default / and allow alpha users to experiment more easily. It lowers the risk of having to revert the change entirely. |
These two examples really worry me. In general NVDA should never lie to user about the text it presents and saying "blank" for a non blank line/word is going to be pretty confusing. In general this introduces a uncertainty about what "blank" means and overloading a very well known concept of it being reported for empty lines may upset users. Has it been considered not to report "blank" in cases of hunks where no text is spoken due to punctuation level being too low, rather try to increase it until the entire hunk produces speech? |
|
Yes, @lukaszgo1 this is a known issue (reporting "blank" or no speech at all are equally unhelpful). I was trying to address this with #12710. That PR didn't go ahead, instead tests were added to demonstrate this behavior and currently desired outcome. We have been discussing this already, see comment thread: #13483 (comment) |
|
This might also close #8057 (Moving by word, or greater, where the whole new block of text to be read is characters at a higher punctuation level than set, so nothing is read). I can also see @lukaszgo1's point. I do think it is better to say something rather than remain silent, however, I can't think of a good, short, phrase to read in lieu of "This utterance would all be text at a higher puncutation level than would be read" (I don't think NVDA should say that). |
I think this might be overly careful, but it can be done if you think that would be best. Could you please advise how to implement the feature flag? |
I'd just like to contest that "blank" or saying nothing at all are equally unhelpful. Since, if this is the case, let us close this PR, since all it does is in situations when nothing would be spoken at all due to symbol level or dictionary substitution, "blank" is spoken instead. So, if both states ar equally bad, then this adds no value at the cost of more lines of code. For me as a user, I feel although perhaps not the ideal final solution, "blank" is much better than nothing being said, because in the scenario that nothing is said after navigating, it gives the impression that NVDA has stopped responding and the user is left momentarily unsure about what just happened. This has happened to me several times and if "blank" was spoken (or anything at all), then it would have been preferable to avoid confusion. I think, aiming for a better final solution is a good idea, but I find this to be an incremental improvement. |
|
Based on feedback so far, I have these todos:
|
fcdeb6e to
b8019cf
Compare
See test results for failed build of commit a0d096abd3 |
|
Hello, so I finally got around to make the cleanups I promised and update new tests etc. This is ready for review again. I think an apt summary of the discussion is that there is no universally prefferable solution to the problem of what if all the text is removed due to either symbol level or dictionary substitution. Therefore, I think the final solution will need to make this configurable, so that a user can choose the one they prefer. However, I think most of us can at least agree that the current behavior of NVDA speaking nothing, giving the impression that it froze, isn't a behavior that anyone finds the most preferable. So, although this wouldn't be the final solution, I propose speaking "blank" as an straightforward, incremental improvement over the current behavior of speaking nothing. |
…parameter in PR nvaccess/nvda#13483. Closes #5.
…parameter in PR nvaccess/nvda#13483. + This was causing many failures of navigation and other things, when used with NVDA alphas. + Closes #5.
|
I was just thinking, if the issue with this implementation is that it isn't possible to tell if "blank" means an actually empty line with no chars or if it is a line with chars but they were filtered out, then how about in this scenario "empty" is spoken instead? That way if you hear "blank" then you know it is a line with no chars and if you hear "empty" you know it is a line with chars that were all filtered out Someone might argue that then when you hear "empty" then you will be wondering whether it is a line that has the text empty or if it is a line with filtered out text. I will just preemptively remind that is already the case with "blank", "heading level 1", "link", "emphasis", and all the other features that speak something that isn't actually there. |
|
Header level 1, bold, emphasis, link and so on are attributs and they are visually presents... |
|
Or better, "blank chars", for spaces and tabs, and "filtered chars", for filtered characters... |
|
@ruifontes Ok, so if I understand correctly, you are suggesting there should be 3 different things spoken:
I think I'd prefer to keep discussion in this thread to just be about the 3rd case since that is what this PR was about. My concern with "filtered chars" is that it is quite verbose. Even "empty" isn't that ideal because it is two syllables compared to the one syllable of "blank". I am not sure what the right phrase is, but I think shorter is better |
|
2. "blank chars" when a line only contains spaces or tabs
"chars" is not a concept that users hear much. You and I know what it means, but
if you go with something along these lines, that doesn't seem like language that
will be approved.
"whitespace" is one possible option.
Or the actual characters, like I suggested--"4 tab", "4 space", "6 tab 3 space".
3. "filtered chars" when the line has all its text filtered out
And now we have two words that users will need defined or explained for them.
"filtered" in this context, is another term that is not used.
Is silence suddenly not looking so bad? :)
This is really an ideal case for an earcon, or some little blip or beep, if
people don't want to hear the punct level raised to speak lines that would
otherwise render as silent.
|
|
For me, silence is good, since I can check in Braille display. |
closes #13431 (yay! a palindrome)
Link to issue number: #13431
Summary of the issue:
After processing a text for dictionary substitutions and symbol level, the result might be an empty string, which leads to nothing being spoken at all (not even "blank"). Something should always be spoken when reading text, since nothing being spoken gives the appearance of NVDA freezing.
Description of how this pull request fixes the issue:
When a speech sequence is submitted to
speech.speak, if all strings of the sequence become empty due to symbol level and dictionary substitution processing, then the sequence is considered blank and "blank" is appended to it.The function now also takes an additional argument,
suppressBlanks, which is false by default. This parameter allows callers to suppress the "blank" being appended to the sequence, even if the conditions are met. The main intention is to suppress this behavior during say all. Usages ofspeech.speakhave been updated to specify this parameter when appropriate.Testing strategy:
Manually tested on following examples using NVDA built by appveyor. Also updated relevant system tests.
Some lines to test changes on:
Before changes:
at symbol level < All and indentation reporting off, 2 tab line, nothing is spoken
in contrast, 4 space line is spoken as "blank" with indentation reporting off, and "4 space blank" when turned on
(Note: as you can read in Tab characters should be considered blank #13431, this is because by
isBlank()it is considered blank, however tabs cant be considered blank because they are actually spoken when symbol level is All, whereas spaces and other `BLANK_CHUNK_CHARS are not spoken at any symbol level)for 3 stars line, nothing is spoken at symbol level None
also when reading by word, the 3 stars between hello and world have nothing spoken
after changes:
Known issues with pull request:
speech.speakfunction might get different output than they used to. Addons are able to setsuppressBlanks=Trueto get the previous behavior. In many cases this updated behavior could be welcomed by addon authors. A way to ensure API compatibility is maintained would be to have the default value beTrueinstead ofFalse, but then the new behavior, which should be correct in majority of cases, isn't automatically used.[BeepCommand, "", BeepCommand], then "blank" will be spoken after the two commands are executed whereas the text it is replacing would have been spoken before the last command was executed.["", Command, "", Command].Change log entries:
New features
Changes
Bug fixes
For Developers
Code Review Checklist: