Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

ComputerCraft - Screen Advanced API

By: Eritzap on Jul 10th, 2013  |  syntax: Lua  |  size: 21.46 KB  |  views: 135  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. local luaPrint = print
  2.  
  3. function isScreen(side, id)
  4.         if wrap(side, id) then
  5.                 return true
  6.         end
  7.         return false
  8. end
  9.  
  10. -- "Class" for handler for remote devices (via a wired modem)
  11. local RemoteHandler = {}
  12. RemoteHandler.new = function(side, id)
  13.  
  14.         local handler = {}
  15.        
  16.         handler.modem = peripheral.wrap(side)
  17.         if handler.modem == nil then return end
  18.        
  19.         handler.side = side
  20.         handler.id = id
  21.         handler.name = "monitor_" .. id
  22.         handler.isHandler = true
  23.         handler.isRemoteHandler = true
  24.        
  25.         handler.clear =                         function()                                              handler.modem.callRemote(handler.name, "clear")                                 end
  26.         handler.write =                         function(txt)   return                  handler.modem.callRemote(handler.name, "write", txt)                    end
  27.         handler.clearLine =             function()                                              handler.modem.callRemote(handler.name, "clearLine")                     end
  28.        
  29.         handler.getCursorPos =          function()              local a, b =    handler.modem.callRemote(handler.name, "getCursorPos")                  return a, b end
  30.                 handler.getCursor =     handler.getCursorPos
  31.                 handler.getCursorXPos = function()              local a, b =    handler.modem.callRemote(handler.name, "getCursorPos")                  return a end
  32.                 handler.getCursorX =    handler.getCursorXPos
  33.                 handler.getX =                  handler.getCursorXPos
  34.                 handler.getCursorYPos = function()              local a, b =    handler.modem.callRemote(handler.name, "getCursorPos")                  return b end
  35.                 handler.getCursorY =    handler.getCursorYPos
  36.                 handler.getY =                  handler.getCursorYPos
  37.                
  38.         handler.setCursorPos =          function(a, b)                                  handler.modem.callRemote(handler.name, "setCursorPos", a, b)    end
  39.                 handler.setCursor =     handler.setCursorPos
  40.                 handler.setCursorXPos = function(x)             local a, b =    handler.modem.callRemote(handler.name, "getCursorPos")
  41.                                                                                                                                 handler.modem.callRemote(handler.name, "setCursorPos", x, b)    end
  42.                 handler.setCursorX =    handler.setCursorXPos
  43.                 handler.setX =                  handler.setCursorXPos
  44.                 handler.setCursorYPos = function(y)             local a, b =    handler.modem.callRemote(handler.name, "getCursorPos")
  45.                                                                                                                                 handler.modem.callRemote(handler.name, "setCursorPos", a, y)    end
  46.                 handler.setCursorY =    handler.setCursorYPos
  47.                 handler.setY =                  handler.setCursorYPos
  48.                
  49.         handler.setCursorBlink =        function(b)                                             handler.modem.callRemote(handler.name, "setCursorBlink", b)             end
  50.                 handler.setBlink =              handler.setCursorBlink
  51.                
  52.         handler.isColor =                       function()              return                  handler.modem.callRemote(handler.name, "isColor")                               end            
  53.        
  54.         handler.getSize =                       function()              local a, b =    handler.modem.callRemote(handler.name, "getSize")                               return a, b end
  55.                 handler.getXSize =              function()              local a, b =    handler.modem.callRemote(handler.name, "getSize")                               return a end
  56.                 handler.getYSize =              function()              local a, b =    handler.modem.callRemote(handler.name, "getSize")                               return b end
  57.        
  58.         handler.scroll =                        function(n)                                             handler.modem.callRemote(handler.name, "scroll", n)                             end
  59.         handler.setTextScale =          function(s)                                             handler.modem.callRemote(handler.name, "setTextScale", s)               end
  60.         if handler.isColor() then
  61.                 handler.setTextColor =                  function(color) handler.modem.callRemote(handler.name, "setTextColor", color)           end
  62.                 handler.setBackgroundColor =    function(color) handler.modem.callRemote(handler.name, "setBackgroundColor", color) end
  63.                         handler.setBackColor =          handler.setBackgroundColor
  64.                 handler.setColors =                             function(col1, col2)    if col1 ~= nil then
  65.                                                                                                                                         handler.modem.callRemote(handler.name, "setTextColor", col1)
  66.                                                                                                                                 else
  67.                                                                                                                                         handler.modem.callRemote(handler.name, "setTextColor", colours.white)
  68.                                                                                                                                 end
  69.                                                                                                                                 if col2 ~= nil then
  70.                                                                                                                                         handler.modem.callRemote(handler.name, "setBackgroundColor", col2)
  71.                                                                                                                                 else
  72.                                                                                                                                         handler.modem.callRemote(handler.name, "setBackgroundColor", colours.black)
  73.                                                                                                                                 end end
  74.         end
  75.        
  76.         -- adding the additional API functions
  77.         handler.reset =                         function()                              handler.modem.callRemote(handler.name, "clear") handler.modem.callRemote(handler.name, "setCursorPos", 1, 1) end
  78.         handler.nextLine =                      function(scrolling)             nextLine(handler.side, handler.id, scrolling) end
  79.         handler.nextLines =                     function(n, scrolling)  nextLines(n, handler.side, handler.id, scrolling) end
  80.         handler.print =                         function(text, scrolling) return print(text, handler.side, handler.id, scrolling) end
  81.         handler.println =                       function(text, scrolling) handler.print(text, handler.side, handler.id, scrolling) handler.nextLine(scrolling) return text end
  82.         handler.left =                          function(text, scrolling) return left(text, handler.side, handler.id, scrolling) end
  83.        
  84.         return handler
  85. end
  86.  
  87. -- "Class" for a normal handler (using this add methods that implements the function added by this API)
  88. local Handler = {}
  89. Handler.new = function(side)
  90.  
  91.         local handler = peripheral.wrap(side)
  92.         if handler == nil then return end
  93.        
  94.         handler.side = side
  95.        
  96.         handler.isHandler = true
  97.         handler.isRemoteHandler = false
  98.  
  99.         handler.getCursor = handler.getCursorPos
  100.         handler.getCursorXPos = function() local a, b = handler.getCursorPos() return a end
  101.                 handler.getCursorX = handler.getCursorXPos
  102.                 handler.getX = handler.getCursorXPos
  103.         handler.getCursorYPos = function() local a, b = handler.getCursorPos() return b end
  104.                 handler.getCursorY = handler.getCursorYPos
  105.                 handler.getY = handler.getCursorYPos
  106.        
  107.         handler.setCursor = handler.setCursorPos
  108.         handler.setCursorXPos = function(x) local a, b = handler.getCursorPos() handler.setCursorPos(x, b) end
  109.                 handler.setCursorX = handler.setCursorXPos
  110.                 handler.setX = handler.setCursorXPos
  111.         handler.setCursorYPos = function(y) local a, b = handler.getCursorPos() handler.setCursorPos(a, y) end
  112.                 handler.setCursorY = handler.setCursorYPos
  113.                 handler.setY = handler.setCursorYPos
  114.                
  115.         handler.getXSize = function() local a, b = handler.getSize() return a end
  116.         handler.getYSize = function() local a, b = handler.getSize() return b end
  117.        
  118.         handler.setBlink = handler.setCursorBlink
  119.        
  120.         if handler.isColor() then
  121.                 handler.setBackColor = handler.setBackgroundColor
  122.                 handler.setColors = function(col1, col2)        if col1 ~= nil then
  123.                                                                                                                 handler.setTextColor(col1)
  124.                                                                                                         else
  125.                                                                                                                 handler.setTextColor(colours.white)
  126.                                                                                                         end
  127.                                                                                                         if col2 ~= nil then
  128.                                                                                                                 handler.setBackgroundColor(col2)
  129.                                                                                                         else
  130.                                                                                                                 handler.setBackgroundColor(colours.black)
  131.                                                                                                         end end
  132.         end
  133.        
  134.         -- adding the additional API functions
  135.         handler.reset = function() handler.clear() handler.setCursorPos(1, 1) end
  136.         handler.nextLine = function(scrolling) nextLine(handler.side, nil, scrolling) end
  137.         handler.nextLines = function(n, scrolling) nextLines(n, handler.side, nil, scrolling) end
  138.         handler.print = function(text, scrolling) return print(text, handler.side, nil, scrolling) end
  139.         handler.println = function(text, scrolling) handler.print(text, handler.side, nil, scrolling) handler.nextLine(scrolling) return text end
  140.         handler.left = function(text, scrolling) return left(text, handler.side, nil, scrolling) end
  141.        
  142.         return handler
  143. end
  144.  
  145. -- wrap around 'side', if 'side' is a modem, 'id' designate the number id of the monitor targetted (name structure is "monitor_id")
  146. function wrap(side, id)
  147.         if side == nil then
  148.                 return term
  149.         elseif peripheral.isPresent(side) then
  150.                 if peripheral.getType(side) == "monitor" then
  151.                         return Handler.new(side)
  152.                 elseif peripheral.getType(side) == "modem" and id ~= nil then
  153.                         local modem = peripheral.wrap(side)
  154.                         if modem.isPresentRemote and modem.isPresentRemote("monitor_" .. id) then
  155.                                 return RemoteHandler.new(side, id)
  156.                         end
  157.                 end
  158.         end
  159.         luaPrint("wrap: invalid input").crash()
  160. end
  161.  
  162. --------------------------------------------------------------------------------------------------------------------------
  163. -------------------------------------------REDEFINITION-OF-STANDARD-FUNCTIONS---------------------------------------------
  164. --------------------------------------------------------------------------------------------------------------------------
  165.  
  166. -- Clear the screen
  167. function clear(side, id)
  168.         wrap(side, id).clear()
  169. end
  170.  
  171. -- Clear the line at the cursor's position
  172. function clearLine(side, id)
  173.         wrap(side, id).clearLine()
  174. end
  175.  
  176. -- Write a text at the cursor's position
  177. function write (text, side, id)
  178.         return wrap(side, id).write(text)
  179. end
  180.  
  181. -- Get the cursor's position
  182. -- getCursorPos, getCursor
  183. -- getCursorXPos, getCursorX, getX
  184. -- getCursorYPos, getCursorY, getY
  185. function getCursorPos(side, id)
  186.         local a, b = wrap(side, id).getCursorPos()
  187.         return a, b
  188. end
  189. getCursor = getCursorPos
  190. function getCursorXPos(side, id)
  191.         local a, b = getCursorPos(side, id)
  192.         return a
  193. end
  194. getCursorX = getCursorXPos
  195. getX = getCursorXPos
  196. function getCursorYPos(side, id)
  197.         local a, b = getCursorPos(side, id)
  198.         return b
  199. end
  200. getCursorY = getCursorYPos
  201. getY = getCursorYPos
  202.  
  203. -- Set the cursor's position
  204. -- setCursorPos, setCursor
  205. -- setCursorXPos, setCursorX
  206. -- setCursorYPos, setCursorY
  207. function setCursorPos(x, y, side, id)
  208.         wrap(side, id).setCursorPos(x, y)
  209. end
  210. setCursor = setCursorPos
  211. function setCursorXPos(x, side, id)
  212.         local handler = wrap(side, id)
  213.         local a, b = handler.getCursorPos()
  214.         handler.setCursorPos(x, b)
  215. end
  216. setCursorX = setCursorXPos
  217. setX = setCursorXPos
  218. function setCursorYPos(y, side, id)
  219.         local handler = wrap(side, id)
  220.         local a, b = handler.getCursorPos()
  221.         handler.setCursorPos(a, y)
  222. end
  223. setCursorY = setCursorYPos
  224. setY = setCursorYPos
  225.  
  226. -- Set weither or not the cursor is blinking
  227. -- setCursorBlink, setBlink
  228. function setCursorBlink(b, side, id)
  229.         wrap(side, id).setCursorBlink(b)
  230. end
  231. setBlink = setCursorBlink
  232.  
  233. -- true if advanced, false if not
  234. function isColor(side, id)
  235.         return wrap(side, id).isColor()
  236. end
  237.  
  238. -- Get the screen's side
  239. -- getSize
  240. -- getXSize
  241. -- getYSize
  242. function getSize(side, id)
  243.         local a, b = wrap(side, id).getSize()
  244.         return a, b
  245. end
  246. function getXSize(side, id)
  247.         local a, b = wrap(side, id).getCursorPos()
  248.         return a
  249. end
  250. function getYSize(side, id)
  251.         local a, b = wrap(side, id).getCursorPos()
  252.         return b
  253. end
  254.  
  255. -- Scroll the screen upward
  256. function scroll(n, side, id)
  257.         wrap(side, id).scroll(n)
  258. end
  259.  
  260. -- Set the scale of the monitor (has no effect on a terminal)
  261. function setTextScale(x, side, id)
  262.         if side ~= nil then
  263.                 wrap(side, id).setTextScale(x)
  264.                 return true
  265.         end
  266.         return false
  267. end
  268.  
  269. -- Set the text color (has no effect on a non-advanced screen
  270. function setTextColor(color, side, id)
  271.         local handler = wrap(side, id)
  272.         if handler.isColor() then
  273.                 handler.setTextColor(color)
  274.                 return true
  275.         end
  276.         return false
  277. end
  278.  
  279. -- Set the background color (has no effect on a non-advanced screen
  280. function setBackgroundColor(color, side, id)
  281.         local handler = wrap(side, id)
  282.         if handler.isColor() then
  283.                 handler.setBackgroundColor(color)
  284.                 return true
  285.         end
  286.         return false
  287. end
  288. setBackColor = setBackgroundColor
  289.  
  290. --------------------------------------------------------------------------------------------------------------------------
  291. --------------------------------------------ADDITIONAL-SIMPLE-FUNCTIONS---------------------------------------------------
  292. --------------------------------------------------------------------------------------------------------------------------
  293.  
  294. -- clear the screen, then set the cursor back to (1,1)
  295. function reset(side, id)
  296.        
  297.         clear(side, id)
  298.         setCursorPos(1, 1, side, id)
  299. end
  300.  
  301. -- set the colors of both the background and the text
  302. function setColors(col1, col2, side, id)
  303.         if handler.isColor() then
  304.                 if col1 ~= nil then
  305.                         handler.setTextColor(col1)
  306.                 else
  307.                         handler.setTextColor(colours.white)
  308.                 end
  309.                 if col2 ~= nil then
  310.                         handler.setBackgroundColor(col2)
  311.                 else
  312.                         handler.setBackgroundColor(colours.black)
  313.                 end
  314.                 return true
  315.         end
  316.         return false
  317. end
  318.  
  319. -- go to the next line, return the number of lines scrolled
  320. -- if scrolling is true, will scroll the screen if on the last line
  321. function nextLine(side, id, scrolling)
  322.         local x, y = getCursor(side, id)
  323.         local a, b = getSize(side, id)
  324.         if y < b then
  325.                 setCursor(1, y+1, side, id)
  326.                 return 0
  327.         elseif y == b and scrolling then
  328.                 scroll(1, side, id)
  329.                 setCursor(1, y, side, id)
  330.                 return 1
  331.         end
  332.         setCursor(1, y, side, id)
  333.         return 0
  334. end
  335. -- multilines version
  336. function nextLines(n, side, id, scrolling)
  337.         local x, y = getCursor(side, id)
  338.         local a, b = getSize(side, id)
  339.         if y+n <= b then
  340.                 if y+n > 0 then
  341.                         setCursor(1, y+n, side, id)
  342.                 else
  343.                         setCursor(1, 1, side, id)
  344.                 end
  345.                 return 0
  346.         end
  347.         if  scrolling then
  348.                 scroll(y+n-b, side, id)
  349.                 setCursor(1, b, side, id)
  350.                 return y+n-b
  351.         end
  352.         setCursor(1, b, side, id)
  353.         return 0
  354. end
  355.        
  356. -- print the text given to screen
  357. -- this function recognize the "\n" character and interprete them accordingly (with a new line)
  358. -- see nextLine function for the usage of "scrolling" argument"
  359. function print(text, side, id, scrolling)
  360.         local handler = wrap(side, id)
  361.         for i=1, text:len() do
  362.                 if text:sub(i, i) == "\n" then
  363.                         handler.nextLine(scrolling)
  364.                 else
  365.                         handler.write(text:sub(i, i))
  366.                 end
  367.         end
  368.         return text
  369. end
  370.  
  371. -- print the given text and go to the next line
  372. -- this function recognize the "\n" character and interprete them accordingly (with a new line)
  373. -- see nextLine function for the usage of "scrolling" argument"
  374. function println(text, side, id, scrolling)
  375.         local handler = wrap(side, id)
  376.         handler.print(text, scrolling)
  377.         handler.nextLine(scrolling)
  378.         return text
  379. end
  380.  
  381. --------------------------------------------------------------------------------------------------------------------------
  382. --------------------------------------------ALIGNMENT-AND-SPACE-PARSING-FUNCTIONS-----------------------------------------
  383. --------------------------------------------------------------------------------------------------------------------------
  384.  
  385. -- return a structured table separating the lines and words
  386. -- the table is an integer array, going from 1 to n, where the line #n is the nth line of the text
  387. -- each line has a table containing an alternance of integers representing an amonth of blank spaces, and of string representing the words
  388. --              so an odd index for a line means the number of spaces, while an even number for a word
  389. local function parseWords(str)
  390.  
  391.         local words = {}
  392.         words[1] = {}
  393.         words[1][1] = 0
  394.        
  395.         local line = 1
  396.         local element = 1
  397.        
  398.         for i=1, str:len() do
  399.                
  400.                 local char = str:sub(i, i)
  401.                 if char == "\n" then
  402.                         line = line+1
  403.                         words[line] = {}
  404.                         element = 1
  405.                         words[line][1] = 0
  406.                 elseif char == " " then
  407.                         if element/2 == math.floor(element/2) then
  408.                                 element = element+1
  409.                                 words[line][element] = 1
  410.                         else
  411.                                 words[line][element] = words[line][element]+1
  412.                         end
  413.                 else
  414.                         if element/2 == math.floor(element/2) then
  415.                                 words[line][element] = words[line][element] .. char
  416.                         else
  417.                                 element = element+1
  418.                                 words[line][element] = char
  419.                         end
  420.                 end
  421.         end
  422.  
  423.         return words
  424. end
  425.  
  426. -- insert into an integer array table, value at key, if the value already exists, all the next elements are shifted the the next key
  427. local function table_insert(t, key, value)
  428.  
  429.         if type(key) ~= "number" then
  430.                 return false
  431.         end
  432.  
  433.         if key > #t then
  434.                 t[#t+1] = value
  435.         elseif key < 1 then
  436.                 table_append(t, 1, value)
  437.         else
  438.                 for i=#t, key-1, -1 do
  439.                         t[i+1] = t[i]
  440.                 end
  441.                 t[key] = value
  442.         end
  443.         return t
  444. end
  445.  
  446. -- remove elements from the integer array table t, from and including index start, till and including index ending
  447. local function table_remove(t, start, ending)
  448.  
  449.         if not ending then
  450.                 ending = start
  451.                 start = 1
  452.         end
  453.         if not start then
  454.                 start = 1
  455.                 ending = #t
  456.         end
  457.         for i=start, #t do
  458.                 if i > ending then
  459.                         t[i-ending-1+start] = t[i]
  460.                 end
  461.                 t[i] = nil
  462.         end
  463.         return t
  464. end
  465.  
  466. -- return a strict duplicate of the table, reccursively dupplicating tables included as elements
  467. local function table_dupplicate(t)
  468.  
  469.         local newTable = {}
  470.         for k, e in pairs(t) do
  471.                 if type(e) == "table" then
  472.                         newTable[k] = table_dupplicate(e)
  473.                 else
  474.                         newTable[k] = e
  475.                 end
  476.         end
  477.         return newTable
  478. end
  479.  
  480. -- concatenate words from and including index a, till and including index b, at the given line
  481. -- this is to be applied on a table resulting from the above function "parseWords"
  482. local function concat_words(t, line, a, b)
  483.  
  484.         if not t or type(t) ~= "table" then return "" end
  485.        
  486.         local lineT = t[line]
  487.        
  488.         if not a then a = 1 b = #lineT end
  489.         if not b then b = a a = 1 end
  490.         if b-a <= 0 then return "" end
  491.        
  492.         local str = ""
  493.         for i=a, b do
  494.        
  495.                 if i/2 == math.floor(i/2) then
  496.                         str = str .. lineT[i]
  497.                 elseif lineT[i] > 0 then
  498.                         str = str .. string.rep(" ", lineT[i])
  499.                 end
  500.         end
  501.        
  502.         return str
  503. end
  504.  
  505. -- create a structured table showings lines to print in a screen of a given width
  506. -- ignore_trailing to true indicate that starting and trailing spaces are removed from the result
  507. -- the table is an integer array like the parseWords result
  508. -- each line is made up of 3 elements of indexes {1,2,3}
  509. --              [1] contains the starting spaces
  510. --              [2] contains the line body text
  511. --              [3] contains the trailing spaces
  512. local function parseLines(words, width, ignore_trailing)
  513.  
  514.         words = table_dupplicate(words)
  515.         local lines = {}
  516.        
  517.         local i=1
  518.         while i <= #words do
  519.        
  520.                 lines[i] = {}
  521.        
  522.                 local wordsLine = words[i]
  523.                 if ignore_trailing then
  524.                         wordsLine[1] = 0
  525.                         if (#wordsLine)/2 ~= math.floor((#wordsLine)/2) then
  526.                                 wordsLine[#wordsLine] = 0
  527.                         end
  528.                 end
  529.                
  530.                 local saveJ = nil
  531.                 for j=1, #wordsLine do
  532.                         saveJ = j
  533.                
  534.                         --wrap("back", 0).print("Concatenation of line " .. i .. "\n  until words #" .. j .. ':\n  "' .. concat_words(words, i, j) .. '"\n', true)
  535.                         if concat_words(words, i, j):len() > width then
  536.                        
  537.                                 saveJ = -1
  538.                        
  539.                                 if j == 1 then
  540.                                 --                                                      wrap("back", 0).print("j == 1\n", true)
  541.                                         lines[i][1] = 0
  542.                                         lines[i][2] = ""
  543.                                         lines[i][3] = width
  544.                                         wordsLine[1] = wordsLine[1] - width
  545.                                         if ignore_trailing then
  546.                                                 lines[i][3] = 0
  547.                                                 wordsLine[1] = 0
  548.                                         end
  549.                                         table_insert(words, i+1, wordsLine)
  550.                                         break
  551.                                        
  552.                                 elseif j == 2 then                                                                                     
  553.                                 --                                                      wrap("back", 0).print("j == 2\n", true)
  554.  
  555.                                         lines[i][1] = 0
  556.                                         if wordsLine[1] == 0 then
  557.                                                 lines[i][2] = string.sub(wordsLine[2], 1, width)
  558.                                                 lines[i][3] = 0
  559.                                                 wordsLine[2] = string.sub(wordsLine[2], width+1)
  560.                                                 table_insert(words, i+1, wordsLine)
  561.                                         else
  562.                                                 lines[i][2] = ""
  563.                                                 lines[i][3] = wordsLine[1]
  564.                                                 if ignore_trailing then
  565.                                                         lines[i][3] = 0
  566.                                                 end
  567.                                                 wordsLine[1] = 0
  568.                                         end
  569.                                         table_insert(words, i+1, wordsLine)
  570.                                         break
  571.                                
  572.                                 elseif j == 3 then
  573.                                 --                                                      wrap("back", 0).print("j == 3\n", true)
  574.                                         lines[i][1] = wordsLine[1]
  575.                                         lines[i][2] = string.rep(" ", wordsLine[1]) .. wordsLine[2]
  576.                                         lines[i][3] = 0
  577.                                         table_remove(wordsLine, 2)
  578.                                         if ignore_trailing then
  579.                                                 lines[i][1] = 0
  580.                                                 wordsLine[1] = 0
  581.                                         end
  582.                                         table_insert(words, i+1, wordsLine)
  583.                                         break
  584.                                        
  585.                                 elseif j/2 == math.floor(j/2) then
  586.                                 --                                                      wrap("back", 0).print("j > 3 and last is odd\n", true)
  587.                                         lines[i][1] = wordsLine[1]
  588.                                         lines[i][2] = concat_words(words, i, j-2)
  589.                                         lines[i][3] = wordsLine[j-1]
  590.                                         table_remove(wordsLine, j-1)
  591.                                         table_insert(wordsLine, 1, 0)
  592.                                        
  593.                                         if ignore_trailing then
  594.                                                 lines[i][1] = 0
  595.                                                 lines[i][3] = 0
  596.                                         end
  597.                                        
  598.                                         table_insert(words, i+1, wordsLine)
  599.                                         break
  600.                                
  601.                                 else
  602.                                 --                                                      wrap("back", 0).print("j > 3 and last is even\n", true)
  603.                                         lines[i][1] = wordsLine[1]
  604.                                         lines[i][2] = concat_words(words, i, j-1)
  605.                                         lines[i][3] = 0
  606.                                         table_remove(wordsLine, j-1) -- in that case, the issue is with a set of spaces, so it's removed from the list so that the next word is sent away
  607.                                                 wordsLine[1] = 0
  608.                                        
  609.                                         if ignore_trailing then
  610.                                                 lines[i][1] = 0
  611.                                                 wordsLine[1] = 0
  612.                                         end
  613.                                        
  614.                                         table_insert(words, i+1, wordsLine)
  615.                                         break
  616.                                        
  617.                                 end
  618.                         end
  619.                 end
  620.                 if not saveJ then
  621.                         lines[i][1] = 0
  622.                         lines[i][2] = ""
  623.                         lines[i][3] = 0
  624.                
  625.                 elseif saveJ > 0 then
  626.                
  627.                         lines[i][1] = wordsLine[1]
  628.                         if (#wordsLine)/2 == math.floor((#wordsLine)/2) then
  629.                                 lines[i][2] = concat_words(words, i, #wordsLine)
  630.                                 lines[i][3] = 0
  631.                         else
  632.                                 lines[i][2] = concat_words(words, i, (#wordsLine)-1)
  633.                                 lines[i][3] = wordsLine[#wordsLine]
  634.                         end
  635.                        
  636.                         if ignore_trailing then
  637.                                 lines[i][1] = 0
  638.                                 lines[i][3] = 0
  639.                         end
  640.  
  641.                 end
  642.                 --wrap("back", 0).print("(" .. lines[i][1] .. ', "' .. lines[i][2] .. '", ' .. lines[i][3] .. ")\n", true)
  643.                 i = i+1
  644.         end
  645.         return lines
  646. end
  647.  
  648. -- print a left-aligned version of the text, parsed with the above functions to send to the next line any overflowing words
  649. -- this function recognize the "\n" character and interprete them accordingly (with a new line)
  650. -- see nextLine function for the usage of "scrolling" argument"
  651. -- if scrolling in disabled, it will only print the lines of text that fits the given space
  652. function left(text, side, id, scrolling)
  653.  
  654.         local handler = wrap(side, id)
  655.         local width, height = handler.getSize()
  656.         local x, y = handler.getCursor()
  657.         term.clear()
  658.         term.setCursorPos(1, 1)
  659.         local words = parseWords(text)
  660.         local lines = parseLines(words, width)
  661.        
  662.         if x > 1 then
  663.                 handler.nextLine(scrolling)
  664.         end
  665.        
  666.         local str = ""
  667.        
  668.         if scrolling then
  669.        
  670.                 for i=1, #lines do
  671.                         local tmp = string.rep(" ", lines[i][1]) .. lines[i][2]
  672.                         handler.write(tmp)
  673.                         str = str .. tmp
  674.                         if i < #lines then
  675.                                 handler.nextLine(true)
  676.                                 str = str .. "\n"
  677.                         end
  678.                 end
  679.        
  680.         else
  681.        
  682.                 for i=y, height do
  683.                         if not lines[i-y+1] then
  684.                                 break
  685.                         end
  686.                        
  687.                         local tmp = string.rep(" ", lines[i-y+1][1]) .. lines[i-y+1][2]
  688.                         handler.write(tmp)
  689.                         str = str .. tmp
  690.                         if i < height then
  691.                                 handler.nextLine(false)
  692.                                 str = str .. "\n"
  693.                         end
  694.                 end
  695.        
  696.         end
  697.        
  698.         return text
  699. end