| # Practical scripts This section will show examples on how scripts can enhance your album in really cool ways. The examples here makes use of the huge library of ready-made java classes that Sun has provided for free and are directly accessible. To better understand the examples and to assist in the writing of your own scripts I strongly recommend that you first read the creating skins section, then bookmark the basic Java API from Sun and use it to look up classes and their methods. If you are new to Java I recommend tutorials and that you then concentrate on the "java.lang", "java.util" and "java.io" packages. They are the ones that are most commonly used. Remenber that you can turn to the forum to get help and help others! If you don't have any programming ambitions, fine. Just copy and paste the examples below to the slide.htt and index.htt files of the skin you wish to enhance. There is a tutorial that covers editing these files that you can check out first. Extra slide pages for original images Adding voice annotations Converting focal length to 35mm equivalent Google-like links to images Multilevel parent links Reading captions/comments from separate text files ### Extra slide pages for original images When clicking on an image in a slide show, you may get to the original image, but it is not displayed in a html page of its own. The downside of this is that the surroundings for the image doesn't match the skin (usually displayed on white background) and you have to use the back navigation button to return. Take a look at the new "Smart" skin in the extras section that addresses this issue by some lines of BeanShell scripting. The skin has an extra template file called "originalslide.htt". The following simple adjustment to the "slide.htt" file will make sure that the "originalslide.htt" file gets processed if needed:
    <!-- Image, maybe with link to original -->
    <ja:if exists=originalPath>
    <!-- Create a slide page for the original image too
    and link to that one instead of linking to an image -->
    <%
      String originalPage = originalPath;  // Default if no extra template page
      File template = new File(skinDirectory, "originalslide.htt");
      if (template.exists()) {
        originalPage = label+"_orig"+engine.getPageExtension();
        engine.processTemplateFile(template,
         new File(outputDirectory,"slides/"+originalPage));
      }
    %>
      <A HREF="<%=originalPage%>">
        <IMG SRC="$imagePath" WIDTH="$imageWidth" HEIGHT="$imageHeight" BORDER=0>
      </A>
    </ja:if>
### Adding voice annotations Many digital cameras allow you to add voice annotations to images. The camera usually puts a wav file next to the image bearing the same base name as the image. This script will make JAlbum look for these wav files and insert a BGSOUND tag if there is an annotation. Put the script just after the body tag of a slide.htt file.
    <!-- add and play voice annotations (.wav files) if they exist -->
    <%
      import se.datadosen.util.IO;
      File sound = new File(imageDirectory, label+".WAV");
      if (sound.exists()) {
        // Make a copy if needed
        String soundPath;
        if (!outputDirectory.equals(imageDirectory) && engine.isCopyOriginals()) {
          IO.copyFile(sound.getAbsolutePath(), outputDirectory, true);
          soundPath = "../" + sound.getName();
        }
        else soundPath = IO.relativePath(sound, new File(outputDirectory, "slides"));
        out.println("<BGSOUND SRC=\"" + soundPath + "\">");
      }
    %>
### Converting focal length to 35mm equivalent Some users prefer to list the focal length of the camera ($focalLength) as its 35mm equivalent value. Here are two scripts that does the conversion for you. In theory, converting is just a matter of muliplying the focal length with a factor that you can get from your camera manual (the factor varies between camera models), but in JAlbum the focalLength variable is a formatted string including "mm" at the end which can't take part in a multiplication. The follwing script takes care of that by stripping non-numeric parts of a value and converting the result to a floating point value. After that, converting is simply a matter of multiplication and rounding the result. Put these scripts into the slide.htt file of the skin you wish to use.
    <%!
    // Strip non-numeric ending on strings and convert result to float
    float numericPart(String s) {
      int i;
      for (i=0; i<s.length(); i++) {
        char c = s.charAt(i);
        if (!Character.isDigit(c) && c != '.') break;
      }
      return Float.parseFloat(s.substring(0,i));
    }
    %>
...And this is the code that displays the converted value (example for a Canon PowerShot G1 camera having 4.857 as conversion factor).
    <ja:if exists="focalLength">
    35 mm equivalent: <%= (int)(numericPart(focalLength) * 4.857 + 0.5) /* PowerShot G1 */ %>
    </ja:if>
### Google-like links to images For quick navigation between images, a list of numbered links might be preferred to just having previous and next buttons. Put this script inside a slide.htt file for the Google effect. The "Chameleon" skin makes use of this effect. Script now updated to show only a set of links at a time.
    <% // Produce links to all other pages, cooler than just next, previous links
      int maxLinks = 20;  // Max number of links to display at the same time
      int start = (imageNum-1)/maxLinks*maxLinks - 1;
      if (start < 0) start = 0;
      for (int i=start; i<files.length && i<start+maxLinks+2; i++) {
        Map vars = (Map)fileVariables.get(files[i]);
        if (i+1 != imageNum) out.print("<a href=\"" + vars.get("currentPage") + "\">");
        else out.print("<b>");
        out.print(" " + (i+1));
        if (i+1 != imageNum) out.print("</a>");
        else out.print("</b>");
      }
    %>
### Multilevel parent links You might have an album with many nested folders (animals/mamals/cats...) In this case it helps a lot to have all folder names displayed like this: animals » mamals » cats (being in the "cats" folder), with links to each parent folder. Copy and paste the two scriptlets below for this effect. The first goes into index.htt and the second into slide.htt:
    <!-- Multilevel index links for index page -->
    <%!
      void writePath(File dir, String prefix, int level) {
        if (level > 0)
          writePath(dir.getParentFile(), prefix + "../", level-1);
        if (level > 0) out.print(" » ");
        if (prefix.length() > 0)
          out.print("<a href=\"" + prefix + engine.getIndexPageName()
           + engine.getPageExtension() + "\">");
        else out.print("<a href=\"" + indexPage + "\">");
        System.out.println(dir);
        out.print((level == 0 ? album.get("rootName") : dir.getName()) + "</a>");
      }
    %>
    <%
      if (album.get("rootName") == null) album.put("rootName", title);
      writePath(imageDirectory, "", level);
    %>
    <!-- Multilevel index links for slide pages -->
    <%!
      void writeSlidePath(File dir, String prefix, int level) {
        if (level > 0)
          writeSlidePath(dir.getParentFile(), prefix + "../", level-1);
        if (level > 0) out.print(" » ");
        if (prefix.length() > 0)
          out.print("<a href=\"../" + prefix + engine.getIndexPageName()
           + engine.getPageExtension() + "\">");
        else out.print("<a href=\"../" + indexPage + "\">");
        System.out.println(dir);
        out.print((level == 0 ? album.get("rootName") : dir.getName()) + "</a>");
      }
    %>
    <%
      if (album.get("rootName") == null) album.put("rootName", title);
      writePath(imageDirectory, "", level);
    %>
### Reading captions/comments from separate text files Some people wonder if it is possible to have JAlbum insert the contents of a text file having the same base name as an image but with ".txt" extension, for example "hiking.jpg" will get text from "hiking.txt". This is simple to do with the following scriptlet:
    <!-- Extract text from textfiles carrying the same base name as this image -->
    <ja:include page="<%= new File(imageDirectory, label+".txt") %>" />