This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
stringcheese's profile picture

Word wrap function

Started by stringcheese, 28 September 2014 - 06:57 PM
stringcheese #1
Posted 28 September 2014 - 08:57 PM
I'm making a program that keeps a list of tasks and displays them on an attached monitor to be cycled through one at a time. I'm trying to write a function that will display a single string on four lines with word wrap – that is, with lines broken up without breaking up words. First of all, I'm only learning programming with ComputerCraft, so I'm sure there are way easier ways to do this, but can anyone see what's wrong with my function? Specifically, it says that something is expecting a string and only getting a nil value.


-- Write the current task in the center of the monitor
function DrawTask()
  local firstLine, secondLine, thirdLine, fourthLine
  local endOfFirstLine, endOfSecondLine, endOfThirdLine
  local restOfTask
  monitor.setCursorPos(2, 3)
  if taskList[currentTask] ~= nil then
	monitor.write(tostring(currentTask))
	monitor.write(". ")
	if string.len(taskList[currentTask]) < 15 then
	  monitor.write(taskList[currentTask])
	else
	  firstLine = string.sub(taskList[CurrentTask], 1, 14)
	  endOfFirstLine = string.find(firstLine, " ", -1)
	  firstLine = string.sub(firstLine, 1, endOfFirstLine - 1)
	  restOfTask = string.sub(taskList[CurrentTask], endOfFirstLine + 1)
	  if string.len(restOfTask) < 18 then
		secondLine = restOfTask
		thirdLine = " "
		fourthLine = " "
	  else
		secondLine = string.sub(restOfTask, 1, 17)
		endOfSecondLine = string.find(secondLine, " ", -1)
		secondLine = string.sub(secondLine, 1, endOfSecondLine - 1)
		restOfTask = string.sub(restOfTask, endOfSecondLine + 1)  
		if string.len(restOfTask) < 18 then
		  thirdLine = restOfTask
		  fourthLine = " "
		else
		  thirdLine = string.sub(restOfTask, 1, 17)
		  endOfThirdLine = string.find(thirdLine, " ", -1)
		  thirdLine = string.sub(thirdLine, 1, endOfThirdLine - 1)
		  fourthLine = string.sub(restOfTask, endOfThirdLine + 1)  
		end
	  end
	  monitor.write(firstLine)
	  monitor.setCursorPos(2, 4)
	  monitor.write(secondLine)
	  monitor.setCursorPos(2, 5)
	  monitor.write(thirdLine)
	  monitor.setCursorPos(2, 6)
	  monitor.write(fourthLine)
	end
  else
	monitor.write("NO TASKS!")
  end
end
KingofGamesYami #2
Posted 28 September 2014 - 09:32 PM
Well, that code is ugly… (edit: no offense) patterns are the way to go here, I believe this will work the way you wish. You'll need to edit the variables and perhaps add some checks for nil values, but it should work correctly.


local lines = {}
for word in str:gmatch( "%S" ) do
  if #word + #lines[ #lines ] > 14 then --#i think you want it below 15, take 1 off for the space
     lines[ #lines ] = lines[ #lines ] + " "
  else
     lines[ #lines + 1 ] = " " .. word
  end
end
for i, line in ipairs( lines ) do
  monitor.setCursorPos( 2, 2 + i )
  monitor.write( line )
end
Edited on 28 September 2014 - 07:33 PM