|
|
|
#!/bin/bash
|
|
|
|
## Process *.Rnw files
|
|
|
|
## Written May 14, 2010
|
|
|
|
## Taha Ahmed
|
|
|
|
|
|
|
|
####################################################
|
|
|
|
# For now, MAKE SURE that the argument consists of
|
|
|
|
# a complete filename, with extension, and
|
|
|
|
# in the directory of the Rnw file
|
|
|
|
####################################################
|
|
|
|
|
|
|
|
# keep track of runtime of entire script
|
|
|
|
starttime=$(date +%s)
|
|
|
|
|
|
|
|
clear
|
|
|
|
echo "-----------------------------------------------------------------------"
|
|
|
|
echo "cheRTeX -- a script for processing R--Sweave/knitr--LaTeX/TikZ projects"
|
|
|
|
echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
|
|
|
|
echo "MMXVI -- taha@chepec.se -- CHEPEC doctoral degree project"
|
|
|
|
echo "-----------------------------------------------------------------------"
|
|
|
|
|
|
|
|
## If the file .latexmkrc exists in the current directory,
|
|
|
|
## set the flag ltxmkrc=TRUE
|
|
|
|
ltxmkrc=false
|
|
|
|
echo "--- Looking for .latexmkrc"
|
|
|
|
if [ -e .latexmkrc ]; then
|
|
|
|
ltxmkrc=true
|
|
|
|
echo "+++ LaTeXMK RC file invoked"
|
|
|
|
else
|
|
|
|
echo "--- This job did not request LaTeXMK RC file"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# define some commands
|
|
|
|
Rfiletype="R"
|
|
|
|
TeXfiletype="tex"
|
|
|
|
tikzfiles="*.tikz"
|
|
|
|
Rnwfiles="*.Rnw"
|
|
|
|
auxfiles="*.acn *.acr *.alg *.aux *.bbl *.bcf *.blg *.dep *.dpth *.fdb* *.figlist *.fls *.glg *.glo *.gls *.lof *.log *.lot *.out *.lox *.makefile *.map *.out *.run* *.slg *.slo *.sls *.tdo *.toc *.xdy"
|
|
|
|
|
|
|
|
|
|
|
|
# depending on number of args and their content, do different things...
|
|
|
|
if [ $# -eq 1 ]; then
|
|
|
|
# Check if the argument contains a filetype
|
|
|
|
# (assumes a complete filename was passed)
|
|
|
|
jobfilename=$1
|
|
|
|
jobfiletype=${jobfilename#*.} # File extension
|
|
|
|
jobname=${jobfilename%.*} # Filename without extension part
|
|
|
|
|
|
|
|
echo "<cheRTeX> Detected filename: " $jobname
|
|
|
|
echo "<cheRTeX> Detected extension:" $jobfiletype
|
|
|
|
|
|
|
|
# Verify that the file extension is "[Rr][Nn][Ww]"
|
|
|
|
if [[ $jobfiletype == "Rnw" || $jobfiletype == "rnw" || $jobfiletype == "RNW" ]]; then
|
|
|
|
# File extension is indeed "[Rr][Nn][Ww]"
|
|
|
|
echo "<cheRTeX> Detected *.Rnw extension"
|
|
|
|
jobfiletype="Rnw"
|
|
|
|
else
|
|
|
|
# File extension is NOT "[Rr][Nn][Ww]"
|
|
|
|
echo "<cheRTeX> This script only handles *.Rnw files"
|
|
|
|
echo "<cheRTeX> Terminating..."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Introducing a short delay to enable on-screen reading of previous echo
|
|
|
|
simpledelay.sh 2
|
|
|
|
echo "Delay completed"
|
|
|
|
|
|
|
|
|
|
|
|
#### Special treatment for sample-matrix.Rnw
|
|
|
|
# If $jobname is sample-matrix, restart Shiny and term this script
|
|
|
|
if [[ $jobname == "sample-matrix" ]]; then
|
|
|
|
echo "<sample-matrix> -------------------------------"
|
|
|
|
echo "<sample-matrix> Restarting Shiny"
|
|
|
|
echo "<sample-matrix> -------------------------------"
|
|
|
|
|
|
|
|
# kill Shiny
|
|
|
|
pkill -f "shiny::runApp"
|
|
|
|
# start Shiny
|
|
|
|
bash -c "/media/bay/taha/chepec/chetex/common/bash/shiny-matrix.sh" &
|
|
|
|
# terminate this script
|
|
|
|
echo "<cheRTeX> Terminating..."
|
|
|
|
simpledelay.sh 2
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
#### Special treatment for thesis
|
|
|
|
if [[ ${PWD} == "/media/bay/taha/chepec/thesis" && $jobname == "thesis" ]]; then
|
|
|
|
# Fetch external assets by reading any assets.external files in assets/ tree
|
|
|
|
echo "<thesis> -------------------------------"
|
|
|
|
echo "<thesis> Getting external assets"
|
|
|
|
echo "<thesis> -------------------------------"
|
|
|
|
# summary of operations in this if-clause:
|
|
|
|
# trawl the assets/ subdirectories looking for a file "external.assets", if found,
|
|
|
|
# read its contents line-by-line (each line is a path) and copy that file to the current assets/ subdir
|
|
|
|
# note that we only look for assets.external inside the subdirectories, and not in assets/ itself
|
|
|
|
assetsubdirectories="$(find /media/bay/taha/chepec/thesis/assets/ -maxdepth 1 -mindepth 1 -type d)"
|
|
|
|
# loop through $assetdirs, and look for the file external.assets in each path
|
|
|
|
for assetdir in $assetsubdirectories; do
|
|
|
|
assetfilename="assets.external"
|
|
|
|
if [ -e ${assetdir}/${assetfilename} ]; then
|
|
|
|
# https://stackoverflow.com/questions/10929453/read-a-file-line-by-line-assigning-the-value-to-a-variable
|
|
|
|
# $assets is the current assets.external file
|
|
|
|
assets="${assetdir}/${assetfilename}"
|
|
|
|
while IFS='' read -r asset || [[ -n "$asset" ]]; do
|
|
|
|
echo "$asset"
|
|
|
|
# copy this filepath into the current assets subdirectory
|
|
|
|
cp --preserve=timestamps $asset $assetdir
|
|
|
|
done < "$assets"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
# Create low-res photos on-the-fly from existing photos/
|
|
|
|
echo "<thesis> -------------------------------"
|
|
|
|
echo "<thesis> Create low-res photos tree"
|
|
|
|
echo "<thesis> -------------------------------"
|
|
|
|
# copy existing photos to assets/photos/.lowres/ path
|
|
|
|
# to save time, rsync only if highres photo has more recent timestamp (otherwise, keep lowres photo without overwriting)
|
|
|
|
# Note: rsync usually looks at file timestamp and size, and if either has changed, copies the file (simplified explanation)
|
|
|
|
# in this case, I'd like rsync to only compare timestamps and disregard size
|
|
|
|
# rsync can't do that. We need to use a different tool. See e.g.
|
|
|
|
# https://superuser.com/questions/260092/rsync-switch-to-only-compare-timestamps
|
|
|
|
# copy only the "large" photos that have file modtimes more recent than the last time this operation was run
|
|
|
|
photoslastrun="/media/bay/taha/chepec/thesis/assets/photos/.lowres/lastrun"
|
|
|
|
if [ ! -f "$photoslastrun" ]; then
|
|
|
|
# if, for some reason, the lastrun file does not exist
|
|
|
|
# copy over everything and then create the file
|
|
|
|
rsync -av /media/bay/taha/chepec/thesis/assets/photos/* /media/bay/taha/chepec/thesis/assets/photos/.lowres/ --exclude /media/bay/taha/chepec/thesis/assets/photos/.lowres/
|
|
|
|
touch "$photoslastrun"
|
|
|
|
fi
|
|
|
|
# cd and use --parents arg to preserve directory structure in .lowres target
|
|
|
|
cd /media/bay/taha/chepec/thesis/assets/photos
|
|
|
|
newphotos="$(find . -type f -cnewer $photoslastrun ! -path './.lowres/*')"
|
|
|
|
if [ -n "$newphotos" ]; then
|
|
|
|
for newphoto in $newphotos; do
|
|
|
|
cp --parents $newphoto .lowres/
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
# revert the effects of cd above. Redirect to null suppresses the output.
|
|
|
|
cd - >/dev/null
|
|
|
|
# in the low-res tree, find any photo larger than specific size (500kB)
|
|
|
|
largephotos="$(find /media/bay/taha/chepec/thesis/assets/photos/.lowres/ -size +500k)"
|
|
|
|
for largephotofilename in $largephotos; do
|
|
|
|
# for the next statement to work reliably, we should probably convert other formats to JPEG
|
|
|
|
# detect file extension, and based on it, convert to jpg using mogrify
|
|
|
|
largephotobase=$(basename -- "$largephotofilename") # just the filename (with extension, sans parents)
|
|
|
|
largephototype=${largephotobase#*.} # file extension only
|
|
|
|
largephotoname=${largephotofilename%.*} # path without extension
|
|
|
|
largephotobasename=${largephotobase%.*} # basename without extension
|
|
|
|
if [ ! "$largephototype" == "jpg" ] && [ ! "$largephototype" == "jpeg" ] && [ ! "$largephototype" == "JPG" ] && [ ! "$largephototype" == "JPEG" ]; then
|
|
|
|
echo "<thesis> Converting $largephotobase to JPG format"
|
|
|
|
mogrify -format jpg $largephotofilename
|
|
|
|
# remove the now unnecessary non-jpg file from .lowres/
|
|
|
|
rm "$largephotofilename"
|
|
|
|
fi
|
|
|
|
# convert photo in-place (overwrite) with new one roughly 300kb in size
|
|
|
|
# https://stackoverflow.com/questions/6917219/imagemagick-scale-jpeg-image-with-a-maximum-file-size
|
|
|
|
echo "<thesis> Shrinking $largephotobasename.jpg"
|
|
|
|
convert $largephotoname.jpg -define jpeg:extent=300kb $largephotoname.jpg
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
# short delay to enable on-screen reading of previous echo
|
|
|
|
simpledelay.sh 2
|
|
|
|
|
|
|
|
|
|
|
|
## Handle knitr or pgfSweave jobs (each requires separate treatment)
|
|
|
|
## But how should we tell the difference between them?
|
|
|
|
## There is no obvious way to tell the difference (apart from reading the *.Rnw file)
|
|
|
|
## IN ALL KNITR DIRECTORIES, CREATE A FILE NAMED: .knitme
|
|
|
|
# If the file .knitme exists in the current directory,
|
|
|
|
# run knitr commands, otherwise run pgfsweave commands
|
|
|
|
echo "--- Looking for .knitme"
|
|
|
|
if [ -e .knitme ]; then
|
|
|
|
# Run knitr commands for this job
|
|
|
|
echo "<cheRTeX> -----------------------"
|
|
|
|
echo "<cheRTeX> This is a job for knitr"
|
|
|
|
echo "<cheRTeX> -----------------------"
|
|
|
|
|
|
|
|
# Knit
|
|
|
|
echo "<cheRTeX> Knitting..."
|
|
|
|
Rscript -e "library(knitr); library(methods); knit('$jobname.$jobfiletype')"
|
|
|
|
|
|
|
|
# Introduce delay to give time to read Rscript exit status
|
|
|
|
echo "<cheRTeX> -----------------------"
|
|
|
|
echo "<cheRTeX> Rscript knitr completed"
|
|
|
|
echo "<cheRTeX> -----------------------"
|
|
|
|
simpledelay.sh 2
|
|
|
|
else
|
|
|
|
# Run pgfSweave commands
|
|
|
|
echo "<cheRTeX> ---------------------------"
|
|
|
|
echo "<cheRTeX> This is a job for pgfSweave"
|
|
|
|
echo "<cheRTeX> ---------------------------"
|
|
|
|
|
|
|
|
# Tangle
|
|
|
|
echo "<cheRTeX> Tangling..."
|
|
|
|
R CMD Stangle $jobname.$jobfiletype
|
|
|
|
# Weave
|
|
|
|
echo "<cheRTeX> Weaving..."
|
|
|
|
R CMD pgfsweave --graphics-only $jobname.$jobfiletype
|
|
|
|
|
|
|
|
# Introduce delay to give time to read R CMD exit status
|
|
|
|
echo "<cheRTeX> -------------------------"
|
|
|
|
echo "<cheRTeX> R CMD pgfsweave completed"
|
|
|
|
echo "<cheRTeX> -------------------------"
|
|
|
|
simpledelay.sh 2
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Run vc script if vc exists in working directory
|
|
|
|
echo "<cheRTeX> Running vc script"
|
|
|
|
if [ -f vc ]; then
|
|
|
|
./vc
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Run pdflatex, bibtex, and company
|
|
|
|
if $ltxmkrc; then
|
|
|
|
echo "<cheRTeX> Calling LaTeXMK with RC file"
|
|
|
|
simpledelay.sh 2
|
|
|
|
latexmk -r .latexmkrc -pdf -bibtex $jobname
|
|
|
|
else
|
|
|
|
echo "<cheRTeX> Calling LaTeXMK"
|
|
|
|
simpledelay.sh 2
|
|
|
|
latexmk -pdf -bibtex $jobname
|
|
|
|
fi
|
|
|
|
|
|
|
|
else
|
|
|
|
# Either no arguments, or more than one argument
|
|
|
|
if [ $# -eq 0 ]; then
|
|
|
|
# Zero arguments. Present a menu of choices
|
|
|
|
echo "This is cheRTeX POST-PROCESSING" # only one choice for now
|
|
|
|
echo "<1> 'pdf-all' -- Process all .tikz files to pdf graphics"
|
|
|
|
echo "<2> 'clean-up' -- Remove all auxiliary files"
|
|
|
|
echo "<3> 'wipe-dir' -- Remove all non-essential files and subdirectories"
|
|
|
|
echo "Any other input exits the program"
|
|
|
|
read usrchoice
|
|
|
|
|
|
|
|
## Determine number of .Rnw files in current directory
|
|
|
|
#Rnwfileno=$(ls -1 $Rnwfiles | wc -l)
|
|
|
|
#echo "No of .Rnw files: $Rnwfileno"
|
|
|
|
#
|
|
|
|
## Check if number of .Rnw files larger than one
|
|
|
|
#if [ $Rnwfileno -gt 1 ]; then
|
|
|
|
# # If larger than one, ask for user input
|
|
|
|
# # Indicates more than one Rnw file in current directory.
|
|
|
|
# # This introduces a naming ambiguity.
|
|
|
|
# # Resolve by asking user for current jobname
|
|
|
|
# echo "Found $Rnwfileno .Rnw files in current directory"
|
|
|
|
# echo "Please specify the jobname"
|
|
|
|
# read jobname
|
|
|
|
# if [ -z "$jobname" ]; then
|
|
|
|
# # string is null
|
|
|
|
# echo "Specified jobname cannot be parsed. Terminating..."
|
|
|
|
# exit 1
|
|
|
|
# fi
|
|
|
|
#else
|
|
|
|
# # There is exactly one *.Rnw file is current directory
|
|
|
|
# # Fetch the jobname from the .Rnw filename by stripping off the file extension
|
|
|
|
# Rnwfilename=$(ls -1 $Rnwfiles)
|
|
|
|
# jobname=${Rnwfilename%.*}
|
|
|
|
#fi
|
|
|
|
#
|
|
|
|
#echo "Jobname set to: $jobname"
|
|
|
|
|
|
|
|
if [[ $usrchoice == "pdf-all" || $usrchoice == "1" ]]; then
|
|
|
|
echo "<1> 'pdf-all' chosen"
|
|
|
|
# This for loop ONLY USED to determine number of *.tikz files in directory
|
|
|
|
for tikzfiles in "$tikzfiles"; do tikzfilenumber=${#tikzfiles}; done
|
|
|
|
echo "cheRTeX detected $tikzfilenumber TikZ files for processing"
|
|
|
|
echo "Starting TikZ file processing..."
|
|
|
|
simpledelay.sh 2
|
|
|
|
|
|
|
|
for tikzfilename in $tikzfiles; do
|
|
|
|
# Call tikz2pdf
|
|
|
|
echo "<Executing> tikz2pdf $tikzfilename"
|
|
|
|
tikz2pdf --once $tikzfilename
|
|
|
|
done
|
|
|
|
echo "Completed TikZ file processing"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ $usrchoice == "clean-up" || $usrchoice == "2" ]]; then
|
|
|
|
echo "<2> 'clean-up' chosen"
|
|
|
|
rm $auxfiles
|
|
|
|
# Still, a rather crude way of cleaning up...
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ $usrchoice == "wipe-dir" || $usrchoice == "3" ]]; then
|
|
|
|
echo "<3> 'wipe-dir' chosen"
|
|
|
|
## Remove all but non-essential files
|
|
|
|
# get the name of the current directory
|
|
|
|
currdirname=${PWD##*/}
|
|
|
|
# get a timestamp
|
|
|
|
timestamp=$(date +%s)
|
|
|
|
# create a unique tmp-dir name
|
|
|
|
tmpdirname="${timestamp}-${currdirname}"
|
|
|
|
# make a directory in chepec/tmp with the name of the current dir
|
|
|
|
mkdir /media/bay/taha/chepec/tmp/$tmpdirname
|
|
|
|
# Copy the contents of the current directory to the tmp/$currdirname directory
|
|
|
|
cp * -R /media/bay/taha/chepec/tmp/$tmpdirname
|
|
|
|
# Empty the current directory of all contents
|
|
|
|
rm * -R # note: hidden files and subdir unaffected
|
|
|
|
# Return the stuff we want to keep after wipe-dir
|
|
|
|
# (we are of course assuming that the following 4 file(type)s always exist)
|
|
|
|
# (if in fact they do not exist, use conditional statements instead (see below)
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/*.Rnw .
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/vc .
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/vc.tex .
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/vc-git.awk .
|
|
|
|
## Return stuff that may not always exist (check first...)
|
|
|
|
## The use of conditionals is mainly to avoid annoying "file does not exist" messages...
|
|
|
|
# Return *.Rproj file (removal is unnecessary and makes RStudio less useful)
|
|
|
|
Rprojfiles=`ls -1 /media/bay/taha/chepec/tmp/$tmpdirname/*.Rproj 2>/dev/null | wc -l`
|
|
|
|
if [ $Rprojfiles != 0 ]; then
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/*.Rproj .
|
|
|
|
fi
|
|
|
|
# Return *.rda files (considering peak-data files, which "cost" a lot to create)
|
|
|
|
rdafiles=`ls -1 /media/bay/taha/chepec/tmp/$tmpdirname/*.rda 2>/dev/null | wc -l`
|
|
|
|
if [ $rdafiles != 0 ]; then
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/*.rda .
|
|
|
|
fi
|
|
|
|
# Return *.Rmd files (R markdown source files)
|
|
|
|
Rmdfiles=`ls -1 /media/bay/taha/chepec/tmp/$tmpdirname/*.Rmd 2>/dev/null | wc -l`
|
|
|
|
if [ $Rmdfiles != 0 ]; then
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/*.Rmd .
|
|
|
|
fi
|
|
|
|
# Return *.css files (css files) [for sample-matrix]
|
|
|
|
cssfiles=`ls -1 /media/bay/taha/chepec/tmp/$tmpdirname/*.css 2>/dev/null | wc -l`
|
|
|
|
if [ $cssfiles != 0 ]; then
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/*.css .
|
|
|
|
fi
|
|
|
|
# Return .knitme file [empty file used to indicate knitr jobs]
|
|
|
|
knitmefile=`ls -1 /media/bay/taha/chepec/tmp/$tmpdirname/.knitme 2>/dev/null | wc -l`
|
|
|
|
if [ $knitmefile != 0 ]; then
|
|
|
|
cp /media/bay/taha/chepec/tmp/$tmpdirname/.knitme .
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "Terminating..."
|
|
|
|
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
## Here is the wild land of more than one *.Rnw file in current directory
|
|
|
|
|
|
|
|
echo "<cheRTeX> This script can be run with one argument is process mode,"
|
|
|
|
echo "<cheRTeX> or with zero arguments in post-processing mode."
|
|
|
|
echo "<cheRTeX> Terminating..."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# Depending on whether the clock uses summer or wintertime, the date string length
|
|
|
|
# will differ by one (CEST vs CET).
|
|
|
|
# Just to be neat, we will take this into consideration when constructing the
|
|
|
|
# "job completed" block below.
|
|
|
|
cetcest=$(date +%Z)
|
|
|
|
|
|
|
|
# keep track of runtime of entire script
|
|
|
|
endtime=$(date +%s)
|
|
|
|
runtime=$(( $endtime - $starttime ))
|
|
|
|
|
|
|
|
echo "-------------------------------------"
|
|
|
|
# the padding for runtime makes the formatting work
|
|
|
|
# three digits for seconds is enough for just above 15 minutes
|
|
|
|
printf "=== chertex.sh completed in %03d s ===\n" $runtime
|
|
|
|
if [[ $cetcest == "CET" ]]; then
|
|
|
|
echo "=== $(date) ==="
|
|
|
|
else
|
|
|
|
echo "=== $(date) ==="
|
|
|
|
fi
|
|
|
|
echo "-------------------------------------"
|
|
|
|
simpledelay.sh 3
|
|
|
|
|
|
|
|
exit 0
|