UI-KeyboardLayout

 view release on metacpan or  search on metacpan

examples/izKeys.kbdd  view on Meta::CPAN

/SLASH=			⁄÷∕ / ˈˌ / / /  ̸  ̷  ̶  ̵ / /  ⃒  ⃓ /  ̸  ̷  ⃒   ⃓ ̶   ̵
#
# These are from "main blocks" of the modifiers and combining; plus Greek standalone diacritics: ͺ΄΅
# One of Ë  is obscured by vertical line with middle dot...  The Macron-\ 29F7 obscures Ë­.
# Circled \ and | with middle dot obscure ˙ˠ.  ˙ duplicated (forward) to make accessible.  Also:  ̅
#  ̾ ̘  ̙  ͘  ͉  ͉  ᷽  combining chars are also duplicated.  Also:  ⃡  ⃗  ⃖ ⃯ ⃮  ⃬  ⃟ (for symbols).
# ʰʱʲˡˢʷ - from IPA.  The rest (and ʳʴʵʶʸ) are v1.1 letter modifiers.  (ˠ is in front to unobscure the rest.)
#
# Combining for symbols: arrows and round arrows -> ~; rectangular around: to ˘ .
#`´¨˜ˆˇ°¯	Harpoons are ordered as →, ←
# perl -C31 -wlne "next if /^#/; s(^/\w+=\s+)() or die; @t = split m((?<=.)/); print q(<tr><td>), join(q(</td><td>), @t), q(</td></tr>)" a1 > a1.html
[face_shortcuts]
l=Latin
c=CyrillicPhonetic
g=GreekPoly
h=Hebrew
b=US-Base

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

#    actually: parses configfile string, not file
sub parse_configfile ($$) {		# Trailing whitespace is ignored, whitespace about "=" is not
  my ($self, $s) = (shift, shift);
  $self->parse_add_configstring($s, {});
}

sub parse_add_configstring ($$$) {		# Trailing whitespace is ignored, whitespace about "=" is not
  my ($self, $s, $vv, @KEYS) = (shift, shift, shift);
  $s =~ s/[^\S\n]+$//gm;
  $s =~ s/^\x{FEFF}//;			# BOM are not stripped by Perl from UTF-8 files with -C31
  (my $pre, my %f) =  split m(^\[((?:visual\s*->\s*)?[\w/]*)\]\s*$ \n?)mx, $s;	# //x is needed to avoid $\
  warn "Part before the first section in configfile ignored: `$pre'" if length $pre;
  for my $k (sort keys %f) {
# warn "Section `$k'";
    my($v, $V, @V) = $f{$k};
    if ($k =~ s{^visual\s*->\s*}{[unparsed]/}) {		# Make sure that prefixes do not allow visual line to be confused with a config
      $v =~ s[(^(?!#|[/\@+]?\w+=).*)]//ms;			# find non-comment non-assignment
      @V = "unparsed_data=$1";
    }
# warn "xxx: @V";
    push @KEYS, $k;
    my @k = split m(/), $k;
    @k = () if "@k" eq '';				# root
    for my $l ((grep !/^#/, split(/\n/, $v)), @V) {
      die "unrecognized config file line: `$l' in `$s'"
        unless my($arr, $at, $slash, $kk, $vvv) = ($l =~ m[^((?:(\@)|(/)|\+)?)(\w+)=(.*)]s);
      my $spl = $at ? qr/,/ : ( $slash ? qr[/] : qr[(?!)] );
      $vvv = [ length $vvv ? (split $spl, $vvv, -1) : $vvv ] if $arr;	# create empty element if $vvv is empty
      my $slot = $self->get_deep($vv, @k);
      if ($slot and exists $slot->{$kk}) {
        if ($arr) {
          if (ref($slot->{$kk} || 0) eq 'ARRAY') {

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

  $name = "VisLr=$name" if $name;
#  warn "Multi-char key in <<@k>>" if grep $_ && 1<length, @k;
  warn "More that 2 Shift-states in <<@k>>" if @k > 2;
#warn "Sep2 in $name, $skip_first, <$k> ==> <@k>\n" if defined $sep2 and $k =~ /$sep2/;
  map {defined() ? [$_, undef, undef, $name] : $_} @k;
#  @k
}	# -> list of chars

sub process_key ($$$$$$;$) {		# $sep may appear only in a beginning of the first key chunk
  my ($self, $k, $limit, $sep, $ln, $l_off, $sep2, @tr)  = (shift, shift, shift, shift, shift, shift, shift);
  my @k = split m((?!^)\Q$sep), $k;
  die "Key descriptor `$k' separated by `$sep' has too many parts: expected $limit, got ", scalar @k
    if @k > $limit;
  defined $k[$_] and $k[$_] =~ s/^--(?=.)/\0/ and $tr[$_]++ for 0..$#k;
  $k[0] = '' if $k[0] eq '--';		# Allow a filler (multi)-chunk
  map [$self->process_key_chunk( $ln->[$l_off+$_], $tr[$_], (defined($k[$_]) ? $k[$_] : ''), $sep2)], 0..$#k;
}	# -> list of arrays of chars

sub decode_kbd_layers ($@) {
  my ($self, $lineN, $row, $line_in_row, $cur_layer, @out, $N, $l0) = (shift, 0, -1);
  my %needed = qw(unparsed_data x visual_rowcount 2 visual_per_row_counts [2;2] visual_prefixes * prefix_repeat 3 in_key_separator / layer_names ???);

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

    return $v->[$idx];
  }
  return;
}

sub fill_kbd_layers ($$) {			# We do not do deep processing here...
  my($self, $h, %o, %c, %O) = (shift, shift);
  my @K = grep m(^\[unparsed]/(KBD|RECT)\b), @{$h->{'[keys]'}};
#  my $H = $h->{'[unparsed]'};
  for my $k (@K) {
    my (@parts, @h) = split m(/), $k;
    ref $self and push @h, $self->get_deep($self, @parts[1..$_]) || {} for 0..$#parts;
    push @h, $self->get_deep($h, @parts[1..$_]) || {} for 0..$#parts;		# Drop [unparsed]/ prefix...
    push @h, $self->get_deep($h,    @parts[0..$_]) || {} for -1..$#parts;
    my ($in, $counts, $offsets) = ($k =~ m(^\[unparsed]/KBD\b) ? $self->decode_kbd_layers( reverse @h )
    							       : $self->decode_rect_layers( reverse @h ) );
    exists $o{$_} and die "Visual spec `$k' overwrites exiting layer `$k'" for keys %$in;
    my $cnt = (@o{keys %$in} = values %$in);
    @c{keys %$in} = ($counts)  x $cnt;
    @O{keys %$in} = ($offsets) x $cnt if $offsets;
  }

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

  for my $f ($self->order_faces_4_massage) {		# Needed for (pre_)link_layers...
    next if 'HASH' ne ref $self->{faces}{$f} or $f =~ m(\bVK$);			# "parent" taking keys for a child
#warn "Massaging face `$f'...";
    for my $key ( qw( Flip_AltGr_Key Diacritic_if_undef DeadChar_DefaultTranslation DeadChar_32bitTranslation extra_report_DeadChar
    		      PrefixChains ctrl_after_modcol create_alpha_ctrl keep_missing_ctrl output_layers
		      output_layers_WIN output_layers_XKB skip_extra_layers_WIN Prefix_Base_Altern Prefix_Force_Altern
    		      layers_modifiers layers_mods_keys mods_keys_KBD AltGrInv_AltGr_as_Ctrl
		      ComposeKey_Show AltGr_Invert_Show Apple_Override Apple_Duplicate Apple_HexInput 
    		      ComposeKey Explicit_AltGr_Invert Auto_Diacritic_Start CapsLOCKoverride
    		      WindowsEmitDeadkeyDescrREX ExtraChars modkeys_vk) ) {
      $self->{faces}{$f}{"[$key]"} = $self->get_deep_via_parents($self, undef, 'faces', (split m(/), $f), $key);
    }
    $self->{faces}{$f}{'[char2key_prefer_first]'}{$_}++ 		# Make a hash
      for @{ $self->{faces}{$f}{char2key_prefer_first} || [] } ;
    $self->{faces}{$f}{'[char2key_prefer_last]'}{$_}++ 			# Make a hash
      for @{ $self->{faces}{$f}{char2key_prefer_last} || [] } ;
    $self->{faces}{$f}{'[AltGrInv_AltGr_as_Ctrl]'} = 1 unless defined $self->{faces}{$f}{'[AltGrInv_AltGr_as_Ctrl]'};

    my $idx = $self->get_deep($self, 'faces', (split m(/), $f), 'MetaData_Index');
    # defined $self->{faces}{$f}{"[$_]"} and not ref $self->{faces}{$f}{"[$_]"}
    #  or
    $self->{faces}{$f}{"[$_]"} = $self->get_deep_via_parents($self, $idx, 'faces', (split m(/), $f), $_)
        for qw(LRM_RLM ALTGR SHIFTLOCK NOALTGR);

    my %R = qw(ComposeKey_Show ⎄    AltGr_Invert_Show ⤨);		# On Apple only
    defined $self->{faces}{$f}{"[$_]"} or $self->{faces}{$f}{"[$_]"} = $R{$_} for keys %R;
    $self->{faces}{$f}{"[ComposeKey_Show]"}[0] = '⎄'			# Make a safe default
      if ref $self->{faces}{$f}{"[ComposeKey_Show]"} and not length $self->{faces}{$f}{"[ComposeKey_Show]"}[0];

    my ($compK, %compK) = $self->{faces}{$f}{'[ComposeKey]'};
    if ($compK and ref $compK) {
      for my $cK (@$compK) {

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

      push @{ $self->{faces}{$f}{'[AltSubstitutions]'}{lc $s[0]} }, [lc $s[1], 'manual']
        if lc $s[0] ne $s[0] and lc $s[1] ne $s[1];
      push @{ $self->{faces}{$f}{'[AltSubstitutions]'}{uc $s[0]} }, [uc $s[1], 'manual']
        if uc $s[0] ne $s[0] and uc $s[1] ne $s[1];
    }
    s/^\s+//, s/\s+$//, $_ = $self->stringHEX2string($_) for @{ $self->{faces}{$f}{Import_Prefix_Keys} || []};
    my %h = @{ $self->{faces}{$f}{Import_Prefix_Keys} || []};
    $self->{faces}{$f}{'[imported2key]'} = \%h if %h;
    my ($l0, $c);
    unless ($c = $self->{layer_counts}{$l0 = $self->{faces}{$f}{layers}[0]}) {
      $l0 = $self->get_deep_via_parents($self, undef, 'faces', (split m(/), $f), 'geometry_via_layer');
      $c = $self->{layer_counts}{$l0} if defined $l0;
    }
    my $o = $self->{layer_offsets}{$l0} if defined $l0;
    $self->{faces}{$f}{'[geometry]'} = $c if $c;
    $self->{faces}{$f}{'[g_offsets]'} = $o if $o;
  }
#  $self->__dbg_latin_CtrlD;
  for my $f ($self->order_faces_4_massage) {	# Needed for face_make_backlinks: must know which keys in faces will be finally present
    next if 'HASH' ne ref $self->{faces}{$f} or $f =~ m(\bVK$);			# "parent" taking keys for a child
    for my $F (@{ $self->{faces}{$f}{AlternCharSubstitutionFaces} || []}) {	# Now has a chance to have real layers

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

      #$self->{faces}{"$f###" . $self->key2hex($k[0])}{'[DEAD]'}{$k[1]}++;
    }
  }
#  $self->__dbg_latin_CtrlD;
  $self
}

sub massage_hash_values($) {
  my($self) = (shift);
  for my $K ( @{$self->{'[keys]'}} ) {
    my $h = $self->get_deep($self, split m(/), $K);
    $_ = $self->charhex2key($_) for @{ $h->{char2key_prefer_first} || []}, @{ $h->{char2key_prefer_last} || []};
  }

}
#use Dumpvalue;

sub print_codepoint ($$;$$) {	# $postfix may be a name of base-font.  Then the coverage_how is used instead of $postfix
  my ($self, $k, $prefix, $postfix) = (shift, shift, shift, shift);
  my $K = ($k =~ /$rxCombining/ ? " $k" : $k);
  if (defined $postfix) {

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

    }
    $self
}

sub massage_deadkeys_win ($$) {
  my($self, $h, @process, @to) = (shift, shift);
  my @K = grep m(^\[unparsed]/DEADKEYS\b), @{$h->{'[keys]'}};
# warn "Found deadkey sections `@K'";
#  my $H = $h->{'[unparsed]'};
  for my $k (@K) {
    push @process, $self->get_deep($h, (split m(/), $k), 'unparsed_data');
    (my $k1 = $k) =~ s(^\[unparsed]/)();
    push @to, $k1
  }
  @K = grep m(^DEADKEYS\b), @{$h->{'[keys]'}};
  for my $k (@K) {
    my $slot = $self->get_deep($h, split m(/), $k);
    next unless exists $slot->{klc_filename};
    open my $fh, '< :encoding(UTF-16)', $slot->{klc_filename}
      or die "open of <klc_filename>=`$slot->{klc_filename}' failed: $!";
    local $/;
    my $in = <$fh>;
    push @process, $in;
    push @to, $k;
  }
  for my $k1 (@to) {
#warn "DK sec `$k' -> `$v', <", join('> <', keys %{$h->{'[unparsed]'}{DEADKEYS}{la_ru}}), ">";
#warn "DK sec `$k' -> `$v', <$h->{'[unparsed]'}{DEADKEYS}{la_ru}{unparsed_data}>";
    my $v = shift @process; 
    my($o,$d,$t) = $self->read_deadkeys_win($v);	# Translation tables, names, rest of input
    my (@parts, @h) = split m(/), $k1;
    my %seen = (%$o, %$d);
    for my $kk (keys %seen) {
#warn "DK sec `$k1', deadkey `$kk'. Map: ", $self->array2string( [%{$o->{$kk} || {}}] );
      my $slot = $self->get_deep($h, @parts, $kk);
      warn "Deadkey `$kk' defined for `$k1' conflicts with previous definition" 
        if $slot and grep exists $slot->{$_}, qw(map name);
      $self->put_deep($h, $o->{$kk}, @parts, $kk, 'map')  if exists $o->{$kk};
      $self->put_deep($h, $d->{$kk}, @parts, $kk, 'name') if exists $d->{$kk};
    }
  }

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

		     MULTIPLY	=> [["*", "*"]],
		     DIVIDE	=> [["/", "/"]],
		     RETURN	=> [["\r", "\r"], ["\n"]],
		     BACK	=> [["\b", "\b"], ["\x7f"]],
		     ESCAPE	=> [["\e", "\e"], ["\e"]],
		     CANCEL	=> [["\cC", "\cC"], ["\cC"]],
		   );

sub get_VK ($$) {
  my ($self, $f) = (shift, shift);
  $self->get_deep_via_parents($self, undef, 'faces', (split m(/), $f), 'VK') || {}
#  $self->{faces}{$f}{VK} || {}
}

my $min_sec;
sub last_pre_funckeys($$) {
  my ($self, $l0) = (shift, shift);
  unless (defined $min_sec) {
    $min_sec = 1e300;
    $min_sec > $_->[0] and $min_sec = $_->[0] for values %start_SEC;
  }

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

	     uc =>  sub ($) {defined (my $c = shift) or return undef; $c = $c->[0] if 'ARRAY' eq ref $c;
				    my $c1 = uc $c;		return undef if $c1 eq $c; $c1} );
sub make_translator ($$$$$) {		# translator may take some values from "environment" 
  # (such as which deadkey is processed), so caching is tricky: if does -> $used_deadkey reflects this
  # The translator should return exactly one value (possibly undef) so that map TRANSLATOR, list works intuitively.
	# Exception: translator with all_layers: takes a ref to a key (array of arrays of chars); returns array of arrays.
	# There is a possibility to redirect the translation to another key; see $cvt (usually combined with 'all_layers').
  my ($self, $name, $deadkey, $face, $N, $used_deadkey) = (shift, shift, shift || 0, shift, shift, '');	# $deadkey used eg for diagnostics
  die "Undefined recipe in a translator for face `$face', layer $N on deadkey `$deadkey'" unless defined $name;
  if ($name =~ /^Imported\[([\/\w]+)(?:,([\da-fA-F]{4,}))?\]$/) {
    my($d, @sec) = (($2 ? "$2" : undef), split m(/), "$1");
    $d = $deadkey, $used_deadkey ="/$deadkey" unless defined $d;
    my $fromKBDD = $self->get_deep($self, 'DEADKEYS', @sec, lc $d, 'map')	# DEADKEYS/bepo with 00A4 ---> DEADKEYS/bepo/00a4
      or die "DEADKEYS section for `$d' with parts `@sec' not found";
	# indexed by lc hex
    return sub { my $cc=my $c=shift; return $c unless defined $c; $c = $c->[0] if 'ARRAY' eq ref $c; defined($c = $fromKBDD->{$self->key2hex($c)}) or return $c; $self->document_char(chr hex $c, $name, $cc) }, '';
  }
  die "unrecognized Imported argument: `$1'" if $name =~ /^Imported(\[.*)/s;
  return $translators{$name}, '' if $translators{$name};
  if ($name =~ /^PrefixDocs\[(.+)\]$/) {
    $self->{faces}{$face}{'[prefixDocs]'}{$deadkey} = $1;

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

# warn "geometry: [@$g] [@$o]";
    for my $r (@$g) {
      my $off = shift @$o;
      $c{$tot + $_} = $_ + $off for 0..($r-1);
      $tot += $r;
    }
    return sub ($$$$) { (undef, my ($L, $k, $shift)) = @_; return undef if $L or $shift or $k >= $tot; $self->document_char($chars[$c{$k}], "ByColumn[$c{$k}]") }, '';
  }
  if ($name =~ /^ByRows\[(.+)\]$/) {
    s(^\s+(?!\s|///\s+))(), s((?<!\s)(?<!\s///)\s+$)() for my $recipes = $1;
    my (@recipes, @subs) = split m(\s+///\s+), $recipes;
    my $LL = $#{ $self->{faces}{$face}{layers} };		# Since all_layers, we are called only for layer 0; subrecipes may need more
    for my $rec (@recipes) {
      push(@subs, sub {return undef}), next unless length $rec;
#warn "recipe=`$rec'; face=`$face'; N=$N; deadkey=`$deadkey'; last_layer=$LL";
      my ($tr) = $self->make_translator_for_layers( $rec, $deadkey, $face, [0..$LL] );
#warn "  done";
      push @subs, $tr;
    }
    my $g = $self->{faces}{$face}{'[geometry]'}
      or die "Face `$face' has no associated layer with geometry info; did you set geometry_via_layer?";

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

    }
    if ($flat and not $N) {
      die "<<<Flat>>> makes sense only in toplevel descriptions of satellite faces: <<<$in>>> in `$face´" unless $deadkey;
      my $inv = $invert ? 'Inv' : '';
      $self->{faces}{$face}{"[FlatPrefixMap$inv]"}{$deadkey}{$self->key2hex($_)}
        = $self->document_char($Map{$_}, 'explicit flat tuneup') for keys %Map;
      $used_deadkey = "/$deadkey";
    }
    return sub ($) { my $c = shift; defined $c or return $c; $c = $c->[0] if 'ARRAY' eq ref $c; $self->document_char($Map{$c}, 'explicit tuneup') }, $used_deadkey;
  }
  my $map = $self->get_deep($self, 'DEADKEYS', split m(/), $name);
  die "Can't resolve character map `$name'" unless defined $map;
  unless (exists $map->{map}) {{
    my($k1) = keys %$map;
    die "Character map `$name' does not contain HEX: `$k1'" if %$map and not $k1 =~ /^[0-9a-f]{4,}$/;
    die "Character map is a parent-type map, but no deadkey to use specified" unless defined $deadkey;
    my $Map = { map +(chr hex $_, $map->{$_}), keys %$map };
    die "Character map `$name' does not contain `$deadkey', contains <", (join '> <', keys %$map), ">"
      unless exists $Map->{chr hex $deadkey};
    $map = $Map->{chr hex $deadkey}, $used_deadkey = "/$deadkey" if %$Map;
    $map = {map => {}}, warn "Character map for `$name' empty" unless %$map;

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

  } else {
    $ARG = [map $self->{faces}{$face}{layers}[$_], @$NN];
    $append = "#$face#";
  }
  [$self->make_translated_layers_tr($ARG, $recipe, $append, $deadkey, $face, $NN)];	# Either we saw (), or $recipe is not a face recipe!
}

sub massage_translated_layers ($$$$;$) {
  my ($self, $in, $face, $NN, $deadkey) = (shift, shift, shift, shift, shift, '');
#warn "Massaging `$deadkey' for `$face':$N";
  return $in unless my $r = $self->get_deep($self, 'faces', (my @p = split m(/), $face), '[Diacritic_if_undef]');
  $r =~ s/^\s+//;
#warn "	-> end recipe `$r'";
	warn "  mk_tr_lyrs 6" if debug_stacking_ord;
  my $post = $self->make_translated_layers($r, $face, $NN, $deadkey);
	warn "  mk_tr_lyrs_st 1" if debug_stacking_ord;
  return [$self->make_translated_layers_stack($in, $post)];
}

sub default_char ($$) {
  my ($self, $F) = (shift, shift);

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

   $recipe =~ s/^\s+//;
   $recipe
}

sub scan_for_DeadKey_Maps ($) {			# Makes a direct-access synonym, scan for DeadKey_Maps* keys
  my ($self, %h, $expl) = (shift);
#Dumpvalue->new()->dumpValue($self);
  my @F = grep m(^faces(/.*)?$), @{$self->{'[keys]'}};
  for my $FF (@F) {
    (my $F = $FF) =~ s(^faces/?)();
    my(@FF, @HH) = split m(/), $FF;
    next if @FF == 1 or $FF[-1] eq 'VK';
    my @FF1 = @FF;
    push(@HH, $self->get_deep($self, @FF1)), pop @FF1 while @FF1;	# All the parents
    my $H = $HH[0];
    next if $H->{PartialFace};
    $self->{faces}{$F} = $H if $F =~ m(/) and exists $H->{layers};			# Make a direct-access copy
#warn "Face section `${FF}'s parents: ", scalar @HH;
#warn "Mismatch of hashes for `$FF'" unless $self->{faces}{$F} == $H;

    # warn "compositing: faces `$F'; -> <", (join '> <', %$H), ">";

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

    }
  }
  $self
}

sub create_prefix_chains ($) {
  my ($self, %h, $expl) = (shift);
  my @F = grep m(^faces(/.*)?$), @{$self->{'[keys]'}};
  for my $FF (@F) {
    (my $F = $FF) =~ s(^faces/?)();
    my(@FF, @HH) = split m(/), $FF;
    next if @FF == 1 or $FF[-1] eq 'VK';
    push(@HH, $self->get_deep($self, @FF)), pop @FF while @FF;
    my($H, %KK) = $HH[0];
    for my $chain ( @{ $H->{'[PrefixChains]'} || [] } ) {
      (my $c = $chain) =~ s/^\s+//;
      my @prefix = map { $_ and $self->charhex2key($_) } split /,/, $c, -1;		# trailing empty means all are prefixes
      length(my $trail_nonprefix = $prefix[-1]) or pop @prefix;
      my $start = shift @prefix;
      warn "PrefixChain for `$start' in font `$F' is empty" unless @prefix > 1;
      for my $Kn (1..$#prefix) {

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

    }
  }
  $self
}

sub link_composite_layers ($) {		# as above, but finish 
  my ($self, %h, $expl) = (shift);
  my @F = grep m(^faces(/.*)?$), @{$self->{'[keys]'}};
  for my $FF (@F) {
    (my $F = $FF) =~ s(^faces/?)();
    my(@FF, @HH) = split m(/), $FF;
    next if @FF == 1 or $FF[-1] eq 'VK';
    push(@HH, $self->get_deep($self, @FF)), pop @FF while @FF;
    my $H = $HH[0];
    for my $new_facename (sort values %{$H->{'[deadkeyFace]'}}) {
#warn "Joining <$F>, <$new_facename>";
      $self->link_layers($F, $new_facename, 'skipfix', 'no-slot-warn');
    }
  }
  $self
}

lib/UI/KeyboardLayout.pm  view on Meta::CPAN

  }
  $self
}

sub massage_flat_maps_extra_keys ($) {
  my $self = shift;
  my @F = grep m(^faces(/.*)?$), @{$self->{'[keys]'}};
  my (@Fok, @Fok0, @Fnok);
  for my $FF (@F) {
    (my $F = $FF) =~ s(^faces/?)();
    my(@FF, @HH, @FokF) = split m(/), $FF;
    next if @FF == 1 or $FF[-1] eq 'VK';
    push @Fok, $F;				# Assumed base faces
    my($H) = $self->get_deep($self, @FF);
    my $Cov = $H->{'[coverageExtraInclPrefix]'};
##    warn join ',', sort keys %$Cov;
    for my $inv ('', 'Inv') {
     for my $dead (sort keys %{$H->{"[FlatPrefixMap$inv]"}}) {
      my($sk, @c) = ('');
      for my $cHex (sort keys %{$H->{"[FlatPrefixMap$inv]"}{$dead}}) {
        my $chr = $self->charhex2key($cHex);



( run in 1.022 second using v1.01-cache-2.11-cpan-5511b514fd6 )