[barcode] Deciphering command line options

Brendon Oliver brendon.oliver@gmail.com
Wed Jun 17 06:41:23 CEST 2009


I've been playing with this quite a bit this morning, still with no
luck.  I just cannot fathom how you derive the margin values you
quoted:

> horizonally: 0 out-of-table margine and 7mm internal margin
> vertically: 13.5 out-of-table and 1.5 internal:

> barcode  -e code39 -c -u 'mm' -p 210x297  -t 3x15+0+13.5 -m 7,1.5

> I tried with "seq 100001 100045" piped to barcode as above and it looks good.

Yes, looks good, but doesn't match the label sheet I tried to
describe.  I did send a reply to the list earlier, but I haven't seen
it show up. So to recap:

- Vertically it's not _too_ bad. I've run a test print on the real
label sheets, the first row (vertically) is ever so slightly too high.
On the first row of labels, the top of the barcode just barely
overlaps above the label cutline, the bottom of the text just touches
the bottom cutline of the row.  But it still gradually goes out of
alignment further down the page - the 15th (last) row has the top of
the barcode about 1mm _below_ the top cutline of the label, the
baseline of the barcode's text is about 2mm below the bottom cutline
of the label.  However, I must say that this is absolutely the best
vertical alignment I've ever had, and could put up with the slightly
cut-off text.

- Horizontally it's still a mess. Using -t 3x15+0+13.5 -m 7,1.5 has
the following effect

LH margin appears to be about 5mm
RH margin appears to be about 7mm
gap between label cells appears to be about 12mm

which sort of looks like:
5mm [57mm barcode] 12mm [57mm barcode] 12mm [57mm barcode] 7mm **

when what I am trying to get is:

>> 14mm [51mm label] 14mm [51mm label] 14mm [51mm label] 14mm

**NB: that 57mm barcode allows the smallest amount of whitespace
either side of the initial & final bars in the code.  If I measure
exactly from first to last bar of the code, it's more like 56.5mm (or
a teeny bit less - I don't have a ruler more accurate than 1mm).
Obviously, the actual printed code needs to be very slightly less than
the 51mm I need in order to fit within the sticky label (49mm first to
last bar bar would be good - as that would give 1mm whitespace each
end to the label cut mark).

I've been playing with different values for the X-margin to both -t &
-m, but with mixed results... I just cannot nail-down a value (or
combination of values) that will align the labels properly across the
page.  The best I've found so far is: -t 3x15+10+13.5 -m 7,1.5    but
that gives me:

- col #1 of labels, _almost_ perfect.  But the RH end of the barcode
is sooo close to the label cut that if the paper misfeeds even the
slightest bit in the printer, then it may actually print right on the
cut line, and be unreadable by our tape library's scanner;
- col #2 is offset 1mm to the left.. (i.e LH end of the barcode prints
outside the label, there's ~1,5mm whitespace between the RH end of the
code & the label cut.
- col #3 is same as col #2 but offset is ~3mm (maybe 3.5mm) to the
left of the label.

If the offset between the columns was consistent, it might make sense,
but given that col #1 is so close to being perfect, but 2 & 3 "drift"
left, I don't have much leeway to change the values without screwing
up col #1.

So I'm a bit lost as to what to try next.

Just as a bit of background, I'm generating the label sheets from a
perl script (copy included below for interest).  The label text
(depending on the sheet I need) is given by either:
    printf("%06dL4")              eg. 000001L4, 000002L4, 000003L4, etc.    or,
    printf("RAW%03dL4")      eg. RAW001L4, RAW002L4, RAW003L4, etc.    or,
    printf("EFS%03dL4")        eg. EFS001L4, EFS002L4, EFS003L4, etc.

- the %d is always an incrementing sequence.

Anyways, more thoughts / suggestions would be most welcome.  Thanks
again for the advice so far.

- Brendon.




>>>>>>>>>>> Script start <<<<<<<<<<<<<<<<<<<<<
#!/usr/local/bin/perl -w

=pod

=head1 NAME

tape_labels - Generate barcode labels for backup tapes.

=head1 SYNOPSIS

  $ tape_labels -?	# show usage

=head1 DESCRIPTION

This script generates barcodes for backup tapes.  The output produced is
standard postscript.  The following options must be given:

=item -s start

Specifies the starting number for the labels printed.

=item -e end

Specifies the end (last) number for the labels printed.

=back

=head1 SEE ALSO

perl(1)

=cut

## =============================================================================
## Requirements and Packages
## -------------------------

use strict;

## standard modules
use Getopt::Long qw(:config no_ignore_case bundling);
use IO::Pipe;

use constant LABEL_FMT => { def => "%06dL4",
			    efs => "EFS%03dL4",
			    raw => "RAW%03dL4",
			  };

## =============================================================================
## Global variables
## ----------------
our $Script_name = "tape_labels.pl";
our $Verbosity   = 0;

## =============================================================================
## Local Support Functions
## -----------------------
sub _barcode_handle
{
	my $barcode = "/home/brendon/barcodes/barcode-0.98/barcode";

## 1 millimeter = 2.857 142 857 1 point [Britain, US]

## 10 point [Britain, US] = 3.5 millimeter

# Label = 51mm x 15mm => use 50mm x 14mm to allow 1mm fit?
#                          = 142.85714pt x 40pt

	my $fh = new IO::Pipe;

# Old (original) version with -g option (doesn't work)
#	$fh->writer("$barcode -e code39 -c -u 'mm' -p 210x297 -t
3x15+0+0-0-7 -g 45x12+17+10 -m 3,2") or

# Alessandro's original suggestion:
# 	$fh->writer("$barcode -e code39 -c -u 'mm' -p 210x297 -t
3x15+0+13.5 -m 7,1.5") or

# My testing ...
	$fh->writer("$barcode -e code39 -c -u 'mm' -p 210x297 -t 3x15+10+13.5
-m 7,1.5") or
		error("popen 'barcode' failed: $!", 1);

	return $fh;
}

sub _get_label_format
{
	my $type = shift;

	my $fmt  = ($type and exists LABEL_FMT->{$type})
		   ? LABEL_FMT->{$type}
		   : undef;

	$fmt or _usage("Invalid type '$type' - must be [def|raw|efs]");

	return $fmt;
}

sub print_range
{
	my $args = shift;
	my $pfx  = $args->{prefix};
	my $fr   = $args->{start};
	my $to   = $args->{end};
	my $num  = $args->{numLabels};
	my $type = $args->{type};

	$num or _usage("Don't know how many labels to print - no '-n num'
option found!");

	my $fh   = _barcode_handle();

	my $fmt  = ( $pfx and $pfx =~ m|%| )
		   ? $pfx
		   : _get_label_format($type);

	for ( my $i = 0; $i < $num; $i++ ) {
		print $fh sprintf("$fmt\n", $fr++);
	}

	$fh->close();
}

sub _singles
{
	my $labels = shift;

	my @labels = map { split(',', $_) } @$labels;

	my $fh = _barcode_handle();

	map { print $fh $_, "\n"; } @labels;

	$fh->close();
}

## -----------------------------------------------------------------------------
## Print usage and exit
## --------------------
sub _usage
{
	my $err_msg = shift;
	print STDERR "$err_msg\n" if (defined $err_msg);
	print STDERR "Usage: $Script_name [-?] [-v level] [-o output]\n";
	print STDERR " -? : display help message\n";
	print STDERR " [-v verbosity]      : verbosity level (1-5)\n";
	print STDERR " [-t def|raw|efs]    : type of label to print.\n";
	print STDERR " [-p prefix]         : tape label prefix.  This can be
a comma-separated string\n";
	print STDERR "                       of prefixes (eg. -p AA,BB,CC).\n";
	print STDERR " [-s start number]   : first label number to print\n";
	print STDERR " [-e end number]     : last label number to print\n";
	print STDERR " [-n no. of labels]  : no. of labels to print starting
from specified prefix and\n";
	print STDERR "                     : start number.\n";
	print STDERR " [-o output]         : output file ('-' for stdout)\n";
	print STDERR " [-S start prefix]   : start tape label prefix\n";
	print STDERR " [-E start prefix]   : end tape label prefix\n";
	print STDERR "                       All labels in the prefix range
specified by -S/-E\n";
	print STDERR "                       will be printed (eg. -S AA -E AG
would print AA, AB .. \n";
	print STDERR "                       AF, AG)\n";
	print STDERR " [-l label,label]    : print comma-separated list of
specific labels\n";
	print STDERR "                     : NB: this will override all other
behaviour!\n";
	print STDERR "\n";
	print STDERR " NB: Either use -p or -S/-E options. If used, -p is
given preference.\n\n";
	exit(1);
}

## -----------------------------------------------------------------------------
## Functions for simple logging
## ----------------------------
sub info
{
	my ($msg, $level) = @_;
	if (!defined($level) or ($Verbosity >= $level)) {
		chomp($msg);
		print STDOUT "I> $msg\n";
	}
}

sub warning
{
	my ($msg) = @_;
	chomp($msg);
	print STDOUT "W> $msg\n";
}

sub error
{
	my ($msg, $die) = @_;
	chomp($msg);
	print STDOUT "E> $msg\n";

	exit $die if $die;
}


## -----------------------------------------------------------------------------
## main
## ----

## -----------------------------------------------------------------------------
## Parse command line
## - e.g. getopts("oif:") o, i boolean params and f requires an argument
## -----------------------------------------------------------------------------

# GetOptions doesn't like '-?' as an option specifier....
map { s/^-\?$/--help/ } @ARGV;  # smurf ARGV before GetOpts sees it!

my ( $Prefix, $Start, $End, $NumLabels,
     $Start_pfx, $End_pfx, $Type, @Singles, $hlp );

Getopt::Long::GetOptions( 'p|prefix=s'     => \$Prefix,
			  's|start=s'      => \$Start,
			  'e|end=s'        => \$End,
			  'n|num_labels=i' => \$NumLabels,
			  'S|start_pfx=s'  => \$Start_pfx,
			  'E|end_pfx=s'    => \$End_pfx,
			  't|type=s'       => \$Type,
			  'l|single=s'     => \@Singles,
			  'v|verbosity=i'  => \$Verbosity,
			  'h|help'         => \$hlp );
_usage() if $hlp;

if ( @Singles ) {
	## Singles mode can be handled immediately & then bail:
	_singles(\@Singles);
	exit 0;
}

$Type or _usage("Missing required option: -t raw|efs");

if ( $Start_pfx and $End_pfx ) {
	( ! $Prefix ) or
		usage("Cannot use -p when -S and -E are used!");
}

( $Start_pfx and ! $End_pfx   ) and _usage("-S requires -E also!");
( $End_pfx   and ! $Start_pfx ) and _usage("-E requires -S also!");
( $NumLabels and $End         ) and _usage("Cannot use -n with -e!");

( $Start and ! $End and ! $NumLabels ) and
	_usage("-s 'start' also requires -n 'no_of_labels' or -e 'end'");

## =============================================================================
## Start script here
## -----------------
my $args = { type      => $Type,
	     start     => $Start,
	     end       => $End,
	     numLabels => $NumLabels };

my @pfx;

if ( $Prefix ) {
	@pfx = split(',', $Prefix);
}
elsif ( $Start_pfx and $End_pfx ) {
	@pfx = ( $Start_pfx .. $End_pfx );
}

if ( @pfx ) {
	map { $args->{prefix} = $_ && print_range($args) } @pfx;
}
else {
	print_range($args);
}

## =============================================================================
## Exit ok
## -------

exit(0);

>>>>>>>>> End Script <<<<<<<<<<<<<<<<<


More information about the barcode mailing list