String manipulation question
#1
Posted 04 September 2013 - 05:43 PM
The advanced monitor is three blocks wide and two blocks tall. The text scale on the monitor is set to 1.5. The top text row is taken by a title bar and the bottom three text rows taken by buttons, so I want to be able to display a task in the four intermediate text rows. I'm storing the task as a particular string in an array of strings (let's say, taskList[currentTask]). I was hoping someone could help me write a function that writes the string on the four lines so that the lines break between words (the lines are 19 columns long except for the first, which has three initial characters for the task number, a period, and a space so only 16 columns for the task). I'm having trouble figuring out Lua's string library, so would be very grateful for any ideas on how to do this!
#2
Posted 04 September 2013 - 07:15 PM
Please post your current code so that we can help you improve/fix it.
#3
Posted 04 September 2013 - 07:59 PM
For example, I want the algorithm to read a string, say, "Build an automated cow farm to stockpile leather," and instead of displaying on the monitor:
1. Build an automat
ed cow farm to stoc
kpile leather
I want it to display the string as:
1. Build an
automated cow farm
to stockpile
leather
I'm not sure really how to even start with this particular function, so I don't have any code. I guess it's a conceptual problem, not a code editing problem?
#4
Posted 04 September 2013 - 08:41 PM
if the string is longer than the line then find the first word that is broken start a new line before that word repeat with a new string starting at the word that would have broken else print the string and return end
Start with a vague outline of what you want to do and bear down on each piece of it until you're putting it into code, if that makes sense.
#5
Posted 05 September 2013 - 01:08 AM
#6
Posted 05 September 2013 - 02:25 AM
Thats an example how you can do that.
str = "Build an automated cow farm to stockpile leather" -- the string you will print to the screen
termX, termY = term.getSize()
write('1. ')
for word in string.gmatch(x, "%S+") do -- that will give you word by word from the string (wihtout a space)
x, y = term.getCursorPos()
if (#word + x > termX) then -- checks if the word will fit to the screen
print() -- when not go to the next line
end
write(word) -- write the word
if (#word + x < termX) then -- checks if there is space for a space
write(' ') -- write the space
end
end
I can't test the code. So sorry if there is any syntax error
#7
Posted 05 September 2013 - 03:27 AM
BlankWolf, on 05 September 2013 - 02:25 AM, said:
Thats an example how you can do that.
str = "Build an automated cow farm to stockpile leather" -- the string you will print to the screen
termX, termY = term.getSize()
write('1. ')
for word in string.gmatch(x, "%S+") do -- that will give you word by word from the string (wihtout a space)
x, y = term.getCursorPos()
if (#word + x > termX) then -- checks if the word will fit to the screen
print() -- when not go to the next line
end
write(word) -- write the word
if (#word + x < termX) then -- checks if there is space for a space
write(' ') -- write the space
end
end
I can't test the code. So sorry if there is any syntax error
im not sure if print works with a monitor. And i think the term.getsize() does not include the textsize parameter. but im not sure about that will test it when im home.
When my suggestion is correct then you can use term.redirect but with that i guess you can not use textscale.
I would create an own print function with a maxchar Limit. just check how much chars you can write per line then use the print function below.
it should do the job but i didnt test it. you have to switch term.xxx to the variable for your Monitor peripheral.
if you want some explenation for the code just ask then i put some comments in.
local sm = {"I hate Cats","Coding HTML for Food","The Internet is for Stuff","Minecraft is a little boring when you not have Computercraft installed"}
local function splistring(x)
local c ={}
local i=1
for word in string.gmatch(x, "[%a%d]+") do
--if tonumber(word) == nil then
c[i]= word
--else
--c[i] = tonumber(word)
--end
i=i+1
end
return c
end
local function newprint(line, row, str, mchars)
local actline = line
if #str > mchars then
local mytext = splistring(str)
local newtext = mytext[1].." "
for i = 2,#mytext do
if #newtext+#mytext[i] < mchars then
newtext = newtext..mytext[i].." "
else
term.setCursorPos(row,actline)
term.write(newtext)
actline = actline+1
newtext = mytext[i].." "
end
end
term.setCursorPos(row,actline)
term.write(newtext)
else
term.setCursorPos(row,actline)
term.write(str)
end
end
term.clear()
newprint(1,2,sm[3],15)
Edit by Bubba: Keep it PG please.
#8
Posted 05 September 2013 - 12:11 PM
BlankWolf, on 05 September 2013 - 02:25 AM, said:
for word in string.gmatch(x, "%S+") do -- that will give you word by word from the string (wihtout a space)
x, y = term.getCursorPos()
if (#word + x > termX) then -- checks if the word will fit to the screen
print() -- when not go to the next line
end
write(word) -- write the word
if (#word + x < termX) then -- checks if there is space for a space
write(' ') -- write the space
end
end
This code is good, but it doesn't handle certain corner cases:
- Multiple spaces between words
- Words that are longer than the screen width
function printWrap(text)
local width, height = term.getSize()
local x, y
local function newLine()
x, y = 1, y + 1
if y > height then
y = height
term.scroll()
end
term.setCursorPos(x, y)
end
for space,word in text:gmatch("(%s-)(%S+)") do
fullWord = space..word
x, y = term.getCursorPos()
if x + #fullWord > width then
if #w > width then -- Handle words longer than screen width
while #fullWord > width do
write(fullWord:sub(1, width - x))
fullWord = fullWord:sub(width - x + 1)
newLine()
term.setCursorPos(x, y)
end
else
-- handle wrapped words shorter than screen width
newLine()
term.setCursorPos(x, y)
write(w)
end
else
write(fullWord)
end
end
end
LordIkol, on 05 September 2013 - 03:27 AM, said:
Oh, the lack of tabs!!! The pain!!!
#9
Posted 06 September 2013 - 12:38 AM
BigTwisty, on 05 September 2013 - 12:11 PM, said:
- Multiple spaces between words
- Words that are longer than the screen width
Well thats true. But I said:
BlankWolf, on 05 September 2013 - 02:25 AM, said:
#10
Posted 06 September 2013 - 12:57 AM
#11
Posted 06 September 2013 - 05:47 AM
LordIkol, on 05 September 2013 - 03:27 AM, said:
First i was like Whaat???!! did i use bad language, then i found the "Stuff"
Sorry Bubba will watch for that next time.
BigTwisty, on 05 September 2013 - 12:11 PM, said:
Nice code too
- you might want to add a number to the term.scroll() else it gives an error when he trys to make a new line.
- if the text has a single word that is longer then the screen it will not be printed. (if its a feature it should announce that this will happen
And when i checked my own piece of code i found a problem with numbers in the text. (fixed it)
its because i wrote the splitstring function for an other programm where i need numbers to be numbers)
Lyqyd, on 06 September 2013 - 12:57 AM, said:
Well spoken, im far away from beeing a Pro, but i try to help the people with their problems. And im always Happy if someone (mostly Bit) is correcting my mistakes or post a solution that makes my solution look toally Ugly
The reason is that i can learn something and the person who started the Topic learns something too, so its a Win/Win Situation.
greets
Loki
Edit: Changed something
#12
Posted 06 September 2013 - 11:45 AM
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











