From 763733bf52dc137a4a3f7cf1f2fe3269e39d519f Mon Sep 17 00:00:00 2001 From: syimyuzya Date: Mon, 6 Dec 2021 15:58:25 +0800 Subject: [PATCH] Improve escaping syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `#` 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 `##` --- README.md | 6 +++++- api.lua | 55 ++++++++++++++++++++++++++++++++----------------------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 97c0062..e710b08 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/api.lua b/api.lua index 690e900..cc20717 100644 --- a/api.lua +++ b/api.lua @@ -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