#!/bin/sh # # Copyright (C) 2022 by Friedemann Bartels # # This file may be distributed and/or modified under the # conditions of the LaTeX Project Public License, either # version 1.3c of this license or (at your option) any later # version. The latest version of this license is in: # # http://www.latex-project.org/lppl.txt # # and version 1.3c or later is part of all distributions of # LaTeX version 2008/05/04 or later. # version=1.0.2 OK="$( tput setaf 2 )•$( tput sgr0 )" FAILED="$( tput setaf 1 )$( tput bold )x$( tput sgr0 )" NEW="$( tput setaf 3 )$( tput bold )+$( tput sgr0 )" REMOVED="$( tput setaf 5 )$( tput bold )-$( tput sgr0 )" ERROR="$( tput setaf 1 )$( tput bold )!$( tput sgr0 )" _playok() { if [ -f /System/Library/Sounds/Glass.aiff ]; then afplay /System/Library/Sounds/Glass.aiff >/dev/null 2>&1 fi } _playhm() { if [ -f /System/Library/Sounds/Basso.aiff ]; then afplay /System/Library/Sounds/Basso.aiff >/dev/null 2>&1 fi } _playerror() { if [ -f /System/Library/Sounds/Sosumi.aiff ]; then afplay /System/Library/Sounds/Sosumi.aiff >/dev/null 2>&1 fi } _gettime() { if command -v gdate &> /dev/null; then echo $( gdate +%s%3N ) else if command -v date &> /dev/null; then milliseconds=$( date +%3N ) if [ $milliseconds = 3N ]; then echo $(( SECONDS * 1000 )) else echo $( date +%s%3N ) fi else echo $(( SECONDS * 1000 )) fi fi } _starttimer() { starttime=$( _gettime ) } _stoptimer() { endtime=$( _gettime ) elapsedtime=$(( endtime - starttime )) elapsedseconds=$(( elapsedtime / 1000 )) elapsedmilliseconds=$(( elapsedtime % 1000 )) elapsed=$elapsedseconds.$( printf "%03d" "$elapsedmilliseconds" ) } test() { _starttimer tmpdir=$( mktemp -d 2>/dev/null )/textest$( date "+%Y%m%d%H%M%S" )$RANDOM mkdir $tmpdir if [ $3 = true ] && [ -d cache ]; then rm -rf cache fi okcount=0 failedcount=0 newcount=0 removedcount=0 fileokcount=0 filefailedcount=0 defaultfiller=23 echo "" for entry in *$5*.tex do if [ $entry != "*$5*.tex" ]; then name=$( echo $entry | sed -e 's/\.tex$//g' ) if [ ${name:0:1} != _ ]; then printf "$( tput sgr0 )$name" runtwice=0 if [ "${name:$(( ${#name} - 2 )):2}" = "@2" ]; then runtwice=1 fi if [ "$4" != "xelatex" ]; then name="$name.$4" fi passed=1 rm -f $name.failed.* cp $entry $tmpdir/$name.tex shell="" if [ $1 = true ]; then shell="--shell-escape" fi $4 -interaction=batchmode $shell --output-directory $tmpdir $tmpdir/$name.tex > /dev/null if [ $? -eq 1 ]; then passed=0 fi if [ $runtwice -eq 1 ]; then $4 -interaction=batchmode $shell --output-directory $tmpdir $tmpdir/$name.tex > /dev/null if [ $? -eq 1 ]; then passed=0 fi fi magick convert -density $2 -quiet $tmpdir/$name.pdf $tmpdir/$name.png if [ -f "$tmpdir/$name.png" ]; then mv $tmpdir/$name.png $tmpdir/$name-0.png fi if [ -f "$name.approved.pdf" ]; then magick convert -density $2 -quiet $name.approved.pdf $tmpdir/$name.approved.png if [ -f "$tmpdir/$name.approved.png" ]; then mv $tmpdir/$name.approved.png $tmpdir/$name.approved-0.png fi fi if [ $passed -eq 0 ]; then filler=$(( defaultfiller - ${#name} - 2 )) else filler=$(( defaultfiller - ${#name} )) fi while [ 0 -le $filler ]; do printf " " filler=$(( filler - 1 )) done if [ $passed -eq 0 ]; then printf " $ERROR" fi index=0 while [ -f "$tmpdir/$name-$index.png" ]; do if [ -f "$tmpdir/$name.approved-$index.png" ]; then changedpixels=$( magick compare -quiet -metric AE $tmpdir/$name-$index.png $tmpdir/$name.approved-$index.png null: 2>&1 ) if [ $changedpixels -eq 0 ]; then okcount=$(( okcount + 1 )) printf " $OK" else failedcount=$(( failedcount + 1 )) passed=0 printf " $FAILED" magick compare -quiet $tmpdir/$name-$index.png $tmpdir/$name.approved-$index.png $name.failed.$(( index + 1 )).png if [ -f "$tmpdir/$name.pdf" ]; then mv $tmpdir/$name.pdf $name.failed.pdf fi fi else newcount=$(( newcount + 1 )) passed=0 printf " $NEW" mv $tmpdir/$name-$index.png $name.failed.$(( index + 1 )).png if [ -f "$tmpdir/$name.pdf" ]; then mv $tmpdir/$name.pdf $name.failed.pdf fi fi index=$(( index + 1 )) if [ `expr $index % 20` -eq 0 ] && [ -f "$tmpdir/$name-$index.png" ]; then echo "" filler=$defaultfiller while [ 0 -le $filler ]; do printf " " filler=$(( filler - 1 )) done fi done while [ -f "$tmpdir/$name.approved-$index.png" ]; do removedcount=$(( removedcount + 1 )) passed=0 printf " $REMOVED" mv $tmpdir/$name.approved-$index.png $name.failed.$(( index + 1 )).png if [ -f "$tmpdir/$name.pdf" ]; then mv $tmpdir/$name.pdf $name.failed.pdf fi index=$(( index + 1 )) if [ `expr $index % 20` -eq 0 ] && [ -f "$tmpdir/$name.approved-$index.png" ]; then echo "" filler=$defaultfiller while [ 0 -le $filler ]; do printf " " filler=$(( filler - 1 )) done fi done if [ $passed -eq 1 ]; then fileokcount=$(( fileokcount + 1 )) else filefailedcount=$(( filefailedcount + 1 )) fi echo "" fi fi done rm -rf $tmpdir _stoptimer seconds=$( printf "%.1f" "$elapsed" ) filecount=$(( fileokcount + filefailedcount )) if [ $filecount -gt 0 ]; then echo "" fi if [ $filecount -eq $fileokcount ]; then if [ $filecount -eq 0 ]; then _playhm & echo "$( tput sgr0 )Tested 0 files 🧐." else _playok & echo "$( tput sgr0 )Successfully tested $filecount files in $seconds seconds 🎉." fi echo "" else _playerror & echo "$( tput sgr0 )Tested $filecount files in $seconds seconds." echo "" if [ $fileokcount -gt 0 ]; then filler=$(( 6 + ${#filecount} - ${#fileokcount} )) while [ 0 -le $filler ]; do printf " " filler=$(( filler - 1 )) done printf "$( tput setaf 2 )$fileokcount OK$( tput sgr0 )" echo "" fi if [ $filefailedcount -gt 0 ]; then filler=$(( 6 + ${#filecount} - ${#filefailedcount} )) while [ 0 -le $filler ]; do printf " " filler=$(( filler - 1 )) done printf "$( tput setaf 1 )$filefailedcount Failed$( tput sgr0 )" echo "" fi echo "" exit 1 fi } approve() { filecount=0 suffix="" if [ "$1" != "xelatex" ]; then suffix=".$1" fi echo "" for entry in *$2*$suffix.failed.pdf do if [ $entry != "*$2*$suffix.failed.pdf" ]; then filecount=$(( filecount + 1 )) name=$( echo $entry | sed -e "s/$suffix.failed.pdf//" ) echo $name rm -f $name$suffix.approved.pdf if [ -f "$name.aux" ]; then cp $name$suffix.failed.pdf $name$suffix.approved.pdf else mv $name$suffix.failed.pdf $name$suffix.approved.pdf fi rm -f $name$suffix.failed.* fi done if [ $filecount -gt 0 ]; then echo "" fi if [ $filecount -eq 1 ]; then echo "Approved 1 file." else echo "Approved $filecount files." fi echo "" } compare() { filea=$2 fileb=$3 tmpdir=$( mktemp -d 2>/dev/null)/textest$( date "+%Y%m%d%H%M%S" )$RANDOM mkdir $tmpdir namea=$( echo $filea | sed -e 's/\.\///g' | sed -e 's/\.pdf$//g' ) nameb=$( echo $fileb | sed -e 's/\.\///g' | sed -e 's/\.pdf$//g' ) basenamea=$(basename $namea) basenameb=$(basename $nameb) rm -f $namea.diff.*.png spacer="" if [ -f "$filea" ]; then if [ -f "$fileb" ]; then magick convert -density $1 -quiet $filea $tmpdir/$basenamea.png if [ -f "$tmpdir/$basenamea.png" ]; then mv $tmpdir/$basenamea.png $tmpdir/$basenamea-0.png fi magick convert -density $1 -quiet $fileb $tmpdir/$basenameb.png if [ -f "$tmpdir/$basenameb.png" ]; then mv $tmpdir/$basenameb.png $tmpdir/$basenameb-0.png fi index=0 while [ -f "$tmpdir/$basenamea-$index.png" ]; do if [ -f "$tmpdir/$basenameb-$index.png" ]; then changedpixels=$( magick compare -quiet -metric AE $tmpdir/$basenamea-$index.png $tmpdir/$basenameb-$index.png null: 2>&1 ) if [ $changedpixels -eq 0 ]; then printf "$spacer$OK" spacer=" " else printf "$spacer$FAILED" spacer=" " magick compare -quiet $tmpdir/$basenamea-$index.png $tmpdir/$basenameb-$index.png $namea.diff.$(( index + 1 )).png fi else printf "$spacer$NEW" spacer=" " fi index=$(( index + 1 )) done while [ -f "$tmpdir/$basenameb-$index.png" ]; do printf "$spacer$REMOVED" spacer=" " index=$(( index + 1 )) done echo "" else echo "File $fileb not found." fi else echo "File $filea not found." fi rm -rf $tmpdir } perf() { if [ -f $4 ]; then tmpdir=$( mktemp -d 2>/dev/null )/textestperf$( date "+%Y%m%d%H%M%S" )$RANDOM mkdir $tmpdir basename=$(basename $4) if [ $1 = true ] && [ -d cache ]; then rm -rf cache fi cp $4 $tmpdir shell="" if [ $2 = true ]; then shell="--shell-escape" fi _starttimer $3 -interaction=batchmode $shell --output-directory $tmpdir $tmpdir/$basename > /dev/null _stoptimer echo "$elapsed" rm -rf $tmpdir else echo "File $4 not found." fi } usage() { cat <