├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── about.hbs ├── about.toml ├── build.sh ├── src └── lib.rs └── typst-package ├── LICENSE ├── README.md ├── examples ├── fib.svg └── fib.typ ├── jogs.wasm ├── lib.typ └── typst.toml /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | *.wasm 3 | 4 | # Added by cargo 5 | # 6 | # already existing elements were commented out 7 | 8 | #/target 9 | !typst-package/jogs.wasm 10 | license.html 11 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anyhow" 31 | version = "1.0.96" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" 34 | 35 | [[package]] 36 | name = "backtrace" 37 | version = "0.3.74" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 40 | dependencies = [ 41 | "addr2line", 42 | "cfg-if", 43 | "libc", 44 | "miniz_oxide", 45 | "object", 46 | "rustc-demangle", 47 | "windows-targets", 48 | ] 49 | 50 | [[package]] 51 | name = "bindgen" 52 | version = "0.69.5" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" 55 | dependencies = [ 56 | "bitflags", 57 | "cexpr", 58 | "clang-sys", 59 | "itertools", 60 | "lazy_static", 61 | "lazycell", 62 | "log", 63 | "prettyplease", 64 | "proc-macro2", 65 | "quote", 66 | "regex", 67 | "rustc-hash", 68 | "shlex", 69 | "syn", 70 | "which", 71 | ] 72 | 73 | [[package]] 74 | name = "bitflags" 75 | version = "2.8.0" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" 78 | 79 | [[package]] 80 | name = "bytes" 81 | version = "1.10.0" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" 84 | 85 | [[package]] 86 | name = "cc" 87 | version = "1.2.16" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" 90 | dependencies = [ 91 | "shlex", 92 | ] 93 | 94 | [[package]] 95 | name = "cexpr" 96 | version = "0.6.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 99 | dependencies = [ 100 | "nom", 101 | ] 102 | 103 | [[package]] 104 | name = "cfg-if" 105 | version = "1.0.0" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 108 | 109 | [[package]] 110 | name = "ciborium" 111 | version = "0.2.2" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" 114 | dependencies = [ 115 | "ciborium-io", 116 | "ciborium-ll", 117 | "serde", 118 | ] 119 | 120 | [[package]] 121 | name = "ciborium-io" 122 | version = "0.2.2" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" 125 | 126 | [[package]] 127 | name = "ciborium-ll" 128 | version = "0.2.2" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" 131 | dependencies = [ 132 | "ciborium-io", 133 | "half", 134 | ] 135 | 136 | [[package]] 137 | name = "clang-sys" 138 | version = "1.8.1" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 141 | dependencies = [ 142 | "glob", 143 | "libc", 144 | "libloading", 145 | ] 146 | 147 | [[package]] 148 | name = "core-foundation" 149 | version = "0.9.4" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 152 | dependencies = [ 153 | "core-foundation-sys", 154 | "libc", 155 | ] 156 | 157 | [[package]] 158 | name = "core-foundation-sys" 159 | version = "0.8.7" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 162 | 163 | [[package]] 164 | name = "crunchy" 165 | version = "0.2.3" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" 168 | 169 | [[package]] 170 | name = "either" 171 | version = "1.14.0" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" 174 | 175 | [[package]] 176 | name = "errno" 177 | version = "0.3.10" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 180 | dependencies = [ 181 | "libc", 182 | "windows-sys 0.59.0", 183 | ] 184 | 185 | [[package]] 186 | name = "fastrand" 187 | version = "2.3.0" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 190 | 191 | [[package]] 192 | name = "fnv" 193 | version = "1.0.7" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 196 | 197 | [[package]] 198 | name = "foreign-types" 199 | version = "0.3.2" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 202 | dependencies = [ 203 | "foreign-types-shared", 204 | ] 205 | 206 | [[package]] 207 | name = "foreign-types-shared" 208 | version = "0.1.1" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 211 | 212 | [[package]] 213 | name = "futures-channel" 214 | version = "0.3.31" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 217 | dependencies = [ 218 | "futures-core", 219 | ] 220 | 221 | [[package]] 222 | name = "futures-core" 223 | version = "0.3.31" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 226 | 227 | [[package]] 228 | name = "futures-task" 229 | version = "0.3.31" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 232 | 233 | [[package]] 234 | name = "futures-util" 235 | version = "0.3.31" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 238 | dependencies = [ 239 | "futures-core", 240 | "futures-task", 241 | "pin-project-lite", 242 | "pin-utils", 243 | ] 244 | 245 | [[package]] 246 | name = "getrandom" 247 | version = "0.3.1" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" 250 | dependencies = [ 251 | "cfg-if", 252 | "libc", 253 | "wasi 0.13.3+wasi-0.2.2", 254 | "windows-targets", 255 | ] 256 | 257 | [[package]] 258 | name = "gimli" 259 | version = "0.31.1" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 262 | 263 | [[package]] 264 | name = "glob" 265 | version = "0.3.2" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" 268 | 269 | [[package]] 270 | name = "half" 271 | version = "2.4.1" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" 274 | dependencies = [ 275 | "cfg-if", 276 | "crunchy", 277 | ] 278 | 279 | [[package]] 280 | name = "home" 281 | version = "0.5.11" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 284 | dependencies = [ 285 | "windows-sys 0.59.0", 286 | ] 287 | 288 | [[package]] 289 | name = "http" 290 | version = "1.2.0" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" 293 | dependencies = [ 294 | "bytes", 295 | "fnv", 296 | "itoa", 297 | ] 298 | 299 | [[package]] 300 | name = "http-body" 301 | version = "1.0.1" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 304 | dependencies = [ 305 | "bytes", 306 | "http", 307 | ] 308 | 309 | [[package]] 310 | name = "http-body-util" 311 | version = "0.1.2" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 314 | dependencies = [ 315 | "bytes", 316 | "futures-util", 317 | "http", 318 | "http-body", 319 | "pin-project-lite", 320 | ] 321 | 322 | [[package]] 323 | name = "httparse" 324 | version = "1.10.0" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" 327 | 328 | [[package]] 329 | name = "hyper" 330 | version = "1.6.0" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 333 | dependencies = [ 334 | "bytes", 335 | "futures-channel", 336 | "futures-util", 337 | "http", 338 | "http-body", 339 | "httparse", 340 | "itoa", 341 | "pin-project-lite", 342 | "smallvec", 343 | "tokio", 344 | "want", 345 | ] 346 | 347 | [[package]] 348 | name = "hyper-tls" 349 | version = "0.6.0" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 352 | dependencies = [ 353 | "bytes", 354 | "http-body-util", 355 | "hyper", 356 | "hyper-util", 357 | "native-tls", 358 | "tokio", 359 | "tokio-native-tls", 360 | "tower-service", 361 | ] 362 | 363 | [[package]] 364 | name = "hyper-util" 365 | version = "0.1.10" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 368 | dependencies = [ 369 | "bytes", 370 | "futures-channel", 371 | "futures-util", 372 | "http", 373 | "http-body", 374 | "hyper", 375 | "pin-project-lite", 376 | "socket2", 377 | "tokio", 378 | "tower-service", 379 | "tracing", 380 | ] 381 | 382 | [[package]] 383 | name = "itertools" 384 | version = "0.12.1" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 387 | dependencies = [ 388 | "either", 389 | ] 390 | 391 | [[package]] 392 | name = "itoa" 393 | version = "1.0.14" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" 396 | 397 | [[package]] 398 | name = "jogs" 399 | version = "0.2.4" 400 | dependencies = [ 401 | "anyhow", 402 | "ciborium", 403 | "quickjs-wasm-rs", 404 | "serde", 405 | "serde_bytes", 406 | "wasm-minimal-protocol", 407 | ] 408 | 409 | [[package]] 410 | name = "lazy_static" 411 | version = "1.5.0" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 414 | 415 | [[package]] 416 | name = "lazycell" 417 | version = "1.3.0" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 420 | 421 | [[package]] 422 | name = "libc" 423 | version = "0.2.170" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" 426 | 427 | [[package]] 428 | name = "libloading" 429 | version = "0.8.6" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" 432 | dependencies = [ 433 | "cfg-if", 434 | "windows-targets", 435 | ] 436 | 437 | [[package]] 438 | name = "linux-raw-sys" 439 | version = "0.4.15" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 442 | 443 | [[package]] 444 | name = "log" 445 | version = "0.4.26" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" 448 | 449 | [[package]] 450 | name = "memchr" 451 | version = "2.7.4" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 454 | 455 | [[package]] 456 | name = "minimal-lexical" 457 | version = "0.2.1" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 460 | 461 | [[package]] 462 | name = "miniz_oxide" 463 | version = "0.8.5" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" 466 | dependencies = [ 467 | "adler2", 468 | ] 469 | 470 | [[package]] 471 | name = "mio" 472 | version = "1.0.3" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 475 | dependencies = [ 476 | "libc", 477 | "wasi 0.11.0+wasi-snapshot-preview1", 478 | "windows-sys 0.52.0", 479 | ] 480 | 481 | [[package]] 482 | name = "native-tls" 483 | version = "0.2.14" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" 486 | dependencies = [ 487 | "libc", 488 | "log", 489 | "openssl", 490 | "openssl-probe", 491 | "openssl-sys", 492 | "schannel", 493 | "security-framework", 494 | "security-framework-sys", 495 | "tempfile", 496 | ] 497 | 498 | [[package]] 499 | name = "nom" 500 | version = "7.1.3" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 503 | dependencies = [ 504 | "memchr", 505 | "minimal-lexical", 506 | ] 507 | 508 | [[package]] 509 | name = "object" 510 | version = "0.36.7" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 513 | dependencies = [ 514 | "memchr", 515 | ] 516 | 517 | [[package]] 518 | name = "once_cell" 519 | version = "1.20.3" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" 522 | 523 | [[package]] 524 | name = "openssl" 525 | version = "0.10.71" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" 528 | dependencies = [ 529 | "bitflags", 530 | "cfg-if", 531 | "foreign-types", 532 | "libc", 533 | "once_cell", 534 | "openssl-macros", 535 | "openssl-sys", 536 | ] 537 | 538 | [[package]] 539 | name = "openssl-macros" 540 | version = "0.1.1" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 543 | dependencies = [ 544 | "proc-macro2", 545 | "quote", 546 | "syn", 547 | ] 548 | 549 | [[package]] 550 | name = "openssl-probe" 551 | version = "0.1.6" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 554 | 555 | [[package]] 556 | name = "openssl-sys" 557 | version = "0.9.106" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" 560 | dependencies = [ 561 | "cc", 562 | "libc", 563 | "pkg-config", 564 | "vcpkg", 565 | ] 566 | 567 | [[package]] 568 | name = "pin-project-lite" 569 | version = "0.2.16" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 572 | 573 | [[package]] 574 | name = "pin-utils" 575 | version = "0.1.0" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 578 | 579 | [[package]] 580 | name = "pkg-config" 581 | version = "0.3.31" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 584 | 585 | [[package]] 586 | name = "prettyplease" 587 | version = "0.2.29" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" 590 | dependencies = [ 591 | "proc-macro2", 592 | "syn", 593 | ] 594 | 595 | [[package]] 596 | name = "proc-macro2" 597 | version = "1.0.93" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" 600 | dependencies = [ 601 | "unicode-ident", 602 | ] 603 | 604 | [[package]] 605 | name = "quickjs-wasm-rs" 606 | version = "3.1.0" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "28238e71a7aaafc42354af7908626b8b062d9a5ff16e4da6a5890e372b717cc5" 609 | dependencies = [ 610 | "anyhow", 611 | "once_cell", 612 | "quickjs-wasm-sys", 613 | "serde", 614 | ] 615 | 616 | [[package]] 617 | name = "quickjs-wasm-sys" 618 | version = "1.2.1" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "b052f6874a9e5c448f4f7d811972290acb3c09f8e580056c07f91ad7644ea33f" 621 | dependencies = [ 622 | "anyhow", 623 | "bindgen", 624 | "cc", 625 | "http-body-util", 626 | "hyper", 627 | "hyper-tls", 628 | "hyper-util", 629 | "tokio", 630 | "walkdir", 631 | ] 632 | 633 | [[package]] 634 | name = "quote" 635 | version = "1.0.38" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 638 | dependencies = [ 639 | "proc-macro2", 640 | ] 641 | 642 | [[package]] 643 | name = "regex" 644 | version = "1.11.1" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 647 | dependencies = [ 648 | "aho-corasick", 649 | "memchr", 650 | "regex-automata", 651 | "regex-syntax", 652 | ] 653 | 654 | [[package]] 655 | name = "regex-automata" 656 | version = "0.4.9" 657 | source = "registry+https://github.com/rust-lang/crates.io-index" 658 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 659 | dependencies = [ 660 | "aho-corasick", 661 | "memchr", 662 | "regex-syntax", 663 | ] 664 | 665 | [[package]] 666 | name = "regex-syntax" 667 | version = "0.8.5" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 670 | 671 | [[package]] 672 | name = "rustc-demangle" 673 | version = "0.1.24" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 676 | 677 | [[package]] 678 | name = "rustc-hash" 679 | version = "1.1.0" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 682 | 683 | [[package]] 684 | name = "rustix" 685 | version = "0.38.44" 686 | source = "registry+https://github.com/rust-lang/crates.io-index" 687 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 688 | dependencies = [ 689 | "bitflags", 690 | "errno", 691 | "libc", 692 | "linux-raw-sys", 693 | "windows-sys 0.59.0", 694 | ] 695 | 696 | [[package]] 697 | name = "same-file" 698 | version = "1.0.6" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 701 | dependencies = [ 702 | "winapi-util", 703 | ] 704 | 705 | [[package]] 706 | name = "schannel" 707 | version = "0.1.27" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 710 | dependencies = [ 711 | "windows-sys 0.59.0", 712 | ] 713 | 714 | [[package]] 715 | name = "security-framework" 716 | version = "2.11.1" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 719 | dependencies = [ 720 | "bitflags", 721 | "core-foundation", 722 | "core-foundation-sys", 723 | "libc", 724 | "security-framework-sys", 725 | ] 726 | 727 | [[package]] 728 | name = "security-framework-sys" 729 | version = "2.14.0" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" 732 | dependencies = [ 733 | "core-foundation-sys", 734 | "libc", 735 | ] 736 | 737 | [[package]] 738 | name = "serde" 739 | version = "1.0.218" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" 742 | dependencies = [ 743 | "serde_derive", 744 | ] 745 | 746 | [[package]] 747 | name = "serde_bytes" 748 | version = "0.11.15" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" 751 | dependencies = [ 752 | "serde", 753 | ] 754 | 755 | [[package]] 756 | name = "serde_derive" 757 | version = "1.0.218" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" 760 | dependencies = [ 761 | "proc-macro2", 762 | "quote", 763 | "syn", 764 | ] 765 | 766 | [[package]] 767 | name = "shlex" 768 | version = "1.3.0" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 771 | 772 | [[package]] 773 | name = "smallvec" 774 | version = "1.14.0" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" 777 | 778 | [[package]] 779 | name = "socket2" 780 | version = "0.5.8" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 783 | dependencies = [ 784 | "libc", 785 | "windows-sys 0.52.0", 786 | ] 787 | 788 | [[package]] 789 | name = "syn" 790 | version = "2.0.98" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" 793 | dependencies = [ 794 | "proc-macro2", 795 | "quote", 796 | "unicode-ident", 797 | ] 798 | 799 | [[package]] 800 | name = "tempfile" 801 | version = "3.17.1" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" 804 | dependencies = [ 805 | "cfg-if", 806 | "fastrand", 807 | "getrandom", 808 | "once_cell", 809 | "rustix", 810 | "windows-sys 0.59.0", 811 | ] 812 | 813 | [[package]] 814 | name = "tokio" 815 | version = "1.43.0" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" 818 | dependencies = [ 819 | "backtrace", 820 | "libc", 821 | "mio", 822 | "pin-project-lite", 823 | "socket2", 824 | "tokio-macros", 825 | "windows-sys 0.52.0", 826 | ] 827 | 828 | [[package]] 829 | name = "tokio-macros" 830 | version = "2.5.0" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 833 | dependencies = [ 834 | "proc-macro2", 835 | "quote", 836 | "syn", 837 | ] 838 | 839 | [[package]] 840 | name = "tokio-native-tls" 841 | version = "0.3.1" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 844 | dependencies = [ 845 | "native-tls", 846 | "tokio", 847 | ] 848 | 849 | [[package]] 850 | name = "tower-service" 851 | version = "0.3.3" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 854 | 855 | [[package]] 856 | name = "tracing" 857 | version = "0.1.41" 858 | source = "registry+https://github.com/rust-lang/crates.io-index" 859 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 860 | dependencies = [ 861 | "pin-project-lite", 862 | "tracing-core", 863 | ] 864 | 865 | [[package]] 866 | name = "tracing-core" 867 | version = "0.1.33" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 870 | dependencies = [ 871 | "once_cell", 872 | ] 873 | 874 | [[package]] 875 | name = "try-lock" 876 | version = "0.2.5" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 879 | 880 | [[package]] 881 | name = "unicode-ident" 882 | version = "1.0.17" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" 885 | 886 | [[package]] 887 | name = "vcpkg" 888 | version = "0.2.15" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 891 | 892 | [[package]] 893 | name = "venial" 894 | version = "0.5.0" 895 | source = "registry+https://github.com/rust-lang/crates.io-index" 896 | checksum = "61584a325b16f97b5b25fcc852eb9550843a251057a5e3e5992d2376f3df4bb2" 897 | dependencies = [ 898 | "proc-macro2", 899 | "quote", 900 | ] 901 | 902 | [[package]] 903 | name = "walkdir" 904 | version = "2.5.0" 905 | source = "registry+https://github.com/rust-lang/crates.io-index" 906 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 907 | dependencies = [ 908 | "same-file", 909 | "winapi-util", 910 | ] 911 | 912 | [[package]] 913 | name = "want" 914 | version = "0.3.1" 915 | source = "registry+https://github.com/rust-lang/crates.io-index" 916 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 917 | dependencies = [ 918 | "try-lock", 919 | ] 920 | 921 | [[package]] 922 | name = "wasi" 923 | version = "0.11.0+wasi-snapshot-preview1" 924 | source = "registry+https://github.com/rust-lang/crates.io-index" 925 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 926 | 927 | [[package]] 928 | name = "wasi" 929 | version = "0.13.3+wasi-0.2.2" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" 932 | dependencies = [ 933 | "wit-bindgen-rt", 934 | ] 935 | 936 | [[package]] 937 | name = "wasm-minimal-protocol" 938 | version = "0.1.0" 939 | source = "git+https://github.com/astrale-sharp/wasm-minimal-protocol#90336ebf2d99844fd8f8e99ea7096af96526cbf4" 940 | dependencies = [ 941 | "proc-macro2", 942 | "quote", 943 | "venial", 944 | ] 945 | 946 | [[package]] 947 | name = "which" 948 | version = "4.4.2" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 951 | dependencies = [ 952 | "either", 953 | "home", 954 | "once_cell", 955 | "rustix", 956 | ] 957 | 958 | [[package]] 959 | name = "winapi-util" 960 | version = "0.1.9" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 963 | dependencies = [ 964 | "windows-sys 0.59.0", 965 | ] 966 | 967 | [[package]] 968 | name = "windows-sys" 969 | version = "0.52.0" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 972 | dependencies = [ 973 | "windows-targets", 974 | ] 975 | 976 | [[package]] 977 | name = "windows-sys" 978 | version = "0.59.0" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 981 | dependencies = [ 982 | "windows-targets", 983 | ] 984 | 985 | [[package]] 986 | name = "windows-targets" 987 | version = "0.52.6" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 990 | dependencies = [ 991 | "windows_aarch64_gnullvm", 992 | "windows_aarch64_msvc", 993 | "windows_i686_gnu", 994 | "windows_i686_gnullvm", 995 | "windows_i686_msvc", 996 | "windows_x86_64_gnu", 997 | "windows_x86_64_gnullvm", 998 | "windows_x86_64_msvc", 999 | ] 1000 | 1001 | [[package]] 1002 | name = "windows_aarch64_gnullvm" 1003 | version = "0.52.6" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1006 | 1007 | [[package]] 1008 | name = "windows_aarch64_msvc" 1009 | version = "0.52.6" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1012 | 1013 | [[package]] 1014 | name = "windows_i686_gnu" 1015 | version = "0.52.6" 1016 | source = "registry+https://github.com/rust-lang/crates.io-index" 1017 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1018 | 1019 | [[package]] 1020 | name = "windows_i686_gnullvm" 1021 | version = "0.52.6" 1022 | source = "registry+https://github.com/rust-lang/crates.io-index" 1023 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1024 | 1025 | [[package]] 1026 | name = "windows_i686_msvc" 1027 | version = "0.52.6" 1028 | source = "registry+https://github.com/rust-lang/crates.io-index" 1029 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1030 | 1031 | [[package]] 1032 | name = "windows_x86_64_gnu" 1033 | version = "0.52.6" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1036 | 1037 | [[package]] 1038 | name = "windows_x86_64_gnullvm" 1039 | version = "0.52.6" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1042 | 1043 | [[package]] 1044 | name = "windows_x86_64_msvc" 1045 | version = "0.52.6" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1048 | 1049 | [[package]] 1050 | name = "wit-bindgen-rt" 1051 | version = "0.33.0" 1052 | source = "registry+https://github.com/rust-lang/crates.io-index" 1053 | checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" 1054 | dependencies = [ 1055 | "bitflags", 1056 | ] 1057 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "jogs" 3 | version = "0.2.4" 4 | edition = "2021" 5 | license = "MIT" 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | [lib] 8 | crate-type = ["cdylib"] 9 | [dependencies] 10 | anyhow = "1" 11 | ciborium = "0.2.2" 12 | quickjs-wasm-rs = "3.1.0" 13 | serde = { version = "1", features = ["derive"] } 14 | serde_bytes = "0.11.15" 15 | wasm-minimal-protocol = { git = "https://github.com/astrale-sharp/wasm-minimal-protocol" } 16 | 17 | [profile.release] 18 | lto = true # Enable link-time optimization 19 | strip = true # Strip symbols from binary* 20 | opt-level = 'z' # Optimize for size 21 | codegen-units = 1 # Reduce number of codegen units to increase optimizations 22 | panic = 'abort' # Abort on panic 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 mgt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jogs 2 | 3 | Quickjs javascript runtime for typst. This package provides a typst plugin for evaluating javascript code. 4 | 5 | ## Example 6 | 7 | ````typst 8 | #import "@preview/jogs:0.2.4": * 9 | 10 | #set page(height: auto, width: auto, fill: black, margin: 1em) 11 | #set text(fill: white) 12 | 13 | #let code = ``` 14 | function sum() { 15 | const total = Array.prototype.slice.call(arguments).reduce(function(a, b) { 16 | return a + b; 17 | }, 0); 18 | return total; 19 | } 20 | 21 | function string_join(arr) { 22 | return arr.join(" | "); 23 | } 24 | 25 | function return_complex_obj() { 26 | return { 27 | a: 1, 28 | b: "2", 29 | c: [1, 2, 3], 30 | d: { 31 | e: 1, 32 | }, 33 | }; 34 | } 35 | 36 | ``` 37 | #let bytecode = compile-js(code) 38 | 39 | #list-global-property(bytecode) 40 | 41 | #call-js-function(bytecode, "sum", 6, 7, 8, 9, 10) 42 | 43 | #call-js-function(bytecode, "string_join", ("a", "b", "c", "d", "e"),) 44 | 45 | #call-js-function(bytecode, "return_complex_obj",) 46 | 47 | 48 | ```` 49 | 50 | result: 51 | 52 | ![](typst-package/examples/fib.svg) 53 | 54 | ## Documentation 55 | 56 | This package provide following function(s): 57 | 58 | ### `eval-js` 59 | 60 | Run a Javascript code snippet. 61 | 62 | #### Arguments 63 | * `code` - The Javascript code to run. It can be a string or a raw block. 64 | 65 | #### Returns 66 | The result of the Javascript code. The type is the typst type which most closely resembles the Javascript type. 67 | 68 | #### Example 69 | 70 | ```typ 71 | #let result = eval-js("1 + 1") 72 | ``` 73 | 74 | ### `compile-js` 75 | 76 | Compile a Javascript code snippet into bytecode. 77 | 78 | #### Arguments 79 | 80 | * `code` - The Javascript code to compile. It can be a string or a raw block. 81 | 82 | #### Returns 83 | 84 | The bytecode of the Javascript code. The type is `bytes`. 85 | 86 | #### Example 87 | 88 | ```typ 89 | #let bytecode = compile-js("function sum(a, b) { return a + b; }") 90 | ``` 91 | 92 | ### `call-js-function` 93 | 94 | Call a Javascript function with arguments. 95 | 96 | #### Arguments 97 | 98 | * `bytecode` - The bytecode of the Javascript function. It can be obtained by calling `compile-js`. 99 | * `name` - The name of the Javascript function. 100 | * `..args` - The arguments to pass to the Javascript function. All other positional arguments are passed to the Javascript function as is. 101 | 102 | #### Returns 103 | 104 | The result of the Javascript function. The type is the typst type which most closely resembles the Javascript type. 105 | 106 | #### Example 107 | 108 | ```typ 109 | #let bytecode = compile-js("function sum(a, b) { return a + b; }") 110 | #let result = call-js-function(bytecode, "sum", 1, 2) 111 | ``` 112 | 113 | ### `list-global-property` 114 | 115 | List all global properties of a compiled Javascript bytecode. This is useful for inspecting the compiled Javascript bytecode. 116 | 117 | #### Arguments 118 | 119 | * `bytecode` - The bytecode of the Javascript function. It can be obtained by calling `compile-js`. 120 | 121 | #### Returns 122 | 123 | A list of all global properties of the Javascript bytecode. The type is `array`. 124 | 125 | #### Example 126 | 127 | ```typ 128 | #let bytecode = compile-js("function sum(a, b) { return a + b; }") 129 | #let result = list-global-property(bytecode) 130 | ``` 131 | ## Build From Source 132 | 133 | To build this project from source, you would need the following tools: 134 | 1. [wasm-pack](https://github.com/rustwasm/wasm-pack) 135 | 2. `wasi-stub` from [wasm-minimal-protocol](https://github.com/astrale-sharp/wasm-minimal-protocol/) 136 | 3. [cargo-about](https://github.com/EmbarkStudios/cargo-about) 137 | Once you've installed them, you can run `install.sh` script to build plugin. 138 | 139 | Installing the `wasi-stub` tool might be confusing for those who aren't familiar with typst or rust toolchain. Here's the detail instruction on how to build it from source. 140 | 141 | 1. Clone the `wasm-minimal-protocol` repo to your own computer, normally we just need the latest version of it, not the full history. 142 | ```bash 143 | git clone https://github.com/astrale-sharp/wasm-minimal-protocol/ --depth=1 144 | ``` 145 | 2. Enter the repo's sub-directory called `wasi-stub`, and build the tool using `cargo`. 146 | ```bash 147 | cd wasm-minimal-protocol/wasi-stub 148 | cargo build 149 | # Better copy one to the project's root directory, so the build.sh script would detect it in build process. 150 | cp ../target/debug/wasi-stub ../.. 151 | ``` 152 | 3. (Optional) Safely delete the `wasm-minimal-protocol` repo, we wouldn't made any changes to it. 153 | -------------------------------------------------------------------------------- /about.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 36 | 37 | 38 | 39 |
40 |
41 |

Third Party Licenses

42 |

This page lists the licenses of the projects used in cargo-about.

43 |
44 | 45 |

Overview of licenses:

46 | 51 | 52 |

All license text:

53 | 67 |
68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /about.toml: -------------------------------------------------------------------------------- 1 | accepted = [ 2 | "Apache-2.0", 3 | "MIT", 4 | "BSD-3-Clause", 5 | "ISC", 6 | "Unlicense", 7 | "Unicode-DFS-2016", 8 | "Apache-2.0 WITH LLVM-exception", 9 | "Unicode-3.0", 10 | ] 11 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euxo pipefail 3 | cargo build --release --target wasm32-wasip1 4 | cargo about generate about.hbs > license.html 5 | cp license.html typst-package/ 6 | cp README.md typst-package/ 7 | wasi-stub -r 0 ./target/wasm32-wasip1/release/jogs.wasm -o typst-package/jogs.wasm 8 | wasm-opt typst-package/jogs.wasm -O3 --enable-bulk-memory -o typst-package/jogs.wasm 9 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use anyhow::{bail, Context, Result}; 4 | use quickjs_wasm_rs::{from_qjs_value, to_qjs_value, JSContextRef, JSValue, JSValueRef}; 5 | use serde::{Deserialize, Serialize}; 6 | use wasm_minimal_protocol::*; 7 | 8 | initiate_protocol!(); 9 | 10 | #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] 11 | #[serde(untagged)] 12 | pub enum MyJSValue { 13 | /// Represents the JavaScript `undefined` value 14 | Undefined, 15 | /// Represents the JavaScript `null` value 16 | Null, 17 | /// Represents a JavaScript boolean value 18 | Bool(bool), 19 | /// Represents a JavaScript integer 20 | Int(i32), 21 | /// Represents a JavaScript floating-point number 22 | Float(f64), 23 | /// Represents a JavaScript string value 24 | String(String), 25 | /// Represents a JavaScript array of `JSValue`s 26 | Array(Vec), 27 | /// Represents a JavaScript ArrayBuffer of bytes 28 | ArrayBuffer(Vec), 29 | /// Represents a JavaScript object, with string keys and `JSValue` values 30 | Object(HashMap), 31 | } 32 | 33 | impl From for MyJSValue { 34 | fn from(value: JSValue) -> Self { 35 | match value { 36 | JSValue::Undefined => MyJSValue::Undefined, 37 | JSValue::Null => MyJSValue::Null, 38 | JSValue::Bool(b) => MyJSValue::Bool(b), 39 | JSValue::Int(i) => MyJSValue::Int(i), 40 | JSValue::Float(f) => MyJSValue::Float(f), 41 | JSValue::String(s) => MyJSValue::String(s), 42 | JSValue::Array(arr) => MyJSValue::Array(arr.into_iter().map(|v| v.into()).collect()), 43 | JSValue::ArrayBuffer(buf) => MyJSValue::ArrayBuffer(buf), 44 | JSValue::Object(obj) => { 45 | MyJSValue::Object(obj.into_iter().map(|(k, v)| (k, v.into())).collect()) 46 | } 47 | } 48 | } 49 | } 50 | 51 | impl From for JSValue { 52 | fn from(value: MyJSValue) -> Self { 53 | match value { 54 | MyJSValue::Undefined => JSValue::Undefined, 55 | MyJSValue::Null => JSValue::Null, 56 | MyJSValue::Bool(b) => JSValue::Bool(b), 57 | MyJSValue::Int(i) => JSValue::Int(i), 58 | MyJSValue::Float(f) => JSValue::Float(f), 59 | MyJSValue::String(s) => JSValue::String(s), 60 | MyJSValue::Array(arr) => JSValue::Array(arr.into_iter().map(|v| v.into()).collect()), 61 | MyJSValue::ArrayBuffer(buf) => JSValue::ArrayBuffer(buf), 62 | MyJSValue::Object(obj) => { 63 | JSValue::Object(obj.into_iter().map(|(k, v)| (k, v.into())).collect()) 64 | } 65 | } 66 | } 67 | } 68 | 69 | #[wasm_func] 70 | fn eval(input: &[u8]) -> Result> { 71 | let context = JSContextRef::default(); 72 | let input = std::str::from_utf8(input).context("failed to parse input as utf8")?; 73 | let res = from_qjs_value(context.eval_global("", input)?)?; 74 | let res = MyJSValue::from(res); 75 | let mut buffer = vec![]; 76 | ciborium::ser::into_writer(&res, &mut buffer).context("failed to serialize result")?; 77 | Ok(buffer) 78 | } 79 | 80 | #[wasm_func] 81 | fn compile(input: &[u8]) -> Result> { 82 | let context = JSContextRef::default(); 83 | let Ok(input) = std::str::from_utf8(input) else { 84 | bail!("input is not utf8"); 85 | }; 86 | context.compile_global("", input) 87 | } 88 | 89 | #[wasm_func] 90 | fn list_property_keys(input: &[u8]) -> Result> { 91 | let context = JSContextRef::default(); 92 | context.eval_binary(input)?; 93 | let mut props = context 94 | .global_object() 95 | .context("failed to get global object")? 96 | .properties() 97 | .context("failed to get properties for global object")?; 98 | let mut keys: Vec = vec![]; 99 | while let Some(key) = props 100 | .next_key() 101 | .context("failed to get next key in props")? 102 | { 103 | keys.push( 104 | from_qjs_value(key) 105 | .context("failed to convert key to MyJSValue")? 106 | .into(), 107 | ); 108 | } 109 | let mut buffer = vec![]; 110 | ciborium::ser::into_writer(&keys, &mut buffer).context("failed to serialize result")?; 111 | Ok(buffer) 112 | } 113 | 114 | #[wasm_func] 115 | fn call_function(bytecode: &[u8], function_name: &[u8], args: &[u8]) -> Result> { 116 | let context = JSContextRef::default(); 117 | let function_name = std::str::from_utf8(function_name).context("function name is not utf8")?; 118 | let arguments: Vec = 119 | ciborium::from_reader(args).context("failed to deserialize arguments")?; 120 | let arguments: Vec = arguments 121 | .into_iter() 122 | .map(|v| { 123 | let v: JSValue = v.into(); 124 | to_qjs_value(&context, &v) 125 | }) 126 | .collect::, _>>() 127 | .context("failed to convert arguments to JSValueRef")?; 128 | context.eval_binary(bytecode)?; 129 | let global_this = context 130 | .global_object() 131 | .context("failed to get global object")?; 132 | let function = global_this 133 | .get_property(function_name) 134 | .with_context(|| format!("failed to get function: {}", function_name))?; 135 | let res = function.call(&global_this, &arguments)?; 136 | let res = from_qjs_value(res).context("failed to convert result to MyJSValue")?; 137 | let res = MyJSValue::from(res); 138 | let mut buffer = vec![]; 139 | ciborium::ser::into_writer(&res, &mut buffer).context("failed to serialize result")?; 140 | Ok(buffer) 141 | } 142 | -------------------------------------------------------------------------------- /typst-package/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 mgt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /typst-package/README.md: -------------------------------------------------------------------------------- 1 | # Jogs 2 | 3 | Quickjs javascript runtime for typst. This package provides a typst plugin for evaluating javascript code. 4 | 5 | ## Example 6 | 7 | ````typst 8 | #import "@preview/jogs:0.2.4": * 9 | 10 | #set page(height: auto, width: auto, fill: black, margin: 1em) 11 | #set text(fill: white) 12 | 13 | #let code = ``` 14 | function sum() { 15 | const total = Array.prototype.slice.call(arguments).reduce(function(a, b) { 16 | return a + b; 17 | }, 0); 18 | return total; 19 | } 20 | 21 | function string_join(arr) { 22 | return arr.join(" | "); 23 | } 24 | 25 | function return_complex_obj() { 26 | return { 27 | a: 1, 28 | b: "2", 29 | c: [1, 2, 3], 30 | d: { 31 | e: 1, 32 | }, 33 | }; 34 | } 35 | 36 | ``` 37 | #let bytecode = compile-js(code) 38 | 39 | #list-global-property(bytecode) 40 | 41 | #call-js-function(bytecode, "sum", 6, 7, 8, 9, 10) 42 | 43 | #call-js-function(bytecode, "string_join", ("a", "b", "c", "d", "e"),) 44 | 45 | #call-js-function(bytecode, "return_complex_obj",) 46 | 47 | 48 | ```` 49 | 50 | result: 51 | 52 | ![](typst-package/examples/fib.svg) 53 | 54 | ## Documentation 55 | 56 | This package provide following function(s): 57 | 58 | ### `eval-js` 59 | 60 | Run a Javascript code snippet. 61 | 62 | #### Arguments 63 | * `code` - The Javascript code to run. It can be a string or a raw block. 64 | 65 | #### Returns 66 | The result of the Javascript code. The type is the typst type which most closely resembles the Javascript type. 67 | 68 | #### Example 69 | 70 | ```typ 71 | #let result = eval-js("1 + 1") 72 | ``` 73 | 74 | ### `compile-js` 75 | 76 | Compile a Javascript code snippet into bytecode. 77 | 78 | #### Arguments 79 | 80 | * `code` - The Javascript code to compile. It can be a string or a raw block. 81 | 82 | #### Returns 83 | 84 | The bytecode of the Javascript code. The type is `bytes`. 85 | 86 | #### Example 87 | 88 | ```typ 89 | #let bytecode = compile-js("function sum(a, b) { return a + b; }") 90 | ``` 91 | 92 | ### `call-js-function` 93 | 94 | Call a Javascript function with arguments. 95 | 96 | #### Arguments 97 | 98 | * `bytecode` - The bytecode of the Javascript function. It can be obtained by calling `compile-js`. 99 | * `name` - The name of the Javascript function. 100 | * `..args` - The arguments to pass to the Javascript function. All other positional arguments are passed to the Javascript function as is. 101 | 102 | #### Returns 103 | 104 | The result of the Javascript function. The type is the typst type which most closely resembles the Javascript type. 105 | 106 | #### Example 107 | 108 | ```typ 109 | #let bytecode = compile-js("function sum(a, b) { return a + b; }") 110 | #let result = call-js-function(bytecode, "sum", 1, 2) 111 | ``` 112 | 113 | ### `list-global-property` 114 | 115 | List all global properties of a compiled Javascript bytecode. This is useful for inspecting the compiled Javascript bytecode. 116 | 117 | #### Arguments 118 | 119 | * `bytecode` - The bytecode of the Javascript function. It can be obtained by calling `compile-js`. 120 | 121 | #### Returns 122 | 123 | A list of all global properties of the Javascript bytecode. The type is `array`. 124 | 125 | #### Example 126 | 127 | ```typ 128 | #let bytecode = compile-js("function sum(a, b) { return a + b; }") 129 | #let result = list-global-property(bytecode) 130 | ``` 131 | ## Build From Source 132 | 133 | To build this project from source, you would need the following tools: 134 | 1. [wasm-pack](https://github.com/rustwasm/wasm-pack) 135 | 2. `wasi-stub` from [wasm-minimal-protocol](https://github.com/astrale-sharp/wasm-minimal-protocol/) 136 | 3. [cargo-about](https://github.com/EmbarkStudios/cargo-about) 137 | Once you've installed them, you can run `install.sh` script to build plugin. 138 | 139 | Installing the `wasi-stub` tool might be confusing for those who aren't familiar with typst or rust toolchain. Here's the detail instruction on how to build it from source. 140 | 141 | 1. Clone the `wasm-minimal-protocol` repo to your own computer, normally we just need the latest version of it, not the full history. 142 | ```bash 143 | git clone https://github.com/astrale-sharp/wasm-minimal-protocol/ --depth=1 144 | ``` 145 | 2. Enter the repo's sub-directory called `wasi-stub`, and build the tool using `cargo`. 146 | ```bash 147 | cd wasm-minimal-protocol/wasi-stub 148 | cargo build 149 | # Better copy one to the project's root directory, so the build.sh script would detect it in build process. 150 | cp ../target/debug/wasi-stub ../.. 151 | ``` 152 | 3. (Optional) Safely delete the `wasm-minimal-protocol` repo, we wouldn't made any changes to it. 153 | -------------------------------------------------------------------------------- /typst-package/examples/fib.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | -------------------------------------------------------------------------------- /typst-package/examples/fib.typ: -------------------------------------------------------------------------------- 1 | #set page(height: auto, width: auto, fill: black, margin: 1em) 2 | #set text(fill: white) 3 | #import "../lib.typ": * 4 | 5 | #let code = ``` 6 | function sum() { 7 | const total = Array.prototype.slice.call(arguments).reduce(function(a, b) { 8 | return a + b; 9 | }, 0); 10 | return total; 11 | } 12 | 13 | function string_join(arr) { 14 | return arr.join(" | "); 15 | } 16 | 17 | function return_complex_obj() { 18 | return { 19 | a: 1, 20 | b: "2", 21 | c: [1, 2, 3], 22 | d: { 23 | e: 1, 24 | }, 25 | }; 26 | } 27 | 28 | ``` 29 | #let bytecode = compile-js(code) 30 | 31 | #list-global-property(bytecode) 32 | 33 | #call-js-function(bytecode, "sum", 6, 7, 8, 9, 10) 34 | 35 | #call-js-function(bytecode, "string_join", ("a", "b", "c", "d", "e"),) 36 | 37 | #call-js-function(bytecode, "return_complex_obj",) 38 | -------------------------------------------------------------------------------- /typst-package/jogs.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Enter-tainer/jogs/9ba6dde9bfe4a6b1e62e76bb26db25f76b9c0b34/typst-package/jogs.wasm -------------------------------------------------------------------------------- /typst-package/lib.typ: -------------------------------------------------------------------------------- 1 | #let jogs-wasm = plugin("jogs.wasm") 2 | 3 | /// Run a Javascript code snippet. 4 | /// 5 | /// # Arguments 6 | /// * `code` - The Javascript code string to run. 7 | /// 8 | /// # Returns 9 | /// The result of the Javascript code. The type is the typst type which most closely resembles the Javascript type. 10 | /// 11 | /// # Example 12 | /// ```typ 13 | /// let result = eval-js("1 + 1") 14 | /// ``` 15 | #let eval-js(code) = if type(code) == str { 16 | cbor(jogs-wasm.eval(bytes(code))) 17 | } else { 18 | cbor(jogs-wasm.eval(bytes(code.text))) 19 | } 20 | 21 | #let compile-js(code) = if type(code) == str { 22 | jogs-wasm.compile(bytes(code)) 23 | } else { 24 | jogs-wasm.compile(bytes(code.text)) 25 | } 26 | 27 | #let list-global-property(bytecode) = cbor(jogs-wasm.list_property_keys(bytecode)) 28 | 29 | #let call-js-function(bytecode, function-name, ..args) = cbor( 30 | jogs-wasm.call_function( 31 | bytecode, 32 | bytes(function-name), 33 | cbor.encode(args.pos()), 34 | ) 35 | ) 36 | -------------------------------------------------------------------------------- /typst-package/typst.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "jogs" 3 | version = "0.2.4" 4 | entrypoint = "lib.typ" 5 | authors = ["Wenzhuo Liu"] 6 | license = "MIT" 7 | description = "QuickJS JavaScript runtime for Typst" 8 | 9 | homepage = "https://github.com/Enter-tainer/jogs" 10 | repository = "https://github.com/Enter-tainer/jogs" 11 | keywords = [ 12 | "wasm", 13 | "rust", 14 | "js", 15 | "javascript", 16 | "quickjs", 17 | "runtime", 18 | ] 19 | exclude = [ 20 | "examples" 21 | ] 22 | --------------------------------------------------------------------------------