0

I am developing a terminal TUI application for myself using the ncurses library. (Running on Linux)

I cannot seem to find much info regarding the use of a "strikethrough/strikeout" text attribute when adding a string to a ncurses window using addstr and friends.

The only information I've found online was on this site: https://midnight-commander.org/ticket/3264

Ncurses will not add [strikethrough text] because the bitfield is already fully packed.

I was wondering if there are any workarounds to this, or any official way to do this.

Any help would be appreciated.
Thanks.

Michael
  • 115
  • 10
  • curses doesn't allow you to do that, but this can be done with Unicode, see [this answer](https://stackoverflow.com/a/25244576/4039050). – schneiderfelipe Nov 18 '21 at 21:00

3 Answers3

2

ncurses has 16 bits allocated for video-attributes. SVr4 curses used 8; XOpen Curses added 7. Those 15 are defined for X/Open Curses compatibility.

Referring to the X/Open Curses documentation, there are two sets of definitions:

A_ALTCHARSET   Alternate character set
A_BLINK        Blinking
A_BOLD         Extra bright or bold
A_DIM          Half bright
A_INVIS        Invisible
A_PROTECT      Protected
A_REVERSE      Reverse video
A_STANDOUT     Best highlighting mode of the terminal
A_UNDERLINE    Underlining

and

WA_ALTCHARSET  Alternate character set
WA_BLINK       Blinking
WA_BOLD        Extra bright or bold
WA_DIM         Half bright
WA_HORIZONTAL  Horizontal highlight
WA_INVIS       Invisible
WA_LEFT        Left highlight
WA_LOW         Low highlight
WA_PROTECT     Protected
WA_REVERSE     Reverse video
WA_RIGHT       Right highlight
WA_STANDOUT    Best highlighting mode of the terminal
WA_TOP         Top highlight
WA_UNDERLINE   Underlining
WA_VERTICAL    Vertical highlight

depending on whether the bits are stored in a attr_t or a chtype (X/Open and SVr4 respectively). In ncurses, those are the same (see the manual page), so that it does not matter if one refers to A_BOLD or WA_BOLD (Solaris xpg4 curses does store those differently).

Discounting the A_ vs WA_, the two lists are different. The newer ones from X/Open Curses are rarely used. Since ncurses doesn't know what it looks like on the screen, someone could add the corresponding terminfo capability to a terminal description and ncurses would handle it.

The terminfo manual page mentions these:

The XSI Curses standard added these hardcopy capabilities. They were used in some post-4.1 versions of System V curses, e.g., Solaris 2.5 and IRIX 6.x. Except for YI, the ncurses termcap names for them are invented. According to the XSI Curses standard, they have no termcap names. If your compiled terminfo entries use these, they may not be binary-compatible with System V terminfo entries after SVr4.1; beware!

(Explaining how to modify a terminal description can be found in thousands of webpages, and is off-topic for this forum).

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • 1
    Thank you for the detailed explanation. So it seems that the only way to use strikethrough text in ncurses is using a bit of hackery... – Michael Apr 04 '20 at 22:23
  • 1
    By that token, any tweaks to the terminal description are "a bit of hackery". The question was whether there "were any workarounds" (there are). – Thomas Dickey Apr 04 '20 at 23:22
1

Possible attributes in ncurses are:

A_NORMAL Normal display (no highlight)
A_STANDOUT Best highlighting mode of the terminal.
A_UNDERLINE Underlining
A_REVERSE Reverse video
A_BLINK Blinking
A_DIM Half bright
A_BOLD Extra bright or bold
A_PROTECT Protected mode
A_INVIS Invisible or blank mode
A_ALTCHARSET Alternate character set
A_CHARTEXT Bit−mask to extract a character
COLOR_PAIR(n) Color−pair number n

Functions like attron(), attroff(), attrset() may be used to work with attributes,

Strikethrough is not and will not be available.

If you know your terminal and want your software to be able to to work just on such an terminal type AND the terminal supports strikethrough, then you can use control characters or escape sequences to activate such a funcionality.

A M
  • 14,694
  • 5
  • 19
  • 44
  • 1
    I am aware of the attributes listed above and how to enable them, though I did not find any attribute for strikethrough text, hence my question. My terminal emulator does indeed support strikethrough text, with the `^[9m` escape code. After some prior searching around, I reached a conclusion that the whole 'printing escape sequences' route would not be a good one to take, as it would likely screw around with the positions of characters on the screen. – Michael Apr 04 '20 at 22:12
-1

You can use Unicode for that:

(n)curses strikethrough using Unicode

(I know it's an old question, but I had a similar issue, and this is the top result for "curses strikethrough" on Google, so this answer might be helpful to someone.)

I made it work using Python, but the strategy should work in any language:

import curses


def strike(text: str) -> str:
    # See <https://stackoverflow.com/a/25244576/4039050>
    return "\u0336".join(text) + "\u0336"


def main(stdscr):
    message = "The quick brown fox jumps over the lazy dog."
    stdscr.addstr(strike(message))
    stdscr.refresh()
    stdscr.getch()


if __name__ == "__main__":
    curses.wrapper(main)
schneiderfelipe
  • 375
  • 1
  • 8
  • 19