diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/api_reference.rst | 19 | ||||
-rw-r--r-- | docs/changelog.rst | 167 | ||||
-rw-r--r-- | docs/common_use_cases.rst | 182 | ||||
-rw-r--r-- | docs/conf.py | 90 | ||||
-rw-r--r-- | docs/contribute.rst | 70 | ||||
-rw-r--r-- | docs/first_steps.rst | 36 | ||||
-rw-r--r-- | docs/going_further.rst | 32 | ||||
-rw-r--r-- | docs/index.rst | 23 | ||||
-rw-r--r-- | docs/support.rst | 28 |
9 files changed, 647 insertions, 0 deletions
diff --git a/docs/api_reference.rst b/docs/api_reference.rst new file mode 100644 index 0000000..80bf16c --- /dev/null +++ b/docs/api_reference.rst @@ -0,0 +1,19 @@ +API Reference +============= + +.. module:: pydyf + +.. autoclass:: Object + :members: + +.. autoclass:: Dictionary + +.. autoclass:: Stream + :members: + +.. autoclass:: String + +.. autoclass:: Array + +.. autoclass:: PDF + :members: diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..cbebc90 --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1,167 @@ +Changelog +========= + + +Version 0.1.1 +------------- + +Released on 2021-08-22. + +Bug fixes: + +* `0f7c8e9 <https://github.com/CourtBouillon/pydyf/commit/0f7c8e9>`_: + Fix string encoding + +Contributors: + +* Guillaume Ayoub + +Backers and sponsors: + +* Grip Angebotssoftware +* PDF Blocks +* SimonSoft +* Menutech +* Manuel Barkhau +* Simon Sapin +* KontextWork +* René Fritz +* Maykin Media +* NCC Group +* Des images et des mots +* Andreas Zettl +* Nathalie Gutton +* Tom Pohl +* Moritz Mahringer +* Florian Demmer +* Yanal-Yvez Fargialla + + +Version 0.1.0 +------------- + +Released on 2021-08-21. + +Bug fixes: + +* `#8 <https://github.com/CourtBouillon/pydyf/issues/8>`_: + Don’t use sys.stdout.buffer as default write object + +Contributors: + +* Guillaume Ayoub + +Backers and sponsors: + +* Grip Angebotssoftware +* PDF Blocks +* SimonSoft +* Menutech +* Manuel Barkhau +* Simon Sapin +* KontextWork +* René Fritz +* Maykin Media +* NCC Group +* Des images et des mots +* Andreas Zettl +* Nathalie Gutton +* Tom Pohl +* Moritz Mahringer +* Florian Demmer +* Yanal-Yvez Fargialla + + +Version 0.0.3 +------------- + +Released on 2021-04-22. + +New features: + +* Support text rendering + +Contributors: + +* Guillaume Ayoub + +Backers and sponsors: + +* PDF Blocks +* SimonSoft +* Menutech +* Simon Sapin +* Manuel Barkhau +* Andreas Zettl +* Nathalie Gutton +* Tom Pohl +* René Fritz +* Moritz Mahringer +* Florian Demmer +* KontextWork +* Michele Mostarda + + +Version 0.0.2 +------------- + +Released on 2021-03-13. + +New features: + +* Support linecap style +* Support line join et miter limit +* Add more cubic Bézier curve options + +Bug fixes: + +* Don’t include EOL in dictionary length +* Add a second binary line in PDF + +Contributors: + +* Guillaume Ayoub +* Lucie Anglade +* Alexander Schrijver +* Kees Cook + +Backers and sponsors: + +* PDF Blocks +* SimonSoft +* Menutech +* Simon Sapin +* Manuel Barkhau +* Andreas Zettl +* Nathalie Gutton +* Tom Pohl +* René Fritz +* Moritz Mahringer +* Florian Demmer +* KontextWork +* Michele Mostarda + + +Version 0.0.1 +------------- + +Released on 2020-12-06. + +Initial release. + +Contributors: + +* Guillaume Ayoub +* Lucie Anglade + +Backers and sponsors: + +* PDF Blocks +* SimonSoft +* Menutech +* Simon Sapin +* Nathalie Gutton +* Andreas Zetti +* Tom Pohl +* Florian Demmer +* Moritz Mahringer diff --git a/docs/common_use_cases.rst b/docs/common_use_cases.rst new file mode 100644 index 0000000..45e2d3d --- /dev/null +++ b/docs/common_use_cases.rst @@ -0,0 +1,182 @@ +Common Use Cases +================ + +pydyf has been created for WeasyPrint and many common use cases can thus be +found in `its repository`_. + +.. _its repository: https://github.com/Kozea/WeasyPrint + + +Draw rectangles and lines +------------------------- + +.. code-block:: python + + import pydyf + + document = pydyf.PDF() + + draw = pydyf.Stream() + + # Draw a first rectangle + # With the border in dash style + # The dash line is 2 points full, 1 point empty + # And the dash line begins with 2 full points + draw.rectangle(100, 100, 50, 70) + draw.set_dash([2, 1], 0) + draw.stroke() + + # Draw a second rectangle + # The dash is reset to a full line + # The line width is set + # Move the bottom-left corner to (80, 80) + # Fill the rectangle + draw.rectangle(50, 50, 20, 40) + draw.set_dash([], 0) + draw.set_line_width(10) + draw.transform(1, 0, 0, 1, 80, 80) + draw.fill() + + # Add the stream with the two rectangles into the document + document.add_object(draw) + + # Add a page to the document containing the draw + document.add_page(pydyf.Dictionary({ + 'Type': '/Page', + 'Parent': document.pages.reference, + 'Contents': draw.reference, + 'MediaBox': pydyf.Array([0, 0, 200, 200]), + })) + + # Write to document.pdf + with open('document.pdf', 'wb') as f: + document.write(f) + +Add some color +-------------- + +.. code-block:: python + + import pydyf + + document = pydyf.PDF() + + draw = pydyf.Stream() + + # Set the color for nonstroking and stroking operations + # Red for nonstroking an green for stroking + draw.set_color_rgb(1.0, 0.0, 0.0) + draw.set_color_rgb(0.0, 1.0, 0.0, stroke=True) + draw.rectangle(100, 100, 50, 70) + draw.set_dash([2, 1], 0) + draw.stroke() + draw.rectangle(50, 50, 20, 40) + draw.set_dash([], 0) + draw.set_line_width(10) + draw.transform(1, 0, 0, 1, 80, 80) + draw.fill() + + document.add_object(draw) + + document.add_page(pydyf.Dictionary({ + 'Type': '/Page', + 'Parent': document.pages.reference, + 'Contents': draw.reference, + 'MediaBox': pydyf.Array([0, 0, 200, 200]), + })) + + with open('document.pdf', 'wb') as f: + document.write(f) + +Display image +------------- + +.. code-block:: python + + import pydyf + + document = pydyf.PDF() + + extra = Dictionary({ + 'Type': '/XObject', + 'Subtype': '/Image', + 'Width': 197, + 'Height': 101, + 'ColorSpace': '/DeviceRGB', + 'BitsPerComponent': 8, + 'Filter': '/DCTDecode', + }) + + image = open('logo.jpg', 'rb').read() + xobject = pydyf.Stream([image], extra=extra) + document.add_object(xobject) + + image = pydyf.Stream() + image.push_state() + image.transform(100, 0, 0, 100, 100, 100) + image.draw_x_object('Im1') + image.pop_state() + document.add_object(image) + + # Put the image in the resources of the PDF + document.add_page(pydyf.Dictionary({ + 'Type': '/Page', + 'Parent': document.pages.reference, + 'MediaBox': pydyf.Array([0, 0, 200, 200]), + 'Resources': pydyf.Dictionary({ + 'ProcSet': pydyf.Array(['/PDF', '/ImageB']), + 'XObject': pydyf.Dictionary({'Im1': xobject.reference}), + }), + 'Contents': image.reference, + })) + + with open('document.pdf', 'wb') as f: + document.write(f) + +Display text +------------ + +.. code-block:: python + + import pydyf + + document = pydyf.PDF() + + # Define the font + font = pydyf.Dictionary({ + 'Type': '/Font', + 'Subtype': '/Type1', + 'Name': '/F1', + 'BaseFont': '/Helvetica', + 'Encoding': '/MacRomanEncoding', + }) + + document.add_object(font) + + # Set the font use for the text + # Move to where to display the text + # And display it + text = pydyf.Stream() + text.begin_text() + text.set_font_size('F1', 24) + text.text_matrix(1, 0, 0, 1, 10, 90) + text.show_text(pydyf.String('Hello World')) + text.end_text() + + document.add_object(text) + + # Put the font in the resources of the PDF + document.add_page(pydyf.Dictionary({ + 'Type': '/Page', + 'Parent': document.pages.reference, + 'MediaBox': pydyf.Array([0, 0, 200, 200]), + 'Contents': text.reference, + 'Resources': pydyf.Dictionary({ + 'ProcSet': pydyf.Array(['/PDF', '/Text']), + 'Font': pydyf.Dictionary({'F1': font.reference}), + }) + })) + + with open('document.pdf', 'wb') as f: + document.write(f) + diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..585afd0 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,90 @@ +# pydyf documentation build configuration file. + +import sys +from pathlib import Path + +import pydyf + +# Add current path for css_diagram_role +sys.path.append(str(Path(__file__).parent)) + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', + 'sphinx.ext.autosectionlabel'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'pydyf' +copyright = 'CourtBouillon and contributors' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The full version, including alpha/beta/rc tags. +release = pydyf.__version__ + +# The short X.Y version. +version = '.'.join(release.split('.')[:2]) + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'monokai' + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'sphinx_rtd_theme' + +html_theme_options = { + 'collapse_navigation': False, +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [] + +# These paths are either relative to html_static_path +# or fully qualified paths (eg. https://...) +html_css_files = [ + 'https://www.courtbouillon.org/static/docs.css', +] + +# Output file base name for HTML help builder. +htmlhelp_basename = 'pydyf2doc' + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'pydyf', 'pydyf Documentation', + ['CourtBouillon and contributors'], 1) +] + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'pydyf', 'pydyf Documentation', + 'CourtBouillon', 'pydyf', + 'A low-level PDF creator', + 'Miscellaneous'), +] + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = { + 'python': ('https://docs.python.org/3/', None), + 'webencodings': ('https://pythonhosted.org/webencodings/', None), +} diff --git a/docs/contribute.rst b/docs/contribute.rst new file mode 100644 index 0000000..adf9024 --- /dev/null +++ b/docs/contribute.rst @@ -0,0 +1,70 @@ +Contribute +========== + +You want to add some code to pydyf, launch its tests or improve its +documentation? Thank you very much! Here are some tips to help you play with +pydyf in good conditions. + +The first step is to clone the repository, create a virtual environment and +install pydyf dependencies. + +.. code-block:: shell + + git clone https://github.com/CourtBouillon/pydyf.git + cd pydyf + python -m venv venv + venv/bin/pip install .[doc,test] + +You can then let your terminal in the current directory and launch Python to +test your changes. ``import pydyf`` will then import the working directory +code, so that you can modify it and test your changes. + +.. code-block:: shell + + venv/bin/python + + +Code & Issues +------------- + +If you’ve found a bug in pydyf, it’s time to report it, and to fix it if you +can! + +You can report bugs and feature requests on GitHub_. If you want to add or +fix some code, please fork the repository and create a pull request, we’ll be +happy to review your work. + +.. _GitHub: https://github.com/CourtBouillon/pydyf + + +Tests +----- + +Tests are stored in the ``tests`` folder at the top of the repository. They use +the pytest_ library. + +Launching tests require to have Ghostscript_ installed and available in +``PATH``. + +You can launch tests (with code coverage and lint) using the following command:: + + venv/bin/pytest + +.. _pytest: https://docs.pytest.org/ +.. _Ghostscript: https://www.ghostscript.com/ + + +Documentation +------------- + +Documentation is stored in the ``docs`` folder at the top of the repository. It +relies on the Sphinx_ library. + +You can build the documentation using the following command:: + + venv/bin/sphinx-build docs docs/_build + +The documentation home page can now be found in the ``docs/_build/index.html`` +file. You can open this file in a browser to see the final rendering. + +.. _Sphinx: https://www.sphinx-doc.org/ diff --git a/docs/first_steps.rst b/docs/first_steps.rst new file mode 100644 index 0000000..61d967f --- /dev/null +++ b/docs/first_steps.rst @@ -0,0 +1,36 @@ +First Steps +=========== + + +Installation +------------ + +The easiest way to use pydyf is to install it in a Python `virtual +environment`_. When your virtual environment is activated, you can then install +pydyf with pip_:: + + pip install pydyf + +.. _virtual environment: https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/ +.. _pip: https://pip.pypa.io/ + + +Create a PDF +------------ + +.. code-block:: python + + import pydyf + + document = pydyf.PDF() + + # Add an empty page + document.add_page(pydyf.Dictionary({ + 'Type': '/Page', + 'Parent': document.pages.reference, + 'MediaBox': pydyf.Array([0, 0, 200, 200]), + })) + + # Write to document.pdf + with open('document.pdf', 'wb') as f: + document.write(f) diff --git a/docs/going_further.rst b/docs/going_further.rst new file mode 100644 index 0000000..ce9a8f3 --- /dev/null +++ b/docs/going_further.rst @@ -0,0 +1,32 @@ +Going Further +============= + + +Why pydyf? +------------- + +pydyf has been created to replace Cairo PDF generation in WeasyPrint_. + +Indeed, there are some bugs in WeasyPrint caused by Cairo_ and Cairo has some +difficulties to make releases. +Also there are features which will be easier to implement while having more +control on the PDF generation. + +So we created pydyf. + +.. _WeasyPrint: https://www.courtbouillon.org/weasyprint +.. _Cairo: https://www.cairographics.org/ + +Why Python? +----------- + +Python is a really good language to design a small, OS-agnostic parser. As it +is object-oriented, it gives the possibility to follow the specification with +high-level classes and a small amount of very simple code. + +And of course, WeasyPrint is written in Python too, giving an obvious reason +for this choice. + +Speed is not pydyf’s main goal. Code simplicity, maintainability and +flexibility are more important goals for this library, as they give the +ability to stay really close to the specification and to fix bugs easily. diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..af30f00 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,23 @@ +pydyf +======== + +.. currentmodule:: pydyf + +.. include:: ../README.rst + +.. toctree:: + :caption: Documentation + :maxdepth: 3 + + first_steps + common_use_cases + api_reference + going_further + +.. toctree:: + :caption: Extra Information + :maxdepth: 3 + + changelog + contribute + support diff --git a/docs/support.rst b/docs/support.rst new file mode 100644 index 0000000..fd4452d --- /dev/null +++ b/docs/support.rst @@ -0,0 +1,28 @@ +Support +======= + + +Sponsorship +----------- + +With `donations and sponsorship`_, you help the projects to be +better. Donations allow the CourtBouillon team to have more time dedicated to +add new features, fix bugs, and improve documentation. + +.. _donations and sponsorship: https://opencollective.com/courtbouillon + + +Professionnal Support +--------------------- + +You can improve your experience with CourtBouillon’s tools thanks to our +professional support. You want bugs fixed as soon as possible? You projects +would highly benefit from some new features? You or your team would like to get +new skills with one of the technologies we master? + +Please contact us by mail_, by chat_ or by tweet_ to get in touch and find the +best way we can help you. + +.. _mail: mailto:contact@courtbouillon.org +.. _chat: https://gitter.im/CourtBouillon/pydyf +.. _tweet: https://twitter.com/BouillonCourt |