CSS parsing error when creating pdf with xhtml2pdf pisa.CreatePDF()
Asked Answered
C

3

8

I am following the xhtml2pdf guides.

I have used one of the sample html files and saved as test.html:

<html>
<head>
<style>
    @page {
        size: a4 portrait;
        @frame header_frame {           # Static Frame
            -pdf-frame-content: header_content;
            left: 50pt; width: 512pt; top: 50pt; height: 40pt;
        }
        @frame content_frame {          # Content Frame
            left: 50pt; width: 512pt; top: 90pt; height: 632pt;
        }
        @frame footer_frame {           # Another static Frame
            -pdf-frame-content: footer_content;
            left: 50pt; width: 512pt; top: 772pt; height: 20pt;
        }
    }
</style>
</head>

<body>
    <!-- Content for Static Frame 'header_frame' -->
    <div id="header_content">Lyrics-R-Us</div>

    <!-- Content for Static Frame 'footer_frame' -->
    <div id="footer_content">(c) - page <pdf:pagenumber>
        of <pdf:pagecount>
    </div>

    <!-- HTML Content -->
    To PDF or not to PDF
</body>
</html>

I then read in this file as a string and attempt to create a pdf:

with open('test.html','r') as f:
    sourceHtml = f.read()
outputFilename = "test.pdf"
resultFile = open(outputFilename , "w+b")
pisaStatus = pisa.CreatePDF(sourceHtml,dest=resultFile)
resultFile.close()

However, I get the following error traceback:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\xhtml2pdf\document.py", line 89, in pisaDocument
    encoding, context=context, xml_output=xml_output)
  File "C:\Python27\lib\site-packages\xhtml2pdf\document.py", line 57, in pisaStory
    pisaParser(src, context, default_css, xhtml, encoding, xml_output)
  File "C:\Python27\lib\site-packages\xhtml2pdf\parser.py", line 660, in pisaParser
    context.parseCSS()
  File "C:\Python27\lib\site-packages\xhtml2pdf\context.py", line 428, in parseCSS
    self.css = self.cssParser.parse(self.cssText)
  File "C:\Python27\lib\site-packages\xhtml2pdf\w3c\cssParser.py", line 431, in parse
    src, stylesheet = self._parseStylesheet(src)
  File "C:\Python27\lib\site-packages\xhtml2pdf\w3c\cssParser.py", line 530, in _parseStylesheet
    src, atResults = self._parseAtKeyword(src)
  File "C:\Python27\lib\site-packages\xhtml2pdf\w3c\cssParser.py", line 650, in _parseAtKeyword
    src, result = self._parseAtPage(src)
  File "C:\Python27\lib\site-packages\xhtml2pdf\w3c\cssParser.py", line 746, in _parseAtPage
    src, atResults = self._parseAtKeyword(src)
  File "C:\Python27\lib\site-packages\xhtml2pdf\w3c\cssParser.py", line 657, in _parseAtKeyword
    src, result = self._parseAtFrame(src)
  File "C:\Python27\lib\site-packages\xhtml2pdf\w3c\cssParser.py", line 766, in _parseAtFrame
    src, properties = self._parseDeclarationGroup(src.lstrip())
  File "C:\Python27\lib\site-packages\xhtml2pdf\w3c\cssParser.py", line 1017, in _parseDeclarationGroup
    raise self.ParseError('Declaration group closing \'}\' not found', src, ctxsrc)
xhtml2pdf.w3c.cssParser.CSSParseError: Declaration group closing '}' not found:: (u'{           ', u'# Static Frame\n     ')

This seems to imply that there is a missing } in the css code. However it seems fine to me. I am using windows so I thought it might be to do with \r\n line EOLs - but it isn't.

Can anyone see what I'm doing wrong?

Codger answered 24/5, 2014 at 14:9 Comment(4)
The example does not have multiple CSS property definitions on a single line, where yours has. While it would be a bummer if that is the problem, it's still worth trying.Spaghetti
@Spaghetti Do you mean the opposite? When I put all the CSS definitions in a single line it works (@page {...} with comments removed). Either way, thanks for inspiring me to investigate that :-). Post as an answer if you want - or I will in a while.Codger
The opposite? Yours contains left: 50pt; width: 512pt; .., the example does not. If this indeed was the problem, feel free to post it as answer, as it was only a guess of mine. You could also file a bug for xhtml2pdf, because this notation really should not be fatal.Spaghetti
Ok, perhaps it is to do with the way I read in test.html. Thanks anyway.Codger
O
5

The problem you are hitting is completely unrelated to the error, but still involves your CSS.

Comments in CSS are created using /* and */, not # like in Python. If you remove the "comments" from your file, it is parsed and created by pisa. This is also why your single line example worked, they weren't included.

Oyler answered 24/5, 2014 at 15:50 Comment(2)
Can you confirm that the example CSSs on github will not work either?Spaghetti
Thanks - I suggested an update to the usage.rst file on github.Codger
C
5

When I put all the CSS definitions in a single line, it works without error:

<html>
<head>
<style>
    @page {size: a4 portrait; @frame header_frame {-pdf-frame-content: header_content; left: 50pt; width: 512pt; top: 50pt; height: 40pt;} @frame content_frame { left: 50pt; width: 512pt; top: 90pt; height: 632pt;} @frame footer_frame { -pdf-frame-content: footer_content; left: 50pt; width: 512pt; top: 772pt; height: 20pt;}}
</style>
</head>
...

Note, if I separate them out so each definition has a separate line, it hangs.

Codger answered 24/5, 2014 at 15:9 Comment(1)
It is indeed the opposite of what I presumed was the error, and most certainly not what is shown in the on-line examples. You might want to file a bug on this.Spaghetti
O
5

The problem you are hitting is completely unrelated to the error, but still involves your CSS.

Comments in CSS are created using /* and */, not # like in Python. If you remove the "comments" from your file, it is parsed and created by pisa. This is also why your single line example worked, they weren't included.

Oyler answered 24/5, 2014 at 15:50 Comment(2)
Can you confirm that the example CSSs on github will not work either?Spaghetti
Thanks - I suggested an update to the usage.rst file on github.Codger
D
0

You can apply CSS inside HTML

 <!DOCTYPE html>
<html lang="en">
  <head>
    <style type="text/css">
      /* Style the header: fixed position (always stay at the top) */
      .header {
        position: fixed;
        top: 0;
        z-index: 1;
        text-align: center;
        width: 100%;
        background-color: #f1f1f1;
      }

      .content {
        font-size: large;
        text-align: center;
        text-emphasis-color: red;
      }
    </style>
  </head>
  <body>
    <div class="header">
    </div>

    <div class="content">
    </div>
  </body>
</html>

External CSS/Stylesheets are not applicable to xhtml2pdf

Declass answered 8/12, 2021 at 15:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.