#!/usr/bin/perl # Filename: simmer_theme # Author: David Ljung Madison # See License: http://MarginalHacks.com/License my $VERSION= '3.03'; # Description: Builds a theme based on: # 1) A group of icons following the same names of Dave Simmer's basic themes # 2) Optional files: Font, CREDIT # # Documentation: Ha! # # CHANGELOG # --------- # # Version 3.03, 2005/01/20 # ------------------------ # + Started to keep a changelog # + Initial Overlay support # ......Overlay($img,'thumb', 'full', $Overlay) if Get($img,'thumb', 'x') # * Fixed tag HTML problem # # Version 3.02, 2004/??/?? # ------------------------ # + Allow for IBord_* image borders (different from thumbnail borders) # # Version 3.01, 2004/??/?? # ------------------------ # + Added Pretty(), New_Row() code - new API support functions # + New stretchable bar code # # Version 3.00, 2004/07/27 # ------------------------ # + Converted to album v3.0 API, big cleanup # + Added Locked.gif support # # Version 2.01, 2004/05/28? # ------------------------ # + Initial use of album Border API function # + Cleanup with get_img, Image_Array functions # + Renamed Bord_* to ThBord_* # # Version 2.00, 2003/11/17 # ------------------------ # + Made HTML valid (removed , fixed tags, etc..) # # Version 1.16, 2002/10/29 # ------------------------ # + Converted to Theme_URL() (allowing for -theme_url option) # + img_src allows for alt tags now # + Some code cleaning # # Version 1.15, 200?/??/?? # ------------------------ # + First revision control release use strict; use Cwd 'abs_path'; my $PROGNAME = $0; my $THEME_DIRECTORY = "/Themes"; my $CONVERT = "convert"; my ($HEADER,$ALBUM,$IMAGE); # Image size sub get_size { my ($img) = @_; return (0,0) unless (-f $img); print STDERR "get_size() run: $CONVERT -verbose $img /dev/null\n" if ($MAIN::DEBUG); open(SIZE,"$CONVERT -verbose \Q$img\E /dev/null 2>&1 |") || die("[$PROGNAME] Couldn't run convert! [$CONVERT]\n"); while() { print STDERR "get_size(): $_" if ($MAIN::DEBUG); if(/\s(\d+)x(\d+)(\s|\+)/) { close(SIZE); return ($1,$2); } } print STDERR "[$PROGNAME] Can't get [$img] size from 'convert -verbose' output\n"; die("\n"); } my @SET; my @BORD; my @IBORD; my @OPTIONS; #my %GOT; sub get_img { my ($path,$img,$use_x,$use_y) = @_; my ($x,$y) = get_size("$path/$img"); return (0,0) unless $x && $y; $use_x = $use_x || $x; $use_y = $use_y || $y; my $arr = $img; $arr =~ s|\.[^\.]+$||; # Use \$PATH instead of $path! push(@SET, " \@$arr = (\"\$PATH/$img\", $use_x, $use_y);\n"); #$GOT{$img} = ($x&&$y) ? 1 : 0; return ($x,$y); } sub fix_names { my ($path) = @_; sub my_rename { my ($path,$old,$new) = @_; rename("$path/$old","$path/$new") if (-f "$path/$old" && !-f "$path/$new"); } # Icons my_rename($path,"alb_bak.gif","Back.gif"); my_rename($path,"nav.gif", "Back.gif"); my_rename($path,"alb_mor.gif","More.gif"); my_rename($path,"alb_nam.gif","Icon.gif"); my_rename($path,"ico.gif", "Icon.gif"); my_rename($path,"alb_nex.gif","Next.gif"); my_rename($path,"alb_prv.gif","Prev.gif"); # Bar my_rename($path,"bar_lef.gif","Bar_L.gif"); my_rename($path,"bar_mid.gif","Bar_M.gif"); my_rename($path,"bar_rig.gif","Bar_R.gif"); # Thumbnail borders my_rename($path,"th_top.gif","Bord_T.gif"); my_rename($path,"th_tlf.gif","Bord_TL.gif"); my_rename($path,"th_trt.gif","Bord_TR.gif"); my_rename($path,"th_bot.gif","Bord_B.gif"); my_rename($path,"th_blf.gif","Bord_BL.gif"); my_rename($path,"th_brt.gif","Bord_BR.gif"); my_rename($path,"th_lef.gif","Bord_L.gif"); my_rename($path,"th_ltp.gif","Bord_LT.gif"); my_rename($path,"th_lbt.gif","Bord_LB.gif"); my_rename($path,"th_rig.gif","Bord_R.gif"); my_rename($path,"th_rtp.gif","Bord_RT.gif"); my_rename($path,"th_rbt.gif","Bord_RB.gif"); my_rename($path,"ThBord_T.gif", "Bord_T.gif"); my_rename($path,"ThBord_TL.gif","Bord_TL.gif"); my_rename($path,"ThBord_TR.gif","Bord_TR.gif"); my_rename($path,"ThBord_B.gif", "Bord_B.gif"); my_rename($path,"ThBord_BL.gif","Bord_BL.gif"); my_rename($path,"ThBord_BR.gif","Bord_BR.gif"); my_rename($path,"ThBord_L.gif", "Bord_L.gif"); my_rename($path,"ThBord_LT.gif","Bord_LT.gif"); my_rename($path,"ThBord_LB.gif","Bord_LB.gif"); my_rename($path,"ThBord_R.gif", "Bord_R.gif"); my_rename($path,"ThBord_RT.gif","Bord_RT.gif"); my_rename($path,"ThBord_RB.gif","Bord_RB.gif"); my_rename($path,"nul.gif","Null.gif"); my_rename($path,"spacer.gif","Null.gif"); print "Warning: Missing Null.gif\n" unless (-f "$path/Null.gif"); } sub get_settings { my ($path) = @_; my $name = abs_path($path); $name =~ s|.*/||; push(@SET, " # Path setting - this is the path to the images\n"); push(@SET, " \$PATH = Theme_URL();\n"); if (-f "$path/Style.css") { push(@SET, " \$CSS = \"\";\n"); } push(@SET, "\n"); if (open(FONT,"<$path/Font")) { while () { (/^\s*(#c)?\s*(\/\/)?\s*options?:\s*(\S.*)/i) ? push(@OPTIONS, $_) : push(@SET, $_); } close FONT; push(@SET, "\n"); } else { print "Warning: Missing $path/Font\n"; } push(@SET, " # Icons/graphics\n"); my (undef,$bar_H) = get_img($path,"Bar_L.gif"); my ($bar_ML,undef) = get_img($path,"Bar_ML.gif","'100%'"); get_img($path,"Bar_MR.gif","'100%'"); get_img($path,"Bar_M.gif",$bar_ML ? undef : "'100%'"); get_img($path,"Bar_R.gif"); get_img($path,"Icon.gif"); get_img($path,"Back.gif"); get_img($path,"Next.gif"); get_img($path,"Prev.gif"); get_img($path,"More.gif"); get_img($path,"Locked.gif"); #get_img($path,"Null.gif"); # Null is used as a spacer push(@SET, <<'END_SET'); sub Bar { my ($colspan) = @_; return unless @Bar_L; :> <: foreach my $bar ( \@Bar_L, \@Bar_ML, \@Bar_M, \@Bar_MR, \@Bar_R ) { next unless @$bar; my $width = $bar->[1] =~ /100%/ ? "" : " width=$bar->[1]"; print "\t\t\t\t\t\t\t\n"; } :>
"; print Image_Array(@$bar); print "
<: } END_SET # Overlays? if (opendir(D,$path)) { my @over = grep(/^Overlay/, readdir(D)); closedir D; if (@over) { push(@SET,"\n# Overlays\n"); @over = sort @over; foreach my $over ( @over ) { my ($x,$y) = get_size("$path/$over"); next unless $x && $y; push(@SET," push(\@Overlays, [\"\$PATH/$over\", $x, $y]);\n"); } # Random matching overlay code push(@SET,<<'OVERLAY'); # Come up with a 'distance' of ratio/size closeness sub OverlayErr { my ($x,$y,$overlay) = @_; my $ox = $overlay->[1]; my $oy = $overlay->[2]; my $err = abs($x-$ox)/$x; $err += abs($y-$oy)/$y; $err += abs(($x/$y)-($ox/$oy))/($x/$y); $err; } srand(time^$$); sub PickOverlay { my ($img, $type) = @_; my $x = Get($img,$type,'x'); return unless $x; my $y = Get($img,$type,'y'); # Find the lowest error my $besterr = undef; foreach my $overlay ( @Overlays ) { my $err = OverlayErr($x,$y,$overlay); next if defined $besterr && $besterr<$err; $besterr = $err; } # Now find a list of overlays that are close to that error $besterr *= 1.05; # Err or within 5% <- HEURISTIC! my @best = grep { OverlayErr($x,$y,$_) <= $besterr; } @Overlays; # Pick one randomly and apply it Overlay($img,$type,'full', $best[int(rand($#best+1))]); } OVERLAY push(@SET,"\n"); } } # Borders push(@BORD, "\n"); push(@BORD, " # Thumbnail border\n"); get_img($path,"Bord_LT.gif"); get_img($path,"Bord_RT.gif"); get_img($path,"Bord_LB.gif"); get_img($path,"Bord_RB.gif"); get_img($path,"Bord_L.gif"); get_img($path,"Bord_R.gif"); get_img($path,"Bord_TL.gif"); get_img($path,"Bord_TR.gif"); get_img($path,"Bord_BL.gif"); get_img($path,"Bord_BR.gif"); get_img($path,"Bord_T.gif"); get_img($path,"Bord_B.gif"); push(@BORD, "\n".' @Border = (\@Bord_TL,\@Bord_T,\@Bord_TR,\@Bord_RT,\@Bord_R,\@Bord_RB,\@Bord_BR,\@Bord_B,\@Bord_BL,\@Bord_LB,\@Bord_L,\@Bord_LT) unless @Border;'."\n"); # Are image borders different than thumbnail borders? unless (-f "$path/IBord_T.gif") { @IBORD = @BORD; return; } push(@IBORD, "\n"); push(@IBORD, " # Thumbnail border\n"); get_img($path,"IBord_LT.gif"); get_img($path,"IBord_RT.gif"); get_img($path,"IBord_LB.gif"); get_img($path,"IBord_RB.gif"); get_img($path,"IBord_L.gif"); get_img($path,"IBord_R.gif"); get_img($path,"IBord_TL.gif"); get_img($path,"IBord_TR.gif"); get_img($path,"IBord_BL.gif"); get_img($path,"IBord_BR.gif"); get_img($path,"IBord_T.gif"); get_img($path,"IBord_B.gif"); push(@IBORD, "\n".' @Border = (\@IBord_TL,\@IBord_T,\@IBord_TR,\@IBord_RT,\@IBord_R,\@IBord_RB,\@IBord_BR,\@IBord_B,\@IBord_BL,\@IBord_LB,\@IBord_L,\@IBord_LT) unless @Border;'."\n"); } sub can_simmer { #c// -- Auto generated by simmer_theme v$VERSION my ($path) = @_; unless (-f "$path/album.th") { return 1 if -f "$path/Bord_T.gif"; return 1 if -f "$path/th_top.gif"; return 1 if -f "$path/ThBord_T.gif"; return 0; } open(CHECK,"<$path/album.th") || return 0; my $simmered = grep(/Auto generated by .*simmer_theme/, ) ? 1 : 0; close(CHECK); $simmered; } sub album { my ($path) = @_; open(OUT,">$path/album.th") || die("Couldn't write $path/album.th"); print OUT @OPTIONS; print OUT $HEADER; print OUT @SET; print OUT @BORD; print OUT $ALBUM; close OUT; } sub image { my ($path) = @_; open(OUT,">$path/image.th") || die("Couldn't write $path/image.th"); #print OUT "#c// options: -image_sizes\n" if ($CORNERS); print OUT $HEADER; print OUT @SET; print OUT @IBORD; print OUT $IMAGE; close OUT; } sub main { my @themes = grep(-d $_, @ARGV); die("No theme args?") unless @themes; foreach my $path ( @themes ) { print "Theme: $path"; unless (can_simmer($path)) { print " [album.th is not a simmer_theme - skipping]\n"; next; } print "\n"; fix_names($path); get_settings($path); album($path); image($path); undef @SET; } } $HEADER = < #c// ################################################################### #c// Album Theme by David Ljung Madison #c// Design by Dave Simmer of DaveWeb.com #c// -- Auto generated by simmer_theme v$VERSION #c// -- From: http://MarginalHacks.com/Hacks/album/ #c// ################################################################### #c// <: END_OF_HEADER $ALBUM = <<'END_OF_ALBUM'; :>// #c// #c// ################################################################### #c// Everything beyond here is the same for every DaveWeb theme.. #c// ################################################################### <: # Shorthand for column info specified by -columns $Cols = Option('columns'); $Col_Perc = int(100/$Cols)."%"; :>// <: Meta() :> Album: <:= Path('album_name') :> <:= $CSS :> > <: if (isHeader()) { _:> <: } _:> <: Bar($Cols) :> #c// Are there more albums below this one? <: my $alb = First('dirs'); if ($alb) { _:> #c// Bar after child albums <: Bar($Cols) :> #c// #c// End if albums <: } :> #c// #c// The images <: my $img = First('pics'); if ($img) { _:>// <: my @save; while ($img) { _:> <: if (New_Row($img,$Cols) || !Next($img)) { _:> <: foreach my $save ( @save ) { _:> <: } undef @save; if (New_Row($img,$Cols)) { _:> <: } } $img = Next($img); } # End child album loop _:> <: Bar($Cols) :> <:}:>// <: if (isFooter()) { _:> <: Bar($Cols) :> <: } _:>
<:=Image_Array("$PATH/Null.gif",11,10):>
> <: if (@Icon) { print Image_Array(@Icon,"align='middle'"); print "\n
    \n"; } else { print "Album:\n"; } _:> <:= Parent_Albums(':'); :>
<: $back=Back(); if ($back && $back ne "''" && $back ne "'0'") { print ""; print @Back ? Image_Array(@Back,"align='middle'") : "Back"; print "\n"; } :>

<:pHeader():>
<:=Image_Array("$PATH/Null.gif",20,10):>
<: if (@More) { :> <: } :> #c// #c// Loop on all the albums <: my @save; while ($alb) { _:> <: if (New_Row($alb,$Cols,@More?1:0) || !Next($alb)) { _:> <: foreach my $save ( @save ) { _:> <:= "\n" unless !@More || Get($save,'num') :> <: } } $alb = Next($alb); } # End child album loop _:>
<:=Image_Array(@More):> <: PickOverlay($alb, 'thumb') if @Overlays :> <: Border($alb, 'thumb','dir', @Border) if Get($alb,'thumb','x') :> <: push(@save,$alb); :>
> <:= Image_Array(@Locked) if -e Get($save,'path').'/.htaccess'; :> <:=Get($save,'href','dir'):> <:=Pretty(Name($save),1,1):> <: my $cap = Caption($save); my $num_pics = Get($save,'num_pics'); $num_pics = $num_pics ? $num_pics>1 ? "$num_pics images\n" : "1 image\n" : ""; my $num_dirs = Get($save,'num_dirs'); $num_dirs = $num_dirs ? $num_dirs>1 ? "$num_dirs albums\n" : "1 album\n" : ""; if ($cap || $num_pics || $num_dirs) { _:>
<:=$cap if $cap:> <:="
" if $cap && ($num_pics || $num_dirs):> <:=$num_dirs:> <:=", " if $num_pics && $num_dirs:> <:=$num_pics:>
<: } :>
<: } undef @save; if (New_Row($alb,$Cols,@More?1:0)) { _:>
<: PickOverlay($img, 'thumb') if @Overlays :> <: Border($img,'thumb','image', @Border) if Get($img,'thumb','x') :> <: push(@save,$img); :>
> <:=Get($save,'href','image'):> <:=Pretty(Name($save),1,1):> <: if (my $cap = Caption($save)) { _:>
<:=$cap:> <: } :>
<:=Image_Array("$PATH/Null.gif",20,20):>
<:=Image_Array("$PATH/Null.gif",20,20):>

<:pFooter():>
><: Credit() :> on <:=scalar localtime:>

END_OF_ALBUM $IMAGE = <<'END_OF_IMAGE'; :>// #c// #c// ################################################################### #c// Everything beyond here is the same for every DaveWeb theme.. #c// ################################################################### <: Meta() :> Image: <:=Name(This_Image) :> <:= $CSS :> > <:=Image_Array("$PATH/Null.gif",1,10):> <: Bar(2) :>
<: if (@Icon) { print Image_Array(@Icon,"align='middle'"); print "\n
\n"; } _:> >     <:= Parent_Albums(':'); :>

#c// #c// Prev/caption/next #c//
<: if (my $Prev = Prev(This_Image, $opt->{image_loop})) { _:>
> <:=Get($Prev,'href','image_page','image_page'):> <:= @Prev ? Image_Array(@Prev,"align='top'") : "(prev) "; :><:=Pretty(Name($Prev),1):>
<: } _:>
> <:=Get(This_Image,'href','image'):> <:=Pretty(Name(This_Image),1,1):>
> <:=Caption(This_Image):>
<: if (my $Next = Next(This_Image, $opt->{image_loop})) { _:>
> <:=Get($Next,'href','image_page','image_page'):> <:=Pretty(Name($Next),1):><:= @Next ? Image_Array(@Next,"align='top'") : " (next)"; :>
<: } _:>
#c// #c// The image #c// <: Bar(1) :>

<: PickOverlay(This_Image, 'full') if @Overlays :> <: Border(This_Image,'full','image', @Border) :>
<:=Image_Array("$PATH/Null.gif",20,20):>
><: Credit() :> on <:=scalar localtime:>

END_OF_IMAGE main();