├── .gitignore
├── .readthedocs.yaml
├── LICENSE
├── MANIFEST.in
├── README.md
├── docs
├── Makefile
├── _static
│ ├── annotations_custom.png
│ ├── annotations_enhanced.png
│ ├── annotations_simple.png
│ ├── demo_pinout_diagram.png
│ ├── huzzah32_pinout.png
│ ├── kicad_export.png
│ ├── kicad_screenshot.png
│ ├── label_dimensions.png
│ ├── quick_start_measurements_labels.png
│ ├── quick_start_measurements_pins.png
│ ├── quick_start_measurements_scale.png
│ └── quick_start_pinout_diagram.png
├── conf.py
├── index.rst
├── make.bat
├── pages
│ ├── KiCad_integration.rst
│ ├── annotation.rst
│ ├── config.rst
│ ├── core.rst
│ ├── customise.rst
│ ├── install.rst
│ ├── integrated_circuits.rst
│ ├── layout.rst
│ ├── leaderline.rst
│ ├── legend.rst
│ ├── manager.rst
│ ├── modules.rst
│ ├── pinlabel.rst
│ ├── resources.rst
│ ├── text.rst
│ └── tutorial.rst
└── requirements.txt
├── pinout.toml
├── pinout
├── __init__.py
├── components
│ ├── __init__.py
│ ├── annotation.py
│ ├── integrated_circuits.py
│ ├── layout.py
│ ├── leaderline.py
│ ├── legend.py
│ ├── pinlabel.py
│ └── text.py
├── config.py
├── core.py
├── kicad2pinout.py
├── manager.py
├── resources
│ ├── config.py
│ ├── pinout_kicad_example.zip
│ └── quick_start
│ │ ├── data.py
│ │ ├── hardware.png
│ │ ├── pinout_diagram.py
│ │ └── styles.css
├── style_tools.py
├── templates.py
└── templates
│ ├── circle.svg
│ ├── clippath.svg
│ ├── component_common.svg
│ ├── group.svg
│ ├── image.svg
│ ├── kicad_footprint_lib
│ ├── Annotation.j2
│ ├── Origin.j2
│ └── PinLabel.j2
│ ├── label.svg
│ ├── path.svg
│ ├── rect.svg
│ ├── style.svg
│ ├── stylesheet.j2
│ ├── svg.svg
│ ├── text.svg
│ ├── textblock.svg
│ └── use.svg
├── samples
├── arduino
│ ├── arduino
│ │ ├── __init__.py
│ │ ├── common
│ │ │ ├── __init__.py
│ │ │ ├── arduino_components.py
│ │ │ ├── patterns.xml
│ │ │ ├── preprocessor.py
│ │ │ └── styles.css
│ │ ├── rp2040
│ │ │ ├── __init__.py
│ │ │ ├── arduino_nano_rp2040_connect.py
│ │ │ ├── hardware.png
│ │ │ └── rp2040_data.py
│ │ └── uno
│ │ │ ├── __init__.py
│ │ │ ├── arduino_uno.py
│ │ │ ├── delete
│ │ │ ├── arduino_components.py
│ │ │ ├── patterns.xml
│ │ │ ├── pinout_arduino_uno_rev3.svg
│ │ │ └── styles.css
│ │ │ ├── hardware.png
│ │ │ └── uno_data.py
│ ├── arduino_notes.md
│ ├── pinout_arduino_nano_rp2040_connect.svg
│ └── pinout_arduino_uno_rev3.svg
├── attiny85
│ ├── attiny85.py
│ ├── attiny_styles.css
│ └── pinout_attiny85.svg
├── clip_path
│ ├── diagram.svg
│ ├── hardware_18pin.png
│ ├── pinout_diagram.py
│ └── styles.css
├── full_sample
│ ├── __init__.py
│ ├── components.py
│ ├── full_sample_data.py
│ ├── hardware.png
│ ├── pinout_diagram.py
│ ├── pinout_diagram.svg
│ ├── styles.css
│ └── styles_auto.css
├── panel_layout
│ ├── __init__.py
│ ├── auto_styles.css
│ ├── output
│ │ ├── panel_layout.svg
│ │ ├── populated_layout.png
│ │ └── populated_layout.svg
│ ├── panel_layout.py
│ ├── populated_layout.py
│ ├── readme.md
│ └── styles.css
├── pci-express
│ ├── autostyles.css
│ ├── pci-express_data.xlsx
│ ├── pci-express_x1.svg
│ ├── pci_data.py
│ ├── pinout_x1.py
│ └── pinout_x1.svg
├── section_pullout
│ ├── diagram.svg
│ ├── hardware_18pin.png
│ ├── pinout_diagram.py
│ ├── section_pullout_data.py
│ └── styles.css
└── teensy_4.0
│ ├── hardware_teensy_4.0_front.svg
│ ├── pinout_diagram.py
│ ├── styles.css
│ ├── styles.scss
│ ├── teensy_4.0_front_pinout_diagram.svg
│ └── teensy_4_data.py
├── setup.py
└── tests
├── resources
├── 200x200.png
├── 200x200.svg
├── __init__.py
├── diagram_export.py
├── diagram_export.svg
├── diagram_image.py
├── diagram_image.svg
└── styles.css
└── test_samples.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 | tests/temp/
54 | temp_pytest_*.svg
55 |
56 | # Translations
57 | *.mo
58 | *.pot
59 |
60 | # Django stuff:
61 | *.log
62 | local_settings.py
63 | db.sqlite3
64 | db.sqlite3-journal
65 |
66 | # Flask stuff:
67 | instance/
68 | .webassets-cache
69 |
70 | # Scrapy stuff:
71 | .scrapy
72 |
73 | # Sphinx documentation
74 | docs/_build/
75 |
76 | # PyBuilder
77 | target/
78 |
79 | # Jupyter Notebook
80 | .ipynb_checkpoints
81 |
82 | # IPython
83 | profile_default/
84 | ipython_config.py
85 |
86 | # pyenv
87 | .python-version
88 |
89 | # pipenv
90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
93 | # install all needed dependencies.
94 | #Pipfile.lock
95 |
96 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
97 | __pypackages__/
98 |
99 | # Celery stuff
100 | celerybeat-schedule
101 | celerybeat.pid
102 |
103 | # SageMath parsed files
104 | *.sage.py
105 |
106 | # Environments
107 | .env
108 | .venv
109 | env/
110 | venv/
111 | ENV/
112 | env.bak/
113 | venv.bak/
114 |
115 | # Spyder project settings
116 | .spyderproject
117 | .spyproject
118 |
119 | # Rope project settings
120 | .ropeproject
121 |
122 | # Visual studio code project settings
123 | .vscode/
124 | *.code-workspace
125 |
126 | # mkdocs documentation
127 | /site
128 |
129 | # mypy
130 | .mypy_cache/
131 | .dmypy.json
132 | dmypy.json
133 |
134 | # Pyre type checker
135 | .pyre/
136 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yaml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 1
7 |
8 | # Build documentation in the docs/ directory with Sphinx
9 | sphinx:
10 | builder: html
11 | configuration: docs/conf.py
12 |
13 | # Optionally build your docs in additional formats such as PDF
14 | formats:
15 | - epub
16 | - pdf
17 |
18 | # Optionally set the version of Python and requirements required to build your docs
19 | python:
20 | version: 3.6
21 | install:
22 | - requirements: docs/requirements.txt
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 John Newall (aka j0ono0)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include pinout/templates *
2 | recursive-include pinout/resources *
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pinout
2 |
3 |   
4 |
5 | SVG diagram creation from Python code - **pinout** provides an easy method of creating pinout diagrams for electronic hardware.
6 |
7 |
8 |
9 |
10 |
11 | Please visit [pinout.readthedocs.io](https://pinout.readthedocs.io) for the full *quick start* tutorial and detailed documentation on all options provided by the *pinout* package.
12 |
13 | ## Quick start
14 |
15 | *pinout* can be easily installed with pip and provides some sample files that demonstrate key features.
16 |
17 | ### Install
18 |
19 | Using a virtual environment is recommended; Start by installing the *pinout* package. Either clone this repo and pip install it or install from PyPi:
20 | ```
21 | pip install pinout
22 |
23 | # Or upgrade to the latest version
24 | pip install --upgrade pinout
25 | ```
26 |
27 | ### Duplicate sample files
28 |
29 | A normal pinout diagram will include a hardware image, stylesheet, data file, and a Python script. Sample files are included with the package and can be duplicated for your use. Open a command line (with enabled virtual environment if you are using one) in the location you plan to work and enter the following:
30 | ```python
31 | py -m pinout.manager --duplicate quick_start
32 |
33 | # expected output:
34 | # >>> data.py duplicated.
35 | # >>> hardware.png duplicated.
36 | # >>> pinout_diagram.py duplicated.
37 | # >>> styles.css duplicated.
38 | ```
39 |
40 | Once you have these file a finished diagram can be generated from a command line `py -m pinout.manager --export pinout_diagram diagram.svg`. An SVG file is created and can be conveniently view in a browser.
41 |
42 | 
43 |
44 | For a detailed walk through *pinout_diagram.py* and more information on *pinout* please visit [pinout.readthedocs.io](https://pinout.readthedocs.io).
45 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/docs/_static/annotations_custom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/annotations_custom.png
--------------------------------------------------------------------------------
/docs/_static/annotations_enhanced.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/annotations_enhanced.png
--------------------------------------------------------------------------------
/docs/_static/annotations_simple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/annotations_simple.png
--------------------------------------------------------------------------------
/docs/_static/demo_pinout_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/demo_pinout_diagram.png
--------------------------------------------------------------------------------
/docs/_static/huzzah32_pinout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/huzzah32_pinout.png
--------------------------------------------------------------------------------
/docs/_static/kicad_export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/kicad_export.png
--------------------------------------------------------------------------------
/docs/_static/kicad_screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/kicad_screenshot.png
--------------------------------------------------------------------------------
/docs/_static/label_dimensions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/label_dimensions.png
--------------------------------------------------------------------------------
/docs/_static/quick_start_measurements_labels.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/quick_start_measurements_labels.png
--------------------------------------------------------------------------------
/docs/_static/quick_start_measurements_pins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/quick_start_measurements_pins.png
--------------------------------------------------------------------------------
/docs/_static/quick_start_measurements_scale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/quick_start_measurements_scale.png
--------------------------------------------------------------------------------
/docs/_static/quick_start_pinout_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/docs/_static/quick_start_pinout_diagram.png
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | import os
14 | import sys
15 |
16 | sys.path.insert(0, os.path.abspath("../../pinout/"))
17 |
18 |
19 | # -- Project information -----------------------------------------------------
20 |
21 | project = "pinout"
22 | copyright = "2021, John Newall"
23 | author = "John Newall"
24 |
25 | # The full version, including alpha/beta/rc tags
26 | release = "0.0.20"
27 |
28 |
29 | # -- General configuration ---------------------------------------------------
30 |
31 | # Add any Sphinx extension module names here, as strings. They can be
32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
33 | # ones.
34 | extensions = [
35 | "sphinx.ext.autodoc",
36 | ]
37 |
38 | # Add any paths that contain templates here, relative to this directory.
39 | templates_path = ["_templates"]
40 |
41 | # List of patterns, relative to source directory, that match files and
42 | # directories to ignore when looking for source files.
43 | # This pattern also affects html_static_path and html_extra_path.
44 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
45 |
46 |
47 | # -- Options for HTML output -------------------------------------------------
48 |
49 | # The theme to use for HTML and HTML Help pages. See the documentation for
50 | # a list of builtin themes.
51 | #
52 | html_theme = "sphinx_rtd_theme"
53 |
54 | # Add any paths that contain custom static files (such as style sheets) here,
55 | # relative to this directory. They are copied after the builtin static files,
56 | # so a file named "default.css" will overwrite the builtin "default.css".
57 | html_static_path = ["_static"]
58 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. pinout documentation master file, created by
2 | sphinx-quickstart on Tue Mar 16 00:16:18 2021.
3 |
4 | **pinout**
5 | ==========
6 |
7 | SVG diagram creation from Python code - **pinout** provides an easy method to create pin-out diagrams for electronic hardware.
8 |
9 | .. figure:: _static/demo_pinout_diagram.*
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 | :caption: Contents:
14 |
15 | pages/install
16 | pages/tutorial
17 | pages/KiCad_integration
18 | pages/modules
19 | pages/customise
20 | pages/resources
21 |
22 |
23 |
24 | Indices and tables
25 | ==================
26 |
27 | * :ref:`genindex`
28 | * :ref:`modindex`
29 | * :ref:`search`
30 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/pages/annotation.rst:
--------------------------------------------------------------------------------
1 | Annotations
2 | ===========
3 |
4 | .. currentmodule:: pinout.components.annotation
5 |
6 | Annotation
7 | ----------
8 |
9 | .. autoclass:: AnnotationLabel
10 | :show-inheritance:
11 |
12 | An alternative method to 'label' a diagram, suitable for highlighting hardware details.
13 |
14 | It is likely the body, leaderline, and target will all require customisation to best suit specific usages. Several methods of customisation are possible:
15 |
16 | **diagram-wide customisations**:
17 |
18 | - Over-ride dictionary settings in pinout.config.annotation
19 | - Over-ride default annotation body, leaderline, and target classes
20 |
21 | **instance specific customisations**:
22 |
23 | - Supply a dictionary of arguments to body, content, leaderline, and target attributes. These override config.annotation settings
24 | - provide an alternative component instance to body, content, leaderline, and target attributes.
25 |
26 | :param content: [description]
27 | :type content: [type]
28 | :param body: [description], defaults to None
29 | :type body: [type], optional
30 | :param leaderline: [description], defaults to None
31 | :type leaderline: [type], optional
32 | :param target: [description], defaults to None
33 | :type target: [type], optional
34 |
35 |
36 | Body
37 | ----
38 | .. autoclass:: Body
39 | :show-inheritance:
40 |
41 |
42 | Content
43 | -------
44 | .. autoclass:: Content
45 | :show-inheritance:
46 |
47 | Content can be provided as a string, list, dictionary, or component instance. Strings are presented as a single line. Entries of a list present as lines of text. If a dictionary is provided it updates the default config settings and expects the 'content' attribute to be a list.
48 |
49 |
50 | Leaderline
51 | ----------
52 |
53 | .. autoclass:: Leaderline
54 | :show-inheritance:
55 |
56 | Target
57 | ------
58 |
59 | .. autoclass:: Target
60 | :show-inheritance:
--------------------------------------------------------------------------------
/docs/pages/config.rst:
--------------------------------------------------------------------------------
1 | .. _Config:
2 |
3 | Config
4 | ======
5 |
6 | Components with a graphical representation have a variety of configuration attributes that affect their appearance. These attributes can be modified at several location whilst scripting.
7 |
8 |
9 | Default values
10 | --------------
11 |
12 | These attributes are stored as Python dictionaries in the **config** module.
13 |
14 | A complete set of all default configurations can be duplicated for reference from the command line::
15 |
16 | py -m pinout.manager --duplicate config
17 |
18 | # expected response:
19 | # >>> config.py duplicated.
20 |
21 | Amending the default configurations can be done by replacing or updating any of the dictionaries with plain Python::
22 |
23 | from pinout import config
24 | config.pinlabel["body"].update({"width": 120})
25 |
26 | # All pin-label bodies will now default to 120 wide
27 |
28 |
29 | Instance attributes
30 | -------------------
31 |
32 | PinLabels and Annotations accept a dictionary of configurations for some attributes. These values are used to update the default settings for that single instance. This is ideal when small alterations are required for a low number items::
33 |
34 | from pinout.core import Diagram
35 | from pinout.components.pinlabel import PinLabel
36 |
37 | diagram = Diagram(1200, 675, "pinout")
38 | diagram.add(
39 | PinLabel(
40 | x=30,
41 | y=30,
42 | tag="sm-label",
43 | body={"width": 40},
44 | )
45 | )
46 |
47 |
--------------------------------------------------------------------------------
/docs/pages/customise.rst:
--------------------------------------------------------------------------------
1 | Customisation
2 | =============
3 |
4 | Documentation conveys not just information about its subject but also the personality of the owner. In the context of product/electronics documentation this 'personality' may be of the hardware itself, the creator of the hardware, or company that creates/distributes/sells the hardware.
5 |
6 | Many *pinout* components have facility for customisation and easy integration into a diagram.
7 |
8 |
9 | Stylesheet
10 | ----------
11 |
12 | The first stop for altering a diagram's appearance is to edit its stylesheet. Presentation styles are all controlled here. If you are coming with some knowlege of CSS for web, be aware SVG has some different names for rules!
13 |
14 |
15 | Component config
16 | ----------------
17 |
18 | Altering the geometry of default components can be done by changing, or providing new, config values. See the :ref:`Config` section for more details
19 |
20 | Building components
21 | -------------------
22 |
23 | It is possible to build new components and integrate them into *pinout*.
24 |
25 | Existing components are split into parts to allow easier overriding. Where a universal change is desired this maybe the best approach - until a guide is written for this, reviewing the package code (hosted on `github `_) is recommended.
26 |
27 | Insertion of customised elements into some component instances is also possible and suitable where only small changes, or multiple variants, of a component are required in a single diagram.
28 |
29 | **PinLabel** has 'leaderline' and 'body' attributes. These accept either a dictionary of values (see :ref:`Config`) or an instance that will be used in preference to the equivalent default component.
30 |
31 | **Annotation** has 'leaderline', 'body', and 'target' atttributes that accept new component instances.
32 |
33 | **An example**: The following code can be added to the quick_start script ('pinout_diagram.py') for quick and easy testing::
34 |
35 | # Import required modules and class at top of the script
36 | from pinout.components import pinlabel
37 | from pinout.core import Path
38 |
39 | # Create a new pin-label body class
40 | # and override the render function
41 | class SkewLabelBody(pinlabel.Body):
42 | def render(self):
43 | skew = 3
44 | path_def = " ".join(
45 | [
46 | f"M {self.x + skew} {self.y -self.height/2}",
47 | f"l {self.width} 0",
48 | f"l {-skew*2} {self.height}",
49 | f"l {-self.width} 0" "Z",
50 | ]
51 | )
52 | body = Path(path_definition=path_def, tag="label__body")
53 | return body.render()
54 |
55 |
56 | # Insert the following before the export statement
57 | # Add an instance of the custom pin-label body to the diagram
58 | diagram.add(
59 | pinlabel.PinLabel(
60 | content="SKEWED",
61 | x=50,
62 | y=50,
63 | body=SkewLabelBody(70, 0, 100, 30),
64 | )
65 | )
66 |
--------------------------------------------------------------------------------
/docs/pages/install.rst:
--------------------------------------------------------------------------------
1 | .. _install:
2 |
3 | Install and Quickstart
4 | ======================
5 |
6 |
7 | Install
8 | -------
9 |
10 | Using a virtual environment is recommended; Start by installing the *pinout* package from PyPi::
11 |
12 | pip install pinout
13 |
14 | # Or upgrade to the latest version
15 | pip install --upgrade pinout
16 |
17 | *pinout* exports diagrams in SVG format and can be used with with no further package installations. With the additional installation of CairoSVG, diagrams can also be exported in PNG, PDF, and PS formats::
18 |
19 | pip install cairosvg
20 |
21 | .. warning::
22 | CairoSVG has non-Python dependencies that will require installing if not present. Installation varies depending on platform and may feel like quite a journey for non-technical users. Information regarding installation requirements can be found in the `CairoSVG `_ and `Cairo Graphics Library `_ websites.
23 |
24 | For Windows users `installing GTK3 via MSYS2 `_ may be the most reliable method to install all requirements (Don't forget to add the correct GTK bin folder to the system PATH environmental variable!)
25 |
26 |
27 | .. _quickstart:
28 |
29 | Quickstart
30 | ----------
31 |
32 | .. image:: /_static/quick_start_pinout_diagram.*
33 |
34 | This guide makes use of a hardware image, stylesheet, data file, and a Python script. Sample files are included with the package and can be duplicated for your use. Open a command line (with enabled virtual environment if you are using one) in the location you plan to work and enter the following
35 |
36 | .. note::
37 | Depending on your operating system the command to invoke Python may differ. This guide uses Windows default method. Exchanging 'py' for 'python' or similar may be required for examples to work on other systems.
38 |
39 | ::
40 |
41 | py -m pinout.manager --duplicate quick_start
42 |
43 | # expected output:
44 | # >>> data.py duplicated.
45 | # >>> hardware.png duplicated.
46 | # >>> pinout_diagram.py duplicated.
47 | # >>> styles.css duplicated.
48 |
49 |
50 | Generating the final SVG graphic is done from the command line::
51 |
52 | py -m pinout.manager --export pinout_diagram.py diagram.svg
53 |
54 | If everything is correctly configured the newly created file 'diagram.svg' can be viewed in a browser and should look identical to the diagram pictured here.
55 |
56 | .. warning::
57 | **Not all SVG viewers are build equal!**
58 | *pinout* uses SVG format 'under-the-hood' and can also output diagrams in this format. SVG is well supported by modern browsers and applications that *specialize* in rendering SVG such as InkScape. If a *pinout* diagram displays unexpected results (eg. mis-aligned text) cross-check by viewing the diagram in an up-to-date browser (eg. Firefox or Chrome) as an initial trouble-shooting step.
59 |
60 | Once you have installed the *pinout* package explore its main features in the :ref:`tutorial`.
--------------------------------------------------------------------------------
/docs/pages/integrated_circuits.rst:
--------------------------------------------------------------------------------
1 | Integrated circuits
2 | ===================
3 |
4 | .. currentmodule:: pinout.components.integrated_circuits
5 |
6 | *pinout* can generate simple integrated circuit (IC) graphics - Ideal for documenting stand-alone IC components.
7 |
8 | DIP and QFP components can be utilised in a diagram in the same way as an image. However helper functions also exists for easy application of labels to these component.
9 |
10 |
11 | Labelled QFP graphic
12 | --------------------
13 |
14 | .. autofunction:: labelled_qfn
15 |
16 | :param labels: List of label data
17 | :type labels: list
18 | :param length: length of the IC sides (including legs), defaults to 160
19 | :type length: int, optional
20 | :param label_start: Offset of the first label from the first pin, defaults to (100, 20)
21 | :type label_start: tuple, optional
22 | :param label_pitch: Offest between each label row, defaults to (0, 30)
23 | :type label_pitch: tuple, optional
24 | :return: IC graphic with pinlabels applied
25 | :rtype: SVG markup
26 |
27 |
28 | Labelled DIP graphic
29 | --------------------
30 |
31 | .. autofunction:: labelled_dip
32 |
33 | :param labels: List of label data
34 | :type labels: list
35 | :param width: Width of IC (includes legs), defaults to 100
36 | :type width: int, optional
37 | :param height: Height of IC (includes inset), defaults to 160
38 | :type height: int, optional
39 | :param label_start_x: Offset in x-axis of first label from first pin, defaults to 100
40 | :type label_start_x: int, optional
41 | :param label_pitch: Offest between each label row, defaults to (0, 30)
42 | :type label_pitch: tuple, optional
43 | :return: IC graphic with pinlabels applied
44 | :rtype: SVG markup
45 |
46 |
47 | Dual in-line package (DIP)
48 | --------------------------
49 |
50 | .. autoclass:: DIP
51 | :show-inheritance:
52 |
53 | :param pin_count: Total number of pins on the integrated circuit
54 | :type pin_count: int
55 | :param width: width of the graphic, including body and legs
56 | :type width: int
57 | :param height: height of the graphic, including body and legs
58 | :type height: int
59 |
60 | Dimensions can be modified to depict a variety of IC types, eg SOIC and TSOP.
61 |
62 | .. autoproperty:: pin_coords
63 |
64 | :param index: Pin number (starts at 1)
65 | :type index: int
66 | :param rotate: If true, includes component rotation in the calculation, defaults to True
67 | :type rotate: bool, optional
68 | :return: coordinates of the pin relative to the IC's origin
69 | :rtype: namedtuple (x,y)
70 |
71 |
72 | Quad flat package (QFP)
73 | -----------------------
74 |
75 | .. autoclass:: QFP
76 | :show-inheritance:
77 |
78 | :param pin_count: Total number of pins on the integrated circuit
79 | :type pin_count: int
80 | :param length: length of the QFP sides
81 | :type length: int
82 |
83 | Dimensions can be modified to depict a variety of 'quad' IC types.
84 |
85 | .. autoproperty:: pin_coords
86 |
87 | :param index: Pin number (starts at 1)
88 | :type index: int
89 | :param rotate: If true, includes component rotation in the calculation, defaults to True
90 | :type rotate: bool, optional
91 | :return: coordinates of the pin relative to the IC's origin
92 | :rtype: namedtuple (x,y)
--------------------------------------------------------------------------------
/docs/pages/layout.rst:
--------------------------------------------------------------------------------
1 | Layout
2 | ======
3 |
4 | .. currentmodule:: pinout.components.layout
5 |
6 | Diagram
7 | --------
8 |
9 | .. autoclass:: Diagram
10 | :show-inheritance:
11 |
12 | :param width: width of diagram
13 | :type width: int
14 | :param height: height of diagram
15 | :type height: int
16 | :param tag: CSS class applied to diagram, defaults to None
17 | :type tag: string (must comply to CSS naming rules), optional
18 |
19 | .. automethod:: Diagram.add_stylesheet
20 |
21 | Pinout relies on cascading-style-sheet (CSS) rules to control presentation attributes of components.
22 |
23 | The path attribute is dependent on whether the styles are linked or embedded. When linked, the path is relative to the exported file. When embedded the path is relative to the diagram script file.
24 |
25 | :param path: Path to stylesheet file
26 | :type path: string
27 | :param embed: embed stylesheet in exported file, defaults to True
28 | :type embed: bool, optional
29 |
30 |
31 | .. automethod:: Diagram.render
32 |
33 | :return: SVG markup
34 | :rtype: string
35 |
36 | Panel
37 | -----
38 | .. autoclass:: Panel
39 | :show-inheritance:
40 |
41 | The basic building block to control layout (grouping and location) of components that make up a complete diagram document. The Panel component renders two rectangles - and outer and inner rectangle - behind all child components to assist with graphical styling.
42 |
43 | The inset attribute controls dimensions of the 'inner rectangle'. All children are aligned relative to the inset coordinate (x1, y1).
44 |
45 | The inner dimensions can be accessed via the properties ``Panel.inset_width`` and ``Panel.inset_height``.
46 |
47 | :param width: Width of component
48 | :type width: int
49 | :param height: Height of component
50 | :type height: int
51 | :param inset: Inset of inner dimensions, defaults to None
52 | :type inset: Tuple (x1, y1, x2, y2), optional
53 |
--------------------------------------------------------------------------------
/docs/pages/leaderline.rst:
--------------------------------------------------------------------------------
1 | Leaderlines
2 | ===========
3 |
4 | .. currentmodule:: pinout.components.leaderline
5 |
6 |
7 | Leaderline
8 | ----------
9 | .. autoclass:: Leaderline
10 | :show-inheritance:
11 |
12 | :param direction: 2 letter code, defaults to "hh"
13 | :type direction: str, optional
14 |
15 | The leaderline connects an origin and destination point. Route taken is controlled with a *direction* argument where the first character dictates the start direction and the second character the end direction:
16 |
17 | - **vh**: vertical , horizontal
18 | - **hv**: horizontal , vertical
19 | - **hh**: horizontal , horizontal
20 | - **vv**: vertical , vertical
21 |
22 |
23 | .. automethod:: Leaderline.end_points
24 |
25 | The end_point method takes two components as arguments and returns coordinates that are aligned with the centre coordinates of the relevant side.
26 |
27 | :param origin: origin component
28 | :type origin: component with width and height attributes and bounding_coords method
29 | :param destination: destination component
30 | :type destination: component with width and height attributes and bounding_coords method
31 | :return: coordinates of start and end points
32 | :rtype: Tuple ((ox, oy), (dx, dy))
33 |
34 | Curved
35 | ------
36 | .. autoclass:: Curved
37 | :show-inheritance:
38 |
39 |
40 | Angled
41 | ------
42 | .. autoclass:: Angled
43 | :show-inheritance:
44 |
45 |
46 | Straight
47 | --------
48 | .. autoclass:: Straight
49 | :show-inheritance:
50 |
--------------------------------------------------------------------------------
/docs/pages/legend.rst:
--------------------------------------------------------------------------------
1 | Legend
2 | ======
3 |
4 | .. currentmodule:: pinout.components.legend
5 |
6 | Legend
7 | ------
8 |
9 | .. autoclass:: Legend
10 |
11 | *Note*: *pinout* does not calculate text widths. A manually provided width may be required to ensure text remains enclosed within the legend.
12 |
13 | :param data: [description]
14 | :type data: [type]
15 | :param max_height: [description], defaults to None
16 | :type max_height: [type], optional
17 |
18 |
19 | Swatch
20 | ------
21 |
22 | .. autoclass:: Swatch
23 |
24 | :param width: Width of swatch, defaults to None
25 | :type width: int, optional
26 | :param height: Height of swatch, defaults to None
27 | :type height: int, optional
28 |
29 |
30 | Entry
31 | -----
32 |
33 | .. autoclass:: LegendEntry
34 |
35 | The swatch attribute accepts either a dictionary of Swatch attributes or a Swatch instance. Swatch styling (ie filling with color) is done via CSS and should reference the LegendEntry class(es).
36 |
37 | :param content: Text displayed in entry
38 | :type content: [type]
39 | :param width: Width of entry, defaults to None
40 | :type width: int, optional
41 | :param height: height of entry, defaults to None
42 | :type height: int, optional
43 | :param swatch: Graphical icon included in entry, defaults to None
44 | :type swatch: dict or Swatch, optional
45 |
46 |
--------------------------------------------------------------------------------
/docs/pages/manager.rst:
--------------------------------------------------------------------------------
1 | Manager
2 | =======
3 |
4 | The manager module provides various functions to assist *pinout* create diagrams. For users, Manager is primarily accessed via the command-line for the following.
5 |
6 | Duplicate quick_start files
7 | ---------------------------
8 |
9 | A fast way to get started exploring *pinout* is by trying out the quick_start diagram that is featured in the tutorial. Required files can be duplicated from the *pinout* package via command line::
10 |
11 | py -m pinout.manager --duplicate quick_start
12 |
13 | # expected output:
14 | # >>> data.py duplicated.
15 | # >>> hardware.png duplicated.
16 | # >>> pinout_diagram.py duplicated.
17 | # >>> styles.css duplicated.
18 |
19 | *-d* works as a short-hand version of *--duplicate*
20 |
21 | Export an SVG diagram
22 | ---------------------
23 |
24 | Once a diagram has been documented it can be exported to SVG format via the command-line. Two arguments must be supplied. A path to the diagram python script and destination path including filename::
25 |
26 | >>> py pinout.manager --export pinout_diagram.py my_diagram.svg
27 |
28 | # expected response:
29 | # 'my_diagram.svg' exported successfully.
30 |
31 | # Example where pinout.Diagram instance is named 'board_x_diagram'
32 | >>> py pinout.manager --export pinout_diagram.py my_diagram.svg board_x_diagram
33 |
34 | Details to note:
35 |
36 | - *--export* can be expressed as a single letter *-e*
37 | - An *--overwrite* (*-o*) can also be included to overwrite an existing file
38 | - if the instance name is not 'diagram' the alternative name can be added as as third argument
39 |
40 | Export in other formats
41 | -----------------------
42 |
43 | With the addition of CairoSVG *pinout* is able to export to PNG, PDF, and PS formats. Installation is done via pip::
44 |
45 | pip install cairosvg
46 |
47 | .. note::
48 |
49 | CairoSVG has it's own (non-Python) dependencies. See :ref:`Install` for more details.
50 |
51 | Once these dependencies have been installed replace the filename suffix to export in the desired format::
52 |
53 | # Export as png
54 | >>> py pinout.manager --export pinout_diagram.py my_diagram.png
55 |
56 | # Export as pdf
57 | >>> py pinout.manager --export pinout_diagram.py my_diagram.pdf
58 |
59 | # Export as ps
60 | >>> py pinout.manager --export pinout_diagram.py my_diagram.ps
61 |
62 |
63 | Generate a cascading stylesheet
64 | -------------------------------
65 |
66 | Provided with a diagram file, the manager can extract components and tags, then export a stylesheet based on this data to assist with styling. The resulting stylesheet can then be further edited or a second stylesheet created to supplement the default styles::
67 |
68 | >>> py pinout.manager --css pinout_diagram.py diagram_styles.css
69 |
70 | # expected response:
71 | # Stylesheet created: 'diagram_styles.css'
72 |
73 | As with exporting an SVG, the *-o* flag can be used to overwrite and existing file. Note, there is no short-hand for the *-css* flag.
--------------------------------------------------------------------------------
/docs/pages/modules.rst:
--------------------------------------------------------------------------------
1 | .. _modules:
2 |
3 | Modules
4 | =======
5 |
6 |
7 | .. toctree::
8 | :maxdepth: 2
9 | :caption: Contents:
10 |
11 | manager
12 | config
13 | core
14 | layout
15 | pinlabel
16 | leaderline
17 | annotation
18 | legend
19 | text
20 | integrated_circuits
21 |
--------------------------------------------------------------------------------
/docs/pages/pinlabel.rst:
--------------------------------------------------------------------------------
1 | Pin Labels
2 | ==========
3 |
4 | .. currentmodule:: pinout.components.pinlabel
5 |
6 | Base
7 | ----
8 | .. autoclass:: Base
9 | :show-inheritance:
10 |
11 | :param content: Text displayed in label, defaults to ""
12 | :type content: str, optional
13 | :param x: position of label on x-axis , defaults to 0
14 | :type x: int, optional
15 | :param y: position of label on y-axis, defaults to 0
16 | :type y: int, optional
17 | :param tag: categorise the label - applied as a CSS class, defaults to None
18 | :type tag: str (CSS name compliant), optional
19 | :param body: replace or configure the default body component, defaults to None
20 | :type body: dict or pinlabel.Body instance, optional
21 | :param leaderline: replace or configure the default leaderline component, defaults to None
22 | :type leaderline: dict or pinlabel.Leaderline, optional
23 |
24 |
25 |
26 | PinLabel
27 | --------
28 | .. autoclass:: PinLabel
29 | :show-inheritance:
30 |
31 | See Base for details of this component.
32 |
33 | Body
34 | ----
35 | .. autoclass:: Body
36 | :show-inheritance:
37 |
38 | :param x: position of label on x-axis
39 | :type x: int
40 | :param y: position of label on y-axis
41 | :type y: int
42 | :param width: Width of label body
43 | :type width: int
44 | :param height: Height of label body
45 | :type height: int
46 | :param corner_radius: Corner radius of label body, defaults to 0
47 | :type corner_radius: int, optional
48 |
49 |
50 | Leaderline
51 | ----------
52 | .. autoclass:: Leaderline
53 | :show-inheritance:
54 |
55 | :param lline: Override configuration or replace the pinlabel's leaderline.
56 | :type lline: dict of leaderline attributes or replacement Leaderline instance
57 |
58 | PinLabelGroup
59 | -------------
60 | .. autoclass:: PinLabelGroup
61 | :show-inheritance:
62 |
63 | This is the recommended method of adding pin labels to a diagram. Locate the PinLabelSet by setting *x* and *y* attributes.
64 |
65 | Pitch is the distance, in pixels, between each pin of the header. (0, 30) steps 0px right and 30px down for each pin. (30, 0) creates a horizontal header. (-30, 0) creates a horizontal header in the reverse direction. This can be useful for 'stacking' rows in reversed order to avoid leader-lines overlapping.
66 |
67 | :param x: x-coordinate of the first pin in the header
68 | :type x: int
69 | :param y: y-coordinate of the first pin in the header
70 | :type y: int
71 | :param pin_pitch: Distance between pins in the header
72 | :type pin_pitch: tuple: (x,y)
73 | :param label_start: Offset of the first label from the first pin
74 | :type label_start: tuple: (x,y)
75 | :param label_pitch: Distance between each row of labels
76 | :type label_pitch: tuple: (x,y)
77 | :param labels: Label data
78 | :type labels: List
79 | :param leaderline: Leaderline customisations, defaults to None
80 | :type leaderline: dict or Leaderline object, optional
81 | :param body: Label body customisations, defaults to None
82 | :type body: dict or LabelBody object, optional
83 |
--------------------------------------------------------------------------------
/docs/pages/resources.rst:
--------------------------------------------------------------------------------
1 | Resources
2 | =========
3 |
4 | Every *pinout* diagram has the fundamental requirement of an image to enhance with graphical additions. This prerequisite can be sizable barrier to creating the clearest diagram possible.
5 |
6 | During *pinout* development several image create methods have been investigated. Community members have also reached out and generously provided feedback and further options to tryout.
7 |
8 | Documented here is a list of what was tried during *pinout* development and some community input (some tried, some on my list to try out). The intent is to revisit all option and write-up some reviews and process notes.
9 |
10 | + Export from KiCad
11 | + Create from scratch
12 | + InkScape
13 | + Illustrator
14 | + With exported elements from KiCad
15 | + Photograph
16 | + https://github.com/yaqwsx/PcbDraw
17 | + fritzing
18 |
--------------------------------------------------------------------------------
/docs/pages/text.rst:
--------------------------------------------------------------------------------
1 | Text
2 | ====
3 |
4 | .. currentmodule:: pinout.components.text
5 |
6 | TextBlock
7 | ---------
8 |
9 | .. autoclass:: TextBlock
10 | :show-inheritance:
11 |
12 | The TextBlock accepts either a string or list for content. Each list entry is presented as a line of text. Where a string is provided, it is converted to a list by splitting on new-line characters ('\\n') and stripping whitespace from start and end of each line created.
13 |
14 | .. note::
15 |
16 | *pinout* cannot detect text character size! Consequently care should be taken to ensure text does not render outside expected boundaries.
17 |
18 | :param content: Text to be displayed
19 | :type content: String or List
20 | :param line_height: Distance between lines, defaults to None
21 | :type line_height: int, optional
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | Jinja2
--------------------------------------------------------------------------------
/pinout.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "setuptools>=42",
4 | "wheel"
5 | ]
6 | build-backend = "setuptools.build_meta"
--------------------------------------------------------------------------------
/pinout/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/pinout/__init__.py
--------------------------------------------------------------------------------
/pinout/components/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/j0ono0/pinout/8a718a4699468d93175624f0683d2dc9a628de78/pinout/components/__init__.py
--------------------------------------------------------------------------------
/pinout/components/annotation.py:
--------------------------------------------------------------------------------
1 | import copy
2 | from pinout import core
3 | from pinout.components.text import TextBlock
4 | from pinout.components import leaderline as lline
5 | from pinout.components.layout import Group
6 |
7 | from pinout import config
8 |
9 |
10 | class Leaderline(lline.Curved):
11 | pass
12 |
13 |
14 | class Target(core.Rect):
15 | pass
16 |
17 |
18 | class Body(core.Rect):
19 | pass
20 |
21 |
22 | class Content(TextBlock):
23 | pass
24 |
25 |
26 | class AnnotationLabel(Group):
27 | """Annotation style label."""
28 |
29 | def __init__(
30 | self,
31 | content=None,
32 | body=None,
33 | leaderline=None,
34 | target=None,
35 | **kwargs,
36 | ):
37 | self._content = None
38 | self._body = None
39 | self._leaderline = None
40 | self._target = None
41 |
42 | super().__init__(**kwargs)
43 | self.update_config(config.annotation)
44 | self.add_tag(self.config["tag"])
45 |
46 | self.leaderline = leaderline
47 | self.body = body
48 | self.target = target
49 | # content relied on body - must come after
50 | self.content = content
51 |
52 | # Route leaderline once other elements exist
53 | self._leaderline.route(self.target, self.body)
54 |
55 | self.add(self.leaderline)
56 | self.add(self.target)
57 | self.add(self.body)
58 | self.add(self.content)
59 |
60 | @property
61 | def content(self):
62 | return self._content
63 |
64 | @content.setter
65 | def content(self, content):
66 | content = copy.deepcopy(content or {})
67 | config = self.config["content"]
68 | # Parse content: str > list > dict > TextBlock
69 | if type(content) is str:
70 | content = [content]
71 | if type(content) is list:
72 | content = {
73 | "content": content,
74 | "x": self.body.x + self.body.width / 2,
75 | "y": (self.body.y + self.body.height / 2)
76 | - (config["line_height"] * (len(content) - 1) / 2 * self.scale.y),
77 | }
78 | if isinstance(content, dict):
79 | config.update(content)
80 | content = Content(**config)
81 | content.add_tag(self.config["content"]["tag"])
82 | content.scale = self.scale
83 | self._content = content
84 |
85 | @property
86 | def leaderline(self):
87 | return self._leaderline
88 |
89 | @leaderline.setter
90 | def leaderline(self, leaderline):
91 | leaderline = copy.deepcopy(leaderline or {})
92 | if isinstance(leaderline, dict):
93 | leaderline_config = self.config["leaderline"]
94 | leaderline_config.update(leaderline)
95 | leaderline = Leaderline(**leaderline_config)
96 | leaderline.add_tag(self.config["leaderline"]["tag"])
97 | self._leaderline = leaderline
98 |
99 | @property
100 | def target(self):
101 | return self._target
102 |
103 | @target.setter
104 | def target(self, target):
105 | target = copy.deepcopy(target or {})
106 | if isinstance(target, dict):
107 | target_config = self.config["target"]
108 | target_config.update(target)
109 | target = Target(**target_config)
110 | target.add_tag(self.config["target"]["tag"])
111 | self._target = target
112 |
113 | @property
114 | def body(self):
115 | return self._body
116 |
117 | @body.setter
118 | def body(self, body):
119 | body = copy.deepcopy(body or {})
120 | if isinstance(body, dict):
121 | body_config = self.config["body"]
122 | body_config.update(body)
123 | body = Body(**body_config)
124 | body.add_tag(self.config["body"]["tag"])
125 | self._body = body
126 |
--------------------------------------------------------------------------------
/pinout/components/layout.py:
--------------------------------------------------------------------------------
1 | import uuid
2 | from pinout import templates, config
3 | from pinout.core import (
4 | Layout,
5 | StyleSheet,
6 | Group,
7 | SvgShape,
8 | Rect,
9 | BoundingCoords,
10 | )
11 |
12 |
13 | class Diagram(Layout):
14 | """Basis of a pinout diagram"""
15 |
16 | def __init__(self, width, height, tag=None, **kwargs):
17 | self.width = width
18 | self.height = height
19 | super().__init__(tag=tag, **kwargs)
20 | self.add(SvgShape(width=width, height=height))
21 |
22 | def add_stylesheet(self, path, embed=False):
23 | """Add a stylesheet to the diagram"""
24 | self.children.insert(0, StyleSheet(path, embed))
25 |
26 | def render(self):
27 | """Render children into an