X-Git-Url: http://git.shiar.nl/sheet.git/blobdiff_plain/544153ced65dfca53ea9195c548db7bc0fa71d71..v1.3-0-g2034c72e12:/Shiar_Sheet/Keyboard.pm diff --git a/Shiar_Sheet/Keyboard.pm b/Shiar_Sheet/Keyboard.pm index cca8333..7607335 100644 --- a/Shiar_Sheet/Keyboard.pm +++ b/Shiar_Sheet/Keyboard.pm @@ -5,7 +5,7 @@ use warnings; no warnings 'uninitialized'; # save some useless checks for more legible code use Carp; -our $VERSION = 'v1.05'; +our $VERSION = 'v2.00'; my @casedesc = (undef, qw/shift ctrl meta/, 'shift meta'); my @rowdesc = qw(numeric top home bottom); @@ -22,18 +22,22 @@ my %keytrans = qw( ); sub new { - my $self = shift; - my ($keys) = @_; + my $class = shift; + my ($self) = @_; + + croak 'Invalid keyboard definitions specified' unless ref $self eq 'HASH'; + croak 'No key definitions specified' unless ref $self->{def} eq 'HASH'; + $self->{map} ||= 'qwerty'; - croak 'Invalid key table specified' unless ref $keys eq 'HASH'; my $parent = (caller)[0]; # calling module my $sign = do { no strict 'refs'; # temporarily allow variable references \%{ $parent.'::sign' }; # return %sign from parent }; croak "%${parent}::sign not found" unless %$sign; + $self->{sign} = $sign; - bless {sign => $sign, keys => $keys, map => 'qwerty'}, $self; + bless $self, $class; } sub map { @@ -68,25 +72,34 @@ sub keyunalias { $key =~ s/(\S*?)(\+?\^?\S)($|\s.*)/$2/; my $mode = $1; - my $keyinfo = $self->{keys}->{$mode}->{$key}; + my $keyinfo = $self->{def}->{$mode}->{$key}; - return [] unless defined $keyinfo; - return $keyinfo if ref $keyinfo; - return if $ancestry->{$key}++; # endless loop failsafe + return unless defined $keyinfo; + return $keyinfo->[0] if ref $keyinfo; + return '' if $ancestry->{$key}++; # endless loop failsafe return $self->keyunalias($keyinfo, $ancestry); } sub print_key { my $self = shift; - my ($mode, $key, $keyinfo) = @_; - - $keyinfo = [ $self->{sign}->{alias}.$keyinfo, $self->keyunalias($keyinfo)->[1] . ' alias' ] - if defined $keyinfo and not ref $keyinfo; # alias - my ($desc, $flags, $mnem) = @$keyinfo if defined $keyinfo; - defined $desc or $flags = $key eq '^0' ? 'ni' : 'no'; + my ($mode, $key, $flags) = @_; + + my $txt = $self->{key}->{$mode.$key}; + my ($desc, $mnem) = defined $txt ? @$txt : (); + + if (not defined $flags) { + $flags = $key eq '^0' ? 'ni' : 'no'; + } + elsif (not ref $flags) { # alias + $desc = $self->{sign}->{alias} . $flags; + $flags = $self->keyunalias($flags) . ' alias'; + } + else { + $flags = $flags->[0]; + } # $key = $keytrans{$key} if defined $keytrans{$key}; - my $keytxt = $mode . escapehtml($key) if $key ne '^0'; + my $keytxt = $self->{def}{$mode}{lead} . escapehtml($key) if $key ne '^0'; $keytxt .= $self->{sign}->{$1} while $flags =~ s/(?:^| )(arg[a-ln-z]?)\b//; # arguments $keytxt .= "$self->{sign}->{motion}" if $flags =~ s/ ?\bargm\b//; # motion argument $keytxt =~ s{\^(?=.)}{^}; # element around ctrl-identifier @@ -95,7 +108,7 @@ sub print_key { $keytxt = "$keytxt"; $keytxt .= ' '.$desc if defined $desc; $keytxt = qq{$keytxt} if $flags =~ s/ ?\blink(\S*)//; - my $onclick = $flags =~ s/ ?\bmode(\S*)// && defined $self->{keys}{$1} && sprintf( + my $onclick = $flags =~ s/ ?\bmode(\S*)// && defined $self->{def}{$1} && sprintf( ' onclick="setmode(%s)"', $1 eq '' ? '' : sprintf(q{'mode%s'}, escapeclass($1)) ); @@ -112,7 +125,7 @@ sub print_rows { # plus specific mode overrides prefixed by '=' ); my $defrows = shift || [2, 1, 0]; - my @modes = sort keys %{ $self->{keys} }; + my @modes = sort keys %{ $self->{def} }; for (my $row = 0; $row <= $#{ $keyrows{$self->{map}} }; $row++) { my $keyrow = $keyrows{$self->{map}}->[$row]; @@ -127,7 +140,7 @@ sub print_rows { my @caserows = $mode =~ s/(\d+)(?:-(\d+))?$// ? (map {$_ - 1} split //, $row == 0 && $2 || $1) # user override : @$defrows; # default - my $modekeys = $self->{keys}{$mode}; + my $modekeys = $self->{def}{$mode}; for my $case (@caserows) { my $keycase = $keyrow->[$case] or next; @@ -137,14 +150,14 @@ sub print_rows { ' class="%s"', 'mode mode' . escapeclass($basemode) ); printf("

%s: %s

\n", # XXX insert   here to fix msie<=6 - $modekeys->{desc} || "mode $basemode", + $self->{mode}->{$mode} || "mode $basemode", "$rowdesc[$row] row $casedesc[$case]" ); my $caseclass = 'keys'; $caseclass .= ' lead' if defined $modekeys->{lead}; # leading command key shown $caseclass .= " $casedesc[$case]" if defined $casedesc[$case]; print qq{\t\t\n}; } # case @@ -166,10 +179,17 @@ Shiar_Sheet::Keyboard - Output HTML for key sheets our %sign = (alias => 'see: '); my $keys = Shiar_Sheet::Keyboard({ - 'mode' => { - desc => 'mode description', - 'A' => 'a', # alias - 'a' => ['description', 'classes', 'comments (on hover)'], + def => { + 'lead' => { + 'A' => 'a', # alias + 'a' => ['classes'], + }, + }, + key => { + 'leada' => ['description', 'comments (on hover)'], + }, + mode => { + 'lead' => 'mode description', }, }); $keys->map('dvorak') or die "Keyboard map not found";