Total RP 3

Total RP 3

4M Downloads

Restrict line breaks count in Currently/OOC info

Solanya opened this issue ยท 9 comments

commented

Restricting the number of characters is nice and all but people just abuse with line breaks instead. Tooltip display of those fields should crop the field after a certain amount of line breaks (with a nice setting to choose how many line breaks to allow).

"basically strsplit using \n as separator, loop through table of line, concatenate them using \n and then [...] add ... and bail out of the loop"

commented

Kat made a good point : Your current version adds "..." regardless of whether there was too many line breaks or not.

commented

It's early afternoon :(

commented
local function limitLines(input)
    local chunks = { strsplit("\n", input) };
    if(#chunks > MAX_LINES) then
        chunks [MAX_LINES] = chunks [MAX_LINES] .. "..."
    end
    return table.concat(chunks, "\n", 1, math.min(MAX_LINES, #chunks ));
end

Based on her version, seems like it would do the trick (replacing MAX_LINES with a config value set by a slider.

commented

I'd still favour the third argument to strsplit for efficiency reasons; a long string with a bunch of newlines would create a lot of temporary strings after the split and grow the array portion of the table when we're only interested in indices 1 through MAX_LINES.

That said I'm over-optimizing.

commented

Oh, I didn't see you edited your function, my bad.

commented

I couldn't resist. This'll net one temporary string only if the string has too many newlines and no temporary tables. #efficiency #thinkofthememory

local MAX_LINES = 4;

local function limitLines(input)
    local finish, matches = 0, 0;
    repeat
        finish = select(2, string.find(input, "\n", finish + 1));
        matches = matches + 1;
    until not finish or matches >= MAX_LINES

    if not finish then
        return input;
    end

    return string.sub(input, 1, finish - 1) .. "...";
end

---

local test1 = "my\nvery\nannoying\nstring\nwith a lot of\nline\nbreaks";
local test2 = "my short string";
local test3 = "my short string\nwith\ntwo line breaks";
local test4 = "my short string\nwith\nexactly\nthree linebreaks";
local test5 = "my short string\nwith\nexactly\nfour\nlinebreaks";
local test6 = "my short string\nwith\na\ntrailing linebreak\n";

print(limitLines(test1));
print("---");
print(limitLines(test2));
print("---");
print(limitLines(test3));
print("---");
print(limitLines(test4));
print("---");
print(limitLines(test5));
print("---");
print(limitLines(test6));

Output:

my
very
annoying
string...
---
my short string
---
my short string
with
two line breaks
---
my short string
with
exactly
three linebreaks
---
my short string
with
exactly
four...
---
my short string
with
a
trailing linebreak...
commented

Note that some thought should be put into how this interacts with the existing truncation of too-long-fields.

It'd be a bit silly if we ended up with "......" being appended to texts because they were both too long and had too many newlines. So I present this final monstrosity. I also did another pass on optimizing it because I have nothing better to do.

local MAX_LINES = 4;
local MAX_LENGTH = 100;

local function limitText(input)
    -- Loop through the string finding newline characters until we either
    -- reach the end of the string or find enough to break our max line limit.
    local finish, matches = 0, 0;
    repeat
        finish = string.find(input, "\n", finish + 1, true);
        matches = matches + 1;
    until not finish or matches >= MAX_LINES

    -- If we exited because we reached the end of the string then there's
    -- not too many lines, so we just need to limit the total length of the
    -- text. This would likely be the most common case.
    if not finish then
        if #input <= MAX_LENGTH then
            return input;
        end

        return string.sub(input, 1, MAX_LENGTH) .. "...";
    end

    -- Otherwise extract the substring up to the character preceeding the
    -- last matched newline or to the maximum allowable length of the text,
    -- whichever is shorter.
    return string.sub(input, 1, math.min(finish - 1, MAX_LENGTH)) .. "...";
end
-- Input: string.rep("this is a line with words and stuff\n", 6);
-- Output:
--  this is a line with words and stuff
--  this is a line with words and stuff
--  this is a line with words an...

-- Input: string.rep("this is a single line with words and stuff okay? ", 6);
-- Output:
--  this is a single line with words and stuff okay? this is a single line with words and stuff okay? th...

Obviously there's also work on making it split the words cleanly but I'm avoiding that/it's a solved solution elsewhere anyway.

commented

Note that the correct character for truncation is โ€ฆ, not ... ๐Ÿ˜
Other than that, I'm super happy with the proposition ๐Ÿ˜„

commented

basically strsplit using \n as separator, loop through table of line, concatenate them using \n and then [...] add ... and bail out of the loop"

The "what was once a simpler two-line method but then evolved to meet requirements" method:

local MAX_LINES = 4;

local function limitLines(input)
    local chunks = { strsplit("\n", input, MAX_LINES + 1) };
    local limit = math.max(1, #chunks - 1);

    local limited = table.concat(chunks, "\n", 1, limit);
    if #chunks <= MAX_LINES then
        return limited;
    end

    return limited .. "...";
end

print(limitLines("my\nvery\nannoying\nstring\nwith a lot of\nline\nbreaks"));
-- Output:
--   my
--   very
--   annoying
--   string...