mirror of
https://github.com/pasky/brmelect.git
synced 2025-06-07 09:33:59 +02:00
Initial version, with gen-ballot.pl
This commit is contained in:
commit
f068590866
3 changed files with 155 additions and 0 deletions
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
Example:
|
||||
|
||||
./gen-ballot.pl 15 <names-sample.txt
|
147
gen-ballot.pl
Executable file
147
gen-ballot.pl
Executable file
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/perl
|
||||
# (c) Petr Baudis 2011, 2014 MIT licence
|
||||
#
|
||||
# Generate PDF with ballots.
|
||||
# Expects number of ballots as argument and names on stdin.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
||||
# -- User configuration --
|
||||
|
||||
our @paper = (598, 842); # A4, 72dpi
|
||||
our @margin = (72, 72);
|
||||
our @ballot = (147, 36);
|
||||
our $filename = 'ballots.pdf';
|
||||
|
||||
our $fontface = 'Arial';
|
||||
our $ffontface = 'Courier New';
|
||||
# large, normal, small
|
||||
our @fontsize = (26, 11, 8);
|
||||
our @linespacing = (18, 13, 10);
|
||||
our $topmargin = 2;
|
||||
|
||||
our $contact = 'brmelect: your votes are safe with us';
|
||||
|
||||
# -- User configuration end --
|
||||
|
||||
|
||||
use lib 'perl';
|
||||
use List::Util qw(min);
|
||||
use List::MoreUtils qw(pairwise);
|
||||
use Cairo;
|
||||
|
||||
my $n_ballots = pop @ARGV;
|
||||
my @names;
|
||||
while (<>) {
|
||||
chomp;
|
||||
push @names, $_;
|
||||
}
|
||||
|
||||
$ballot[1] += @names * ($linespacing[1] + $fontsize[1] + 5);
|
||||
|
||||
our $surface = Cairo::PdfSurface->create ($filename, @paper);
|
||||
|
||||
# Effective surface area
|
||||
our @surfsize = pairwise { $a - $b * 2 } @paper, @margin;
|
||||
# Grid layout on effective surface
|
||||
our @grid = pairwise { int($a / $b) } @surfsize, @ballot;
|
||||
# Grid surface area
|
||||
|
||||
our @gridsurfsize = pairwise { $a * $b } @grid, @ballot;
|
||||
# Start of grid surface so that it is centered on the paper
|
||||
our @gridsurfstart = pairwise { ($a - $b) / 2 } @paper, @gridsurfsize;
|
||||
|
||||
sub gen_token {
|
||||
my $token = '';
|
||||
my @chars = ('a'..'z', '0'..'9');
|
||||
for (1..5) {
|
||||
$token .= $chars[rand @chars];
|
||||
}
|
||||
return($token);
|
||||
}
|
||||
|
||||
# Produce a context for single ballot, starting at coordinates [0,0]
|
||||
sub ballot_cr {
|
||||
my ($surface, $cell) = @_;
|
||||
my @startM = pairwise { $a * $b } @ballot, @$cell;
|
||||
my @start = pairwise { $a + $b } @gridsurfstart, @startM;
|
||||
|
||||
my $cr = Cairo::Context->create($surface);
|
||||
$cr->translate(@start);
|
||||
|
||||
$cr->set_source_rgb(0, 0, 0);
|
||||
$cr->set_line_width(1);
|
||||
$cr;
|
||||
}
|
||||
|
||||
# Centered text with top border at $$y. $size is index in font config above.
|
||||
sub ballot_text_centered {
|
||||
my ($cr, $y, $face, $slant, $weight, $size, $text) = @_;
|
||||
$$y += $linespacing[$size] / 2;
|
||||
|
||||
$cr->select_font_face($face, $slant, $weight);
|
||||
$cr->set_font_size($fontsize[$size]);
|
||||
my $textents = $cr->text_extents($text);
|
||||
my $fextents = $cr->font_extents();
|
||||
$$y += $fextents->{height};
|
||||
$cr->move_to(($ballot[0] - $textents->{width}) / 2, $$y);
|
||||
$cr->show_text($text);
|
||||
|
||||
$$y += $linespacing[$size] / 2;
|
||||
}
|
||||
|
||||
sub ballot_text_plus_box {
|
||||
my ($cr, $y, $face, $slant, $weight, $size, $text) = @_;
|
||||
$$y += $linespacing[$size] / 2;
|
||||
|
||||
$cr->select_font_face($face, $slant, $weight);
|
||||
$cr->set_font_size($fontsize[$size]);
|
||||
my $textents = $cr->text_extents($text);
|
||||
my $fextents = $cr->font_extents();
|
||||
$$y += $fextents->{height};
|
||||
$cr->move_to(45, $$y);
|
||||
$cr->show_text($text);
|
||||
|
||||
$cr->rectangle(15, $$y - $fontsize[$size], 20, $fontsize[$size] * 3 / 2);
|
||||
$cr->stroke;
|
||||
|
||||
$$y += $linespacing[$size] / 2;
|
||||
}
|
||||
|
||||
sub ballot {
|
||||
my ($cr, $names) = @_;
|
||||
|
||||
$cr->rectangle(0, 0, @ballot);
|
||||
$cr->stroke;
|
||||
|
||||
|
||||
my $ypos = $topmargin + $linespacing[0] / 2;
|
||||
# ballot_text($cr, \$ypos, $fontface, 'normal', 'bold', 0, $host);
|
||||
# ballot_text($cr, \$ypos, $ffontface, 'normal', 'normal', 1, $mac);
|
||||
for my $name (@$names) {
|
||||
ballot_text_plus_box($cr, \$ypos, $fontface, 'normal', 'normal', 1, $name);
|
||||
}
|
||||
my $tok = gen_token();
|
||||
print($tok."\n");
|
||||
ballot_text_centered($cr, \$ypos, $fontface, 'italic', 'normal', 2, $tok);
|
||||
ballot_text_centered($cr, \$ypos, $fontface, 'italic', 'normal', 2, $contact);
|
||||
}
|
||||
|
||||
|
||||
my ($x, $y) = (0, 0);
|
||||
|
||||
for my $n (1..$n_ballots) {
|
||||
ballot(ballot_cr($surface, [$x, $y]), \@names);
|
||||
|
||||
$y++;
|
||||
if ($y >= $grid[1]) {
|
||||
$y = 0; $x++;
|
||||
if ($x >= $grid[0]) {
|
||||
my $cr = Cairo::Context->create($surface);
|
||||
$cr->show_page;
|
||||
($x, $y) = (0, 0);
|
||||
}
|
||||
}
|
||||
}
|
5
names-sample.txt
Normal file
5
names-sample.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
Tinky Winky
|
||||
Dipsy Simmit
|
||||
Laa-Laa Smedley
|
||||
Po Pui Fan Lee
|
||||
Noo-noo
|
Loading…
Add table
Add a link
Reference in a new issue