6 $semicolon = ";"; # help out stupid emacs
20 GetOptions ("platform=s" => \$platform);
22 if ($platform eq "osx") {
23 $gtk_modifier_map{'PRIMARY'} = 'meta';
24 $gtk_modifier_map{'SECONDARY'} = 'Mod1';
25 $gtk_modifier_map{'TERTIARY'} = 'Shift';
26 $gtk_modifier_map{'LEVEL4'} = 'Control';
27 $gtk_modifier_map{'WINDOW'} = 'Mod1';
29 $cs_modifier_map{'PRIMARY'} = 'Command';
30 $cs_modifier_map{'SECONDARY'} = 'Alt';
31 $cs_modifier_map{'TERTIARY'} = 'Shift';
32 $cs_modifier_map{'LEVEL4'} = 'Control';
33 $cs_modifier_map{'WINDOW'} = 'Alt';
37 $gtk_modifier_map{'PRIMARY'} = 'Control';
38 $gtk_modifier_map{'SECONDARY'} = 'Alt';
39 $gtk_modifier_map{'TERTIARY'} = 'Shift';
40 $gtk_modifier_map{'LEVEL4'} = 'Mod4';
41 $gtk_modifier_map{'WINDOW'} = 'Alt';
43 $cs_modifier_map{'PRIMARY'} = 'Control';
44 $cs_modifier_map{'SECONDARY'} = 'Alt';
45 $cs_modifier_map{'TERTIARY'} = 'Shift';
46 $cs_modifier_map{'LEVEL4'} = 'Win';
47 $cs_modifier_map{'WINDOW'} = 'Alt';
51 'asciicircum' => '\\verb=^=',
54 'bracketright' => ']',
56 'braceright' => '\\}',
57 'backslash' => '$\\backslash$',
58 'rightanglebracket' => '>',
59 'leftanglebracket' => '<',
69 'rightarrow' => '$\rightarrow$',
70 'leftarrow' => '$\\leftarrow$',
71 'uparrow' => '$\\uparrow$',
72 'downarrow' => '$\\downarrow$',
73 'Page_Down' => 'Page Down',
74 'Page_Up' => 'Page Up',
80 next if /^$semicolon/;
86 $group_names{$group_key} = $group_name;
87 $group_text{$group_key} = $group_text;
88 $group_numbering{$group_key} = $group_number;
89 # each binding entry is 2 element array. bindings
90 # are all collected into a container array. create
91 # the first dummy entry so that perl knows what we
93 $group_bindings{$group_key} = [ [] ];
98 ($group_key,$group_name) = split (/\s+/, $_, 2);
108 $group_names{$group_key} = $group_name;
109 $group_text{$group_key} = $group_text;
112 next if (/^[ \t]+$/);
122 ($key,$action,$binding,$text) = split (/\|/, $_, 4);
124 # substitute bindings
126 $gtk_binding = $binding;
128 foreach $k (keys %gtk_modifier_map) {
129 $gtk_binding =~ s/\@$k\@/$gtk_modifier_map{$k}/;
132 # print the accelmap output
135 # remove + and don't print it in the accelmap
138 # include this in the accelmap
139 # print "(gtk_accel_map \"<Actions>/$action\" \"$gtk_binding\")\n";
143 # do not include this binding in the cheat sheet
147 $bref = $group_bindings{$key};
148 push (@$bref, [$binding, $text]);
156 # Now print the cheatsheet
158 $boilerplate_header = <<END_HEADER;
159 \\documentclass[10pt,landscape]{article}
160 \\usepackage{multicol}
163 \\usepackage{palatino}
164 \\usepackage[landscape]{geometry}
167 % This sets page margins to .5 inch if using letter paper, and to 1cm
168 % if using A4 paper. (This probably isnott strictly necessary.)
169 % If using another size paper, use default 1cm margins.
170 \\ifthenelse{\\lengthtest { \\paperwidth = 11in}}
171 { \\geometry{top=.5in,left=.5in,right=.5in,bottom=.5in} }
172 {\\ifthenelse{ \\lengthtest{ \\paperwidth = 297mm}}
173 {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
174 {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
177 % Turn off header and footer
180 % Redefine section commands to use less space
182 \\renewcommand{\\section}{\\\@startsection{section}{1}{0mm}%
183 {-1ex plus -.5ex minus -.2ex}%
185 {\\normalfont\\large\\bfseries}}
186 \\renewcommand{\\subsection}{\\\@startsection{subsection}{2}{0mm}%
187 {-1explus -.5ex minus -.2ex}%
189 {\\normalfont\\normalsize\\bfseries}}
190 \\renewcommand{\\subsubsection}{\\\@startsection{subsubsection}{3}{0mm}%
191 {-1ex plus -.5ex minus -.2ex}%
193 {\\normalfont\\small\\bfseries}}
196 % Define BibTeX command
197 \\def\\BibTeX{{\\rm B\\kern-.05em{\\sc i\\kern-.025em b}\\kern-.08em
198 T\\kern-.1667em\\lower.7ex\\hbox{E}\\kern-.125emX}}
200 % Do not print section numbers
201 \\setcounter{secnumdepth}{0}
203 \\setlength{\\parindent}{0pt}
204 \\setlength{\\parskip}{0pt plus 0.5ex}
206 %-------------------------------------------
212 \\begin{multicols}{3}
215 $boilerplate_footer = <<END_FOOTER;
220 print $boilerplate_header;
222 @groups_sorted_by_number = sort { $group_numbering{$a} <=> $group_numbering{$b} } keys %group_numbering;
224 foreach $gk (@groups_sorted_by_number) {
225 # $bref is a reference to the array of arrays for this group
226 $bref = $group_bindings{$gk};
228 if (scalar @$bref > 1) {
229 print "\\section*{$group_names{$gk}}\n";
231 if (!($group_text{$gk} eq "")) {
232 print "$group_text{$gk}\n\\par\n";
235 # ignore the first entry, which was empty
239 # find the longest descriptive text (this is not 100% accuracy due to typography)
244 for $bbref (@$bref) {
245 # $bbref is a reference to an array
247 if ($text =~ /\\linebreak/) {
248 $matchtext = s/\\linebreak.*//;
252 if (length ($matchtext) > $maxtextlen) {
253 $maxtextlen = length ($matchtext);
254 $maxtext = $matchtext;
262 print "\\settowidth{\\MyLen}{\\texttt{$maxtext}}\n";
263 print "\\begin{tabular}{\@{}p{\\the\\MyLen}%
264 \@{}p{\\linewidth-\\the\\MyLen}%
267 # now print the bindings
269 for $bbref (@$bref) {
270 # $bbref is a reference to an array
272 $binding = @$bbref[0];
275 if ($binding =~ /:/) { # mouse binding with "where" clause
276 ($binding,$where) = split (/:/, $binding, 2);
279 $binding =~ s/></\+/g;
283 foreach $k (keys %cs_modifier_map) {
284 $binding =~ s/\@$k\@/$cs_modifier_map{$k}/;
287 # substitute keycode names for something printable
289 $re = qr/${ \(join'|', map quotemeta, keys %keycodes)}/;
290 $binding =~ s/($re)/$keycodes{$1}/g;
292 # split up mouse bindings to "click" and "where" parts
294 if ($gk eq "mobject") {
295 print "{\\tt @$bbref[1] } & {\\tt $binding} {\\it $where}\\\\\n";
297 print "{\\tt @$bbref[1] } & {\\tt $binding} \\\\\n";
301 print "\\end{tabular}\n";
306 print $boilerplate_footer;