#!/bin/csh -f # makeslides # ------------------------------------------------------------------------- # C shell script to create a "slideshow" folder of slides of all images # (JPG, GIF, PNG, etc.) in the current directory. Each slide shows the # image and associated caption. # ------------------------------------------------------------------------- # Revision History: # $Log$ # ------------------------------------------------------------------------- # Collect command line options set option_quick = "false" set option_local_string = "" set option_interactive_string = "-i" set diff_cmd = "diff" set diffreviewdel_cmd = "diffreviewdel" while ($#argv > 0) if ("$1" == "-h" || "$1" == "--help") then echo "Usage: $0:t [options]" echo "Options:" echo " -h = Show this help text" echo " --help = Show this help text" echo " -q = Quick. Skip interactive review of index.htm." echo " Just show and accept changes." echo " Also, skip prompts when deleting obsolete files." echo " -l = Local. Don't publish updated files" echo " -I pattern = Ignore diff of lines containing pattern" echo " --ignore-matching-lines pattern" echo " = Ignore diff of lines containing pattern" exit 1 else if ("$1" == "-q") then shift set option_quick = "true" set option_interactive_string = "" else if ("$1" == "-l") then shift set option_local_string = "-l" else if ("$1" == "-I" || "$1" == "--ignore-matching-lines") then shift if ("$1" == "") then echo "Error: Missing argument to -I or --ignore-matching-lines option" $0 --help exit 1 else set diff_cmd = "$diff_cmd --ignore-matching-lines $1" set diffreviewdel_cmd = "$diffreviewdel_cmd --ignore-matching-lines $1" shift endif else if ("-" == "`echo $1:q | cut -c 1`") then echo "Error: Invalid option: $1:q" $0 --help exit 1 else # Not a recognized option. Assume it's the first argument break endif end # No arguments defined, so allow none if ($#argv > 0) then $0 --help exit 1 endif mkdir -p slideshow >& /dev/null if ("$option_quick" == "true") then set action = "q" else set action = "" endif foreach image_file (*.[jJ][pP][gG] *.[gG][iI][fF] *.[pP][nN][gG]) set slide_file = "slideshow/${image_file:r}.htm" set txt_file = "${image_file:r}.txt" if (-e "$slide_file") then # Note: mv, not cp, to avoid updating timestamp. Then if the new # version is identical, we can mv it back and avoid publishing # the file to the server needlessly. # Note: Use -i regardless of option_interactive_string. Happens rarely. # Only when previous run was aborted with Ctrl-C. Seems to be # worth confirming with the user. mv -i "$slide_file" "$slide_file.old" endif # Need a relative URL for the image file, referring to the parent folder # because this URL will be embedded in the HTML file of the slide, which # will be loaded from the slideshow subfolder. Need a simple filename, # not a relative URL, for the caption file, since that gets accessed now, # by name in the called script, not later by the HTML file that the script # generates. make_html_for_image_and_caption "../$image_file" "$txt_file" >! "$slide_file" # Prevent wildcard and command line pattern expansion because there may # be a regular expression in the --ignore-matching-lines value inside # diff_cmd and diffreviewdel_cmd. We want to avoid "No match." errors # when the shell tries to expand it into filenames. Also, we really do # want the regular expression to get passed to diff. # Note: Can't do this for the entire file because we're using wildcards # in other parts of the file. Turn noglob on temporarily here, # and off again later. set noglob if (-e "$slide_file.old") then if ("$action" == "q") then # Quick mode. The caller passed an option to update all slides w/o # prompting. # Note: Don't use --ignore-matching-lines here. Or we'll discard # the newly generated file when only diff is version number. diff "$slide_file" "$slide_file.old" >& /dev/null if ($status) then # Slide has changed, but in more than just the version number? $diff_cmd "$slide_file" "$slide_file.old" >& /dev/null if ($status) then # Slide has real changes. Show the user the changes, and # accept them. echo "Slide $slide_file has changed. Accepting changes..." $diff_cmd "$slide_file" "$slide_file.old" rm "$slide_file.old" else # Slide has changed only in version number. Delete the old # slide. rm "$slide_file.old" endif else # Slide has not changed. Move old copy back into position so # the identical slide with new timestamp doesn't get published # needlessly. mv "$slide_file.old" "$slide_file" endif else if ("$action" != "a") then # We're not in quick mode. But the user hasn't yet said to # update all slides w/o further prompting. Diff the slide and # prompt if changed. # Note: Don't use --ignore-matching-lines here. Or we'll discard # the newly generated file when only diff is version number. diff "$slide_file" "$slide_file.old" >& /dev/null if ($status) then # Slide has changed, but in more than just the version number? $diff_cmd "$slide_file" "$slide_file.old" >& /dev/null if ($status) then # Slide has real changes. Prompt user for what to do. echo "Slide $slide_file has changed." set action = `promptloop "Review via windiff(w), review via diff(d), update all slides(a)? " w d a` else # Slide has changed only in version number. Delete the old # slide. rm "$slide_file.old" endif else # Slide has not changed. Move old copy back into position so # the identical slide with new timestamp doesn't get published # needlessly. mv "$slide_file.old" "$slide_file" endif endif if ("$action" == "w") then # Slide has changed in more than just version number, and user # chose the option to review via windiff. # Give the user a chance to review and reconcile the differences, # then prompt to delete the old slide, showing any changes that were # not reconciled. # Note: Use -i since user has already requested windiff. Don't # prompt again. $diffreviewdel_cmd -i "$slide_file" "$slide_file.old" # Reset action for next file. "w" applies only to one file at a time. set action = "" else if ("$action" == "d") then # Slide has changed in more than just version number, and user # chose the option to review via diff. # Show the user the changes about to be accepted, then prompt to # delete the old slide. No option for him to reconcile the # changes, but it's a faster option if he's pretty sure. If not, # he can later manually reverse the changes and manually delete # the old slide. $diff_cmd "$slide_file" "$slide_file.old" rm -iv "$slide_file.old" # Reset action for next file. "d" applies only to one file at a time. set action = "" else if ("$action" == "a") then # Slide may have changed. At least one slide in this batch changed # and the user chose the option to stop reviewing and just update # all slides. But, we may have looped on to the next slide since # then. Check again for diffs, on this slide. # Note: Don't use --ignore-matching-lines here. Or we'll discard # the newly generated file when only diff is version number. diff "$slide_file" "$slide_file.old" >& /dev/null if ($status) then # Slide has changed, but in more than just the version number? $diff_cmd "$slide_file" "$slide_file.old" >& /dev/null if ($status) then # Slide has real changes. Show the user the changes, and # accept them. echo "Slide $slide_file has changed. Accepting changes..." $diff_cmd "$slide_file" "$slide_file.old" rm "$slide_file.old" else # Slide has changed only in version number. Delete the old # slide. rm "$slide_file.old" endif else # Slide has not changed. Move old copy back into position so # the identical slide with new timestamp doesn't get published # needlessly. mv "$slide_file.old" "$slide_file" endif # Note: Don't clear action here. "a" applies to all remaining files. endif endif # Re-allow wildcard and command line pattern expansion. unset noglob end # Link from slideshow to itself, so slide captions can use "slideshow/" to # refer to other slides, regardless of whether the slide with the caption # is in an album or a slideshow. # And from album to itself and slideshow to album both via "album/". # And create "js/" links up the tree to find the JS library. echo "=======================================================================" echo "Creating symlinks: album, slideshow, js" echo "=======================================================================" make_symlink_if_necessary $cwd/album . (cd slideshow; make_symlink_if_necessary $cwd/slideshow .) (cd slideshow; make_symlink_if_necessary $cwd/album ..) (cd slideshow; make_links_up_the_tree $option_local_string js) # Create the error pages echo "=======================================================================" echo "Creating slideshow/error.htm" echo "=======================================================================" make_error_loading_slide_page >! "slideshow/error.htm" # Check for obsolete slide files that have no image counterpart. echo "=======================================================================" echo "Deleting obsolete slide files" echo "=======================================================================" cd slideshow foreach slide_file (*.htm) if ("$slide_file" == "index.htm") then # Nothing to do. This file is expected. else if ("$slide_file" == "error.htm") then # Nothing to do. This file is expected. else # Note: Put all the -o clauses at the end. Can't end with -print. # That causes it to find nothing. Why? # Also, can't put -print earlier. That causes it to find all. # Just leave -print out. It's implied anyhow. set image_file = `find .. -maxdepth 1 \ -name "${slide_file:r}.[jJ][pP][gG]" \ -o -name "${slide_file:r}.[gG][iI][fF]" \ -o -name "${slide_file:r}.[pP][nN][gG]" \ ` if ("$image_file" == "") then echo "Deleting obsolete slide $slide_file..." rm -v $option_interactive_string "$slide_file" endif endif end cd - # Create symlinks from slideshow folder to all MP4 files in main album # folder. This is a convenience for users who put HTTP links to MP4 files # in their TXT files. Those HTTP links will work fine when the TXT file # is copied into the main index.htm file for the album, but would fail # when the same TXT file is copied into the slideshow/index.htm file, since # it would look for the MP4 file in the slideshow folder. Putting symlinks # there resolves the problem. # Note: I tried to create a single videos links in each folder and having # the user always prefix MP4 filename in TXT files with "videos/". # 2 problems: # - User will often forget and be confused when it works from the # album but not from the slideshow # - I couldn't get it to work. At least in the case of my 0_Favorites # folder, where the slideshow needed to follow "videos" to ".." # (or to "../", or to "../videos" -- I tried all 3), and then # follow a filename.mp4 link to the real mp4 file in another folder. # Worked fine remotely on a Linux server, but not locally. # Not locally when accessed via file: URLs from the browser, and # not locally when accessed from the command line via the Mac # "open" command. See Fred's 12/13/2019 notes for details. #?? Do the same for all other files that might be referred to by the user's #?? TXT files, not just for MP4 files? #?? Could iterate over all files in main folder, and search for uses in #?? *.txt files, and create symlinks only for those referred to in a #?? *.txt file? #?? Any way to find references like abc/file2.mp4 in *.txt files? Would #?? miss it now, if we were only looking for file1.mp4 that existed #?? locally, not other files in other relative folders. #?? If so, how to clean up old symlinks created earlier and no longer #?? needed since the user deleted the reference to it from all *.txt #?? files? So far, we delete any symlinks whose names don't match local #?? files. echo "=======================================================================" echo "Creating symlinks for MP4 files" echo "=======================================================================" if (`find . -name "*.[Mm][Pp]4" -print` != "") then foreach mp4_file (*.[Mm][Pp]4) make_symlink_if_necessary "slideshow/$mp4_file" "../$mp4_file" end endif # Check for obsolete MP4 symlinks that have no real file counterpart. echo "=======================================================================" echo "Deleting obsolete symlinks for MP4 files" echo "=======================================================================" cd slideshow if (`find . -name "*.[Mm][Pp]4" -print` != "") then foreach mp4_file (*.[Mm][Pp]4) if (-l "$mp4_file" && ! -e "../$mp4_file") then echo "Deleting obsolete symlink $mp4_file..." rm -v $option_interactive_string "$mp4_file" endif end endif cd -