From 755f323a1da2259a39d0bc5746a6d24c91ec4f15 Mon Sep 17 00:00:00 2001 From: "robinwilliam.hundt" <robinwilliam.hundt@stud.uni-goettingen.de> Date: Tue, 5 Nov 2019 15:10:47 +0100 Subject: [PATCH] Interactive notebook fixing, latex rendering, change to output schema concerning tests --- Cargo.lock | 138 ++++++++++++++++++++++++---- Cargo.toml | 1 + src/lib.rs | 25 ++++- src/main.rs | 46 +++------- src/parser/ipynb_parser/notebook.rs | 53 ++++++++++- src/parser/mod.rs | 6 +- src/parser/xml_parser.rs | 38 +++++--- src/submission.rs | 16 +--- src/submission_type.rs | 41 ++++++++- src/test_output.rs | 2 +- tests/test_xml_parser.rs | 8 +- 11 files changed, 277 insertions(+), 97 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0040d4..db758d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,7 +34,7 @@ name = "atty" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -50,7 +50,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -60,7 +60,7 @@ version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -97,7 +97,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bzip2-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -106,7 +106,16 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "c2-chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -140,7 +149,7 @@ name = "chrono" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)", @@ -349,7 +358,7 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -391,6 +400,16 @@ dependencies = [ "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "getrandom" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "h2" version = "0.1.26" @@ -515,7 +534,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -548,7 +567,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.61" +version = "0.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -626,7 +645,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -639,7 +658,7 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -664,7 +683,7 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -695,7 +714,7 @@ name = "num_cpus" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -720,7 +739,7 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -742,6 +761,11 @@ name = "podio" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ppv-lite86" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.4.30" @@ -798,7 +822,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -810,6 +834,18 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_chacha" version = "0.1.1" @@ -819,6 +855,15 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_chacha" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -832,6 +877,14 @@ name = "rand_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_hc" version = "0.1.0" @@ -840,6 +893,14 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_isaac" version = "0.1.1" @@ -853,7 +914,7 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -865,7 +926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -917,6 +978,14 @@ name = "regex-syntax" version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "remove_dir_all" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "reqwest" version = "0.9.19" @@ -959,7 +1028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1019,6 +1088,7 @@ dependencies = [ "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "sxd-document 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "sxd-xpath 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "zip 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1245,6 +1315,19 @@ name = "take_mut" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "tempfile" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termcolor" version = "1.0.5" @@ -1274,7 +1357,7 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1518,6 +1601,11 @@ dependencies = [ "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasi" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "webpki" version = "0.19.1" @@ -1626,6 +1714,7 @@ dependencies = [ "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum bzip2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" "checksum bzip2-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6584aa36f5ad4c9247f5323b0a42f37802b37a836f0ad87084d7a33961abe25f" +"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum calamine 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3ab74871ccd5a5b62749ec8b8a43c8dedc5e325ee16d6def84bcad8b449726" "checksum cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "b548a4ee81fccb95919d4e22cfea83c7693ebfd78f0495493178db20b3139da7" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" @@ -1658,6 +1747,7 @@ dependencies = [ "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "372bcb56f939e449117fb0869c2e8fd8753a8223d92a172c6e808cf123a5b6e4" @@ -1673,7 +1763,7 @@ dependencies = [ "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)" = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa" +"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum libflate 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "45c97cf62125b79dcac52d506acdc4799f21a198597806947fd5f40dc7b93412" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" @@ -1697,6 +1787,7 @@ dependencies = [ "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum peresil 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f658886ed52e196e850cfbbfddab9eaa7f6d90dd0929e264c31e5cec07e09e57" "checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5afecba86dcf1e4fd610246f89899d1924fe12e1e89f555eb7c7f710f3c5ad1d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" @@ -1704,10 +1795,14 @@ dependencies = [ "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" @@ -1717,6 +1812,7 @@ dependencies = [ "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3d9193984285d544df4a30c23a4e62ead42edf70a4452ceb76dac1ce05c26" "checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f" +"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum reqwest 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0777154c2c3eb54f5c480db01de845652d941e47191277cc673634c3853939" "checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" "checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" @@ -1751,6 +1847,7 @@ dependencies = [ "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" @@ -1782,6 +1879,7 @@ dependencies = [ "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" +"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" "checksum webpki 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7e1cd7900a3a6b65a3e8780c51a3e6b59c0e2c55c6dc69578c288d69f7d082" "checksum webpki-roots 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10fa4212003ba19a564f25cd8ab572c6791f99a03cc219c13ed35ccab00de0e" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 8810160..f957040 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,4 @@ chrono = {version = "0.4.6", features = ["serde"]} semver = {version = "0.9.0", features = ["serde"]} display_derive = "0.0.0" snafu = "0.5.0" +tempfile = "3.1.0" diff --git a/src/lib.rs b/src/lib.rs index 830efc9..f41a59b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,6 +67,27 @@ where } } +pub fn yes_or_no(prompt: &str) -> bool { + let mut buffer = String::new(); + let allowed_responses = vec!["y", "Y", "n", "N", ""]; + + // this is a do-while loop! :D + while { + buffer.clear(); + print!("{} (Y/n):", prompt); + io::stdout().flush().expect("Io error"); + io::stdin().read_line(&mut buffer).expect("Io error"); + buffer = buffer.trim().to_owned(); + + !allowed_responses.contains(&buffer.as_str()) + } {} + match buffer.as_str() { + "y" | "Y" | "" => true, + "n" | "N" => false, + &_ => unreachable!(), + } +} + pub fn run_test(test: Box<dyn Test>, students: &mut [StudentSerializable]) { for student in students { student.submissions = student @@ -75,9 +96,7 @@ pub fn run_test(test: Box<dyn Test>, students: &mut [StudentSerializable]) { .into_iter() .map(|mut submission| { let test_output = test.run(&submission); - submission - .tests - .insert(test_output.name.clone(), test_output); + submission.tests.push(test_output); submission }) .collect() diff --git a/src/main.rs b/src/main.rs index 2b0eba7..fefc489 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ use std::error::Error; use std::ffi::OsStr; use std::fs; -use std::io::{self, Write}; use std::ops::Not; use std::path::PathBuf; @@ -20,7 +19,7 @@ use rusty_hektor::student::StudentSerializable; use rusty_hektor::submission_type::{ProgrammingLang, SubmissionType}; use rusty_hektor::testrunner::empty_test::EmptyTest; use rusty_hektor::testrunner::Test; -use rusty_hektor::{anonymizer, run_test}; +use rusty_hektor::{anonymizer, run_test, yes_or_no}; use ParsedData::*; /// Parse ILIAS exam export for importing into Grady @@ -47,6 +46,10 @@ struct Opt { #[structopt(long = "skip-text")] skip_text: bool, + /// Disable latex rendering + #[structopt(long = "no-latex")] + no_latex: bool, + /// Tests to run on the the submissions, the default (and only available option at /// the moment) is "empty" to check for empty submissions #[structopt(short, name = "TEST", parse(from_os_str), default_value = "empty")] @@ -82,13 +85,6 @@ impl From<&OsStr> for TestEnum { _ => panic!("Unable to parse test. Allowed values: empty"), } } - - // fn from_str(s: &str) -> Result<Self, Self::Err> { - // match s { - // "empty" => Ok(Self::Empty), - // _ => Err("Unable to parse test. Allowed values: empty")? - // } - // } } enum ParsedData { @@ -102,13 +98,14 @@ fn main() -> Result<(), Box<dyn Error>> { "Unable to check for a new Rusty-Hektor version.\n\ Please check manually at https://gitlab.gwdg.de/robinwilliam.hundt/rusty-hektor" ); - if yes_or_no("Exit?")? { + if yes_or_no("Exit?") { std::process::exit(0) } } let opt = Opt::from_args(); let parse_text = opt.skip_text.not(); + let render_latex = opt.no_latex.not(); let parsed_data: Result<Vec<ParsedData>, Box<dyn Error>> = opt .in_files @@ -124,7 +121,7 @@ fn main() -> Result<(), Box<dyn Error>> { ); std::process::exit(1) } else if extension == "zip" { - Ok(XML(XMLParser::parse(path, parse_text)?)) + Ok(XML(XMLParser::parse(path, parse_text, render_latex)?)) } else { Err(ParserError::new(format!( "Unsupported filetype: {:?}", @@ -186,8 +183,8 @@ fn interactive_annotate(mut data: ExamSerializable) -> Result<ExamSerializable, if sub_type .programming_language .as_ref() - .expect("Programming lan must not be None after annote") - == &ProgrammingLang::ipynb + .expect("Programming lang must not be None after annotate") + == &ProgrammingLang::python { for student in data.students.iter_mut() { render_student_notebooks(student, &sub_type)?; @@ -242,30 +239,9 @@ fn check_for_new_version() -> Result<(), Box<dyn Error>> { Please download the latest version from https://gitlab.gwdg.de/robinwilliam.hundt/rusty-hektor", current_version, latest_version ); - if yes_or_no("Exit?")? { + if yes_or_no("Exit?") { std::process::exit(0); } } Ok(()) } - -fn yes_or_no(prompt: &str) -> io::Result<bool> { - let mut buffer = String::new(); - let allowed_responses = vec!["y", "Y", "n", "N", ""]; - - // this is a do-while loop! :D - while { - buffer.clear(); - print!("{} (Y/n):", prompt); - io::stdout().flush()?; - io::stdin().read_line(&mut buffer)?; - buffer = buffer.trim().to_owned(); - - !allowed_responses.contains(&buffer.as_str()) - } {} - Ok(match buffer.as_str() { - "y" | "Y" | "" => true, - "n" | "N" => false, - &_ => unreachable!(), - }) -} diff --git a/src/parser/ipynb_parser/notebook.rs b/src/parser/ipynb_parser/notebook.rs index 93421ae..ee19dc4 100644 --- a/src/parser/ipynb_parser/notebook.rs +++ b/src/parser/ipynb_parser/notebook.rs @@ -4,8 +4,12 @@ use std::error::Error; use std::fmt::{Display, Formatter}; use std::str::FromStr; +use crate::{input, yes_or_no}; use lazy_static::lazy_static; use regex::Regex; +use std::io::{Read, Write}; +use std::path::PathBuf; +use std::process::Command; /// Media attachments (e.g. inline images), stored as mimebundle keyed by filename. #[derive(Clone, PartialEq, Debug, Deserialize, Serialize)] @@ -74,10 +78,45 @@ impl FromStr for Notebook { type Err = NotebookParseError; fn from_str(s: &str) -> Result<Self, Self::Err> { - Ok(serde_json::from_str(s)?) + match serde_json::from_str(s) { + Err(err) => { + println!( + "An error has been encountered while parsing a notebook:\n{}", + err + ); + let edit = yes_or_no("Edit the file in an editor to fix the json?:"); + if !edit { + Err(err)?; + } + let fixed_json = edit_json(s); + fixed_json.parse() + } + Ok(notebook) => return Ok(notebook), + } } } +fn edit_json(s: &str) -> String { + let editor = get_editor(); + let mut file = tempfile::NamedTempFile::new().expect("Unable to create temp file"); + file.write_all(s.as_bytes()) + .expect("Unable to write json to temp file"); + Command::new(editor) + .arg(file.as_ref()) + .status() + .expect("Unable to start editor"); + let mut buf = String::new(); + let mut file = file.reopen().expect("Unable to reopen temp file"); + file.read_to_string(&mut buf) + .expect("Unable to read from temp file"); + buf +} + +fn get_editor() -> PathBuf { + let editor: PathBuf = input("Please enter a name or a path to a terminal editor"); + editor +} + impl Display for Notebook { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { for cell in &self.cells { @@ -123,12 +162,12 @@ impl Display for CodeCell { .execution_count .and_then(|count| Some(count.to_string())) .unwrap_or(" ".into()); - writeln!(f, "# In[{}]:\n", exec_count_as_str)?; + writeln!(f, "\n# In[{}]:\n", exec_count_as_str)?; writeln!(f, "{}\n", self.source)?; writeln!(f, "# Out[{}]:\n", exec_count_as_str)?; for output in &self.outputs { - write!(f, "{}", comment_out(output.to_string()))?; + write!(f, "{}\n", comment_out(output.to_string()))?; } Ok(()) } @@ -144,7 +183,11 @@ pub struct MarkdownCell { impl Display for MarkdownCell { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - writeln!(f, "# Markdown:\n{}", comment_out(self.source.to_string()))?; + writeln!( + f, + "\n# MarkdownCell:\n{}", + comment_out(self.source.to_string()) + )?; if self.attachments.is_some() { write!( f, @@ -165,7 +208,7 @@ pub struct RawCell { impl Display for RawCell { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - writeln!(f, "# RawCell:\n{}", comment_out(self.source.to_string()))?; + writeln!(f, "\n# RawCell:\n{}", comment_out(self.source.to_string()))?; if self.attachments.is_some() { writeln!( f, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index ee2a313..e9dba4b 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -7,7 +7,11 @@ pub mod ipynb_parser; pub mod xml_parser; pub trait Parser { - fn parse<'a>(path: &Path, parse_text_questions: bool) -> result::Result<Exam, Box<dyn Error>>; + fn parse<'a>( + path: &Path, + parse_text_questions: bool, + render_latex: bool, + ) -> result::Result<Exam, Box<dyn Error>>; } #[derive(Debug)] diff --git a/src/parser/xml_parser.rs b/src/parser/xml_parser.rs index f4eb9a7..bac3926 100644 --- a/src/parser/xml_parser.rs +++ b/src/parser/xml_parser.rs @@ -1,11 +1,3 @@ -use crate::errors::{ - EmptyFieldError, InvalidMatrNumber, InvalidStringLengthError, ValidationError, -}; -use crate::student::Student; -use crate::submission::Submission; -use crate::submission_type::SubmissionType; - -use regex::Regex; use std::collections::{BTreeSet, HashMap}; use std::error::Error; use std::fs::File; @@ -15,14 +7,22 @@ use std::result; use base64::decode; use itertools::Itertools; -use lazy_static::lazy_static; use log::warn; +use regex::Regex; use sxd_document::{dom::Document, parser, Package}; use sxd_xpath::{nodeset::Nodeset, Context, Factory, Value}; use zip::ZipArchive; +use lazy_static::lazy_static; + +use crate::errors::{ + EmptyFieldError, InvalidMatrNumber, InvalidStringLengthError, ValidationError, +}; use crate::exam::Exam; use crate::parser::{Parser, ParserError}; +use crate::student::Student; +use crate::submission::Submission; +use crate::submission_type::SubmissionType; #[derive(Debug, Default)] struct PartialXMLFiles { @@ -86,7 +86,11 @@ impl XMLFiles { pub struct XMLParser {} impl Parser for XMLParser { - fn parse(path: &Path, parse_text_questions: bool) -> result::Result<Exam, Box<dyn Error>> { + fn parse( + path: &Path, + parse_text_questions: bool, + render_latex: bool, + ) -> result::Result<Exam, Box<dyn Error>> { let file = File::open(path)?; let mut archive = ZipArchive::new(file)?; @@ -96,7 +100,7 @@ impl Parser for XMLParser { } else { &["assSourceCode"] }; - let sub_types = extract_submission_types(&xml_files, allowed_question_types)?; + let sub_types = extract_submission_types(&xml_files, allowed_question_types, render_latex)?; let students = extract_students(&xml_files, &sub_types)?; Ok(Exam { @@ -110,6 +114,7 @@ impl Parser for XMLParser { fn extract_submission_types( xml_files: &XMLFiles, allowed_types: &[&str], + render_latex: bool, ) -> result::Result<HashMap<String, SubmissionType>, Box<dyn Error>> { let context = Context::new(); let xp_factory = Factory::new(); @@ -154,7 +159,16 @@ fn extract_submission_types( let name = name_xp.evaluate(&context, item)?.into_string(); let text = text_xp.evaluate(&context, item)?.into_string(); - let sub_type = SubmissionType::new(name).add_description(text); + let mut sub_type = SubmissionType::new(name.clone()).add_description(text); + if render_latex { + sub_type.enable_latex_rendering().unwrap_or_else(|err| { + warn!( + "Unable to render latex for submission type {}.\ + To disable latex rendering, run program with --no-latex.\n{}", + name, err + ) + }); + } results.insert(id, sub_type); } Ok(results) diff --git a/src/submission.rs b/src/submission.rs index 37e90a2..38f27d5 100644 --- a/src/submission.rs +++ b/src/submission.rs @@ -1,11 +1,9 @@ use crate::test_output::TestOutput; use serde::export::fmt::Display; -use std::collections::BTreeMap; use std::error::Error; -use std::hash::{Hash, Hasher}; use std::str::FromStr; -#[derive(Debug, Eq, PartialEq, Serialize, Default, Clone, PartialOrd, Ord)] +#[derive(Debug, Eq, PartialEq, Serialize, Default, Clone, Hash, PartialOrd, Ord)] pub struct Submission { pub code: String, /// This field is populated if the displayed source code differs from the @@ -13,7 +11,7 @@ pub struct Submission { /// into a python script to display but want to keep the original notebook as json pub source_code: Option<String>, pub r#type: String, - pub tests: BTreeMap<String, TestOutput>, + pub tests: Vec<TestOutput>, } impl Submission { @@ -22,7 +20,7 @@ impl Submission { code, source_code: None, r#type, - tests: BTreeMap::new(), + tests: vec![], } } @@ -37,11 +35,3 @@ impl Submission { Ok(()) } } - -impl Hash for Submission { - fn hash<H: Hasher>(&self, state: &mut H) { - self.code.hash(state); - self.source_code.hash(state); - self.r#type.hash(state); - } -} diff --git a/src/submission_type.rs b/src/submission_type.rs index 147f13e..e5b36a3 100644 --- a/src/submission_type.rs +++ b/src/submission_type.rs @@ -6,6 +6,8 @@ use std::str::FromStr; use crate::input; use display_derive::Display; +use sxd_document::{parser, writer::format_document}; +use sxd_xpath::{Context, Factory, Value}; #[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Default, PartialOrd, Ord)] pub struct SubmissionType { @@ -70,6 +72,39 @@ impl SubmissionType { Ok(()) } + + pub fn enable_latex_rendering(&mut self) -> Result<(), Box<dyn Error>> { + if self.description.is_none() { + panic!("enable_latex_rendering must be called after description is set"); + } + let context = Context::new(); + let factory = Factory::new(); + let latex_xp = factory.build("//span[@class='latex']").unwrap().unwrap(); + let wrapped_description = format!("<div>{}</div>", self.description.as_ref().unwrap()); + let package = parser::parse(&wrapped_description)?; + let doc = package.as_document(); + let items = match latex_xp.evaluate(&context, doc.root())? { + Value::Nodeset(nodes) => nodes, + _ => Err("latex xpath didn't return nodeset")?, + }; + for item in items.iter() { + match item.element() { + Some(el) => { + el.set_text(&format!("\\({}\\)", item.string_value())); + } + None => log::warn!( + "Encountered Node without Element during Latex preprocessing.\ + Output may not be able to be rendered" + ), + } + } + + let mut description = vec![]; + format_document(&doc, &mut description)?; + self.description = Some(String::from_utf8(description)?); + + Ok(()) + } } #[allow(non_camel_case_types)] @@ -79,13 +114,13 @@ pub enum ProgrammingLang { java, mipsasm, haskell, - ipynb, + python, plaintext, } #[derive(Debug, Display)] #[display( - fmt = "Unparseable programming language: {}. Allowed: c, java, mipsasm, haskell, ipynb, plaintext", + fmt = "Unparseable programming language: {}. Allowed: c, java, mipsasm, haskell, python, plaintext", input )] pub struct ParseProgrammingLangError { @@ -104,7 +139,7 @@ impl FromStr for ProgrammingLang { "mipsasm" => ProgrammingLang::mipsasm, "haskell" => ProgrammingLang::haskell, "plaintext" => ProgrammingLang::plaintext, - "ipynb" => ProgrammingLang::ipynb, + "python" => ProgrammingLang::python, _ => Err(ParseProgrammingLangError { input: s.to_owned(), })?, diff --git a/src/test_output.rs b/src/test_output.rs index 62bc933..6fb0df5 100644 --- a/src/test_output.rs +++ b/src/test_output.rs @@ -1,4 +1,4 @@ -#[derive(Debug, Eq, PartialEq, Serialize, Default, Clone, PartialOrd, Ord)] +#[derive(Debug, Eq, PartialEq, Serialize, Default, Clone, PartialOrd, Hash, Ord)] pub struct TestOutput { pub name: String, pub annotation: String, diff --git a/tests/test_xml_parser.rs b/tests/test_xml_parser.rs index b534c46..788edd6 100644 --- a/tests/test_xml_parser.rs +++ b/tests/test_xml_parser.rs @@ -7,7 +7,7 @@ use std::collections::{BTreeSet, HashSet}; #[test] fn can_parse_zipped_xml_data() -> Result<(), Box<dyn Error>> { - let parsed = XMLParser::parse(Path::new("tests/test.zip"), false)?; + let parsed = XMLParser::parse(Path::new("tests/test.zip"), false, true)?; let serializable = parsed.into_serializable()?; assert_eq!(1, serializable.submission_types.len()); assert_eq!(1, serializable.students.len()); @@ -16,7 +16,7 @@ fn can_parse_zipped_xml_data() -> Result<(), Box<dyn Error>> { #[test] fn parsed_xml_contains_correct_submission_types() -> Result<(), Box<dyn Error>> { - let parsed = XMLParser::parse(Path::new("tests/test.zip"), false)?; + let parsed = XMLParser::parse(Path::new("tests/test.zip"), false, true)?; let serializable = parsed.into_serializable()?; let submission_type_names: HashSet<String> = serializable @@ -37,7 +37,7 @@ fn parsed_xml_contains_correct_submission_types() -> Result<(), Box<dyn Error>> #[test] fn parsed_xls_contains_correct_students() -> Result<(), Box<dyn Error>> { - let parsed = XMLParser::parse(Path::new("tests/test.zip"), false)?; + let parsed = XMLParser::parse(Path::new("tests/test.zip"), false, true)?; let serializable = parsed.into_serializable()?; let students: BTreeSet<StudentSerializable> = serializable @@ -68,7 +68,7 @@ fn parsed_xls_contains_correct_students() -> Result<(), Box<dyn Error>> { fn correct_mapping_is_generated() -> Result<(), Box<dyn Error>> { use rusty_hektor::anonymizer; - let parsed = XMLParser::parse(Path::new("tests/test.zip"), false)?; + let parsed = XMLParser::parse(Path::new("tests/test.zip"), false, true)?; let mut serializable = parsed.into_serializable()?; let map = anonymizer::replace_students(&mut serializable.students); -- GitLab