Archive for the ‘Programming’ Category

Building a unified time_select field, with simple_form

Wednesday, April 10th, 2013

Before I migrated to Rails 3.2, I used a plugin to provide a unified input field for time_select with either the standard Rails ActionView or the SimpleForm gem (SimpleForm uses ActionView under the hood). I was happy until the Rails upgrade caused my gem to inexplicably stop working. I had a deadline to meet and could not be bothered with complicated solutions. I searched and searched for alternatives to this fine gem, but none were found. Then it hit me: why not just write my own code and replace the inputs with my own code? Surely it can’t take too long to build a time input based on the simple_time_select gem! So here it is: my simple version of the gem, with only a few modifications from the simple_time_select gem.

Here is my old code, utilizing simple_time_select. The gem is used only if :simple_time_select is true, and it uses the :minute_interval, :time_separator, :start_hour, :end_hour, and a host of other options for setting the times. I wish it had a way for specifying just a start_time and end_time.

  1. <div class="field">
  2.   <%= f.input :start_time,
  3.               :label=>"Start Time:",
  4.               :default=>appt.start_time,
  5.               :wrapper=>false,
  6.               :simple_time_select => true,
  7.               :label_html=>{:class=>"head"},
  8.               :minute_interval => 5,
  9.               :time_separator => "",
  10.               :start_hour => 06,
  11.               :end_hour => 17
  12.    %>
  13. </div>

I had to search for an algorithm to use for the periodicity, and settled on the algorithm discussed in this discussion on Stack Overflow, and is inlined as the :collection option. Since the :default option removes the inital blank I wanted as the first item in the list, I has to add a blank :include_blank option.

  1. <div class="field">
  2.   <%- time_start = Time.now.change(:hour=>6,:minute=>0) %>
  3.   <%- time_end = Time.now.change(:hour=>17,:minute=>55) %>
  4.   <%- period = 5.minutes %>
  5.   <%= f.input :start_time,
  6.            :as=>:collection_select,
  7.            :required=>true,
  8.            :include_blank => ,
  9.            :selected=>(
  10.              f.object.start_time.blank? ?
  11.                "" : f.object.start_time.strftime("%H:%M")
  12.            ),
  13.            :input_html=>{
  14.              :name=>"appt[start_time(5i)]",
  15.              :id=>"appt_start_time_5i"},
  16.            :collection=> (
  17.              [time_start].tap{
  18.                |array| array << array.last + period
  19.                  while array.last < time_end
  20.              }).map{
  21.                |t| [t.strftime("%l:%M %p"), t.strftime("%H:%M")]
  22.              }
  23.    %>
  24. </div>

I am sure you can wrap this in a Helper class somewhere, and it should be easy to monkeypatch ActiveView or SimpleForm to display this instead of the default.

References:

Simple Rails Development Part I: Gedit Click Config

Thursday, August 30th, 2012

After evaluating all editors and IDEs I could ahold of for Ruby On Rails development in Linux, I decided none were really up to my expectations. I was really looking for something as powerful for Rails development as Eclipse is for Java development. Unfortunately, there were not any. Most of them were close, but all lacked some key ingredient necessary to make my life a little easier. However, I did find a great solution which required learning a little more about an undiscovered basic text editor in Fedora: GEdit. In order to make my rails development a little easier, I installed a few plugins, but only one of them took me by surprise: Click Config.

NOTE: This article is written for GEdit 3+. A simple Google search will yield many articles for Gedit 2.

Most IDEs and editors have different functions when multi-clicking in an editor pane. Most of them have the following selection actions:

  • Single-Click: Move the editing cursor to the mouse cursor’s location
  • Double-Click: Select the word that is under the mouse cursor
  • Triple-Click : Select the entire line that is under the mouse cursor

Only a few editors have a quad-click option for selecting an entire paragraph. GEdit Click Config not only has a quad-click option, but has a quit-click (five clicks in quick succession) option as well. Amazing! Not only can you configure what click-types are available in GEdit, but you can configure the click parameters based on a given regular expression (“regex” for short). And to top it all off, you can configure which click options are activated based on what language GEdit is set to.

I Gotta Have It!

I have not found a distro yet which ships with GNOME and does not have GEdit as well, so it should be in your local *nix distro’s repository or already installed it.  If you don’t have it already, you can pick it up at http://code.google.com/p/gedit-click-config/, and it doesn’t require root access, so setup should be really simple, just follow the directions.

You mentioned Ruby on Rails?

Yes… yes I did.  You can find out more about Ruby words, constants, and other things here. Ruby words are pretty simple: they:

  1. can begin with a single $ sign 
  2. can begin with a single or double @ sign, a
  3. can contain any letter a-z, case insensitive

I like to add a fourth rule, just for constants, because when i select a part of a constant, i want the whole thing: can contain two colons in a row.

To put all that in simple regular expressions: ((\$?)|(@?@?))([_a-zA-Z]+(::)?)+. I am sure you can write that in a thousand different ways, but that is the one I like best, because it is really clear what is going on. Also – the matches almost line up at \2,\3,\4.\5 This regex should be newly defined in the Click Config settings. You can get there by menu, at Edit->Click Config->Configure. You can create a new selection rule by adding it in the only editable inoput field at the bottom, clicking the “Add” button and entering a name for it. I suggest using “Ruby Word” for the name.

I also find myself moving ruby strings around a lot. Wouldn’t it be great if you could just triple-click and select the entire string? With GEdit Click Config, you can! All you have to do is create a new selection rule, with the following regular expression: (['"]).*?\1. Make sure to check the ‘M’ flag to the right of the input field, in prder to make it multi-line, if you wish. To break down the pattern, the first paren matches either single- or double-quotes. Then match anything until you get to the next single- or double-quote. The ‘\1′ means to match the value from the first parenthetical match, so the quotes will line up properly. The ‘.*?’ means to match anything, but only until the next regex portion matches. If we leave out the question mark, we will match anything until the last next-character match, This is called a non-greedy search, and is necessary for this type of pattern-matching.

Come Together

I hope you learn to enjoy some of the basics as I have. To close this entry out, I will list all the Click Configs I have for all my Languages:

Selection Rules

  • Ruby Word: ((\$?)|(@?@?))([_a-zA-Z]+(::)?)+    (Flags: None)
  • Full Quote: (['"]).*?\1   (Flags: M)
  • Single-Line Quote  (Flags: None)
  • Haml Word: (\.|\#|\$?|(@?@?))([_a-zA-Z]+(::)?)+

jQuery ThemeSwitcherTool – Working Version!!!!!

Sunday, March 6th, 2011

I recently tried to install the jQuery UI  ThemeSwitcher on a site for a project on which I am working. It failed. Miserably! I scoured the interwebs for a working version, but could not find one anywhere. However, I did find out why the tool was not working. It seems the jQuery team disabled hotlinking to its servers. This was extremely good news, as it meant I could simply recode the widget to point to the new files or download them and point the script to the downloaded files. I dove right in to the code and made some modifications to the start of the script. Then I optimized some of the rest of the code. Finally, I added a few extra options to cover the changes I made.

Download

You can click on the following links to download the files.

  • themeswitchertool.js – The themeswitcher.
  • The Following files are images used by themeswitcher. To use them, place them in /javascripts/jquery/themeswitcher/ or use the imageLocation option to point to the directory where these are stored.

Changes

  • The old script appended up to three styles to the document, then removed the first one. It now uses the selector “head link#ui-theme” to change the stylesheet. I changed this so you can set the id of your default custom theme to “ui-theme” and it will change this. If the id isn’t found, it creates a new one.
  • Added new options for specifying your own themes to add to the list.
  • Added new option, useStandard, for specifying whether to use the themes from the jQuery UI site.
  • Added new options for specifying where to find the UI icons and stylesheets
  • Added new option, imageLocation, for specifying where to find the widget images (found in the downloaded file)
  • Added the widget images to the downloaded file, so you don’t have to link to jQuery’s servers
  • Added option, useCookie, for whether to use a cookie for saving the theme for later use on the same page.

Examples

Basic usage, no custom theme support

  1. $(‘<div id="theme-switcher"></div>’).prependTo(‘body’).themeswitchertool( );

Adding custom themes

  1. $(‘<div id="theme-switcher"></div>’).prependTo(‘body’).themeswitchertool( {
  2.     themes: {
  3.        ‘theme1′: {
  4.            icon:"/path/to/theme-icon.png",
  5.            css:"/path/to/theme.css"
  6.        },
  7.        ‘theme2′: {
  8.            icon:"/path/to/theme2-icon.png",
  9.            css:"/path/to/theme2.css"
  10.        }
  11.     }
  12. });

Using Only Custom Themes

  1. $(‘<div id="theme-switcher"></div>’).prependTo(‘body’).themeswitchertool( {
  2.     useStandard: false,
  3.     themes: {
  4.        ‘theme1′: {
  5.            icon:"/path/to/theme-icon.png",
  6.            css:"/path/to/theme.css"
  7.        },
  8.        ‘theme2′: {
  9.            icon:"/path/to/theme2-icon.png",
  10.            css:"/path/to/theme2.css"
  11.        }
  12.     }
  13. });

New Options

themes
Default: {}
A hash of themes, where each key is the theme name, and the value is another hash specifying the icon to use and the css file for the theme. Here is an example:

  1. {
  2.   ‘theme1′: {
  3.     icon:"/path/to/theme-icon.png",
  4.     css:"/path/to/theme.css"
  5.   }
  6. }
useStandard
Default: true
If you don’t want the themes from the jQuery UI site to show up in the list, set this to false.
useCookie
Default: true
The Theme Switcher uses a browser cookie to store and retrieve the theme name for the current site. Set this option to false if you do not want your site to remember the theme.
imageLocation
Default: “/javascripts/jquery/themeswitcher/”
This is where the images are stored which Theme Switcher uses. The following files must be in the folder: buttonbg.png, icon_color_arrow.gif, menuhoverbg.png . You can get these from the download.
imgPrefix
Default: “http://static.jquery.com/ui/themeroller/images/themeGallery/theme_90_”
This option specifies the default icon prefix URI. The icons are the previews for each theme. The default option sets the default images to the jquery hotlink site. This may change in the future, so it is specified here as an option.
imgSuffix
Default: “.png”
This option specifies the rest of the image URI.
cssPrefix
Default: “http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/”
This option specifies the deafault css location prefix.
cssSuffix
Default: “/jquery-ui.css”
This option specifies the deafault css location sufffix.

New Theme Under Construction…

Friday, July 31st, 2009

Hello, all RBS followers! I am creating a new theme for WordPress called Bubbly Blue, which is part of my Bubbly Blue theme series. So far I have only one other – an Ampache theme. I am using this blog as a testing area for this theme, so please be patient if something goes horribly awry!

Thank you all!

Updated August 9:

Here are some features of my theme so far:

  • Three-Layer Header for more customization! = The background layer is for gradients, etc. The Logo layer is for your logo. The FX layer is for added graphics to enhance the other layers.
  • A top menu, which can show all pages as tabs. Also doubles as a sidebar.
  • Three sidebars: one dropdown menu and two sidebars on either side of main content area. These can be turned on/off in the options panel.
  • W3C standards-compliance. A graphic link has been added to the footer so you can just click to test
    the validity of each page.

My theme is almost complete! Still left to do:

  • Move header text over when logo is enabled/disabled
  • Fix Comments/Respond tabs on posts
  • Create Default sidebar widgets if dynamic widgets are not available
  • Add login form to header/sidebar and add option for which to use.
  • Resize content area when sidebars are turned off.
  • Curve corners of header, footer and sidebars
  • Sort Through and optimize Stylesheet
  • Ajax-ify Comments
  • Three-Layer header options panel.
  • Remove unused php files / consolidate php files
  • Cleanup code!
  • More Testing!

How To Repair Images with ImageMagick

Monday, June 15th, 2009

I have been doing a lot of importing of photos on my photo site, and have noticed some images do not display properly. SinceI love ImageMagick so much,  I set up  my gallery to use it. However, there appears to be a check in the Coppermine software that aborts reading the file upon errors in the image. So I typed the command “display imagename.jpg” for some of the files that did not import properly, and everything appeared to be fine. But I did notice something peculiar about the images: they were taken with my phone’s camera and all had errors printed out when I tried to open them, but seem to display correctly.

Since these files could be opened by ImageMagick, I figured if I saved them again, I would be able to fix the errors. I ran “convert image1.jpg image1.jpg”, got the familiar errors printed and opened the file again. This time, no errors! But since I have a  lot of files I want to import, I needed a way to convert a bunch at once.

I created a neat little Perl script to do just that. All you need is ImageMagick and perl installed. This script does not rely on PerlMagick, as it runs the convert command. So here it is:

  1. #!/usr/bin/perl
  2.  
  3. processFile("$_") foreach (@ARGV);
  4.  
  5. #recursively fix images
  6. sub processFile {
  7.    my $file=shift;
  8.    return (-d "$file")?( do{ processFile("$_") foreach (<"$file"/*>) }) : `convert "$file" "$file"`;
  9. }

I saved this file as $HOME/bin/fiximage. All you need to do to run it is type “fiximage file1 file2 directory1 directory2 …”. One other thing to note is that this script has been purposefully shortened. I like to use the ternary operator whenever possible in my scripts for just this reason. As such, it does not print anything to the command line itself, but if the convert command encounters an error, that will be printed.

I hope you have found this article useful!

Fun With Numbers!

Friday, May 29th, 2009

I have always had a certain love for math and the neat things you can do with it. Here is a bit of information and shortcuts I have picked up in a few of my math classes.

Pascal’s Triangle

Pascal’s Triangle is a pretty neat thing. It is very simple to construct and can be used to understand a lot of different ideas. It follows a very simple form: start with a ’1′ and add the two digits above  to get the next number. The first few line look like this:

1
1  1
1  2  1
1  3  3  1
1  4  6  4  1
1  5 10 10  5  1
1  6 15 20 15  6  1

The line numbers start at 0, and continue on ad infinitum. In order to generate this triangle, programmatically, you would use something like this:

  1. vector<int> pascal(
  2.       vector<int> prev, //the current (old) row data
  3.       int *len,           //the length of the data
  4.       int end,                    //the row to retrieve
  5.       int cur=0           //the current row we are on
  6.       );
  7.  
  8. vector<int> pascal(vector<int> prev,int *len,int end,int cur){
  9.  
  10.        //return immediately if we are at the last row
  11.       if (cur==end) return prev;
  12.  
  13.            //if the current vector length is 0, then set it to 1
  14.           if (*len==0) *len=1;
  15.  
  16.           //create a temp vector (all 1′s) to store the new row data
  17.           vector<int> t((*len)+1,1);
  18.  
  19.           //sum the two rows
  20.           for(int i=1;i<(*len);i++)
  21.             t[i]=prev[i-1]+prev[i];
  22.  
  23.           //increase the length by 1
  24.           *len=(*len)+1;
  25.  
  26.           //return the new row data
  27.           return pascal(t,len,end,cur+1);
  28.  
  29. }

Binomial Expansion

Remember binomials from algebra? They were the pair of numbers used to create or simplify polynomial expressions, something like:

( x + 3 )^3 = x^3 + 9x^2 + 27x + 27

You can use Pascal’s triangle to find the coefficients of the polynomials. Let’s begin by solving for the generic case:

(a+b)^n =
(a+b)^{n-1}(a+b) =
(a+b)^{n-2}(a+b)^2 =
(a+b)^{n-2}((a+b)(a+b)) =
( (a*a) + (a*b) + (b*a) + (b*b) )(a+b)^{n-1} =
(a^2+2ab+b^2)(a+b)^{n-1} =

See the coefficients so far, with n=2 ? They are [1 2 1], which corresponds to the second row in Pascal’s triangle. But this could be a fluke, right, so let’s jump ahead to n=5 to see if that works as well.

(a+b)^n =
(a+b)^{n-6}(a+b)^5 =
(a+b)^{n-6}( (a+b) (a+b) (a+b) (a+b) (a+b) ) =
(a+b)^{n-6}( ( (a+b)(a+b) )( (a+b)(a+b) ) (a+b) ) =
[we know what (a+b)^2 is, so: ]
(( a^2+2ab+b^2 )( a^2+2ab+b^2 )(a+b) )(a+b)^{n-6} =
( ( (a^2*a^2)+(a^2*2ab) + (a^2*b^2) + ( 2ab*a^2) + (2ab*2ab) +
    (2ab*b^2) + (b^2*a^2)+(b^2*2ab) + (b^2*b^2) ) (a+b) )(a+b)^{n-6} =
( ( a^4 + 2a^3b+ a^2b^2 + 2a^3b + 4a^2b^2 + 2ab^3 + b^2a^2 + 2ab^3+ b^4) (a+b) )(a+b)^{n-6} =
( ( a^4 + 4a^3b + 6a2b^2 + 4ab^3+b^4) (a+b) )(a+b)^{n-6} =
[note: notice that the coefficients of (a+b)^4 are (1 4 6 4 1) ! ]
( ( a^4*a + a^4*b + 4a^3b*a + 4a^3b*b + 6a^2b^2*a + 6a^2b^2*b + 4ab^3*a + 4ab^3*b + b^4*a+b^4*b))(a+b)^{n-6} =
( ( a^5 + a^4b + 4a^4b + 4a^3b^2 + 6a^3b^2 + 6a^2b^3 + 4a^2b^3 + 4ab^4 + ab^4+b^5))(a+b)^{n-6}=
( ( a^5 +5a^4b + 10a^3b^2 + 10a^2b^3 + 5ab^4 + b^5)(a+b)^{n-6}

There it is! The coefficients correspond to the rows on Pascal’s Triangle!

Features

Now, to make things a little simpler, I will note some interesting “features” about what we just did.

General Formula for Binomial Expansion

The general formula for binomial expansion is:

(a+b)^n = \sum_{i=0}^{n}(P_{ni}a^{n-i}b^i)

Where P_{ni} is the coefficient at row n (starting from 0) and column i in Pascal’s Triangle. The formula means to add from i=0 to n all the terms (P_{ni}a^{n-i}b^i) , replacing i with the number you are at. For example, supposing i=3, you would get:

\sum_{i=0}^{3}(P_{3i}a^{3-i}b^i) =
(P_{(3,0)}a^{3-0}b^0) + (P_{(3,1)}a^{3-1}b^1) + (P_{(3,2)}a^{3-2}b^2) + (P_{(3,3)}a^{3-3}b^3) =
since P_3 = [1 3 3 1] , we finally get:
((1)a^{3-0}b^0) + ((3)a^{3-1}b^1) + ((3)a^{3-2}b^2) + ((1)a^{3-3}b^3)
cleaning up a bit :
a^3 + 3a^2b + 3ab^2 + b^3

Exponents

Note in all the expansions, the first variable counts down from n to 0, while the second variable counts up from 0 to n.

Does your binomial already have coefficients?

If your binomial already has coefficients, simply add the coefficient in with the variable it is with, so it merely multiplies the term by that amount. For example:

(3a+b)^3 =

jQuery Style Sheet (CSS) Switcher

Wednesday, April 1st, 2009

I have been looking for a nifty style-switching script, and have found none. So here is the code for a checkbox-based style switcher. This uses jQuery.

The Javascript:

  1. /*ChangeStyle.js:
  2. * -by Skaman Sam Tyler – http://rbe.homeip.net
  3. *
  4. * This script uses checkboxes to add and remove stylesheets from the page.
  5. * It takes the value of the ‘rel’ attribute from the checkbox and creates a stylesheet link with it.
  6. * */
  7.  
  8. if ($) {    //check for jQuery
  9.  
  10.   //on document load, uncheck all checked boxes and add function handler for
  11.   $(document).ready( function() {
  12.     $(‘.styleToggle’).removeAttr("checked");    //uncheck all checked
  13.     $(‘.styleToggle’).click( function() {        //add handler for clicking
  14.       toggleStyle(this.getAttribute("rel"));
  15.       return true;
  16.     });
  17. });
  18.  
  19. //the toggling of the style. it takes a single parameter: the href of the stylesheet to toggle
  20. function toggleStyle(href) {
  21.  
  22.   //check for presence of link, if it exists, delete it, else, add it.
  23.   if($(‘link[href*='+href+']‘).size()!=0){
  24.     $(‘link[href*='+href+']‘).remove();
  25.   }else{
  26.     console.log("Adding: "+$(‘link[href*='+href+']‘));
  27.     $(‘head’).append(‘<link rel="stylesheet" href="’+href+‘" type="text/css" media="screen" />’);
  28.   }
  29. }
  30. }

The HTML file should include something like this:

  1. <form name="styleSwitchForm">
  2. <li><label><input type="checkbox" rel="/styles/red.css" class="styleToggle"/> Red Style</label></li>
  3. <li><label><input type="checkbox" rel="/styles/blue.css" class="styleToggle"/> Blue Style</label></li>
  4. <li><label><input type="checkbox" rel="/styles/green.css" class="styleToggle"/> Green Style</label></li>
  5. </ul>
  6. </form>
  7.  

Installing Aptana in Fedora Eclipse

Saturday, February 14th, 2009

Aptana is a wonderful tool for web design. I have been using it for years for my personal web sites and my professional ones. I have been trying to get more people turned on to it, as well. When I installed Fedora 10 recently, I didn’t want to install Aptana, as it has, in the past, FooBar’d my Eclipse installation. However, I am learning Ruby (on rails), and want to install RadRails, which means I need Aptana. I thought about installing Aptana standalone, but don’t want to start up a new Eclipse platform just for my rails development. So -

First, I tried to install Aptana normally, as an eclipse plugin, several times. However, some parts of it refused to work and the “My Aptana” page never showed up. After assessing this problem, I thought there may be conflicts with some of the plugins Fedora installs through yum. Ihad  installed all the Eclipse plugins that my yum repositories offered.

So I removed all the plugins using yum. Since I needed those plugins, I had to get the update sites to install in Eclipse. Here are the update sites for the rpms, for convenience. You can get the same information by checking the Fedora Eclipse project wiki at http://fedoraproject.org/wiki/Eclipse.

Keep Installed:

eclipse-ecj.x86_64
eclipse-demos.noarch
eclipse-platform.x86_64
eclipse-rcp.x86_64
eclipse-setools.x86_64
eclipse-shelled.noarch
eclipse-slide.noarch
eclipse-swt.x86_64
icu4j-eclipse.x86_64
tomcat5-jasper-eclipse.noarch

Install Using Aptana:

Subclipse (SVN Integration):
http://subclipse.tigris.org/update_1.4.x :

eclipse-subclipse*
Eclipse Git:
http://www.jgit.org/update-site/ :

eclipse-egit.noarch

Install Using The Update Manager:

Ganymede:
http://download.eclipse.org/releases/ganymede :

eclipse-cdt* (C and C++ Development)
eclipse-emf* (Model and Model Development)
eclipse-gef* (Graphical editors and frameworks)
eclipse-jdt* (Java development)
eclipse-mylyn* (Collaboration Tools)
eclipse-pde.x86_64 (Java Development/Eclipse plug-in development environment)

Maven Integration for Eclipse:
http://m2eclipse.sonatype.org/update-dev/
(stable development)
or http://m2eclipse.sonatype.org/update/ (stable)
maven2-plugin-eclipse.x86_64

Linux Tools for Eclipse:
http://download.eclipse.org/technology/linuxtools/update/ :

eclipse-changelog.x86_64
eclipse-rpm-editor.x86_64

Checkstyle Plugin:

http://eclipse-cs.sourceforge.net/update:

eclipse-checkstyle.x86_64

Eclipse Perl Integration:
http://e-p-i-c.sourceforge.net/updates/testing :

eclipse-epic.x86_64

Babel (milti-lingual support):
http://download.eclipse.org/technology/babel/update-site/ganymede :

eclipse-nls-*.noarch

Photran (fortran support):
http://download.eclipse.org/technology/photran/updates/eclipse3.4cdt5.0 :

eclipse-photran* (requires cdt plugin)

PHPEclipse (php):
http://phpeclipse.sourceforge.net/update/stable/1.2.x/ :

eclipse-phpeclipse.x86_64

Pydev (python):
http://pydev.sourceforge.net/updates/ :

eclipse-pydev*

QuickRex (regular expression editor):
http://www.bastian-bergerhoff.com/eclipse/features :

eclipse-quickrex.noarch

Now you are ready to install the Aptana plugin, using this update site: http://update.aptana.com/install/studio/3.2/. I recommend installing Aptan before installing any of the previously mentioned plugins, for best compatability.

That’s it and good luck!

Drop-Down Menu with CSS

Monday, February 9th, 2009

This is the first post in a series of articles on web technologies I most commonly use. I will mostly use these posts as a central repository for my (X)HTML/CSS/Javascript/Perl/etc. code.

The CSS Drop-down Menu is fairly simple. It is simply a list with certain style attributes. We will begin by creating a simple XHTML page with a list for the menu, and a place for the styles. The names of the menu items must all be links.

  1. <?xml version="1.0" encoding="ISO-8859-1" ?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  6. <title>Drop-Down Menu Test</title>
  7. <style type="text/css">
  8. @import menu.css
  9. </style>
  10. </head>
  11. <body>
  12. <ul class="menu">
  13. <li><a href="#">Menu 1</a></li>
  14. <li><a href="#">Menu 2</a>
  15. <ul>
  16. <li><a href="#">Sub Menu 2.1</a>
  17. <ul>
  18. <li><a href="#">Sub Menu 2.1.1</a></li>
  19. <li><a href="#">Sub Menu 2.2.2</a></li>
  20. <li><a href="#">Sub Menu 2.3.3</a></li>
  21. <li><a href="#">Sub Menu 2.4.4</a></li>
  22. </ul>
  23. </li>
  24. <li><a href="#">Sub Menu 2.2</a></li>
  25. <li><a href="#">Sub Menu 2.3</a></li>
  26. <li><a href="#">Sub Menu 2.4</a></li>
  27. </ul>
  28. </li>
  29. <li><a href="#">Menu 3</a>
  30. <ul class="submenu">
  31. <li><a href="#">Sub Menu 3.1</a></li>
  32. <li><a href="#">Sub Menu 3.2</a></li>
  33. <li><a href="#">Sub Menu 3.3</a></li>
  34. <li><a href="#">Sub Menu 3.4</a></li>
  35. </ul>
  36. </li>
  37. <li><a href="#">Menu 4</a></li>
  38. </ul>
  39.  
  40. </body>
  41. </html>

That’s all for the HTML! we’re only going to be dealing with the CSS from now on, which are placed in the file named ‘menu.css’. If you want to change the name, make sure you change the @import statement in the css in the header to point to the appropriate file.

Next, we want to apply our styles. The first styles we’ll create are for the actual mechanics of the menu: the showing and hiding of the items.

  1. .menu li>ul,.menu li>ol { display: none; }                                /*hide all submenus*/
  2. .menu li:hover>ul,.menu li:hover>ol { display: block; }    /*show all submenus on hover*/
  3.  

That’s it! That’s all there is to a really, really simple drop-down menu. No-frills, no fuss.

Problem 1: Internet Explorer

The previous solution only seems to work on Firefox, Opera, Safari, Konqueror, and all other KHTML and Mozilla-based browsers. What if we want to work with Internet Explorer? It seems we have to get dirty, since IE is not standards-compliant. One way to get IE on the train  is to use conditional comments. A conditional comment is something M$ invented because their browsers aren’t compatible with each other. Conditional comments only work on Internet Explorer.

  1. <!–[if IE 6]>
  2. @import menu_ie6.css
  3. <![endif]>
  4. <!–[if IE 5.5]>
  5. @import menu_ie55.css
  6. <![endif]>
  7. <!–[if IE 5]>
  8. @import menu_ie5.css
  9. <![endif]>
  10.  

You can also test ranges by using:

  1. <!–[if gte IE 5]>
  2. @import menu_ie.css
  3. <!–[else]>
  4. </style>
  5. <script type="javascript">
  6. //menu code in Javascript
  7. </script
  8. <style type="text/css" >
  9. <![endif]>
  10.  

This code tests if we are using IE 5 or greater, and if so, imports the IE5-relevant stylesheet. If the browser is less than IEv5, it closes the style tag, opens a javscript
tag which inserts a comment to do the dropdown meu in javascript. DO NOT, under any circumstances put the previous code on your web site. Nasty things will happen if you do!

That was just an example of conditional comments. Now on to our use of them.

Ugly!

The styles are pretty ugly so far, and have some serious alignment issues. This makes it pretty hard to select the submenus. The first thing we want to do is make sure the menus appear above all other elements on the page.

  1. /*all submenus*/
  2. .menu li>ul,.menu li>ol {
  3. float: left;
  4. margin-left: 0px;
  5. margin-top: -1.1em;
  6. list-style-type: none;
  7. position: absolute;
  8. background-color: #fffff;
  9. z-index: 10000;
  10. }

Installing Gentoo 2008 in (qemu) Sun’s VirtualBox on Fedora 10

Monday, February 2nd, 2009

I am currently taking a class on Operating System design and need to do some kernel hacking for the class. I thought about modifying the Fedora kernel, but decided against it, as I still want a stable system to operate in.So I looked into virtual machines, as Fedora has qemu and a nice graphical virtd client for managing virtual machines. While deciding on my mainstay distro (in 2000), I evaluated the gamut of Linux distros, so I decided to install Gentoo linux on my virtual machine because it rebuilds everyting on the fly.
I went to the Gentoo site and downloaded the minimal install CD for ia64. No luck here – it won’t even boot, just hangs.
Then I downloaded the minimal install CD for amd64. I got into the boot loader and booted the system, but it hung on the kernel module loading step.
I finally decided to try a LiveCD. This worked beautifully. However, I couldn’t start an X session, as the appropriate driver was not included on the CD. No real need, as I was installing it on my disk image. So I ran /opt/installer/bin/install and now it is installing fine. It is taking quite a while to install, however, and I hope to have it finished by the end of the day. (I have classes all day, and will resume install this evening.)

[more to come later...]

So I scrapped the idea of installing Gentoo on qemu. I t was just too slow and too much of a pain. So I decided to try out Sun’s VirtualBox for the first time. I really like it! On my machine, it is faster than qemu and VMWare. The reason for testing on VBox is that qemu doesn’t really support 64 bit OSs. I also wanted something that could take advantage of my hardware, and VMware does an OK job, but not at the level I want. It seems that VBox is everything I wanted, and i get speeds of almost the same as my host platform. I am running a benchmark program, nbench, and will post the results here when I finish.

nbench result for host OS (Fedora 10 x86_64 on Intel Core 2 Duo w/ 4Gb RAM):

BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
--------------------:------------------:-------------:------------
NUMERIC SORT        :          1165.6  :      29.89  :       9.82
STRING SORT         :          258.88  :     115.67  :      17.90
BITFIELD            :      4.6794e+08  :      80.27  :      16.77
FP EMULATION        :          251.44  :     120.65  :      27.84
FOURIER             :           25958  :      29.52  :      16.58
ASSIGNMENT          :          34.798  :     132.41  :      34.34
IDEA                :            7068  :     108.10  :      32.10
HUFFMAN             :          2325.1  :      64.48  :      20.59
NEURAL NET          :          50.819  :      81.64  :      34.34
LU DECOMPOSITION    :            1652  :      85.58  :      61.80
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 84.556
FLOATING-POINT INDEX: 59.082
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
CPU                 : Dual GenuineIntel Intel(R) Core(TM)2 Duo CPU     T8300  @ 2.40GHz 800MHz
L2 Cache            : 3072 KB
OS                  : Linux 2.6.27.12-170.2.5.fc10.x86_64
C compiler          : gcc version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC) 
libc                : libc-2.9.so
MEMORY INDEX        : 21.765
INTEGER INDEX       : 20.615
FLOATING-POINT INDEX: 32.769
Baseline (LINUX)    : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38
* Trademarks are property of their respective holder.

nbench result for Gentoo 2008 x86_64 on Sun VirtualBox (w/ 768 Mb RAM):

BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
--------------------:------------------:-------------:------------
NUMERIC SORT        :          1139.8  :      29.23  :       9.60
STRING SORT         :          250.16  :     111.78  :      17.30
BITFIELD            :      4.2657e+08  :      73.17  :      15.28
FP EMULATION        :          108.16  :      51.90  :      11.98
FOURIER             :           20163  :      22.93  :      12.88
ASSIGNMENT          :          34.385  :     130.84  :      33.94
IDEA                :            4207  :      64.34  :      19.10
HUFFMAN             :          2259.9  :      62.67  :      20.01
NEURAL NET          :          44.636  :      71.70  :      30.16
LU DECOMPOSITION    :          1589.6  :      82.35  :      59.46
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 67.742
FLOATING-POINT INDEX: 51.348
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
CPU                 : Dual GenuineIntel Intel(R) Core(TM)2 Duo CPU     T8300  @ 2.40GHz 2399MHz
L2 Cache            : 64 KB
OS                  : Linux 2.6.27-gentoo-r8
C compiler          : x86_64-pc-linux-gnu-gcc 
libc                : 
MEMORY INDEX        : 20.781
INTEGER INDEX       : 14.479
FLOATING-POINT INDEX: 28.480
Baseline (LINUX)    : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38
* Trademarks are property of their respective holder.