xhtml2pdf 0.2.23__tar.gz → 0.2.25__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xhtml2pdf-0.2.23/xhtml2pdf.egg-info → xhtml2pdf-0.2.25}/PKG-INFO +179 -85
- xhtml2pdf-0.2.25/README.rst +298 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/pyproject.toml +12 -4
- xhtml2pdf-0.2.25/tests/test_bidi.py +187 -0
- xhtml2pdf-0.2.25/tests/test_block_margins.py +88 -0
- xhtml2pdf-0.2.25/tests/test_block_width.py +86 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_flex.py +5 -1
- xhtml2pdf-0.2.25/tests/test_font_isolation.py +90 -0
- xhtml2pdf-0.2.25/tests/test_frame_align.py +68 -0
- xhtml2pdf-0.2.25/tests/test_frame_pages.py +62 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_inline_box.py +20 -2
- xhtml2pdf-0.2.25/tests/test_optional_dependencies.py +85 -0
- xhtml2pdf-0.2.25/tests/test_page_numbering.py +80 -0
- xhtml2pdf-0.2.25/tests/test_page_padding.py +79 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_reportlab.py +69 -1
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_reportlab_api.py +66 -1
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_right_to_left_font_support.py +179 -9
- xhtml2pdf-0.2.25/tests/test_signatures.py +213 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_table_border_radius.py +23 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_tables.py +168 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_tags.py +88 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_utils.py +17 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/__init__.py +1 -1
- xhtml2pdf-0.2.25/xhtml2pdf/_bidi_data.py +578 -0
- xhtml2pdf-0.2.25/xhtml2pdf/bidi.py +654 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/builders/block.py +211 -6
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/builders/signs.py +15 -2
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/context.py +107 -69
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/default.py +1 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/document.py +85 -60
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/paragraph.py +3 -1
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/parser.py +70 -6
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/properties.py +5 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/reportlab_paragraph.py +298 -8
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/tables.py +9 -1
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/tags.py +16 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/util.py +14 -46
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/xhtml2pdf_reportlab.py +308 -13
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25/xhtml2pdf.egg-info}/PKG-INFO +179 -85
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf.egg-info/SOURCES.txt +12 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf.egg-info/requires.txt +8 -3
- xhtml2pdf-0.2.23/README.rst +0 -207
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/AUTHORS.rst +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/LICENSE.txt +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/MANIFEST.in +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/setup.cfg +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_asian_font_support.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_block_box.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_cli.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_css_media_rule.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_css_parser.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_css_variables.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_document.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_files.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_flex_flowable.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_flex_layout.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_fonts.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_http.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_inline_block.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_paragraph.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_paragraph_height.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_parser.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_pdf.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_position.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_reportlab_paragraph.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_resource_policy.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_security_limits.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_selectors.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_special_css.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_table_css.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_update_face_name.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_watermarks.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_word_breaking.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/tests/test_wsgi.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/__main__.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/builders/__init__.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/builders/flex.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/builders/flex_layout.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/builders/position.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/builders/watermarks.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/charts.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/config/__init__.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/config/httpconfig.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/config/resources.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/files.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/pdf.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/pisa.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/w3c/__init__.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/w3c/css.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/w3c/cssDOMElementInterface.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/w3c/cssParser.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/w3c/cssSpecial.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/w3c/css_variables.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf/wsgi.py +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf.egg-info/dependency_links.txt +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf.egg-info/entry_points.txt +0 -0
- {xhtml2pdf-0.2.23 → xhtml2pdf-0.2.25}/xhtml2pdf.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xhtml2pdf
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.25
|
|
4
4
|
Summary: PDF generator using HTML and CSS
|
|
5
5
|
Author-email: Dirk Holtwick <dirk.holtwick@gmail.com>
|
|
6
6
|
Maintainer-email: Luis Zarate <luisza14@gmail.com>, Timo Brembeck <opensource@timo.brembeck.email>
|
|
@@ -246,17 +246,20 @@ License-File: AUTHORS.rst
|
|
|
246
246
|
Requires-Dist: arabic-reshaper>=3.0.0
|
|
247
247
|
Requires-Dist: html5lib>=1.1
|
|
248
248
|
Requires-Dist: Pillow>=8.1.1
|
|
249
|
-
Requires-Dist: pyHanko>=0.12.1
|
|
250
|
-
Requires-Dist: pyhanko-certvalidator>=0.19.5
|
|
251
249
|
Requires-Dist: pypdf>=3.1.0
|
|
252
|
-
Requires-Dist: python-bidi>=0.5.0
|
|
253
250
|
Requires-Dist: reportlab<6,>=4.4.9
|
|
254
251
|
Requires-Dist: svglib>=1.2.1
|
|
252
|
+
Provides-Extra: signing
|
|
253
|
+
Requires-Dist: pyHanko>=0.37.0; extra == "signing"
|
|
254
|
+
Requires-Dist: pyhanko-certvalidator>=0.32.1; extra == "signing"
|
|
255
|
+
Provides-Extra: all
|
|
256
|
+
Requires-Dist: xhtml2pdf[signing]; extra == "all"
|
|
255
257
|
Provides-Extra: pycairo
|
|
256
258
|
Requires-Dist: reportlab[pycairo]<6,>=4.4.9; extra == "pycairo"
|
|
257
259
|
Provides-Extra: renderpm
|
|
258
260
|
Requires-Dist: xhtml2pdf[pycairo]; extra == "renderpm"
|
|
259
261
|
Provides-Extra: test
|
|
262
|
+
Requires-Dist: xhtml2pdf[signing]; extra == "test"
|
|
260
263
|
Requires-Dist: tomli>=2.0.1; python_version < "3.11" and extra == "test"
|
|
261
264
|
Requires-Dist: tox; extra == "test"
|
|
262
265
|
Requires-Dist: coverage>=5.3; extra == "test"
|
|
@@ -276,6 +279,9 @@ Dynamic: license-file
|
|
|
276
279
|
XHTML2PDF
|
|
277
280
|
=========
|
|
278
281
|
|
|
282
|
+
**Write the document in HTML and CSS. Get a PDF.** Pure Python on top of
|
|
283
|
+
ReportLab, with no browser to install or keep running.
|
|
284
|
+
|
|
279
285
|
.. image:: https://img.shields.io/pypi/v/xhtml2pdf?label=PyPI&logo=PyPI&logoColor=white&color=blue
|
|
280
286
|
:target: https://pypi.python.org/pypi/xhtml2pdf
|
|
281
287
|
:alt: PyPI version
|
|
@@ -304,152 +310,240 @@ XHTML2PDF
|
|
|
304
310
|
:target: http://xhtml2pdf.readthedocs.io/en/latest/?badge=latest
|
|
305
311
|
:alt: Read the Docs
|
|
306
312
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
313
|
+
xhtml2pdf turns HTML5 and CSS into PDF on top of the ReportLab toolkit. Anyone
|
|
314
|
+
who can build a web page can build an invoice, a report, a ticket or a book
|
|
315
|
+
with it, from a Django or Flask template or from a plain string, and render
|
|
316
|
+
it anywhere Python runs.
|
|
311
317
|
|
|
312
|
-
|
|
318
|
+
Made with xhtml2pdf
|
|
319
|
+
===================
|
|
313
320
|
|
|
314
|
-
|
|
315
|
-
|
|
321
|
+
Every page below is an HTML document converted by xhtml2pdf, fonts, charts,
|
|
322
|
+
barcodes and all.
|
|
316
323
|
|
|
317
|
-
|
|
324
|
+
.. |annual-report| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/annual-report.png
|
|
325
|
+
:width: 180px
|
|
326
|
+
:alt: An annual report with a cover photo, key figures and charts
|
|
318
327
|
|
|
319
|
-
|
|
328
|
+
.. |invoice| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/invoice.png
|
|
329
|
+
:width: 180px
|
|
330
|
+
:alt: An invoice with a long table of line items and totals
|
|
320
331
|
|
|
321
|
-
|
|
332
|
+
.. |book| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/book.png
|
|
333
|
+
:width: 180px
|
|
334
|
+
:alt: The cover of a novella, a full-page illustration with the title
|
|
322
335
|
|
|
336
|
+
.. |poster| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/poster.png
|
|
337
|
+
:width: 180px
|
|
338
|
+
:alt: A concert poster with a city skyline and a strip of dates
|
|
323
339
|
|
|
340
|
+
.. |certificate| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/certificate.png
|
|
341
|
+
:width: 180px
|
|
342
|
+
:alt: A certificate of completion in landscape with a QR code
|
|
324
343
|
|
|
325
|
-
|
|
326
|
-
|
|
344
|
+
.. |receipt-pos| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/receipt-pos.png
|
|
345
|
+
:width: 180px
|
|
346
|
+
:alt: A narrow point-of-sale receipt in a monospaced font
|
|
327
347
|
|
|
328
|
-
|
|
348
|
+
.. |boarding-pass| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/boarding-pass.png
|
|
349
|
+
:width: 180px
|
|
350
|
+
:alt: An airline boarding pass with a barcode and a QR code
|
|
329
351
|
|
|
330
|
-
|
|
352
|
+
.. |event-ticket| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/event-ticket.png
|
|
353
|
+
:width: 180px
|
|
354
|
+
:alt: A concert ticket with a stub and a barcode
|
|
331
355
|
|
|
356
|
+
+-----------------+-----------------+-----------------+-----------------+
|
|
357
|
+
| |annual-report| | |invoice| | |book| | |poster| |
|
|
358
|
+
+-----------------+-----------------+-----------------+-----------------+
|
|
359
|
+
| |certificate| | |receipt-pos| | |boarding-pass| | |event-ticket| |
|
|
360
|
+
+-----------------+-----------------+-----------------+-----------------+
|
|
332
361
|
|
|
333
|
-
|
|
334
|
-
|
|
362
|
+
Quick start
|
|
363
|
+
===========
|
|
335
364
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
pip install xhtml2pdf
|
|
365
|
+
.. code:: bash
|
|
339
366
|
|
|
367
|
+
pip install xhtml2pdf[all]
|
|
340
368
|
|
|
341
|
-
|
|
342
|
-
============
|
|
369
|
+
.. code:: python
|
|
343
370
|
|
|
344
|
-
|
|
371
|
+
from xhtml2pdf import pisa
|
|
345
372
|
|
|
346
|
-
|
|
373
|
+
html = """
|
|
374
|
+
<style>
|
|
375
|
+
@page { size: a4; margin: 2cm;
|
|
376
|
+
@frame footer { -pdf-frame-content: footer; bottom: 1cm;
|
|
377
|
+
margin-left: 2cm; margin-right: 2cm; height: 1cm } }
|
|
378
|
+
h1 { color: #204a87 }
|
|
379
|
+
</style>
|
|
380
|
+
<h1>Hello, PDF</h1>
|
|
381
|
+
<p>Written in HTML, laid out by CSS.</p>
|
|
382
|
+
<div id="footer">Page <pdf:pagenumber /> of <pdf:pagecount /></div>
|
|
383
|
+
"""
|
|
347
384
|
|
|
348
|
-
|
|
349
|
-
|
|
385
|
+
with open("hello.pdf", "wb") as output:
|
|
386
|
+
result = pisa.CreatePDF(html, dest=output)
|
|
387
|
+
print("errors:", result.err)
|
|
350
388
|
|
|
351
|
-
|
|
352
|
-
in combination with the ``PyCairo`` extra dependency:
|
|
389
|
+
Or from the command line:
|
|
353
390
|
|
|
354
|
-
|
|
391
|
+
.. code:: bash
|
|
355
392
|
|
|
356
|
-
|
|
357
|
-
the C ``RenderPM`` backend, so ``pycairo`` is now the only backend.
|
|
393
|
+
xhtml2pdf report.html report.pdf
|
|
358
394
|
|
|
395
|
+
What it can do
|
|
396
|
+
==============
|
|
359
397
|
|
|
360
|
-
|
|
361
|
-
============
|
|
398
|
+
**Layout**
|
|
362
399
|
|
|
363
|
-
|
|
400
|
+
* Flexbox (``display: flex``), including containers that break across
|
|
401
|
+
pages, and ``display: inline-block``.
|
|
402
|
+
* ``position: relative``, ``absolute`` and ``fixed``, with ``z-index``.
|
|
403
|
+
* Block boxes with padding, borders and backgrounds around everything they
|
|
404
|
+
hold, ``border-radius`` on blocks, tables, cells, images and inline
|
|
405
|
+
boxes, and dashed, dotted and double borders.
|
|
406
|
+
* Tables with header rows repeated on every page, ``colspan`` and
|
|
407
|
+
``rowspan``, auto margins and widths, and rows taller than a page cut
|
|
408
|
+
between pages.
|
|
409
|
+
* Word breaking with ``overflow-wrap``, ``page-break-before``/``after``,
|
|
410
|
+
``page-break-inside: avoid`` and keeping a heading with what follows.
|
|
364
411
|
|
|
412
|
+
**CSS**
|
|
365
413
|
|
|
366
|
-
|
|
367
|
-
|
|
414
|
+
* Selectors up to Level 4: ``:not()``, ``:is()``, ``:where()``, ``:has()``,
|
|
415
|
+
``:nth-child()`` and attribute selectors.
|
|
416
|
+
* Custom properties with ``var()``, ``em``/``rem``/percent units, and colours
|
|
417
|
+
with an alpha channel.
|
|
418
|
+
* ``@font-face`` with TrueType and OpenType fonts, matched per character, so
|
|
419
|
+
a paragraph that mixes scripts finds a font for each of them.
|
|
368
420
|
|
|
369
|
-
|
|
421
|
+
**Pages**
|
|
370
422
|
|
|
371
|
-
|
|
423
|
+
* ``@page`` sizes and margins, named page templates and left/right pages,
|
|
424
|
+
background images, and frames for headers, footers and columns.
|
|
425
|
+
* Page numbers and page counts, watermarks and backgrounds from an image or
|
|
426
|
+
another PDF.
|
|
372
427
|
|
|
428
|
+
**Navigation**
|
|
373
429
|
|
|
374
|
-
|
|
375
|
-
|
|
430
|
+
* Tables of contents with dot leaders, more than one per document,
|
|
431
|
+
clickable entries and a PDF outline (bookmarks).
|
|
432
|
+
* Links to any element by ``id``, to other files and to the web.
|
|
376
433
|
|
|
377
|
-
|
|
434
|
+
**International text**
|
|
378
435
|
|
|
379
|
-
|
|
436
|
+
* Right-to-left documents in Arabic, Hebrew, Persian and Urdu, laid out with
|
|
437
|
+
a pure-Python implementation of the Unicode Bidirectional Algorithm that
|
|
438
|
+
passes the whole of the Unicode conformance suites.
|
|
439
|
+
* Chinese, Japanese and Korean, Cyrillic and Greek, with the document's
|
|
440
|
+
language written to the PDF.
|
|
380
441
|
|
|
381
|
-
|
|
442
|
+
**Graphics and PDF features**
|
|
382
443
|
|
|
383
|
-
|
|
444
|
+
* SVG images, bar, line and pie charts, and barcodes and QR codes.
|
|
445
|
+
* Fillable form fields, encryption with passwords and permissions, and
|
|
446
|
+
digital signatures (simple and PAdES) through pyHanko.
|
|
384
447
|
|
|
385
|
-
|
|
386
|
-
xhtml2pdf in editable mode with the ``test``, ``docs`` and ``release``
|
|
387
|
-
extras (the latter brings in ``build`` and ``twine``), and installs the
|
|
388
|
-
pre-commit hooks. Run it and skip to activating the environment::
|
|
448
|
+
**Safe by default**
|
|
389
449
|
|
|
390
|
-
|
|
391
|
-
|
|
450
|
+
* A document cannot read local files outside its directory or reach
|
|
451
|
+
internal network addresses, and ``ResourceAccessPolicy.server()`` adds
|
|
452
|
+
limits on size, nesting and time for HTML from untrusted sources. See
|
|
453
|
+
`Security <https://xhtml2pdf.readthedocs.io/en/latest/security.html>`__.
|
|
392
454
|
|
|
393
|
-
|
|
455
|
+
Documentation
|
|
456
|
+
=============
|
|
394
457
|
|
|
395
|
-
|
|
458
|
+
The documentation is on `Read the Docs <http://xhtml2pdf.readthedocs.io>`__,
|
|
459
|
+
and what changed in each version is in the `Release Notes
|
|
460
|
+
<https://xhtml2pdf.readthedocs.io/en/latest/release-notes.html>`__. Help
|
|
461
|
+
improving it is welcome; a good place to start is
|
|
462
|
+
``docs/source/quickstart.rst``.
|
|
396
463
|
|
|
397
|
-
|
|
464
|
+
Installation
|
|
465
|
+
============
|
|
398
466
|
|
|
399
|
-
|
|
467
|
+
.. code:: bash
|
|
400
468
|
|
|
401
|
-
|
|
469
|
+
pip install xhtml2pdf[all]
|
|
402
470
|
|
|
403
|
-
|
|
471
|
+
Python 3.10 and newer is tested and supported. Every mandatory requirement is
|
|
472
|
+
listed in ``pyproject.toml`` and installed with xhtml2pdf; ``all`` adds the
|
|
473
|
+
optional ones: pyHanko, for digital signatures, which is also the
|
|
474
|
+
``signing`` extra on its own. ``pip install xhtml2pdf`` leaves it out:
|
|
475
|
+
asking for a signature then raises an ``ImportError`` that names the extra.
|
|
404
476
|
|
|
405
|
-
|
|
477
|
+
ReportLab needs a rendering backend to turn vector graphics into bitmaps (for
|
|
478
|
+
charts and SVG rasterised into the page). The supported one is `cairo
|
|
479
|
+
<https://cairographics.org/>`__, installed system-wide, for example through
|
|
480
|
+
the OS package manager, together with the ``pycairo`` extra:
|
|
406
481
|
|
|
407
|
-
|
|
482
|
+
.. code:: bash
|
|
408
483
|
|
|
409
|
-
pip install
|
|
484
|
+
pip install xhtml2pdf[pycairo]
|
|
410
485
|
|
|
411
|
-
|
|
486
|
+
The ``renderpm`` extra is a deprecated alias for ``pycairo``: ReportLab 5
|
|
487
|
+
removed the C ``RenderPM`` backend. See the `ReportLab installation notes
|
|
488
|
+
<https://docs.reportlab.com/install/open_source_installation/>`__.
|
|
412
489
|
|
|
413
|
-
|
|
490
|
+
Development environment
|
|
491
|
+
=======================
|
|
414
492
|
|
|
415
|
-
|
|
493
|
+
``make devsetup`` creates ``.venv``, installs xhtml2pdf in editable mode with
|
|
494
|
+
the ``test``, ``docs`` and ``release`` extras and installs the pre-commit
|
|
495
|
+
hooks:
|
|
416
496
|
|
|
417
|
-
|
|
497
|
+
.. code:: bash
|
|
418
498
|
|
|
499
|
+
make devsetup
|
|
500
|
+
source .venv/bin/activate
|
|
419
501
|
|
|
420
|
-
|
|
421
|
-
==================
|
|
502
|
+
Or by hand:
|
|
422
503
|
|
|
423
|
-
|
|
504
|
+
.. code:: bash
|
|
424
505
|
|
|
506
|
+
python -m venv .venv
|
|
507
|
+
source .venv/bin/activate
|
|
508
|
+
pip install -e .[test,docs,release]
|
|
425
509
|
|
|
426
510
|
Running tests
|
|
427
511
|
=============
|
|
428
512
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
#. Unit tests. The unit testing framework is currently minimal, but is being
|
|
432
|
-
improved on a regular basis (contributions welcome). They should run in the
|
|
433
|
-
expected way for Python's unittest module, i.e.::
|
|
513
|
+
.. code:: bash
|
|
434
514
|
|
|
435
|
-
|
|
515
|
+
make test # unit tests
|
|
516
|
+
make test-ref # reference renders for testrender
|
|
517
|
+
make test-render # compare the renders against the reference
|
|
518
|
+
make test-browser # compare against a headless browser's rendering
|
|
519
|
+
make test-all # every supported Python and ReportLab, with tox
|
|
436
520
|
|
|
437
|
-
|
|
438
|
-
|
|
521
|
+
``testrender/`` renders a set of documents and compares the pages; the
|
|
522
|
+
browser comparison scores xhtml2pdf against Chrome on the same markup, so a
|
|
523
|
+
change that moves a layout away from a browser's shows up as a regression.
|
|
524
|
+
``tools/perf`` measures time and memory.
|
|
439
525
|
|
|
440
|
-
|
|
526
|
+
Contributing
|
|
527
|
+
============
|
|
441
528
|
|
|
442
|
-
|
|
529
|
+
This project is community-led. Ideas, bug reports with a small HTML that
|
|
530
|
+
shows the problem, and pull requests are welcome on GitHub. If xhtml2pdf is
|
|
531
|
+
useful to you, look at the `test coverage
|
|
532
|
+
<https://coveralls.io/github/xhtml2pdf/xhtml2pdf>`__ for parts that are not
|
|
533
|
+
yet tested.
|
|
443
534
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
535
|
+
You can also support the project on `Patreon
|
|
536
|
+
<https://www.patreon.com/xhtml2pdf>`__ or with Bitcoin:
|
|
537
|
+
``bc1qmr0skzwx5scyvh2ql28f7gfh6l65ua250qv227``.
|
|
447
538
|
|
|
448
|
-
|
|
449
|
-
|
|
539
|
+
**Big thanks** to everyone who has worked on this project so far and to those
|
|
540
|
+
who help maintain it.
|
|
450
541
|
|
|
451
|
-
|
|
542
|
+
Alternatives
|
|
543
|
+
============
|
|
452
544
|
|
|
545
|
+
`WeasyPrint <http://weasyprint.org>`__ covers much of the same ground with a
|
|
546
|
+
different design and set of features.
|
|
453
547
|
|
|
454
548
|
History
|
|
455
549
|
=======
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
XHTML2PDF
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
**Write the document in HTML and CSS. Get a PDF.** Pure Python on top of
|
|
5
|
+
ReportLab, with no browser to install or keep running.
|
|
6
|
+
|
|
7
|
+
.. image:: https://img.shields.io/pypi/v/xhtml2pdf?label=PyPI&logo=PyPI&logoColor=white&color=blue
|
|
8
|
+
:target: https://pypi.python.org/pypi/xhtml2pdf
|
|
9
|
+
:alt: PyPI version
|
|
10
|
+
|
|
11
|
+
.. image:: https://img.shields.io/pypi/pyversions/xhtml2pdf?label=Python&logo=Python&logoColor=white
|
|
12
|
+
:target: https://www.python.org/downloads
|
|
13
|
+
:alt: Python versions
|
|
14
|
+
|
|
15
|
+
.. image:: https://img.shields.io/github/actions/workflow/status/xhtml2pdf/xhtml2pdf/tests.yml?branch=master&label=Tests&logo=github&logoColor=white
|
|
16
|
+
:target: https://github.com/xhtml2pdf/xhtml2pdf/actions/workflows/tests.yml
|
|
17
|
+
:alt: Tests
|
|
18
|
+
|
|
19
|
+
.. image:: https://img.shields.io/github/actions/workflow/status/xhtml2pdf/xhtml2pdf/linting.yml?branch=master&label=Linting&logo=github&logoColor=white
|
|
20
|
+
:target: https://github.com/xhtml2pdf/xhtml2pdf/actions/workflows/linting.yml
|
|
21
|
+
:alt: Linting
|
|
22
|
+
|
|
23
|
+
.. image:: https://img.shields.io/github/actions/workflow/status/xhtml2pdf/xhtml2pdf/spelling.yml?branch=master&label=Spelling&logo=github&logoColor=white
|
|
24
|
+
:target: https://github.com/xhtml2pdf/xhtml2pdf/actions/workflows/spelling.yml
|
|
25
|
+
:alt: Spelling
|
|
26
|
+
|
|
27
|
+
.. image:: https://img.shields.io/coveralls/github/xhtml2pdf/xhtml2pdf?label=Coveralls&logo=Coveralls&logoColor=white
|
|
28
|
+
:target: https://coveralls.io/github/xhtml2pdf/xhtml2pdf
|
|
29
|
+
:alt: Coveralls
|
|
30
|
+
|
|
31
|
+
.. image:: https://img.shields.io/readthedocs/xhtml2pdf?label=Read%20the%20Docs&logo=read%20the%20docs&logoColor=white
|
|
32
|
+
:target: http://xhtml2pdf.readthedocs.io/en/latest/?badge=latest
|
|
33
|
+
:alt: Read the Docs
|
|
34
|
+
|
|
35
|
+
xhtml2pdf turns HTML5 and CSS into PDF on top of the ReportLab toolkit. Anyone
|
|
36
|
+
who can build a web page can build an invoice, a report, a ticket or a book
|
|
37
|
+
with it, from a Django or Flask template or from a plain string, and render
|
|
38
|
+
it anywhere Python runs.
|
|
39
|
+
|
|
40
|
+
Made with xhtml2pdf
|
|
41
|
+
===================
|
|
42
|
+
|
|
43
|
+
Every page below is an HTML document converted by xhtml2pdf, fonts, charts,
|
|
44
|
+
barcodes and all.
|
|
45
|
+
|
|
46
|
+
.. |annual-report| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/annual-report.png
|
|
47
|
+
:width: 180px
|
|
48
|
+
:alt: An annual report with a cover photo, key figures and charts
|
|
49
|
+
|
|
50
|
+
.. |invoice| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/invoice.png
|
|
51
|
+
:width: 180px
|
|
52
|
+
:alt: An invoice with a long table of line items and totals
|
|
53
|
+
|
|
54
|
+
.. |book| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/book.png
|
|
55
|
+
:width: 180px
|
|
56
|
+
:alt: The cover of a novella, a full-page illustration with the title
|
|
57
|
+
|
|
58
|
+
.. |poster| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/poster.png
|
|
59
|
+
:width: 180px
|
|
60
|
+
:alt: A concert poster with a city skyline and a strip of dates
|
|
61
|
+
|
|
62
|
+
.. |certificate| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/certificate.png
|
|
63
|
+
:width: 180px
|
|
64
|
+
:alt: A certificate of completion in landscape with a QR code
|
|
65
|
+
|
|
66
|
+
.. |receipt-pos| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/receipt-pos.png
|
|
67
|
+
:width: 180px
|
|
68
|
+
:alt: A narrow point-of-sale receipt in a monospaced font
|
|
69
|
+
|
|
70
|
+
.. |boarding-pass| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/boarding-pass.png
|
|
71
|
+
:width: 180px
|
|
72
|
+
:alt: An airline boarding pass with a barcode and a QR code
|
|
73
|
+
|
|
74
|
+
.. |event-ticket| image:: https://raw.githubusercontent.com/xhtml2pdf/xhtml2pdf/master/docs/source/_static/readme/event-ticket.png
|
|
75
|
+
:width: 180px
|
|
76
|
+
:alt: A concert ticket with a stub and a barcode
|
|
77
|
+
|
|
78
|
+
+-----------------+-----------------+-----------------+-----------------+
|
|
79
|
+
| |annual-report| | |invoice| | |book| | |poster| |
|
|
80
|
+
+-----------------+-----------------+-----------------+-----------------+
|
|
81
|
+
| |certificate| | |receipt-pos| | |boarding-pass| | |event-ticket| |
|
|
82
|
+
+-----------------+-----------------+-----------------+-----------------+
|
|
83
|
+
|
|
84
|
+
Quick start
|
|
85
|
+
===========
|
|
86
|
+
|
|
87
|
+
.. code:: bash
|
|
88
|
+
|
|
89
|
+
pip install xhtml2pdf[all]
|
|
90
|
+
|
|
91
|
+
.. code:: python
|
|
92
|
+
|
|
93
|
+
from xhtml2pdf import pisa
|
|
94
|
+
|
|
95
|
+
html = """
|
|
96
|
+
<style>
|
|
97
|
+
@page { size: a4; margin: 2cm;
|
|
98
|
+
@frame footer { -pdf-frame-content: footer; bottom: 1cm;
|
|
99
|
+
margin-left: 2cm; margin-right: 2cm; height: 1cm } }
|
|
100
|
+
h1 { color: #204a87 }
|
|
101
|
+
</style>
|
|
102
|
+
<h1>Hello, PDF</h1>
|
|
103
|
+
<p>Written in HTML, laid out by CSS.</p>
|
|
104
|
+
<div id="footer">Page <pdf:pagenumber /> of <pdf:pagecount /></div>
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
with open("hello.pdf", "wb") as output:
|
|
108
|
+
result = pisa.CreatePDF(html, dest=output)
|
|
109
|
+
print("errors:", result.err)
|
|
110
|
+
|
|
111
|
+
Or from the command line:
|
|
112
|
+
|
|
113
|
+
.. code:: bash
|
|
114
|
+
|
|
115
|
+
xhtml2pdf report.html report.pdf
|
|
116
|
+
|
|
117
|
+
What it can do
|
|
118
|
+
==============
|
|
119
|
+
|
|
120
|
+
**Layout**
|
|
121
|
+
|
|
122
|
+
* Flexbox (``display: flex``), including containers that break across
|
|
123
|
+
pages, and ``display: inline-block``.
|
|
124
|
+
* ``position: relative``, ``absolute`` and ``fixed``, with ``z-index``.
|
|
125
|
+
* Block boxes with padding, borders and backgrounds around everything they
|
|
126
|
+
hold, ``border-radius`` on blocks, tables, cells, images and inline
|
|
127
|
+
boxes, and dashed, dotted and double borders.
|
|
128
|
+
* Tables with header rows repeated on every page, ``colspan`` and
|
|
129
|
+
``rowspan``, auto margins and widths, and rows taller than a page cut
|
|
130
|
+
between pages.
|
|
131
|
+
* Word breaking with ``overflow-wrap``, ``page-break-before``/``after``,
|
|
132
|
+
``page-break-inside: avoid`` and keeping a heading with what follows.
|
|
133
|
+
|
|
134
|
+
**CSS**
|
|
135
|
+
|
|
136
|
+
* Selectors up to Level 4: ``:not()``, ``:is()``, ``:where()``, ``:has()``,
|
|
137
|
+
``:nth-child()`` and attribute selectors.
|
|
138
|
+
* Custom properties with ``var()``, ``em``/``rem``/percent units, and colours
|
|
139
|
+
with an alpha channel.
|
|
140
|
+
* ``@font-face`` with TrueType and OpenType fonts, matched per character, so
|
|
141
|
+
a paragraph that mixes scripts finds a font for each of them.
|
|
142
|
+
|
|
143
|
+
**Pages**
|
|
144
|
+
|
|
145
|
+
* ``@page`` sizes and margins, named page templates and left/right pages,
|
|
146
|
+
background images, and frames for headers, footers and columns.
|
|
147
|
+
* Page numbers and page counts, watermarks and backgrounds from an image or
|
|
148
|
+
another PDF.
|
|
149
|
+
|
|
150
|
+
**Navigation**
|
|
151
|
+
|
|
152
|
+
* Tables of contents with dot leaders, more than one per document,
|
|
153
|
+
clickable entries and a PDF outline (bookmarks).
|
|
154
|
+
* Links to any element by ``id``, to other files and to the web.
|
|
155
|
+
|
|
156
|
+
**International text**
|
|
157
|
+
|
|
158
|
+
* Right-to-left documents in Arabic, Hebrew, Persian and Urdu, laid out with
|
|
159
|
+
a pure-Python implementation of the Unicode Bidirectional Algorithm that
|
|
160
|
+
passes the whole of the Unicode conformance suites.
|
|
161
|
+
* Chinese, Japanese and Korean, Cyrillic and Greek, with the document's
|
|
162
|
+
language written to the PDF.
|
|
163
|
+
|
|
164
|
+
**Graphics and PDF features**
|
|
165
|
+
|
|
166
|
+
* SVG images, bar, line and pie charts, and barcodes and QR codes.
|
|
167
|
+
* Fillable form fields, encryption with passwords and permissions, and
|
|
168
|
+
digital signatures (simple and PAdES) through pyHanko.
|
|
169
|
+
|
|
170
|
+
**Safe by default**
|
|
171
|
+
|
|
172
|
+
* A document cannot read local files outside its directory or reach
|
|
173
|
+
internal network addresses, and ``ResourceAccessPolicy.server()`` adds
|
|
174
|
+
limits on size, nesting and time for HTML from untrusted sources. See
|
|
175
|
+
`Security <https://xhtml2pdf.readthedocs.io/en/latest/security.html>`__.
|
|
176
|
+
|
|
177
|
+
Documentation
|
|
178
|
+
=============
|
|
179
|
+
|
|
180
|
+
The documentation is on `Read the Docs <http://xhtml2pdf.readthedocs.io>`__,
|
|
181
|
+
and what changed in each version is in the `Release Notes
|
|
182
|
+
<https://xhtml2pdf.readthedocs.io/en/latest/release-notes.html>`__. Help
|
|
183
|
+
improving it is welcome; a good place to start is
|
|
184
|
+
``docs/source/quickstart.rst``.
|
|
185
|
+
|
|
186
|
+
Installation
|
|
187
|
+
============
|
|
188
|
+
|
|
189
|
+
.. code:: bash
|
|
190
|
+
|
|
191
|
+
pip install xhtml2pdf[all]
|
|
192
|
+
|
|
193
|
+
Python 3.10 and newer is tested and supported. Every mandatory requirement is
|
|
194
|
+
listed in ``pyproject.toml`` and installed with xhtml2pdf; ``all`` adds the
|
|
195
|
+
optional ones: pyHanko, for digital signatures, which is also the
|
|
196
|
+
``signing`` extra on its own. ``pip install xhtml2pdf`` leaves it out:
|
|
197
|
+
asking for a signature then raises an ``ImportError`` that names the extra.
|
|
198
|
+
|
|
199
|
+
ReportLab needs a rendering backend to turn vector graphics into bitmaps (for
|
|
200
|
+
charts and SVG rasterised into the page). The supported one is `cairo
|
|
201
|
+
<https://cairographics.org/>`__, installed system-wide, for example through
|
|
202
|
+
the OS package manager, together with the ``pycairo`` extra:
|
|
203
|
+
|
|
204
|
+
.. code:: bash
|
|
205
|
+
|
|
206
|
+
pip install xhtml2pdf[pycairo]
|
|
207
|
+
|
|
208
|
+
The ``renderpm`` extra is a deprecated alias for ``pycairo``: ReportLab 5
|
|
209
|
+
removed the C ``RenderPM`` backend. See the `ReportLab installation notes
|
|
210
|
+
<https://docs.reportlab.com/install/open_source_installation/>`__.
|
|
211
|
+
|
|
212
|
+
Development environment
|
|
213
|
+
=======================
|
|
214
|
+
|
|
215
|
+
``make devsetup`` creates ``.venv``, installs xhtml2pdf in editable mode with
|
|
216
|
+
the ``test``, ``docs`` and ``release`` extras and installs the pre-commit
|
|
217
|
+
hooks:
|
|
218
|
+
|
|
219
|
+
.. code:: bash
|
|
220
|
+
|
|
221
|
+
make devsetup
|
|
222
|
+
source .venv/bin/activate
|
|
223
|
+
|
|
224
|
+
Or by hand:
|
|
225
|
+
|
|
226
|
+
.. code:: bash
|
|
227
|
+
|
|
228
|
+
python -m venv .venv
|
|
229
|
+
source .venv/bin/activate
|
|
230
|
+
pip install -e .[test,docs,release]
|
|
231
|
+
|
|
232
|
+
Running tests
|
|
233
|
+
=============
|
|
234
|
+
|
|
235
|
+
.. code:: bash
|
|
236
|
+
|
|
237
|
+
make test # unit tests
|
|
238
|
+
make test-ref # reference renders for testrender
|
|
239
|
+
make test-render # compare the renders against the reference
|
|
240
|
+
make test-browser # compare against a headless browser's rendering
|
|
241
|
+
make test-all # every supported Python and ReportLab, with tox
|
|
242
|
+
|
|
243
|
+
``testrender/`` renders a set of documents and compares the pages; the
|
|
244
|
+
browser comparison scores xhtml2pdf against Chrome on the same markup, so a
|
|
245
|
+
change that moves a layout away from a browser's shows up as a regression.
|
|
246
|
+
``tools/perf`` measures time and memory.
|
|
247
|
+
|
|
248
|
+
Contributing
|
|
249
|
+
============
|
|
250
|
+
|
|
251
|
+
This project is community-led. Ideas, bug reports with a small HTML that
|
|
252
|
+
shows the problem, and pull requests are welcome on GitHub. If xhtml2pdf is
|
|
253
|
+
useful to you, look at the `test coverage
|
|
254
|
+
<https://coveralls.io/github/xhtml2pdf/xhtml2pdf>`__ for parts that are not
|
|
255
|
+
yet tested.
|
|
256
|
+
|
|
257
|
+
You can also support the project on `Patreon
|
|
258
|
+
<https://www.patreon.com/xhtml2pdf>`__ or with Bitcoin:
|
|
259
|
+
``bc1qmr0skzwx5scyvh2ql28f7gfh6l65ua250qv227``.
|
|
260
|
+
|
|
261
|
+
**Big thanks** to everyone who has worked on this project so far and to those
|
|
262
|
+
who help maintain it.
|
|
263
|
+
|
|
264
|
+
Alternatives
|
|
265
|
+
============
|
|
266
|
+
|
|
267
|
+
`WeasyPrint <http://weasyprint.org>`__ covers much of the same ground with a
|
|
268
|
+
different design and set of features.
|
|
269
|
+
|
|
270
|
+
History
|
|
271
|
+
=======
|
|
272
|
+
|
|
273
|
+
These are the major milestones and the maintainers of the project:
|
|
274
|
+
|
|
275
|
+
* 2000-2007 Dirk Holtwick (commercial project of spirito.de)
|
|
276
|
+
* 2007-2010 Dirk Holtwick (project named "pisa", project released as GPL)
|
|
277
|
+
* 2010-2012 Dirk Holtwick (project named "xhtml2pdf", changed license to Apache)
|
|
278
|
+
* 2012-2015 Chris Glass (@chrisglass)
|
|
279
|
+
* 2015-2016 Benjamin Bach (@benjaoming)
|
|
280
|
+
* 2016-2018 Sam Spencer (@LegoStormtroopr)
|
|
281
|
+
* 2018-Current Luis Zarate (@luisza)
|
|
282
|
+
|
|
283
|
+
For more history, see the `Release Notes <https://xhtml2pdf.readthedocs.io/en/latest/release-notes.html>`__.
|
|
284
|
+
|
|
285
|
+
License
|
|
286
|
+
=======
|
|
287
|
+
|
|
288
|
+
Copyright 2010 Dirk Holtwick, holtwick.it
|
|
289
|
+
|
|
290
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
291
|
+
you may not use this file except in compliance with the License.
|
|
292
|
+
You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
|
|
293
|
+
|
|
294
|
+
Unless required by applicable law or agreed to in writing, software
|
|
295
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
296
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
297
|
+
See the License for the specific language governing permissions and
|
|
298
|
+
limitations under the License.
|