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.
* 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.

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
local chars = { }
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 i = 1
local escape = 0
while i <= word_l do
local wide_type, wide_c = string.match(word:sub(i), "^&#([xu])(%x+);")
local c = word:sub(i, i)
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
if force_unicode_font 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
end
if c == "#" and c2 ~= "#" then
local cc = tonumber(c2, 16)
if cc then
if c == "#" and escape == 0 and c2:find("[0-9A-Fa-f#^]") then
if c2 == "#" or c2 == "^" then
escape = 2
else
i = i + 1
cur_color = cc
cur_color = tonumber(c2, 16)
end
elseif wide_c then
local w, code
@ -754,7 +761,9 @@ local function make_infotext(text)
local lines = signs_lib.split_lines_and_words(text) or {}
local lines2 = { }
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
return table.concat(lines2, "\n")
end