我一直在研究一种格式化程序,它会使用一个长字符串并将其格式化为一系列在某个字符限制范围内断开的行。例如,他吃面包,每8个字符断开,会返回如下内容:
He eats
the
bread
这是因为“他吃”包含7个字符,而“面包”包含9个字符,所以它必须在“the”中断并继续“面包”。
由于之前其他成员的帮助,脚本本身一直运行得非常好。但是,现在我遇到了新的挑战。
我正在使用自由输入框来输入一系列线条。这是一个名为MUSHclient的程序,如果有人熟悉的话。 utils.editbox 会打开一个编辑器文本框,并允许自由格式,并将结果作为字符串返回。例如:
result = utils.editbox("What are you typing?")
将输入的响应保存到result
string
类型。我想正确地设置换行符,但我无法弄清楚如何做到这一点。如果我print(result)
,则返回如下内容:
This is the result of three separate paragraphs.
As you can see, there is a line break between each paragraph.
So the result contains line breaks, or control characters.
现在,我已设法使用以下代码推断各行,但不能推断其间的换行:
for line in result:gmatch("[^%c]+%c?") do
Send(note_wrap(line))
end
我如何推断换行符和文本内容?
修改作为参考,note_wrap
功能如下:
function note_wrap(str, limit, indent, indent1)
indent = indent or ""
indent1 = indent1 or indent
limit = limit or 79
local here = 1-#indent1
local last_color = ''
return indent1..str:gsub("(%s+)()(%S+)()",
function(sp, st, word, fi)
local delta = 0
local color_before_current_word = last_color
word:gsub('()@([@%a])',
function(pos, c)
if c == '@' then
delta = delta + 1
elseif c == 'x' then
delta = delta + 5
last_color = word:sub(pos, pos+4)
else
delta = delta + 2
last_color = word:sub(pos, pos+1)
end
end)
here = here + delta
if fi-here > limit then
here = st - #indent + delta
return "\n"..indent..color_before_current_word..word
end
end)
end
此代码的原因是能够 @rHe吃@ x123面包,忽略颜色代码(由@< letter>或@ x< digits>表示)并返回上述结果:
He eats
the
bread
但插入颜色代码,然后返回:
@rHe eats
@x123the
bread
如果可以修改此项以识别新行并添加实际的新行,那将非常棒。
编辑2 尝试了保罗的解决方案,并没有按照我的要求去做。我可能不够清楚,所以我会尝试在此编辑中清除它。
当我输入自由格式框时,我希望信息完全按原样显示,但格式化为正确破坏并保持输入的换行符。例如,如果我在自由格式框中写这个:
Mary had a little lamb, little lamb, little lamb
Mary had a little lamb
It's fleece was white as snow
使用Paul的代码,并将字符串设置为79,我得到:
Mary had a little lamb, little lamb, little lamb
Mary had a little lamb
It's fleece was white as snow
这不是我想要的。我希望它能像它写的那样返回它,并根据需要打破它。因此,如果我有一个20个字符的限制,它会返回:
Mary had a little
lamb, little lamb,
little lamb
Mary had a little
lamb
It's fleece was
white as snow
如果我添加了手动换行符,我希望它能够尊重这些换行符,所以如果我在第一行之后点击返回两次,那么它在第一行下面也会有换行符。例如,如果我在自由格式框中写这篇文章,我希望它尊重每个新段落和每个正确的换行符。我希望这能解决问题。
答案 0 :(得分:1)
我在我的代码中使用了类似的东西(假设\n
是行分隔符):
local function formatUpToX(s, x, indent)
x = x or 79
indent = indent or ""
local t = {""}
local function cleanse(s) return s:gsub("@x%d%d%d",""):gsub("@r","") end
for prefix, word, suffix, newline in s:gmatch("([ \t]*)(%S*)([ \t]*)(\n?)") do
if #(cleanse(t[#t])) + #prefix + #cleanse(word) > x and #t > 0 then
table.insert(t, word..suffix) -- add new element
else -- add to the last element
t[#t] = t[#t]..prefix..word..suffix
end
if #newline > 0 then table.insert(t, "") end
end
return indent..table.concat(t, "\n"..indent)
end
print(formatUpToX(result, 20))
print(formatUpToX("@rHe eats @x123the bread", 8, " "))
cleanse
函数删除了需要包含在字符串中的任何标记,但不需要计算限制。
对于您的示例,我得到以下输出(使用20
作为第一个片段的限制,8
作为第二个片段的限制:
This is the result
of three separate
paragraphs.
As you can see,
there is a line
break between each
paragraph.
So the result
contains line
breaks, or control
characters.
@rHe eats
@x123the
bread