Terminal control/Coloured text: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added XPL0)
Line 413: Line 413:


tput sgr0 # reset everything before exiting</lang>
tput sgr0 # reset everything before exiting</lang>

=={{header|XPL0}}==
Device 6 is similar to the standard console output device 0, but it
supports color. When light colors are used for background (in a text
rather than graphic display mode) they are displayed as standard (dim)
colors and the foreground color flashes. A BIOS call (int 10h, func 10h,
sub 03h) can be used to disable flashing and enable bright backgrounds.

It's possible to detect monochrome displays with a BIOS call, but
monochrome is so ancient it's not worth demonstrating. Actually the older
16-bit versions of the language made it easy to detect monochrome using
the Equip(ment) intrinsic, but the newer 32-bit version doesn't provide
the Equip intrinsic.

Of course these features are provided by the hardware of IBM-compatible
PCs and by simulators, such as DOSBox, on other computers.

<lang XPL0>code ChOut=8, Attrib=69;
def Black, Blue, Green, Cyan, Red, Magenta, Brown, White, \attribute colors
Gray, LBlue, LGreen, LCyan, LRed, LMagenta, Yellow, BWhite; \EGA palette
[ChOut(6,^C); \default white on black background
Attrib(Red<<4+White); \white on red
ChOut(6,^o);
Attrib(Green<<4+Red); \red on green
ChOut(6,^l);
Attrib(Blue<<4+LGreen); \light green on blue
ChOut(6,^o);
Attrib(LRed<<4+White); \flashing white on (standard/dim) red
ChOut(6,^u);
Attrib(Cyan<<4+Black); \black on cyan
ChOut(6,^r);
]</lang>


== {{header|ZX Spectrum Basic}} ==
== {{header|ZX Spectrum Basic}} ==

Revision as of 18:33, 18 November 2012

Task
Terminal control/Coloured text
You are encouraged to solve this task according to the task description, using any language you may know.

The task is to display a word in various colours on the terminal. The system palette, or colours such as Red, Green, Blue, Magenta, Cyan, and Yellow can be used.

Optionally demonstrate:

  • How the system should determine if the terminal supports colour
  • Setting of the background colour
  • How to cause blinking or flashing (if supported by the terminal)

AutoHotkey

AutoHotkey is not written for the command line, so we need to use the WinAPI directly. For simplicity, this example demonstrates only the foreground colours. <lang AHK>DllCall( "AllocConsole" ) ; create a console if not launched from one hConsole := DllCall( "GetStdHandle", int, STDOUT := -11 ) Loop 15 SetConsoleTextAttribute(hConsole, A_Index) ,WriteConsole(hConsole, "AutoHotkey`n")

MsgBox

SetConsoleTextAttribute(hConsole, Attributes){ return DllCall( "SetConsoleTextAttribute", UPtr, hConsole, UShort, Attributes) } WriteConsole(hConsole, text){ VarSetCapacity(out, 16) If DllCall( "WriteConsole", UPtr, hConsole, Str, text, UInt, StrLen(text) , UPtrP, out, uint, 0 ) return out return 0 }</lang>

BASIC

Works with: QBasic

<lang qbasic>FOR n = 1 TO 15

   COLOR n
   PRINT "Rosetta Code"

NEXT</lang>

BBC BASIC

<lang bbcbasic> FOR col% = 0 TO 14

       COLOUR col% : REM foreground
       COLOUR 128+(15-col%) : REM background
       PRINT "Rosetta Code"
     NEXT</lang>

C

On a terminal that understands ANSI escape sequences, such as color xterm, this shows you some annoyingly huge, annoyingly colorful tables. <lang c>#include <stdio.h>

void table(char *title, char *mode) { int f, b; printf("\n\033[1m%s\033[m\n bg\t fg\n", title); for (b = 40; b <= 107; b++) { if (b == 48) b = 100; printf("%3d\t\033[%s%dm", b, mode, b); for (f = 30; f <= 97; f++) { if (f == 38) f = 90; printf("\033[%dm%3d ", f, f); } puts("\033[m"); } }

int main(void) { int fg, bg, blink, inverse;

table("normal ( ESC[22m or ESC[m )", "22;"); table("bold ( ESC[1m )", "1;"); table("faint ( ESC[2m ), not well supported", "2;"); table("italic ( ESC[3m ), not well supported", "3;"); table("underline ( ESC[4m ), support varies", "4;"); table("blink ( ESC[5m )", "5;"); table("inverted ( ESC[7m )", "7;"); return 0; }</lang>

Mathematica

Delegating to tput on terminal enabled OS(Mac Os, Linux) <lang Mathematica>Run["tput setaf 1"]; Print["Coloured Text"]; Run["tput setaf 2"]; Print["Coloured Text"]; Run["tput setaf 3"]; Print["Coloured Text"]</lang>

OCaml

Using the library ANSITerminal in the interactive loop:

<lang ocaml>$ ocaml unix.cma -I +ANSITerminal ANSITerminal.cma

  1. open ANSITerminal ;;
  2. print_string [cyan; on_blue] "Hello\n" ;;

Hello - : unit = ()</lang>

PicoLisp

Translation of: UNIX Shell

<lang PicoLisp>(unless (member (sys "TERM") '("linux" "xterm" "xterm-color" "rxvt"))

  (quit "This application requires a colour terminal") )
  1. Coloured text

(for X '((1 . "Red") (4 . "Blue") (3 . "Yellow"))

  (call 'tput "setaf" (car X))
  (prinl (cdr X)) )
  1. Blinking

(out '(tput "-S")

  (prinl "setab 1^Jsetaf 3^Jblink") )

(prin "Flashing text")

(call 'tput 'sgr0) # reset (prinl)</lang>

PureBasic

<lang purebasic>If OpenConsole()

 PrintN("Background color#     00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15")
 PrintN("                      -----------------------------------------------")
 Define Foreground, Background
 For Foreground = 0 To 15
   ConsoleColor(7, 0) ;grey foreground, black background
   Print("Foreground color# " + RSet(Str(Foreground), 2, "0") + "  ")
   For Background = 0 To 15
     ConsoleColor(Foreground, Background)
     Print(RSet(Str(Foreground), 2, "0"))
     ConsoleColor(7, 0) ;grey foreground, black background
     Print(" ")
   Next
   PrintN("")
 Next
 
 ConsoleColor(7, 0) ;grey foreground, black background
 Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
 CloseConsole()

EndIf</lang>

REXX

PC/REXX or Personal REXX

This REXX program only works under PC/REXX (also called Personal REXX).
PC/REXX can execute under MSDOS (or a Windows DOS window), or OS/2.

The prologue code (at the bottom of the program) is a collection of some general-purpose subroutines which determine:

  • which environment (operating system) the REXX interpreter is running under
  • if Windows/NT/XP/Vista/7/8 (the NT family) is running
  • which REXX is being executed
  • what literal to use to obtain the environmental variables (for the value bif)
  • what the fileName, fileType/fileExt, fileMode/path is of the REXX program
  • which command to use to clear the terminal screen
  • invokes $H to show general documentation (1st and only arg = ?)
  • invokes $H to show a flow diagram (1st and only arg = ?FLOW)
  • invokes $H to show sample uses (1st and only arg = ?SAMPLE)
  • invokes $H to show the author & contact info (1st and only arg = ?AUTHOR)

All the prologue was left intact to give a general feel of the scope of the boilerplate code.
The prologue code is in many REXX programs and it's easier to keep them on one line for copying purposes and sorting.

The program displays 16 lines, each of a different color with text stating the color of the text.
(The black text, of course, is essentiall invisible as the background is also black.) <lang rexx>/*REXX*/parse arg !;if !all(arg()) then exit

if \!dos & \!os2 then exit /*if this isn't DOS, then exit. */ if \!pcrexx then exit /*if this isn't PC/REXX, exit. */

               /* The "real" programs issue all errors through another */
               /* program which has more verbage and explanation, and  */
               /* issues the error text in red  (if color is avaiable).*/

color.0 = 'black' color.1 = 'dark blue' color.2 = 'dark green' color.3 = 'dark cyan/turquois' color.4 = 'dark red' color.5 = 'dark pink/magenta' color.6 = 'dark yellow (orange)' color.7 = 'dark white' color.8 = 'brite black (grey/gray)' color.9 = 'bright blue' color.10 = 'bright green' color.11 = 'bright cyan/turquois' color.12 = 'bright red' color.13 = 'bright pink/magenta' color.14 = 'bright yellow' color.15 = 'bright white'

        do j=0 to 15                  /*show all sixteen color codes.  */
        call scrwrite ,,'color code=['right(j,2)"]" color.j,,,j;   say
        end                           /*the  "SAY"  forces a  NEWLINE. */

exit /*stick a fork in it, we're done.*/

/*═════════════════════════════general 1-line subs══════════════════════*/ !all:!!=!;!=space(!);upper !;call !fid;!nt=right(!var('OS'),2)=='NT';!cls=word('CLS VMFCLEAR CLRSCREEN',1+!cms+!tso*2);if arg(1)\==1 then return 0;if wordpos(!,'? ?SAMPLES ?AUTHOR ?FLOW')==0 then return 0;!call=']$H';call '$H' !fn !;!call=;return 1 !cal:if symbol('!CALL')\=="VAR" then !call=;return !call !env:!env='ENVIRONMENT';if !sys=='MSDOS'|!brexx|!r4|!roo then !env='SYSTEM';if !os2 then !env='OS2'!env;!ebcdic=1=='f0'x;return !fid:parse upper source !sys !fun !fid . 1 . . !fn !ft !fm .;call !sys;if !dos then do;_=lastpos('\',!fn);!fm=left(!fn,_);!fn=substr(!fn,_+1);parse var !fn !fn '.' !ft;end;return word(0 !fn !ft !fm,1+('0'arg(1))) !rex:parse upper version !ver !vernum !verdate .;!brexx='BY'==!vernum;!kexx='KEXX'==!ver;!pcrexx='REXX/PERSONAL'==!ver|'REXX/PC'==!ver;!r4='REXX-R4'==!ver;!regina='REXX-REGINA'==left(!ver,11);!roo='REXX-ROO'==!ver;call !env;return !sys:!cms=!sys=='CMS';!os2=!sys=='OS2';!tso=!sys=='TSO'|!sys=='MVS';!vse=!sys=='VSE';!dos=pos('DOS',!sys)\==0|pos('WIN',!sys)\==0|!sys=='CMD';call !rex;return !var:call !fid;if !kexx then return space(dosenv(arg(1)));return space(value(arg(1),,!env)) </lang>

Open Object REXX

This program is based on the shell script in the Bash Prompt HowTo at http://www.tldp.org/, by Giles Orr. It uses object-oriented features of Open Object Rexx. <lang REXX>

  1. !/usr/bin/rexx

/*.----------------------------------------------------------------------.*/ /*|bashcolours: Display a table showing all of the possible colours that |*/ /*| can be generated using ANSI escapes in bash in an xterm |*/ /*| terminal session. |*/ /*| |*/ /*|Usage: |*/ /*| |*/ /*|>>-bashcolours-.----------.-----------------------------------------><|*/ /*| |-- -? ----| |*/ /*| |-- -h ----| |*/ /*| '- --help -' |*/ /*| |*/ /*|where |*/ /*| -?, -h or --help |*/ /*| display this documentation. |*/ /*| |*/ /*|This program is based on the shell script in the Bash Prompt HowTo at |*/ /*|http://www.tldp.org/, by Giles Orr. |*/ /*| |*/ /*|This program writes the various colour codes to the terminal to |*/ /*|demonstrate what's available. Each line showshe colour code of one |*/ /*|forground colour, out of 17 (default + 16 escapes), followed by a test|*/ /*|use of that colour on all nine background colours (default + 8 |*/ /*|escapes). Additional highlighting escapes are also demonstrated. |*/ /*| |*/ /*|This program uses object-oriented features of Open Object Rexx. |*/ /*|The lineout method is used instead of say for consistency with use of |*/ /*|the charout method. |*/ /*'----------------------------------------------------------------------'*/

 call usage arg(1)
 trace normal

/* See if escapes work on the kind of terminal in use. */

 if value('TERM',,'ENVIRONMENT') = 'LINUX' then
   do
     say 'The Linux console does not support ANSI escape sequences for',
         'changing text colours or highlighting.'
     exit 4
   end

/* Set up the escape sequences. */

 ! = '1B'x                                                  -- ASCII escape
 bg = .array~of('[40m','[41m','[42m','[43m','[44m','[45m','[46m','[47m')
 fg = .array~of('[0m',   '[1m',   '[0;30m','[1;30m','[0;31m','[1;31m',,
                '[0;32m','[1;32m','[0;33m','[1;33m','[0;34m','[1;34m',,
                '[0;35m','[1;35m','[0;36m','[1;36m','[0;37m','[1;37m')
 hi = .array~of('[4m','[5m','[7m','[8m')
 text = 'gYw'                                              -- The test text
 .OUTPUT~lineout(' ')
 .OUTPUT~lineout('Foreground  |       Background Codes')
 .OUTPUT~lineout(!'[4mCodes       '!'[0m|'||,
                 !'[4m~[40m ~[41m ~[42m ~[43m ~[44m ~[45m ~[46m ~[47m'!'[0m')
 do f = 1 to fg~size                          -- write the foreground info.
   prefix = '~'fg[f]~left(6)' '!||fg[f]~strip' 'text
   .OUTPUT~charout(prefix)
   do b = 1 to bg~size                        -- write the background info.
     segment = !||fg[f]~strip !||bg[b]' 'text' '!||fg[1]
     .OUTPUT~charout(segment)
   end
   .OUTPUT~lineout(' ')
 end

/* Write the various highlighting escape sequences. */

 prefix = '~[4m'~left(6)'   '!||hi[1]'Underlined'!||fg[1]
 .OUTPUT~lineout(prefix)
 prefix = '~[5m'~left(6)'   '!||hi[2]'Blinking'!||fg[1]
 .OUTPUT~lineout(prefix)
 prefix = '~[7m'~left(6)'   '!||hi[3]'Inverted'!||fg[1]
 .OUTPUT~lineout(prefix)
 prefix = '~[8m'~left(6)'   '!||hi[4]'Concealed'!||fg[1],
          "(Doesn't seem to work in my xterm; might in Windows?)"
 .OUTPUT~lineout(prefix)
 .OUTPUT~lineout(' ')
 .OUTPUT~lineout("Where ~ denotes the ASCII escape character ('1B'x).")
 .OUTPUT~lineout(' ')

exit

/*.--------------------------------------------------------.*/ /*|One might expect to be able to use directory collections|*/ /*|as below instead of array collections, but there is no |*/ /*|way to guarantee that a directory's indices will be |*/ /*|iterated over in a consistent sequence, since directory |*/ /*|objects are not ordered. Oh, well... |*/ /*'--------------------------------------------------------'*/

 fg = .directory~new
 fg[Default]   = '[0m';    fg[DefaultBold] = '[1m'
 fg[Black]     = '[0;30m'; fg[DarkGray]    = '[1;30m'
 fg[Blue]      = '[0;34m'; fg[LightBlue]   = '[1;34m'
 fg[Green]     = '[0;32m'; fg[LightGreen]  = '[1;32m'
 fg[Cyan]      = '[0;36m'; fg[LightCyan]   = '[1;36m'
 fg[Red]       = '[0;31m'; fg[LightRed]    = '[1;31m'
 fg[Purple]    = '[0;35m'; fg[LightPurple] = '[1;35m'
 fg[Brown]     = '[0;33m'; fg[Yellow]      = '[1;33m'
 fg[LightGray] = '[0;37m'; fg[White]       = '[1;37m'
 bg = .directory~new;      hi = .directory~new
 bg[Black]     = '[0;40m'; hi[Underlined]  = '[4m'
 bg[Blue]      = '[0;44m'; hi[Blinking]    = '[5m'
 bg[Green]     = '[0;42m'; hi[Inverted]    = '[7m'
 bg[Cyan]      = '[0;46m'; hi[Concealed]   = '[8m'
 bg[Red]       = '[0;41m'
 bg[Purple]    = '[0;45m'
 bg[Brown]     = '[0;43m'
 bg[LightGray] = '[0;47m'

usage: procedure

 trace normal
 if arg(1) = '-h',
  | arg(1) = '-?',
  | arg(1) = '--help'
 then
   do
     line = '/*|'
     say
     do l = 3 by 1 while line~left(3) = '/*|'
       line = sourceline(l)
       parse var line . '/*|' text '|*/' .
       .OUTPUT~lineout(text)
     end
     say
     exit 0
   end

return </lang> This is what the output looks like:

--Leslie 23:10, 23 September 2012 (UTC)

Tcl

This only works on Unix terminals as it delegates to the system tput command. <lang tcl># Utility interfaces to the low-level command proc capability cap {expr {![catch {exec tput -S << $cap}]}} proc colorterm {} {expr {[capability setaf] && [capability setab]}} proc tput args {exec tput -S << $args >/dev/tty} array set color {black 0 red 1 green 2 yellow 3 blue 4 magenta 5 cyan 6 white 7} proc foreground x {exec tput -S << "setaf $::color($x)" > /dev/tty} proc background x {exec tput -S << "setab $::color($x)" > /dev/tty} proc reset {} {exec tput sgr0 > /dev/tty}

  1. Demonstration of use

if {[colorterm]} {

   foreground blue
   background yellow
   puts "Color output"
   reset

} else {

   puts "Monochrome only"

}

if {[capability blink]} {

   tput blink
   puts "Blinking output"
   reset

} else {

   puts "Steady only"

}</lang>

TPP

<lang tpp>--color red This is red --color green This is green --color blue This is blue --color cyan This is cyan --color magenta This is magenta --color yellow This is yellow</lang>

UNIX Shell

<lang sh>#!/bin/sh

  1. Check if the terminal supports colour

case $TERM in

 linux)
   ;;
 rxvt)
   ;;
 *)
   echo "HW65000 This application requires a colour terminal" >&2
   exit 252    #ERLHW incompatible hardware
   ;;

esac

  1. Coloured text

tput setaf 1 #red echo "Red" tput setaf 4 #blue echo "Blue" tput setaf 3 # yellow echo "Yellow"

  1. Blinking

tput setab 1 # red background tput setaf 3 # yellow foreground

  1. tput blink # enable blinking (but does not work on some terminals)

echo "Flashing text"

tput sgr0 # reset everything before exiting</lang>

XPL0

Device 6 is similar to the standard console output device 0, but it supports color. When light colors are used for background (in a text rather than graphic display mode) they are displayed as standard (dim) colors and the foreground color flashes. A BIOS call (int 10h, func 10h, sub 03h) can be used to disable flashing and enable bright backgrounds.

It's possible to detect monochrome displays with a BIOS call, but monochrome is so ancient it's not worth demonstrating. Actually the older 16-bit versions of the language made it easy to detect monochrome using the Equip(ment) intrinsic, but the newer 32-bit version doesn't provide the Equip intrinsic.

Of course these features are provided by the hardware of IBM-compatible PCs and by simulators, such as DOSBox, on other computers.

<lang XPL0>code ChOut=8, Attrib=69; def Black, Blue, Green, Cyan, Red, Magenta, Brown, White, \attribute colors

   Gray, LBlue, LGreen, LCyan, LRed, LMagenta, Yellow, BWhite; \EGA palette

[ChOut(6,^C); \default white on black background Attrib(Red<<4+White); \white on red ChOut(6,^o); Attrib(Green<<4+Red); \red on green ChOut(6,^l); Attrib(Blue<<4+LGreen); \light green on blue ChOut(6,^o); Attrib(LRed<<4+White); \flashing white on (standard/dim) red ChOut(6,^u); Attrib(Cyan<<4+Black); \black on cyan ChOut(6,^r); ]</lang>

ZX Spectrum Basic

The ZX Spectrum will always output colour. However if the television is black and white, these will show as various levels of luminence corresponding to the numerical colour value. <lang zxbasic>10 FOR l=0 TO 7 20 READ c$: REM get our text for display 30 INK l: REM set the text colour 40 PRINT c$ 50 NEXT l 60 PAPER 2: REM red background 70 INK 6: REM yellow forground 80 FLASH 1: REM activate flashing 90 PRINT "Flashing!": REM this will flash red and yellow (alternating inverse) 100 PAPER 7: INK 0: FLASH 0: REM normalize colours before exit 110 STOP

900 DATA "Black","Blue","Red","Magenta","Green","Cyan","Yellow","White"</lang>