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};
185 # this action is not defined in the merge from set, so forget it
190 # print the accelmap output
193 # remove + and don't print it in the accelmap
196 # include this in the accelmap
197 if (!$merge_from && $make_accelmap) {
198 foreach $k (keys %gtk_modifier_map) {
199 $gtk_binding =~ s/\@$k\@/$gtk_modifier_map{$k}/;
201 print "(gtk_accel_map \"<Actions>/$action\" \"$gtk_binding\")\n";
206 # do not include this binding in the cheat sheet
210 $bref = $group_bindings{$key};
211 push (@$bref, [$binding, $text]);
219 if ($make_accelmap || !$make_cheatsheet) {
223 # Now print the cheatsheet
225 $boilerplate_header = <<END_HEADER;
226 \\documentclass[10pt,landscape]{article}
227 \\usepackage{multicol}
230 \\usepackage{palatino}
231 \\usepackage{geometry}
233 \\setlength{\\parskip}{0pt}
234 \\setlength{\\parsep}{0pt}
235 \\setlength{\\headsep}{0pt}
236 \\setlength{\\topskip}{0pt}
237 \\setlength{\\topmargin}{0pt}
238 \\setlength{\\topsep}{0pt}
239 \\setlength{\\partopsep}{0pt}
241 % This sets page margins to .5 inch if using letter paper, and to 1cm
242 % if using A4 paper. (This probably isnott strictly necessary.)
243 % If using another size paper, use default 1cm margins.
244 \\ifthenelse{\\lengthtest { \\paperwidth = 11in}}
245 { \\geometry{top=.5in,left=1in,right=0in,bottom=.5in} }
246 {\\ifthenelse{ \\lengthtest{ \\paperwidth = 297mm}}
247 {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
248 {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
251 % Turn off header and footer
254 % Redefine section commands to use less space
256 \\renewcommand{\\section}{\\\@startsection{section}{1}{0mm}%
257 {-1ex plus -.5ex minus -.2ex}%
259 {\\normalfont\\large\\bfseries}}
260 \\renewcommand{\\subsection}{\\\@startsection{subsection}{2}{0mm}%
261 {-1explus -.5ex minus -.2ex}%
263 {\\normalfont\\normalsize\\bfseries}}
264 \\renewcommand{\\subsubsection}{\\\@startsection{subsubsection}{3}{0mm}%
265 {-1ex plus -.5ex minus -.2ex}%
267 {\\normalfont\\small\\bfseries}}
270 % Do not print section numbers% Do not print section numbers
271 \\setcounter{secnumdepth}{0}
273 \\setlength{\\parindent}{0pt}
274 \\setlength{\\parskip}{0pt plus 0.5ex}
276 %-------------------------------------------
282 \\begin{multicols}{3}
285 $boilerplate_footer = <<END_FOOTER;
286 \\rule{0.3\\linewidth}{0.25pt}
289 Copyright \\copyright\\ 2009 ardour.org
291 % Should change this to be date of file, not current date.
292 %\\verb!$Revision: 1.13 $, $Date: 2008/05/29 06:11:56 $.!
294 http://ardour.org/manual
300 if ($make_cheatsheet) {
301 print $boilerplate_header;
302 print "\\begin{center}\\Large\\bf $title \\end{center}\n";
305 @groups_sorted_by_number = sort { $group_numbering{$a} <=> $group_numbering{$b} } keys %group_numbering;
307 foreach $gk (@groups_sorted_by_number) {
308 # $bref is a reference to the array of arrays for this group
309 $bref = $group_bindings{$gk};
311 if (scalar @$bref > 1) {
312 print "\\section{$group_names{$gk}}\n";
314 if (!($group_text{$gk} eq "")) {
315 print "$group_text{$gk}\n\\par\n";
318 # ignore the first entry, which was empty
322 # find the longest descriptive text (this is not 100% accuracy due to typography)
327 for $bbref (@$bref) {
328 # $bbref is a reference to an array
332 # if there is a linebreak, just use everything up the linebreak
333 # to determine the width
336 if ($text =~ /\\linebreak/) {
337 $matchtext = s/\\linebreak.*//;
341 if (length ($matchtext) > $maxtextlen) {
342 $maxtextlen = length ($matchtext);
343 $maxtext = $matchtext;
348 # mouse mode: don't extend max text at all - space it tight
356 print "\\settowidth{\\MyLen}{\\texttt{$maxtext}}\n";
357 print "\\begin{tabular}{\@{}p{\\the\\MyLen}%
358 \@{}p{\\linewidth-\\the\\MyLen}%
361 # sort the array of arrays by the descriptive text for nicer appearance,
364 for $bbref (sort { @$a[1] cmp @$b[1] } @$bref) {
365 # $bbref is a reference to an array
367 $binding = @$bbref[0];
370 if ($binding =~ /:/) { # mouse binding with "where" clause
371 ($binding,$where) = split (/:/, $binding, 2);
375 # mouse mode - use shorter abbrevs
376 foreach $k (keys %mouse_modifier_map) {
377 $binding =~ s/\@$k\@/$mouse_modifier_map{$k}/;
380 foreach $k (keys %cs_modifier_map) {
381 $binding =~ s/\@$k\@/$cs_modifier_map{$k}/;
385 $binding =~ s/></\+/g;
389 # substitute keycode names for something printable
391 $re = qr/${ \(join'|', map quotemeta, keys %keycodes)}/;
392 $binding =~ s/($re)/$keycodes{$1}/g;
394 # split up mouse bindings to "click" and "where" parts
396 if ($gk eq "mobject") {
397 print "{\\tt @$bbref[1] } & {\\tt $binding} {\\it $where}\\\\\n";
399 print "{\\tt @$bbref[1] } & {\\tt $binding} \\\\\n";
403 print "\\end{tabular}\n";
408 print $boilerplate_footer;