Is it possible to display text in a console with a strike-through effect? - text

I have already looked into ANSI escape codes, but it looks like only underlining is supported.
Do I miss something or is there another option?
If it is not possible, is there something equivalent in the meaning of "this is deprecated"?

According to the ECMA-48 standard for terminals, SGR (Select Graphic Rendition) code number 9 is supposed to enable crossed-out text. However, the ANSI escape code wikipedia page says that it's not widely supported, and I'm not aware of any that do. I'd suspect that's because DEC's VTxxx series didn't support it.

An alternative solution for applications written in C11 or C++11 is to use the Unicode combining long stroke overlay character.
In C++11 you can write code something like this:
#include <iostream>
#include <string>
std::string strikethrough(const std::string& text) {
std::string result;
for (auto ch : text) {
result.append(u8"\u0336");
result.push_back(ch);
}
return result;
}
int main() {
std::cout << strikethrough("strikethrough") << std::endl;
}
The code prefixes each character in the input text with the stroke overlay \u0336. Note that the function assumes that text is encoded in a singlebyte encoding such as ASCII or Latin. If the input is in UTF-8 it must be converted to UTF-32 first to get the character boundaries.
The output then is s̶t̶r̶i̶k̶e̶t̶h̶r̶o̶u̶g̶h in a UTF-8 capable terminal. I don't know why the first character has no strike-through, must be a terminal issue. I could work around this by printing at least one character before the strikethrough function call.
The Unicode solution also generates a slightly different locking in my terminal (terminator) compared to the ANSI escape sequence mentioned above. The former renders the line exactly in the middle of the text whereas the latter renders it a bit below.

This works for me.
$ echo -e `echo "this is a strikethrough text" | sed 's/.\{1\}/&\\\u0336/g'`

couldn't find anything easier than this:
$ echo -e "\e[9myour text goes here\e"

Related

PolyML colored output to terminal in Linux

Ideally, this line of PolyML code should give desired result:
print "\033[31m RED \033[0m NORMAL \n";
But the \033 turns out to be just an exclamation mark, not a special symbol for color encoding.
I use the following "way-around" approach, but it doesn't allow to do anything interactively: I just take the output of my program and color it.
echo "\\\\033[31m RED \\\\033[0m NORMAL \\\\n" | xargs echo -e
What are the possible solutions to this problem? Is it possible to solve it within the standard PolyML instruments?
added: I checked how Ocaml do the same thing with
Printf.printf "\033[31m RED \033[0m NORMAL \n";;
-- situation is the same: no color obtained.
p.s. this question is not a dublicate because it is about differences between echo -e and print in ML languages
\033 is a character escape sequence which in bash and many other languages is interpreted as the character with ASCII code corresponding to the octal number 33.
In OCaml however, this escape sequence is interpreted as decimal. We can either convert the number from octal (33) to decimal (27) and continue to use this syntax, or use the correct syntax for octal escape sequences (\o027). Or we could even use hex (\x1b) if we want to be a bit more adventurous.
All of these will work in OCaml, and possibly also PolyML (if you replace Printf.printf with print of course):
Printf.printf "\027[31m RED \027[0m NORMAL \n";;
Printf.printf "\o033[31m RED \o033[0m NORMAL \n";;
Printf.printf "\x1b[31m RED \x1b[0m NORMAL \n";;
Source: The OCaml manual Chapter 9.1: Lexical conventions
Thanks to this question:
OCaml color console output
The correct answer is to use code \027 instead of \033 both in Ocaml and PolyML:
print "\027[31m RED \027[0m NORMAL \n";

Eiffel: is there a way to print colorized characters into a terminal (console)

Trying to write some logger enhancements I'd like to deal with ANSI codes interpretation, and it seems that it's not working with the standard io.putstring method neither with print I wonder there is a way to do something such as
echo -e "\u001B[31mSome_red_txt" in bash
Seems other languages can do it but I can't in Eiffel.
Using ANSI codes interpretation, you can do
print ("%/27/[31mSome_red_txt%N")
print ("%/27/[1;31mbold red text%/27/[0m%N")
You may check for existing C libraries like ncurses.
Note it will not work on Windows console, as now it does not support ANSI code anymore, so you need to use the Windows API.
To complement Jocelyn's answer, the same ANSI code sequences can be used on Windows with recent update by making sure the console is initialized to handle the sequences:
-- Make sure the console is allocated in a non-console application.
io.output.end_of_file.do_nothing
-- Set console to terminal mode.
initialize_terminal
-- Use ANSI codes to color text.
print ("%/27/[31mSome_red_txt")
where
initialize_terminal
external "C inline"
alias "[
#ifdef EIF_WINDOWS
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE) return;
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode)) return;
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(hOut, dwMode);
}
#endif
]"
end
After such initialization, print statements work the same on Windows and Linux.
If output can go not only to the console, but also to a file, a pipe, etc., error status of setting the terminal mode on Windows console can be recorded in the external feature and used later to avoid outputting ANSI sequences in such cases.

Use char-codes in strings

I'm working on a terminal program under Linux. I consider adding colorized output.
The task is not really hard, so I succeeded with the following:
[3]> (format t "~a[1;31mred text~a[0m" #\escape #\escape)
red text ; this text is really red and bold in terminal ;-)
NIL
But the code is ugly: I don't know how to put char #\escape (decimal value 27) into a string in 'inline' fashion. For example C++ code from this thread:
cout << "\033[1;31mbold red text\033[0m\n";
Here is #\Escape as \033 (octal). Is there something similar in Common Lisp?
My effort naïf doesn't work as intended:
[4]> (format t "#\escape1;31mred test#\escape[0m")
#escape1;31mred test#escape[0m
NIL
You can type the characters manually…
You don't have to do anything special to have the control characters (or other "unusual" characters) in your strings. You just need to be able to type them into the editor. How easy it will be will depend on your editor. In Emacs, and in at least some terminal emulators, you can press Ctrl-Q followed by another character to insert that character literally. Thus, you can press Ctrl-Q followed by Escape to insert a literal #\escape character. How it appears will depend on the terminal emulator or editor. In my terminal, the literal Escape character is displayed as ^[. Thus, I end up with:
(format t "^[[1;31mhello^[[0!")
; ** **
; result of C-Q Esc
This gives me some red text, as in your example:
…or use a library to make it easier!
If you don't want your source to contain characters that might not be easily readable, you might look into something like Edi Weitz's CL-INTERPOL:
CL-INTERPOL is a library for Common Lisp which modifies the
reader so that you can have interpolation within strings similar to
Perl or Unix Shell scripts. It also provides various ways to insert
arbitrary characters into literal strings even if your editor/IDE
doesn't support them. Here's an example:
* (let ((a 42))
#?"foo: \xC4\N{Latin capital letter U with diaeresis}\nbar: ${a}")
"foo: ÄÜ
bar: 42"
Using CL-INTERPOL, this becomes easy:
* (interpol:enable-interpol-syntax)
* (format t #?"\e[1;31mhello\e[0m!")
hello! ; there's color here, honest!
NIL

How I can recive colored result from Replace Function?

How I can recive colored result from Replace Function?
Regex.Replace("My Document", "My", ?);
EDITED:
I soleved it:
if (richTextBox1.Find("ab") > 0)
{
richTextBox1.SelectionBackColor = Color.LightGreen;
}
(Parts) in strings don't have an inherent color. A string is only a sequence of characters. Some terminals however use "escape characters" that are interpreted as meta-data on how to typeset parts of the string.
For instance the linux shell uses data like "\033[31mHello\e[0m World" to highlight Hello in red. But there are always terminals that will not recognize such directives.
Some control components (i.e. the RichtTextBox) use such directives as well and provide transparent methods to insert directives.

ncurses- KEY_ENTER is fail

I've been trying to teach myself ncurses and I'm loving it so far. However, I'm trying to write a small little text editor like pico or nano. I've got it set up fairly well so far. I created a function to map the keys. No matter what I do I can not get a response from KEY_ENTER. Whenever I press it it just goes to the beginning of the currently line that I'm on. I've tried using raw(); and using 13 instead of KEY_ENTER no luck. All the other keys respond as expected. I would appreciate any advice. I've been staring at this trying to make it work forever. Thanks!
#include <stdlib.h>
#include <ncurses.h>
// gcc keymaps.c -lncurses -o keymaps
int main(){
int ch;
initscr();
cbreak();
noecho();
keypad(stdscr,TRUE);
while (ch = getch()) {
switch(ch){
case KEY_UP:
addstr("Up\n");
break;
case KEY_LEFT:
addstr("Left\n");
break;
case KEY_RIGHT:
addstr("Right\n");
break;
case KEY_BACKSPACE:
addstr("Backspace\n");
break;
case KEY_ENTER:
addstr("You pressed Enter\n");
default:
printw ("%u\n", ch);
break;
}
}
}
The likely problem is user confusion between the Enter key on the regular keyboard versus the Enter key on the numeric keypad. Those could both send a control/M (13), but not necessarily. The terminal description and KEY_ENTER refer to the numeric keypad.
The ncurses manual page for getch explains the behavior in the NOTES:
Some keys may be the same as commonly used control keys,
e.g., KEY_ENTER versus control/M, KEY_BACKSPACE versus
control/H. Some curses implementations may differ according to whether they treat these control keys specially
(and ignore the terminfo), or use the terminfo definitions. Ncurses uses the terminfo definition. If it says
that KEY_ENTER is control/M, getch will return KEY_ENTER
when you press control/M.
Generally, KEY_ENTER denotes the character(s) sent by the
Enter key on the numeric keypad:
the terminal description lists the most useful keys,
the Enter key on the regular keyboard is already handled by the standard ASCII characters for carriage-return and line-feed,
depending on whether nl or nonl was called, pressing
"Enter" on the regular keyboard may return either a
carriage-return or line-feed, and finally
"Enter or send" is the standard description for this
key.
Line-feed, by the way, is a 10. But in C, it is usually shown as '\n' (and carriage return as '\r').
Try 10 as ASCII value ... worked for me on ncurses.Also please update the actual code because this code that you put is wrong by syntax.
From the PDCurses documentation:
#define KEY_ENTER 0x157 /* enter or send (unreliable) */
Try calling nonl() after raw().
The nl and nonl routines control whether the underlying display device translates the return key into newline on input, and whether it translates newline into return and line-feed on output (in either case, the call addch('\n') does the equivalent of return and line feed on the virtual screen). Initially, these translations do occur. If you disable them using nonl, curses will be able to make better use of the line-feed capability, resulting in faster cursor motion. Also, curses will then be able to detect the return key.
I got the same KEY_ENTER problem recently, and I fixed it by replacing KEY_ENTER with 10 or \n, which is ASCII new line.
#include <ncurses.h>
int main() {
initscr(); /* init ncurses */
keypad(stdscr, TRUE); /* get keyboard input */
addstr("Press enter to exit.\n");
while (10 != getch()) {} /* 10 == enter */
endwin(); /* end ncurses */
return 0;
}

Resources