diff --git a/README.md b/README.md
index b565aa6..2def5c4 100644
--- a/README.md
+++ b/README.md
@@ -5,10 +5,27 @@ Generate labels for printing using HTML rendering.
## Features
* Customizable for most label sheet layouts.
+* Partial sheet printing
* Custom data for each label
-* Uses HTML templates for easy customization
+* Uses HTML templates easy label design.
-## TODO
+## Usage
+
+The simplest use case is some static labels:
+
+ python -m pylabel -t examples/simple.html -p avery.L7157 -c 10 > output.html
+
+Then, when you need some more just pop the same sheet back in the printer and offset the start
+
+ python -m pylabel -t examples/simple.html -p avery.L7157 -c 10 > output.html
+
+To do some mail merge operations create a list of names:
+
+ Andy Andrews
+ Bob Brown
+ Charlie Chaplin
+
+and use a `{data[text]}` element in your template. Note we've shifted to an external stylesheet now as well.
+
+ python -m pylabel -t examples/name_tags.html -p avery.L7157 -d examples/names.txt -s examples/hello.css > output.html
-* Switch to profiles for command line usage
-* Switch to
\ No newline at end of file
diff --git a/examples/__init__.py b/examples/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/examples/hello.css b/examples/hello.css
new file mode 100644
index 0000000..3c6fc77
--- /dev/null
+++ b/examples/hello.css
@@ -0,0 +1,33 @@
+
+DIV.label {
+ background-color: red;
+ color: white;
+}
+
+DIV.hello-tag {
+ height: 100%;
+ display: flex;
+ text-align: center;
+ align-items: stretch;
+ flex-direction: column;
+ justify-content: space-between;
+ font-family: Arial;
+ font-size: 10pt;
+}
+
+.greeting {
+ font-size: 20pt;
+ font-weight: bold;
+}
+
+.name {
+ font-family: 'Times New Roman', Times, serif;
+ font-weight: bold;
+ font-size: 20pt;
+ border-radius: 10px;
+ background-color: white;
+ flex-grow: 1;
+ margin-bottom: 2mm;
+ color: #333;
+
+}
\ No newline at end of file
diff --git a/examples/name_tags.html b/examples/name_tags.html
new file mode 100644
index 0000000..b2bb0c4
--- /dev/null
+++ b/examples/name_tags.html
@@ -0,0 +1,5 @@
+
+
Hello
+
my name is
+
{data[text]}
+
\ No newline at end of file
diff --git a/examples/names.txt b/examples/names.txt
new file mode 100644
index 0000000..dac3fc9
--- /dev/null
+++ b/examples/names.txt
@@ -0,0 +1,3 @@
+Andy Andrews
+Bob Brown
+Charlie Chaplin
\ No newline at end of file
diff --git a/examples/simple.html b/examples/simple.html
new file mode 100644
index 0000000..24cffa5
--- /dev/null
+++ b/examples/simple.html
@@ -0,0 +1,5 @@
+
+
Property of
+
Andy Andrews
+
Please return to office if found
+
\ No newline at end of file
diff --git a/examples/simple.py b/examples/simple.py
new file mode 100644
index 0000000..601a1d1
--- /dev/null
+++ b/examples/simple.py
@@ -0,0 +1,15 @@
+from pylabel import avery
+
+profile = avery.L6009
+
+data = range(10)
+
+template = """
+Hello World
+"""
+
+style = """
+.content {
+ font-family: Arial;
+}
+"""
\ No newline at end of file
diff --git a/pylabel/__init__.py b/pylabel/__init__.py
index 123a340..389c2a0 100644
--- a/pylabel/__init__.py
+++ b/pylabel/__init__.py
@@ -21,7 +21,7 @@ class LabelSheet(object):
logger.debug(profile)
self.size = profile['size']
- logger.debug(self.size)
+ logger.debug("Label size: %r", self.size)
# get the pagesize and rotate if landscape
pagesize = profile.get('pagesize', 'a4')
@@ -57,10 +57,20 @@ class LabelSheet(object):
self.layout = layout
# Calculate gaps between labels
- self.gaps = (
- round((self.printarea[0] - layout[0]*self.size[0]) / (layout[0]-1), 1),
- round((self.printarea[1] - layout[1]*self.size[1]) / (layout[1]-1), 1)
- )
+
+ pitch = profile.get('pitch')
+ if pitch:
+ logger.debug("Pitch: %r", pitch)
+ self.gaps = (
+ pitch[0] - self.size[0],
+ pitch[1] - self.size[1],
+ )
+ else:
+ self.gaps = (
+ round((self.printarea[0] - layout[0]*self.size[0]) / (layout[0]-1), 1),
+ round((self.printarea[1] - layout[1]*self.size[1]) / (layout[1]-1), 1)
+ )
+
logger.debug("Gaps: %r", self.gaps)
@property
@@ -87,7 +97,7 @@ DIV.label {{
def render_page(self, template, data, skip=0):
- label_template = f''
+ label_template = f''
blank_labels = "".join([ '' for x in range(skip) ])
diff --git a/pylabel/__main__.py b/pylabel/__main__.py
index 242f53f..edc54da 100644
--- a/pylabel/__main__.py
+++ b/pylabel/__main__.py
@@ -3,30 +3,46 @@ import sys
import logging
import importlib
-from . import LabelSheet
+from pylabel import LabelSheet
+
+class EmptySpec:
+ profile = None
+ template = None
+ data = None
logger = logging.getLogger(__name__)
parser = argparse.ArgumentParser(description="Generate a page of labels")
-parser.add_argument("profile", help="Profile to load")
-
-parser.add_argument('--style', '-s', type=argparse.FileType('r'), help='Additional stylesheet')
+parser.add_argument('--count', '-c', type=int, default=0, help="Number of labels to generate")
parser.add_argument('--skip', '-n', type=int, default=0, help="Skip first n labels")
+parser.add_argument('--profile', '-p', help='Label profile')
parser.add_argument('--template', '-t', type=argparse.FileType('r'), help='Template for label')
-parser.add_argument('--json', '-j', action='store_true', help='Parse lines as json')
-
+parser.add_argument('--style', '-s', type=argparse.FileType('r'), help='Additional stylesheet')
+parser.add_argument('--data', '-d', type=argparse.FileType('r'), help="Pre-generated data, one entry per line")
+parser.add_argument('--json', '-j', action='store_true', help='Parse data lines as json')
parser.add_argument('--logging', '-l', default="info", help="Logging level")
+
+parser.add_argument("spec", nargs="?", help="Specification module")
+
options = parser.parse_args()
logging.basicConfig(level=getattr(logging, options.logging.upper(), logging.INFO))
logger.debug(options)
+if options.spec:
+ spec = importlib.import_module(options.spec)
+else:
+ spec = EmptySpec
+
try:
- module, profile = options.profile.rsplit('.', 1)
- m = importlib.import_module(module)
- p = getattr(m, profile)
+ if options.profile:
+ module, profile = options.profile.rsplit('.', 1)
+ if module.startswith('avery'):
+ module = 'pylabel.avery'
+ m = importlib.import_module(module)
+ spec.profile = getattr(m, profile)
except ValueError:
raise RuntimeError("Expected profile in the form module.profile")
except ModuleNotFoundError:
@@ -34,24 +50,31 @@ except ModuleNotFoundError:
except AttributeError:
raise RuntimeError(f"Unable to file profile {profile} in module {module}")
-sheet = LabelSheet(p)
-
-extra_style=""
-if options.style is not None:
- extra_style = options.style.read()
- options.style.close()
-
-template = '{data[text]}'
if options.template is not None:
- template = options.template.read()
+ spec.template = options.template.read()
options.template.close()
-lines = [ l.strip() for l in sys.stdin.readlines() if l != '\n' ]
-if options.json:
- import json
- data = [ json.loads(line) for line in lines ]
-else:
- data = [ {'text': line} for line in lines ]
+if options.style is not None:
+ spec.style = options.style.read()
+ options.style.close()
-sys.stdout.write(sheet.render_html(template, data, options.skip, extra_style))
\ No newline at end of file
+if options.data is not None:
+ lines = [ l.strip() for l in options.data.readlines() if l != '\n' ]
+ options.data.close()
+ if options.json:
+ import json
+ spec.data = [ json.loads(line) for line in lines ]
+ else:
+ spec.data = [ {'text': line} for line in lines ]
+
+if options.count:
+ spec.data = range(options.count)
+
+for required in ('profile', 'template', 'data'):
+ if not getattr(spec, required):
+ parser.error(f"Missing {required}")
+
+sheet = LabelSheet(spec.profile)
+
+sys.stdout.write(sheet.render_html(spec.template, spec.data, options.skip, getattr(spec, 'style', '')))
\ No newline at end of file
diff --git a/pylabel/avery.py b/pylabel/avery.py
index 8e36453..45a8945 100644
--- a/pylabel/avery.py
+++ b/pylabel/avery.py
@@ -1,4 +1,11 @@
+L6009 = {
+ "size": (45.7, 21.2),
+ "layout": (4, 12),
+ "papersize": "a4",
+ "margins": (9.8, 21.4),
+}
+
L7157 = {
"size": (64, 24.3),
"layout": (3, 11),
diff --git a/pylabel/templates/layout.css b/pylabel/templates/layout.css
index 131c73b..03663d9 100644
--- a/pylabel/templates/layout.css
+++ b/pylabel/templates/layout.css
@@ -22,6 +22,11 @@
}
}
+HTML, BODY {
+ margin: 0;
+ padding: 0;
+}
+
DIV.label {
display: inline-block;
background-color: #FFF;
@@ -29,5 +34,7 @@ DIV.label {
}
DIV.content {
- margin: 2mm; /* Minimum to be safe */
+ /*margin: 2mm; /* Minimum to be safe */
+ height: 100%;
+ margin: 0 2mm;
}
\ No newline at end of file