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

Help with printers and launch time variables

Started by lukasdragon, 17 April 2014 - 02:38 PM
lukasdragon #1
Posted 17 April 2014 - 04:38 PM
Hello, I was wondering if it is possible to get CC read a file then print it including page breaks?
Also how would I make launch variables?

Thanks,
Lukas
Lignum #2
Posted 17 April 2014 - 05:27 PM
I'm not too familiar with printers so I can't help you there.

As for program arguments:

--# argv is a table containing the arguments.
--# As per usual it starts at one.
local argv = { ... } --# The dots are actual code.

--# Personally I like to have a variable which contains
--# the size of the table. This is completely optional.
local argc = #argv

--# You can use the table like a regular table:
local firstArgument = argv[1]
local secondArgument = argv[2]
Edited on 17 April 2014 - 03:28 PM
RoD #3
Posted 17 April 2014 - 08:08 PM
I think this page may help you a lot:
http://computercraft.info/wiki/Printer

You are after the:

printer.write()

To read a file and print it you need to:

file = fs.open("mytext", "r")
out = file.readAll()
file.close()
printer.write(out)

I almost never use printers, so this may need a change or tow, but i hope you get it.
Edited on 17 April 2014 - 06:08 PM
lukasdragon #4
Posted 17 April 2014 - 11:58 PM
I'm not too familiar with printers so I can't help you there.

As for program arguments:

--# argv is a table containing the arguments.
--# As per usual it starts at one.
local argv = { ... } --# The dots are actual code.

--# Personally I like to have a variable which contains
--# the size of the table. This is completely optional.
local argc = #argv

--# You can use the table like a regular table:
local firstArgument = argv[1]
local secondArgument = argv[2]
I think this page may help you a lot:
http://computercraft.info/wiki/Printer

You are after the:

printer.write()

To read a file and print it you need to:

file = fs.open("mytext", "r")
out = file.readAll()
file.close()
printer.write(out)

I almost never use printers, so this may need a change or tow, but i hope you get it.


Thanks :)/> that will help me ALOT! :)/>
--- #5
Posted 18 April 2014 - 04:57 AM
Edited on 19 April 2014 - 04:33 AM
RoD #6
Posted 18 April 2014 - 12:28 PM
Generally printing is done in a loop, printing each page. Each page must be begun with newPage(), and finished with endPage(). The contents of the page must be formatted to the page size, which we can't get until calling newPage(). With one page size supported we could assume 25x21 but getting the page size from the printer is more exact. The write() method, as on the terminal, will just keep printing past the right side of the page. The text must be broken into lines of the page width.
Both newPage() and endPage() can fail, if the printer is not ready or the out tray is full.
In the following, wrapString() breaks the string into lines of a maximum of the given width, returning an indexed table of the lines. printOut() is the printing loop. readFile() does just that, returning a single string.
The abort clauses allow the printing to be stopped easily if we are mistakenly about to print 500 pages, for example. Aborting at a failed endPage() will leave the last page in the printer until the next print on that printer.

local args = {...}



local function wrapString(str, maxWidth)
   local result = { "" }
   local line, start, pos, lastBreak = 1, 1, 1, maxWidth + 1

   while pos <= string.len(str) do
	  local char = string.byte(str, pos)

	  if char == 13 or char == 10 then
		 --# hard break
		 if (pos - start) > 0 then
			result[line] = string.sub(str, start, pos - 1)
		 else
			result[line] = ""
		 end

		 line = line + 1

		 if char == 13 and pos < string.len(str) then
			if string.byte(str, pos + 1) == 10 then
			   --# windows/dos eol
			   pos = pos + 1
			end
		 end

		 start = pos + 1
		 lastBreak = start + maxWidth
	  elseif char == 32 or char == 9 then
		 --# last potential soft break
		 lastBreak = pos + 1
	  end

	  if (pos - start) >= maxWidth then
		 --# line at max, must break
		 result[line] = string.sub(str, start, lastBreak - 1)

		 line = line + 1

		 start = lastBreak

		 char = string.byte(str, start)
		 if char == 32 or char == 9 then
			--# skip first white space
			start = start + 1
		 end

		 lastBreak = start + maxWidth
	  end

	  pos = pos + 1
   end

   if (pos - start) > 0 then
	  --# get the left overs
	  result[line] = string.sub(str, start)
   end

   return result
end



local function printOut(title, contents, side)
   local printer;
   local continue = true
   local lines;
   local page = 1

   if not side then
	  printer = peripheral.find("printer")
	  assert(printer, "Could not find a printer")
   else
	  assert(peripheral.getType(side) == "printer",
					 "Expected printer on "..side)
	  printer = peripheral.wrap(side)
	  assert(printer, "Failed to connect printer "..side)
   end

   while continue do
	  --# start a page, fails if no ink/paper
	  while not printer.newPage() do
		 print("Check printer...")
		 local event, key = os.pullEvent("key")
		 if key == keys.delete then
			print("Print aborted")
			return
		 end
	  end

	  --# get the page size (in chars)
	  --# must be called after newPage()
	  local width, height = printer.getPageSize()

	  --# split contents into lines if not done yet
	  --# assumes all pages same width
	  if not lines then
		 lines = wrapString(contents, width)
		 print("Printing "..tostring(math.ceil(#lines / height)).." pages")
	  end

	  --# no page number on first page
	  --# first page is also title if made into book
	  if page == 1 then
		 printer.setPageTitle(title)
	  else
		 printer.setPageTitle(title.." "..tostring(page))
	  end

	  --# work out the lines to print on this page
	  local lastLine = page * height
	  local firstLine = lastLine - height + 1

	  --# if at end trim lastLine and flag drop out
	  if lastLine >= #lines then
		 continue = false
		 lastLine = #lines
	  end

	  --# write the lines to the page
	  for line = firstLine, lastLine, 1 do
		 printer.setCursorPos(1, line - firstLine + 1)
		 printer.write(lines[line])
	  end

	  --# next page
	  page = page + 1

	  --# spit page into out tray
	  while not printer.endPage() do
		 print("Empty tray...")
		 local event, key = os.pullEvent("key")
		 if key == keys.delete then
			print("Print aborted")
			return
		 end
	  end
   end

   print("Print complete")
end


local function readFile(path)
   local hFile = fs.open(path, "r")
   assert(hFile, "Could not open file "..path)

   local contents = hFile.readAll()

   hFile.close()

   assert(contents, "Could not read file "..path)
   return contents
end


if #args < 1 then
   print("Usage: "..fs.getName(shell.getRunningProgram()).." filePath [printer]")
else
   printOut(fs.getName(args[1]), readFile(args[1]), args[2])
end
Customize as desired.
Its kind of you to help him, but the forums are mainly to help others. As Lyqyd said, we will never do the code for you, but we will alaways help in any matter, like that, new users learn faster and better.
lukasdragon #7
Posted 19 April 2014 - 01:02 AM
Generally printing is done in a loop, printing each page. Each page must be begun with newPage(), and finished with endPage(). The contents of the page must be formatted to the page size, which we can't get until calling newPage(). With one page size supported we could assume 25x21 but getting the page size from the printer is more exact. The write() method, as on the terminal, will just keep printing past the right side of the page. The text must be broken into lines of the page width.
Both newPage() and endPage() can fail, if the printer is not ready or the out tray is full.
In the following, wrapString() breaks the string into lines of a maximum of the given width, returning an indexed table of the lines. printOut() is the printing loop. readFile() does just that, returning a single string.
The abort clauses allow the printing to be stopped easily if we are mistakenly about to print 500 pages, for example. Aborting at a failed endPage() will leave the last page in the printer until the next print on that printer.

local args = {...}



local function wrapString(str, maxWidth)
   local result = { "" }
   local line, start, pos, lastBreak = 1, 1, 1, maxWidth + 1

   while pos <= string.len(str) do
	  local char = string.byte(str, pos)

	  if char == 13 or char == 10 then
		 --# hard break
		 if (pos - start) > 0 then
			result[line] = string.sub(str, start, pos - 1)
		 else
			result[line] = ""
		 end

		 line = line + 1

		 if char == 13 and pos < string.len(str) then
			if string.byte(str, pos + 1) == 10 then
			   --# windows/dos eol
			   pos = pos + 1
			end
		 end

		 start = pos + 1
		 lastBreak = start + maxWidth
	  elseif char == 32 or char == 9 then
		 --# last potential soft break
		 lastBreak = pos + 1
	  end

	  if (pos - start) >= maxWidth then
		 --# line at max, must break
		 result[line] = string.sub(str, start, lastBreak - 1)

		 line = line + 1

		 start = lastBreak

		 char = string.byte(str, start)
		 if char == 32 or char == 9 then
			--# skip first white space
			start = start + 1
		 end

		 lastBreak = start + maxWidth
	  end

	  pos = pos + 1
   end

   if (pos - start) > 0 then
	  --# get the left overs
	  result[line] = string.sub(str, start)
   end

   return result
end



local function printOut(title, contents, side)
   local printer;
   local continue = true
   local lines;
   local page = 1

   if not side then
	  printer = peripheral.find("printer")
	  assert(printer, "Could not find a printer")
   else
	  assert(peripheral.getType(side) == "printer",
					 "Expected printer on "..side)
	  printer = peripheral.wrap(side)
	  assert(printer, "Failed to connect printer "..side)
   end

   while continue do
	  --# start a page, fails if no ink/paper
	  while not printer.newPage() do
		 print("Check printer...")
		 local event, key = os.pullEvent("key")
		 if key == keys.delete then
			print("Print aborted")
			return
		 end
	  end

	  --# get the page size (in chars)
	  --# must be called after newPage()
	  local width, height = printer.getPageSize()

	  --# split contents into lines if not done yet
	  --# assumes all pages same width
	  if not lines then
		 lines = wrapString(contents, width)
		 print("Printing "..tostring(math.ceil(#lines / height)).." pages")
	  end

	  --# no page number on first page
	  --# first page is also title if made into book
	  if page == 1 then
		 printer.setPageTitle(title)
	  else
		 printer.setPageTitle(title.." "..tostring(page))
	  end

	  --# work out the lines to print on this page
	  local lastLine = page * height
	  local firstLine = lastLine - height + 1

	  --# if at end trim lastLine and flag drop out
	  if lastLine >= #lines then
		 continue = false
		 lastLine = #lines
	  end

	  --# write the lines to the page
	  for line = firstLine, lastLine, 1 do
		 printer.setCursorPos(1, line - firstLine + 1)
		 printer.write(lines[line])
	  end

	  --# next page
	  page = page + 1

	  --# spit page into out tray
	  while not printer.endPage() do
		 print("Empty tray...")
		 local event, key = os.pullEvent("key")
		 if key == keys.delete then
			print("Print aborted")
			return
		 end
	  end
   end

   print("Print complete")
end


local function readFile(path)
   local hFile = fs.open(path, "r")
   assert(hFile, "Could not open file "..path)

   local contents = hFile.readAll()

   hFile.close()

   assert(contents, "Could not read file "..path)
   return contents
end


if #args < 1 then
   print("Usage: "..fs.getName(shell.getRunningProgram()).." filePath [printer]")
else
   printOut(fs.getName(args[1]), readFile(args[1]), args[2])
end
Customize as desired.
Its kind of you to help him, but the forums are mainly to help others. As Lyqyd said, we will never do the code for you, but we will alaways help in any matter, like that, new users learn faster and better.
I agree! I just want general methods :)/>