#!/usr/bin/perl use strict; use Encode; use PDF::API2::Lite; use Getopt::Long; Getopt::Long::Configure ("bundling"); my $PaperSize = '8.5x11'; my $CardLayout = '3x8'; my $Margins = 0.5; my $LineLength = 8; my $VerticalWriting = 0; my $Landscape = 0; my $OutFile = "flashcards.pdf"; my $FontFile = 'KozMinPro-Regular.otf'; GetOptions("paper|p=s" => \$PaperSize, "cardlayout|c=s" => \$CardLayout, "margins|m=f" => \$Margins, "linelength|L=i" => \$LineLength, "vertical|v" => \$VerticalWriting, "output|o=s" => \$OutFile, "landscape|l" => \$Landscape, "font|f=s" => \$FontFile) or die <new; my $font = $pdf->ttfont($FontFile); my ($pw,$ph) = papersize($PaperSize); my $count = 0; my $position; while (<>) { chomp; $_ = decode("utf8",$_); $position = $count % ($cols * $rows); if ($position == 0) { $pdf->page($pw,$ph); $pdf->move($Margins,$ph - $Margins); $pdf->line($pw - $Margins,$ph - $Margins); $pdf->line($pw - $Margins,$Margins); $pdf->line($Margins,$Margins); $pdf->close; $pdf->stroke; $pdf->transform(-translate => [$pw,0], -rotate => 90) if $Landscape; } my ($x,$y) = ($cards[$position]->{x},$cards[$position]->{y}); $pdf->move($x,$y+$ch); $pdf->line($x,$y); $pdf->line($x+$cw,$y); $pdf->stroke; if ($VerticalWriting) { VerticalPrint($font,$fontsize,$x+$fx,$y+$fy,$_); } else { $pdf->print($font,$fontsize,$x+$fx,$y+$fy,0,1,$_); } $count++; } while ($position < $cols * $rows) { my ($x,$y) = ($cards[$position]->{x},$cards[$position]->{y}); $pdf->move($x,$y+$ch); $pdf->line($x,$y); $pdf->line($x+$cw,$y); $pdf->stroke; $position++; } $pdf->saveas($OutFile); exit 0; sub VerticalPrint { my($font,$fontsize,$x,$y,$text) = @_; $pdf->savestate; $pdf->transform(-translate => [$x,$y], -rotate => 90); my @char = split(/ */,$text); $y = (@char - 2) / 2 * $fontsize; foreach my $char (split(//,$text)) { $pdf->print($font,$fontsize,0,$y,0,1,$char); $y -= $fontsize; } $pdf->restorestate; } sub MakeLayout { my ($PaperSize,$Margins,$CardLayout,$Landscape) = @_; my ($cols,$rows) = $CardLayout =~ /^(\d+)x(\d+)$/; die "usage: $0 --cardlayout INTxINT\n" unless $cols * $rows > 0; my ($pw,$ph) = papersize($PaperSize,$Landscape); my ($px1,$py1) = ($Margins,$Margins); my ($px2,$py2) = ($pw - $Margins, $ph - $Margins); my @c; my $cw = ($px2 - $px1) / $cols; my $ch = ($py2 - $py1) / $rows; foreach my $col (1..$cols) { foreach my $row (1..$rows) { my $tmp = {}; $tmp->{x} = $px1 + $cw * ($col - 1); $tmp->{y} = $py1 + $ch * ($row - 1); push(@c,$tmp); } } return ($cols,$rows,$cw,$ch,reverse @c); } sub CalcTextLayout { my($width,$height,$LineLength,$isvertical) = @_; my $margin = 4; my $size1 = (($width - 2 * $margin) / $LineLength); my $size2 = ($height - 2 * $margin) / 2; my $size = $size1 < $size2 ? $size1 : $size2; if ($isvertical) { return ($size,$width/2,$height / 2); } else { return ($size,$width/2,$height / 2 - $size/2.75); } } #return the dimensions of a standard paper size #source: # http://partners.adobe.com/asn/developer/pdfs/tn/5003.PPD_Spec_v4.3.pdf # # sub papersize { my ($size,$islandscape) = @_; my %paper = ( a0 => {x => 2384, y => 3370}, a1 => {x => 1684, y => 2384}, a2 => {x => 1191, y => 1684}, a3 => {x => 842, y => 1191}, a4 => {x => 595, y => 842}, a5 => {x => 420, y => 595}, a6 => {x => 297, y => 420}, b0 => {x => 2920, y => 4127}, b1 => {x => 2064, y => 2920}, b2 => {x => 1460, y => 2064}, b3 => {x => 1032, y => 1460}, b4 => {x => 729, y => 1032}, b5 => {x => 516, y => 729}, b6 => {x => 363, y => 516}, '36x48' => {x => 2592, y => 3456}, '24x36' => {x => 1728, y => 2592}, '18x24' => {x => 1296, y => 1728}, '11x17' => {x => 792, y => 1224}, 'tabloid' => {x => 792, y => 1224}, '8.5x14' => {x => 612, y => 1008}, 'uslegal' => {x => 612, y => 1008}, '8.5x11' => {x => 612, y => 792}, 'usletter' => {x => 612, y => 792}, '4x6' => {x => 288, y => 432}, ); return undef unless defined $paper{$size}; if ($islandscape) { return ($paper{$size}->{y},$paper{$size}->{x}); }else{ return ($paper{$size}->{x},$paper{$size}->{y}); } }