Terminal control/Unicode output: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Phix}}: syntax coloured, made p2js compatible)
Line 438: Line 438:


The following (grubby low-level details are hidden away in) builtins/unicode_console.e which is now included in the standard distribution:
The following (grubby low-level details are hidden away in) builtins/unicode_console.e which is now included in the standard distribution:
<lang Phix>include builtins\cffi.e
<!--<lang Phix>(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
constant tGSH = """
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">cffi</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
HANDLE WINAPI GetStdHandle(
<span style="color: #008080;">constant</span> <span style="color: #000000;">tGSH</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
_In_ DWORD nStdHandle
HANDLE WINAPI GetStdHandle(
);
_In_ DWORD nStdHandle
""",
);
tSCOCP = """
"""</span><span style="color: #0000FF;">,</span>
BOOL WINAPI SetConsoleOutputCP(
<span style="color: #000000;">tSCOCP</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
_In_ UINT wCodePageID
BOOL WINAPI SetConsoleOutputCP(
);
_In_ UINT wCodePageID
""",
);
STD_OUTPUT_HANDLE = -11,
"""</span><span style="color: #0000FF;">,</span>
CP_UTF8 = 65001,
<span style="color: #000000;">STD_OUTPUT_HANDLE</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span>
envset = {"LANG","LC_ALL","LC_CTYPE"}
<span style="color: #000000;">CP_UTF8</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">65001</span><span style="color: #0000FF;">,</span>

<span style="color: #000000;">envset</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"LANG"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"LC_ALL"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"LC_CTYPE"</span><span style="color: #0000FF;">}</span>
atom k32 = NULL, xGetStdHandle, hConsole, xSetConsoleOutputCP

<span style="color: #004080;">atom</span> <span style="color: #000000;">k32</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">xGetStdHandle</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hConsole</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">xSetConsoleOutputCP</span>
global function unicode_console()
-- initialises the windows console for unicode, and
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #000000;">unicode_console</span><span style="color: #0000FF;">()</span>
-- returns true if unicode is supported, else false.
<span style="color: #000080;font-style:italic;">-- initialises the windows console for unicode, and
bool res = false
-- returns true if unicode is supported, else false.</span>
if platform()=WINDOWS then
<span style="color: #004080;">bool</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
if k32=NULL then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">WINDOWS</span> <span style="color: #008080;">then</span>
puts(1,"") -- force console to exist
<span style="color: #008080;">if</span> <span style="color: #000000;">k32</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
k32 = open_dll("kernel32.dll")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- force console to exist</span>
xGetStdHandle = define_cffi_func(k32,tGSH)
<span style="color: #000000;">k32</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">open_dll</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"kernel32.dll"</span><span style="color: #0000FF;">)</span>
hConsole = c_func(xGetStdHandle,{STD_OUTPUT_HANDLE})
<span style="color: #000000;">xGetStdHandle</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">define_cffi_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k32</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tGSH</span><span style="color: #0000FF;">)</span>
xSetConsoleOutputCP = define_cffi_func(k32,tSCOCP)
<span style="color: #000000;">hConsole</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xGetStdHandle</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">STD_OUTPUT_HANDLE</span><span style="color: #0000FF;">})</span>
end if
<span style="color: #000000;">xSetConsoleOutputCP</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">define_cffi_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k32</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tSCOCP</span><span style="color: #0000FF;">)</span>
-- following is equivalent to running "chcp 65001":
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res = c_func(xSetConsoleOutputCP,{CP_UTF8})
<span style="color: #000080;font-style:italic;">-- following is equivalent to running "chcp 65001":</span>
else -- LINUX
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">c_func</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xSetConsoleOutputCP</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">CP_UTF8</span><span style="color: #0000FF;">})</span>
for i=1 to length(envset) do
<span style="color: #008080;">else</span> <span style="color: #000080;font-style:italic;">-- LINUX</span>
if match("UTF",upper(getenv(envset[i])))!=0 then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">envset</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
res = true
<span style="color: #008080;">if</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"UTF"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">getenv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">envset</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])))!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
exit
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
end if
<span style="color: #008080;">exit</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function</lang>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</lang>-->
Which can be used like this:
Which can be used like this:
<lang Phix>include builtins\unicode_console.e
<!--<lang Phix>(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>

<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">unicode_console</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
-- pi, root, lambda, sigma, delta
constant prlsd = "\u03C0\u221A\u03BB\u03A3\u25B3"
<span style="color: #000080;font-style:italic;">-- pi, root, lambda, sigma, delta</span>

<span style="color: #008080;">constant</span> <span style="color: #000000;">prlsd</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"\u03C0\u221A\u03BB\u03A3\u25B3"</span>
if unicode_console() then
puts(1,prlsd&"\n")
<span style="color: #008080;">if</span> <span style="color: #000000;">unicode_console</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">then</span>
else
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prlsd</span><span style="color: #0000FF;">&</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
puts(1,"unicode is not supported\n")
<span style="color: #008080;">else</span>
end if</lang>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"unicode is not supported\n"</span><span style="color: #0000FF;">)</span>
Note that delta does not work on Windows (see talk page) but the others do, and all five work on linux.
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</lang>-->
Note that delta does not work on Windows (see talk page) but the others do, and all five work on linux and under pwa/p2js.


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==

Revision as of 09:24, 15 April 2022

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

The task is to check that the terminal supports Unicode output, before outputting a Unicode character. If the terminal supports Unicode, then the terminal should output a Unicode delta (U+25b3). If the terminal does not support Unicode, then an appropriate error should be raised.

Note that it is permissible to use system configuration data to determine terminal capabilities if the system provides such a facility.

Arturo

<lang rebol>canHandleUnicode?: function [][

   any? @[
       if key? env "LC_ALL"    -> contains? lower get env "LC_ALL" "utf-8"
       if key? env "LC_CTYPE"  -> contains? lower get env "LC_CTYPE" "utf-8"
       if key? env "LANG"      -> contains? lower get env "LANG" "utf-8"
   ]

]

if? canHandleUnicode? ->

   print "Terminal handle unicode and U+25B3 is: △"

else ->

   print "Unicode is not supported on this terminal"</lang>
Output:
Terminal handle unicode and U+25B3 is: △

AutoHotkey

<lang autohotkey>DllCall("AllocConsole") hConsole:=DllCall("GetConsoleWindow","UPtr") Stdout:=FileOpen(DllCall("GetStdHandle", "int", -11, "ptr"), "h `n") Stdin:=FileOpen(DllCall("GetStdHandle", "int", -10, "ptr"), "h `n")

Full Unicode-support font needed

e:=SetConsoleOutputCP(65001) if (e && A_IsUnicode) { Print("△ - Unicode delta (U+25b3)") GetPos(x,y) if (x=0 && y=0) ;nothing prints if Non-Unicode font Print("Non-Unicode font") } else Print("Unicode not supported") Pause()

Print(string=""){ global Stdout if (!StrLen(string)) return 1 e:=DllCall("WriteConsole" . ((A_IsUnicode) ? "W" : "A") , "UPtr", Stdout.__Handle , "Str", string , "UInt", strlen(string) , "UInt*", Written , "uint", 0) if (!e) or (ErrorLevel) return 0 ;Failure Stdout.Read(0) return e }

SetConsoleOutputCP(codepage) { e:=DllCall("SetConsoleOutputCP","UInt",codepage) if (!e) or (ErrorLevel) return 0 ;Failure return 1 }

GetPos(ByRef x, ByRef y) { global Stdout VarSetCapacity(struct,22,0) e:=DllCall("GetConsoleScreenBufferInfo","UPtr",Stdout.__Handle,"Ptr",&struct) if (!e) or (ErrorLevel) return 0 ;Failure x:=NumGet(&struct,4,"UShort") y:=NumGet(&struct,6,"UShort") return 1 }

Pause() { RunWait, %comspec% /c pause>NUL }</lang>

AWK

<lang awk>#!/usr/bin/awk -f BEGIN {

 unicodeterm=1   # Assume Unicode support
 if (ENVIRON["LC_ALL"] !~ "UTF") {
   if (ENVIRON["LC_ALL"] != ""
     unicodeterm=0    # LC_ALL is the boss, and it says nay
   else {
     # Check other locale settings if LC_ALL override not set
     if (ENVIRON["LC_CTYPE"] !~ "UTF") {
       if (ENVIRON["LANG"] !~ "UTF")
         unicodeterm=0    # This terminal does not support Unicode
     }        
   }    
 }
 if (unicodeterm) {
     # This terminal supports Unicode
     # We need a Unicode compatible printf, so we source this externally
     # printf might not know \u or \x, so use octal.
     # U+25B3 => UTF-8 342 226 263
     "/usr/bin/printf \\342\\226\\263\\n"
 } else {
     print "HW65001 This program requires a Unicode compatible terminal"|"cat 1>&2"
   exit 252    # Incompatible hardware
 }</lang>

BaCon

LANG environment test borrowed from C solution. <lang freebasic>' Determine if the terminal supports Unicode ' if so display delta, if not display error message LET lc$ = GETENVIRON$("LANG") IF INSTR(LCASE$(lc$), "utf8") != 0 THEN

   PRINT UTF8$(0x25B3)

ELSE

   EPRINT "Sorry, terminal is not testing as unicode ready"

END IF</lang>

BBC BASIC

<lang bbcbasic> VDU 23,22,640;512;8,16,16,128+8 : REM Enable UTF-8 mode

     *FONT Arial Unicode MS,36
     PRINT CHR$(&E2)+CHR$(&96)+CHR$(&B3)</lang>

C

<lang c>

  1. include<stdlib.h>
  2. include<stdio.h>

int main () {

 int i;
 char *str = getenv ("LANG");
 for (i = 0; str[i + 2] != 00; i++)
   {
     if ((str[i] == 'u' && str[i + 1] == 't' && str[i + 2] == 'f')
         || (str[i] == 'U' && str[i + 1] == 'T' && str[i + 2] == 'F'))
       {
         printf
           ("Unicode is supported on this terminal and U+25B3 is : \u25b3");
         i = -1;
         break;
       }
   }
 if (i != -1)
   printf ("Unicode is not supported on this terminal.");
 return 0;

} </lang> Output:

Unicode is supported on this terminal and U+25B3 is : â³

Clojure

<lang clojure> (if-not (empty? (filter #(and (not (nil? %)) (.contains (.toUpperCase %) "UTF"))

 (map #(System/getenv %) ["LANG" "LC_ALL" "LC_CTYPE"]))) 
   "Unicode is supported on this terminal and U+25B3 is : \u25b3"
   "Unicode is not supported on this terminal.")

</lang>

Output:
"Unicode is supported on this terminal and U+25B3 is : △"

Common Lisp

Each implementation has a different "getenv" function, to work with various implementations was created the "my-getenv" function. <lang lisp> (defun my-getenv (name &optional default)

 #+CMU
 (let ((x (assoc name ext:*environment-list*
                 :test #'string=)))
   (if x (cdr x) default))
 #-CMU
 (or
   #+Allegro (sys:getenv name)
   #+CLISP (ext:getenv name)
   #+ECL (si:getenv name)
   #+SBCL (sb-unix::posix-getenv name)
   #+ABCL (getenv name)
   #+LISPWORKS (lispworks:environment-variable name)
   default))

(if (not ( null (remove-if #'null (mapcar #'my-getenv '("LANG" "LC_ALL" "LC_CTYPE")))))

 (format t "Unicode is supported on this terminal and U+25B3 is : ~a~&" (code-char #x25b3))
 (format t "Unicode is not supported on this terminal.~&")
 )

</lang>

Output:
Unicode is supported on this terminal and U+25B3 is : △

Elixir

<lang elixir> if ["LANG", "LC_CTYPE", "LC_ALL"]

    |> Enum.map(&System.get_env/1)
    |> Enum.any?(&(&1 != nil and String.contains?(&1, "UTF")))

do

 IO.puts "This terminal supports Unicode: \x{25b3}"

else

 raise "This terminal does not support Unicode."

end </lang>

FunL

<lang funl>if map( v -> System.getenv(v), ["LC_ALL", "LC_CTYPE", "LANG"]).filter( (!= null) ).exists( ('UTF' in) )

 println( '\u25b3' )

else

 println( 'Unicode not supported' )</lang>

Go

Works with: Ubuntu 16.04

<lang go>package main

import (

   "fmt"
   "os"
   "strings"

)

func main() {

   lang := strings.ToUpper(os.Getenv("LANG"))
   if strings.Contains(lang, "UTF") {
       fmt.Printf("This terminal supports unicode and U+25b3 is : %c\n", '\u25b3')
   } else {
       fmt.Println("This terminal does not support unicode")
   }

}</lang>

Output:
This terminal supports unicode and U+25b3 is : △

Haskell

<lang Haskell>import System.Environment import Data.List import Data.Char import Data.Maybe

main = do

       x <- mapM lookupEnv ["LANG", "LC_ALL", "LC_CTYPE"]
       if any (isInfixOf "UTF". map toUpper) $ catMaybes x 
        then putStrLn "UTF supported: \x25b3"
        else putStrLn "UTF not supported"

</lang> Output:

UTF supported: △

jq

Works with: jq version >1.4

The jq "env" function is required to inspect environment variables. It is NOT available in jq version 1.4.

Note also that "The values of locale categories are determined by a precedence order ..." -- http://pubs.opengroup.org/onlinepubs/007908799/xbd/envvar.html

"has_unicode_support" therefore cannot simply test whether one of the variables LC_ALL, LC_TYPE and LANG contains the string UTF. <lang jq>def has_unicode_support:

 def utf: if . == null then false else contains("UTF") or contains("utf") end;
 env.LC_ALL
 | if utf then true
   elif . != null and . != "" then false
   elif env.LC_CTYPE | utf then true
   else env.LANG | utf
   end ;

def task:

 if has_unicode_support then "\u25b3"
 else error("HW65001 This program requires a Unicode-compatible terminal")
 end ;

task</lang>

Output:
$ jq -M -r -n -f Terminal_control.jq
jq: error: HW65001 This program requires a Unicode-compatible terminal
# In a galaxy not far away:
$ jq -M -r -n -f Terminal_control.jq
△

Jsish

Detection based on code from other entries, looking in LC_ALL, LC_CTYPE, LANG for hints of 'UTF'. <lang javascript>/* Terminal Control/Unicode, in Jsish */

var utf = false; for (var envar of ['LC_ALL', 'LC_CTYPE', 'LANG']) {

   var val = Util.getenv(envar);
   if (val && (val.search(/utf/i) > 0)) {
       utf = true;
       break;
   }

}

puts((utf) ? '\u25b3' : 'Unicode support not detected');

/*

!EXPECTSTART!

!EXPECTEND!

  • /</lang>
Output:
prompt$ jsish --U terminalControlUnicode.jsi
△

Julia

Works with: Linux

<lang Julia> c = '\u25b3'

if ismatch(r"UTF", get(ENV, "LANG", ""))

   println("This output device supports Unicode: ", c)

else

   println("This output device does not support Unicode.")

end </lang>

Output:
This output device supports Unicode: △

Kotlin

Works with: Ubuntu version 14.04

<lang scala>// version 1.1.2

fun main(args: Array<String>) {

   val supportsUnicode = "UTF" in System.getenv("LANG").toUpperCase()
   if (supportsUnicode)
       println("This terminal supports unicode and U+25b3 is : \u25b3")
   else
       println("This terminal does not support unicode")

}</lang>

Output:
This terminal supports unicode and U+25b3 is : △

Lasso

<lang Lasso>local(env_vars = sys_environ -> join('###')) if(#env_vars >> regexp(`(LANG|LC_ALL|LC_CTYPE).*?UTF.*?###`)) => { stdout('UTF supported \u25b3') else stdout('This terminal does not support UTF') }</lang>

UTF supported △

M2000 Interpreter

M2000 Environment has own console (with graphics support) <lang M2000 Interpreter> Module CheckIt {

     If IsWine then Font "DejaVu Sans"
     Cls
     Report format$("\u25B3")
     Keyboard 0x25B3, format$("\u25B3")
     \\ report use kerning
     Report Key$+"T"+Key$
     Keyboard 0x25B3, format$("\u25B3")
     Print Key$;"T";Key$

} Checkit </lang>

Mathematica/Wolfram Language

<lang Mathematica>If[StringMatchQ[$CharacterEncoding, "UTF*"], Print[FromCharacterCode[30000]], Print["UTF-8 capable terminal required"]] ->田</lang>

Mercury

<lang mercury>:- module unicode_output.

- interface.
- import_module io.
- pred main(io::di, io::uo) is det.
- implementation.
- import_module list.
- import_module maybe.
- import_module string.

main(!IO) :-

   list.map_foldl(io.get_environment_var, ["LANG", "LC_ALL", "LC_CTYPE"], EnvValues, !IO),
   ( if
       list.member(EnvValue, EnvValues),
       EnvValue = yes(Lang),
       string.sub_string_search(Lang, "UTF-8", _)
   then
       io.write_string("Unicode is supported on this terminal and U+25B3 is : \u25b3\n", !IO)
   else
       io.write_string("Unicode is not supported on this terminal.\n", !IO)
   ).</lang>

Output:

Unicode is supported on this terminal and U+25B3 is : △

Nemerle

Typically, on a windows system, the output encoding is not UTF-8, so in an actual application it would make more sense to set Console.OutputEncoding than to merely check it. <lang Nemerle>using System.Console;

module UnicodeOut {

   Main() : void
   {
       if (OutputEncoding.ToString() == "System.Text.UTF8Encoding") Write("Δ") 
       else Write("Console encoding may not support Unicode characters.");
   }

}</lang>

Nim

<lang nim>import os, strutils

if "utf" in getEnv("LANG").toLower:

 echo "Unicode is supported on this terminal and U+25B3 is: △"

else:

 echo "Unicode is not supported on this terminal."</lang>

Perl

Much like Raku... <lang perl>die "Terminal can't handle UTF-8"

   unless $ENV{LC_ALL} =~ /utf-8/i or $ENV{LC_CTYPE} =~ /utf-8/i or $ENV{LANG} =~ /utf-8/i;

print "△ \n";</lang>

Phix

Works on both linux and windows.

The following (grubby low-level details are hidden away in) builtins/unicode_console.e which is now included in the standard distribution:

with javascript_semantics
include builtins\cffi.e
constant tGSH = """
HANDLE WINAPI GetStdHandle(
  _In_  DWORD nStdHandle
);
""",
tSCOCP = """
BOOL WINAPI SetConsoleOutputCP(
  _In_  UINT wCodePageID
);
""",		   
STD_OUTPUT_HANDLE = -11,
CP_UTF8 = 65001,
envset = {"LANG","LC_ALL","LC_CTYPE"}
 
atom k32 = NULL, xGetStdHandle, hConsole, xSetConsoleOutputCP
 
global function unicode_console()
-- initialises the windows console for unicode, and
-- returns true if unicode is supported, else false.
    bool res = false
    if platform()=WINDOWS then
        if k32=NULL then
            puts(1,"")  -- force console to exist
            k32 = open_dll("kernel32.dll")
            xGetStdHandle = define_cffi_func(k32,tGSH)
            hConsole = c_func(xGetStdHandle,{STD_OUTPUT_HANDLE})
            xSetConsoleOutputCP = define_cffi_func(k32,tSCOCP)
        end if
        -- following is equivalent to running "chcp 65001":
        res = c_func(xSetConsoleOutputCP,{CP_UTF8})
    else    -- LINUX
        for i=1 to length(envset) do
            if match("UTF",upper(getenv(envset[i])))!=0 then
                res = true
                exit
            end if
        end for
    end if
    return res
end function

Which can be used like this:

with javascript_semantics
include builtins\unicode_console.e

-- pi, root, lambda, sigma, delta
constant prlsd = "\u03C0\u221A\u03BB\u03A3\u25B3"

if unicode_console() then
    puts(1,prlsd&"\n")
else
    puts(1,"unicode is not supported\n")
end if

Note that delta does not work on Windows (see talk page) but the others do, and all five work on linux and under pwa/p2js.

PicoLisp

<lang PicoLisp>(if (sub? "UTF-8" (or (sys "LC_ALL") (sys "LC_CTYPE") (sys "LANG")))

  (prinl (char (hex "25b3")))
  (quit "UTF-8 capable terminal required") )</lang>

Python

<lang Python>import sys

if "UTF-8" in sys.stdout.encoding:

   print("△")

else:

   raise Exception("Terminal can't handle UTF-8")</lang>

R

<lang R>if (any(grepl("UTF", toupper(Sys.getenv(c("LANG", "LC_ALL", "LC_CTYPE")))))) {

       cat("Unicode is supported on this terminal and U+25B3 is : \u25b3\n")

} else {

       cat("Unicode is not supported on this terminal.")

}</lang>

Output:
Unicode is supported on this terminal and U+25B3 is : △

Racket

<lang racket>

  1. lang racket

(displayln

(if (regexp-match? #px"(?i:utf-?8)"
                   (or (getenv "LC_ALL") (getenv "LC_CTYPE") (getenv "LANG")))
  "\u25b3" "No Unicode detected."))

</lang>

Raku

(formerly Perl 6) <lang perl6>die "Terminal can't handle UTF-8"

   unless first(*.defined, %*ENV<LC_ALL LC_CTYPE LANG>) ~~ /:i 'utf-8'/;

say "△";</lang>

Output:

Ruby

<lang ruby>#encoding: UTF-8 # superfluous in Ruby >1.9.3

if ENV.values_at("LC_ALL","LC_CTYPE","LANG").compact.first.include?("UTF-8")

 puts "△"

else

 raise "Terminal can't handle UTF-8"

end </lang>

Scala

Ad hoc in the REPL:

Library: Scala

<lang Scala>scala> println(s"Unicode is supported on this terminal and U+25B3 is : \u25b3")

Unicode is supported on this terminal and U+25B3 is : △</lang>

Seed7

The Seed7 library console.s7i defines STD_CONSOLE, which can used directly, or be assigned to OUT (which is the default output file). STD_CONSOLE supports Unicode under Linux and Windows.

<lang seed7>$ include "seed7_05.s7i";

 include "environment.s7i";
 include "console.s7i";

const proc: main is func

 begin
   if pos(lower(getenv("LANG")), "utf") <> 0 or
      pos(lower(getenv("LC_ALL")), "utf") <> 0 or
      pos(lower(getenv("LC_CTYPE")), "utf") <> 0 then
     writeln(STD_CONSOLE, "Unicode is supported on this terminal and U+25B3 is: △");
   else
     writeln("Unicode is not supported on this terminal.");
   end if;
 end func;</lang>

Sidef

<lang ruby>if (/\bUTF-?8/i ~~ [ENV{"LC_ALL","LC_CTYPE","LANG"}]) {

   say "△"

} else {

   die "Terminal can't handle UTF-8.\n";

}</lang>

Tcl

Tcl configures the standard output channel to use the system encoding by default. The system encoding is formally the encoding for use when communicating with the OS (e.g., for filenames) but is virtually always correlated with the default terminal encoding.<lang tcl># Check if we're using one of the UTF or "unicode" encodings if {[string match utf-* [encoding system]] || [string match *unicode* [encoding system]]} {

   puts "\u25b3"

} else {

   error "terminal does not support unicode (probably)"

}</lang>Note that idiomatic Tcl code would not perform such a check; it would just produce the output which would be translated as best as possible (possibly into the target encoding's placeholder character).

UNIX Shell

This script only checks if the name of the locale contains "UTF-8". This often works because many UTF-8 locales have names like "en_US.UTF-8". This script will fail to recognize a Unicode terminal if:

  • The locale is a UTF-8 locale, but does not have "UTF-8" in its name.
  • The locale uses some other Unicode Transformation Format, such as GB18030.
Works with: Bourne Shell

<lang bash>unicode_tty() {

 # LC_ALL supersedes LC_CTYPE, which supersedes LANG.
 # Set $1 to environment value.
 case y in
 ${LC_ALL:+y})		set -- "$LC_ALL";;
 ${LC_CTYPE:+y})	set -- "$LC_CTYPE";;
 ${LANG:+y})		set -- "$LANG";;
 y)			return 1;;  # Assume "C" locale not UTF-8.
 esac
 # We use 'case' to perform pattern matching against a string.
 case "$1" in
 *UTF-8*)		return 0;;
 *)			return 1;;
 esac

}

if unicode_tty; then

 # printf might not know \u or \x, so use octal.
 # U+25B3 => UTF-8 342 226 263
 printf "\342\226\263\n"

else

 echo "HW65001 This program requires a Unicode compatible terminal" >&2
 exit 252    # Incompatible hardware

fi</lang>

The terminal might support UTF-8, but its fonts might not have every Unicode character. Unless they have U+25B3, the output will not look correct. Greek letters like U+25B3 tend to be common, but some fonts might not have Chinese characters (for example), and almost no fonts have dead scripts such as Cuneiform.

Wren

Translation of: C

As there is currently no way to obtain this information via Wren CLI, we instead embed a Wren script in a C application and ask the host program to get it for us. <lang ecmascript>/* terminal_control_unicode_output.wren */

class C {

   foreign static isUnicodeSupported

}

if (C.isUnicodeSupported) {

   System.print("Unicode is supported on this terminal and U+25B3 is : \u25b3")

} else {

   System.print("Unicode is not supported on this terminal.")

}</lang>
We now embed this Wren script in the following C program, compile and run it. <lang c>#include <stdlib.h>

  1. include <stdio.h>
  2. include <string.h>
  3. include "wren.h"

void C_isUnicodeSupported(WrenVM* vm) {

   char *str = getenv("LANG");
   bool us = false;
   int i;
   for (i = 0; str[i + 2] != 0; i++) {
       if ((str[i] == 'u' && str[i + 1] == 't' && str[i + 2] == 'f') ||
           (str[i] == 'U' && str[i + 1] == 'T' && str[i + 2] == 'F')) {
           us = true;
           break;
       }
   }
   wrenSetSlotBool(vm, 0, us);

}

WrenForeignMethodFn bindForeignMethod(

   WrenVM* vm,
   const char* module,
   const char* className,
   bool isStatic,
   const char* signature) {
   if (strcmp(module, "main") == 0) {
       if (strcmp(className, "C") == 0) {
           if (isStatic && strcmp(signature, "isUnicodeSupported") == 0) {
               return C_isUnicodeSupported;
           }
       }
   }
   return NULL;

}

static void writeFn(WrenVM* vm, const char* text) {

   printf("%s", text);

}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {

   switch (errorType) {
       case WREN_ERROR_COMPILE:
           printf("[%s line %d] [Error] %s\n", module, line, msg);
           break;
       case WREN_ERROR_STACK_TRACE:
           printf("[%s line %d] in %s\n", module, line, msg);
           break;
       case WREN_ERROR_RUNTIME:
           printf("[Runtime Error] %s\n", msg);
           break;
   }

}

char *readFile(const char *fileName) {

   FILE *f = fopen(fileName, "r");
   fseek(f, 0, SEEK_END);
   long fsize = ftell(f);
   rewind(f);
   char *script = malloc(fsize + 1);
   fread(script, 1, fsize, f);
   fclose(f);
   script[fsize] = 0;
   return script;

}

int main() {

   WrenConfiguration config;
   wrenInitConfiguration(&config);
   config.writeFn = &writeFn;
   config.errorFn = &errorFn;
   config.bindForeignMethodFn = &bindForeignMethod;
   WrenVM* vm = wrenNewVM(&config);
   const char* module = "main";
   const char* fileName = "terminal_control_unicode_output.wren";
   char *script = readFile(fileName);
   WrenInterpretResult result = wrenInterpret(vm, module, script);
   switch (result) {
       case WREN_RESULT_COMPILE_ERROR:
           printf("Compile Error!\n");
           break;
       case WREN_RESULT_RUNTIME_ERROR:
           printf("Runtime Error!\n");
           break;
       case WREN_RESULT_SUCCESS:
           break;
   }
   wrenFreeVM(vm);
   free(script);
   return 0;

}</lang>

Output:
Unicode is supported on this terminal and U+25B3 is : △

zkl

This code works for Unix/Linux, Windows XP cmd terminals don't support UTF-8. <lang zkl>if(System.isUnix and T("LC_CTYPE","LC_LANG","LANG").apply(System.getenv) .filter().filter("holds","UTF"))

  println("This terminal supports UTF-8 (\U25B3;)");

else println("I have doubts about UTF-8 on this terminal.");</lang>

Output:
This terminal supports UTF-8 (△)

ZX Spectrum Basic

<lang zxbasic>10 REM There is no Unicode delta in ROM 20 REM So we first define a custom character 30 FOR l=0 TO 7 40 READ n 50 POKE USR "d"+l,n 60 NEXT l 70 REM our custom character is a user defined d 80 PRINT CHR$(147): REM this outputs our delta 9500 REM data for our custom delta 9510 DATA 0,0,8,20,34,65,127,0 </lang>