Shell command of the day: Image size as XML attributes

for file in `grep -l 'rel="shadowbox' raw/*.htm`; do echo $file; for imgsrc in `xmlstarlet sel -q -t -v '//_:a[@rel and not(@data-size)]/@href' "$file"`; do size=`exiftool -T -Imagesize raw/$imgsrc`; echo $imgsrc $size; xmlstarlet ed --inplace -P --append "//_:a[@href='$imgsrc' and not(@data-size)]" --type attr -n data-size --value "$size" "$file"; done; done

For this blog I wanted to have an image gallery that works on mobile devices. I found the open source PhotoSwipe library, and after some days I had it integrated in my blog. ​

PhotoSwipe requires you to specify the full image size when initializing; it does not auto-detect it. I had 29 blog posts with image galleries, and over a hundred images in them - adding the image sizes manually was not an option. ​

I opted for a HTML5 data attribute on the link to the large image: ​

<a href="image.jpg" data-size="1200x800">..

What I had to do: ​

  1. Find all files with galleries ​

    $ grep -l 'rel="shadowbox' raw/*.htm
    ​
  2. Extract image paths from the HTML files ​

    $ xmlstarlet sel -q -t -v '//_:a[@rel and not(@data-size)]/@href' "$file"
    ​
  3. Extract the image size ​

    $ exiftool -T -Imagesize "raw/$imgsrc"
    ​
  4. Add the data-size attribute to the link tags which link to the image: ​

    $ xmlstarlet ed --inplace -P --append "//_:a[@href='$imgsrc' and not(@data-size)]" --type attr -n data-size --value "$size" "$file"
    ​

And this all into one nice shell script: ​

for file in `grep -l 'rel="shadowbox' raw/*.htm`
do
    echo $file
    for imgsrc in `xmlstarlet sel -q -t -v '//_:a[@rel and not(@data-size)]/@href' "$file"`
    do
        size=`exiftool -T -Imagesize raw/$imgsrc`
        echo $imgsrc $size
        xmlstarlet ed --inplace -P --append "//_:a[@href='$imgsrc' and not(@data-size)]" --type attr -n data-size --value "$size" "$file"
    done
done

This all did only work because I my blog posts are XHTML. ​

You can see the new galleries in e.g. Kinderzimmerlampe im Eigenbau and Playing Tomb Raider 1 on OUYA. ​

Written by Christian Weiske.

Comments? Please send an e-mail.