2

Alright, I've been coming here for help for years, and now I finally have a question that isn't covered. I'm trying to take a .txt file from my AS/400 print queue(no problems here), and output each "page" as a PDF(the next step is merging them into one file). Ive got the formatting part down, and I can create a single page document correctly with no issues.

I've taken the code that generates the single pages, and expanded it to handle files that contain multiple pages when "printed" with adobe writer. The code below crashes python (report error to windows) at a specific spot, and I'm just looking for clarification on why. My current code is very sloppy, I'm mainly looking for functionality first, and I do plan on rewriting most of this.

The input()'s and print()'s are there so I can see where any errors occur

The section that casuses the crash:

for line in lineDict[x]:
    context.show_text(line)
    yPos += 14
    context.move_to(10, yPos)
    context.show_page()
    surface.finish()
    print(line) #Testing where crash occurs 

Below is the full program

import cairo
width, height = 792,612
myText=open("QSYSPRT120972.txt","r")
yPos = 10
lineList=[]
lineDict=dict()
x=0
surface = cairo.PDFSurface(outPDF+".pdf", width, height)
context = cairo.Context(surface)
context.set_source_rgb( 1, 1, 1)
context.rectangle(0, 0, width, height)
context.fill()
context.set_font_size(8)
context.select_font_face( "Courier")
context.move_to(10, yPos)
context.set_source_rgb(0, 0, 0)

lineList=[str(line.replace('\x00', '').encode("ascii", "ignore")).lstrip('b\'').replace('\\n','').rstrip("'").replace(' ','  ') for line in myText]
outPDF=lineList[0]
outPDF=outPDF[0:6]#Get the file name from the first line on each page
input("Press Enter to continue")
print(lineList[0])
while '' in lineList:
    lineList.remove('')
ll=';'.join(lineList)
#print(ll)
LoL=ll.split(outPDF)
LoL.remove('')
input("Press enter")
for pages in LoL:
    yPos = 10
    outPDF=lineList[0]
    outPDF=outPDF[0:6]
    LoL[x]=outPDF+lol[x]
    LoL[x].split(";;")
    outPDF=outPDF+str(x)# Not the best way to do this, but its okay for now
    tempLOL=LoL[x]
    tempLOL=tempLOL.split(";")
    while '' in tempLOL:
    tempLOL.remove('')
    print(tempLOL) #More testing
    lineDict[x]=tempLOL
    for line in lineDict[x]: #Crash happens here. Works fine if I just print each line to console
        context.show_text(line)
        yPos += 14
        context.move_to(10, yPos)
        context.show_page()
        surface.finish()
        print(line) #Testing where crash occurs 
    x+=1
    print("File: "+outPDF+".pdf Created!")
#print(lineDict)
input()

Version that only outputs single paged PDFs

import cairo
width, height = 792,612
myText=open("QSYSPRT120972.txt","r")
yPos = 10
lineList=[]

lineList=[str(line.replace('\x00', '').encode("ascii", "ignore")).lstrip('b\'').replace('\\n','').rstrip("'").replace(' ','  ') for line in myText]
outPDF=lineList[0]
outPDF=outPDF[0:6]
surface = cairo.PDFSurface( outPDF+".pdf", width, height)
context = cairo.Context( surface)
context.set_source_rgb( 1, 1, 1)
context.rectangle( 0, 0, width, height)
context.fill()
context.set_font_size(8)
context.select_font_face( "Arial")
context.move_to( 10, yPos)
context.set_source_rgb( 0, 0, 0)
while '' in lineList:
    lineList.remove('')

for line in lineList:
    context.show_text(line)
    yPos += 14
    context.move_to(10, yPos)
context.show_page()
surface.finish()
print("File: "+outPDF+".pdf Created!")

This is really the only relevant question I've found regarding the issue, but from all the print()'s I'm doing, I know that my lists are set to the correct data each iteration.

python: open file, feed line to list, process list data

FWIW I'm on Windows XP.

Thanks.

Community
  • 1
  • 1
  • So where the crash occurs and what's the error message? And what's `context`? – J0HN Jun 17 '13 at 18:33
  • The crash occurs when i do the for loop through my dictionary. I'm not getting any type of error within python, rather the "Windows Error Reporting" dialog comes up, and the only information I'm getting from that is that python.exe is crashing, and that the cairo module is causing it. `context` is a method of cairo – pHorniCaiTe Jun 17 '13 at 18:41
  • You either omitted the part of code where `context` is defined, or you haven't initialized it. You must create a context using something like `context = cairo.Context()` – J0HN Jun 17 '13 at 18:45
  • Sorry about that, forgot part of the code. Added to the OP. I have initialized `context` and `surface`. I'll post the version that only generates one page in a moment. – pHorniCaiTe Jun 17 '13 at 18:52
  • Try moving `surface.finish()` outside the loop – J0HN Jun 17 '13 at 18:57
  • I moved it into the loop 1 higher tham the one it was in, no longer getting the error, but python still exits at the same spot. Added some inputs, and its closing at `for line in lineDict[x]: context.show_text(line)` on the first iteration. Your suggestion does give me an idea though. I may have to initialize `surface` withtin the first `for` loop depending on how `surface.finish` executes. – pHorniCaiTe Jun 17 '13 at 19:04
  • Move it outside the outermost loop. `surface.finish` frees cairo internal resources needed for drawing, so you are basically kicking the ground off the cairo python bindings. I'm not familiar with cairo btw, but I think you should initialize surface and context once for *file*, so it should be outside of any page loop. – J0HN Jun 17 '13 at 19:07
  • 1
    Thanks alot! Moved everything out of the loops, and now cairo creates a single file with multiple pages. Not sure how that happened to be honest, earlier I was getting one page with 45 pages worth of text just not rendering. – pHorniCaiTe Jun 17 '13 at 19:23
  • 1
    I'll write an answer later (maybe :)) In short, you created a single drawing surface and let cairo to do the job of laying out the pages. The source of error you had is in the fact that you were deallocating resources in the middle of drawing, so the cairo lib (which is written in c/c++ I assume) just crashed with segmentation fault or something like that. – J0HN Jun 17 '13 at 19:39

0 Answers0