#! /bin/sh # This script "prints" the code of your project into a pdf file that can be annoted for comments by the profs # # The easiest to use this script is to call it from the main directory of your project, as follows: # ../proj2pdf /tmp/TP4-myname.pdf # In this case, the script will attempt to find the relevant files to be included in your submission. # # If the script fail to detect the files to include, just specify them on the command line, as follows: # ../proj2pdf /tmp/TP4-myname.pdf file1.c file2.c file1.h Makefile # # You must call it from the directory hosting your sources, as it will try to grab the git logs and the README.md file from there. # Exit the script if any command fails (this is generally safer than to continue running further commands) set -o errexit ## ## Check the dependencies ## if command -v uudecode >/dev/null ; then : else printf '%s\n' "Please install uudecode (apt install sharutils || pacman -S sharutils)" exit 1; fi if command -v pygmentize >/dev/null ; then : else printf '%s\n' "Please install pygmentize (apt install python3-pygments || pacman -S python-pygments)" exit 1; fi if command -v rsvg-convert >/dev/null ; then : else printf '%s\n' "Please install rsvg-convert (apt install librsvg2-bin || pacman -S librsvg)" exit 1; fi if command -v pandoc >/dev/null ; then : else printf '%s\n' "Please install pandoc to include README.md files (apt install pandoc || pacman -S pandoc-cli)" exit 1; fi ## ## Check the parameters ## usage() { printf '%s\n' "Usage: proj2pdf output.pdf # search/guess source files in current dir" printf '%s\n' "Usage: proj2pdf output.pdf directory # search/guess source files in the specified dir (TODO: search of README.md may fail in this case)" printf '%s\n' "Usage: proj2pdf output.pdf f1 f2 f3 # use the specified files" exit 1 } if [ $# -eq 0 ] ; then printf '%s\n' "Please specify an output file name." usage fi output=$1 shift if printf '%s' "$output" | grep -q '.pdf$' ; then : else printf '%s\n' "Please provide a valid output file name (ending with .pdf)" usage fi IFS=' ' files="$*" dir="." if [ -d "$files" ] ; then # Given a directory printf '%s\n' "Guessing the files in directory '$files'" dir="$files" cd "$dir" files=$(find . -name Makefile -o -name CMakeLists.txt -o -name '*.[ch]' | grep -v '/CMakeFiles/') fi if [ -z "$files" ] ; then # no explicit parameters printf '%s\n' "Guessing the files in the current dir" files=$(find . -name Makefile -o -name CMakeLists.txt -o -name '*.[ch]' | grep -v '/CMakeFiles/') fi printf '%s' 'Input files:' printf '%s\n' "$files" | while read -r file do printf ' %s' "$file" done printf '\n' tempdir=$(mktemp -d /tmp/proj2pdf-XXXXXXXX) printf '%s\n' "Installing a small mpi.h, in case your project needs it" # Regenerate the following chunk with: # gzip -9 tools/mpi.h --stdout | uuencode --base64 - uudecode << 'INCLUDE_EOF' | gunzip > "$tempdir/mpi.h" begin-base64 644 - H4sICFKfEWUCA21waS5oAMVW23KjRhB95yu6dl8Uap01SL5s/CTL2FaVJFQg xetsbVEYxl4SBAozUsVJ5d8zF0A0IAvlUuHFVvfpnj6npxveh+Q5SghM52Pv ZrgYLh7nljdbTiYAYGjvK97R/dABE5nce9tZQB/ZxrMFDJBlYs/u4KxhUvZz nHB8N7Nu1FEXyLOcVX2X7T5Vz6dWJxin7UGyDMPY78wRmPrtxB4uwMDcb+zl 9cQCo8m/dGEdHiQbA4sw8q5tewLGRV3XS4+feFm3GufC/Klu7pvcbJ7WzecD Ya6xzXObmOL148ICs9+AygPNQcOuTjxr2NWRdY5SQG9kT+cT6zOYFzW30mvn v6z5K6LuQFiEobiKfayAfXvrWtyKBZhcQx9zX3JLv9lwebv7Le2V9rOWy6A8 582xUQ5M25S2y323R4Vgkqa6iANM08yv28AAbJdXeWBqWE17OvUebGdyA/I5 xe7p8DNUH6ydu5wiL9ZxOp4hb1+rBY9GluuWbsxiOHv0XHvpjCzpPDEa3sXw rgiteS3H8ezFveW0el2+6JYuXzc/WUVZ2kcdNP6vy3y2oZA+/UwC9j3AmEFE gX0jkCbxK2woyU62EY2eYpkKQp/5J5Rlm4BtMiJTLDj4XZBuEvYOniMShyLD 3Bn/OFxYVyKDrOGOME+CgKXgBwGhFCJ+ogb6R429rgmvF1Ri+EPmhYiDZchV +VOykRphG1cGG7ggtnOl/akiJMkrxVqwyMivG0JZTptWSygSOApyVcYI5gLU Br7JfTt0kK5WbcgRt+9Q6ZpkPovSpA1qr/OK51nKUuGlPwjcNo1CgNU68kiW pVkPpOE7DhaRoFZfRoJt7ike/Wnz/EGD+qOC8kfK3QKqkiyVOJSMppssOIhi /sueA4VWeVWr1R5M3ibOrugpFsIlSdhJhy4ydFQBpQp5TQcgrQo0BBDEWoaa v7htxwLxDaPt7i5vvuCsg+C6G6QPeyhIBM0C9Y+oZ3e+FL8yRjqfUvEX6/zg R6yHOlI0pJ1avndAV8nKrslh5lE9lKoYWFmfDs9xUWGjpGoOP3nt1agXGfN8 9MvXPGWUhOS3I9PH8Z70Zb30QEZSz0nTFZFJo6RL1emG5bCCRMQXa/Wk/KAv X2sHeYGfBCSOSQi9IE0oq8YU5VWqr62XRHRb/tb97CVo9jj45meg68K7rY2k uFVe5ie/9OqXrDniaFZ0EdSWjEa/k6OTiSCZLEw3+dvNe2AR17+2UOXHoZ9l Eclqh2DMbZT4saykGT+M44yEm4DUdxHl+6l9L/MHQ8VK3wtFC4V3h6xoOxAt gD1bPIfZ6/xHut4Pauyo4pZxyi8+/5DI8vul9lHBV20c/qNtLwm72ksqqGAu g8SPtiBhV0GoR20Vbf/FklQmOSdlZRSZw4iuY3p0tW7gM/Y/qCdRacoOVrZH xQrzssIOgvxnVe+G0DlyAruOX7fZ6zJ4h6cOnSUJa93GEu0iloqX1xGrCH/X lRdPO7Rgyq5q/2i9YdblZTh4fHk/tK7bqynT9qiVjSrVKwPQES1no8PmflPY v/3i0CsrrCO6a8FvtuKNXsi3b+DzL8KjP2hb98Ff+KGVTwIUAAA= ==== INCLUDE_EOF ## ## Generate the svg files ## printf '%s\n' "Generating svg files" # Git logs printf '%s\n' " git logs -> $tempdir/00_summary.svg" ( printf '%s\n' " # Included files:"; printf '%s\n' "$files" | while read -r c ; do if clang-format "$c" | cmp --quiet "$c" ; then printf '%s\n' " * $(basename "$c")"; else printf '%s\n' " * $(basename "$c") TODO: clang-format ."; fi done printf '\n\n' printf '%s\n' " # Ignored C and H files" find . -name '*.[ch]' | while IFS= read -r c; do if printf '%s\n' "$files" | grep --quiet "$(basename "$c")" ; then : # printf '%s\n' " * (not) "$(basename $c) else printf '%s\n' " * $(basename "$c")" fi done if git status >/dev/null 2>/dev/null ; then printf '\n\n\n\n' git log --stat fi printf '\n.\n' ) | pygmentize -O line_number_pad:12 -o "$tempdir/00_summary.svg" # Parse the README.md that must be there if [ -e README.md ] ; then printf '%s\n' " README.md -> $tempdir/01_README.svg" (pandoc -f markdown -t markdown README.md ; printf '\n.\n') | pygmentize -l markdown -o "$tempdir/01_README.svg" else printf '%s\n' "Please include a README.md to your submission" exit 1 fi count=2 # To keep the file ordering while generating the SVGs. 0 is summary; 1 is README printf '%s\n' "$files" | while read -r file ; do num=$(printf "%02d" $count) case "$file" in *Makefile) if grep -q "CMAKE generated file:" "$file" ; then printf '%s\n' "Ignoring the Makefile that seems generated by CMake." if printf '%s\n' "$files" | grep -q CMakeLists.txt ; then printf '%s\n' "The CMakeLists.txt will be used instead" else printf '%s\n' "WARNING: the CMakeLists.txt seems to not be included." fi else printf '%s\n' " $file -> $tempdir/${num}_Makefile.svg" ( # Note: this is a non-breakable whitespace sed 's/^/ /' "$file" printf '\n\n\n#eof\n' ) | pygmentize -l make -O line_number_pad:12 -o "$tempdir/${num}_Makefile.svg" fi ;; *CMakeLists.txt) printf '%s\n' " $file -> $tempdir/${num}_CMakelists.svg" ( # Note: this is a non-breakable whitespace printf '%s\n' " ## CMakeLists.txt" printf '\n' # Note: this is a non-breakable whitespace sed 's/^/ /' "$file" printf '\n\n\n#eof\n' ) | pygmentize -l cmake -O line_number_pad:12 -o "$tempdir/${num}_CMakeLists.svg" ;; *.[ch]) name=$(basename "$file") if command -v clang-tidy >/dev/null ; then : else printf '%s\n' "Please install clang-tidy (apt install clang-tidy || pacman -S clang)" exit 1; fi printf '%s\n' " $file -> $tempdir/${num}_${name}.svg" (printf '\n\n/*\n ******************************************************\n ********* Fichier %s *********\n ******************************************************\n */\n' "$file"; cat "$file" printf '\n\n/////////////////////////////// clang-tidy output\n\n' clang-tidy "$file" -- -I.. -I. -I"$tempdir" ) | pygmentize -l C -o "$tempdir/${num}_${name}.svg" ;; *.py) name=$(basename "$file") printf '%s\n' " $file -> $tempdir/${count}_${name}.svg" ( # Note: this is a non-breakable whitespace sed 's/^/ /' "$file" printf '\n\n\n#eof\n' ) | pygmentize -l python -o "$tempdir/${count}_${name}.svg" ;; *.svg) name=$(basename "$file") printf '%s\n' " $file -> $tempdir/${count}_${name}.svg" cp "$file" "$tempdir/${count}_${name}.svg" ;; *) printf '%s\n' "File $file not handled! Bailing out." rm -rf "$tempdir" exit 0 ;; esac; count=$((count + 1)) done printf '%s\n' "done." rm "$tempdir/mpi.h" printf '%s\n' "Generating $output" rm -f "$output" rsvg-convert -f pdf -o "$output" "$tempdir"/* rm -rf "$tempdir" printf '\n\nGeneration done. Please check the content of %s before submitting it\n' "$output" exit 0