Edit: it's been done in Ruby.
Edit 2: a serendipitous link to the same in Python. Freaky.
invoiceThis is still pretty crude, but effectively we can scan the template to see whether all the information is available that we need for a full invoice. Some sort of interactive process will allow me to fill in what's missing, and some other specification not shown here will allow the invoice to be stored. That part's probably some sort of workflow environment. Once defined, the invoice can be expressed using a template to produce PDF or a Word file, and attached to an email. These actions are certainly workflow.
customer {{index customer}}
data items (description, price, unit, subtotal)
{{.assert count(items) > 0}}
total "{{select sum(price) from items}}"
currency "{{index currency default USD}}"
{{.section comments}}
comments
{{@}}
{{.end}}
use Class::Declarative qw(PDF::Declarative);
pdf (displaytitle, encoding=latin1) "mynewpdf.pdf"
author "Michael Roberts"
title "PDF::Declarative Example 1"
subject "Building PDFs with explicitly placed elements"
keywords "Declarative PDF generation"
mediabox "105mm x 148mm"
#bleedbox "5mm, 5mm, 100mm, 143 mm"
cropbox "7.5mm 7.5mm 97.5 mm 140.5mm"
#artbox "10mm, 10mm, 95mm, 138mm"
page
graphic blue_box
fill (darkblue)
rect "5mm, 125mm, 95mm, 18mm"
graphic red_line
stroke (red)
move "5mm, 125mm"
line "100mm, 125mm"
text heading (flow=no, x=95mm, y=131mm, align=right, color=white, font=helvetica, bold, fontsize=18pt)
Using PDF::Declarative
graphic background
stroke (lightgrey)
circle "20mm, 45mm, 45mm"
circle "18mm, 48mm, 43mm"
circle "19mm, 40mm, 46mm"
box left_column (border) "10mm, 121mm, 41mm, 111mm"
text (lead=7pt, parspace=0, align=justify, color=black, font=times, fontsize=6)
Perci ent ulluptat vel eum zzriure feuguero core consenis adignim...
text (align=center, font=helvetica, bold, fontsize=6pt, color=blue)
Enim eugiamc ommodolor sendre feum zzrit at. Ut prat. Ut lum quisi.
text (align=right, font=times, color=black, fontsize=6pt)
It augait ate magniametum irit, venim doloreet augiamet...
graphic
image "54mm, 66mm, 41mm, 55mm"
jpeg "Portrait.jpg"
box right_column (border, dash=2 2 1 2, color=blue) "54mm, 64mm, 41mm, 54mm"
text (lead=7pt, parspace=0pt, align=justify, indent=5pt, fontsize=6pt, bullet=B7)
Orpero do odipit ercilis ad er augait ing ex elit autatio....
#!/usr/bin/perl
#############################################################################
## Name: samples/dialog/dialog.pl
## Purpose: Dialog wxPerl sample
## Author: Mattia Barbon
## Modified by:
## Created: 12/11/2000
## RCS-ID: $Id: dialog.pl,v 1.4 2004/10/19 20:28:13 mbarbon Exp $
## Copyright: (c) 2000 Mattia Barbon
## Licence: This program is free software; you can redistribute it and/or
## modify it under the same terms as Perl itself
#############################################################################
use Wx;
package MyApp;
use strict;
use vars qw(@ISA);
@ISA=qw(Wx::App);
use Wx qw(wxDefaultSize wxDefaultPosition);
sub OnInit {
my( $this ) = @_;
my( $dialog ) = MyDialog->new( "wxPerl dialog sample",
wxDefaultPosition,
);
$this->SetTopWindow( $dialog );
$dialog->Show( 1 );
1;
}
package MyDialog;
use strict;
use vars qw(@ISA);
@ISA=qw(Wx::Dialog);
use Wx::Event qw(EVT_CLOSE EVT_BUTTON);
use Wx qw(wxDefaultSize wxDefaultValidator);
sub new {
my( $class ) = shift;
my( $this ) = $class->SUPER::new( undef, -1, $_[0], $_[1], [250, 110] );
# $this->SetIcon( Wx::GetWxPerlIcon() );
my( $ct ) = $this->{CELSIUS} =
Wx::TextCtrl->new( $this, -1, '0', [20, 20], [100, -1] );
my( $cb ) = Wx::Button->new( $this, -1, 'Celsius', [130, 20] );
my( $ft ) = $this->{FAHRENHEIT} =
Wx::TextCtrl->new( $this, -1, '32', [20, 50], [100, -1] );
my( $fb ) = Wx::Button->new( $this, -1, 'Fahrenheit', [130, 50] );
EVT_BUTTON( $this, $cb, \&CelsiusToFahrenheit );
EVT_BUTTON( $this, $fb, \&FahrenheitToCelsius );
EVT_CLOSE( $this, \&OnClose );
$this;
}
sub CelsiusToFahrenheit {
my( $this, $event ) = @_;
$this->{FAHRENHEIT}->SetValue( ( $this->{CELSIUS}->GetValue() /
100.0 ) * 180 + 32 );
}
sub FahrenheitToCelsius {
my( $this, $event ) = @_;
$this->{CELSIUS}->SetValue( ( ( $this->{FAHRENHEIT}->GetValue()-32 ) /
180.0 ) * 100 );
}
sub OnClose {
my( $this, $event ) = @_;
$this->Destroy();
}
package main;
my( $app ) = MyApp->new();
$app->MainLoop();
# Local variables: #
# mode: cperl #
# End: #
use Class::Declarative qw(Wx::Declarative);
dialog (xsize=250, ysize=110) "Wx::Declarative dialog sample"
field celsius (size=100, x=20, y=20) "0"
button celsius (x=130, y=20) "Celsius" { $^fahrenheit = ($^celsius / 100.0) * 180 + 32; }
field fahrenheit (size=100, x=20, y=50) "32"
button fahrenheit (x=130, y=50) "Fahrenheit" { $^celsius = (($^fahrenheit - 32) / 180.0) * 100; }
use Wx::DefinedUI qw(-filter);That's it. Granted, that code doesn't do anything, it just demonstrates the use of box sizers, but there are two points I want to make about it.
dialog (resize) "Wx::BoxSizer"
size (box, v):
size (box, h) [1, GROW]:
button (id=OK) [0, ALL, 10] "Close window"
button [0, 0] "Button 2"
button [0, TOP BOTTOM, 5] "Button 3"
space [10, 10, 0, GROW]
size (box, h) [1, GROW]:
button [1, ALL, 5] "Button 1"
space [1, 30, 1, 0, 0]
button [1, GROW ALL, 5] "Button 2"
size (static, v) [2, GROW] "Wx::StaticBoxSizer":
button [1, GROW ALL, 5] "Button 3"
button [1, GROW ALL, 5] "Button 4"