diff --git a/Cargo.lock b/Cargo.lock index cbef3fb..c3bd07a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,12 @@ version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +[[package]] +name = "argparse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f8ebf5827e4ac4fd5946560e6a99776ea73b596d80898f357007317a7141e47" + [[package]] name = "async-channel" version = "2.3.1" @@ -158,7 +164,7 @@ checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -246,7 +252,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -276,6 +282,36 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.6.0" @@ -409,6 +445,32 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const_format" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "cookie" version = "0.18.1" @@ -450,6 +512,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -529,6 +600,30 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.77", +] + [[package]] name = "deunicode" version = "1.6.0" @@ -553,6 +648,12 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "either" version = "1.13.0" @@ -562,6 +663,12 @@ dependencies = [ "serde", ] +[[package]] +name = "entities" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" + [[package]] name = "equivalent" version = "1.0.1" @@ -610,12 +717,32 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "fancy-regex" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +dependencies = [ + "bit-set", + "regex", +] + [[package]] name = "fastrand" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "flume" version = "0.11.0" @@ -721,7 +848,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -801,7 +928,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags", + "bitflags 2.6.0", "ignore", "walkdir", ] @@ -895,6 +1022,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + [[package]] name = "http" version = "1.1.0" @@ -1038,6 +1174,16 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "0.5.0" @@ -1144,6 +1290,21 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linkify" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dfa36d52c581e9ec783a7ce2a5e0143da6237be5811a0b3153fedfdbe9f780" +dependencies = [ + "memchr", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -1177,6 +1338,7 @@ dependencies = [ "common", "dotenvy", "futures-util", + "markdown-it", "oauth2", "reqwest", "serde", @@ -1190,6 +1352,29 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "markdown-it" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f99c010929c8217b2dc0940954267a2e15a15f17cb309cd1f299e21933f84fac" +dependencies = [ + "argparse", + "const_format", + "derivative", + "derive_more", + "downcast-rs", + "entities", + "html-escape", + "linkify", + "mdurl", + "once_cell", + "readonly", + "regex", + "stacker", + "syntect", + "unicode-general-category", +] + [[package]] name = "matchers" version = "0.1.0" @@ -1215,6 +1400,17 @@ dependencies = [ "digest", ] +[[package]] +name = "mdurl" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5736ba45bbac8f7ccc99a897f88ce85e508a18baec973a040f2514e6cdbff0d2" +dependencies = [ + "idna 0.3.0", + "once_cell", + "regex", +] + [[package]] name = "memchr" version = "2.7.4" @@ -1468,7 +1664,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -1537,7 +1733,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -1590,6 +1786,19 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "plist" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" +dependencies = [ + "base64", + "indexmap", + "quick-xml", + "serde", + "time", +] + [[package]] name = "polling" version = "3.7.3" @@ -1629,6 +1838,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "psm" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205" +dependencies = [ + "cc", +] + +[[package]] +name = "quick-xml" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +dependencies = [ + "memchr", +] + [[package]] name = "quinn" version = "0.11.5" @@ -1716,13 +1943,24 @@ dependencies = [ "getrandom", ] +[[package]] +name = "readonly" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25d631e41bfb5fdcde1d4e2215f62f7f0afa3ff11e26563765bd6ea1d229aeb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "redox_syscall" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ - "bitflags", + "bitflags 2.6.0", ] [[package]] @@ -1859,13 +2097,22 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1940,6 +2187,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "serde" version = "1.0.210" @@ -1966,7 +2219,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -2194,7 +2447,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn", + "syn 2.0.77", ] [[package]] @@ -2217,7 +2470,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn", + "syn 2.0.77", "tempfile", "tokio", "url", @@ -2231,7 +2484,7 @@ checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a" dependencies = [ "atoi", "base64", - "bitflags", + "bitflags 2.6.0", "byteorder", "bytes", "crc", @@ -2273,7 +2526,7 @@ checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8" dependencies = [ "atoi", "base64", - "bitflags", + "bitflags 2.6.0", "byteorder", "crc", "dotenvy", @@ -2326,6 +2579,19 @@ dependencies = [ "url", ] +[[package]] +name = "stacker" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.59.0", +] + [[package]] name = "stringprep" version = "0.1.5" @@ -2343,6 +2609,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.77" @@ -2369,6 +2646,28 @@ dependencies = [ "futures-core", ] +[[package]] +name = "syntect" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" +dependencies = [ + "bincode", + "bitflags 1.3.2", + "fancy-regex", + "flate2", + "fnv", + "once_cell", + "plist", + "regex-syntax 0.8.4", + "serde", + "serde_derive", + "serde_json", + "thiserror", + "walkdir", + "yaml-rust", +] + [[package]] name = "tempfile" version = "3.12.0" @@ -2421,7 +2720,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -2505,7 +2804,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -2597,7 +2896,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8437150ab6bbc8c5f0f519e3d5ed4aa883a83dd4cdd3d1b21f9482936046cb97" dependencies = [ - "bitflags", + "bitflags 2.6.0", "bytes", "futures-util", "http", @@ -2699,7 +2998,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] @@ -2824,6 +3123,12 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +[[package]] +name = "unicode-general-category" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7" + [[package]] name = "unicode-ident" version = "1.0.13" @@ -2845,6 +3150,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "unicode_categories" version = "0.1.1" @@ -2864,11 +3175,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", - "idna", + "idna 0.5.0", "percent-encoding", "serde", ] +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + [[package]] name = "valuable" version = "0.1.0" @@ -2940,7 +3257,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -2974,7 +3291,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3232,6 +3549,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -3250,7 +3576,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.77", ] [[package]] diff --git a/lang-runner/src/run.rs b/lang-runner/src/run.rs index 483b46d..2eb02ad 100644 --- a/lang-runner/src/run.rs +++ b/lang-runner/src/run.rs @@ -171,7 +171,7 @@ async fn run_lang( } let data = serde_json::to_string(&RunnerInput { lang, code, judge }) - .map_err(|e| RunProcessError::SerializationFailed(e))?; + .map_err(RunProcessError::SerializationFailed)?; stdin.write_all(data.as_bytes()).await?; let output = child.output().await?; diff --git a/main-server/Cargo.toml b/main-server/Cargo.toml index d3da905..e5de5b9 100644 --- a/main-server/Cargo.toml +++ b/main-server/Cargo.toml @@ -22,3 +22,4 @@ oauth2 = "5.0.0-rc.1" tower-sessions = "0.13.0" tower-http = { version = "0.6.1", features = ["catch-panic", "fs"] } serde_json = "1.0.128" +markdown-it = "0.6.1" diff --git a/main-server/src/auto_output_format.rs b/main-server/src/auto_output_format.rs index c91eaa1..7e2b823 100644 --- a/main-server/src/auto_output_format.rs +++ b/main-server/src/auto_output_format.rs @@ -18,7 +18,10 @@ use serde::Deserialize; use serde::{de::DeserializeOwned, Serialize}; use tera::{escape_html, to_value, Context, Tera, Value}; -use crate::models::account::Account; +use crate::{ + markdown::MarkdownFilter, + models::account::Account, +}; #[derive(Serialize)] pub struct HtmlContext { @@ -214,6 +217,7 @@ impl AutoOutputFormat { tera.autoescape_on(vec![".html.jinja", ".xml.jinja", ".html", ".xml"]); tera.register_function("languages", get_langs); tera.register_function("modules", load_assets); + tera.register_filter("markdown", MarkdownFilter); tera }) }); diff --git a/main-server/src/controllers/challenges.rs b/main-server/src/controllers/challenges.rs index 1462df4..929b8f8 100644 --- a/main-server/src/controllers/challenges.rs +++ b/main-server/src/controllers/challenges.rs @@ -101,7 +101,7 @@ pub async fn new_challenge( ) .fetch_one(&pool) .await - .map_err(|e| Error::DatabaseError(e))?; + .map_err(Error::DatabaseError)?; Ok(Redirect::temporary(&format!("/challenge/{row}")).into_response()) } diff --git a/main-server/src/main.rs b/main-server/src/main.rs index 2deca1b..378f44d 100644 --- a/main-server/src/main.rs +++ b/main-server/src/main.rs @@ -2,6 +2,7 @@ mod auto_output_format; mod controllers; mod error; mod file_session_storage; +mod markdown; mod models; mod session; mod test_solution; diff --git a/main-server/src/markdown.rs b/main-server/src/markdown.rs new file mode 100644 index 0000000..f397e82 --- /dev/null +++ b/main-server/src/markdown.rs @@ -0,0 +1,51 @@ +use std::cell::OnceCell; + +use markdown_it::{plugins::cmark::inline::link::Link, MarkdownIt}; +use tera::Filter; + +thread_local! { + static MARKDOWN: OnceCell = const { OnceCell::new() }; +} + +pub fn render_markdown(source: &str) -> String { + MARKDOWN.with(|markdown| { + let parser = markdown.get_or_init(|| { + let mut parser = markdown_it::MarkdownIt::new(); + markdown_it::plugins::cmark::add(&mut parser); + markdown_it::plugins::extra::add(&mut parser); + parser + }); + + let mut ast = parser.parse(source); + + // TODO: this is probbly better with a plugin + ast.walk_mut(|e, _index| { + if e.is::() { + e.attrs.push(("rel", "nofollow noopener".to_owned())); + } + }); + ast.render() + }) +} + +pub struct MarkdownFilter; + +impl Filter for MarkdownFilter { + fn is_safe(&self) -> bool { + true + } + + fn filter( + &self, + value: &tera::Value, + args: &std::collections::HashMap, + ) -> tera::Result { + if !args.is_empty() { + return Err(tera::Error::msg("The markdown function takes no arguments")); + } + let text = value + .as_str() + .ok_or_else(|| tera::Error::msg("Expected type to be a string"))?; + Ok(tera::Value::String(render_markdown(text))) + } +} diff --git a/main-server/src/models/challenge.rs b/main-server/src/models/challenge.rs index 14f5aa4..451fd93 100644 --- a/main-server/src/models/challenge.rs +++ b/main-server/src/models/challenge.rs @@ -56,7 +56,7 @@ impl ChallengeWithAuthorInfo { .bind(id) .fetch_optional(pool) .await - .map_err(|e| Error::DatabaseError(e))?; + .map_err(Error::DatabaseError)?; Ok(challenge) } diff --git a/templates/base/base.html.jinja b/templates/base/base.html.jinja index a378fc2..df25c1a 100644 --- a/templates/base/base.html.jinja +++ b/templates/base/base.html.jinja @@ -7,6 +7,7 @@ + {% endblock head %} {% block scripts %} diff --git a/templates/challenge.html.jinja b/templates/challenge.html.jinja index d7b48b2..070adfb 100644 --- a/templates/challenge.html.jinja +++ b/templates/challenge.html.jinja @@ -5,14 +5,16 @@

{{ object.challenge.challenge.name }}

A challenge by - {{ object.challenge.author_name }} avatar + {{ object.challenge.author_name }} avatar {{ object.challenge.author_name }} Edit

Descripion

- {{ object.challenge.challenge.description }} + {{ object.challenge.challenge.description | markdown }}

Leaderboard