Build LaTeX document and Release PDF #3121
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build LaTeX document and Release PDF | |
# | |
# Version: 11222024 | |
# | |
# Is executed at gooTeX script's prompt. | |
# ############################ | |
# Pamela M. Marcum # | |
# first created: 07/14/2024 # | |
# ############################ | |
# Controls when the action will run. | |
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions | |
# https://mrturkmen.com/posts/build-release-latex/ | |
# https://github.com/PHPirates/travis-ci-latex-pdf/blob/master/.github/workflows/texlive.yml | |
# https://github.com/teatimeguest/setup-texlive-action includes caching | |
# | |
on: | |
workflow_dispatch: | |
inputs: | |
file2compile: | |
description: "Name of .tex file to compile, without the .tex part" | |
required: true | |
default: "myPaper" | |
# Allow only one concurrent deployment, skipping runs quesed between the run in progress and most recent queued | |
#concurrency: | |
# group: "pages" | |
# cancel-in-progress: true | |
# # | |
jobs: | |
# followed: https://dev.to/dessygil/ | |
# how-to-automatically-update-resume-on-your-personal-site-from-overleaf-1fld | |
# https://superuser.com/questions/1455483/how-to-get-wsl-use-git-bash-to-run-a-latexmk-command | |
# https://www.overleaf.com/learn/latex/TeX_engine_command_line_options_for_pdfTeX%2C_XeTeX_and_LuaTeX | |
#_______________________________________________________________________ | |
#| | | |
#| STRIP OUT UNUSED REFERENCES AND CONSTRUCT A PRUNED BIB FILE | | |
#|______________________________________________________________________| | |
pruneBib: | |
runs-on: ubuntu-latest | |
continue-on-error: true | |
permissions: | |
# Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. | |
contents: write | |
# | |
steps: | |
- name: Clone repo | |
uses: actions/checkout@v4 | |
# | |
- name: Prune the bib file | |
# https://www.baeldung.com/linux/regex-matching | |
# https://askubuntu.com/questions/1502281/using-grep-to-search-for-line-that-begins-with-a-variable-whose-value-is-a-dolla | |
# https://stackoverflow.com/questions/13210880/replace-one-substring-for-another-string-in-shell-script | |
# going to strip out all used citations and make a pruned.bib file that can be used as final bib file for submission | |
# purposes rather than having to use whole master bib file. based on stand-alone "pruneMyBibfile" github action file | |
id: pruneBib | |
run: | | |
# determine if the pruned bib file is already being used in the document. If so, we should bypass | |
# all the below because pruned bib file does not need to be created. | |
# First, make sure that there is a bibliography in the document. Otherwise, don't even continue | |
makeNewPrunedBib=false | |
if [[ "$(grep -Eq "^ *\\\\bibliography[{]" ${{ github.event.inputs.file2compile }}.tex)$?" == 0 ]]; then makeNewPrunedBib=true; fi | |
# next, see if pruned.bib is already being used. If so, then bail out now and dont try to recreate the pruned.bib | |
if [[ "$(grep -Eq "^ *\\\\bibliography[{]pruned([.]bib)?" ${{ github.event.inputs.file2compile }}.tex)$?" == 0 ]]; then makeNewPrunedBib=false; fi | |
# | |
if $makeNewPrunedBib; then | |
echo "madePruned=T" >> $GITHUB_OUTPUT | |
rm -f pruned.bib | |
touch pruned.bib | |
# get a list of bib files used in this document: | |
readarray -t bibfiles < <( grep -E "^ *\\\\bibliography[{][^}]+[}]" "${{ github.event.inputs.file2compile }}.tex" | \ | |
sed -r 's/^ *\\bibliography[{]//i' | sed -r 's/} *$//' | sed -r 's/ *//g' ) | |
# the .bib extension might not have been included in the bibfile name, so make sure the extension is there | |
bibfilesstr=$( printf "%s" "${bibfiles[@]}" ) | |
bibfilesstr=$( sed -r 's/\.bib//g' <<<$bibfilesstr | sed -r 's/,/\.bib,/g' | sed -r 's/,/ /g' ) | |
bibfilesstr+='.bib' | |
bibfiles=( $(IFS=" " echo "$bibfilesstr") ) | |
# make sure the bib files are not duplicated | |
readarray -t bibfiles < <(printf '%s\n' "${bibfiles[@]}" | awk '!seen[$0]++') | |
# | |
# =========== Now go through the .tex files and gather up all cited references | |
readarray -t cites < <( grep "\cite" *.tex | sed -r 's/^[^ ]+\.tex: *//' | sed -r 's/^%.*$//' | \ | |
sed -r 's/\a//g' | sed -r 's/\t//g' | sed -r 's/\\cite/\a/ig' | sed -r 's/\a[^{]*(\{[^}]*\})*\{([^}]+)\}/\a\2\t/g' | \ | |
sed -r 's/^[^\a]+\a//' | sed -r 's/\t[^\a]+$//' | sed -r 's/\t[^\a]+\a/ /g' | sed -r 's/[,]/ /g' | sed -r 's/^[0-9]+$//g' ) | |
citesstr=$( printf "%s " "${cites[@]}" ) | |
citesstr=$( sed -r 's/[\a\t]/ /g' <<<$citesstr | sed -r 's/ +/ /g' | sed -r 's/ [^ ]*[:(){}\\/]+[^ ]* / /g' ) | |
# any plus signs in the citation bib code causes problems because they are not escaped. The below substitutes all plus signs and | |
# replaces with escaped pluses, so that grep will perform search on literal plus sign rather than interpret plus sign as meaning "search | |
# for 2 or more of the character to left of plus sign". Periods also cause problems, as do dashes, and have to likewise be treated. | |
citesstr=$( sed -r 's/\+/\\+/g' <<<"$citesstr" | sed -r 's/\-/\\-/g' | sed -r 's/\./\\\./g' ) | |
# break the references into individual entries that go into the array "cites" | |
cites=( $(IFS=" " echo "$citesstr") ) | |
# get a sorted unique list | |
cites=( $(echo "${cites[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ') ) | |
# Search for each of the cites in the bibfile(s) and extract the relevant full bib item for that citation, to | |
# put into the pruned bibfile | |
for (( i=0; i<${#cites[@]}; i++ )); do grep -zoE "@[^{]+\{ *${cites[$i]}[^@]+" "${bibfiles[@]}" | tr '\0' '\n' >> pruned.bib; done | |
sed -ri 's/^[^@]+@/@/g;s/^([^@}])/ \1/g' pruned.bib | |
else | |
echo "madePruned=F" >> $GITHUB_OUTPUT | |
fi | |
continue-on-error: true | |
# | |
- name: Make pruned bibfile available to other jobs | |
if: ${{ steps.pruneBib.outputs.madePruned == 'T' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: pruned-bibfile-artifact | |
path: pruned.bib | |
overwrite: true | |
continue-on-error: true | |
# | |
#- name: post newly-made pruned bibfile to repository | |
# if: ${{ steps.pruneBib.outputs.madePruned == 'T' }} | |
# run: | | |
# git config --global user.email "[email protected]" | |
# git config --global user.name "github actions" | |
# git add pruned.bib | |
# git commit -m "Upload new pruned.bib file" | |
# git push | |
# continue-on-error: true | |
#_______________________________________________________________________ | |
#| | | |
#| DEFINE THE ENVIRONMENTAL VARIABLES | | |
#|______________________________________________________________________| | |
defineVariables: | |
runs-on: ubuntu-latest | |
continue-on-error: true | |
permissions: | |
# Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. | |
contents: write | |
# | |
outputs: | |
corename: ${{ steps.vardefn.outputs.CORENAME }} | |
texfile: ${{ steps.vardefn.outputs.TEXFILE }} | |
outfile: ${{ steps.vardefn.outputs.OUTFILE }} | |
pdffile: ${{ steps.vardefn.outputs.PDFFILE }} | |
pdfhires: ${{ steps.vardefn.outputs.PDFHIRES }} | |
htmlfile: ${{ steps.vardefn.outputs.HTMLFILE }} | |
startfile: ${{ steps.vardefn.outputs.STARTFILE }} | |
timestamp: ${{ steps.vardefn.outputs.TIMESTAMP }} | |
steps: | |
- name: Clone repo | |
uses: actions/checkout@v4 | |
# | |
- name: Define environmental variables | |
id: vardefn | |
run: | | |
echo "CORENAME=${{ github.event.inputs.file2compile }}" >> $GITHUB_OUTPUT | |
echo "TEXFILE=${{ github.event.inputs.file2compile }}.tex" >> $GITHUB_OUTPUT | |
echo "OUTFILE=${{ github.event.inputs.file2compile }}Out.txt" >> $GITHUB_OUTPUT | |
echo "PDFFILE=${{ github.event.inputs.file2compile }}.pdf" >> $GITHUB_OUTPUT | |
echo "PDFHIRES=${{ github.event.inputs.file2compile }}_hiRes.pdf" >> $GITHUB_OUTPUT | |
echo "HTMLFILE=${{ github.event.inputs.file2compile }}.html" >> $GITHUB_OUTPUT | |
echo "STARTFILE=${{ github.event.inputs.file2compile }}START.txt" >> $GITHUB_OUTPUT | |
echo "TIMESTAMP=$(date +'%Y-%m-%dT%H:%M:%SZ') $(($(date +%s%N)/1000000))" >> $GITHUB_OUTPUT | |
continue-on-error: true | |
#_______________________________________________________________________ | |
#| | | |
#| COMPRESS THE IMAGES IF THERE ARE UNCOMPRESSED ONES | | |
#|______________________________________________________________________| | |
compressImages: | |
runs-on: ubuntu-latest | |
continue-on-error: true | |
permissions: | |
# Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. | |
contents: write | |
# | |
steps: | |
- name: Clone repo | |
uses: actions/checkout@v4 | |
# | |
- name: Install ImageMagick | |
uses: mfinelli/setup-imagemagick@v5 | |
with: | |
cache: true | |
continue-on-error: true | |
# | |
- name: Search for uncompressed images, and compress them | |
id: compressImages | |
run: | | |
listOfCompressedFiles='' | |
compressionDone=false | |
bigfile=500000 | |
minDpi=150 # optimal dpi for pdf files | |
maxWidthInches=6.5 #inches | |
maxHeightInches=9.0 #inches | |
maxWidth=$(echo "(($minDpi * $maxWidthInches)+0.5)/1" | bc) | |
maxWidth=${maxWidth%.*} | |
maxHeight=$(echo "(($minDpi * $maxHeightInches)+0.5)/1" | bc) | |
maxHeight=${maxHeight%.*} | |
shopt -s globstar | |
nUncompressed=0 | |
for imagefile in **/*UNCOMPRESSED.*; do | |
newname=$(echo "${imagefile}" | sed 's/UNCOMPRESSED//') | |
pdfname=$(echo "${newname}" | sed 's/\..*$/\.pdf/') | |
fileSize=$( stat -c %s -- "${imagefile}" ) | |
compressionDone=true | |
nUncompressed+=1 | |
if [[ -f "${imagefile}" && ! -L "${imagefile}" && "$fileSize" -gt "$bigfile" && "${imagefile}" =~ UNCOMPRESSED\. ]]; then | |
# Get the current dimensions of the image | |
magick identify -format "%w %h" "${imagefile}" | |
dimensions=$(magick identify -format "%w %h" "${imagefile}") | |
read -r origWidth origHeight <<< "$dimensions" | |
# determine which, if either, dimension exceeds the max desirable size (origWidth origHeight) | |
if [[ "$origWidth" -gt "$origHeight" && "$origWidth" -gt "$maxWidth" ]]; then | |
newWidth=$maxWidth | |
newHeight=$(echo "(($origHeight * $newWidth) / $origWidth) + 0.5" | bc) | |
newHeight=${newHeight%.*} | |
elif [[ "$origWidth" -lt "$origHeight" && "$origHeight" -gt "$maxHeight" ]]; then | |
newHeight=$maxHeight | |
newWidth=$(echo "(($origWidth * $newHeight) / $origHeight) + 0.5" | bc) | |
newWidth=${newWidth%.*} | |
elif [[ "$origWidth" -gt "$maxWidth" ]]; then | |
newWidth=$maxWidth | |
newHeight=$(echo "(($origHeight * $newWidth) / $origWidth) + 0.5" | bc) | |
newHeight=${newHeight%.*} | |
elif [[ "$origHeight" -gt "$maxHeight" ]]; then | |
newHeight=$origHeight | |
newWidth=$(echo "(($origWidth * $newHeight) / $origHeight) + 0.5" | bc) | |
newWidth=${newWidth%.*} | |
else | |
newHeight=$origHeight | |
newWidth=$origWidth | |
fi | |
qualityValue=82 | |
# Note: the quality value seems to not matter at all. The size seems to be the main factor behind the size of the file. | |
magick mogrify -filter Triangle -define filter:support=2 -unsharp 0.25x0.08+8.3+0.045 -dither None -quality ''"${qualityValue}"'' \ | |
-define jpeg:fancy-upsampling=off -define png:compression=filter=5 -define png:compression-level=9 \ | |
-define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB \ | |
-strip -thumbnail ''"${newWidth}x${newHeight}>"'' "${imagefile}" | |
mv -f "${imagefile}" "${newname}" | |
elif [[ -f "${imagefile}" && ! -L "${imagefile}" && "${imagefile}" =~ UNCOMPRESSED\. ]]; then | |
mv -f "${imagefile}" "${newname}" | |
fi | |
listOfCompressedFiles+="${imagefile} ${newname} " | |
done | |
echo "listOfImages=$listOfCompressedFiles" >> $GITHUB_OUTPUT | |
if [[ $compressionDone ]]; then | |
echo "didCompression=T" >> $GITHUB_OUTPUT | |
else | |
echo "didCompression=F" >> $GITHUB_OUTPUT | |
fi | |
continue-on-error: true | |
# | |
- name: post newly compressed images to repository | |
if: ${{ steps.compressImages.outputs.didCompression == 'T' }} | |
run: | | |
git config --global user.email "[email protected]" | |
git config --global user.name "github actions" | |
git add "${{ steps.compressImages.outputs.listOfImages }}" | |
git commit -m "Upload newly compressed image files" | |
git push | |
continue-on-error: true | |
#_______________________________________________________________________ | |
#| | | |
#| GET THE DIRECTORY SET UP BY REMOVING OLD FILES | | |
#|______________________________________________________________________| | |
initializeFolder: | |
runs-on: ubuntu-latest | |
needs: [defineVariables] | |
continue-on-error: true | |
permissions: | |
# Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. | |
contents: write | |
steps: | |
- name: Clone repo | |
uses: actions/checkout@v4 | |
# | |
- name: Recall stored variables | |
run: | | |
echo "STARTFILE=${{ needs.defineVariables.outputs.startfile }}" >> $GITHUB_ENV | |
echo "HTMLFILE=${{ needs.defineVariables.outputs.htmlfile }}" >> $GITHUB_ENV | |
echo "TIMESTAMP=${{ needs.defineVariables.outputs.timestamp }}" >> $GITHUB_ENV | |
continue-on-error: true | |
# | |
- name: Post note alerting start time | |
run: | | |
rm -f $STARTFILE | |
touch $STARTFILE | |
echo $TIMESTAMP >> $STARTFILE | |
link2job="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/job/JOBIDPLACEHOLDER" | |
echo "$link2job" >> $STARTFILE | |
echo "HTMLLINK PLACEHOLDER" >> $STARTFILE | |
echo "precomp" >> $STARTFILE | |
continue-on-error: true | |
# | |
- name: post the start file to repository | |
uses: actions/upload-artifact@v4 | |
with: | |
name: start-alert | |
path: ${{ env.STARTFILE }} | |
overwrite: true | |
continue-on-error: true | |
#run: | | |
# git config --global user.email "[email protected]" | |
# git config --global user.name "github actions" | |
# git add ${{ env.STARTFILE }} | |
# git commit -m "Upload new start notification file" | |
# git push | |
#continue-on-error: true | |
#_______________________________________________________________________ | |
#| | | |
#| COMPILE THE FILE | | |
#|______________________________________________________________________| | |
build_latex: | |
needs: [defineVariables,initializeFolder,compressImages] | |
runs-on: ubuntu-latest | |
continue-on-error: true | |
permissions: | |
# Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. | |
contents: write | |
# | |
outputs: | |
jobnumber: ${{ steps.job-id.outputs.JOBNUMBER }} | |
# | |
steps: | |
- name: Clone repo | |
uses: actions/checkout@v4 | |
# | |
- name: Recall stored variables | |
run: | | |
echo "PDFHIRES=${{ needs.defineVariables.outputs.pdfhires }}" >> $GITHUB_ENV | |
echo "PDFFILE=${{ needs.defineVariables.outputs.pdffile }}" >> $GITHUB_ENV | |
echo "CORENAME=${{ needs.defineVariables.outputs.corename }}" >> $GITHUB_ENV | |
echo "OUTFILE=${{ needs.defineVariables.outputs.outfile }}" >> $GITHUB_ENV | |
echo "STARTFILE=${{ needs.defineVariables.outputs.startfile }}" >> $GITHUB_ENV | |
continue-on-error: true | |
# | |
- uses: actions/download-artifact@v4 | |
with: | |
name: start-alert | |
# | |
- name: Get Job ID from GH API | |
id: job-id | |
env: | |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# | |
run: | | |
jobs=$(gh api repos/${{ github.repository }}/actions/runs/${{ github.run_id}}/attempts/${{ github.run_attempt }}/jobs) | |
job_id=$(echo $jobs | jq -r '.jobs[] | select(.runner_name=="${{ runner.name }}") | .id') | |
echo "the job id is: $job_id" | |
echo "JOBNUMBER=$job_id" >> $GITHUB_OUTPUT | |
continue-on-error: true | |
# | |
- name: Remove old files | |
run: | | |
rm -f $PDFFILE | |
rm -f $PDFHIRES | |
rm -f $OUTFILE | |
continue-on-error: true | |
# | |
# https://tex.stackexchange.com/questions/245982/differences-between-texlive-packages-in-linux | |
# https://www.overleaf.com/learn/latex/TeX_engine_command_line_options_for_pdfTeX%2C_XeTeX_and_LuaTeX | |
# https://github.com/teatimeguest/setup-texlive-action/tree/v3.3.0 | |
# | |
# array.sty is incompatable with latest version of texlive and/or aastex. Until aastex is fixed in mid-2025, | |
# will need to keep this fix of using version 2023 instead of latest version. array.sty is used in WorPT files. | |
# See more details here: https://github.com/AASJournals/AASTeX60/issues/149 | |
# tools package not loaded because of errors | |
- name: Install texlive | |
uses: teatimeguest/setup-texlive-action@v3 | |
with: | |
version: 2023 | |
packages: | |
collection-basic | |
collection-bibtexextra | |
collection-binextra | |
collection-context | |
collection-fontsextra | |
collection-fontsrecommended | |
collection-formatsextra | |
collection-fontutils | |
collection-latex | |
collection-latexextra | |
collection-latexrecommended | |
collection-mathscience | |
collection-metapost | |
collection-pictures | |
collection-plaingeneric | |
collection-pstricks | |
collection-publishers | |
collection-texworks | |
amsfonts | |
graphics | |
scrextend | |
rotating | |
threeparttable | |
units | |
cache: true | |
continue-on-error: true | |
# | |
- name: Compile paper | |
# https://stackoverflow.com/questions/418896/how-to-redirect-output-to-a-file-and-stdout | |
id: compilation | |
run: | | |
rm -f "$CORENAME.aux $CORENAME.bbl $CORENAME.blg $CORENAME.fdb_latexmk $CORENAME.fls $CORENAME.out $CORENAME.sync* $CORENAME.synctex.gz" | |
rm -f compileOut.txt | |
latexmk -bibtex -verbose -f -g -pdf -time -file-line-error -view=none -synctex=1 -interaction=nonstopmode "$TEXFILE" 2>&1 | tee compileOut.txt | |
echo "______________________________________________________________________________" | |
cat compileOut.txt | |
echo "______________________________________________________________________________" | |
continue-on-error: true | |
# | |
- name: clean up after compilation | |
run: | | |
rm -f "$PDFHIRES" | |
mv -f "$PDFFILE" "$PDFHIRES" | |
# clean up unneeded files from the compilation | |
rm -f "$CORENAME.aux $CORENAME.bbl $CORENAME.blg $CORENAME.fdb_latexmk $CORENAME.fls $CORENAME.out $CORENAME.sync* $CORENAME.synctex.gz" | |
rm -f $OUTFILE | |
mv -f compileOut.txt $OUTFILE | |
# replace the job id placeholder in the START file with the job id | |
sed -ri "s/JOBIDPLACEHOLDER/${{ steps.job-id.outputs.JOBNUMBER }}/" ${{ env.STARTFILE }} | |
continue-on-error: true | |
# | |
- name: post raw latex compilation output to repository for further processing | |
run: | | |
git config --global user.email "[email protected]" | |
git config --global user.name "github actions" | |
#git add "${{ env.OUTFILE }}" "${{ env.PDFHIRES }}" "${{ env.STARTFILE }}" | |
git add . | |
git commit -m "post high-res PDF and raw latex compilation log for additional processing" | |
git push | |
continue-on-error: true | |
#_______________________________________________________________________ | |
#| | | |
#| COMPRESS THE PDF FILE INTO LOWER RESOLUTION FILE FOR DISPLAY | | |
#|______________________________________________________________________| | |
#compressPdf: | |
# needs: build_latex | |
# runs-on: ubuntu-latest | |
# continue-on-error: true | |
# permissions: | |
# # Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. | |
# contents: write | |
# # | |
# steps: | |
# - name: Clone repo | |
# uses: actions/checkout@v4 | |
# # | |
# - name: compress PDF | |
# if: ${{ always() && hashFiles("${{ github.event.inputs.file2compile }}_hiRes.pdf") }} | |
# uses: jy95/ghostscript-action@v1 | |
# with: | |
# file: "$PDFHIRES" | |
# output: "$PDFFILE" | |
# arbitrary-parameters: '-dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen' | |
# continue-on-error: true | |
# # | |
# - name: post reduced resolution PDF on repository | |
# if: ${{ always() && hashFiles("$PDFFILE") }} | |
# uses: stefanzweifel/git-auto-commit-action@v5 | |
# with: | |
# commit_message: post low-resolution version of PDF | |
# file_pattern: "$PDFFILE" | |
# continue-on-error: true | |
#_______________________________________________________________________ | |
#| | | |
#| PROCESS COMPILATION OUTPUT | | |
#|______________________________________________________________________| | |
#processLogFile: | |
# needs: build_latex | |
# runs-on: ubuntu-latest | |
# continue-on-error: true | |
# permissions: | |
# # Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. | |
# contents: write | |
# # | |
# steps: | |
# - name: Clone repo | |
# uses: actions/checkout@v4 | |
# # | |
# - name: Capture full compilation output | |
# run: | | |
# # | |
# # ============================================================================= | |
# # open up the compilation output log file and strip out a lot of unnecessary stuff | |
# # ============================================================================= | |
# fatalErrors=false | |
# fileliststr='' | |
# # ....... if the pdf file was generated, then the errors must have NOT been fatal. | |
# if [[ "$( -Eq "output to '${PDFFILE}'" compileOut.txt)$?" == 0 ]]; then fatalErrors=true; fi | |
# # ....... prepare the compilation log for processing by first removing all end-of-line characters | |
# rm -f errout.txt | |
# rm -f compileOut.txt | |
# touch errout.txt | |
# mv -f $OUTFILE compileOut.txt | |
# # ....... just to be safe, remove all \a, \t and \x0 because we use these as special markers later | |
# sed -ri 's/[\x0\a\t]/ /g' compileOut.txt | |
# # ....... before removing end of line carriage returns, mark the citations that could not be found in the bib file(s) | |
# sed -r 's/^ *(Citation `[[:print:]]*on input line )([0-9][0-9]*) *$/ \x0\2-BIB-\1\2\.\a/g' compileOut.txt >> errout.txt | |
# # ....... before removing end of line carriage returns, mark "on input line" phrases so they can be easily found (and/or avoided) later: | |
# rm -f tmp.txt && sed -r 's/on input line ([0-9][0-9]*)/on input line \t\1/g' errout.txt > tmp.txt && mv -f tmp.txt errout.txt | |
# # ....... also indicate any pdfTeX error that will not have a line number and involves explamation marks which mess sed up | |
# rm -f tmp.txt && sed -r 's/pdfTeX error: / \x0 0-ERROR-pdfTeX error:/g' errout.txt > tmp.txt && mv -f tmp.txt errout.txt | |
# rm -f tmp.txt && sed -r 's/failed *$/failed\a/g' errout.txt > tmp.txt && mv -f tmp.txt errout.txt | |
# # ....... now remove all the end of line returns | |
# rm -f tmp.txt && tr -d "\n" < errout.txt > tmp.txt && mv -f tmp.txt errout.txt | |
# # ....... remove a lot of the lines that have noithing to do with errors and warnings, to make the next searches go faster | |
# sed -ri 's/[(]\/home\/runner[^)][^)]*[)]/ /g' errout.txt | |
# sed -ri 's/<\/home\/runner[^>][^>]*\>/ /g' errout.txt | |
# # ....... remove [] [] that are just clutter in the file | |
# sed -ri 's/\[ *\]/ /g' errout.txt | |
# # ....... remove the ((( left behind in the above substitutions | |
# sed -ri 's/[(] *[(]/ /g' errout.txt | |
# # ....... remove the )))) left behind in above subs | |
# sed -ri 's/[)] *[)]/ /g' errout.txt | |
# # ....... remove all multiple white spaces to a single white space | |
# sed -ri 's/ */ /g' errout.txt | |
# rm -f tmp.txt | |
# sed -r 's/(\.[^.][^.]*\.tex:[0-9][0-9]*:[^.\t][^.\t]*\t)([0-9][0-9]*)([^.]*\.)/\x0\2-ERROR-\1\2\3\a/g' errout.txt > tmp.txt | |
# mv -f tmp.txt errout.txt | |
# rm -f tmp.txt | |
# sed -r 's/([^:][^:][^:])(LaTeX )((Error)|(Warning))(:[^.\t][^.\t]*\t)([0-9][0-9]*)([^.]*\.)/\1\x0\7-\3-\2\3\6\7\8\a/g' errout.txt >> tmp.txt | |
# mv -f tmp.txt errout.txt | |
# sed -ri 's/\-Error\-/-ERROR-/g' errout.txt | |
# sed -ri 's/\-Warning\-/-WARNING-/g' errout.txt | |
# rm -f tmp.txt | |
# sed -r 's/([^-])(\.[^.][^.]*\.tex:)([0-9][0-9]*)(:[^.\t][^.\t]*\.)/\1\x0\3-ERROR-\2\3\4\a/g' errout.txt > tmp.txt | |
# mv -f tmp.txt errout.txt | |
# sed -ri 's/^[^\x0]*\x0//' errout.txt | |
# sed -ri 's/\a[^\a]*$//' errout.txt | |
# # ....... remove all the \t placeholders | |
# sed -ri 's/\t//g' errout.txt | |
# sed -ri 's/\a[^\x0]*\x0 */\n/g' errout.txt | |
# # the next step, sorting the entries, does not work as expected unless all the white space is gone, so replace white space with \a | |
# sed -ri 's/ /\a/g' errout.txt | |
# # ....... sort and remove redundances in the error/warning list | |
# rm -f tmp.txt | |
# cat errout.txt | sort -r -t- -g -k1,1n -k2 -s | uniq | sed -r 's/\a/ /g' > tmp.txt | |
# mv -f tmp.txt errout.txt | |
# # | |
# # ============================================================================= | |
# # remove lines in the output that are unrelated to the latex compilation itself | |
# # ============================================================================= | |
# readarray -t sorted < errout.txt | |
# # ####################### START CONSOLIDATING THE ERRORS ################### | |
# rm -f tout.txt | |
# touch tout.txt | |
# errtypes=("ERROR" "WARNING" "BIB") | |
# banners=("FATAL ERRORS" "WARNINGS" "CITATION ISSUES") | |
# for (( i=0; i<${#errtypes[@]}; i++ )); do | |
# echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> tout.txt | |
# echo " ${banners[$i]} IN $TEXFILE" >> tout.txt | |
# echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> tout.txt | |
# issue="" | |
# for (( j=0; j<${#sorted[@]}; j++ )); do | |
# if [[ "${sorted[$j]}" =~ "-${errtypes[$i]}-" ]]; then | |
# issue="${sorted[$j]}" | |
# if [[ "${errtypes[$i]}" =~ "ERROR" ]]; then fatalErrors=true; fi | |
# break; | |
# fi | |
# done | |
# # if there were no issues, then put 'none' | |
# if [[ "$issue" = "" ]]; then echo " none" >> tout.txt; fi | |
# while [ "$issue" != "" ]; do | |
# linenum=$( sed -r 's/^([0-9][0-9]*)\-.*/\1/' <<<"$issue" ) | |
# if [[ $linenum > 0 ]]; then | |
# # look for all occurances of this line number in the error/warning list | |
# for (( j=0; j<${#sorted[@]}; j++ )); do | |
# if [[ "$( -q -E -- "^$linenum-" <<<"${sorted[$j]}" )$?" == 0 ]]; then | |
# line="$( echo "${sorted[$j]}" | sed -r 's/^[0-9][0-9]*\-[A-Z][A-Z]*\-//' )" | |
# echo $line >> tout.txt | |
# # remove this item from the list | |
# sorted[$j]="DONE" | |
# fi | |
# done | |
# # now look up the line in the .tex file and place underneath | |
# echo "line #$linenum ----------------------- " >> tout.txt | |
# head -n $linenum "$TEXFILE" | tail -1 >> tout.txt | |
# else | |
# # look up where this line is in the list and remove it from the list | |
# for (( j=0; j<${#sorted[@]}; j++ )); do | |
# if [[ "${sorted[$j]}" =~ "$issue" ]]; then | |
# line="$( echo "${sorted[$j]}" | sed -r 's/^ *[0-9][0-9]*\-[A-Z][A-Z]*\-//' )" | |
# echo $line >> tout.txt | |
# # remove from list | |
# sorted[$j]="DONE" | |
# fi | |
# done | |
# fi | |
# # See if any more issue remain in the list and need to be processed in the next loop iteration | |
# issue="" | |
# for (( j=0; j<${#sorted[@]}; j++ )); do | |
# if [[ "${sorted[$j]}" =~ "-${errtypes[$i]}-" ]]; then issue="${sorted[$j]}"; break; fi | |
# done | |
# echo "._______________________________________________________________________" >> tout.txt | |
# done | |
# echo " " >> tout.txt | |
# done | |
# echo "FATALERRORS=$fatalErrors" >> $GITHUB_ENV | |
# continue-on-error: true | |
# # | |
# - name: Gather up list of references | |
# run: | | |
# # https://stackoverflow.com/questions/57788813/-return-0-if-no-match | |
# # squash.io/extracting=numbers-from-strings-in-bash | |
# # https://stackoverflow.com/questions/17883661/how-to-extract-numbers-from-a-string | |
# # https://stackoverflow.com/questions/2624300/save-part-of-matching-pattern-to-variable | |
# echo "" >> tout.txt | |
# echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> tout.txt | |
# echo " LIST OF REFERENCES IN $TEXFILE" >> tout.txt | |
# echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> tout.txt | |
# # create an array of just the bibcodes | |
# # extract just the bibcode from the pruned bibfile to use for another file that will be used in the summary | |
# readarray -t cites < <( grep "@" pruned.bib | sed -r 's/^[^ ]+\.bib: *//' | sed -r 's/@[^\{]+\{//' | sed -r 's/,//' ) | |
# if [[ ${#cites[@]} -gt 0 ]]; then echo "Number of citations: ${#cites[@]}" >> tout.txt; fi | |
# for (( i=0; i<${#cites[@]}; i++ )); do echo "${cites[$i]}" >> tout.txt; done | |
# if [[ ${#cites[@]} == 0 ]]; then echo " None"; fi | |
# rm -f $OUTFILE | |
# mv tout.txt "$OUTFILE" | |
# rm -f html.txt | |
# rm -f finHtml.html | |
# rm -f $HTMLFILE | |
# if [$fatalErrors]; then | |
# # | |
# # ======================================================================= | |
# # construct the html file showing errors, if there were fatal ones | |
# # ======================================================================= | |
# # There were errors - Create a .html file from the out.txt file | |
# rm -f "$PDFFILE" | |
# rm -f "$PDFHIRES" | |
# # make sure that long lines are split if they exceed 20 words | |
# fold -sw 90 "$OUTFILE" > html.txt | |
# echo "<span style='color:blue;'>FATAL LATEX COMPILATION ERROR(s)</span><br><br>" > finHtml.html | |
# echo "<i>To view full GitHub Actions output, click on item at top of list here:</i><br>" >> finHtml.html | |
# echo "<span style='color:blue;'><i>${JOBLINK}</i></span><br>" >> finHtml.html | |
# echo "<hr><br>" >> finHtml.html | |
# echo "$TIMESTAMP" >> finHtml.html | |
# # Go through the html.txt file and make the errors red to stand out | |
# touch red.txt | |
# red=false | |
# while IFS= read -r line; do | |
# start='^line #[0-9]+' | |
# end='^\.__________' | |
# if [[ $line =~ $start ]]; then red=true; elif [[ $line =~ $end ]]; then red=false; fi | |
# thisline="$( echo "$line" | sed -r 's/^line #/Line #/g' | sed -r 's/^\.__________/___________/g' )" | |
# if $red; then | |
# echo "<span style='color:red;'>$thisline</span>" >> red.txt | |
# else | |
# echo "$thisline" >> red.txt | |
# fi | |
# done < "html.txt" | |
# sed ':a;N;$!ba;s/\n/<br>\n/g;s/ /\ /g;s/span\ style/span style/g' red.txt >> finHtml.html | |
# rm -f $HTMLFILE | |
# mv -f finHtml.html "$HTMLFILE" | |
# rm -f red.txt | |
# rm -f ${{ github.event.inputs.file2compile }}START.txt" | |
# touch ${{ github.event.inputs.file2compile }}START.txt" | |
# echo $TIMESTAMP >> ${{ github.event.inputs.file2compile }}START.txt" | |
# echo $JOBLINK >> ${{ github.event.inputs.file2compile }}START.txt" | |
# echo "https://raw.githubusercontent.com/${{ github.repository }}/${GITHUB_REF_NAME}/${{ github.event.inputs.file2compile }}.html" >> ${{ github.event.inputs.file2compile }}START.txt" | |
# echo "html" >> ${{ github.event.inputs.file2compile }}START.txt" | |
# else | |
# rm -f ${{ github.event.inputs.file2compile }}START.txt" | |
# touch ${{ github.event.inputs.file2compile }}START.txt" | |
# echo $TIMESTAMP >> ${{ github.event.inputs.file2compile }}START.txt" | |
# echo $JOBLINK >> ${{ github.event.inputs.file2compile }}START.txt" | |
# echo "https://raw.githubusercontent.com/${{ github.repository }}/${GITHUB_REF_NAME}/${{ github.event.inputs.file2compile }}.html" >> ${{ github.event.inputs.file2compile }}START.txt" | |
# echo "pdf" >> ${{ github.event.inputs.file2compile }}START.txt" | |
# # finalize the compilation output file by putting a few sentences at the top | |
# rm -f fin.txt | |
# rm -f "$OUTFILE" | |
# touch fin.txt | |
# echo "$TIMESTAMP" >> fin.txt | |
# echo "LATEX COMPILATION ERRORS and WARNINGS" >> fin.txt | |
# echo "" >> fin.txt | |
# echo "To view full GitHub Actions output, click on item at top of list here:" >> fin.txt | |
# echo "$JOBLINK" >> fin.txt | |
# echo "" >> fin.txt | |
# while IFS= read -r line; do | |
# thisline="$( echo "$line" | sed -r 's/^line #/Line #/g' | sed -r 's/^=----/-----/g' )" | |
# echo "$thisline" >> fin.txt | |
# done < "$OUTFILE" | |
# mv -f fin.txt "$OUTFILE" | |
# fi | |
# continue-on-error: true | |
# # | |
# - name: post finalized compilation errors and notice of completion to the repository | |
# uses: stefanzweifel/git-auto-commit-action@v5 | |
# with: | |
# commit_message: low-resolution version of PDF | |
# file_pattern: "${{ github.event.inputs.file2compile }}START.txt" $OUTFILE $HTMLFILE" | |
# continue-on-error: true |