In short, I must add the entire log to the page, how do I split up the massive string so it can fit on the pages?
This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Splitting a massive string to print with
Started by samdeman22, 06 March 2013 - 08:59 AMPosted 06 March 2013 - 09:59 AM
So I have a log system where I add lines to a file through an API, but when I want to print part of it I thought I'd be able to use fs.readLine() with a number to read a specific line, but it apparently doesn't work like that (it just reads the 'next' line?).
In short, I must add the entire log to the page, how do I split up the massive string so it can fit on the pages?
In short, I must add the entire log to the page, how do I split up the massive string so it can fit on the pages?
Posted 06 March 2013 - 10:06 AM
Do you have any code we can see to get a better understanding?
Posted 06 March 2013 - 10:12 AM
ok, I show you then
its not quite finished as you'll see (the actual printing part is missing)
function printLog(log, fromLn, copies)
if open == true then
error("Log must be ended before printing")
end
--printer setup
local side = nil
local sides = { 1 = "front", 2 = "back", 3 = "left", 4 = "right", 5 = "top", 6 = "bottom" }
local no = 1
for i = 1, 6 do
if no == 1 then
side = sides[no]
elseif no == 2 then
side = sides[no]
elseif no == 3 then
side = sides[no]
elseif no == 4 then
side = sides[no]
elseif no == 5 then
side = sides[no]
elseif no == 6 then
side = sides[no]
else
error("no printer found")
end
end
local p = peripheral.wrap(side)
h = fs.open("log/"..log..".log", r)
local printstr = nil
for i = 1, fromLn do
h.readLine()
end
printstr = h.readAll()
fs.close()
end
its not quite finished as you'll see (the actual printing part is missing)
Posted 06 March 2013 - 10:52 AM
h = fs.open("log/"..log..".log", r)
When opening a file the mode must be in string format like so:
h = fs.open("log/"..log..".log", "r")
Also since you defined the file as "h", you must close it like so:
h.close()
I think storing all the data in a table then printing it will be your best bet
EDIT: "printing" should be indexing (Nub)
Posted 06 March 2013 - 10:57 AM
You can read the entire file into a table, line by line, then index the table to retrieve the line you want.
Posted 06 March 2013 - 12:20 PM
Yeah, I'll reshape this based on what you guys say tomorrow and show you.
Posted 06 March 2013 - 12:21 PM
Sounds like a plan :)/>
Posted 06 March 2013 - 05:52 PM
You can store the whole thing in a string and use an awesome function made by TheOriginalBit which splits it into a table with the desired length of each line. You can find it in his Extended Library api. Check it out at the programs section.
Posted 06 March 2013 - 06:23 PM
You can store the whole thing in a string and use an awesome function made by TheOriginalBit which splits it into a table with the desired length of each line. You can find it in his Extended Library api. Check it out at the programs section.
If it is the same function I am thinking of, it was not written by him, but is actually an example function found in the PIL. The one I'm thinking of is the one that's been floating around the forums for quite some time. I simply don't wish it to be misattributed if that is the case.
Posted 06 March 2013 - 07:13 PM
You can store the whole thing in a string and use an awesome function made by TheOriginalBit which splits it into a table with the desired length of each line. You can find it in his Extended Library api. Check it out at the programs section.
If it is the same function I am thinking of, it was not written by him, but is actually an example function found in the PIL. The one I'm thinking of is the one that's been floating around the forums for quite some time. I simply don't wish it to be misattributed if that is the case.
Oh, sorry if that is the case. He has it licensed in his api and told me that he did make it.
Posted 15 March 2013 - 08:40 AM
Right I've left the printing part for a while, the rest of the code is completely buggering me… here's a pastebin http://pastebin.com/YHBpSVyG and here's the code…
--The Log API 1.1
runningProgram = "test"
function openLog(name)
h = fs.open("logs/"..name..".log", "a")
end
function closeLog()
h.close()
end
--function setRunningProgram(name)
-- runningProgram = name
--end
function generateLog() --will create the Dir "log" in the root and create a .log file based on the running program (if if is not already there)
if not fs.exists("log") then
fs.mkDir("log")
end
if runningProgram == nil then
error("program not specified")
end
h = fs.open("logs/"..runningProgram..".log", "a")
h.writeLine("--- The "..runningProgram.." event log ---")
h.writeLine(" ")
h.close()
end
function addEntry(type, str)
local time = os.time()
local day = os.day()
h.writeLine("["..day.."]".."["..time.."]".."["..type.."] | #"..str)
end
function startLog()
open = true
local time = os.time()
local day = os.day()
openLog()
h.writeLine("["..day.."]".."["..time.."] | #STARTING LOG")
end
function endLog()
open = false
local time = os.time()
local day = os.day()
h.writeLine("["..day.."]".."["..time.."] | #ENDING LOG")
end
function setPrinterSide(side)
printside = side
end
function printLog(log, fromLn, copies)
if open == true then
error("Log must be ended before printing")
end
end
Posted 15 March 2013 - 08:44 AM
It comes up with an error "log:5:attempt to concatenate nil and string" in this case its talking about the line h = fs.open("logs/"..name..".log", "a") which is strange because it actually gets past that part EVERY time and outputs the generateLog() stuff into the log properly.
Posted 15 March 2013 - 08:56 AM
this is when calling log.openLog("test")
Posted 15 March 2013 - 10:09 AM
The startLog function calls openLog with no parameters.
Posted 15 March 2013 - 12:11 PM
Thanks, that makes sense.
Posted 17 March 2013 - 02:05 AM
Ok, returning to the printLog function, I have got it so it reads the entire thing line by line into a table, now printing it in a way that looks good, eugh.
what was the name of the function? there are too many to choose from!You can store the whole thing in a string and use an awesome function made by TheOriginalBit which splits it into a table with the desired length of each line. You can find it in his Extended Library api. Check it out at the programs section.
Posted 17 March 2013 - 02:21 AM
also could someone make me a function that gets how many pages are needed based on the length of the string?
Posted 30 March 2013 - 07:03 AM
Right, I'm hoping this will be the final iteration of the printLog(log, side, fromLn, toLn) function
-- a function you cant access ;P
local function round(num idp)
local mult = 10 ^ (idp or 0)
return (math.floor(num * mult + 0.5) / mult)
end
function printLog(log, side, fromLn, toLn)
if open == true then
error("Log must be ended before printing")
end
if not fs.exists( "logs/"..log..".log") then
error("Log does not exist")
end
h = fs.open("logs/"..log..".log", "r")
page = {}
while h.readLine() ~= nil do
local ln = h.readLine()
table.insert(page, ln)
end
p = peripheral.wrap(side)
local paper = p.getPaperLevel()
local ink = p.getInkLevel()
local w, h = p.getPageSize()
local doc = {}
for i = fromLn, toLn do
table.insert(doc, page[i])
end
local length = 0
for i = 0, #doc do
length = length + doc[i]
end
local size = w*h
local pages = round(length/size, 0)
if pages > paper then
error("not enough paper")
end
if pages > ink then
error("not enough ink")
end
for i = 0, #doc do
p.write(doc[i])
end
end
This looks good to me but on loading the API I get "bios:338: [string "log"]:59: ' ) ' expected". Why ?Posted 30 March 2013 - 07:05 AM
ok, fixed the error as soon as I posted it *facepalm, I forgot a comma on the round(num, idp) function :)/>
Posted 30 March 2013 - 07:13 AM
ok, there are some things to do yet with the printer stuff :(/> will work on it tho!
Posted 30 March 2013 - 08:21 AM
Aha, a new problem,
-- a function you cant access ;P
local function round(num, idp)
local mult = 10 ^ (idp or 0)
return (math.floor(num * mult + 0.5) / mult)
end
function printLog(log, side, fromLn, toLn)
if open == true then
error("Log must be ended before printing")
end
if not fs.exists( "logs/"..log..".log") then
error("Log does not exist")
end
h = fs.open("logs/"..log..".log", "r")
page = {}
while h.readLine() ~= nil do
local ln = h.readLine()
table.insert(page, ln)
end
p = peripheral.wrap(side)
p.newPage()
local paper = p.getPaperLevel()
local ink = p.getInkLevel()
local w, h = p.getPageSize()
local doc = {}
for i = fromLn, toLn do
table.insert(doc, page[i])
end
local length = 0
for i = 0, #doc do
length = length + #doc[i]
end
local size = w*h
local pages = round(length/size, 0)
if pages > paper then
error("not enough paper")
end
if pages > ink then
error("not enough ink")
end
for i = 0, pages do
p.newPage()
p.setPageTitle(log.." page:"..i)
for indx = 0, size do
p.write(doc[indx])
end
p.endPage()
end
end
"log:91 attempt to get length of nil" it says, any suggestions?Posted 30 March 2013 - 08:31 AM
You're starting the loop
if there isn't a value at doc[0], it can't get the length of it.
for i = 0, #doc do
length = length + #doc[i]
end
at 0 instead of 1.if there isn't a value at doc[0], it can't get the length of it.
Posted 30 March 2013 - 11:43 AM
I maybe thought about that briefly and then forgot it, thanks, will try this soon, expect to see the log API out soon!You're starting the loopat 0 instead of 1.for i = 0, #doc do length = length + #doc[i] end
if there isn't a value at doc[0], it can't get the length of it.
Posted 30 March 2013 - 12:55 PM
nope, this time it actually runs, but it just fills the tray with 5 blank pages :/ Can anyone suggest a better print function to what I have? I need to be able to print a file from a certain line to a certain line so basically (log, side, fromLn, toLn) where log is the file, side is the printer, and from/toLn are the from/to line.
Posted 30 March 2013 - 12:57 PM
oh and you must use this at the beginning
open is defined in the rest of the API
if open == true then
error("Log must be ended before printing")
end
if not fs.exists( "logs/"..log..".log") then
error("Log does not exist")
end
h = fs.open("logs/"..log..".log", "r")
ok :)/>open is defined in the rest of the API
Posted 31 March 2013 - 02:31 AM
could the reason it prints blank pages be:
for i = 0, pages do
p.newPage()
p.setPageTitle(log.." page:"..i)
for indx = 0, size do
p.write(doc[indx])
end
p.endPage()
end
should this be for i = 1, pages and indx = 1, size rather than 0, pages and 0, size?Posted 31 March 2013 - 11:13 AM
Yes.. doc table doesn't have a 0 index
Posted 02 April 2013 - 07:20 AM
ok, still haven't had a chance to test this out but you know, I need to get it in my head "tables do not have a position:0". :)/>Yes.. doc table doesn't have a 0 index