+if ($make_accelmap || !$make_cheatsheet) {
+ exit 0;
+}
+
+if ($html) {
+
+ @groups_sorted_by_number = sort { $group_numbering{$a} <=> $group_numbering{$b} } keys %group_numbering;
+
+ foreach $gk (@groups_sorted_by_number) {
+
+ if ($gk =~ /^m/) {
+ # mouse stuff - ignore
+ next;
+ }
+
+ # $bref is a reference to the array of arrays for this group
+ $bref = $group_bindings{$gk};
+
+ if (scalar @$bref > 1) {
+
+ $name = $group_names{$gk};
+ $name =~ s/\\linebreak.*//;
+ $name =~ s/\\&/&/;
+ $name =~ s/\$\\_\$/-/g;
+ $name =~ s/\\[a-z]+ //g;
+ $name =~ s/[{}]//g;
+ $name =~ s/\\par//g;
+
+ print "<h3>$name</h3>\n";
+
+ $gtext = $group_text{$gk};
+ $gtext =~ s/\\linebreak.*//;
+ $gtext =~ s/\\&/&/;
+ $gtext =~ s/\$\\_\$/-/g;
+ $gtext =~ s/\\[a-z]+ //g;
+ $gtext =~ s/[{}]//g;
+ $gtext =~ s/\\par//g;
+
+ if (!($gtext eq "")) {
+ print "$gtext\n\n";
+ }
+
+ # ignore the first entry, which was empty
+
+ shift (@$bref);
+
+ # set up the list
+
+ print "<dl class=\"bindings\">\n";
+
+ # sort the array of arrays by the descriptive text for nicer appearance,
+ # and print them
+
+ for $bbref (sort { @$a[1] cmp @$b[1] } @$bref) {
+ # $bbref is a reference to an array
+
+ $binding = @$bbref[0];
+ $text = @$bbref[1];
+
+ if ($binding =~ /:/) { # mouse binding with "where" clause
+ ($binding,$where) = split (/:/, $binding, 2);
+ }
+
+ foreach $k (keys %cs_modifier_map) {
+ $binding =~ s/\@$k\@/$cs_modifier_map{$k}/;
+ }
+
+ # remove braces for HTML
+
+ $binding =~ s/></\+/g;
+ $binding =~ s/^<//;
+ $binding =~ s/>/\+/;
+
+ # substitute keycode names for something printable
+
+ $re = qr/${ \(join'|', map quotemeta, keys %keycodes)}/;
+ $binding =~ s/($re)/$keycodes{$1}/g;
+
+ # tidy up description
+
+ $descr = @$bbref[1];
+ $descr =~ s/\\linebreak.*//;
+ $descr =~ s/\\&/&/;
+ $descr =~ s/\$\\_\$/-/g;
+ $descr =~ s/\\[a-z]+ //g;
+ $descr =~ s/[{}]//g;
+ $descr =~ s/\\par//g;
+
+ print "<dt>$descr</dt><dd>$binding</dd>\n";
+ }
+
+ print "</dl>\n";
+
+ }
+ }
+ print " <!-- remove this if more text is added below -->\n";
+ exit 0;
+}
+
+
+# Now print the cheatsheet
+
+$boilerplate_header = <<END_HEADER;
+\\documentclass[10pt,landscape]{article}
+%\\documentclass[10pt,landscape,a4paper]{article}
+%\\documentclass[10pt,landscape,letterpaper]{article}
+\\usepackage{multicol}
+\\usepackage{calc}
+\\usepackage{ifthen}
+\\usepackage{palatino}
+\\usepackage{geometry}
+
+\\setlength{\\parskip}{0pt}
+\\setlength{\\parsep}{0pt}
+\\setlength{\\headsep}{0pt}
+\\setlength{\\topskip}{0pt}
+\\setlength{\\topmargin}{0pt}
+\\setlength{\\topsep}{0pt}
+\\setlength{\\partopsep}{0pt}
+
+% This sets page margins to .5 inch if using letter paper, and to 1cm
+% if using A4 paper. (This probably isnott strictly necessary.)
+% If using another size paper, use default 1cm margins.
+\\ifthenelse{\\lengthtest { \\paperwidth = 11in}}
+ { \\geometry{top=.5in,left=.5in,right=.5in,bottom=.5in} }
+ {\\ifthenelse{ \\lengthtest{ \\paperwidth = 297mm}}
+ {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
+ {\\geometry{top=1cm,left=1cm,right=1cm,bottom=1cm} }
+ }
+
+% Turn off header and footer
+\\pagestyle{empty}
+
+% Redefine section commands to use less space
+\\makeatletter
+\\renewcommand{\\section}{\\\@startsection{section}{1}{0mm}%
+ {-1ex plus -.5ex minus -.2ex}%
+ {0.5ex plus .2ex}%
+ {\\normalfont\\large\\bfseries}}
+\\renewcommand{\\subsection}{\\\@startsection{subsection}{2}{0mm}%
+ {-1explus -.5ex minus -.2ex}%
+ {0.5ex plus .2ex}%
+ {\\normalfont\\normalsize\\bfseries}}
+\\renewcommand{\\subsubsection}{\\\@startsection{subsubsection}{3}{0mm}%
+ {-1ex plus -.5ex minus -.2ex}%
+ {1ex plus .2ex}%
+ {\\normalfont\\small\\bfseries}}
+\\makeatother
+
+% Do not print section numbers% Do not print section numbers
+\\setcounter{secnumdepth}{0}
+
+\\setlength{\\parindent}{0pt}
+\\setlength{\\parskip}{0pt plus 0.5ex}
+
+%-------------------------------------------
+
+\\begin{document}
+\\newlength{\\MyLen}
+\\raggedright
+\\footnotesize
+\\begin{multicols}{3}
+END_HEADER
+
+$boilerplate_footer = <<END_FOOTER;
+\\rule{0.3\\linewidth}{0.25pt}
+\\scriptsize
+
+Copyright \\copyright\\ 2013 ardour.org
+
+% Should change this to be date of file, not current date.
+
+http://manual.ardour.org
+
+\\end{multicols}
+\\end{document}
+END_FOOTER
+
+if ($make_cheatsheet) {
+ print $boilerplate_header;
+ print "\\begin{center}\\Large\\bf $title \\end{center}\n";
+}
+
+@groups_sorted_by_number = sort { $group_numbering{$a} <=> $group_numbering{$b} } keys %group_numbering;
+
+foreach $gk (@groups_sorted_by_number) {
+ # $bref is a reference to the array of arrays for this group
+ $bref = $group_bindings{$gk};
+
+ if (scalar @$bref > 1) {
+ print "\\section{$group_names{$gk}}\n";
+
+ if (!($group_text{$gk} eq "")) {
+ print "$group_text{$gk}\n\\par\n";
+ }
+
+ # ignore the first entry, which was empty
+
+ shift (@$bref);
+
+ # find the longest descriptive text (this is not 100% accuracy due to typography)
+
+ $maxtextlen = 0;
+ $maxtext = "";
+
+ for $bbref (@$bref) {
+ # $bbref is a reference to an array
+ $text = @$bbref[1];
+
+ #
+ # if there is a linebreak, just use everything up the linebreak
+ # to determine the width
+ #
+
+ if ($text =~ /\\linebreak/) {
+ $matchtext = s/\\linebreak.*//;
+ } else {
+ $matchtext = $text;
+ }
+ if (length ($matchtext) > $maxtextlen) {
+ $maxtextlen = length ($matchtext);
+ $maxtext = $matchtext;
+ }
+ }
+
+ if ($gk =~ /^m/) {
+ # mouse mode: don't extend max text at all - space it tight
+ $maxtext .= ".";
+ } else {
+ $maxtext .= "....";
+ }
+
+ # set up the table
+
+ print "\\settowidth{\\MyLen}{\\texttt{$maxtext}}\n";
+ print "\\begin{tabular}{\@{}p{\\the\\MyLen}%
+ \@{}p{\\linewidth-\\the\\MyLen}%
+ \@{}}\n";
+
+ # sort the array of arrays by the descriptive text for nicer appearance,
+ # and print them
+
+ for $bbref (sort { @$a[1] cmp @$b[1] } @$bref) {
+ # $bbref is a reference to an array
+
+ $binding = @$bbref[0];
+ $text = @$bbref[1];
+
+ if ($binding =~ /:/) { # mouse binding with "where" clause
+ ($binding,$where) = split (/:/, $binding, 2);
+ }
+
+ if ($gk =~ /^m/) {
+ # mouse mode - use shorter abbrevs
+ foreach $k (keys %mouse_modifier_map) {
+ $binding =~ s/\@$k\@/$mouse_modifier_map{$k}/;
+ }
+ } else {
+ foreach $k (keys %cs_modifier_map) {
+ $binding =~ s/\@$k\@/$cs_modifier_map{$k}/;
+ }
+ }
+
+ $binding =~ s/></\+/g;
+ $binding =~ s/^<//;
+ $binding =~ s/>/\+/;
+
+ # substitute keycode names for something printable
+
+ $re = qr/${ \(join'|', map quotemeta, keys %keycodes)}/;
+ $binding =~ s/($re)/$keycodes{$1}/g;
+
+ # split up mouse bindings to "click" and "where" parts
+
+ if ($gk eq "mobject") {
+ print "{\\tt @$bbref[1] } & {\\tt $binding} {\\it $where}\\\\\n";
+ } else {
+ print "{\\tt @$bbref[1] } & {\\tt $binding} \\\\\n";
+ }
+ }
+
+ print "\\end{tabular}\n";
+
+ }
+}
+
+print $boilerplate_footer;
+