Skip to content

Commit

Permalink
Version 0.1.0
Browse files Browse the repository at this point in the history
++++++++++++++

Initial port of datalog/datamatrix-svg.
  • Loading branch information
adrianschlatter committed May 30, 2021
2 parents 9709d78 + 5c9eb3f commit ca2a705
Show file tree
Hide file tree
Showing 29 changed files with 1,524 additions and 12 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ __pycache__/

# due to using coverage
.coverage
htmlcov/

# due to vscode:
.vscode/

# due to Mac:
**/.DS_Store

# due to comparing against the code we port from:
datamatrix-svg/
5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Include the license file
include LICENSE

# Exclude docs (they are needed on github and pypi, not in installation):
recursive-exclude docs *
6 changes: 0 additions & 6 deletions README.md

This file was deleted.

68 changes: 68 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<img alt="ppf.datamatrix logo" src="./imgs/logo.svg" width="500em">

ppf.datamatrix is a pure-python package to generate datamatrix codes in SVG. Also, it integrates nicely in IPython.

ppf.datamatrix has been ported from [datalog's datamatrix-svg](https://github.com/datalog/datamatrix-svg), which is written in javascript. If you like to see what you'll get before installation, check out their [nice web demo](https://datalog.github.io/demo/datamatrix-svg).

Creating a datamatrix with ppf.datamatrix is as easy as

```
from ppf.datamatrix import DataMatrix
myDataMatrix = DataMatrix('Test!')
```

If you are working in a graphically enabled IPython terminal, you'll see your datamatrix immediately:

![IPython integration](imgs/ipython.png)

Using the DataMatrix object you get the SVG source like this:

```
myDataMatrix.svg()
'<?xml version="1.0" encoding="utf-8" ?><svg ...'
```

<img alt="Test! DataMatrix" src="./imgs/Test.svg" width="50em">

Use this on your website, to stamp a pdf, to uniquely identify a drawing, or whatever you like. Background and foreground color are configurable by specifying fg and/or bg arguments. Create a light blue matrix on a petrol background like this:

```
myDataMatrix.svg(fg='#EEF', bg='#09D')
```

<img alt="Test! DataMatrix in red on blue background" src="./imgs/Test_colored.svg" width="50em">

Note: This sets the colors of the SVG. It does *not* change the color of the representation inside your IPython terminal.


## Advanced Features

ppf.datamatrix supports a [variety of encodings](https://en.m.wikipedia.org/wiki/Data_Matrix#Encoding), namely EDIFACT ('datamatrix.edifact'), ASCII ('datamatrix.ascii'), X12 ('datamatrix.X12'), C40 ('datamatrix.C40'), TEXT ('datamatrix.text'). These are used to store your message inside the datamatrix code efficiently. DataMatrix handles the encoding internally: If you just want to create a DataMatrix, you don't have to care about any of this. If you want to do advanced stuff (designing your own form of matrix code, maybe), ppf.datamatrix enables you to use its encoders. After importing ppf.datamatrix, they are available via the python codecs system:

```
import ppf.datamatrix
encoded = 'TEST'.encode('datamatrix.edifact')
encoded
b'\xf0PT\xd4'
decoded = encoded.decode('datamatrix.edifact')
decoded
'TEST'
```


# Installation

ppf.datamatrix is available via [pypi](https://pypi.org):

```
pip install ppf.datamatrix
```


# Change Log

* 0.1: Initial port of datamatrix–svg
17 changes: 17 additions & 0 deletions docs/README_pypi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# ppf.datamatrix

ppf.datamatrix is a pure-python package to generate datamatrix codes in SVG. Also, it integrates nicely in IPython.

ppf.datamatrix has been ported from [datalog's datamatrix-svg](https://github.com/datalog/datamatrix-svg), which is written in javascript. If you like to see what you'll get before installation, check out their [nice web demo](https://datalog.github.io/demo/datamatrix-svg).

Creating a datamatrix with ppf.datamatrix is as easy as

```
from ppf.datamatrix import DataMatrix
myDataMatrix = DataMatrix('Test!')
```

A graphically enabled IPython terminal will even represent myDataMatrix as a picture.

Check out the project website to find out more!
1 change: 1 addition & 0 deletions docs/imgs/Test.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/imgs/Test_colored.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/imgs/ipython.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions docs/imgs/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 26 additions & 6 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ name = ppf-datamatrix
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version = 0.0.0
version = 0.1.0
description = Python port of https://github.com/datalog/datamatrix-svg
long_description = file: README.md
long_description_content_type='text/markdown',
long_description = file: docs/README_pypi.md
long_description_content_type = text/markdown

# The projects main homepage.
url = https://github.com/adrianschlatter/ppf.datamatrix
url = https://github.com/adrianschlatter/ppf.datamatrix/tree/master
# Author details
author = Adrian Schlatter
# Do *not* provide author_email here. Instead, provide email for
Expand All @@ -25,20 +25,22 @@ classifiers =
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
Development Status :: 3 - Alpha
Development Status :: 4 - Beta
# Indicate who your project is intended for
Intended Audience :: Developers
Intended Audience :: Manufacturing
Intended Audience :: Information Technology
Intended Audience :: Other Audience
Topic :: Utilities
# Pick your license as you wish (should match "license" above)
License :: OSI Approved :: MIT License
# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
Programming Language :: Python :: 3
Operating System :: OS Independent
Framework :: IPython
# What does your project relate to?
keywords = datamatrix, 2d code, barcode, identification
keywords = datamatrix, svg, python, ipython, codecs

[options]
# You can just specify the packages manually here if your project is
Expand All @@ -62,3 +64,21 @@ where = src
# $ pip install -e .[dev,test]
dev = check-manifest
test = pytest; twine; check-manifest; readme_renderer; flake8; coverage

[check-manifest]
ignore =
tox.ini
tests
tests/**
docs/**

[flake8]
per-file-ignores =
# imported but unused, import *, undefined name:
__init__.py: F401, F403, F821
# imported but unused: Needed due to side-effects of import:
test_X12.py: F401
test_C40.py: F401
test_text.py: F401
# bare except: We *are* trying to crash it:
test_smoke.py: E722
33 changes: 33 additions & 0 deletions src/ppf/datamatrix/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
ppf.datamatrix
++++++++++++++
ppf.datamatrix is a pure-python package to generate datamatrix codes.
Example:
from ppf.datamatrix import DataMatrix
my_matrix = DataMatrix('Write your message here')
# get svg of datamatrix:
svg = my_matrix.svg()
"""

# register codecs
from .codec_ascii import *
from .codec_edifact import *
from .codec_C40 import *
from .codec_text import *
from .codec_X12 import *

# import every function, class, etc. that should be visible in the package
from .datamatrix import *

del datamatrix
del codec_ascii
del codec_edifact
del codec_C40
del codec_text
del codec_X12
del codec_common
del utils
60 changes: 60 additions & 0 deletions src/ppf/datamatrix/codec_C40.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
datamatrix.C40 codec
++++++++++++++++++++++
Adds datamatrix.C40 codec to python's codecs.
encoded = 'ABC'.encode('datamatrix.C40')
decoded = encoded.decode('datamatrix.C40')
.. author: Adrian Schlatter
"""
__all__ = []

import codecs
from .codec_common import set1, set2, add_inverse_lookup
from .codec_common import encode_text_mode, decode_text_mode

# Source: https://en.m.wikipedia.org/wiki/Data_Matrix
set0 = ' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
set3 = '`abcdefghijklmnopqrstuvwxyz{|}~' + b'\x7f'.decode('ascii')

codepage = {char: [code] for char, code in zip(set0, range(3, 40))}
codepage = {**codepage,
**{char: [0, code] for char, code in zip(set1, range(40))}}
codepage = {**codepage,
**{char: [1, code] for char, code in zip(set2, range(40))}}
codepage = {**codepage,
**{char: [2, code] for char, code in zip(set3, range(40))}}

add_inverse_lookup(codepage)


def encode_to_C40(msg):
"""Encode to datamatrix.C40."""
return encode_text_mode(msg, codepage, b'\xE6', True)


def decode_from_C40(enc):
"""Decode datamatrix.C40-encoded message."""
try:
msg, length = decode_text_mode(enc, codepage, b'\xE6', True)
except ValueError:
raise ValueError(f'{enc} is not valid C40 code')

return msg, length


def search_codec_C40(encoding_name):
"""Search function needed for registration in python codecs."""
if encoding_name != 'datamatrix.c40':
return None

return codecs.CodecInfo(encode_to_C40,
decode_from_C40,
name='datamatrix.C40')


codecs.register(search_codec_C40)
57 changes: 57 additions & 0 deletions src/ppf/datamatrix/codec_X12.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
datamatrix.X12 codec
++++++++++++++++++++++
Adds datamatrix.X12 codec to python's codecs.
encoded = 'ABC'.encode('datamatrix.X12')
decoded = encoded.decode('datamatrix.X12')
.. author: Adrian Schlatter
"""
__all__ = []

import codecs
from .codec_common import add_inverse_lookup
from .codec_common import encode_text_mode, decode_text_mode

# Source: https://en.m.wikipedia.org/wiki/Data_Matrix
X12 = '\r*> 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'

codepage = {char: [code] for char, code in zip(X12, range(40))}
add_inverse_lookup(codepage)


def encode_to_X12(msg):
"""Encode to datamatrix.X12."""
try:
enc, length = encode_text_mode(msg, codepage, b'\xEE', False)
except ValueError:
raise ValueError(f'{msg} is not encodeable in X12')

return enc, length


def decode_from_X12(enc):
"""Decode datamatrix.X12-encoded message."""
try:
msg, length = decode_text_mode(enc, codepage, b'\xEE', False)
except ValueError:
raise ValueError(f'{enc} is not valid X12 code')

return msg, length


def search_codec_X12(encoding_name):
"""Search function needed for registration in python codecs."""
if encoding_name != 'datamatrix.x12':
return None

return codecs.CodecInfo(encode_to_X12,
decode_from_X12,
name='datamatrix.X12')


codecs.register(search_codec_X12)
40 changes: 40 additions & 0 deletions src/ppf/datamatrix/codec_ascii.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
datamatrix.ascii codec
++++++++++++++++++++++
Adds datamatrix.ascii codec to python's codecs.
encoded = 'ABC'.encode('datamatrix.ascii')
decoded = encoded.decode('datamatrix.ascii')
.. author: Adrian Schlatter
"""
__all__ = []

import codecs


def encode_to_ascii(msg):
"""Encode to datamatrix.ascii."""
enc = msg.encode('ascii')
return bytes([code + 1 for code in enc]), len(msg)


def decode_from_ascii(code):
"""Decode datamatrix.ascii-encoded message."""
return bytes([c - 1 for c in code]).decode('ascii'), len(code)


def search_codec_ascii(encoding_name):
"""Search function needed for registration in python codecs."""
if encoding_name != 'datamatrix.ascii':
return None

return codecs.CodecInfo(encode_to_ascii,
decode_from_ascii,
name='datamatrix.ascii')


codecs.register(search_codec_ascii)
Loading

0 comments on commit ca2a705

Please sign in to comment.