tikz-trackschematic/build.sh

1133 lines
31 KiB
Bash
Executable File

#!/usr/bin/env sh
# Copyright (c) 2018 - 2022, Martin Scheidt (ISC license)
# Permission to use, copy, modify, and/or distribute this file for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
#
# Variables in upper case, e.g.: $VARIABLE
# Functions in lower case as action with underscore, e.g.: do_something
#
# Halt on error
set -e
## -- print usage
print_usage() {
cat << EOF
Usage: ./build.sh [OPTIONS]
install, test or release a package for tikz-trackschematic
-h, --help Display this help message.
-s, --silent Run script in silent mode.
The -s option overrides any previous -v or -d options.
-v, --verbose Run script in verbose mode.
The -v option overrides any previous -s or -d options.
-d, --debug Run script in debug mode.
The -d option overrides any previous -s or -v options.
-m, --messy Do not clean up afterwards.
-n, --non-interactive Run script with no interaction.
-i, --install-dev Install as dev-package in local TeX Live environment.
The -i option overrides any previous -u option.
-u, --uninstall-dev Deinstall dev-package from local TeX Live environment.
The -u option overrides any previous -i option.
-x, --memory-increase Increase available TeX memory.
-t, --test Tests the current src/ against the test/.
-c, --compile-doc Compile documentation sources.
-y, --compile-symbology Compile symbology sources.
-r, --release VERSION Creates a .zip with the release for given VERSION in
Semantic Versioning with leading 'v', e.g: v1.0.0
-z, --update-cite DOI Updates the CITATION.cff with the current version in
CHANGELOG.md and a given DOI
EOF
}
## -- processes getopts
VERBOSITY=2 # set by cli argument
NOINTERACT=0 # set by cli argument
INSTALL=0 # set by cli argument
TEXMEMORY=0 # set by cli argument
TESTING=0 # set by cli argument
COMPILE=0 # set by cli argument
SYMBOLOGY=0 # set by cli argument
RELEASE=0 # set by cli argument
CITATION=0 # set by cli argument
CLEANUP=1 # set by cli argument
process_arguments() {
while true; do
# loop condition - test for empty string:
if [ -z "$1" ]; then break; fi
# loop test
case $1 in
-h|--help)
print_usage
exit 0
;;
-s|--silent)
VERBOSITY=0
;;
-v|--verbose)
VERBOSITY=3
;;
-d|--debug)
VERBOSITY=4
;;
-m|--messy)
CLEANUP=0
;;
-n|--non-interactive)
NOINTERACT=1
;;
-i|--install-dev)
INSTALL=1
;;
-u|--uninstall-dev)
INSTALL=2
;;
-x|--memory-increase)
TEXMEMORY=1
;;
-t|--test)
TESTING=1
;;
-c|--compile-doc)
COMPILE=1
;;
-y|--compile-symbology)
SYMBOLOGY=1
;;
-r|--release)
RELEASE=1
shift
if [ -z "$1" ] || [ "`echo $1 | cut -c1-1`" = "-" ]; then
print_usage
exit 1
fi
VERSION_STR=$1
;;
-z|--update-cite)
CITATION=1
shift
if [ -z "$1" ] || [ "`echo $1 | cut -c1-1`" = "-" ]; then
print_usage
exit 1
fi
DOI=$1
;;
*)
print_usage
exit 1
;;
esac
shift
done
}
## -- run variables
#
PDFTOPPM_CONVERT=0 # set by check_pdftoppm
POLICY_MOD=0 # set by check_imagemagick_policy
#
ERROR_OCCURRED=0
## -- logging functions
## colors
RED="\033[0;31m"
GREEN="\033[0;32m"
YELLOW="\033[0;33m"
COLOR_RESET="\033[0;m"
## cross platform echo option
if [ "`echo -n`" = "-n" ]; then
n=""; c="\c"
else
n="-n"; c=""
fi
log() {
NO_LINE_BREAK=0
case $2 in
-n) NO_LINE_BREAK=1;;
esac
COLOR=${COLOR_RESET}
case $1 in
1) COLOR=${RED};;
2) COLOR=${GREEN};;
4) COLOR=${YELLOW};;
esac
if [ $VERBOSITY -ge $1 ]; then
shift
if [ $NO_LINE_BREAK = 0 ]; then
echo "${COLOR}$@${COLOR_RESET}" | fold -s
else
shift
echo $n "${COLOR}$@ $c${COLOR_RESET}" | fold -s
fi
fi
}
log_show() { log 0 $@; } # will always show
log_error() { log 1 $@; } # print message in RED ; but not when --silent
log_info() { log 2 $@; } # print message in GREEN ; but not when --silent
log_note() { log 3 $@; } # print message ; with --verbose and --debug
log_debug() { log 4 $@; } # print message in YELLOW; only with --debug
## -- user interaction
user_confirmation () {
if [ ! $NOINTERACT = 1 ]; then
log_show $@
log_show -n "(y/n)"
while true; do
read -p "" answer
case $answer in
[Yy]* ) break;;
[Nn]* ) exit 1;;
* ) log_show "Please answer yes or no.";;
esac
done
fi
}
## -- commands
check_path() {
# test for project specific files
STATUS=0
set -- doc/tikz-trackschematic-documentation.sty src/tikz-trackschematic.sty test/turnout.tex
for FILE in "$@"; do
if [ ! -e $FILE ]; then
STATUS=1
fi
done
if [ $STATUS = 0 ]; then
log_note "Build script is within the project folder."
return 0
fi
log_error "Please run this script from inside the project folder!"
exit 1
}
## checks for installed software
sedi () {
## cross platform sed -i option without a backup file name
# https://stackoverflow.com/questions/2320564/sed-i-command-for-in-place-editing-to-work-with-both-gnu-sed-and-bsd-osx
sed --version >/dev/null 2>&1 && sed -i -- "$@" || sed -i "" "$@"
}
check_zip() {
# check for zip
STATUS=0
command -v zip >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "zip found"
return 0
fi
log_error "Program 'zip' not found. Be sure to have zip installed!"
exit 1
}
check_sudo() {
# checks if sudo is available
STATUS=0
rootrun=""
# If we are root, we do note require sudo
if [ "$EUID" = 0 ]; then
log_note "you are root"
return 0
fi
command -v sudo >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "sudo found"
rootrun="sudo"
return 0
else
log_debug "sudo failed."
fi
log_error "This script must be run as root!"
exit 1
}
check_texlive() {
# check for kpsewhich (and mktexlsr)
STATUS=0
command -v kpsewhich >/dev/null 2>&1 || STATUS=1
command -v mktexlsr >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "kpsewhich and mktexlsr found"
TEXMFLOCAL=$(kpsewhich --var-value TEXMFLOCAL)
return 0
fi
log_error "Program 'kpsewhich' or 'mktexlsr' not found. Be sure to use texlive or mactex!"
exit 1
}
check_latexmk() {
# check for latexmk
STATUS=0
command -v latexmk >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "latexmk found"
return 0
fi
log_error "Program 'latexmk' not found. Be sure to have texlive or mactex installed!"
exit 1
}
check_pdflatex() {
# check for pdflatex
STATUS=0
command -v pdflatex >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "pdflatex found"
return 0
fi
log_error "Program 'pdflatex' not found. Be sure to have texlive or mactex installed!"
exit 1
}
check_imagemagick() {
# check for ImageMagick/compare
STATUS=0
command -v compare >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "compare found"
return 0
fi
log_error "Program 'compare' not found. Be sure to have ImageMagick installed!"
exit 1
}
check_pdftoppm() {
# check for poppler/pdftoppm
STATUS=0
command -v pdftoppm >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "pdftoppm found"
PDFTOPPM_CONVERT=1
return 0
fi
log_note "Program 'pdftoppm' not found."
# no # exit 1 ## can still modify ImageMagick policy!
}
check_pdf2svg() {
# check for pdf2svg
STATUS=0
command -v pdf2svg >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "pdf2svg found"
svg_convert="pdf2svg"
return 0
fi
# check for poppler/pdftocairo
STATUS=0
command -v pdftocairo >/dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "pdftocairo found"
svg_convert="pdftocairo -svg"
return 0
fi
log_note "Program 'pdf2svg' or 'pdftocairo' not found."
exit 1
}
check_imagemagick_policy() {
STATUS=1
convert -list policy | grep -q "pattern: PDF" || STATUS=0
if [ $STATUS = 0 ]; then
log_note "ImageMagick allows to convert PDFs. Great!"
return 0
else
log_note "ImageMagick does not allow to convert PDFs."
## check for alternative
check_pdftoppm # if pdftoppm is available, then PDFTOPPM_CONVERT=1
if [ $PDFTOPPM_CONVERT = 0 ]; then
## modify ImageMagick-6/policy.xml
user_confirmation "Be sure to have either poppler(-utils) installed or an ImageMagick \
policy which allows for PDF conversion! Do you wish to temporaly remove \
the policy preventing ImageMagick from converting PDFs?"
check_sudo
POLICY_PATH=$(convert -list policy | grep "Path" | awk "NR==1" | cut -d " " -f2) # default /etc/ImageMagick-*/policy.xml
if [ ! -e $POLICY_PATH ]; then
VERSION=$(convert --version | grep "Version" | cut -d " " -f3 | cut -d "." -f1 )
POLICY_PATH="/etc/ImageMagick-${VERSION}/policy.xml"
if [ ! -e $POLICY_PATH ]; then
log_error "ImageMagick policy is preventing converting PDFs to PNGs and program \
'pdftoppm' was not found. Modifying the policy temporaly failed! Be sure \
to have either poppler(-utils) installed or an ImageMagick policy which \
allows for PDF conversion!"
exit 1
fi
fi
POLICY_MOD=1
$rootrun sed -i".backup" 's/^.*policy.*coder.*none.*PDF.*//' $POLICY_PATH
log_note "Modified ${POLICY_PATH}!"
fi
fi
}
check_trackschematic() {
# check for tikz-trackschematic
STATUS=0
TEXMFLOCAL=$(kpsewhich --var-value TEXMFLOCAL)
DEVDIR=$(find $TEXMFLOCAL -name 'tikz-trackschematic-dev')
ls $DEVDIR/tikz-trackschematic-dev.sty >> /dev/null 2>&1 || STATUS=1
if [ $STATUS = 0 ]; then
log_note "Package tikz-trackschematic-dev found."
return 0
fi
log_note "Package 'tikz-trackschematic-dev' not found - using project src/."
export TEXINPUTS=.:$(pwd)/src/:$TEXINPUTS
}
## checks for updated repository
check_version_number() {
while true; do
# loop condition - test format of $VERSION_STR:
echo "$VERSION_STR" | egrep -q "v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)?" && break;
# loop test
if [ $NOINTERACT = 0 ]; then
log_error "Your version '$VERSION_STR' has not the correct format!"
log_show -n "Please specify as Semantic Versioning ( e.g. v1.0.0 ): "
read VERSION_STR
else
log_error "Your version '$VERSION_STR' has not the correct format! \
Please use Semantic Versioning with leading 'v'"
exit 1
fi
done
# remove leading 'v'
VERSION_NUM=$(echo $VERSION_STR | cut -c 2-)
}
check_versionhistory() {
# check if $VERSION is present in doc/versionhistory.tex
STATUS=0
grep -qs "vhEntry{$VERSION_NUM" doc/versionhistory.tex || STATUS=1
if [ $STATUS = 0 ]; then
log_note "Version $VERSION_NUM is present in versionhistory.tex."
return 0
fi
log_error "Version $VERSION_NUM not found in versionhistory.tex. \
Be sure to edit versionhistory.tex and specify current version!"
exit 1
}
check_changelog() {
# check if $VERSION is present in CHANGELOG.md
STATUS=0
grep -qs "Version \[$VERSION_NUM\]" CHANGELOG.md || STATUS=1
if [ $STATUS = 0 ]; then
log_note "Version $VERSION_NUM is present in CHANGELOG.md."
return 0
fi
log_error "Version $VERSION_NUM not found in CHANGELOG.md. \
Be sure to edit CHANGELOG.md and specify current version!"
exit 1
}
check_date() {
## extract DATE from versionhistory.tex, CHANGELOG.md, and CITATION.cff
# fallback: DATE=$(date "+%Y-%m-%d")
#
STATUS=0
#
LINE_1=$(grep "vhEntry{$VERSION_NUM" doc/versionhistory.tex)
LINE_2=$(grep "Version \[$VERSION_NUM\]" CHANGELOG.md)
# LINE_3=$(grep "date-released:" CITATION.cff)
DATEISO_1=$(echo $LINE_1 | egrep -o '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])')
DATEISO_2=$(echo $LINE_2 | egrep -o '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])')
# DATEISO_3=$(echo $LINE_3 | egrep -o '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])')
if [ $DATEISO_1 != $DATEISO_2 ]; then
STATUS=1
fi
# if [ $DATEISO_1 != $DATEISO_3 ]; then
# STATUS=1
# fi
if [ $STATUS = 0 ]; then
DATE="$DATEISO_1"
log_note "The date $DATE was extracted from versionhistory.tex and CHANGELOG.md."
return 0
fi
log_error "The date in versionhistory.tex, CHANGELOG.md, and CITATION.cff did not match.\
Be sure to edit versionhistory.tex, CHANGELOG.md, or CITATION.cff and modifiy the date!"
exit 1
}
check_changelog_url1() {
## extract urls from CHANGELOG.md
STATUS=0
LINE=$(grep "\[$VERSION_NUM\]: https://" CHANGELOG.md)
echo $LINE | grep -qs "...$VERSION_STR" || STATUS=1
if [ $STATUS = 0 ]; then
log_note "Version $VERSION_NUM URL is present in CHANGELOG.md."
return 0
fi
log_error "Version $VERSION_NUM URL was not found in CHANGELOG.md. \
Be sure to edit CHANGELOG.md and specify a URL for the current version!"
exit 1
}
check_changelog_url2() {
## extract urls from CHANGELOG.md
STATUS=0
LINE=$(grep "\[Unreleased\]: https://" CHANGELOG.md)
echo $LINE | grep -qs "/$VERSION_STR..." || STATUS=1
if [ $STATUS = 0 ]; then
log_note "The URL for [Unreleased] was also updated in CHANGELOG.md! Thx!"
return 0
fi
log_show "WARNING: URL for [Unreleased] in CHANGELOG.md does not reflect the current version $VERSION_NUM."
log_show "WARNING: Be sure to edit CHANGELOG.md and specify current version!"
user_confirmation "Do you wish to continue without updated URL for [Unreleased]?"
if [ $NOINTERACT = 1 ]; then
log_error "Aborting in batch mode!"
exit 1
fi
}
## functionality
create_release() {
####
# This function produces a .zip-file in accordance to the requirements for CTAN.
# For more information see https://ctan.org/help/upload-pkg.
####
user_confirmation "Do you wish to create a release for the version $VERSION_NUM?"
## create backup-file und update VERSIONDATE in tikz-trackschematic.sty
sed -i".backup" -e"s/%\[VERSIONDATE/\[$DATE $VERSION_STR/g" src/tikz-trackschematic.sty
sedi "/%%\[SCRIPT\]/d" src/tikz-trackschematic.sty
log_note "Updated version in src/tikz-trackschematic.sty"
## -- create zip-archive
# create temporary folder
TMP="tikz-trackschematic-$VERSION_STR"
mkdir -p $TMP
# copy README, CHANGELOG, LICENSE and CITATION
cp README.md $TMP/README.md
cp CHANGELOG.md $TMP/CHANGELOG.md
cp LICENSE $TMP/LICENSE
cp CITATION.cff $TMP/CITATION.cff
# copy and rename documentation
cp doc/tikz-trackschematic-documentation.sty $TMP/
cp doc/manual.pdf $TMP/tikz-trackschematic.pdf
cp doc/manual.tex $TMP/tikz-trackschematic.tex
cp doc/snippets.pdf $TMP/tikz-trackschematic-snippets.pdf
cp doc/snippets.tex $TMP/tikz-trackschematic-snippets.tex
cp doc/symbology-table.pdf $TMP/tikz-trackschematic-symbology-table.pdf
cp doc/symbology-table.tex $TMP/tikz-trackschematic-symbology-table.tex
mkdir $TMP/tikz-trackschematic-examples
mkdir $TMP/tikz-trackschematic-snippets
cp -R doc/examples/* $TMP/tikz-trackschematic-examples/
cp -R doc/snippets/* $TMP/tikz-trackschematic-snippets/
log_note "copied documentation"
# copy src-files
for SRC in src/*; do
EXT=${SRC##*.}
# do not copy backup created by sed
if [ $EXT != "backup" ]; then
cp $SRC $TMP/
fi
done
log_note "copied src-files"
# zip package
zip -r $TMP.zip $TMP/* >/dev/null 2>&1
log_note "compressed the release in $TMP.zip"
}
create_release_notes() {
user_confirmation "Do you wish to create a release notes for the version $VERSION_NUM?"
## -- create release note as excerpt from CHANGELOG.md
# determine beginning and end in CHANGELOG.md
TOP=$(grep -n "Version \[$VERSION_NUM\]" CHANGELOG.md | cut -d: -f1)
awk "NR>$TOP" CHANGELOG.md > release-note.tmp.md
BOTTOM=$(grep -n -m 1 "## Version\|[Unreleased]:" release-note.tmp.md | cut -d: -f1)
BOTTOM=$(( $TOP + $BOTTOM ))
BOTTOM=$(( $BOTTOM - 2 ))
TOP=$(( $TOP + 1 ))
# extract the excerpt
awk "NR>$TOP&&NR<$BOTTOM" CHANGELOG.md > release-note-$VERSION_STR.md
sedi "s/###/##/g" release-note-$VERSION_STR.md
}
create_ctan_configuration() {
# modify the file .github/tex/tikz-trackschematic.pkg for ctan-o-mat
# 1. replace \version{}%%[SCRIPT]
sed -i".backup" -e"s/version{}%%\[SCRIPT\]/version{$DATE $VERSION_STR}/g" .github/tex/tikz-trackschematic.pkg
# 2. replace \file{}%%[SCRIPT]
sedi "s/file{}%%\[SCRIPT\]/file{tikz-trackschematic-$VERSION_STR.zip}/g" .github/tex/tikz-trackschematic.pkg
# 3. replace %RELEASE-NOTES%%[SCRIPT]
awk '/%RELEASE-NOTES%%\[SCRIPT\]/{system("cat release-note-*.md");next}1' .github/tex/tikz-trackschematic.pkg > .github/tex/tikz-trackschematic.tmp.pkg
mv .github/tex/tikz-trackschematic.tmp.pkg .github/tex/tikz-trackschematic.pkg
}
create_zenodo_metadata() {
# modify the file .github/zenodo/metadata.json for zenodo upload
# 1. replace "version": "%%[SCRIPT]"
sed -i".backup" -e"s/\"version\": \"%%\[SCRIPT\]\"/\"version\": \"$VERSION_STR\"/g" .github/zenodo/metadata.json
# 2. replace "publication_date": "%%[SCRIPT]"
sedi "s/\"publication_date\": \"%%\[SCRIPT\]\"/\"publication_date\": \"$DATE\"/g" .github/zenodo/metadata.json
}
run_compile_documentation() {
## compile order
# 1. manual, symbology-table, snippets
# 2. examples
# 3. symbology
cd doc/
mkdir -p .tex
log_debug "entered documentation dir"
## 1. main documentation
set -- manual symbology-table snippets
for NAME in "$@"; do
log_info -n "compiling $NAME:"
#
## TeX build
EXIT_CODE=0
/usr/bin/time -p -o .tex/${NAME}.time \
latexmk -pdf -f -g -emulate-aux-dir -auxdir=.tex -outdir=.tex $NAME.tex >> /dev/null 2>&1 || EXIT_CODE=1
#
TIME=$(awk "NR==2" .tex/${NAME}.time | cut -d " " -f2)
# understanding TeX statistics:
# -> https://tex.stackexchange.com/questions/26208/components-of-latexs-memory-usage
MEMORY_USAGE=$(grep "words of memory out of" .tex/${NAME}.log | cut -d " " -f2)
MEMORY_USAGE=$(($MEMORY_USAGE/1000))
#
if [ $EXIT_CODE = 0 ]; then
log_info " - build successful in ${TIME}s and with ${MEMORY_USAGE}k memory."
#
mv .tex/$NAME.pdf $NAME.pdf
log_debug "copied $NAME to doc/"
else
ERROR_OCCURRED=1
log_error " - build failed."
fi
done
## 2. examples
cd examples/
mkdir -p .tex
EXAMPLEDIR="../examples"
for EXAMPLE in `ls $EXAMPLEDIR/*.tex`; do
FILE=$(basename "$EXAMPLE") # remove path
NAME=${FILE%.*} # remove extension
#
log_info -n "compiling $FILE:"
#
## TeX build
EXIT_CODE=0
/usr/bin/time -p -o .tex/${NAME}.time \
latexmk -pdf -f -g -emulate-aux-dir -auxdir=.tex -outdir=.tex $NAME.tex >> /dev/null 2>&1 || EXIT_CODE=1
#
TIME=$(awk "NR==2" .tex/${NAME}.time | cut -d " " -f2)
# understanding TeX statistics:
# -> https://tex.stackexchange.com/questions/26208/components-of-latexs-memory-usage
MEMORY_USAGE=$(grep "words of memory out of" .tex/${NAME}.log | cut -d " " -f2)
MEMORY_USAGE=$(($MEMORY_USAGE/1000))
#
if [ $EXIT_CODE = 0 ]; then
log_info " - build successful in ${TIME}s and with ${MEMORY_USAGE}k memory."
#
mv .tex/$NAME.pdf $NAME.pdf
log_debug "copied $NAME to doc/examples/"
#
if [ $PDFTOPPM_CONVERT = 0 ]; then
# 'compare' will convert the pdf to png
# -> this reasonably fast!
convert -density 300 ${NAME}.pdf ${NAME}.png >> /dev/null 2>&1
else
# use 'pdftoppm' convert the pdf to png
# -> this is slower!
pdftoppm -png -r 300 -singlefile ${NAME}.pdf ${NAME}.png
fi
log_debug "converted $NAME.pdf to PNG"
else
ERROR_OCCURRED=1
log_error " - build failed."
fi
done
cd ..
## 3. symbology
cd ..
}
run_compile_symbology() {
cd doc/symbology/
mkdir -p .tex
for FILE in symbols_tikz/*.tikz; do
SYMBOL=$(basename $FILE .tikz)
log_note "converting: $SYMBOL"
## -- header tex file
echo '\\documentclass[tikz,border=0]{standalone}' > tmp.tex
echo '\\usepackage[dev]{tikz-trackschematic}' >> tmp.tex
echo '\\begin{document}' >> tmp.tex
echo '\\begin{tikzpicture}[font=\\sffamily]' >> tmp.tex
## -- input symbol
echo '\\input{'$FILE'}' >> tmp.tex
## -- footer tex file
echo '\\end{tikzpicture}' >> tmp.tex
echo '\\end{document}' >> tmp.tex
# echo "---------------"
# cat tmp.tex
# echo "---------------"
## -- compile tmp.tex
# pdflatex -output-directory=.tex tmp.tex
pdflatex -output-directory=.tex -interaction=batchmode tmp.tex 2>&1 > /dev/null
## -- copy and convert symbols
## SVG
$svg_convert .tex/tmp.pdf symbols_svg/$SYMBOL.svg
#
## PNG
if [ $PDFTOPPM_CONVERT = 0 ]; then
# 'compare' will convert the pdf to png
# -> this reasonably fast!
convert -density 600 .tex/tmp.pdf symbols_png/$SYMBOL.png >> /dev/null 2>&1
else
# use 'pdftoppm' convert the pdf to png
# -> this is slower!
pdftoppm -png -r 600 -singlefile .tex/tmp.pdf symbols_png/$SYMBOL.png
fi
#
mv .tex/tmp.pdf symbols_pdf/$SYMBOL.pdf
done
cd ../..
}
run_test_cases() {
cd test/
TESTDIR="../test"
mkdir -p .tex
STATUS=0
# Start with an empty List:
FAILED=""
for TEST in `ls $TESTDIR/*.tex`; do
# setup
FILE=$(basename "$TEST") # remove path
NAME=${FILE%.*} # remove extension
ADD_TO_LIST=0
#
log_info "$NAME test:"
#
#
## TeX build
#
EXIT_CODE=0
/usr/bin/time -p -o .tex/${NAME}.time \
pdflatex -output-directory=.tex -interaction=NOINTERACT -halt-on-error ${NAME}.tex >> /dev/null 2>&1 || EXIT_CODE=1
#
TIME=$(awk "NR==2" .tex/${NAME}.time | cut -d " " -f2)
# understanding TeX statistics:
# -> https://tex.stackexchange.com/questions/26208/components-of-latexs-memory-usage
MEMORY_USAGE=$(grep "words of memory out of" .tex/${NAME}.log | cut -d " " -f2)
MEMORY_USAGE=$(($MEMORY_USAGE/1000))
#
if [ $EXIT_CODE = 0 ]; then
log_info " - build successful in ${TIME}s and with ${MEMORY_USAGE}k memory."
else
STATUS=1
ADD_TO_LIST=1
log_error " - build failed."
fi
#
#
## compare images with following compare metrics
# AE: absolute error count, number of different pixels (-fuzz affected)
# DSSIM: structural dissimilarity index
# FUZZ: mean color distance
# MAE: mean absolute error (normalized), average channel error distance
# MEPP: mean error per pixel (normalized mean error, normalized peak error)
# MSE: mean error squared, average of the channel error squared
# NCC: normalized cross correlation
# PAE: peak absolute (normalized peak absolute)
# PHASH: perceptual hash for the sRGB and HCLp colorspaces.
# PSNR: peak signal to noise ratio
# RMSE: root mean squared (normalized root mean squared)
# SSIM: structural similarity index
#
EXIT_CODE=0
if [ $PDFTOPPM_CONVERT = 0 ]; then
# 'compare' will convert the pdf to png
# unless the policy of ImageMagick prevents it
# -> this reasonably fast!
compare -metric RMSE -colorspace RGB .tex/${NAME}.pdf ${NAME}_expected.pdf NULL: >> /dev/null 2>&1 || EXIT_CODE=1
else
# use 'pdftoppm' convert the pdf to png
# then use 'compare' for comparison without converting
# -> this is slower!
pdftoppm -png -r 144 -singlefile .tex/${NAME}.pdf .tex/${NAME}
pdftoppm -png -r 144 -singlefile ${NAME}_expected.pdf .tex/${NAME}_expected
compare -metric RMSE -colorspace RGB .tex/${NAME}.png .tex/${NAME}_expected.png NULL: >> /dev/null 2>&1 || EXIT_CODE=1
fi
if [ $EXIT_CODE = 0 ]; then
log_info " - comparison successful."
else
STATUS=1
ADD_TO_LIST=1
log_error " - comparison failed."
fi
## if a test failed add to list
if [ $ADD_TO_LIST = 1 ]; then
if [ -z "$FAILED" ]; then
# first item
FAILED="$NAME"
else
FAILED="$FAILED, $NAME"
fi
fi
done
if [ $STATUS = 0 ]; then
log_info "\n=> All tests passed!\n"
else
log_error "\n=> Some or all tests failed!"
log_debug "The following tests failed: ${FAILED}!"
ERROR_OCCURRED=1
fi
cd ..
}
link_dev_files() {
# destination folder inside the TeX Live installation
TEXMFLOCAL=$(kpsewhich --var-value TEXMFLOCAL)
DEVDIR="$TEXMFLOCAL/tex/latex/tikz-trackschematic-dev"
PROJECTDIR=$(pwd -P)
user_confirmation "Do you wish to install this package for development to $DEVDIR?"
# make sure that destination folder exists
if [ ! -d "$DEVDIR" ]; then
$rootrun mkdir -p $DEVDIR
fi
# link every file in src/ and rename it
for SRC in src/*; do
FILE=$(basename "$SRC") # remove path
NAME=${FILE%.*} # remove extension
PREFIX=${NAME%%.*}
POSTFIX=${NAME#*.}
EXT=${SRC##*.}
if [ "$PREFIX" = "$POSTFIX" ]; then
DST="$PREFIX-dev.$EXT"
else
DST="$PREFIX-dev.$POSTFIX.$EXT"
fi
$rootrun ln -sfn $PROJECTDIR/$SRC $DEVDIR/$DST
if [ $VERBOSITY = 1 ]; then
echo "linked '$DST'"
fi
done
# update TeX Live installation
TEXlsr=`which mktexlsr`
if [ $VERBOSITY -ge 3 ]; then
$rootrun $TEXlsr
else
$rootrun $TEXlsr --quiet
fi
}
remove_dev_files() {
# destination folder inside the TeX Live installation
cd $DEVDIR # from check_trackschematic
user_confirmation "Do you wish to remove the package '$DEVDIR'?"
log_note "removing $DEVDIR!"
$rootrun rm -f *
cd ..
$rootrun rmdir tikz-trackschematic-dev
# update TeX Live installation
TEXlsr=`which mktexlsr`
if [ $VERBOSITY -ge 3 ]; then
$rootrun $TEXlsr
else
$rootrun $TEXlsr --quiet
fi
}
change_tex_memory() {
## compiling snipptes.tex may run out of memory!
## to increase available memory find local texmf.cnf:
TEXMF_PATH=$(kpsewhich -a texmf.cnf | awk "NR==1") # default .../texlive/YYYY/texmf.cnf
log_note "Found local texmf.cnf at $TEXMF_PATH"
##
## check for already made changes
STATUS=0
grep -qs '%% \[tikz-trackschematic\] increase available memory' $TEXMF_PATH || STATUS=1
if [ $STATUS = 0 ]; then
log_note "$TEXMF_PATH has already been modified!"
return 0
fi
##
user_confirmation "Do you wish to increase TeX memory by modifying the file $TEXMF_PATH?"
## increase available memory
echo '%% [tikz-trackschematic] increase available memory' | $rootrun tee -a $TEXMF_PATH >> /dev/null 2>&1
echo 'main_memory = 12000000' | $rootrun tee -a $TEXMF_PATH >> /dev/null 2>&1
echo 'extra_mem_bot = 12000000' | $rootrun tee -a $TEXMF_PATH >> /dev/null 2>&1
echo 'font_mem_size = 12000000' | $rootrun tee -a $TEXMF_PATH >> /dev/null 2>&1
echo 'pool_size = 12000000' | $rootrun tee -a $TEXMF_PATH >> /dev/null 2>&1
echo 'buf_size = 12000000' | $rootrun tee -a $TEXMF_PATH >> /dev/null 2>&1
## update TeX Live installation
TEXlsr=`which mktexlsr`
if [ $VERBOSITY -ge 3 ]; then
$rootrun $TEXlsr
else
$rootrun $TEXlsr --quiet
fi
}
update_citation() {
## use CHANGELOG.md as source for $VERSION and $DATE
CHANGELOG_LINE=$(grep "Version \[" CHANGELOG.md | awk "NR==1")
VERSION=$(echo $CHANGELOG_LINE | egrep -o '(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)?')
DATE=$(echo $CHANGELOG_LINE | egrep -o '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])')
## check for already made changes
STATUS=0
grep -qs "version: v$VERSION" CITATION.cff || STATUS=1
if [ $STATUS = 0 ]; then
log_note "CITATION.cff is already up to date!"
return 0
fi
## find lines in CITATION.cff
VERSION_LINE=$(grep -n 'version: v' CITATION.cff | cut -d: -f1)
DATE_LINE=$(grep -n 'date-released:' CITATION.cff | cut -d: -f1)
# select the second DOI
DOI_LINE=$(grep -n 'type: doi' CITATION.cff | cut -d: -f1 | awk "NR==2")
DOI_LINE=$(( $DOI_LINE + 1 ))
## update CITATION.cff
sedi "${VERSION_LINE}s|.*|version: v${VERSION}|" CITATION.cff
sedi "${DATE_LINE}s|.*|date-released: ${DATE}|" CITATION.cff
sedi "${DOI_LINE}s|.*| value: ${DOI}|" CITATION.cff
}
cleanup() {
## -- cleanup
## from create_release
if [ $CLEANUP = 1 ]; then
## from run_test_cases
if [ $TESTING = 1 ]; then
# remove TMP-folder
rm -rf test/.tex
fi
## from check_imagemagick_policy
if [ $POLICY_MOD = 1 ]; then
# undo changes to /etc/ImageMagick-6/policy.xml by sed
$rootrun mv ${POLICY_PATH}.backup $POLICY_PATH
fi
## from run_compile
if [ $COMPILE = 1 ]; then
# remove TMP-folder
rm -rf doc/examples/.tex
rm -rf doc/.tex
fi
## from run_symbology
if [ $SYMBOLOGY = 1 ]; then
# remove TMP-folder
rm -rf doc/symbology/.tex/
rm doc/symbology/tmp.tex
fi
## from create_release(_notes)
if [ $RELEASE = 1 ]; then
# remove TMP-folder
rm -rf $TMP
# undo changes to tikz-trackschematic.sty by sed
mv src/tikz-trackschematic.sty.backup src/tikz-trackschematic.sty
# remove TMP-release-note
rm release-note.tmp.md
# # undo changes to .github/tex/tikz-trackschematic.pkg by sed
# mv .github/tex/tikz-trackschematic.pkg.backup .github/tex/tikz-trackschematic.pkg
# # undo changes to .github/zenodo/metadata.json by sed
# mv .github/zenodo/metadata.json.backup .github/zenodo/metadata.json
fi
##
log_note "Clean up done!"
fi
}
## -- execution
## Process user arguments
process_arguments $@
check_path
## do what is requested
if [ $INSTALL = 1 ]; then
## install package
check_texlive
check_sudo
##
link_dev_files
fi
if [ $INSTALL = 2 ]; then
## deinstall package
check_texlive
check_trackschematic
check_sudo
##
remove_dev_files
fi
if [ $TEXMEMORY = 1 ]; then
##
check_texlive
check_sudo
##
change_tex_memory
fi
if [ $TESTING = 1 ]; then
##
check_pdflatex
check_trackschematic
check_imagemagick
check_imagemagick_policy
##
run_test_cases
fi
if [ $COMPILE = 1 ]; then
##
check_latexmk
check_trackschematic
check_imagemagick
check_imagemagick_policy
##
run_compile_documentation
fi
if [ $SYMBOLOGY = 1 ]; then
##
check_pdflatex
check_trackschematic
check_imagemagick
check_imagemagick_policy
check_pdf2svg
##
run_compile_symbology
fi
if [ $RELEASE = 1 ]; then
## check if version ist in the correct format
check_version_number
## check if $VERSION is present in CHANGELOG.md, versionhistory.tex, and CITATION.cff
check_versionhistory
check_changelog
check_changelog_url1
check_changelog_url2
check_date
## check for installed software
check_zip
##
create_release
create_release_notes
create_ctan_configuration
create_zenodo_metadata
fi
if [ $CITATION = 1 ]; then
##
update_citation
fi
##
cleanup
##
if [ $ERROR_OCCURRED = 0 ]; then
exit 0
else
exit 1
fi
#EOF