6 $semicolon = ";"; # help out stupid emacs
7 $title = "Ardour Shortcuts";
21 $winkey = 'Mod4><Super';
26 GetOptions
("platform=s" => \
$platform,
27 "winkey=s" => \
$winkey,
28 "cheatsheet" => \
$make_cheatsheet,
29 "accelmap" => \
$make_accelmap,
30 "merge=s" => \
$merge_from);
32 if ($platform eq "osx") {
34 $gtk_modifier_map{'PRIMARY'} = 'meta';
35 $gtk_modifier_map{'SECONDARY'} = 'Mod1';
36 $gtk_modifier_map{'TERTIARY'} = 'Shift';
37 $gtk_modifier_map{'LEVEL4'} = 'Control';
38 $gtk_modifier_map{'WINDOW'} = 'Mod1';
40 $cs_modifier_map{'PRIMARY'} = 'Command';
41 $cs_modifier_map{'SECONDARY'} = 'Opt';
42 $cs_modifier_map{'TERTIARY'} = 'Shift';
43 $cs_modifier_map{'LEVEL4'} = 'Control';
44 $cs_modifier_map{'WINDOW'} = 'Opt';
46 $mouse_modifier_map{'PRIMARY'} = 'Cmd';
47 $mouse_modifier_map{'SECONDARY'} = 'Opt';
48 $mouse_modifier_map{'TERTIARY'} = 'Shift';
49 $mouse_modifier_map{'LEVEL4'} = 'Control';
50 $mouse_modifier_map{'WINDOW'} = 'Opt';
54 $gtk_modifier_map{'PRIMARY'} = 'Control';
55 $gtk_modifier_map{'SECONDARY'} = 'Alt';
56 $gtk_modifier_map{'TERTIARY'} = 'Shift';
57 $gtk_modifier_map{'LEVEL4'} = $winkey;
58 $gtk_modifier_map{'WINDOW'} = 'Alt';
59 $gtk_modifier_map{$winkey} => 'Win';
61 $cs_modifier_map{'PRIMARY'} = 'Control';
62 $cs_modifier_map{'SECONDARY'} = 'Alt';
63 $cs_modifier_map{'TERTIARY'} = 'Shift';
64 $cs_modifier_map{'LEVEL4'} = 'Win';
65 $cs_modifier_map{'WINDOW'} = 'Alt';
66 $cs_modifier_map{$winkey} => 'Win';
68 $mouse_modifier_map{'PRIMARY'} = 'Ctl';
69 $mouse_modifier_map{'SECONDARY'} = 'Alt';
70 $mouse_modifier_map{'TERTIARY'} = 'Shift';
71 $mouse_modifier_map{'LEVEL4'} = 'Win';
72 $mouse_modifier_map{'WINDOW'} = 'Alt';
73 $mouse_modifier_map{$winkey} => 'Win';
77 'asciicircum' => '\\verb=^=',
80 'bracketright' => ']',
82 'braceright' => '\\}',
83 'backslash' => '$\\backslash$',
85 'rightanglebracket' => '>',
86 'leftanglebracket' => '<',
96 'rightarrow' => '$\rightarrow$',
97 'leftarrow' => '$\\leftarrow$',
98 'uparrow' => '$\\uparrow$',
99 'downarrow' => '$\\downarrow$',
100 'Page_Down' => 'Page Down',
101 'Page_Up' => 'Page Up',
107 open (BINDINGS
, $merge_from) || die ("merge from bindings: file not readable");
109 next if (/^$semicolon/);
110 if (/^\(gtk_accel/) {
112 chop; # closing parenthesis
114 ($junk, $action, $binding) = split;
115 $merge_bindings{$action} = $binding;
121 if ($make_accelmap && !$merge_from) {
122 print ";; this accelmap was produced by tools/fmt-bindings\n";
126 next if /^$semicolon/;
138 $group_names{$group_key} = $group_name;
139 $group_text{$group_key} = $group_text;
140 $group_numbering{$group_key} = $group_number;
141 # each binding entry is 2 element array. bindings
142 # are all collected into a container array. create
143 # the first dummy entry so that perl knows what we
145 $group_bindings{$group_key} = [ [] ];
150 ($group_key,$group_name) = split (/\s+/, $_, 2);
160 $group_names{$group_key} = $group_name;
161 $group_text{$group_key} = $group_text;
164 next if (/^[ \t]+$/);
174 ($key,$action,$binding,$text) = split (/\|/, $_, 4);
176 # substitute bindings
178 $gtk_binding = $binding;
181 $lookup = "<Actions>/" . $action;
182 if ($merge_bindings{$lookup}) {
183 $binding = $merge_bindings{$lookup};
186 # forced inclusion of bindings from template
188 # this action is not defined in the merge from set, so forget it
194 # print the accelmap output
197 # remove + and don't print it in the accelmap
200 # include this in the accelmap
201 if (!$merge_from && $make_accelmap) {
202 foreach $k (keys %gtk_modifier_map) {
203 $gtk_binding =~ s/\@$k\@/$gtk_modifier_map{$k}/;
205 print "(gtk_accel_path \"<Actions>/$action\" \"$gtk_binding\")\n";
210 # do not include this binding in the cheat sheet
214 $bref = $group_bindings{$key};
215 push (@
$bref, [$binding, $text]);
223 if ($make_accelmap || !$make_cheatsheet) {
227 # Now print the cheatsheet
229 $boilerplate_header = <<END_HEADER;
230 \\documentclass[10pt,landscape]{article}
231 \\usepackage{multicol}
234 \\usepackage{palatino}
235 \\usepackage{geometry}
237 \\setlength{\\parskip}{0pt}
238 \\setlength{\\parsep}{0pt}
239 \\setlength{\\headsep}{0pt}
240 \\setlength{\\topskip}{0pt}
241 \\setlength{\\topmargin}{0pt}
242 \\setlength{\\topsep}{0pt}
243 \\setlength{\\partopsep}{0pt}
245 % This sets page margins to .5 inch if using letter paper, and to 1cm
246 % if using A4 paper. (This probably isnott strictly necessary.)
247 % If using another size paper, use default 1cm margins.
248 \\ifthenelse{\\lengthtest { \\paperwidth = 11in}}
249 { \\geometry{top=.5in,left=1in,right=0in,bottom=.5in} }
250 {\\ifthenelse{ \\lengthtest{ \\paperwidth = 297mm}}
251 {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
252 {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
255 % Turn off header and footer
258 % Redefine section commands to use less space
260 \\renewcommand{\\section}{\\\@startsection{section}{1}{0mm}%
261 {-1ex plus -.5ex minus -.2ex}%
263 {\\normalfont\\large\\bfseries}}
264 \\renewcommand{\\subsection}{\\\@startsection{subsection}{2}{0mm}%
265 {-1explus -.5ex minus -.2ex}%
267 {\\normalfont\\normalsize\\bfseries}}
268 \\renewcommand{\\subsubsection}{\\\@startsection{subsubsection}{3}{0mm}%
269 {-1ex plus -.5ex minus -.2ex}%
271 {\\normalfont\\small\\bfseries}}
274 % Do not print section numbers% Do not print section numbers
275 \\setcounter{secnumdepth}{0}
277 \\setlength{\\parindent}{0pt}
278 \\setlength{\\parskip}{0pt plus 0.5ex}
280 %-------------------------------------------
286 \\begin{multicols}{3}
289 $boilerplate_footer = <<END_FOOTER
;
290 \\rule
{0.3\\linewidth
}{0.25pt
}
293 Copyright
\\copyright
\\ 2009 ardour
.org
295 % Should change this to be date of file
, not current date
.
296 %\\verb
!$Revision: 1.13 $, $Date: 2008/05/29 06:11:56 $.!
298 http
://ardour
.org
/manual
304 if ($make_cheatsheet) {
305 print $boilerplate_header;
306 print "\\begin{center}\\Large\\bf $title \\end{center}\n";
309 @groups_sorted_by_number = sort { $group_numbering{$a} <=> $group_numbering{$b} } keys %group_numbering;
311 foreach $gk (@groups_sorted_by_number) {
312 # $bref is a reference to the array of arrays for this group
313 $bref = $group_bindings{$gk};
315 if (scalar @
$bref > 1) {
316 print "\\section{$group_names{$gk}}\n";
318 if (!($group_text{$gk} eq "")) {
319 print "$group_text{$gk}\n\\par\n";
322 # ignore the first entry, which was empty
326 # find the longest descriptive text (this is not 100% accuracy due to typography)
331 for $bbref (@
$bref) {
332 # $bbref is a reference to an array
336 # if there is a linebreak, just use everything up the linebreak
337 # to determine the width
340 if ($text =~ /\\linebreak/) {
341 $matchtext = s/\\linebreak.*//;
345 if (length ($matchtext) > $maxtextlen) {
346 $maxtextlen = length ($matchtext);
347 $maxtext = $matchtext;
352 # mouse mode: don't extend max text at all - space it tight
360 print "\\settowidth{\\MyLen}{\\texttt{$maxtext}}\n";
361 print "\\begin{tabular}{\@{}p{\\the\\MyLen}%
362 \@{}p{\\linewidth-\\the\\MyLen}%
365 # sort the array of arrays by the descriptive text for nicer appearance,
368 for $bbref (sort { @
$a[1] cmp @
$b[1] } @
$bref) {
369 # $bbref is a reference to an array
371 $binding = @
$bbref[0];
374 if ($binding =~ /:/) { # mouse binding with "where" clause
375 ($binding,$where) = split (/:/, $binding, 2);
379 # mouse mode - use shorter abbrevs
380 foreach $k (keys %mouse_modifier_map) {
381 $binding =~ s/\@$k\@/$mouse_modifier_map{$k}/;
384 foreach $k (keys %cs_modifier_map) {
385 $binding =~ s/\@$k\@/$cs_modifier_map{$k}/;
389 $binding =~ s/></\+/g;
393 # substitute keycode names for something printable
395 $re = qr/${ \(join'|', map quotemeta, keys %keycodes)}/;
396 $binding =~ s/($re)/$keycodes{$1}/g;
398 # split up mouse bindings to "click" and "where" parts
400 if ($gk eq "mobject") {
401 print "{\\tt @$bbref[1] } & {\\tt $binding} {\\it $where}\\\\\n";
403 print "{\\tt @$bbref[1] } & {\\tt $binding} \\\\\n";
407 print "\\end{tabular}\n";
412 print $boilerplate_footer;