1
0
Fork 0
mirror of https://github.com/lise-henry/crowbook synced 2024-04-20 05:03:49 +02:00

Merge pull request #104 from Geobert/update-clap

chore: update dependencies
This commit is contained in:
Élisabeth Henry 2023-01-02 23:31:21 +01:00 committed by GitHub
commit ad785c5b21
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 591 additions and 488 deletions

336
Cargo.lock generated
View File

@ -17,6 +17,17 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom",
"once_cell",
"version_check",
]
[[package]]
name = "aho-corasick"
version = "0.6.10"
@ -35,15 +46,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -203,39 +205,38 @@ dependencies = [
[[package]]
name = "clap"
version = "2.34.0"
version = "4.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim 0.8.0",
"textwrap 0.11.0",
"unicode-width",
"vec_map",
"clap_derive",
"clap_lex",
"once_cell",
"strsim 0.10.0",
"termcolor",
"terminal_size 0.2.2",
]
[[package]]
name = "clap"
version = "3.2.15"
name = "clap_derive"
version = "4.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44bbe24bbd31a185bc2c4f7c2abe80bea13a20d57ee4e55be70ac512bdc76417"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
dependencies = [
"atty",
"bitflags",
"clap_lex",
"indexmap",
"strsim 0.10.0",
"termcolor",
"textwrap 0.15.0",
"heck",
"proc-macro-error",
"proc-macro2 1.0.42",
"quote 1.0.20",
"syn 1.0.98",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
@ -251,19 +252,19 @@ dependencies = [
[[package]]
name = "comrak"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15bf1e432b302dc6236dd0db580d182ce520bb24af82d6462e2d7a5e0a31c50d"
checksum = "c11e55664fcff7f4d37cc2adf3a1996913692f037312f4ab0909047fdd2bf962"
dependencies = [
"clap 2.34.0",
"clap",
"entities",
"lazy_static 1.4.0",
"memchr",
"once_cell",
"pest",
"pest_derive",
"regex 1.6.0",
"regex 1.7.0",
"shell-words",
"syntect 4.6.0",
"syntect",
"typed-arena",
"unicode_categories",
"xdg",
@ -278,8 +279,8 @@ dependencies = [
"encode_unicode",
"libc",
"once_cell",
"regex 1.6.0",
"terminal_size",
"regex 1.7.0",
"terminal_size 0.1.17",
"unicode-width",
"winapi 0.3.9",
]
@ -359,7 +360,7 @@ name = "crowbook"
version = "0.16.0"
dependencies = [
"caribon",
"clap 3.2.15",
"clap",
"comrak",
"console",
"crowbook-intl",
@ -381,9 +382,9 @@ dependencies = [
"serde_derive",
"serde_json",
"simplelog",
"syntect 5.0.0",
"syntect",
"tempdir",
"textwrap 0.15.0",
"textwrap",
"url",
"uuid 1.1.2",
"walkdir 2.3.2",
@ -417,7 +418,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0fe6b9d03ee72398cab2bd37c564bb898e351c4cff1f5f8a0db2bd9b909accc"
dependencies = [
"lazy_static 1.4.0",
"regex 1.6.0",
"regex 1.7.0",
]
[[package]]
@ -485,7 +486,7 @@ dependencies = [
"atty",
"humantime",
"log 0.4.17",
"regex 1.6.0",
"regex 1.7.0",
"termcolor",
]
@ -502,12 +503,33 @@ dependencies = [
"lazy_static 1.4.0",
"log 0.4.17",
"mustache",
"regex 1.6.0",
"regex 1.7.0",
"tempdir",
"uuid 0.8.2",
"zip",
]
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi 0.3.9",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "error-chain"
version = "0.12.4"
@ -531,7 +553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6b8560a05112eb52f04b00e5d3790c0dd75d9d980eb8a122fb23b92a623ccf"
dependencies = [
"bit-set",
"regex 1.6.0",
"regex 1.7.0",
]
[[package]]
@ -700,6 +722,15 @@ name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
dependencies = [
"ahash",
]
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
@ -842,14 +873,14 @@ dependencies = [
[[package]]
name = "indicatif"
version = "0.16.2"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b"
checksum = "4295cbb7573c16d310e99e713cf9e75101eb190ab31fccd35f2d2691b4352b19"
dependencies = [
"console",
"lazy_static 1.4.0",
"number_prefix",
"regex 1.6.0",
"portable-atomic",
"unicode-width",
]
[[package]]
@ -861,6 +892,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "io-lifetimes"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074"
[[package]]
name = "ipnet"
version = "2.5.0"
@ -904,12 +941,6 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.126"
@ -931,6 +962,12 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d"
[[package]]
name = "log"
version = "0.3.9"
@ -1010,7 +1047,7 @@ dependencies = [
"libc",
"log 0.4.17",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys",
"windows-sys 0.36.1",
]
[[package]]
@ -1373,6 +1410,36 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c135f38778ad324d9e9ee68690bac2c1a51f340fdf96ca13e2ab3914eb2e51d8"
[[package]]
name = "portable-atomic"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2 1.0.42",
"quote 1.0.20",
"syn 1.0.98",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2 1.0.42",
"quote 1.0.20",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "0.4.30"
@ -1542,21 +1609,19 @@ dependencies = [
[[package]]
name = "rayon"
version = "1.5.3"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
dependencies = [
"autocfg 1.1.0",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.3"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
@ -1608,9 +1673,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.6.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
dependencies = [
"aho-corasick 0.7.18",
"memchr",
@ -1696,6 +1761,20 @@ version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
[[package]]
name = "rustix"
version = "0.35.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72c825b8aa8010eb9ee99b75f05e10180b9278d161583034d7574c9d617aeada"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys 0.36.1",
]
[[package]]
name = "ryu"
version = "1.0.10"
@ -1734,7 +1813,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
dependencies = [
"lazy_static 1.4.0",
"windows-sys",
"windows-sys 0.36.1",
]
[[package]]
@ -1885,12 +1964,6 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.10.0"
@ -1919,29 +1992,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "syntect"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b20815bbe80ee0be06e6957450a841185fcf690fe0178f14d77a05ce2caa031"
dependencies = [
"bincode",
"bitflags",
"fancy-regex",
"flate2",
"fnv",
"lazy_static 1.4.0",
"lazycell",
"onig",
"plist",
"regex-syntax 0.6.27",
"serde",
"serde_derive",
"serde_json",
"walkdir 2.3.2",
"yaml-rust",
]
[[package]]
name = "syntect"
version = "5.0.0"
@ -1950,6 +2000,7 @@ checksum = "c6c454c27d9d7d9a84c7803aaa3c50cd088d2906fe3c6e42da3209aa623576a8"
dependencies = [
"bincode",
"bitflags",
"fancy-regex",
"flate2",
"fnv",
"lazy_static 1.4.0",
@ -2009,19 +2060,20 @@ dependencies = [
]
[[package]]
name = "textwrap"
version = "0.11.0"
name = "terminal_size"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
checksum = "40ca90c434fd12083d1a6bdcbe9f92a14f96c8a1ba600ba451734ac334521f7a"
dependencies = [
"unicode-width",
"rustix",
"windows-sys 0.42.0",
]
[[package]]
name = "textwrap"
version = "0.15.0"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
dependencies = [
"smawk",
"unicode-linebreak",
@ -2177,9 +2229,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "typed-arena"
version = "1.7.0"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
[[package]]
name = "typenum"
@ -2222,11 +2274,12 @@ checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]]
name = "unicode-linebreak"
version = "0.1.2"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f"
checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137"
dependencies = [
"regex 1.6.0",
"hashbrown",
"regex 1.7.0",
]
[[package]]
@ -2240,9 +2293,9 @@ dependencies = [
[[package]]
name = "unicode-width"
version = "0.1.9"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "unicode-xid"
@ -2304,12 +2357,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.4"
@ -2485,43 +2532,100 @@ version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_msvc",
"windows_aarch64_msvc 0.36.1",
"windows_i686_gnu 0.36.1",
"windows_i686_msvc 0.36.1",
"windows_x86_64_gnu 0.36.1",
"windows_x86_64_msvc 0.36.1",
]
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.42.0",
"windows_i686_gnu 0.42.0",
"windows_i686_msvc 0.42.0",
"windows_x86_64_gnu 0.42.0",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.42.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
[[package]]
name = "winreg"
version = "0.10.1"

View File

@ -13,6 +13,7 @@ license = "LGPL-2.1+"
publish = true
build = "build.rs"
autobins = false
rust-version = "1.58"
exclude = [
"docs/*",
@ -48,13 +49,13 @@ crowbook-intl = "0.2"
[dependencies]
mime_guess = "2"
comrak = "0.14"
comrak = "0.15"
yaml-rust = "0.4"
mustache = "0.9"
uuid = { version = "1", features = ["v4"] }
walkdir = "2"
rustc-serialize = "0.3"
rayon = "1.0"
rayon = "1.6"
crowbook-text-processing = "1"
lazy_static = "1"
crowbook-intl-runtime = "0.1"
@ -63,14 +64,14 @@ epub-builder = "0.5"
log = "0.4"
punkt = { version = "1.0", optional = true }
hyphenation = { version = "0.8", optional = true, features = ["embed_all"] }
textwrap = { version = "0.15", optional = true }
textwrap = { version = "0.16", optional = true }
serde = { version = "1", optional = true }
serde_json = { version = "1", optional = true }
serde_derive = { version = "1", optional = true }
indicatif = { version = "0.16", optional = true }
indicatif = { version = "0.17", optional = true }
console = { version = "0.15", optional = true }
caribon = { version = "0.8", optional = true }
clap = { version = "3", optional = true }
clap = { version = "4", optional = true }
simplelog = { version = "0.12", optional = true }
url = { version = "2", optional = true }
syntect = { version = "5", optional = true }

View File

@ -15,7 +15,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with Crowbook. If not, see <http://www.gnu.org/licenses/>.
use clap::{Command, AppSettings, Arg, ArgMatches};
use clap::{Arg, ArgAction, ArgMatches, Command};
use console::style;
use crowbook::Book;
@ -76,9 +76,9 @@ pub fn get_lang() -> Option<String> {
}
/// Gets the book options in a (key, value) list, or print an error
pub fn get_book_options<'a>(matches: &'a ArgMatches) -> Vec<(&'a str, &'a str)> {
pub fn get_book_options(matches: &ArgMatches) -> Vec<(&str, &str)> {
let mut output = vec![];
if let Some(iter) = matches.values_of("set") {
if let Some(iter) = matches.get_many::<String>("set") {
let v: Vec<_> = iter.collect();
if v.len() % 2 != 0 {
print_error_and_exit(
@ -93,10 +93,10 @@ pub fn get_book_options<'a>(matches: &'a ArgMatches) -> Vec<(&'a str, &'a str)>
for i in 0..v.len() / 2 {
let key = v[i * 2];
let value = v[i * 2 + 1];
output.push((key, value));
output.push((key.as_str(), value.as_str()));
}
}
if matches.is_present("proofread") {
if matches.get_flag("proofread") {
output.push(("proofread", "true"));
}
output
@ -115,7 +115,7 @@ pub fn set_book_options(book: &mut Book, matches: &ArgMatches) -> String {
if let Err(err) = res {
print_error_and_exit(&lformat!("Error in setting key {}: {}", key, err), false);
}
output.push_str(&format!("{}: {}\n", key, value));
output.push_str(&format!("{key}: {value}\n"));
}
output
}
@ -123,7 +123,7 @@ pub fn set_book_options(book: &mut Book, matches: &ArgMatches) -> String {
/// create a book file with the command line arguments
/// and exit the process at the end
pub fn create_book(matches: &ArgMatches) -> ! {
let mut f: Box<dyn Write> = if let Some(book) = matches.value_of("BOOK") {
let mut f: Box<dyn Write> = if let Some(book) = matches.get_one::<String>("BOOK") {
if fs::metadata(book).is_ok() {
print_error_and_exit(
&lformat!("Could not create file {}: it already exists!", book),
@ -135,8 +135,8 @@ pub fn create_book(matches: &ArgMatches) -> ! {
Box::new(io::stdout())
};
if let Some(values) = matches.values_of("create") {
if matches.is_present("set") {
if let Some(values) = matches.get_many::<String>("files") {
if matches.get_many::<String>("set").is_some() {
let mut book = Book::new();
let s = set_book_options(&mut book, matches);
f.write_all(s.as_bytes()).unwrap();
@ -167,9 +167,9 @@ lang: en
f.write_all(lformat!("\n## List of chapters\n").as_bytes())
.unwrap();
for file in values {
f.write_all(format!("+ {}\n", file).as_bytes()).unwrap();
f.write_all(format!("+ {file}\n").as_bytes()).unwrap();
}
if let Some(s) = matches.value_of("BOOK") {
if let Some(s) = matches.get_one::<String>("BOOK") {
println!(
"{}",
lformat!("Created {}, now you'll have to complete it!", s)
@ -181,10 +181,13 @@ lang: en
}
}
pub fn create_matches() -> (ArgMatches, String, String) {
pub fn create_matches() -> ArgMatches {
app().get_matches()
}
// in its own function for testing purpose
fn app() -> clap::Command {
lazy_static! {
static ref HELP: String = lformat!("Print help information");
static ref VERSION: String = lformat!("Print version information");
static ref ABOUT: String = lformat!("Render a Markdown book in EPUB, PDF or HTML.");
static ref SINGLE: String = lformat!("Use a single Markdown file instead of a book configuration file");
static ref EMOJI: String = lformat!("Force emoji usage even if it might not work on your system");
@ -210,9 +213,6 @@ pub fn create_matches() -> (ArgMatches, String, String) {
USAGE:
{{usage}}
FLAGS:
{{flags}}
OPTIONS:
{{options}}
@ -221,35 +221,84 @@ ARGS:
");
}
let mut app = Command::new("crowbook")
let app = Command::new("crowbook")
.version(env!("CARGO_PKG_VERSION"))
.author("Élisabeth Henry <liz.henry@ouvaton.org>")
.setting(AppSettings::UnifiedHelpMessage)
.setting(AppSettings::HidePossibleValuesInHelp)
.hide_possible_values(true)
.about(ABOUT.as_str())
.arg(Arg::from_usage("-☺️, --force-emoji").help(EMOJI.as_str()))
.arg(Arg::from_usage("-s, --single").help(SINGLE.as_str()))
.arg(Arg::from_usage("-n, --no-fancy").help(NO_FANCY.as_str()))
.arg(Arg::from_usage("-v, --verbose").help(VERBOSE.as_str()))
.arg(Arg::from_usage("-a, --autograph").help(AUTOGRAPH.as_str()))
.arg(
Arg::from_usage("-q, --quiet")
Arg::new("force-emoji")
.short('f')
.long("force-emoji")
.action(ArgAction::SetTrue)
.help(EMOJI.as_str()),
)
.arg(
Arg::new("single")
.short('s')
.long("single")
.action(ArgAction::SetTrue)
.help(SINGLE.as_str()),
)
.arg(
Arg::new("no-fancy")
.short('n')
.long("no-fancy")
.action(ArgAction::SetTrue)
.help(NO_FANCY.as_str()),
)
.arg(
Arg::new("verbose")
.short('v')
.long("verbose")
.action(ArgAction::SetTrue)
.help(VERBOSE.as_str()),
)
.arg(
Arg::new("autograph")
.short('a')
.long("autograph")
.action(ArgAction::SetTrue)
.help(AUTOGRAPH.as_str()),
)
.arg(
Arg::new("quiet")
.short('q')
.long("quiet")
.action(ArgAction::SetTrue)
.help(QUIET.as_str())
.conflicts_with("verbose"),
)
.arg(Arg::from_usage("-h, --help").help(HELP.as_str()))
.arg(Arg::from_usage("-V, --version").help(VERSION.as_str()))
.arg(Arg::from_usage("-p, --proofread").help(PROOFREAD.as_str()))
.arg(Arg::from_usage("-c, --create [FILES]...").help(CREATE.as_str()))
.arg(
Arg::from_usage("-o, --output [FILE]")
Arg::new("proofread")
.short('p')
.long("poofread")
.action(ArgAction::SetTrue)
.help(PROOFREAD.as_str()),
)
.arg(
Arg::new("files")
.short('c')
.long("create")
.action(ArgAction::Set)
.num_args(1..)
.help(CREATE.as_str()),
)
.arg(
Arg::new("output")
.short('o')
.long("output")
.action(ArgAction::Set)
.num_args(1)
.help(OUTPUT.as_str())
.requires("to"),
)
.arg(
Arg::from_usage("-t, --to [FORMAT]")
.help(TO.as_str())
.possible_values(&[
Arg::new("to")
.short('t')
.long("to")
.action(ArgAction::Set)
.value_parser([
"epub",
"pdf",
"html",
@ -260,48 +309,69 @@ ARGS:
"proofread.html.dir",
"proofread.pdf",
"proofread.tex",
]),
])
.help(TO.as_str()),
)
.arg(
Arg::from_usage("--set [KEY_VALUES]")
.help(SET.as_str())
.min_values(2),
Arg::new("set")
.long("set")
.action(ArgAction::Set)
.num_args(2..)
.help(SET.as_str()),
)
.arg(Arg::from_usage("-l --list-options").help(LIST_OPTIONS.as_str()))
.arg(
Arg::from_usage("--list-options-md")
Arg::new("list-options")
.short('l')
.long("list-options")
.action(ArgAction::SetTrue)
.help(LIST_OPTIONS.as_str()),
)
.arg(
Arg::new("list-options-md")
.long("list-options-md")
.action(ArgAction::SetTrue)
.help(LIST_OPTIONS_MD.as_str())
.hidden(true),
.hide(true),
)
.arg(Arg::from_usage("-L --lang [LANG]").help(LANG.as_str()))
.arg(Arg::from_usage("--print-template [TEMPLATE]").help(PRINT_TEMPLATE.as_str()))
.arg(Arg::from_usage("--stats -S").help(STATS.as_str()))
.arg(Arg::with_name("BOOK").index(1).help(BOOK.as_str()))
.template(TEMPLATE.as_str());
.arg(
Arg::new("lang")
.short('L')
.long("lang")
.action(ArgAction::Set)
.num_args(1)
.help(LANG.as_str()),
)
.arg(
Arg::new("print-template")
.long("print-template")
.action(ArgAction::Set)
.num_args(1)
.help(PRINT_TEMPLATE.as_str()),
)
.arg(
Arg::new("stats")
.short('S')
.long("stats")
.action(ArgAction::SetTrue)
.help(STATS.as_str()),
)
.arg(
Arg::new("BOOK")
.index(1)
.action(ArgAction::Set)
.help(BOOK.as_str()),
)
.help_template(TEMPLATE.as_str());
// Write help and version now since it `app` is moved when `get_matches` is run
let mut help = vec![];
app.write_help(&mut help).unwrap();
let help = String::from_utf8(help).unwrap();
let mut version = vec![];
app.write_version(&mut version).unwrap();
let version = String::from_utf8(version).unwrap();
let matches = app.get_matches();
pre_check(&matches);
(matches, help, version)
app
}
/// Pre-check the matches to see if there isn't illegal options not detected by clap
fn pre_check(matches: &ArgMatches) {
if matches.is_present("files") && !matches.is_present("create") {
print_error_and_exit(
&lformat!(
"A list of additional files is only valid with the --create \
option."
),
false,
);
#[cfg(test)]
mod tests {
use super::app;
#[test]
fn verify_app() {
app().debug_assert();
}
}

View File

@ -39,8 +39,8 @@ fn render_format(book: &mut Book, emoji: bool, matches: &ArgMatches, format: &st
let mut stdout = false;
let mut file = None;
if let Some(f) = matches.value_of("output") {
if f == "-" {
if let Some(f) = matches.get_one::<String>("output") {
if f.as_str() == "-" {
stdout = true;
} else {
file = Some(String::from(f));
@ -56,7 +56,7 @@ fn render_format(book: &mut Book, emoji: bool, matches: &ArgMatches, format: &st
};
if let Err(err) = result {
print_error(&format!("{}", err), emoji)
print_error(&format!("{err}"), emoji)
}
}
@ -76,39 +76,38 @@ pub fn try_main() -> Result<()> {
let mut fancy_ui = true;
let mut emoji = console::Term::stderr().features().wants_emoji();
let (matches, help, version) = create_matches();
let matches = create_matches();
if matches.is_present("force-emoji") {
if matches.get_flag("force-emoji") {
emoji = true;
}
if !matches.is_present("quiet") {
if !matches.get_flag("quiet") {
display_header(emoji);
}
if matches.is_present("list-options") {
if matches.get_flag("list-options") {
println!("{}", BookOptions::description(false));
exit(0);
}
if matches.is_present("no-fancy") || matches.is_present("stats") {
if matches.get_flag("no-fancy") || matches.get_flag("stats") {
fancy_ui = false;
emoji = false;
}
if matches.is_present("list-options-md") {
if matches.get_flag("list-options-md") {
println!("{}", BookOptions::description(true));
exit(0);
}
if matches.is_present("print-template") {
let template = matches.value_of("print-template").unwrap();
if let Some(template) = matches.get_one::<String>("print-template") {
let mut book = Book::new();
set_book_options(&mut book, &matches);
let result = book.get_template(template.as_ref());
match result {
Ok(s) => {
println!("{}", s);
println!("{s}");
exit(0);
}
Err(_) => print_error_and_exit(
@ -118,44 +117,34 @@ pub fn try_main() -> Result<()> {
}
}
if matches.is_present("help") {
println!("{}", help);
exit(0);
}
if matches.is_present("version") {
println!("{}", version);
exit(0);
}
if matches.is_present("create") {
if matches.get_many::<String>("files").is_some() {
create_book(&matches);
}
if !matches.is_present("BOOK") {
let book = matches.get_one::<String>("BOOK");
if book.is_none() {
print_error_and_exit(
&lformat!(
"You must pass the file of a book configuration \
file.\nnFor more information try --help."
file.\nFor more information try --help."
),
emoji,
);
}
// ok to unwrap since clap checks it's there
let s = matches.value_of("BOOK").unwrap();
let &s = book.as_ref().unwrap();
// Initalize logger
let mut builder = ConfigBuilder::new();
builder.set_target_level(LevelFilter::Off);
builder.set_location_level(LevelFilter::Off);
builder.set_time_level(LevelFilter::Off);
let verbosity = if matches.is_present("verbose") && !matches.is_present("stats") {
let verbosity = if matches.get_flag("verbose") && !matches.get_flag("stats") {
builder.set_time_level(LevelFilter::Error);
builder.set_target_level(LevelFilter::Error);
fancy_ui = false;
LevelFilter::Debug
} else if matches.is_present("quiet") {
} else if matches.get_flag("quiet") {
fancy_ui = false;
LevelFilter::Error
} else if fancy_ui {
@ -184,7 +173,7 @@ pub fn try_main() -> Result<()> {
{
let mut book = Book::new();
if matches.is_present("autograph") {
if matches.get_flag("autograph") {
println!("{}", &lformat!("Enter autograph: "));
let mut autograph = String::new();
match io::stdin().read_to_string(&mut autograph) {
@ -206,7 +195,7 @@ pub fn try_main() -> Result<()> {
book.set_options(&get_book_options(&matches));
{
let res = if matches.is_present("single") {
let res = if matches.get_flag("single") {
if s != "-" {
book.load_markdown_file(s)
} else {
@ -222,7 +211,7 @@ pub fn try_main() -> Result<()> {
match res {
Ok(..) => {}
Err(err) => {
book.set_error(&format!("{}", err));
book.set_error(&format!("{err}"));
return Err(err);
}
}
@ -230,13 +219,13 @@ pub fn try_main() -> Result<()> {
set_book_options(&mut book, &matches);
if matches.is_present("stats") {
let stats = Stats::new(&book, matches.is_present("verbose"));
println!("{}", stats);
if matches.get_flag("stats") {
let stats = Stats::new(&book, matches.get_flag("verbose"));
println!("{stats}");
exit(0);
}
if let Some(format) = matches.value_of("to") {
if let Some(format) = matches.get_one::<String>("to") {
render_format(&mut book, emoji, &matches, format);
} else {
book.render_all();
@ -282,6 +271,6 @@ pub fn try_main() -> Result<()> {
pub fn real_main() {
if let Err(err) = try_main() {
print_error_and_exit(&format!("{}", err), false);
print_error_and_exit(&format!("{err}"), false);
}
}

View File

@ -312,7 +312,7 @@ impl Book {
I: IntoIterator<Item = &'a (&'a str, &'a str)>,
{
// set options
for &(key, value) in options {
for (key, value) in options {
if let Err(err) = self.options.set(key, value) {
error!(
"{}",
@ -515,7 +515,7 @@ impl Book {
/// ```
pub fn read_config<R: Read>(&mut self, mut source: R) -> Result<&mut Book> {
fn get_filename<'a>(source: &Source, s: &'a str) -> Result<&'a str> {
let words: Vec<&str> = (&s[1..]).split_whitespace().collect();
let words: Vec<&str> = (s[1..]).split_whitespace().collect();
if words.len() > 1 {
return Err(Error::config_parser(
source,
@ -551,17 +551,14 @@ impl Book {
let mut line_number = 0;
let mut is_next_line_ok: bool;
loop {
if let Some(next_line) = lines.peek() {
if next_line.starts_with(|c| match c {
'-' | '+' | '!' | '@' => true,
_ => c.is_digit(10),
}) {
break;
}
} else {
while let Some(next_line) = lines.peek() {
if next_line.starts_with(|c| match c {
'-' | '+' | '!' | '@' => true,
_ => c.is_ascii_digit(),
}) {
break;
}
line = lines.next().unwrap();
line_number += 1;
self.source.set_line(line_number);
@ -578,15 +575,14 @@ impl Book {
if let Some(next_line) = lines.peek() {
let doc = YamlLoader::load_from_str(next_line);
if doc.is_err() {
is_next_line_ok = false;
} else {
let doc = doc.unwrap();
if let Ok(doc) = doc {
if !doc.is_empty() && doc[0].as_hash().is_some() {
is_next_line_ok = true;
} else {
is_next_line_ok = false;
}
} else {
is_next_line_ok = false;
}
} else {
break;
@ -659,7 +655,7 @@ impl Book {
// hidden chapter
let file = get_filename(&self.source, line)?;
self.add_chapter(Number::Hidden, file, false)?;
} else if line.starts_with(|c: char| c.is_digit(10)) {
} else if line.starts_with(|c: char| c.is_ascii_digit()) {
// chapter with specific number
let parts: Vec<_> = line
.splitn(2, |c: char| c == '.' || c == ':' || c == '+')
@ -681,9 +677,8 @@ impl Book {
)
})?;
self.add_chapter(Number::Specified(number), file, true)?;
} else if line.starts_with('@') {
} else if let Some(subline) = line.strip_prefix('@') {
/* Part */
let subline = &line[1..];
if subline.starts_with(|c: char| c.is_whitespace()) {
let subline = subline.trim();
let ast = Parser::from(self).parse_inline(subline)?;
@ -698,7 +693,7 @@ impl Book {
/* Numbered part */
let file = get_filename(&self.source, subline)?;
self.add_chapter(Number::DefaultPart, file, true)?;
} else if subline.starts_with(|c: char| c.is_digit(10)) {
} else if subline.starts_with(|c: char| c.is_ascii_digit()) {
/* Specified part*/
let parts: Vec<_> = subline
.splitn(2, |c: char| c == '.' || c == ':' || c == '+')
@ -838,7 +833,7 @@ impl Book {
if !self.is_proofread() && fmt.contains("proofread") {
return false;
}
self.options.get_path(&format!("output.{}", fmt)).is_ok()
self.options.get_path(&format!("output.{fmt}")).is_ok()
})
.map(|s| s.to_string())
.collect();
@ -880,7 +875,7 @@ impl Book {
self.bar_finish(
Crowbar::Spinner(bar),
CrowbarState::Error,
&format!("{}", err),
&format!("{err}"),
);
error!(
"{}",
@ -906,7 +901,7 @@ impl Book {
);
let path = path.into();
match self.formats.get(format) {
Some(&(ref description, ref renderer)) => {
Some((description, renderer)) => {
let path = if path.ends_with("auto") {
let file = if let Some(s) = self
.source
@ -972,7 +967,7 @@ impl Book {
);
let bar = self.add_spinner_to_multibar(format);
match self.formats.get(format) {
Some(&(ref description, ref renderer)) => match renderer.render(self, f) {
Some((description, renderer)) => match renderer.render(self, f) {
Ok(_) => {
self.bar_finish(
Crowbar::Spinner(bar),
@ -1066,7 +1061,6 @@ impl Book {
)
})?;
// parse the file
self.bar_set_message(Crowbar::Second, &lformat!("Parsing..."));
@ -1074,7 +1068,7 @@ impl Book {
parser.set_source_file(file);
let mut yaml_block = String::from("");
let mut tokens = parser.parse(&content, Option::Some(&mut yaml_block))?;
// Parse YAML block
self.parse_yaml(&yaml_block);
self.features = self.features | parser.features();
@ -1220,16 +1214,13 @@ impl Book {
{
let last = self.chapters.last_mut().unwrap();
for token in &mut last.content {
match *token {
Token::Header(ref mut n, _) => {
let new = *n + level;
if !(0..=6).contains(&new) {
return Err(Error::parser(Source::new(file),
if let Token::Header(ref mut n, _) = *token {
let new = *n + level;
if !(0..=6).contains(&new) {
return Err(Error::parser(Source::new(file),
lformat!("this subchapter contains a heading that, when adjusted, is not in the right range ({} instead of [0-6])", new)));
}
*n = new;
}
_ => {}
*n = new;
}
}
}
@ -1336,17 +1327,13 @@ impl Book {
_ => {
return Err(Error::config_parser(
&self.source,
lformat!("invalid template '{template}'", template = template),
lformat!("invalid template '{template}'"),
))
}
};
if let Ok(ref s) = option {
let mut f = File::open(s).map_err(|_| {
Error::file_not_found(
&self.source,
format!("template '{template}'", template = template),
s.to_owned(),
)
Error::file_not_found(&self.source, format!("template '{template}'"), s.to_owned())
})?;
let mut res = String::new();
f.read_to_string(&mut res).map_err(|_| {
@ -1397,7 +1384,7 @@ impl Book {
}
format!("{:X}", Roman::from(n as i16))
} else {
format!("{}", n)
format!("{n}")
};
Ok(number)
}
@ -1420,17 +1407,17 @@ impl Book {
};
let mut data = self.get_metadata(&mut f)?;
if !title.is_empty() {
data = data.insert_bool(format!("has_{}_title", header_type), true);
data = data.insert_bool(format!("has_{header_type}_title"), true);
}
let number = self.get_header_number(header, n)?;
let header_name = self
.options
.get_str(&format!("rendering.{}", header_type))
.get_str(&format!("rendering.{header_type}"))
.map(|s| s.to_owned())
.unwrap_or_else(|_| lang::get_str(self.options.get_str("lang").unwrap(), header_type));
data = data
.insert_str(format!("{}_title", header_type), title.clone())
.insert_str(format!("{header_type}_title"), title.clone())
.insert_str(header_type, header_name.clone())
.insert_str("number", number.clone());
let data = data.build();
@ -1446,10 +1433,10 @@ impl Book {
} else {
let template = compile_str(
self.options
.get_str(&format!("rendering.{}.template", header_type))
.get_str(&format!("rendering.{header_type}.template"))
.unwrap(),
&self.source,
&format!("rendering.{}.template", header_type),
&format!("rendering.{header_type}.template"),
)?;
template.render_data(&mut res, &data)?;
}
@ -1519,12 +1506,12 @@ impl Book {
match content {
Ok(content) => {
if !content.is_empty() {
mapbuilder = mapbuilder.insert_str(format!("{}_raw", key), raw);
mapbuilder = mapbuilder.insert_str(format!("{key}_raw"), raw);
mapbuilder = mapbuilder.insert_str(key.clone(), content);
mapbuilder = mapbuilder.insert_bool(format!("has_{}", key), true);
mapbuilder = mapbuilder.insert_bool(format!("has_{key}"), true);
} else {
mapbuilder = mapbuilder.insert_bool(format!("has_{}", key), false);
mapbuilder = mapbuilder.insert_bool(format!("has_{key}"), false);
}
}
Err(err) => {
@ -1540,7 +1527,7 @@ impl Book {
}
}
} else {
mapbuilder = mapbuilder.insert_bool(format!("has_{}", key), false);
mapbuilder = mapbuilder.insert_bool(format!("has_{key}"), false);
}
}
@ -1568,9 +1555,7 @@ impl Book {
Ok(docs) => {
// Use this yaml block to set options only if 1) it is valid
// 2) the option is activated
if docs.len() >= 1
&& docs[0].as_hash().is_some()
{
if !docs.is_empty() && docs[0].as_hash().is_some() {
let hash = docs[0].as_hash().unwrap();
for (key, value) in hash {
match self
@ -1603,17 +1588,22 @@ impl Book {
)
);
}
},
}
Err(e) => {
error!("{}", lformat!("Inline YAML block could \
error!(
"{}",
lformat!(
"Inline YAML block could \
not set {:?} to {:?}: {}",
key,
value,
e))
key,
value,
e
)
)
}
}
}
self.update_cleaner();
self.init_checker();
} else {
@ -1627,7 +1617,7 @@ impl Book {
)
);
}
},
}
Err(err) => {
error!(
"{}",

View File

@ -22,9 +22,8 @@ use crate::book::{Book, Crowbar, CrowbarState};
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use std::mem;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
/// Store the progress bars needed for the book
pub struct Bars {
@ -36,8 +35,8 @@ pub struct Bars {
pub mainbar: Option<ProgressBar>,
/// Secondary bar
pub secondbar: Option<ProgressBar>,
/// Guard for thread
pub guard: Option<thread::JoinHandle<()>>,
// /// Guard for thread
// pub guard: Option<thread::JoinHandle<()>>,
/// Spinners for each renderier
pub spinners: Vec<ProgressBar>,
}
@ -50,7 +49,7 @@ impl Bars {
multibar: None,
mainbar: None,
secondbar: None,
guard: None,
// guard: None,
spinners: vec![],
}
}
@ -71,28 +70,28 @@ impl Book {
pub fn private_add_progress_bar(&mut self, emoji: bool) {
self.bars.emoji = emoji;
let multibar = Arc::new(MultiProgress::new());
self.bars.multibar = Some(multibar.clone());
self.bars.multibar = Some(multibar);
let b = self
.bars
.multibar
.as_ref()
.unwrap()
.add(ProgressBar::new_spinner());
b.enable_steady_tick(200);
b.enable_steady_tick(Duration::from_millis(200));
self.bars.mainbar = Some(b);
// let sty = ProgressStyle::default_spinner()
// .tick_chars("🕛🕐🕑🕒🕓🕔🕔🕕🕖🕗🕘🕘🕙🕚V")
// .tick_chars("/|\\-V")
// .template("{spinner:.dim.bold.yellow} {prefix} {wide_msg}");
self.bar_set_style(Crowbar::Main, CrowbarState::Running);
self.bars.guard = Some(thread::spawn(move || {
if let Err(_) = multibar.join() {
error!(
"{}",
lformat!("could not display fancy UI, try running crowbook with --no-fancy")
);
}
}));
// self.bars.guard = Some(thread::spawn(move || {
// if let Err(_) = multibar.join() {
// error!(
// "{}",
// lformat!("could not display fancy UI, try running crowbook with --no-fancy")
// );
// }
// }));
}
/// Sets a finished message to the progress bar, if it is set
@ -153,9 +152,9 @@ impl Book {
}
let bar = multibar.add(ProgressBar::new_spinner());
bar.enable_steady_tick(200);
bar.enable_steady_tick(Duration::from_millis(200));
bar.set_message(lformat!("waiting..."));
bar.set_prefix(format!("{}:", key));
bar.set_prefix(format!("{key}:"));
let i = self.bars.spinners.len();
self.bars.spinners.push(bar);
self.bar_set_style(Crowbar::Spinner(i), CrowbarState::Running);
@ -246,22 +245,23 @@ impl Book {
Crowbar::Second => {
style = style
.template("{bar:40.cyan/blue} {percent:>7} {wide_msg}")
.expect("Error in second progress bar style")
.progress_chars("##-");
}
bar => {
style = style.tick_chars(&format!("{}{}", tick_chars, end_tick));
style = style.tick_chars(&format!("{tick_chars}{end_tick}"));
match bar {
Crowbar::Spinner(_) => {
style = style.template(&format!(
"{{spinner:.bold.{color}}} {{prefix}} {{wide_msg}}",
color = color
));
style = style
.template(&format!(
"{{spinner:.bold.{color}}} {{prefix}} {{wide_msg}}"
))
.expect("Error in spinner progress bar style");
}
_ => {
style = style.template(&format!(
"{{spinner:.bold.{color}}} {{prefix}}{{wide_msg}}",
color = color
));
style = style
.template(&format!("{{spinner:.bold.{color}}} {{prefix}}{{wide_msg}}"))
.expect("Error in progress bar style");
}
};
}
@ -277,8 +277,8 @@ impl Drop for Book {
}
if let Some(ref bar) = self.bars.mainbar {
bar.finish();
let guard = mem::replace(&mut self.bars.guard, None);
guard.unwrap().join().unwrap();
// let guard = mem::replace(&mut self.bars.guard, None);
// guard.unwrap().join().unwrap();
}
}
}

View File

@ -521,7 +521,7 @@ impl BookOptions {
if &key == "output" {
for format in &inner {
self.set_yaml(
Yaml::String(format!("output.{}", format)),
Yaml::String(format!("output.{format}")),
Yaml::String(String::from("auto")),
)
.map_err(|_| {
@ -998,7 +998,7 @@ impl BookOptions {
let mut previous_is_comment = true;
for (comment, key, o_type, default) in Self::options_to_vec() {
// Don't display deprecated options if md is not set
if !md && comment.trim() == &lformat!("Deprecated options") {
if !md && comment.trim() == lformat!("Deprecated options") {
return out;
}
if key.is_none() {
@ -1060,6 +1060,7 @@ impl BookOptions {
}
/// OPTIONS to a vec of tuples (comment, key, type, default value)
#[allow(clippy::type_complexity)]
fn options_to_vec() -> Vec<(
&'static str,
Option<&'static str>,
@ -1072,8 +1073,8 @@ impl BookOptions {
if line.is_empty() {
continue;
}
if line.starts_with('#') {
out.push((&line[1..], None, None, None));
if let Some(stripped) = line.strip_prefix('#') {
out.push((stripped, None, None, None));
continue;
}
let v: Vec<_> = line.split(" #").collect();

View File

@ -533,9 +533,9 @@ impl<'a> EpubRenderer<'a> {
)
})?;
let mut new_content = if initial.is_alphanumeric() {
format!("<span class = \"initial\">{}</span>", initial)
format!("<span class = \"initial\">{initial}</span>")
} else {
format!("{}", initial)
format!("{initial}")
};
for c in chars {
new_content.push(c);
@ -569,12 +569,9 @@ impl<'a> EpubRenderer<'a> {
== 3;
Ok(format!(
"<a {} href = \"#note-dest-{}\"><sup id = \
\"note-source-{}\">[{}]</sup></a>",
"<a {} href = \"#note-dest-{reference}\"><sup id = \
\"note-source-{reference}\">[{reference}]</sup></a>",
if epub3 { "epub:type = \"noteref\"" } else { "" },
reference,
reference,
reference
))
}
Token::FootnoteDefinition(ref reference, ref vec) => {
@ -588,17 +585,15 @@ impl<'a> EpubRenderer<'a> {
let html: &mut HtmlRenderer = this.as_mut();
let note_number = format!(
"<p class = \"note-number\">
<a href = \"#note-source-{}\">[{}]</a>
<a href = \"#note-source-{reference}\">[{reference}]</a>
</p>\n",
reference, reference
);
let inner = if epub3 {
format!(
"<aside epub:type = \"footnote\" id = \"note-dest-{}\">{}</aside>",
reference, inner_content
"<aside epub:type = \"footnote\" id = \"note-dest-{reference}\">{inner_content}</aside>"
)
} else {
format!("<a id = \"note-dest-{}\" />{}", reference, inner_content)
format!("<a id = \"note-dest-{reference}\" />{inner_content}")
};
html.add_footnote(note_number, inner);
@ -611,7 +606,7 @@ impl<'a> EpubRenderer<'a> {
/// Generate a file name given an int
fn filenamer(i: usize) -> String {
format!("chapter_{:03}.xhtml", i)
format!("chapter_{i:03}.xhtml")
}
derive_html! {EpubRenderer<'a>, EpubRenderer::static_render_token}
@ -620,7 +615,7 @@ pub struct Epub {}
impl BookRenderer for Epub {
fn auto_path(&self, book_name: &str) -> Result<String> {
Ok(format!("{}.epub", book_name))
Ok(format!("{book_name}.epub"))
}
fn render(&self, book: &Book, to: &mut dyn Write) -> Result<()> {

View File

@ -70,9 +70,9 @@ impl Source {
impl fmt::Display for Source {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref file) = self.file {
write!(f, "{}", file)?;
write!(f, "{file}")?;
if let Some(line) = self.line {
write!(f, ":{}", line)?;
write!(f, ":{line}")?;
}
} else {
write!(f, "<UNKNOWN FILE>")?;
@ -268,15 +268,15 @@ impl error::Error for Error {
fn description(&self) -> &str {
match self.inner {
Inner::Default(ref s)
| Inner::Parser(ref s)
| Inner::Zipper(ref s)
| Inner::BookOption(ref s)
| Inner::ConfigParser(ref s)
| Inner::InvalidOption(ref s)
| Inner::Render(ref s)
| Inner::Template(ref s)
| Inner::Syntect(ref s)
| Inner::GrammarCheck(ref s) => s.as_ref(),
| Inner::Parser(ref s)
| Inner::Zipper(ref s)
| Inner::BookOption(ref s)
| Inner::ConfigParser(ref s)
| Inner::InvalidOption(ref s)
| Inner::Render(ref s)
| Inner::Template(ref s)
| Inner::Syntect(ref s)
| Inner::GrammarCheck(ref s) => s.as_ref(),
Inner::FileNotFound(..) => "File not found",
}
@ -287,15 +287,15 @@ impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let source = &self.source;
if let Some(ref file) = source.file {
write!(f, "{}", file)?;
write!(f, "{file}")?;
if let Some(line) = source.line {
write!(f, ":{}", line)?;
write!(f, ":{line}")?;
}
write!(f, ": ")?;
}
match self.inner {
Inner::Default(ref s) => write!(f, "{}", s),
Inner::Default(ref s) => write!(f, "{s}"),
Inner::GrammarCheck(ref s) => {
write!(
f,
@ -363,7 +363,7 @@ pub type Result<T> = result::Result<T, Error>;
/// Implement our Error from mustache::Error
impl From<mustache::Error> for Error {
fn from(err: mustache::Error) -> Error {
Error::template(Source::empty(), format!("{}", err))
Error::template(Source::empty(), format!("{err}"))
}
}
@ -408,7 +408,7 @@ impl From<syntect::Error> for Error {
fn from(err: syntect::Error) -> Error {
Error::syntect(
Source::empty(),
lformat!("syntect error: {error}", error = err)
lformat!("syntect error: {error}", error = err),
)
}
}

View File

@ -78,7 +78,7 @@ impl GrammalecteChecker {
let res = checker
.client
.get(&format!("http://localhost:{}", port))
.get(format!("http://localhost:{port}"))
.send()
.map_err(|e| {
Error::grammar_check(
@ -113,7 +113,7 @@ impl GrammalecteChecker {
let mut res = self
.client
.post(&format!("http://localhost:{}/gc_text/fr", self.port))
.post(format!("http://localhost:{}/gc_text/fr", self.port))
.body(query)
.send()
.map_err(|e| {

View File

@ -67,7 +67,7 @@ impl GrammarChecker {
let res = checker
.client
.get(&format!("http://localhost:{}/v2/languages", port))
.get(format!("http://localhost:{port}/v2/languages"))
.send()
.map_err(|e| {
Error::grammar_check(
@ -99,7 +99,7 @@ impl GrammarChecker {
let mut res = self
.client
.post(&format!("http://localhost:{}/v2/check", self.port))
.post(format!("http://localhost:{}/v2/check", self.port))
.body(query)
.send()
.map_err(|e| {

View File

@ -248,7 +248,7 @@ impl<'a> HtmlRenderer<'a> {
} else if self.current_numbering >= n {
let numbers = self.get_numbers();
Ok(HeaderData {
text: format!("{} {}", numbers, c_title),
text: format!("{numbers} {c_title}"),
number: numbers,
header: String::new(),
title: c_title,
@ -373,8 +373,7 @@ impl<'a> HtmlRenderer<'a> {
for (note_number, footnote) in self.footnotes.drain(..) {
write!(
res,
"<div class = \"sidenote\">\n{} {}\n</div>\n",
note_number, footnote
"<div class = \"sidenote\">\n{note_number} {footnote}\n</div>\n",
)
.unwrap();
}
@ -407,13 +406,12 @@ impl<'a> HtmlRenderer<'a> {
res,
"<tr class = \"notes\">
<td class = \"note-number\">
{}
{note_number}
</td>
<td class = \"note\">
{}
{footnote}
</td>
</tr>\n",
note_number, footnote
</tr>\n"
)
.unwrap();
}
@ -449,9 +447,7 @@ impl<'a> HtmlRenderer<'a> {
"<span class = \"repetition\" \
style = \"text-decoration-line: underline; \
text-decoration-style: wavy; \
text-decoration-color: {colour}\">{content}</span>",
colour = colour,
content = content
text-decoration-color: {colour}\">{content}</span>"
))
} else {
Ok(content)
@ -506,10 +502,7 @@ impl<'a> HtmlRenderer<'a> {
let content = this.render_vec(vec)?;
this.as_mut().current_par += 1;
let par = this.as_ref().current_par;
Ok(format!(
"<p id = \"para-{}\"{}>{}</p>\n",
par, class, content
))
Ok(format!("<p id = \"para-{par}\"{class}>{content}</p>\n"))
}
Token::Header(n, ref vec) => {
let data = this.as_mut().render_title(n, vec)?;
@ -556,11 +549,10 @@ impl<'a> HtmlRenderer<'a> {
let output = if let Some(ref syntax) = this.as_ref().syntax {
syntax.to_html(s, language)?
} else if language.is_empty() {
format!("<pre><code>{}</code></pre>\n", s)
format!("<pre><code>{s}</code></pre>\n")
} else {
format!(
"<pre><code class = \"language-{}\">{}</code></pre>\n",
language,
"<pre><code class = \"language-{language}\">{}</code></pre>\n",
escape::html(s)
)
};
@ -575,7 +567,7 @@ impl<'a> HtmlRenderer<'a> {
if n == 1 {
String::new()
} else {
format!(" start = \"{}\"", n)
format!(" start = \"{n}\"")
},
this.render_vec(vec)?
)),
@ -598,12 +590,11 @@ impl<'a> HtmlRenderer<'a> {
};
Ok(format!(
"<a href = \"{}\"{}>{}</a>",
url,
"<a href = \"{url}\"{}>{}</a>",
if title.is_empty() {
String::new()
} else {
format!(" title = \"{}\"", title)
format!(" title = \"{title}\"")
},
this.render_vec(vec)?
))
@ -616,16 +607,14 @@ impl<'a> HtmlRenderer<'a> {
if token.is_image() {
Ok(format!(
"<img src = \"{}\" title = \"{}\" alt = \"{}\" />",
url, title, content
"<img src = \"{url}\" title = \"{title}\" alt = \"{content}\" />",
))
} else {
Ok(format!(
"<div class = \"image\">
<img src = \"{}\" title = \"{}\" alt = \
\"{}\" />
<img src = \"{url}\" title = \"{title}\" alt = \
\"{content}\" />
</div>",
url, title, content
))
}
}
@ -639,25 +628,23 @@ impl<'a> HtmlRenderer<'a> {
Token::TableRow(ref vec) => Ok(format!("<tr>\n{}</tr>\n", this.render_vec(vec)?)),
Token::TableCell(ref vec) => {
let tag = if this.as_ref().table_head { "th" } else { "td" };
Ok(format!("<{}>{}</{}>", tag, this.render_vec(vec)?, tag))
Ok(format!("<{tag}>{}</{tag}>", this.render_vec(vec)?))
}
Token::TableHead(ref vec) => {
this.as_mut().table_head = true;
let s = this.render_vec(vec)?;
this.as_mut().table_head = false;
Ok(format!("<tr>\n{}</tr>\n", s))
Ok(format!("<tr>\n{s}</tr>\n"))
}
Token::FootnoteReference(ref reference) => Ok(format!(
"<a href = \"#note-dest-{}\"><sup id = \
\"note-source-{}\">[{}]</sup></a>",
reference, reference, reference
"<a href = \"#note-dest-{reference}\"><sup id = \
\"note-source-{reference}\">[{reference}]</sup></a>",
)),
Token::FootnoteDefinition(ref reference, ref vec) => {
let note_number = format!(
"<p class = \"note-number\">
<a href = \"#note-source-{}\">[{}]</a>
<a href = \"#note-source-{reference}\">[{reference}]</a>
</p>\n",
reference, reference
);
let inner = format!(
@ -752,7 +739,7 @@ impl<'a> HtmlRenderer<'a> {
} else {
let tokens = Parser::from(this.as_ref().book).parse(&content, None)?;
let content = this.render_vec(&tokens)?;
Ok(format!("<footer id = \"footer\">{}</footer>", content))
Ok(format!("<footer id = \"footer\">{content}</footer>"))
}
}

View File

@ -73,7 +73,7 @@ impl<'a> HtmlDirRenderer<'a> {
.add_link(chapter.filename.as_str(), filenamer(i));
}
if let Ok(metadata) = fs::metadata(&dest_path) {
if let Ok(metadata) = fs::metadata(dest_path) {
if metadata.is_file() {
return Err(Error::render(
&self.html.book.source,
@ -91,7 +91,7 @@ impl<'a> HtmlDirRenderer<'a> {
path = dest_path.display()
)
);
fs::remove_dir_all(&dest_path).map_err(|e| {
fs::remove_dir_all(dest_path).map_err(|e| {
Error::render(
&self.html.book.source,
lformat!(
@ -106,7 +106,7 @@ impl<'a> HtmlDirRenderer<'a> {
fs::DirBuilder::new()
.recursive(true)
.create(&dest_path)
.create(dest_path)
.map_err(|e| {
Error::render(
&self.html.book.source,
@ -331,7 +331,7 @@ impl<'a> HtmlDirRenderer<'a> {
.map_image(&self.html.book.source, favicon)?;
mapbuilder = mapbuilder.insert_str(
"favicon",
format!("<link rel = \"icon\" href = \"{}\">", favicon),
format!("<link rel = \"icon\" href = \"{favicon}\">"),
);
}
if self.html.highlight == Highlight::Js {
@ -437,7 +437,7 @@ impl<'a> HtmlDirRenderer<'a> {
.map_image(&self.html.book.source, favicon)?;
mapbuilder = mapbuilder.insert_str(
"favicon",
format!("<link rel = \"icon\" href = \"{}\">", favicon),
format!("<link rel = \"icon\" href = \"{favicon}\">"),
);
}
if self.html.highlight == Highlight::Js {
@ -499,7 +499,7 @@ impl<'a> HtmlDirRenderer<'a> {
// dir does not exist, create it
fs::DirBuilder::new()
.recursive(true)
.create(&dest_dir)
.create(dest_dir)
.map_err(|e| {
Error::render(
&self.html.book.source,
@ -536,7 +536,7 @@ impl<'a> HtmlDirRenderer<'a> {
/// Generate a file name given an int
fn filenamer(i: usize) -> String {
format!("chapter_{:03}.html", i)
format!("chapter_{i:03}.html")
}
derive_html! {HtmlDirRenderer<'a>, HtmlRenderer::static_render_token}

View File

@ -84,7 +84,7 @@ impl<'a> HtmlIfRenderer<'a> {
gen_code.push_str(&rendered.replace('"', "\\\"").replace('\n', "\\\n"));
gen_code.push('"');
for var in &variables {
gen_code.push_str(&format!(".replace(/{{{{{var}}}}}/, {var})", var = var));
gen_code.push_str(&format!(".replace(/{{{{{var}}}}}/, {var})"));
}
gen_code.push(';');
i = end + 2;
@ -97,31 +97,26 @@ impl<'a> HtmlIfRenderer<'a> {
if contains_md {
gen_code = format!(
"var crowbook_return_variable = \"\";
{}
{gen_code}
return crowbook_return_variable.replace(/<\\/ul><ul>/g, '');\n",
gen_code
);
}
let container = if !contains_md { "p" } else { "div" };
let id = self.n_fn;
self.fn_defs.push_str(&format!(
"function fn_{id}() {{
{code}
{gen_code}
}}\n",
id = id,
code = gen_code
));
self.curr_init.push_str(&format!(
" result = fn_{id}();
if (result != undefined) {{
document.getElementById(\"result_{id}\").innerHTML = result;
}}\n",
id = id
));
let content = format!(
"<{container} id = \"result_{id}\"></{container}>\n",
id = (self.n_fn),
container = container
);
self.n_fn += 1;
Ok(content)
@ -153,11 +148,9 @@ return crowbook_return_variable.replace(/<\\/ul><ul>/g, '');\n",
{
let html_if: &mut HtmlIfRenderer = this.as_mut();
let code = format!(
"if (passageCount(state.current_id) {expr}) {{
"if (passageCount(state.current_id) {language}) {{
{code};
}}\n",
code = code,
expr = language
);
let content = html_if.parse_inner_code(&code)?;
Ok(content)
@ -189,7 +182,7 @@ return crowbook_return_variable.replace(/<\\/ul><ul>/g, '');\n",
for (i, chapter) in self.html.book.chapters.iter().enumerate() {
self.html
.handler
.add_link(chapter.filename.as_str(), format!("#chapter-{}", i));
.add_link(chapter.filename.as_str(), format!("#chapter-{i}"));
}
let pre_code = self
@ -247,10 +240,9 @@ return crowbook_return_variable.replace(/<\\/ul><ul>/g, '');\n",
}
chapters.push(format!(
"<div id = \"chapter-{}\" class = \"chapter\">
{}
"<div id = \"chapter-{i}\" class = \"chapter\">
{chapter_content}
</div>",
i, chapter_content
));
self.fn_defs.push_str(&format!(
"initFns.push(function () {{
@ -337,7 +329,7 @@ return crowbook_return_variable.replace(/<\\/ul><ul>/g, '');\n",
.map_image(&self.html.book.source, favicon)?;
mapbuilder = mapbuilder.insert_str(
"favicon",
format!("<link rel = \"icon\" href = \"{}\">", favicon),
format!("<link rel = \"icon\" href = \"{favicon}\">"),
);
}
if self.html.highlight == Highlight::Js {
@ -347,7 +339,7 @@ return crowbook_return_variable.replace(/<\\/ul><ul>/g, '');\n",
.get_template("html.highlight.js")?
.as_bytes()
.to_base64(base64::STANDARD);
let highlight_js = format!("data:text/javascript;base64,{}", highlight_js);
let highlight_js = format!("data:text/javascript;base64,{highlight_js}");
mapbuilder = mapbuilder
.insert_bool("highlight_code", true)
.insert_str(
@ -377,7 +369,7 @@ pub struct HtmlIf {}
impl BookRenderer for HtmlIf {
fn auto_path(&self, book_name: &str) -> Result<String> {
Ok(format!("{}.html", book_name))
Ok(format!("{book_name}.html"))
}
fn render(&self, book: &Book, to: &mut dyn io::Write) -> Result<()> {

View File

@ -79,13 +79,13 @@ impl<'a> HtmlSingleRenderer<'a> {
/// Render books as a standalone HTML file
pub fn render_book(&mut self) -> Result<String> {
let menu_svg = img::MENU_SVG.to_base64(base64::STANDARD);
let menu_svg = format!("data:image/svg+xml;base64,{}", menu_svg);
let menu_svg = format!("data:image/svg+xml;base64,{menu_svg}");
let book_svg = img::BOOK_SVG.to_base64(base64::STANDARD);
let book_svg = format!("data:image/svg+xml;base64,{}", book_svg);
let book_svg = format!("data:image/svg+xml;base64,{book_svg}");
let pages_svg = img::PAGES_SVG.to_base64(base64::STANDARD);
let pages_svg = format!("data:image/svg+xml;base64,{}", pages_svg);
let pages_svg = format!("data:image/svg+xml;base64,{pages_svg}");
let mut content = String::new();
@ -101,7 +101,7 @@ impl<'a> HtmlSingleRenderer<'a> {
for (i, chapter) in self.html.book.chapters.iter().enumerate() {
self.html
.handler
.add_link(chapter.filename.as_str(), format!("#chapter-{}", i));
.add_link(chapter.filename.as_str(), format!("#chapter-{i}"));
}
for (i, chapter) in self.html.book.chapters.iter().enumerate() {
@ -297,7 +297,7 @@ impl<'a> HtmlSingleRenderer<'a> {
.map_image(&self.html.book.source, favicon)?;
mapbuilder = mapbuilder.insert_str(
"favicon",
format!("<link rel = \"icon\" href = \"{}\">", favicon),
format!("<link rel = \"icon\" href = \"{favicon}\">"),
);
}
if !self.html.toc.is_empty() {
@ -311,7 +311,7 @@ impl<'a> HtmlSingleRenderer<'a> {
.get_template("html.highlight.js")?
.as_bytes()
.to_base64(base64::STANDARD);
let highlight_js = format!("data:text/javascript;base64,{}", highlight_js);
let highlight_js = format!("data:text/javascript;base64,{highlight_js}");
mapbuilder = mapbuilder
.insert_bool("highlight_code", true)
.insert_str(
@ -342,7 +342,7 @@ pub struct ProofHtmlSingle {}
impl BookRenderer for HtmlSingle {
fn auto_path(&self, book_name: &str) -> Result<String> {
Ok(format!("{}.html", book_name))
Ok(format!("{book_name}.html"))
}
fn render(&self, book: &Book, to: &mut dyn io::Write) -> Result<()> {
@ -360,7 +360,7 @@ impl BookRenderer for HtmlSingle {
impl BookRenderer for ProofHtmlSingle {
fn auto_path(&self, book_name: &str) -> Result<String> {
Ok(format!("{}.proof.html", book_name))
Ok(format!("{book_name}.proof.html"))
}
fn render(&self, book: &Book, to: &mut dyn io::Write) -> Result<()> {

View File

@ -43,7 +43,7 @@ pub fn get_str(lang: &str, s: &str) -> String {
key = s,
lang = lang
));
if let &Yaml::String(ref result) = yaml {
if let Yaml::String(result) = yaml {
result.clone()
} else {
panic!(

View File

@ -129,9 +129,8 @@ impl<'a> LatexRenderer<'a> {
let numbering = self.book.options.get_i32("rendering.num_depth").unwrap() - 1;
write!(
content,
"\\setcounter{{tocdepth}}{{{}}}
\\setcounter{{secnumdepth}}{{{}}}\n",
numbering, numbering
"\\setcounter{{tocdepth}}{{{numbering}}}
\\setcounter{{secnumdepth}}{{{numbering}}}\n",
)?;
if self.book.options.get_bool("rendering.inline_toc").unwrap() {
@ -140,7 +139,7 @@ impl<'a> LatexRenderer<'a> {
for (i, chapter) in self.book.chapters.iter().enumerate() {
self.handler
.add_link(chapter.filename.as_str(), format!("chapter-{}", i));
.add_link(chapter.filename.as_str(), format!("chapter-{i}"));
}
for (i, chapter) in self.book.chapters.iter().enumerate() {
@ -153,7 +152,7 @@ impl<'a> LatexRenderer<'a> {
content.push_str(&self.render_token(&v[0])?);
offset = 1;
}
writeln!(content, "\\label{{chapter-{}}}", i)?;
writeln!(content, "\\label{{chapter-{i}}}")?;
content.push_str(&self.render_vec(&v[offset..])?);
}
self.source = Source::empty();
@ -246,7 +245,7 @@ impl<'a> LatexRenderer<'a> {
if let Ok(tex_font_size) = self.book.options.get_i32("tex.font.size") {
data = data
.insert_bool("has_tex_size", true)
.insert_str("tex_size", format!("{}", tex_font_size));
.insert_str("tex_size", format!("{tex_font_size}"));
}
// If class isn't book, set open_any to true, so margins are symetric.
@ -331,12 +330,8 @@ impl<'a> Renderer for LatexRenderer<'a> {
)
})?;
let mut first_word = String::new();
loop {
let c = if let Some(next_char) = chars.peek() {
*next_char
} else {
break;
};
while let Some(next_char) = chars.peek() {
let c = *next_char;
if !c.is_whitespace() {
first_word.push(c);
chars.next();
@ -348,12 +343,9 @@ impl<'a> Renderer for LatexRenderer<'a> {
let rest = chars.collect::<String>();
if initial.is_alphanumeric() {
Ok(format!(
"\\lettrine{{{}}}{{{}}}{}",
initial, first_word, rest
))
Ok(format!("\\lettrine{{{initial}}}{{{first_word}}}{rest}"))
} else {
Ok(format!("{}{}{}", initial, first_word, rest))
Ok(format!("{initial}{first_word}{rest}"))
}
} else {
Ok(content.into_owned())
@ -452,15 +444,13 @@ impl<'a> Renderer for LatexRenderer<'a> {
format!(
"\\begin{{spverbatim}}
{code}
\\end{{spverbatim}}",
code = code
\\end{{spverbatim}}"
)
};
res = format!(
"\\begin{{mdcodeblock}}
{}
\\end{{mdcodeblock}}",
res
{res}
\\end{{mdcodeblock}}"
);
Ok(res)
}
@ -504,11 +494,7 @@ impl<'a> Renderer for LatexRenderer<'a> {
))
}
};
format!(
"\\setcounter{{{counter}}}{{{n}}}\n",
counter = counter,
n = n - 1
)
format!("\\setcounter{{{counter}}}{{{n}}}\n", n = n - 1)
};
let result = format!(
"\\begin{{enumerate}}
@ -526,14 +512,13 @@ impl<'a> Renderer for LatexRenderer<'a> {
if self.hyperref && self.handler.contains_link(url) {
Ok(format!(
"\\hyperref[{}]{{{}}}",
"\\hyperref[{}]{{{content}}}",
escape::tex(self.handler.get_link(url)),
content
))
} else {
let url = escape::tex(url.as_str());
if content == url {
Ok(format!("\\url{{{}}}", content))
Ok(format!("\\url{{{content}}}"))
} else if self
.book
.options
@ -541,18 +526,17 @@ impl<'a> Renderer for LatexRenderer<'a> {
.unwrap()
{
Ok(format!(
"\\href{{{}}}{{{}}}\\protect\\footnote{{\\url{{{}}}}}",
url, content, url
"\\href{{{url}}}{{{content}}}\\protect\\footnote{{\\url{{{url}}}}}"
))
} else {
Ok(format!("\\href{{{}}}{{{}}}", url, content))
Ok(format!("\\href{{{url}}}{{{content}}}"))
}
}
}
Token::StandaloneImage(ref url, _, _) => {
if ResourceHandler::is_local(url) {
let img = self.handler.map_image(&self.source, url.as_str())?;
Ok(format!("\\mdstandaloneimage{{{}}}\n", img))
Ok(format!("\\mdstandaloneimage{{{img}}}\n"))
} else {
debug!(
"{}",
@ -585,7 +569,7 @@ impl<'a> Renderer for LatexRenderer<'a> {
Ok(String::new())
}
}
Token::FootnoteReference(ref reference) => Ok(format!("\\footnotemark[{}]", reference)),
Token::FootnoteReference(ref reference) => Ok(format!("\\footnotemark[{reference}]")),
Token::FootnoteDefinition(ref reference, ref v) => Ok(format!(
"\\footnotetext[{}]{{{}}}",
reference,
@ -625,13 +609,12 @@ impl<'a> Renderer for LatexRenderer<'a> {
if self.proofread {
match *annotation {
Data::GrammarError(ref s) => Ok(format!(
"\\underline{{{}}}\\protect\\footnote{{{}}}",
content,
"\\underline{{{content}}}\\protect\\footnote{{{}}}",
escape::tex(s.as_str())
)),
Data::Repetition(ref colour) => {
if !self.escape && colour == "red" {
Ok(format!("\\underline{{{}}}", content))
Ok(format!("\\underline{{{content}}}"))
} else {
Ok(content)
}
@ -652,7 +635,7 @@ pub struct ProofPdf;
impl BookRenderer for Latex {
fn auto_path(&self, book_name: &str) -> Result<String> {
Ok(format!("{}.tex", book_name))
Ok(format!("{book_name}.tex"))
}
fn render(&self, book: &Book, to: &mut dyn io::Write) -> Result<()> {
@ -670,7 +653,7 @@ impl BookRenderer for Latex {
impl BookRenderer for ProofLatex {
fn auto_path(&self, book_name: &str) -> Result<String> {
Ok(format!("{}.proof.tex", book_name))
Ok(format!("{book_name}.proof.tex"))
}
fn render(&self, book: &Book, to: &mut dyn io::Write) -> Result<()> {
@ -688,7 +671,7 @@ impl BookRenderer for ProofLatex {
impl BookRenderer for Pdf {
fn auto_path(&self, book_name: &str) -> Result<String> {
Ok(format!("{}.pdf", book_name))
Ok(format!("{book_name}.pdf"))
}
fn render(&self, book: &Book, to: &mut dyn io::Write) -> Result<()> {
@ -699,7 +682,7 @@ impl BookRenderer for Pdf {
impl BookRenderer for ProofPdf {
fn auto_path(&self, book_name: &str) -> Result<String> {
Ok(format!("{}.proof.pdf", book_name))
Ok(format!("{book_name}.proof.pdf"))
}
fn render(&self, book: &Book, to: &mut dyn io::Write) -> Result<()> {

View File

@ -65,7 +65,7 @@ impl RepetitionDetector {
/// Check repetitions in a vector of tokens.
///
/// This modifies the AST
pub fn check_chapter(&self, tokens: &mut Vec<Token>) -> Result<()> {
pub fn check_chapter(&self, tokens: &mut [Token]) -> Result<()> {
let fuzzy = if self.fuzzy {
Some(self.fuzzy_threshold)
} else {

View File

@ -81,7 +81,7 @@ impl ResourceHandler {
return Err(Error::file_not_found(
source,
lformat!("image"),
format!("{}", file),
format!("{file}"),
));
}
@ -122,7 +122,7 @@ impl ResourceHandler {
return Err(Error::file_not_found(
source,
lformat!("image"),
format!("{}", file),
format!("{file}"),
));
}
};
@ -146,7 +146,7 @@ impl ResourceHandler {
);
return Ok(file);
}
Some(s) => format!("data:{};base64,{}", s, base64),
Some(s) => format!("data:{s};base64,{base64}"),
}
};
@ -254,7 +254,7 @@ pub fn get_files(list: &[String], base: &str) -> Result<Vec<String>> {
let mut out: Vec<String> = vec![];
let base = Path::new(base);
for path in list {
let abs_path = base.join(&path);
let abs_path = base.join(path);
let res = fs::metadata(&abs_path);
match res {
Err(err) => {

View File

@ -46,5 +46,5 @@ pub fn fill(msg: &str, indent: &str) -> String {
let options = textwrap::Options::new(width.into())
.initial_indent(indent)
.subsequent_indent(indent);
textwrap::fill(msg, &options)
textwrap::fill(msg, options)
}

View File

@ -82,10 +82,7 @@ impl Syntax {
let res: String = syntect::html::styled_line_to_highlighted_html(&regions[..], bg)?;
formatted_code.push_str(&res);
}
Ok(format!(
"<pre>{}</pre>",
formatted_code
))
Ok(format!("<pre>{formatted_code}</pre>"))
}
pub fn to_tex(&self, code: &str, language: &str) -> Result<String> {
@ -107,32 +104,26 @@ impl Syntax {
content = content
.replace('\n', "\\\\{}\n")
.replace(' ', "\\hphantom{ }\\allowbreak{}");
content = format!("\\texttt{{{}}}", content);
content = format!("\\texttt{{{content}}}");
if style.foreground != Color::BLACK {
let r = style.foreground.r as f32 / 255.0;
let g = style.foreground.g as f32 / 255.0;
let b = style.foreground.b as f32 / 255.0;
content = format!(
"\\textcolor[rgb]{{{r}, {g}, {b}}}{{{text}}}",
r = r,
g = g,
b = b,
text = content
);
content = format!("\\textcolor[rgb]{{{r}, {g}, {b}}}{{{content}}}");
}
if style.font_style.contains(FontStyle::BOLD) {
content = format!("\\textbf{{{}}}", content);
content = format!("\\textbf{{{content}}}");
}
if style.font_style.contains(FontStyle::ITALIC) {
content = format!("\\emph{{{}}}", content);
content = format!("\\emph{{{content}}}");
}
if style.font_style.contains(FontStyle::UNDERLINE) {
content = format!("\\underline{{{}}}", content);
content = format!("\\underline{{{content}}}");
}
formatted_code.push_str(&content);
}
}
Ok(format!("{{\\sloppy {}}}", formatted_code))
Ok(format!("{{\\sloppy {formatted_code}}}"))
}
}

View File

@ -82,8 +82,8 @@ pub fn insert_annotation(
let mut pos = pos;
let mut found_left = None;
let mut found_right = None;
for i in 0..tokens.len() {
let recurse = match tokens[i] {
for (i, item) in tokens.iter_mut().enumerate() {
let recurse = match item {
Token::Str(ref s) => {
let len = s.chars().count();
if pos < len || (pos == len && found_left.is_some()) {
@ -121,7 +121,7 @@ pub fn insert_annotation(
}
_ => {
if let Some(inner) = tokens[i].inner() {
if let Some(inner) = item.inner() {
let len = count_length(inner);
// Only recurse if the two is in this subtree
if pos < len {
@ -151,7 +151,7 @@ pub fn insert_annotation(
// Moved out of the match 'thanks' to borrowcheck
if recurse {
if let Some(ref mut inner) = tokens[i].inner_mut() {
if let Some(ref mut inner) = item.inner_mut() {
if let Some(new_pos) = insert_annotation(inner, annotation, pos, length) {
pos = new_pos;
} else {

View File

@ -75,7 +75,7 @@ This is forbidden because we are supposed \
// dir does not exist, create it
DirBuilder::new()
.recursive(true)
.create(&dest_dir)
.create(dest_dir)
.map_err(|_| {
Error::zipper(lformat!(
"could not create temporary directory in {path}",