← 都来码 / Dolaima← 例程索引r/tty/demo_tty.r原文

r/tty/demo_tty.r · 11207 字节 · 下载原文

#include "../../../Lib/r/vml_ui.r"

# demo_tty.r —— **第 2 层:彩色控制台**

# demo_tty.r -- **layer 2: color console**

#

# 这一层解决的问题是「**在一个字符界面上做版面**」:清屏、把光标挪到第几行第几列、

# The problem this layer solves is "**laying out a character display**": clear the screen, move the cursor to a given row and column,

# 设前景/背景色。老 DOS 程序(菜单、表格、状态栏)全靠这几个原语拼出来。

# set foreground/background colors. Old DOS programs (menus, tables, status bars) were built entirely from these primitives.

#

# R 这一层**没有 conio/crt 绑定**(`Lib/r/console.r` 那几个 `console_*` 是文档性存根),

# R has **no conio/crt binding** at this layer (the `console_*` entries in `Lib/r/console.r` are documentary stubs),

# 所以这里**直接输出 ANSI 转义序列** —— 那正是"支持彩色的控制台程序":

# so this file **emits ANSI escape sequences directly** -- which is exactly a "console program with color support":

#

#     清屏        ESC [ 2 J          ESC [ H

#     clear screen        ESC [ 2 J          ESC [ H

#     定位光标    ESC [ <行> ; <列> H

#     position cursor     ESC [ <row> ; <col> H

#     前景/背景   ESC [ 3x m / 4x m / 9x m / 10x m,256 色 38;5;N,真彩 38;2;r;g;b

#     foreground/background  ESC [ 3x m / 4x m / 9x m / 10x m, 256 color 38;5;N, true color 38;2;r;g;b

#     复位        ESC [ 0 m

#     reset        ESC [ 0 m

#

# ## ⚠ 本前端的两条限制(写 demo 时避开)

# ## ⚠ Two limitations of this frontend (avoid them when writing a demo)

#

#   · **`cat` 只打印第一个实参** —— `cat("\x1b[31m", " 红 ")` 只会打出转义。

#   · **`cat` prints only the first argument** -- `cat("\x1b[31m", " red ")` prints only the escape.

#     (`Examples/r/catch.r` 的文件头记着同一条。)所以**一个 `cat` 恰好一个实参**。

#     (The header of `Examples/r/catch.r` notes the same thing.) So **one `cat` has exactly one argument**.

#   · **没有 `paste`**(`未定义的函数 'func_paste'`)⇒ 数字没法拼进字符串里,

#   · **There is no `paste`** ("undefined function 'func_paste'") => numbers cannot be joined into a string,

#     坐标只能写成字面量。

#     so coordinates can only be written as literals.

#   · `\x1b` 在**字符串字面量里是支持的**,所以可以内联 ESC(本前端不认 `0x` 开头的

#   · `\x1b` **is supported inside string literals**, so ESC can be inlined (this frontend does not accept integers

#     整数,颜色要写负数十进制 —— 那是绘图那一层的规矩,这里用不上)。

#     starting with `0x`; colors must be negative decimals -- that is the drawing layer's rule and is not needed here).

#

# ## 在哪儿能看到什么

# ## What you can see where

#

# · **真终端**(`vmlcli … | cat -v`):整套转义都生效。

# · **A real terminal** (`vmlcli ... | cat -v`): the whole escape set takes effect.

# · **手机"命令行"页**:那一层把 stdout 里的 ANSI 转成仓库统一的 `«»` 中间格式

# · **The phone's "command line" page**: that layer turns ANSI on stdout into the repo's unified `«»` intermediate format

#   (`UI/Shared/AnsiMarkup.cs`),**只认 SGR(颜色/样式)**;光标定位(`ESC[…H`)

#   (`UI/Shared/AnsiMarkup.cs`) and **understands only SGR (color/style)**; cursor positioning (`ESC[...H`)

#   与清屏(`ESC[2J`)会被**吃掉** —— 这是刻意的有限子集(见

#   and clearing the screen (`ESC[2J`) are **eaten** -- a deliberately limited subset (see

#   `Examples/c/ansi_colors.c` 的说明)。所以每行末尾都补了换行,

#   the notes in `Examples/c/ansi_colors.c`). So every line ends with a newline,

#   定位被吃掉时输出仍然一行一句、读得通。

#   and when positioning is eaten the output is still one sentence per line and readable.

#

# 跑法:命令行页输入  vml run examples/r/demo_tty.r

# How to run: type this into the command-line page:  vml run examples/r/demo_tty.r


# ── 开场:清屏 + 回左上角 ───────────────────────────────────────

# -- Opening: clear the screen + go back to the top left --

lang <- ui_scr_get_language()

cat("\x1b[2J")
cat("\x1b[H")

# ── 标题条:蓝底白字(ESC[44;97m)──────────────────────────────

# -- Title bar: white on blue (ESC[44;97m) --

cat("\x1b[1;1H")
cat("\x1b[44;97m")
if (lang == 0) cat("  demo_tty (R) —— 彩色控制台 / ANSI 转义序列               ") else cat("  demo_tty (R) -- color console / ANSI escapes               ")
cat("\x1b[0m")
cat("\n")

cat("\x1b[2;1H")
cat("\x1b[90m")
if (lang == 0) cat("清屏 ESC[2J   定位 ESC[r;cH   颜色 ESC[3xm / ESC[4xm   复位 ESC[0m") else cat("clear ESC[2J   cursor ESC[r;cH   color ESC[3xm / ESC[4xm   reset ESC[0m")
cat("\x1b[0m")
cat("\n")

# ── 标准 8 色前景(30–37)──────────────────────────────────────

# -- The standard 8 foreground colors (30-37) --

cat("\x1b[4;1H")
cat("\x1b[1;37m")
if (lang == 0) cat("标准 8 色前景:") else cat("Standard 8 foreground colors:")
cat("\x1b[0m")
cat("\n")

cat("\x1b[5;1H")
cat("\x1b[30m")
if (lang == 0) cat(" 30 黑 ") else cat(" 30 black ")
cat("\x1b[0m")
cat("\x1b[31m")
if (lang == 0) cat(" 31 红 ") else cat(" 31 red ")
cat("\x1b[0m")
cat("\x1b[32m")
if (lang == 0) cat(" 32 绿 ") else cat(" 32 green ")
cat("\x1b[0m")
cat("\x1b[33m")
if (lang == 0) cat(" 33 黄 ") else cat(" 33 yellow ")
cat("\x1b[0m")
cat("\x1b[34m")
if (lang == 0) cat(" 34 蓝 ") else cat(" 34 blue ")
cat("\x1b[0m")
cat("\x1b[35m")
if (lang == 0) cat(" 35 品红 ") else cat(" 35 magenta ")
cat("\x1b[0m")
cat("\x1b[36m")
if (lang == 0) cat(" 36 青 ") else cat(" 36 cyan ")
cat("\x1b[0m")
cat("\x1b[37m")
if (lang == 0) cat(" 37 白 ") else cat(" 37 white ")
cat("\x1b[0m")
cat("\n")

# ── 亮色前景(90–97)────────────────────────────────────────────

# -- Bright foreground colors (90-97) --

cat("\x1b[6;1H")
cat("\x1b[90m")
if (lang == 0) cat(" 90 亮黑(灰) ") else cat(" 90 gray ")
cat("\x1b[0m")
cat("\x1b[91m")
if (lang == 0) cat(" 91 亮红 ") else cat(" 91 bright red ")
cat("\x1b[0m")
cat("\x1b[92m")
if (lang == 0) cat(" 92 亮绿 ") else cat(" 92 bright green ")
cat("\x1b[0m")
cat("\x1b[93m")
if (lang == 0) cat(" 93 亮黄 ") else cat(" 93 bright yellow ")
cat("\x1b[0m")
cat("\x1b[94m")
if (lang == 0) cat(" 94 亮蓝 ") else cat(" 94 bright blue ")
cat("\x1b[0m")
cat("\x1b[95m")
if (lang == 0) cat(" 95 亮品红 ") else cat(" 95 bright magenta ")
cat("\x1b[0m")
cat("\x1b[96m")
if (lang == 0) cat(" 96 亮青 ") else cat(" 96 bright cyan ")
cat("\x1b[0m")
cat("\x1b[97m")
if (lang == 0) cat(" 97 亮白 ") else cat(" 97 bright white ")
cat("\x1b[0m")
cat("\n")

# ── 背景色(40–47 / 100–107)───────────────────────────────────

# -- Background colors (40-47 / 100-107) --

cat("\x1b[8;1H")
cat("\x1b[1;37m")
if (lang == 0) cat("背景色:") else cat("Background colors:")
cat("\x1b[0m")
cat("\n")

cat("\x1b[9;1H")
cat("\x1b[41m")
if (lang == 0) cat(" 红底 ") else cat(" red bg ")
cat("\x1b[0m")
cat("\x1b[42m")
if (lang == 0) cat(" 绿底 ") else cat(" green bg ")
cat("\x1b[0m")
cat("\x1b[44m")
if (lang == 0) cat(" 蓝底 ") else cat(" blue bg ")
cat("\x1b[0m")
cat("\x1b[46m")
if (lang == 0) cat(" 青底 ") else cat(" cyan bg ")
cat("\x1b[0m")
cat("\x1b[103m")
if (lang == 0) cat(" 亮黄底 ") else cat(" bright yellow bg ")
cat("\x1b[0m")
cat("\x1b[105m")
if (lang == 0) cat(" 亮品红底 ") else cat(" bright magenta bg ")
cat("\x1b[0m")
cat("\n")

# ── 样式(1 粗 / 2 暗 / 3 斜 / 4 下划线 / 9 删除线)─────────────

# -- Styles (1 bold / 2 dim / 3 italic / 4 underline / 9 strikethrough) --

cat("\x1b[11;1H")
cat("\x1b[1;37m")
if (lang == 0) cat("样式:") else cat("Styles:")
cat("\x1b[0m")
cat("\x1b[1m")
if (lang == 0) cat(" 粗体 ") else cat(" bold ")
cat("\x1b[0m")
cat("\x1b[2m")
if (lang == 0) cat(" 暗淡 ") else cat(" dim ")
cat("\x1b[0m")
cat("\x1b[3m")
if (lang == 0) cat(" 斜体 ") else cat(" italic ")
cat("\x1b[0m")
cat("\x1b[4m")
if (lang == 0) cat(" 下划线 ") else cat(" underline ")
cat("\x1b[0m")
cat("\x1b[9m")
if (lang == 0) cat(" 删除线 ") else cat(" strike ")
cat("\x1b[0m")
cat("\n")

# ── 256 色(38;5;N)与真彩(38;2;r;g;b)─────────────────────────

# -- 256 colors (38;5;N) and true color (38;2;r;g;b) --

cat("\x1b[13;1H")
cat("\x1b[1;37m")
if (lang == 0) cat("256 色 / 真彩:") else cat("256 colors / truecolor:")
cat("\x1b[0m")
cat("\x1b[38;5;208m")
if (lang == 0) cat(" 256-208 橙 ") else cat(" 256-208 orange ")
cat("\x1b[0m")
cat("\x1b[38;5;46m")
if (lang == 0) cat(" 256-46 亮绿 ") else cat(" 256-46 bright green ")
cat("\x1b[0m")
cat("\x1b[38;2;255;128;0m")
if (lang == 0) cat(" 真彩橙 ") else cat(" truecolor orange ")
cat("\x1b[0m")
cat("\x1b[48;2;60;0;90m")
if (lang == 0) cat(" 真彩深紫底 ") else cat(" truecolor deep purple bg ")
cat("\x1b[0m")
cat("\n")

# ── 循环画一条色带(12 格,颜色在 8 档里循环)──────────────────

# -- Draw a color band in a loop (12 cells, colors cycling through 8 steps) --

# 「算出来的」那一格:取模 + 分支挑字面量色码(数字转不进字符串,见文件头)。

# The "computed" cell: modulo plus a branch picking a literal color code (digits cannot be joined into a string, see the file header).

cat("\x1b[16;1H")
cat("\x1b[1;37m")
if (lang == 0) cat("循环画 12 格色带:") else cat("Draw a 12-cell color band in a loop:")
cat("\x1b[0m")
cat("\n")

cat("\x1b[17;1H")
i <- 0
while (i < 12) {
  k <- i %% 8
  if (k == 0) {
    cat("\x1b[41m")
  }
  if (k == 1) {
    cat("\x1b[42m")
  }
  if (k == 2) {
    cat("\x1b[43m")
  }
  if (k == 3) {
    cat("\x1b[44m")
  }
  if (k == 4) {
    cat("\x1b[45m")
  }
  if (k == 5) {
    cat("\x1b[46m")
  }
  if (k == 6) {
    cat("\x1b[47m")
  }
  if (k == 7) {
    cat("\x1b[100m")
  }
  cat("   ")
  cat("\x1b[0m")
  i <- i + 1
}
cat("\n")

# ── 收尾:复位颜色 + 定位到第 20 行写结束语 ─────────────────────

# -- Wrap-up: reset the colors + position to row 20 for the closing line --

cat("\x1b[0m")
cat("\x1b[20;1H")
cat("\x1b[1;32m")
if (lang == 0) cat("demo_tty 结束 —— 没有按键等待,画完即退出。") else cat("demo_tty done -- no key wait, draws and exits.")
cat("\x1b[0m")
cat("\n")