6 $semicolon = ";"; # help out stupid emacs
7 $title = "Ardour Shortcuts";
27 GetOptions ("platform=s" => \$platform,
28 "winkey=s" => \$winkey,
29 "cheatsheet" => \$make_cheatsheet,
30 "accelmap" => \$make_accelmap,
31 "merge=s" => \$merge_from,
35 # The use of a separate @WINDOW@ meta-modifier was a mistake and needs to be removed from the bindings.in file.
36 # There is no separate key/modifier we can use for this, so inevitably it will be the same modifier as one of
37 # the other meta-modifiers. This means, for example, that @WINDOW@-b could be same as @SECONDARY@-b with no
38 # warnings given. One of the bindings will work, one won't.
41 if ($platform eq "darwin") {
43 $gtk_modifier_map{'PRIMARY'} = 'Primary'; # GTK supports Primary to allow platform-independent binding to the "primary" modifier, which on OS X is Command
44 $gtk_modifier_map{'SECONDARY'} = 'Control';
45 $gtk_modifier_map{'TERTIARY'} = 'Shift';
46 $gtk_modifier_map{'LEVEL4'} = 'Mod1';
47 $gtk_modifier_map{'WINDOW'} = 'Control';
49 # cs_modifier_map == "Cheat Sheet Modifier Map"
50 # Used to control what gets shown in the
51 # cheat sheet for a given (meta)-modifier
53 $cs_modifier_map{'PRIMARY'} = 'Cmd';
54 $cs_modifier_map{'SECONDARY'} = 'Control';
55 $cs_modifier_map{'TERTIARY'} = 'Shift';
56 $cs_modifier_map{'LEVEL4'} = 'Opt';
57 $cs_modifier_map{'WINDOW'} = 'Control';
59 # used to display what gets shown in the
60 # cheat sheet for mouse bindings. Differs
61 # from cs_modifier map in using shorter
64 $mouse_modifier_map{'PRIMARY'} = 'Cmd';
65 $mouse_modifier_map{'SECONDARY'} = 'Ctrl';
66 $mouse_modifier_map{'TERTIARY'} = 'Shift';
67 $mouse_modifier_map{'LEVEL4'} = 'Opt';
68 $mouse_modifier_map{'WINDOW'} = 'Ctrl';
72 $gtk_modifier_map{'PRIMARY'} = 'Control';
73 $gtk_modifier_map{'SECONDARY'} = 'Alt';
74 $gtk_modifier_map{'TERTIARY'} = 'Shift';
75 $gtk_modifier_map{'LEVEL4'} = $winkey; # something like "Mod4><Super"
76 $gtk_modifier_map{'WINDOW'} = 'Alt';
78 # cs_modifier_map == "Cheat Sheet Modifier Map"
79 # Used to control what gets shown in the
80 # cheat sheet for a given (meta)-modifier
82 $cs_modifier_map{'PRIMARY'} = 'Control';
83 $cs_modifier_map{'SECONDARY'} = 'Alt';
84 $cs_modifier_map{'TERTIARY'} = 'Shift';
85 $cs_modifier_map{'LEVEL4'} = 'Win';
86 $cs_modifier_map{'WINDOW'} = 'Alt';
88 # used to display what gets shown in the
89 # cheat sheet for mouse bindings. Differs
90 # from cs_modifier map in using shorter
93 $mouse_modifier_map{'PRIMARY'} = 'Ctl';
94 $mouse_modifier_map{'SECONDARY'} = 'Alt';
95 $mouse_modifier_map{'TERTIARY'} = 'Shift';
96 $mouse_modifier_map{'LEVEL4'} = 'Win';
97 $mouse_modifier_map{'WINDOW'} = 'Alt';
104 'asciicircum' => '^',
105 'apostrophe' => '\'',
106 'bracketleft' => '[',
107 'bracketright' => ']',
112 'rightanglebracket' => '>',
113 'leftanglebracket' => '<',
123 'rightarrow' => '→',
124 'leftarrow' => '←',
125 'uparrow' => '↑',
126 'downarrow' => '↓',
127 'Page_Down' => 'PageDown',
128 'Page_Up' => 'PageUp',
130 'KP_Right' => 'KP-→',
131 'KP_Left' => 'KP-←',
132 'KP_Up' => 'KP-↑',
133 'KP_Down' => 'KP-↓',
141 'asciicircum' => '\\verb=^=',
142 'apostrophe' => '\'',
143 'bracketleft' => '[',
144 'bracketright' => ']',
145 'braceleft' => '\\{',
146 'braceright' => '\\}',
147 'backslash' => '$\\backslash$',
149 'rightanglebracket' => '>',
150 'leftanglebracket' => '<',
151 'ampersand' => '\\&',
160 'rightarrow' => '$\rightarrow$',
161 'leftarrow' => '$\\leftarrow$',
162 'uparrow' => '$\\uparrow$',
163 'downarrow' => '$\\downarrow$',
164 'Page_Down' => 'Page Down',
165 'Page_Up' => 'Page Up',
174 open (BINDINGS, $merge_from) || die ("merge from bindings: file not readable");
176 next if (/^$semicolon/);
177 if (/^\(gtk_accel/) {
179 chop; # closing parenthesis
181 ($junk, $action, $binding) = split;
182 $merge_bindings{$action} = $binding;
188 if ($make_accelmap && !$merge_from) {
189 print ";; this accelmap was produced by tools/fmt-bindings\n";
193 next if /^$semicolon/;
205 $group_names{$group_key} = $group_name;
206 $group_text{$group_key} = $group_text;
207 $group_numbering{$group_key} = $group_number;
208 # each binding entry is 2 element array. bindings
209 # are all collected into a container array. create
210 # the first dummy entry so that perl knows what we
212 $group_bindings{$group_key} = [ [] ];
217 ($group_key,$group_name) = split (/\s+/, $_, 2);
227 $group_names{$group_key} = $group_name;
228 $group_text{$group_key} = $group_text;
231 next if (/^[ \t]+$/);
241 ($key,$action,$binding,$text) = split (/\|/, $_, 4);
243 # substitute bindings
245 $gtk_binding = $binding;
248 $lookup = "<Actions>/" . $action;
249 if ($merge_bindings{$lookup}) {
250 $binding = $merge_bindings{$lookup};
253 # forced inclusion of bindings from template
255 # this action is not defined in the merge from set, so forget it
261 # print the accelmap output
264 # remove + and don't print it in the accelmap
267 # include this in the accelmap
268 if (!$merge_from && $make_accelmap) {
269 foreach $k (keys %gtk_modifier_map) {
270 $gtk_binding =~ s/\@$k\@/$gtk_modifier_map{$k}/;
272 print "(gtk_accel_path \"<Actions>/$action\" \"$gtk_binding\")\n";
277 # do not include this binding in the cheat sheet
281 $bref = $group_bindings{$key};
282 push (@$bref, [$binding, $text]);
290 if ($make_accelmap || !$make_cheatsheet) {
296 @groups_sorted_by_number = sort { $group_numbering{$a} <=> $group_numbering{$b} } keys %group_numbering;
298 foreach $gk (@groups_sorted_by_number) {
301 # mouse stuff - ignore
305 # $bref is a reference to the array of arrays for this group
306 $bref = $group_bindings{$gk};
308 if (scalar @$bref > 1) {
310 $name = $group_names{$gk};
311 $name =~ s/\\linebreak.*//;
313 $name =~ s/\$\\_\$/-/g;
314 $name =~ s/\\[a-z]+ //g;
318 print "<h3>$name</h3>\n";
320 $gtext = $group_text{$gk};
321 $gtext =~ s/\\linebreak.*//;
323 $gtext =~ s/\$\\_\$/-/g;
324 $gtext =~ s/\\[a-z]+ //g;
326 $gtext =~ s/\\par//g;
328 if (!($gtext eq "")) {
332 # ignore the first entry, which was empty
338 print "<dl class=\"bindings\">\n";
340 # sort the array of arrays by the descriptive text for nicer appearance,
343 for $bbref (sort { @$a[1] cmp @$b[1] } @$bref) {
344 # $bbref is a reference to an array
346 $binding = @$bbref[0];
349 if ($binding =~ /:/) { # mouse binding with "where" clause
350 ($binding,$where) = split (/:/, $binding, 2);
353 foreach $k (keys %cs_modifier_map) {
354 $binding =~ s/\@$k\@/$cs_modifier_map{$k}/;
357 # remove braces for HTML
359 $binding =~ s/></\+/g;
363 # substitute keycode names for something printable
365 $re = qr/${ \(join'|', map quotemeta, keys %keycodes)}/;
366 $binding =~ s/($re)/$keycodes{$1}/g;
368 # tidy up description
371 $descr =~ s/\\linebreak.*//;
373 $descr =~ s/\$\\_\$/-/g;
374 $descr =~ s/\\[a-z]+ //g;
376 $descr =~ s/\\par//g;
378 print "<dt>$descr</dt><dd>$binding</dd>\n";
385 print " <!-- remove this if more text is added below -->\n";
390 # Now print the cheatsheet
392 $boilerplate_header = <<END_HEADER;
393 \\documentclass[10pt,landscape]{article}
394 %\\documentclass[10pt,landscape,a4paper]{article}
395 %\\documentclass[10pt,landscape,letterpaper]{article}
396 \\usepackage{multicol}
399 \\usepackage{palatino}
400 \\usepackage{geometry}
402 \\setlength{\\parskip}{0pt}
403 \\setlength{\\parsep}{0pt}
404 \\setlength{\\headsep}{0pt}
405 \\setlength{\\topskip}{0pt}
406 \\setlength{\\topmargin}{0pt}
407 \\setlength{\\topsep}{0pt}
408 \\setlength{\\partopsep}{0pt}
410 % This sets page margins to .5 inch if using letter paper, and to 1cm
411 % if using A4 paper. (This probably isnott strictly necessary.)
412 % If using another size paper, use default 1cm margins.
413 \\ifthenelse{\\lengthtest { \\paperwidth = 11in}}
414 { \\geometry{top=.5in,left=.5in,right=.5in,bottom=.5in} }
415 {\\ifthenelse{ \\lengthtest{ \\paperwidth = 297mm}}
416 {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
417 {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
420 % Turn off header and footer
423 % Redefine section commands to use less space
425 \\renewcommand{\\section}{\\\@startsection{section}{1}{0mm}%
426 {-1ex plus -.5ex minus -.2ex}%
428 {\\normalfont\\large\\bfseries}}
429 \\renewcommand{\\subsection}{\\\@startsection{subsection}{2}{0mm}%
430 {-1explus -.5ex minus -.2ex}%
432 {\\normalfont\\normalsize\\bfseries}}
433 \\renewcommand{\\subsubsection}{\\\@startsection{subsubsection}{3}{0mm}%
434 {-1ex plus -.5ex minus -.2ex}%
436 {\\normalfont\\small\\bfseries}}
439 % Do not print section numbers% Do not print section numbers
440 \\setcounter{secnumdepth}{0}
442 \\setlength{\\parindent}{0pt}
443 \\setlength{\\parskip}{0pt plus 0.5ex}
445 %-------------------------------------------
451 \\begin{multicols}{3}
454 $boilerplate_footer = <<END_FOOTER;
455 \\rule{0.3\\linewidth}{0.25pt}
458 Copyright \\copyright\\ 2013 ardour.org
460 % Should change this to be date of file, not current date.
462 http://manual.ardour.org
468 if ($make_cheatsheet) {
469 print $boilerplate_header;
470 print "\\begin{center}\\Large\\bf $title \\end{center}\n";
473 @groups_sorted_by_number = sort { $group_numbering{$a} <=> $group_numbering{$b} } keys %group_numbering;
475 foreach $gk (@groups_sorted_by_number) {
476 # $bref is a reference to the array of arrays for this group
477 $bref = $group_bindings{$gk};
479 if (scalar @$bref > 1) {
480 print "\\section{$group_names{$gk}}\n";
482 if (!($group_text{$gk} eq "")) {
483 print "$group_text{$gk}\n\\par\n";
486 # ignore the first entry, which was empty
490 # find the longest descriptive text (this is not 100% accuracy due to typography)
495 for $bbref (@$bref) {
496 # $bbref is a reference to an array
500 # if there is a linebreak, just use everything up the linebreak
501 # to determine the width
504 if ($text =~ /\\linebreak/) {
505 $matchtext = s/\\linebreak.*//;
509 if (length ($matchtext) > $maxtextlen) {
510 $maxtextlen = length ($matchtext);
511 $maxtext = $matchtext;
516 # mouse mode: don't extend max text at all - space it tight
524 print "\\settowidth{\\MyLen}{\\texttt{$maxtext}}\n";
525 print "\\begin{tabular}{\@{}p{\\the\\MyLen}%
526 \@{}p{\\linewidth-\\the\\MyLen}%
529 # sort the array of arrays by the descriptive text for nicer appearance,
532 for $bbref (sort { @$a[1] cmp @$b[1] } @$bref) {
533 # $bbref is a reference to an array
535 $binding = @$bbref[0];
538 if ($binding =~ /:/) { # mouse binding with "where" clause
539 ($binding,$where) = split (/:/, $binding, 2);
543 # mouse mode - use shorter abbrevs
544 foreach $k (keys %mouse_modifier_map) {
545 $binding =~ s/\@$k\@/$mouse_modifier_map{$k}/;
548 foreach $k (keys %cs_modifier_map) {
549 $binding =~ s/\@$k\@/$cs_modifier_map{$k}/;
553 $binding =~ s/></\+/g;
557 # substitute keycode names for something printable
559 $re = qr/${ \(join'|', map quotemeta, keys %keycodes)}/;
560 $binding =~ s/($re)/$keycodes{$1}/g;
562 # split up mouse bindings to "click" and "where" parts
564 if ($gk eq "mobject") {
565 print "{\\tt @$bbref[1] } & {\\tt $binding} {\\it $where}\\\\\n";
567 print "{\\tt @$bbref[1] } & {\\tt $binding} \\\\\n";
571 print "\\end{tabular}\n";
576 print $boilerplate_footer;