1

TL;DR?

How can I change every instance of one character (e.g. 'E') in a terminal window to another string of characters (e.g. '~E'), moving all other characters along in the window in the process? So:

abcdEfghij

becomes:

abcd~Efghij

This should work in the gnome-terminal and work with whatever output is on that terminal, from whatever program. Ideally it will be a script or other program I can run within that terminal emulator.

The context

I am using a Braille display (the Canute 360) with a Braille screen-reader (brltty), which at present does not support capital letters. They show up in Braille the same as lower-case letters. Until this is developed for BRLTTY I sometimes need to be able to force showing which letters are capitalised in order for me to, for example, write code.

The proposed solution

N.B. The below proposed solution is not intended to be elegant; it is a quick and dirty way of letting me and other Braille-using developers continue to program with this display for our work until the proper solution is forthcoming in the screen-reader proper.

I am trying to essentially 'wrap' the output of the terminal emulator (in this case gnome-terminal to force a certain character in front of every capital letter so on the Braille display it can be identified. I am going to assume that character is tilde (~). I am not concerned about this breaking vertical alignment, or forcing the line off the edge of the display. I am assuming a 40 character wide terminal (width of the Canute).

So this normal output:

$ echo ${string}
A Quick Brown Fox
Jumps over the lazy
Dog. Etc.
$

Becomes this:

$ echo ${string}
~A ~Quick ~Brown ~Fox
~Jumps over the lazy
~Dog. ~Etc.
$

That would then be viewable on the Canute (in US Computer Braille) as this:

$ echo ${string}
~a ~quick ~brown ~fox
~jumps over the lazy
~dog. ~etc.
$

It is fine for this to be a command that has to be called first, like screen. So:

$ caps-hack
$ nano
[doing my thing, then quit nano]
$
[ctrl-x to quit caps-hack]
$

Or alternatively it could launch a new terminal window, or it could be tied to specific TUI applications (like nano). I will primarily be using it for working inside vi, nano, micro and other editors, so if it cannot capture all terminal output the solution is still valuable.

Example use case: Micro/nano text editor

When I need to see capitals whilst editing text using micro or nano I would first launch caps-hack, then I could use the TUI editor, exit it, be back on the terminal, then cancel caps-hack if I wanted to revert to usual behaviour.

This is what nano normally looks like:

  GNU nano 4.8   New Buffer   Modified  

This is a nonsense file for 
Stackoverflow.



^G Get Hel^O Write O^W Where I^K Cut Tex
^X Exit   ^R Read Fi^\ Replace^U Paste T

I'm looking for a solution that would then make it look like this:

  ~G~N~U nano 4.8   ~New ~Buffer   ~Modi

~This is a nonsense file for 
~Stackoverflow.



^~G Get ~Hel^~O ~Write ~O^~W ~Where ~I^~
^~X ~Exit   ^~R ~Read ~Fi^\ ~Replace^~U 

(Note that I have cut it off at 40 characters.)

The effect would be the same (inserting tildes, cutting off at 40 characters) whether I was in the terminal itself, in mc, or watching a ping stream.

This active use case means that so far as I can see I cannot simply pipe the output of programs to a bash script (like the one below), as that wouldn't work with a TUI. So I cannot do: $ nano myfile.txt | caps-hack

What I have tried so far

I have not worked out how to essentially capture the output, modify it and write it back to the terminal window. However I have the following shell snippet which I believe could be used for it, if I know where to put it.

# Repeat for all visible lines in the terminal
moddedline1=$( echo ${originalLine1} | sed -E -e 's/\([A-Z]\)/~\1/g' )
moddedline1="${moddedline1:0:40}" 
tput cup 1 0 && printf "${moddedline1}"
Ed Rogers
  • 75
  • 5
  • Don't have time to dig in on this now, but you need to think about capturing the output of what ever program, modifying it AND THEN display to the terminal. Your sed command may be all you need. `myCommand | sed '....'`, but I'm in a rush now, you probably have indicated that users need to send input to `myProgram`? Try to make a more "use-case" view of your prroblem. Good luck. – shellter Feb 13 '23 at 23:23
  • 1
    So the only input you need from a user is "page up, down," etc? There is probably a way to send input to your program and still filter the output thru your `sed` command. Respond or update your question in a way that makes it possible for readers here that don't have `brltty` can understand what is needed. Good luck. – shellter Feb 14 '23 at 15:37
  • Thanks for your comments @shellter. I have edited it to include an example use case which I hopes make it clearer that the solution must allow full, normal keyboard input from the user in the terminal applications like nano. – Ed Rogers Feb 14 '23 at 17:32
  • I think you're looking at a complicated project to get the results you need. Taking your `nano` use-case as the example, the only way I'm aware that you could create a display in `nano` like `~this` would be to modify the source code to provide that feature. OR maybe there would be a way to add another function in the `*nix-kernel` that could provide this to output streams, but how would it know to only apply this to the one particular program? This would be even more complicated. How much do you know about `*nix` programming? Do you understand the output of `pstree`? .... – shellter Feb 14 '23 at 21:02
  • I'm having an idea. Back in a while. – shellter Feb 14 '23 at 21:11
  • 1
    Nope, that didn't work. I tried a simpler case where from one terminal window, I used a loop to send output to another termnial window via `echo "something" > /dev/pts/N` (where N is what ever number was returned from running `tty` in the receiver terminal). I wasn't able to use another shell (in another terminal window) to capture `"something"` and echo it out in the alterrnate window. There may be a way using `/dev/pts/N` to do such a thing but I can't find it now. If we could get that to work, that might be the basis of overriding to output of another program running in another term session – shellter Feb 14 '23 at 21:51
  • 1
    I half expected to be able to say `read -r var < /dev/pts/(N) ; echo "var=$var"` in another terminal session. But on another point, it is disappointing that no one else has remarked/replied/critisized/etc your questioin. I half expected your Q to be voted closes immediately as too broad or as a request for tool/library recommendation, both of which are off topic. And in that spirit, I offer a few more comments. You have gone to a lot of care to define and provide context for your problem, but in a way, it is too much information. Consider another rewrite of this question including .... – shellter Feb 14 '23 at 21:57
  • 1
    a `TLDR` section at the top. To me, you're asking 'How can I modify the screen output of a running program'. (Maybe that is wrong). Then a quick illustration of what you're trying to achieve and what you have tried so far (you have this). I would rely on the `nano` use-case for above, but then you can have a final section "what I really need to do" with more details about `brltty`. If you can update this, I will back your question with a Bounty. This will certainly get more readers looking at your question. If we do, I will probably selectively delete my comments above. ... OK? Good luck! – shellter Feb 14 '23 at 22:03
  • Hi @shellter, thanks for taking the time on this. You are correct it is an over-wordy problem. I will re-write with a TL;DR. I liked your thinking about capturing one terminal and feeding it to another. It hadn't occurred to me; my mind was on using a tool like `screen` or `tmux`. – Ed Rogers Feb 17 '23 at 18:56
  • @shellter I don't know much about nix programming and have never looked at the output of `pstree` before you mentioned it. – Ed Rogers Feb 17 '23 at 19:01
  • @EdRodgers. (Did you find `pstree` instructive?) ... Sorry WIll have to look at this later. My dog is sick. Hopefully later today I'll have any final comments and set the bounty. Your's is an interesting projecdt and question and it is trying to help a handicapped community. Kuds to you!. – shellter Feb 17 '23 at 21:19
  • https://github.com/brltty/brltty in case anyone else is interested in commenting on this. I'll try to build it on my machine and see what I can see. – shellter Feb 18 '23 at 02:50
  • Trying to setup a chat as this may take a while. But first (for some reason) you have to have already visited at chat room so goto https://chat.stackoverflow.com/rooms/98569/bin-bash and say "Ping @shellter" . Then I'll be able to add you to our Brltty chat. No Rush, I check S.O. 4-6 times a way, Chicago time. Arg! – shellter Feb 18 '23 at 03:00
  • @shellter I'm sorry for going totally off grid after you were being so generous with your time. A bout of illness plus trying to do too many multiline Braille projects at once. An update on this issue is that a month ago brltty was updated to support multiline in literary Braille mode, which removes much (not all) of the need for the fix I was asking about above. However there are still some important use-cases for it so I will keep thinking about it and will thaw out this query again some moons from now. – Ed Rogers Apr 15 '23 at 11:30
  • Hi. Glad to hear from you and very sorry about the illness. I hope things are better now. FWIW, the brltty developer seems like he would be open to a discussion about your project. Also YouTube has a channel "Blind Android Users" and I found this interview worth the time to listen https://www.youtube.com/watch?v=ny1DuLkYb18&pp=ygUGYnJsdHR5 . Stay in touch. I will help if I can. Good luck with your projects! – shellter Apr 15 '23 at 15:27

0 Answers0