Improve escaping syntax

`#` is now a general escaping character:

- `#[0-9a-fA-F]` changes color
- `##` and `#^` produces literal `#` and `^` respectively
- A `#` not followed by characters above produces a normal `#`

Examples:

- `^3` produces `→`
- `#^3` produces `^3`
- `##^3` produces `#→`
- `###^3` produces `#^3`
- `####^3` produces `##→`
- `^k` and `#^k` both produce `^k` (`^k` is not a valid arrow sequence)
- `##^k` and `###^k` both produce `#^k`
- `####^k` produces `##^k`
- `#1` changes color
- `##1` produces `#1`
- `###1` produces `#`, then changes color
- `####1` produces `##1`
- `#k` and `##k` both produce `#k` (`k` is not a hex digit)
- `##` produces `#`
- `###` and `####` both produce `##`
This commit is contained in:
syimyuzya 2021-12-06 15:58:25 +08:00
parent 65c86c8a9c
commit 763733bf52
2 changed files with 37 additions and 24 deletions

View File

@ -22,7 +22,11 @@ That said, there are some basic text formatting options:
Writing "^" followed by a letter "a" through "h" will produce double-wide versions of these arrows, in the same order. These wide arrows occupy 0x89 to 0x91 in the character set. Writing "^" followed by a letter "a" through "h" will produce double-wide versions of these arrows, in the same order. These wide arrows occupy 0x89 to 0x91 in the character set.
* A color may be specified in the sign text by using "#" followed by a single hexadcimal digit (0-9 or a-f). These colors come from the standard Linux/IRC/CGA color set, and are shown in the sign's formspec. Any color change will remain in effect until changed again, or until the next line break. Any number of color changes in any arbitrary arrangement is allowed. To write "#" on a sign, write "##". To write a "^" on a sign, wirte "#^"
* A color may be specified in the sign text by using "#" followed by a single hexadcimal digit (0-9 or a-f). These colors come from the standard Linux/IRC/CGA color set, and are shown in the sign's formspec. Any color change will remain in effect until changed again, or until the next line break. Any number of color changes in any arbitrary arrangement is allowed.
To write "#" on a sign, write "##".
* Most writable signs can display double-wide text by flipping a switch in the sign's formspec. * Most writable signs can display double-wide text by flipping a switch in the sign's formspec.

55
api.lua
View File

@ -513,31 +513,37 @@ local function make_line_texture(line, lineno, pos, line_width, line_height, cwi
for word_i, word in ipairs(line) do for word_i, word in ipairs(line) do
local chars = { } local chars = { }
local ch_offs = 0 local ch_offs = 0
word = string.gsub(word, "%^[12345678abcdefgh]", {
["^1"] = string.char(0x81),
["^2"] = string.char(0x82),
["^3"] = string.char(0x83),
["^4"] = string.char(0x84),
["^5"] = string.char(0x85),
["^6"] = string.char(0x86),
["^7"] = string.char(0x87),
["^8"] = string.char(0x88),
["^a"] = string.char(0x8a),
["^b"] = string.char(0x8b),
["^c"] = string.char(0x8c),
["^d"] = string.char(0x8d),
["^e"] = string.char(0x8e),
["^f"] = string.char(0x8f),
["^g"] = string.char(0x90),
["^h"] = string.char(0x91)
})
local word_l = #word local word_l = #word
local i = 1 local i = 1
local escape = 0
while i <= word_l do while i <= word_l do
local wide_type, wide_c = string.match(word:sub(i), "^&#([xu])(%x+);") local wide_type, wide_c = string.match(word:sub(i), "^&#([xu])(%x+);")
local c = word:sub(i, i) local c = word:sub(i, i)
local c2 = word:sub(i+1, i+1) local c2 = word:sub(i+1, i+1)
if escape > 0 then escape = escape - 1 end
if c == "^" and escape == 0 and c2:find("[1-8a-h]") then
c = ({
["1"] = string.char(0x81),
["2"] = string.char(0x82),
["3"] = string.char(0x83),
["4"] = string.char(0x84),
["5"] = string.char(0x85),
["6"] = string.char(0x86),
["7"] = string.char(0x87),
["8"] = string.char(0x88),
["a"] = string.char(0x8a),
["b"] = string.char(0x8b),
["c"] = string.char(0x8c),
["d"] = string.char(0x8d),
["e"] = string.char(0x8e),
["f"] = string.char(0x8f),
["g"] = string.char(0x90),
["h"] = string.char(0x91)
})[c2]
i = i + 1
end
local wide_skip = 0 local wide_skip = 0
if force_unicode_font then if force_unicode_font then
if wide_c then if wide_c then
@ -562,11 +568,12 @@ local function make_line_texture(line, lineno, pos, line_width, line_height, cwi
wide_skip = #wide_c + 3 wide_skip = #wide_c + 3
end end
if c == "#" and c2 ~= "#" then if c == "#" and escape == 0 and c2:find("[0-9A-Fa-f#^]") then
local cc = tonumber(c2, 16) if c2 == "#" or c2 == "^" then
if cc then escape = 2
else
i = i + 1 i = i + 1
cur_color = cc cur_color = tonumber(c2, 16)
end end
elseif wide_c then elseif wide_c then
local w, code local w, code
@ -754,7 +761,9 @@ local function make_infotext(text)
local lines = signs_lib.split_lines_and_words(text) or {} local lines = signs_lib.split_lines_and_words(text) or {}
local lines2 = { } local lines2 = { }
for _, line in ipairs(lines) do for _, line in ipairs(lines) do
table.insert(lines2, (table.concat(line, " "):gsub("#[0-9a-fA-F]", ""):gsub("##", "#"))) table.insert(lines2, (table.concat(line, " "):gsub("#[0-9a-fA-F#^]", function (s)
return s:sub(2):find("[#^]") and s:sub(2) or ""
end)))
end end
return table.concat(lines2, "\n") return table.concat(lines2, "\n")
end end