Hi: I'm sending this to freshmeat as well, thought it might be of use to the readership. It's a hack of a perl script for WM and KDE which I modified for Blackbox and KDE. Modifications welcome, and enjoy! EAM #!/usr/bin/perl # # # bbkdemenu.pl # by Erick A. Medina # based on a script by Malcolm Cowe ([EMAIL PROTECTED]) # # # This script is made for users of Blackbox (http://bb.alug.org) # to be used along with KDE (http://www.kde.org). # # # The default directory, /usr/share/applnk, will contain various # sub-directories such as Development, Editors, Internet, etc. If for some # reason, you wish to use an alternate (parent) directory that contains the # various applnk files, it can be specified on the command line. # # The directory, if an alternate is specified, MUST be a parent directory to # any/all sub-directories. # # Usage: bbkdemenu.pl [ Options... ] # # Options: # # -d <KDE App.kdelnk dir> # -f <output menufile> # -t <X terminal application> # # When the script is run, it will write out a proper Blackbox submenu # entry that can be included in the menu. When the External Menu has # been correctly configured, the root menu will display a sub-menu containing # all of the KDE related items found. The script only needs to be run when/if # KDE is updated. # # # Installation and Configuration: # # 1) If /usr/bin/perl is not the location of the perl binary on your system, # the first line should be changed to reflect upon it's location. # 2) Run the script as follows: perl bbkdemenu.pl -f kdemenu # 3) Copy the kdemenu file to ~/.blackbox/kdemenu # 4) Configure Blackbox's menu by editing ~/.blackbox/kdemenu # This could be done with any text editor. Insert # the following line (if done with a text editor) into the menu file: # # [include] (~/.blackbox/kdemenu) # # 5) Some KDE entries, such as "Pine" will require a terminal to # execute it. There is a terminal variable below. You may use any # terminal, XTerm is the default. Any command line options such as: # -fg -bg, etc. can be specified in this variable as well. # # # (from Michael Hokenson - [EMAIL PROTECTED]) # # # To Do # ----- # # Programmatically determine the system location for the KDE menu # directory. # # Organise the output alphabetically, with directories appearing # before files. # # Find a better way to parse the exec lines. In the short term, # provide a user mechanism for generating exceptions to the curtailing # of command line options. In the longer term, emulate what KDE does # with these command line features. # # ### ### Variables ### ### The External Menu file, this should NEVER point to the root menu file $menufile = "$ENV{'HOME'}/.blackbox/kdemenu"; ### Base directory, location of all the KDE AppName.kdelnk files + ### Change the base directory default to point at the system files, ### not the user files. Need to find a way of determining the prefix ### programmatically. $prefix="/opt/kde2"; $basedir = $prefix."/share/applnk"; ### Terminal to use. May be specified on the command line with the -t ### switch. $term = "konsole"; ### Print to STDOUT, default is YES, unless a filename is specified $stdout = 1; ### KDE Locale Support ### Support for KDE internationalisation so that menu entries appear ### in the language chosen by the user. Also gets around some problems ### with the KDE applnk file format. ### The Locale is stored in one of two places, depending on the ### version of KDE that is running. $kde2cf="$ENV{'HOME'}/.kde/share/config/kdeglobals"; $kde1cf="$ENV{'HOME'}/.kderc"; $kdeLanguage = ""; ### Open the file, if it exists, otherwise provide a default language. unless(open KDERC, $kde2cf) { unless(open KDERC, $kde1cf) { $kdeLanguage = "C"; } } if ( $kdeLanguage == ""){ $kdeLanguage = "C"; ### Search through the contents of the file while($line = <KDERC>) { chomp($line); ### Grab the Language if($line =~ /^Language=/) { $kdeLanguage = $line; $kdeLanguage =~ s/Language=//; ($kdeLanguage) = split /:/,$kdeLanguage; last; } } close(KDERC); } ### ### Begin Main Iteration. ### ### Process command line arguments foreach $arg(@ARGV) { if($last) { if($last eq "-d") { $basedir = $arg; } elsif($last eq "-f") { $menufile = $arg; $stdout = 0; } elsif($last eq "-t") { $term = $arg; } undef($last); } elsif($arg =~ /^-/) { if($arg =~ /^-[dfst]$/) { $last = $arg; } else { die("Unknown option: $arg\n\nUsage: bbkdemenu.pl [ Options... ]\n". "\n\tOptions:\n\n". "\t\t-d <KDE App.kdelnk dir>\n". "\t\t-f <output menufile>\n". "\t\t-t <X terminal application>\n"); &Usage; } } } ### Make sure the KDE Menu's Top Level Directory exists. if(-d $basedir) { ### See if there is an old menu file. If there is, rename it unless($stdout) { if(-e $menufile) { print STDERR "\tFound $menufile, renaming\n\n"; rename $menufile, "$menufile.old"; } open(MENUFILE,"> $menufile"); } ### Start the main menu entry if($stdout) { print STDOUT "[submenu]\ (KDE)\n"; process_dir (STDOUT, $basedir); print STDOUT "[end]\ (KDE)\n"; } else { print MENUFILE "[submenu]\ (KDE)\n"; process_dir (MENUFILE, $basedir); print MENUFILE "[end]\ (KDE)\n"; } } else { ### Error out :/ print STDERR "ERROR:\n\t$basedir not found\n\tTry another directory.\n"; exit(0); } # End of Main Iteration. ### process_dir() works it's way through each file and directory in ### the tree and generates the menu output to be used by Blackbox. sub process_dir { my $OUT = @_[0]; my $path = @_[1]; my $item; my @tld; my ($gotLang, $gotDef, $gotExec, $inTerm); my $inDesktop; ### tld == Top Level Directory. opendir(TLD, $path) || return; @tld = readdir(TLD); closedir(TLD); foreach $item(@tld) { $gotLang = 0; $gotDef = 0; $gotExec = 0; $inTerm = 0; $inDesktop = 0; ### Ignore hidden files and directories. unless($item =~ /^\./) { if (-d "$path/$item") { print $OUT "[submenu]\ ($item)\n"; process_dir($OUT, "$path/$item"); print $OUT "[end]\ ($item)\n"; } else { # Process the contents of the applnk file to generate a menu # entry for the application. open(SUB,"$path/$item"); ### Search through the contents of the file while($line = <SUB>) { chomp($line); ### Get the application's name. This is stored in the ### [Desktop Entry] section of the applnk description. ### ### The application's name can have one of these forms: ### Name= ### Name[]= ### Name[language]= ### ### Get the default name anyway (one of the first two, just ### in case there is no language specific entry). if ($inDesktop) { # Make sure we are in fact still in the [Desktop Entry] # section. if ($line =~ /^\[/) { $inDesktop = 0; } ### Extract the Name of the Application elsif ($line =~ /^Name\[?\]?=/ && (!$gotDef || !gotLang)) { $pname = $line; $pname =~ s/^Name\[?\]?=//s; $pname =~ s/\"/\'\'/g; $gotDef = 1; } elsif ($line =~ /^Name\[$kdeLanguage\]=/ && !$gotLang) { $pname = $line; $pname =~ s/^Name\[$kdeLanguage\]=//s; $pname =~ s/\"/\'\'/g; $gotLang = 1; } ### Grab the command elsif($line =~ /^Exec=/ && !$gotExec) { $pargs = $line; $pargs =~ s/^Exec=//s; # Strip off all command line options unless the # application is "kfmclient", etc. if ($pargs !~ /^kfmclient/ && $pargs !~ /^kcmshell/ && $pargs !~ /^\/bin\/bash/ && $pargs !~ /^kdesu/){ ($pargs) = split(/\s/, $pargs); } else { # A double check to remove any dubious characters from # the command line of the exceptions listed in the # above "if" statement. The only culprit so far is the # KDE 1 kfmclient command line. $pargs =~ s/\%[a-zA-Z]//g; } $gotExec = 1; } ### If Terminal=1, then we need to execute application ### within a terminal window. elsif($line =~ /^Terminal=(1|true)$/i) { $inTerm=1; } } elsif ($line =~ /^\[(KDE\ )?Desktop\ Entry\]/){ $inDesktop = 1; } } close(SUB); ### Begin printing menu items if ($inTerm) { $pargs = "$term -T \"$pname\" -e $pargs"; } print $OUT "[exec]\ ($pname) {$pargs}\n"; } } } return; } ### - Erick A. Medina 2/11/01, based on Malcolm Cowe, 21/01/2001.
