feat: bump typst to v0.13.0-rc1 (#1342)

* dev: use range type from lsp-types

* feat: add html document variant

* feat: use new-style bytes constructors

* fix: broken span usages

* fix: syntax kind is changed

* fix: label use pico str

* fix: bib element is changed

* fix: raw element is changed

* fix: typst use codex

* fix: package fn is removed from world trait

* feat: reflexo accept typst document

* docs: update changelog

* dev: cargo patch

* fix: typst pdf timestamp is changed

* fix: pattern is renamed to tiling

* dev: make eval compat

* test: update snapshots

* build: bump version to nightly 0.12.19-rc4

* build: bump version to 0.12.19-rc1 (#1164)

  * build update changelog

  * build: bump version to 0.12.19-rc1

* build: bump version to nightly 0.12.19-rc2 (#1221)

  * feat: update typst to `85d1778`

  * deps: lock git deps version

  * build: bump version to 0.12.19-rc2

  * docs: remove rc in changelog

  * fix: mathtext formatting of typstyle

  * fix: completion related to mathtext

  * build: update cargo.lock

* build: bump version to nightly 0.12.19-rc3 (#1232)

* build: bump version to nightly 0.12.19-rc4 (#1239)

* feat: add typst-html

* feat: add typst-html

* cargo patch

* fix: features doesn't take effect

* fix: casting

* fix: broken no-content-hint

* fix: snapshot

* fix: remove unnecessary `fs` feature

* fix: move system features feature

* feat: remove nightly shim

* test: update snapshot

* dev: nightly v0.12.21 (#1279)

* feat: update typst to `0ea6680`

feat: update typst to `0ea6680`

build: bump version to nightly 0.12.19 (#1261)

* fix: fix lint errors

* styl: fotmat

* fix: build web ci

* build: update cargo.toml

* build: bump version to nightly 0.12.21-rc1 (#1280)

* build: update typstyle & reflexo (#1336)

* build: update typstyle & reflexo

* dev: remove useless patches

---------

Co-authored-by: Myriad-Dreamin <camiyoru@gmail.com>

* build: update version

* fix: pdf gate were broken (#1285)

* fix: panic on convert_datetime (#1286)

* feat: run language sever with targeting html (#1284)

* dev: add some debug logging

* feat: html compilation

* fix: revert changes

* feat: adjust html interfaces

* feat: lock reflexo

* feat: provide exportTarget configuration

* feat: export html actions when target is html

* build: bump reflexo

* fix: system feature gate

* fix: feature gate 2

* fix: feature gate 3

* feat: make tinymist-world featured by lsp

* feat: text export over typst's HTML export (#1289)

* feat: add more doc, world, and task apis (#1290)

* feat: add num of pages method

* feat: add from_snapshot_inner method

* feat: add clear_dedicates method

* feat: more convertion traits

* feat: add doc_get_as_value method

* feat: add doc_get_as_value method

* feat: add cast_run method

* fix: set is compiling flag (#1293)

* feat: publish {tinymist-{derive,analysis,std,vfs,world,project},typlite,crityp} crates (#1310)

* build: bump version to 0.12.21-pre-rc1

* fix: deps

* build: set nightly in nightly branch

* docs: add readmes for publish

* feat: add release crates action

* dev: remove publish of sync-lsp

* dev: remove useless setup

* fix: remove readme

* fix: publish ignore errors

* fix: specify version for publish

* fix: specify version for publish

* feat: update tinymist-web version

* test: update snapshot

* fix: diverged deps

---------

Co-authored-by: ParaN3xus <136563585+ParaN3xus@users.noreply.github.com>
This commit is contained in:
Myriad-Dreamin 2025-02-21 03:18:04 +08:00 committed by GitHub
parent 0260bfb527
commit d21ebc38dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
137 changed files with 1722 additions and 1156 deletions

View file

@ -48,42 +48,30 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install llvm
- name: Install AArch64 target toolchain
if: matrix.rust-target == 'aarch64-unknown-linux-gnu' && (fromJson(env.isRelease) || fromJson(env.isNightly))
run: |
sudo apt-get update
sudo apt-get install gcc-aarch64-linux-gnu
- name: Install ARM target toolchain
if: matrix.rust-target == 'arm-unknown-linux-gnueabihf' && (fromJson(env.isRelease) || fromJson(env.isNightly))
run: |
sudo apt-get update
sudo apt-get install gcc-arm-linux-gnueabihf
# - name: Run rust-cache
# uses: Swatinem/rust-cache@v2
# if: (fromJson(env.isRelease) || fromJson(env.isNightly))
- name: Publish crates
run: |
cargo publish --no-verify -p typst-shim
cargo publish --no-verify -p sync-lsp
cargo publish --no-verify -p tinymist-derive
cargo publish --no-verify -p tinymist-analysis
cargo publish --no-verify -p tinymist-std
cargo publish --no-verify -p tinymist-vfs
cargo publish --no-verify -p tinymist-world
cargo publish --no-verify -p tinymist-task
cargo publish --no-verify -p tinymist-project
cargo publish --no-verify -p typlite
cargo publish --no-verify -p crityp
cargo publish --no-verify -p typst-shim || true
cargo publish --no-verify -p tinymist-derive || true
cargo publish --no-verify -p tinymist-analysis || true
cargo publish --no-verify -p tinymist-std || true
cargo publish --no-verify -p tinymist-vfs || true
cargo publish --no-verify -p tinymist-world || true
cargo publish --no-verify -p tinymist-task || true
cargo publish --no-verify -p tinymist-project || true
cargo publish --no-verify -p typlite || true
cargo publish --no-verify -p crityp || true
- name: Verifies crate health (Optional)
run: |
cargo publish -p typst-shim
cargo publish -p sync-lsp
cargo publish -p tinymist-derive
cargo publish -p tinymist-analysis
cargo publish -p tinymist-std
cargo publish -p tinymist-vfs
cargo publish -p tinymist-world
cargo publish -p tinymist-task
cargo publish -p tinymist-project
cargo publish -p typlite
cargo publish -p crityp
cargo publish --dry-run -p typst-shim
cargo publish --dry-run -p tinymist-derive
cargo publish --dry-run -p tinymist-analysis
cargo publish --dry-run -p tinymist-std
cargo publish --dry-run -p tinymist-vfs
cargo publish --dry-run -p tinymist-world
cargo publish --dry-run -p tinymist-task
cargo publish --dry-run -p tinymist-project
cargo publish --dry-run -p typlite
cargo publish --dry-run -p crityp

536
Cargo.lock generated
View file

@ -595,6 +595,12 @@ dependencies = [
"unicode-width 0.1.14",
]
[[package]]
name = "codex"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "724d27a0ee38b700e5e164350e79aba601a0db673ac47fce1cb74c3e38864036"
[[package]]
name = "color_quant"
version = "1.1.0"
@ -735,7 +741,7 @@ dependencies = [
[[package]]
name = "crityp"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"base64",
@ -747,7 +753,7 @@ dependencies = [
"tinymist-project",
"tinymist-std",
"typst",
"typst-syntax",
"typst-syntax 0.13.0",
]
[[package]]
@ -1169,6 +1175,12 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
[[package]]
name = "fontconfig-parser"
version = "0.5.7"
@ -1428,6 +1440,9 @@ name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
dependencies = [
"foldhash",
]
[[package]]
name = "hashlink"
@ -1890,12 +1905,6 @@ dependencies = [
"serde",
]
[[package]]
name = "indexmap-nostd"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590"
[[package]]
name = "inotify"
version = "0.9.6"
@ -1991,6 +2000,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.14"
@ -2009,9 +2027,9 @@ dependencies = [
[[package]]
name = "kamadak-exif"
version = "0.5.5"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4fc70d0ab7e5b6bafa30216a6b48705ea964cdfc29c050f2412295eba58077"
checksum = "1130d80c7374efad55a117d715a3af9368f0fa7a2c54573afc15a188cd984837"
dependencies = [
"mutate_once",
]
@ -2277,17 +2295,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.98",
]
[[package]]
name = "num-integer"
version = "0.1.46"
@ -2851,9 +2858,9 @@ dependencies = [
[[package]]
name = "reflexo"
version = "0.5.4"
version = "0.5.5-rc3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b13fc37349d5c5bbf5d2ad365a55f2439d59deb78acb5578575b1d88cb8e66"
checksum = "52998674c1fcc34a81b730e4cfb370f84c1356a2ec445e288806594264b30487"
dependencies = [
"base64",
"bitvec",
@ -2861,10 +2868,8 @@ dependencies = [
"dashmap",
"ecow",
"fxhash",
"js-sys",
"parking_lot",
"path-clean",
"reflexo-typst-shim",
"rkyv",
"rustc-hash 2.1.1",
"serde",
@ -2873,15 +2878,16 @@ dependencies = [
"serde_with",
"siphasher",
"tiny-skia-path",
"wasm-bindgen",
"tinymist-std",
"typst",
"web-time",
]
[[package]]
name = "reflexo-typst"
version = "0.5.4"
version = "0.5.5-rc3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94fe8e18c1d82e428e598c4099af771e7b1b3cc56e58ae5cd450867d595f95f1"
checksum = "ea122a5ba883bfc3bfdbe8ea06e5f571383aa7459f78b420f770747b6b2467be"
dependencies = [
"codespan-reporting",
"comemo",
@ -2892,44 +2898,36 @@ dependencies = [
"js-sys",
"log",
"nohash-hasher",
"notify",
"parking_lot",
"pathdiff",
"rayon",
"reflexo",
"reflexo-typst2vec",
"reflexo-vfs",
"reflexo-world",
"reflexo-vec2svg",
"serde",
"serde_json",
"tar",
"tinymist-project",
"tinymist-task",
"tinymist-world",
"tokio",
"typst",
"typst-eval",
"web-sys",
]
[[package]]
name = "reflexo-typst-shim"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41e26fc8d9096f2ab25dabca6407544961172f1bd6b255668e5d3e91f2ded2c1"
dependencies = [
"cfg-if",
"typst",
"typst-syntax",
]
[[package]]
name = "reflexo-typst2vec"
version = "0.5.4"
version = "0.5.5-rc3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5f0f3aa5ce66a27c72a9baddeb0f46281d8e9ef6296bfd51cf7aec002c48e07"
checksum = "2fcc41da7110413ad6b5ddc37a6295e2146ab4ad7a8aad33f15d419b4667d2fa"
dependencies = [
"bitvec",
"comemo",
"crossbeam-queue",
"dashmap",
"flate2",
"image",
"log",
"parking_lot",
"rayon",
@ -2947,9 +2945,9 @@ dependencies = [
[[package]]
name = "reflexo-vec2svg"
version = "0.5.4"
version = "0.5.5-rc3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7dce08258ec590d103b4eb839a1ad7297274135b6d4d5cb36d178de9ef73ad8"
checksum = "cab6e537ac83993b221f4be0586dc6a17ef6885573d89de66e1c3f4a8f7f40db"
dependencies = [
"base64",
"comemo",
@ -2959,57 +2957,6 @@ dependencies = [
"typst",
]
[[package]]
name = "reflexo-vfs"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5513a7f75fc88d8cc4e151832f0596b0e925fa74aaf374351977df06c6ef6eb0"
dependencies = [
"indexmap 2.7.1",
"js-sys",
"log",
"nohash-hasher",
"parking_lot",
"reflexo",
"rpds",
"typst",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "reflexo-world"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e30d61064c8821db1ace4da82b6129f19560f203430f20159f4e42ae025c19"
dependencies = [
"chrono",
"codespan-reporting",
"comemo",
"dirs",
"ecow",
"flate2",
"fontdb",
"hex",
"js-sys",
"log",
"parking_lot",
"reflexo",
"reflexo-typst-shim",
"reflexo-vfs",
"reqwest",
"serde",
"serde-wasm-bindgen",
"serde_json",
"serde_with",
"sha2",
"strum",
"tar",
"typst",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "regex"
version = "1.11.1"
@ -3618,12 +3565,11 @@ dependencies = [
[[package]]
name = "string-interner"
version = "0.17.0"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c6a0d765f5807e98a091107bae0a56ea3799f66a5de47b2c84c94a39c09974e"
checksum = "1a3275464d7a9f2d4cac57c89c2ef96a8524dba2864c8d6f82e3980baf136f9b"
dependencies = [
"cfg-if",
"hashbrown 0.14.5",
"hashbrown 0.15.2",
"serde",
]
@ -3721,7 +3667,7 @@ dependencies = [
[[package]]
name = "sync-lsp"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"clap",
@ -3843,7 +3789,7 @@ dependencies = [
[[package]]
name = "tests"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"insta",
"lsp-server",
@ -3966,7 +3912,7 @@ dependencies = [
[[package]]
name = "tinymist"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"async-trait",
@ -4009,7 +3955,7 @@ dependencies = [
"serde_yaml",
"strum",
"sync-lsp",
"tinymist-assets 0.12.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tinymist-assets 0.12.20",
"tinymist-core",
"tinymist-project",
"tinymist-query",
@ -4023,6 +3969,7 @@ dependencies = [
"typlite",
"typst",
"typst-ansi-hl",
"typst-html",
"typst-pdf",
"typst-preview",
"typst-render",
@ -4038,7 +3985,7 @@ dependencies = [
[[package]]
name = "tinymist-analysis"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"ecow",
"insta",
@ -4050,19 +3997,19 @@ dependencies = [
"typst",
]
[[package]]
name = "tinymist-assets"
version = "0.12.20"
[[package]]
name = "tinymist-assets"
version = "0.12.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f73b4b64dfed7f28335992d79570ea1dd8828c921883284cf5d9f415f726986a"
[[package]]
name = "tinymist-assets"
version = "0.12.21"
[[package]]
name = "tinymist-core"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"cargo_metadata",
@ -4074,7 +4021,7 @@ dependencies = [
[[package]]
name = "tinymist-derive"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"quote",
"syn 2.0.98",
@ -4082,7 +4029,7 @@ dependencies = [
[[package]]
name = "tinymist-project"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"chrono",
@ -4107,12 +4054,11 @@ dependencies = [
"toml",
"typst",
"typst-assets",
"typst-preview",
]
[[package]]
name = "tinymist-query"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"base64",
@ -4166,7 +4112,7 @@ dependencies = [
[[package]]
name = "tinymist-render"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"base64",
"log",
@ -4179,7 +4125,7 @@ dependencies = [
[[package]]
name = "tinymist-std"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"base64",
@ -4215,7 +4161,7 @@ dependencies = [
[[package]]
name = "tinymist-task"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"chrono",
@ -4240,6 +4186,8 @@ dependencies = [
"toml",
"typst",
"typst-assets",
"typst-eval",
"typst-html",
"typst-pdf",
"typst-render",
"typst-shim",
@ -4248,7 +4196,7 @@ dependencies = [
[[package]]
name = "tinymist-vfs"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"comemo",
"ecow",
@ -4266,7 +4214,7 @@ dependencies = [
[[package]]
name = "tinymist-world"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"anyhow",
"chrono",
@ -4555,7 +4503,7 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "typlite"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"base64",
"clap",
@ -4568,75 +4516,25 @@ dependencies = [
"tinymist-std",
"typst",
"typst-svg",
"typst-syntax",
"typst-syntax 0.13.0",
]
[[package]]
name = "typst"
version = "0.12.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"arrayvec 0.7.6",
"az",
"bitflags 2.8.0",
"bumpalo",
"chinese-number",
"ciborium",
"comemo",
"csv",
"ecow",
"flate2",
"fontdb",
"hayagriva",
"hypher",
"icu_properties",
"icu_provider",
"icu_provider_adapters",
"icu_provider_blob",
"icu_segmenter",
"if_chain",
"image",
"indexmap 2.7.1",
"kamadak-exif",
"kurbo",
"lipsum",
"log",
"once_cell",
"palette",
"phf",
"png",
"portable-atomic",
"qcms",
"rayon",
"regex",
"roxmltree",
"rust_decimal",
"rustybuzz",
"serde",
"serde_json",
"serde_yaml",
"siphasher",
"smallvec",
"stacker",
"syntect",
"time",
"toml",
"ttf-parser",
"two-face",
"typed-arena",
"typst-assets",
"typst-eval",
"typst-html",
"typst-layout",
"typst-library",
"typst-macros",
"typst-syntax",
"typst-realize",
"typst-syntax 0.13.0",
"typst-timing",
"typst-utils",
"unicode-bidi",
"unicode-math-class",
"unicode-script",
"unicode-segmentation",
"unscanny",
"usvg",
"wasmi",
"xmlwriter",
"typst-utils 0.13.0",
]
[[package]]
@ -4650,19 +4548,142 @@ dependencies = [
"termcolor",
"thiserror 1.0.69",
"two-face",
"typst-syntax",
"typst-syntax 0.12.0",
]
[[package]]
name = "typst-assets"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fe00da1b24da2c4a7da532fc33d0c3bd43a902ca4c408ee2c36eabe70f2f4ba"
source = "git+https://github.com/typst/typst-assets?rev=8cccef9#8cccef93b5da73a1c80389722cf2b655b624f577"
[[package]]
name = "typst-eval"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"comemo",
"ecow",
"if_chain",
"indexmap 2.7.1",
"stacker",
"toml",
"typst-library",
"typst-macros",
"typst-syntax 0.13.0",
"typst-timing",
"typst-utils 0.13.0",
"unicode-segmentation",
]
[[package]]
name = "typst-html"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"comemo",
"ecow",
"typst-library",
"typst-macros",
"typst-svg",
"typst-syntax 0.13.0",
"typst-timing",
"typst-utils 0.13.0",
]
[[package]]
name = "typst-layout"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"az",
"bumpalo",
"comemo",
"ecow",
"hypher",
"icu_properties",
"icu_provider",
"icu_provider_adapters",
"icu_provider_blob",
"icu_segmenter",
"kurbo",
"rustybuzz",
"smallvec",
"ttf-parser",
"typst-assets",
"typst-library",
"typst-macros",
"typst-syntax 0.13.0",
"typst-timing",
"typst-utils 0.13.0",
"unicode-bidi",
"unicode-math-class",
"unicode-script",
"unicode-segmentation",
]
[[package]]
name = "typst-library"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"az",
"bitflags 2.8.0",
"bumpalo",
"chinese-number",
"ciborium",
"codex",
"comemo",
"csv",
"ecow",
"flate2",
"fontdb",
"hayagriva",
"icu_properties",
"icu_provider",
"icu_provider_blob",
"image",
"indexmap 2.7.1",
"kamadak-exif",
"kurbo",
"lipsum",
"palette",
"phf",
"png",
"qcms",
"rayon",
"regex",
"regex-syntax",
"roxmltree",
"rust_decimal",
"rustybuzz",
"serde",
"serde_json",
"serde_yaml",
"siphasher",
"smallvec",
"syntect",
"time",
"toml",
"ttf-parser",
"two-face",
"typed-arena",
"typst-assets",
"typst-macros",
"typst-syntax 0.13.0",
"typst-timing",
"typst-utils 0.13.0",
"unicode-math-class",
"unicode-segmentation",
"unscanny",
"usvg",
"wasmi",
"xmlwriter",
]
[[package]]
name = "typst-macros"
version = "0.12.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"heck",
"proc-macro2",
@ -4672,8 +4693,8 @@ dependencies = [
[[package]]
name = "typst-pdf"
version = "0.12.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"arrayvec 0.7.6",
"base64",
@ -4683,23 +4704,23 @@ dependencies = [
"image",
"indexmap 2.7.1",
"miniz_oxide",
"once_cell",
"pdf-writer",
"serde",
"subsetter",
"svg2pdf",
"ttf-parser",
"typst",
"typst-assets",
"typst-library",
"typst-macros",
"typst-syntax 0.13.0",
"typst-timing",
"unscanny",
"typst-utils 0.13.0",
"xmp-writer",
]
[[package]]
name = "typst-preview"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"clap",
"comemo",
@ -4713,55 +4734,73 @@ dependencies = [
"reflexo-vec2svg",
"serde",
"serde_json",
"tinymist-assets 0.12.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tinymist-assets 0.12.20",
"tinymist-std",
"tokio",
"typst",
"typst-assets",
]
[[package]]
name = "typst-realize"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"arrayvec 0.7.6",
"bumpalo",
"comemo",
"ecow",
"regex",
"typst-library",
"typst-macros",
"typst-syntax 0.13.0",
"typst-timing",
"typst-utils 0.13.0",
]
[[package]]
name = "typst-render"
version = "0.12.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"bytemuck",
"comemo",
"image",
"pixglyph",
"resvg",
"roxmltree",
"tiny-skia",
"ttf-parser",
"typst",
"typst-library",
"typst-macros",
"typst-timing",
"usvg",
]
[[package]]
name = "typst-shim"
version = "0.12.20"
version = "0.12.21"
dependencies = [
"cfg-if",
"comemo",
"typst",
"typst-syntax",
"typst-eval",
"typst-syntax 0.13.0",
]
[[package]]
name = "typst-svg"
version = "0.12.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"base64",
"comemo",
"ecow",
"flate2",
"image",
"ttf-parser",
"typst",
"typst-library",
"typst-macros",
"typst-timing",
"typst-utils 0.13.0",
"xmlparser",
"xmlwriter",
]
@ -4769,13 +4808,31 @@ dependencies = [
[[package]]
name = "typst-syntax"
version = "0.12.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b7be8b6ed6b2cb39ca495947d548a28d7db0ba244008e44c5a759120327693"
dependencies = [
"ecow",
"once_cell",
"serde",
"toml",
"typst-utils",
"typst-utils 0.12.0",
"unicode-ident",
"unicode-math-class",
"unicode-script",
"unicode-segmentation",
"unscanny",
]
[[package]]
name = "typst-syntax"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"ecow",
"serde",
"toml",
"typst-timing",
"typst-utils 0.13.0",
"unicode-ident",
"unicode-math-class",
"unicode-script",
@ -4785,19 +4842,19 @@ dependencies = [
[[package]]
name = "typst-timing"
version = "0.12.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"parking_lot",
"serde",
"serde_json",
"typst-syntax",
]
[[package]]
name = "typst-utils"
version = "0.12.0"
source = "git+https://github.com/Myriad-Dreamin/typst.git?tag=tinymist-v0.12.0#58426a90a7ef721738a01be09793d33e55eb75a9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f0305443ed97f0b658471487228f86bf835705e7525fbdcc671cebd864f7a40"
dependencies = [
"once_cell",
"portable-atomic",
@ -4806,6 +4863,19 @@ dependencies = [
"thin-vec",
]
[[package]]
name = "typst-utils"
version = "0.13.0"
source = "git+https://github.com/ParaN3xus/typst.git?tag=tinymist-nightly-v0.12.21-content-hint#bba9db89a228e7fe1e6f9e6f2ff531f92a1a4856"
dependencies = [
"once_cell",
"portable-atomic",
"rayon",
"siphasher",
"thin-vec",
"unicode-math-class",
]
[[package]]
name = "typstfmt"
version = "0.12.1"
@ -4819,21 +4889,20 @@ dependencies = [
"serde",
"toml",
"tracing",
"typst-syntax",
"typst-syntax 0.12.0",
"unicode-width 0.2.0",
]
[[package]]
name = "typstyle-core"
version = "0.12.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e221e78ecf6aedf3fc0efc883cace3dce79b4b1416caedce06409ba866b4dcd"
source = "git+https://github.com/ParaN3xus/typstyle/?tag=tinymist-nightly-v0.12.21-rc1#37529defcada013bb4c8342c70968daff8097f24"
dependencies = [
"ecow",
"itertools 0.13.0",
"itertools 0.14.0",
"pretty",
"rustc-hash 2.1.1",
"typst-syntax",
"typst-syntax 0.13.0",
]
[[package]]
@ -5142,51 +5211,56 @@ dependencies = [
[[package]]
name = "wasmi"
version = "0.35.0"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbaac6e702fa7b52258e5ac90d6e20a40afb37a1fbe7c645d0903ee42c5f85f4"
checksum = "a19af97fcb96045dd1d6b4d23e2b4abdbbe81723dbc5c9f016eb52145b320063"
dependencies = [
"arrayvec 0.7.6",
"multi-stash",
"num-derive",
"num-traits",
"smallvec",
"spin",
"wasmi_collections",
"wasmi_core",
"wasmparser-nostd",
"wasmi_ir",
"wasmparser",
]
[[package]]
name = "wasmi_collections"
version = "0.35.0"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ff59e30e550a509cc689ec638e5042be4d78ec9f6dd8a71fd02ee28776a74fd"
checksum = "e80d6b275b1c922021939d561574bf376613493ae2b61c6963b15db0e8813562"
dependencies = [
"ahash 0.8.11",
"hashbrown 0.14.5",
"string-interner",
]
[[package]]
name = "wasmi_core"
version = "0.35.0"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13e10c674add0f92f47bf8ad57c55ee3ac1762a0d9baf07535e27e22b758a916"
checksum = "3a8c51482cc32d31c2c7ff211cd2bedd73c5bd057ba16a2ed0110e7a96097c33"
dependencies = [
"downcast-rs",
"libm",
"num-traits",
"paste",
]
[[package]]
name = "wasmparser-nostd"
version = "0.100.2"
name = "wasmi_ir"
version = "0.40.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5a015fe95f3504a94bb1462c717aae75253e39b9dd6c3fb1062c934535c64aa"
checksum = "6e431a14c186db59212a88516788bd68ed51f87aa1e08d1df742522867b5289a"
dependencies = [
"indexmap-nostd",
"wasmi_core",
]
[[package]]
name = "wasmparser"
version = "0.221.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d06bfa36ab3ac2be0dee563380147a5b81ba10dd8885d7fbbc9eb574be67d185"
dependencies = [
"bitflags 2.8.0",
"indexmap 2.7.1",
]
[[package]]

View file

@ -1,7 +1,7 @@
[workspace.package]
description = "An integrated language service for Typst."
authors = ["Myriad-Dreamin <camiyoru@gmail.com>", "Nathan Varner"]
version = "0.12.20"
version = "0.12.21"
edition = "2021"
readme = "README.md"
license = "Apache-2.0"
@ -32,11 +32,7 @@ triomphe = { version = "0.1.10", default-features = false, features = ["std"] }
async-trait = "0.1.77"
futures = "0.3"
rayon = "1.10.0"
tokio = { version = "1.42.0", features = [
"macros",
"rt-multi-thread",
"io-std",
] }
tokio = { version = "1.42.0", features = ["macros"] }
tokio-util = { version = "0.7.13", features = ["compat"] }
# System
@ -129,26 +125,26 @@ env_logger = "0.11.3"
log = "0.4"
# Typst
reflexo = { version = "=0.5.4", default-features = false, features = [
reflexo = { version = "=0.5.5-rc3", default-features = false, features = [
"flat-vector",
] }
reflexo-typst = { version = "=0.5.4", default-features = false }
reflexo-vec2svg = { version = "=0.5.4" }
reflexo-typst-shim = { version = "=0.5.4", features = ["nightly"] }
reflexo-typst = { version = "=0.5.5-rc3", default-features = false }
reflexo-vec2svg = { version = "=0.5.5-rc3" }
typst = "0.12.0"
typst-timing = "0.12.0"
typst-svg = "0.12.0"
typst-render = "0.12.0"
typst-pdf = "0.12.0"
typst-syntax = "0.12.0"
typst = "0.13.0-rc1"
typst-html = "0.13.0-rc1"
typst-timing = "0.13.0-rc1"
typst-svg = "0.13.0-rc1"
typst-render = "0.13.0-rc1"
typst-pdf = "0.13.0-rc1"
typst-syntax = "0.13.0-rc1"
typst-eval = "0.13.0-rc1"
typst-assets = "0.12.0"
typstfmt = { git = "https://github.com/Myriad-Dreamin/typstfmt", tag = "v0.12.1" }
typst-ansi-hl = "0.3.0"
typstyle-core = { version = "=0.12.15", default-features = false }
typlite = { path = "./crates/typlite" }
typst-shim = { path = "./crates/typst-shim" }
# LSP
crossbeam-channel = "0.5.12"
@ -178,19 +174,20 @@ insta = { version = "1.39", features = ["glob"] }
# Our Own Crates
typst-preview = { path = "./crates/typst-preview" }
typst-preview = { path = "./crates/typst-preview", version = "0.12.21" }
typst-shim = { path = "./crates/typst-shim", version = "0.12.21" }
tinymist-assets = { version = "=0.12.20" }
tinymist = { path = "./crates/tinymist/" }
tinymist-std = { path = "./crates/tinymist-std/", default-features = false }
tinymist-vfs = { path = "./crates/tinymist-vfs/", default-features = false }
tinymist-core = { path = "./crates/tinymist-core/", default-features = false }
tinymist-world = { path = "./crates/tinymist-world/", default-features = false }
tinymist-project = { path = "./crates/tinymist-project/" }
tinymist-task = { path = "./crates/tinymist-task/" }
tinymist-derive = { path = "./crates/tinymist-derive/" }
tinymist-analysis = { path = "./crates/tinymist-analysis/" }
tinymist-query = { path = "./crates/tinymist-query/" }
tinymist-render = { path = "./crates/tinymist-render/" }
tinymist = { path = "./crates/tinymist/", version = "0.12.21" }
tinymist-std = { path = "./crates/tinymist-std/", version = "0.12.21", default-features = false }
tinymist-vfs = { path = "./crates/tinymist-vfs/", version = "0.12.21", default-features = false }
tinymist-core = { path = "./crates/tinymist-core/", version = "0.12.21", default-features = false }
tinymist-world = { path = "./crates/tinymist-world/", version = "0.12.21", default-features = false }
tinymist-project = { path = "./crates/tinymist-project/", version = "0.12.21" }
tinymist-task = { path = "./crates/tinymist-task/", version = "0.12.21" }
tinymist-derive = { path = "./crates/tinymist-derive/", version = "0.12.21" }
tinymist-analysis = { path = "./crates/tinymist-analysis/", version = "0.12.21" }
tinymist-query = { path = "./crates/tinymist-query/", version = "0.12.21" }
tinymist-render = { path = "./crates/tinymist-render/", version = "0.12.21" }
[profile.dev.package.insta]
opt-level = 3
@ -257,12 +254,15 @@ extend-exclude = ["/.git", "fixtures"]
# These patches use a different version of `typst`, which only exports some private functions and information for code analysis.
#
# A regular build MUST use `tag` or `rev` to specify the version of the patched crate to ensure stability.
typst = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" }
typst-timing = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" }
typst-svg = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" }
typst-render = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" }
typst-pdf = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" }
typst-syntax = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tinymist-v0.12.0" }
typst = { git = "https://github.com/ParaN3xus/typst.git", tag = "tinymist-nightly-v0.12.21-content-hint" }
typst-html = { git = "https://github.com/ParaN3xus/typst.git", tag = "tinymist-nightly-v0.12.21-content-hint" }
typst-timing = { git = "https://github.com/ParaN3xus/typst.git", tag = "tinymist-nightly-v0.12.21-content-hint" }
typst-svg = { git = "https://github.com/ParaN3xus/typst.git", tag = "tinymist-nightly-v0.12.21-content-hint" }
typst-render = { git = "https://github.com/ParaN3xus/typst.git", tag = "tinymist-nightly-v0.12.21-content-hint" }
typst-pdf = { git = "https://github.com/ParaN3xus/typst.git", tag = "tinymist-nightly-v0.12.21-content-hint" }
typst-syntax = { git = "https://github.com/ParaN3xus/typst.git", tag = "tinymist-nightly-v0.12.21-content-hint" }
typst-eval = { git = "https://github.com/ParaN3xus/typst.git", tag = "tinymist-nightly-v0.12.21-content-hint" }
typst-assets = { git = "https://github.com/typst/typst-assets", rev = "8cccef9" }
# These patches use local `typst` for development.
# typst = { path = "../typst/crates/typst" }
@ -275,16 +275,29 @@ typst-syntax = { git = "https://github.com/Myriad-Dreamin/typst.git", tag = "tin
# These patches use a different version of `reflexo`.
#
# A regular build MUST use `tag` or `rev` to specify the version of the patched crate to ensure stability.
# reflexo = { git = "https://github.com/Myriad-Dreamin/typst.ts/", rev = "1b6e29c650ad6d3095e5ea18d93a2428c1ae77b9" }
# reflexo-typst = { git = "https://github.com/Myriad-Dreamin/typst.ts/", rev = "1b6e29c650ad6d3095e5ea18d93a2428c1ae77b9" }
# reflexo-typst2vec = { git = "https://github.com/Myriad-Dreamin/typst.ts/", rev = "1b6e29c650ad6d3095e5ea18d93a2428c1ae77b9" }
# reflexo-vec2svg = { git = "https://github.com/Myriad-Dreamin/typst.ts/", rev = "1b6e29c650ad6d3095e5ea18d93a2428c1ae77b9" }
# reflexo-typst-shim = { git = "https://github.com/Myriad-Dreamin/typst.ts/", rev = "1b6e29c650ad6d3095e5ea18d93a2428c1ae77b9" }
# reflexo = { git = "https://github.com/Myriad-Dreamin/typst.ts/", tag = "v0.5.5-rc3" }
# reflexo-typst = { git = "https://github.com/Myriad-Dreamin/typst.ts/", tag = "v0.5.5-rc3" }
# reflexo-vec2svg = { git = "https://github.com/Myriad-Dreamin/typst.ts/", tag = "v0.5.5-rc3" }
# These patches use local `reflexo` for development.
# reflexo = { path = "../typst.ts/crates/reflexo/" }
# reflexo-typst = { path = "../typst.ts/crates/reflexo-typst/" }
# reflexo-typst2vec = { path = "../typst.ts/crates/conversion/typst2vec/" }
# reflexo-vec2svg = { path = "../typst.ts/crates/conversion/vec2svg/" }
# reflexo-typst-shim = { path = "../typst.ts/crates/reflexo-typst-shim/" }
# typstyle = { path = "../typstyle" }
typstyle-core = { git = "https://github.com/ParaN3xus/typstyle/", tag = "tinymist-nightly-v0.12.21-rc1" }
typst-shim = { path = "crates/typst-shim" }
tinymist-analysis = { path = "crates/tinymist-analysis" }
tinymist-std = { path = "crates/tinymist-std" }
tinymist-vfs = { path = "crates/tinymist-vfs" }
tinymist-world = { path = "crates/tinymist-world" }
tinymist-project = { path = "crates/tinymist-project" }
tinymist-task = { path = "crates/tinymist-task" }
# If reflexo use the tinymist from git, you should use the following patch.
# [patch."https://github.com/Myriad-Dreamin/tinymist.git"]
# typst-shim = { path = "crates/typst-shim" }
# tinymist-analysis = { path = "crates/tinymist-analysis" }
# tinymist-std = { path = "crates/tinymist-std" }
# tinymist-world = { path = "crates/tinymist-world" }
# tinymist-project = { path = "crates/tinymist-project" }
# tinymist-task = { path = "crates/tinymist-task" }

View file

@ -30,7 +30,7 @@ criterion = "0.5.1"
comemo.workspace = true
ecow.workspace = true
tinymist-std.workspace = true
tinymist-project = { workspace = true, features = ["system"] }
tinymist-project = { workspace = true, features = ["lsp"] }
typst.workspace = true
typst-syntax.workspace = true

View file

@ -40,12 +40,12 @@ pub fn bench(c: &mut Criterion, world: &mut LspWorld) -> anyhow::Result<()> {
// Collects all benchmarks.
let mut goals: Vec<(EcoString, &Func)> = vec![];
for (name, value, _) in module.scope().iter() {
for (name, bind) in module.scope().iter() {
if !name.starts_with("bench") {
continue;
}
if let Value::Func(func) = value {
if let Value::Func(func) = bind.read() {
goals.push((eco_format!("{main_path}@{name}"), func));
}
}
@ -55,6 +55,7 @@ pub fn bench(c: &mut Criterion, world: &mut LspWorld) -> anyhow::Result<()> {
let route = Route::default();
let mut sink = Sink::default();
let engine = &mut Engine {
routines: &typst::ROUTINES,
world: ((world) as &dyn World).track(),
introspector: introspector.track(),
traced: traced.track(),

View file

@ -0,0 +1,6 @@
# sync-lsp
Sync LSP server inspired by async-lsp, primarily for tinymist. The author of this crate thinks that async-lsp is better than sync-lsp, so please use async-lsp whenever possible unless you have a good reason to use sync-lsp. Some random points:
- The `req_queue` and `transport` are extracted from the rust-analyzer project.
- The sync-lsp should have better performance on stdio transport than async-lsp, especially on windows, but the author have forgotten the idea.

View file

@ -0,0 +1,3 @@
# tinymist-analysis
Typst Static Analyzers for Tinymist.

View file

@ -325,7 +325,7 @@ pub fn interpret_mode_at(mut leaf: Option<&LinkedNode>) -> InterpretMode {
pub(crate) fn interpret_mode_at_kind(kind: SyntaxKind) -> Option<InterpretMode> {
use SyntaxKind::*;
Some(match kind {
LineComment | BlockComment => InterpretMode::Comment,
LineComment | BlockComment | Shebang => InterpretMode::Comment,
Raw => InterpretMode::Raw,
Str => InterpretMode::String,
CodeBlock | Code => InterpretMode::Code,
@ -342,7 +342,7 @@ pub(crate) fn interpret_mode_at_kind(kind: SyntaxKind) -> Option<InterpretMode>
Strong | Emph | Link | Ref | RefMarker | Heading | HeadingMarker | ListItem
| ListMarker | EnumItem | EnumMarker | TermItem | TermMarker => InterpretMode::Markup,
MathIdent | MathAlignPoint | MathDelimited | MathAttach | MathPrimes | MathFrac
| MathRoot | MathShorthand => InterpretMode::Math,
| MathRoot | MathShorthand | MathText => InterpretMode::Math,
Let | Set | Show | Context | If | Else | For | In | While | Break | Continue | Return
| Import | Include | Closure | Params | LetBinding | SetRule | ShowRule | Contextual
| Conditional | WhileLoop | ForLoop | LoopBreak | ModuleImport | ImportItems
@ -727,8 +727,10 @@ pub fn classify_syntax(node: LinkedNode, cursor: usize) -> Option<SyntaxClass<'_
if node.offset() + 1 == cursor && {
// Check if the cursor is exactly after single dot.
matches!(node.kind(), SyntaxKind::Dot)
|| (matches!(node.kind(), SyntaxKind::Text | SyntaxKind::Error)
&& node.text().starts_with("."))
|| (matches!(
node.kind(),
SyntaxKind::Text | SyntaxKind::MathText | SyntaxKind::Error
) && node.text().starts_with("."))
} {
if let Some(dot_access) = classify_dot_access(&node) {
return Some(dot_access);

View file

@ -1,6 +1,6 @@
{
"name": "tinymist-web",
"version": "0.12.20",
"version": "0.12.21",
"description": "WASM module for running tinymist analyzers in JavaScript environment.",
"author": "Myriad-Dreamin",
"license": "Apache-2.0",

View file

@ -0,0 +1,3 @@
# tinymist-derive
Provides derive for tinymist.

View file

@ -34,16 +34,13 @@ tinymist-derive.workspace = true
toml.workspace = true
typst.workspace = true
typst-assets.workspace = true
typst-preview = { workspace = true, optional = true }
notify.workspace = true
[features]
default = ["system"]
fonts = ["typst-assets/fonts"]
no-content-hint = ["tinymist-task/no-content-hint"]
# no-content-hint = ["reflexo-typst/no-content-hint"]
preview = ["typst-preview"]
lsp = ["system"]
system = ["tinymist-std/system", "tinymist-world/system"]

View file

@ -0,0 +1,3 @@
# tinymist-project
Project model of typst for tinymist.

View file

@ -5,9 +5,6 @@ use tinymist_std::{bail, error::prelude::Result};
pub use tinymist_world::args::{CompileFontArgs, CompilePackageArgs};
#[cfg(feature = "preview")]
pub use typst_preview::{PreviewArgs, PreviewMode};
use crate::model::*;
use crate::PROJECT_ROUTE_USER_ACTION_PRIORITY;
@ -21,15 +18,6 @@ pub enum DocCommands {
Configure(DocConfigureArgs),
}
/// Project task commands.
#[derive(Debug, Clone, clap::Subcommand)]
#[clap(rename_all = "kebab-case")]
pub enum TaskCommands {
/// Declare a preview task.
#[cfg(feature = "preview")]
Preview(TaskPreviewArgs),
}
/// Declare a document (project's input).
#[derive(Debug, Clone, clap::Parser)]
pub struct DocNewArgs {
@ -246,28 +234,3 @@ impl TaskCompileArgs {
})
}
}
/// Declare an lsp task.
#[derive(Debug, Clone, clap::Parser)]
#[cfg(feature = "preview")]
pub struct TaskPreviewArgs {
/// Argument to identify a project.
#[clap(flatten)]
pub declare: DocNewArgs,
/// Name a task.
#[clap(long = "task")]
pub name: Option<String>,
/// When to run the task
#[arg(long = "when")]
pub when: Option<TaskWhen>,
/// Preview arguments
#[clap(flatten)]
pub preview: PreviewArgs,
/// Preview mode
#[clap(long = "preview-mode", default_value = "document", value_name = "MODE")]
pub preview_mode: PreviewMode,
}

View file

@ -1,12 +1,14 @@
//! Project compiler for tinymist.
use core::fmt;
use std::any::TypeId;
use std::collections::HashSet;
use std::path::Path;
use std::sync::{Arc, OnceLock};
use ecow::{eco_vec, EcoVec};
use tinymist_std::error::prelude::Result;
use tinymist_std::typst::{TypstHtmlDocument, TypstPagedDocument};
use tinymist_std::{typst::TypstDocument, ImmutPath};
use tinymist_world::vfs::notify::{
FilesystemEvent, MemoryEvent, NotifyDeps, NotifyMessage, UpstreamUpdateEvent,
@ -14,19 +16,11 @@ use tinymist_world::vfs::notify::{
use tinymist_world::vfs::{FileId, FsProvider, RevisingVfs, WorkspaceResolver};
use tinymist_world::{
CompileSnapshot, CompilerFeat, CompilerUniverse, EntryReader, EntryState, ExportSignal,
ProjectInsId, TaskInputs, WorldDeps,
ProjectInsId, TaskInputs, WorldComputeGraph, WorldDeps,
};
use tokio::sync::mpsc;
use typst::diag::{SourceDiagnostic, SourceResult, Warned};
use crate::LspCompilerFeat;
/// LSP compile snapshot.
pub type LspCompileSnapshot = CompileSnapshot<LspCompilerFeat>;
/// LSP compiled artifact.
pub type LspCompiledArtifact = CompiledArtifact<LspCompilerFeat>;
/// LSP interrupt.
pub type LspInterrupt = Interrupt<LspCompilerFeat>;
/// A compiled artifact.
pub struct CompiledArtifact<F: CompilerFeat> {
/// The used snapshot.
@ -39,7 +33,7 @@ pub struct CompiledArtifact<F: CompilerFeat> {
pub deps: OnceLock<EcoVec<FileId>>,
}
impl fmt::Display for CompiledArtifact<LspCompilerFeat> {
impl<F: CompilerFeat> fmt::Display for CompiledArtifact<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let rev = self.world.revision();
write!(f, "CompiledArtifact({:?}, rev={rev:?})", self.id)
@ -88,12 +82,49 @@ impl<F: CompilerFeat> CompiledArtifact<F> {
}
/// Runs the compiler and returns the compiled document.
pub fn from_snapshot(mut snap: CompileSnapshot<F>) -> CompiledArtifact<F> {
pub fn from_snapshot(snap: CompileSnapshot<F>) -> CompiledArtifact<F> {
let is_html = snap.world.library.features.is_enabled(typst::Feature::Html);
if is_html {
Self::from_snapshot_inner::<TypstHtmlDocument>(snap)
} else {
Self::from_snapshot_inner::<TypstPagedDocument>(snap)
}
}
/// Runs the compiler and returns the compiled document.
fn from_snapshot_inner<D>(mut snap: CompileSnapshot<F>) -> CompiledArtifact<F>
where
D: typst::Document + 'static,
Arc<D>: Into<TypstDocument>,
{
snap.world.set_is_compiling(true);
let res = ::typst::compile(&snap.world);
let res = ::typst::compile::<D>(&snap.world);
snap.world.set_is_compiling(false);
Self::from_snapshot_result(
snap,
Warned {
output: res.output.map(Arc::new),
warnings: res.warnings,
},
)
}
/// Runs the compiler and returns the compiled document.
pub fn from_snapshot_result<D>(
snap: CompileSnapshot<F>,
res: Warned<SourceResult<Arc<D>>>,
) -> CompiledArtifact<F>
where
D: typst::Document + 'static,
Arc<D>: Into<TypstDocument>,
{
let is_html_compilation = TypeId::of::<D>() == TypeId::of::<TypstHtmlDocument>();
let warned = match res.output {
Ok(doc) => Ok(Warned {
output: Arc::new(doc),
output: doc,
warnings: res.warnings,
}),
Err(diags) => match (res.warnings.is_empty(), diags.is_empty()) {
@ -107,15 +138,27 @@ impl<F: CompilerFeat> CompiledArtifact<F> {
}
},
};
snap.world.set_is_compiling(false);
let (doc, warnings) = match warned {
Ok(doc) => (Ok(TypstDocument::Paged(doc.output)), doc.warnings),
Ok(doc) => (Ok(doc.output.into()), doc.warnings),
Err(err) => (Err(err), EcoVec::default()),
};
let exclude_html_warnings = if !is_html_compilation {
warnings
} else if warnings.len() == 1
&& warnings[0]
.message
.starts_with("html export is under active development")
{
EcoVec::new()
} else {
warnings
};
CompiledArtifact {
snap,
doc,
warnings,
warnings: exclude_html_warnings,
deps: OnceLock::default(),
}
}
@ -244,7 +287,7 @@ pub enum Interrupt<F: CompilerFeat> {
Fs(FilesystemEvent),
}
impl fmt::Debug for Interrupt<LspCompilerFeat> {
impl<F: CompilerFeat> fmt::Debug for Interrupt<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Interrupt::Compile(id) => write!(f, "Compile({id:?})"),
@ -454,19 +497,31 @@ impl<F: CompilerFeat + Send + Sync + 'static, Ext: Default + 'static> ProjectCom
dedicates.iter_mut().find(|e| e.id == *id).unwrap()
}
/// Clear all dedicate projects.
pub fn clear_dedicates(&mut self) {
self.dedicates.clear();
}
/// Restart a dedicate project.
pub fn restart_dedicate(&mut self, group: &str, entry: EntryState) -> Result<ProjectInsId> {
pub fn restart_dedicate(
&mut self,
group: &str,
entry: EntryState,
enable_html: bool,
) -> Result<ProjectInsId> {
let id = ProjectInsId(group.into());
let verse = CompilerUniverse::<F>::new_raw(
entry,
enable_html,
Some(self.primary.verse.inputs().clone()),
self.primary.verse.vfs().fork(),
self.primary.verse.registry.clone(),
self.primary.verse.font_resolver.clone(),
);
let proj = Self::create_project(id.clone(), verse, self.handler.clone());
let mut proj = Self::create_project(id.clone(), verse, self.handler.clone());
proj.reason.see(reason_by_entry_change());
self.remove_dedicates(&id);
self.dedicates.push(proj);
@ -761,6 +816,26 @@ impl<F: CompilerFeat, Ext: 'static> ProjectInsState<F, Ext> {
}
}
/// Compile the document once if there is any reason and the entry is
/// active. (this is used for experimenting typst.node compilations)
#[must_use]
pub fn may_compile2(
&mut self,
compute: impl FnOnce(&Arc<WorldComputeGraph<F>>),
) -> Option<impl FnOnce() -> Arc<WorldComputeGraph<F>>> {
if !self.reason.any() || self.verse.entry_state().is_inactive() {
return None;
}
let snap = self.snapshot();
self.reason = Default::default();
Some(move || {
let compiled = WorldComputeGraph::new(snap);
compute(&compiled);
compiled
})
}
/// Compile the document once if there is any reason and the entry is
/// active.
#[must_use]

View file

@ -3,19 +3,34 @@
mod args;
mod compiler;
mod entry;
pub mod font;
mod lock;
mod model;
#[cfg(feature = "lsp")]
pub mod font;
#[cfg(feature = "lsp")]
mod lock;
#[cfg(feature = "lsp")]
mod lsp;
#[cfg(feature = "system")]
mod watch;
#[cfg(feature = "system")]
pub mod world;
pub use args::*;
pub use compiler::*;
pub use entry::*;
pub use lock::*;
pub use model::*;
#[cfg(feature = "lsp")]
pub use lock::*;
#[cfg(feature = "lsp")]
pub use lsp::*;
#[cfg(feature = "system")]
pub use watch::*;
#[cfg(feature = "system")]
pub use world::*;
pub use tinymist_world::{CompileSnapshot, ExportSignal, ProjectInsId};
/// The default project route priority assigned to user actions.
pub const PROJECT_ROUTE_USER_ACTION_PRIORITY: u32 = 256;

View file

@ -16,8 +16,6 @@ use crate::{LockFile, LockFileCompat, LspWorld, ProjectPathMaterial, LOCK_VERSIO
pub const LOCK_FILENAME: &str = "tinymist.lock";
pub const PROJECT_ROUTE_USER_ACTION_PRIORITY: u32 = 256;
impl LockFile {
pub fn get_document(&self, id: &Id) -> Option<&ProjectInput> {
self.document.iter().find(|i| &i.id == id)

View file

@ -0,0 +1,260 @@
use std::path::Path;
use std::{borrow::Cow, sync::Arc};
use tinymist_std::error::prelude::*;
use tinymist_std::{bail, ImmutPath};
use tinymist_task::ExportTarget;
use tinymist_world::args::*;
use tinymist_world::config::CompileFontOpts;
use tinymist_world::font::system::SystemFontSearcher;
use tinymist_world::package::{http::HttpRegistry, RegistryPathMapper};
use tinymist_world::vfs::{system::SystemAccessModel, Vfs};
use tinymist_world::{
CompileSnapshot, CompilerFeat, CompilerUniverse, CompilerWorld, EntryOpts, EntryState,
};
use typst::foundations::{Dict, Str, Value};
use typst::utils::LazyHash;
use crate::ProjectInput;
use crate::font::TinymistFontResolver;
use crate::{CompiledArtifact, Interrupt};
/// Compiler feature for LSP universe and worlds without typst.ts to implement
/// more for tinymist. type trait of [`CompilerUniverse`].
#[derive(Debug, Clone, Copy)]
pub struct LspCompilerFeat;
impl CompilerFeat for LspCompilerFeat {
/// Uses [`TinymistFontResolver`] directly.
type FontResolver = TinymistFontResolver;
/// It accesses a physical file system.
type AccessModel = SystemAccessModel;
/// It performs native HTTP requests for fetching package data.
type Registry = HttpRegistry;
}
/// LSP universe that spawns LSP worlds.
pub type LspUniverse = CompilerUniverse<LspCompilerFeat>;
/// LSP world that holds compilation resources
pub type LspWorld = CompilerWorld<LspCompilerFeat>;
/// LSP compile snapshot.
pub type LspCompileSnapshot = CompileSnapshot<LspCompilerFeat>;
/// LSP compiled artifact.
pub type LspCompiledArtifact = CompiledArtifact<LspCompilerFeat>;
/// LSP interrupt.
pub type LspInterrupt = Interrupt<LspCompilerFeat>;
/// Immutable prehashed reference to dictionary.
pub type ImmutDict = Arc<LazyHash<Dict>>;
/// World provider for LSP universe and worlds.
pub trait WorldProvider {
/// Get the entry options from the arguments.
fn entry(&self) -> Result<EntryOpts>;
/// Get a universe instance from the given arguments.
fn resolve(&self) -> Result<LspUniverse>;
}
impl WorldProvider for CompileOnceArgs {
fn resolve(&self) -> Result<LspUniverse> {
let entry = self.entry()?.try_into()?;
let inputs = self.resolve_inputs().unwrap_or_default();
let fonts = Arc::new(LspUniverseBuilder::resolve_fonts(self.font.clone())?);
let package = LspUniverseBuilder::resolve_package(
self.cert.as_deref().map(From::from),
Some(&self.package),
);
// todo: more export targets
Ok(LspUniverseBuilder::build(
entry,
ExportTarget::Paged,
inputs,
fonts,
package,
))
}
fn entry(&self) -> Result<EntryOpts> {
let mut cwd = None;
let mut cwd = move || {
cwd.get_or_insert_with(|| {
std::env::current_dir().context("failed to get current directory")
})
.clone()
};
let main = {
let input = self.input.as_ref().context("entry file must be provided")?;
let input = Path::new(&input);
if input.is_absolute() {
input.to_owned()
} else {
cwd()?.join(input)
}
};
let root = if let Some(root) = &self.root {
if root.is_absolute() {
root.clone()
} else {
cwd()?.join(root)
}
} else {
main.parent()
.context("entry file don't have a valid parent as root")?
.to_owned()
};
let relative_main = match main.strip_prefix(&root) {
Ok(relative_main) => relative_main,
Err(_) => {
log::error!("entry file must be inside the root, file: {main:?}, root: {root:?}");
bail!("entry file must be inside the root, file: {main:?}, root: {root:?}");
}
};
Ok(EntryOpts::new_rooted(
root.clone(),
Some(relative_main.to_owned()),
))
}
}
// todo: merge me with the above impl
impl WorldProvider for (ProjectInput, ImmutPath) {
fn resolve(&self) -> Result<LspUniverse> {
let (proj, lock_dir) = self;
let entry = self.entry()?.try_into()?;
let inputs = proj
.inputs
.iter()
.map(|(k, v)| (Str::from(k.as_str()), Value::Str(Str::from(v.as_str()))))
.collect();
let fonts = LspUniverseBuilder::resolve_fonts(CompileFontArgs {
font_paths: {
proj.font_paths
.iter()
.flat_map(|p| p.to_abs_path(lock_dir))
.collect::<Vec<_>>()
},
ignore_system_fonts: !proj.system_fonts,
})?;
let package = LspUniverseBuilder::resolve_package(
// todo: recover certificate path
None,
Some(&CompilePackageArgs {
package_path: proj
.package_path
.as_ref()
.and_then(|p| p.to_abs_path(lock_dir)),
package_cache_path: proj
.package_cache_path
.as_ref()
.and_then(|p| p.to_abs_path(lock_dir)),
}),
);
// todo: more export targets
Ok(LspUniverseBuilder::build(
entry,
ExportTarget::Paged,
Arc::new(LazyHash::new(inputs)),
Arc::new(fonts),
package,
))
}
fn entry(&self) -> Result<EntryOpts> {
let (proj, lock_dir) = self;
let entry = proj
.main
.to_abs_path(lock_dir)
.context("failed to resolve entry file")?;
let root = if let Some(root) = &proj.root {
root.to_abs_path(lock_dir)
.context("failed to resolve root")?
} else {
lock_dir.as_ref().to_owned()
};
if !entry.starts_with(&root) {
bail!("entry file must be in the root directory, {entry:?}, {root:?}");
}
let relative_entry = match entry.strip_prefix(&root) {
Ok(relative_entry) => relative_entry,
Err(_) => bail!("entry path must be inside the root: {}", entry.display()),
};
Ok(EntryOpts::new_rooted(
root.clone(),
Some(relative_entry.to_owned()),
))
}
}
/// Builder for LSP universe.
pub struct LspUniverseBuilder;
impl LspUniverseBuilder {
/// Create [`LspUniverse`] with the given options.
/// See [`LspCompilerFeat`] for instantiation details.
pub fn build(
entry: EntryState,
export_target: ExportTarget,
inputs: ImmutDict,
font_resolver: Arc<TinymistFontResolver>,
package_registry: HttpRegistry,
) -> LspUniverse {
let registry = Arc::new(package_registry);
let resolver = Arc::new(RegistryPathMapper::new(registry.clone()));
LspUniverse::new_raw(
entry,
matches!(export_target, ExportTarget::Html),
Some(inputs),
Vfs::new(resolver, SystemAccessModel {}),
registry,
font_resolver,
)
}
/// Resolve fonts from given options.
pub fn only_embedded_fonts() -> Result<TinymistFontResolver> {
let mut searcher = SystemFontSearcher::new();
searcher.resolve_opts(CompileFontOpts {
font_profile_cache_path: Default::default(),
font_paths: vec![],
no_system_fonts: true,
with_embedded_fonts: typst_assets::fonts().map(Cow::Borrowed).collect(),
})?;
Ok(searcher.into())
}
/// Resolve fonts from given options.
pub fn resolve_fonts(args: CompileFontArgs) -> Result<TinymistFontResolver> {
let mut searcher = SystemFontSearcher::new();
searcher.resolve_opts(CompileFontOpts {
font_profile_cache_path: Default::default(),
font_paths: args.font_paths,
no_system_fonts: args.ignore_system_fonts,
with_embedded_fonts: typst_assets::fonts().map(Cow::Borrowed).collect(),
})?;
Ok(searcher.into())
}
/// Resolve package registry from given options.
pub fn resolve_package(
cert_path: Option<ImmutPath>,
args: Option<&CompilePackageArgs>,
) -> HttpRegistry {
HttpRegistry::new(
cert_path,
args.and_then(|args| Some(args.package_path.clone()?.into())),
args.and_then(|args| Some(args.package_cache_path.clone()?.into())),
)
}
}

View file

@ -17,7 +17,7 @@ use tinymist_world::vfs::notify::NotifyDeps;
use tokio::sync::mpsc;
use typst::diag::FileError;
use crate::vfs::{
use tinymist_world::vfs::{
notify::{FilesystemEvent, NotifyMessage, UpstreamUpdateEvent},
system::SystemAccessModel,
FileChangeSet, FileSnapshot, PathAccessModel,
@ -174,7 +174,7 @@ impl<F: FnMut(FilesystemEvent) + Send + Sync> NotifyActor<F> {
// function entries to handle some event
match event {
ActorEvent::Message(None) => {
log::info!("failed to get event, exiting...");
log::info!("NotifyActor: failed to get event, exiting...");
break 'event_loop;
}
ActorEvent::Message(Some(Settle)) => {
@ -520,7 +520,7 @@ pub async fn watch_deps(
inbox: mpsc::UnboundedReceiver<NotifyMessage>,
interrupted_by_events: impl FnMut(FilesystemEvent) + Send + Sync + 'static,
) {
log::debug!("start watching files...");
log::info!("NotifyActor: start watching files...");
// Watch messages to notify
tokio::spawn(NotifyActor::new(interrupted_by_events).run(inbox));
}

View file

@ -8,240 +8,3 @@ pub use tinymist_world::{font, package, vfs};
pub use tinymist_world::{
CompilerUniverse, CompilerWorld, EntryOpts, EntryState, RevisingUniverse, TaskInputs,
};
use std::path::Path;
use std::{borrow::Cow, sync::Arc};
use tinymist_std::error::prelude::*;
use tinymist_std::{bail, ImmutPath};
use tinymist_world::font::system::SystemFontSearcher;
use tinymist_world::package::{http::HttpRegistry, RegistryPathMapper};
use tinymist_world::vfs::{system::SystemAccessModel, Vfs};
use tinymist_world::CompilerFeat;
use typst::foundations::{Dict, Str, Value};
use typst::utils::LazyHash;
use crate::font::TinymistFontResolver;
use crate::ProjectInput;
/// Compiler feature for LSP universe and worlds without typst.ts to implement
/// more for tinymist. type trait of [`CompilerUniverse`].
#[derive(Debug, Clone, Copy)]
pub struct LspCompilerFeat;
impl CompilerFeat for LspCompilerFeat {
/// Uses [`TinymistFontResolver`] directly.
type FontResolver = TinymistFontResolver;
/// It accesses a physical file system.
type AccessModel = SystemAccessModel;
/// It performs native HTTP requests for fetching package data.
type Registry = HttpRegistry;
}
/// LSP universe that spawns LSP worlds.
pub type LspUniverse = CompilerUniverse<LspCompilerFeat>;
/// LSP world that holds compilation resources
pub type LspWorld = CompilerWorld<LspCompilerFeat>;
/// Immutable prehashed reference to dictionary.
pub type ImmutDict = Arc<LazyHash<Dict>>;
/// World provider for LSP universe and worlds.
pub trait WorldProvider {
/// Get the entry options from the arguments.
fn entry(&self) -> Result<EntryOpts>;
/// Get a universe instance from the given arguments.
fn resolve(&self) -> Result<LspUniverse>;
}
impl WorldProvider for CompileOnceArgs {
fn resolve(&self) -> Result<LspUniverse> {
let entry = self.entry()?.try_into()?;
let inputs = self.resolve_inputs().unwrap_or_default();
let fonts = Arc::new(LspUniverseBuilder::resolve_fonts(self.font.clone())?);
let package = LspUniverseBuilder::resolve_package(
self.cert.as_deref().map(From::from),
Some(&self.package),
);
Ok(LspUniverseBuilder::build(entry, inputs, fonts, package))
}
fn entry(&self) -> Result<EntryOpts> {
let mut cwd = None;
let mut cwd = move || {
cwd.get_or_insert_with(|| {
std::env::current_dir().context("failed to get current directory")
})
.clone()
};
let main = {
let input = self.input.as_ref().context("entry file must be provided")?;
let input = Path::new(&input);
if input.is_absolute() {
input.to_owned()
} else {
cwd()?.join(input)
}
};
let root = if let Some(root) = &self.root {
if root.is_absolute() {
root.clone()
} else {
cwd()?.join(root)
}
} else {
main.parent()
.context("entry file don't have a valid parent as root")?
.to_owned()
};
let relative_main = match main.strip_prefix(&root) {
Ok(relative_main) => relative_main,
Err(_) => {
log::error!("entry file must be inside the root, file: {main:?}, root: {root:?}");
bail!("entry file must be inside the root, file: {main:?}, root: {root:?}");
}
};
Ok(EntryOpts::new_rooted(
root.clone(),
Some(relative_main.to_owned()),
))
}
}
// todo: merge me with the above impl
impl WorldProvider for (ProjectInput, ImmutPath) {
fn resolve(&self) -> Result<LspUniverse> {
let (proj, lock_dir) = self;
let entry = self.entry()?.try_into()?;
let inputs = proj
.inputs
.iter()
.map(|(k, v)| (Str::from(k.as_str()), Value::Str(Str::from(v.as_str()))))
.collect();
let fonts = LspUniverseBuilder::resolve_fonts(CompileFontArgs {
font_paths: {
proj.font_paths
.iter()
.flat_map(|p| p.to_abs_path(lock_dir))
.collect::<Vec<_>>()
},
ignore_system_fonts: !proj.system_fonts,
})?;
let package = LspUniverseBuilder::resolve_package(
// todo: recover certificate path
None,
Some(&CompilePackageArgs {
package_path: proj
.package_path
.as_ref()
.and_then(|p| p.to_abs_path(lock_dir)),
package_cache_path: proj
.package_cache_path
.as_ref()
.and_then(|p| p.to_abs_path(lock_dir)),
}),
);
Ok(LspUniverseBuilder::build(
entry,
Arc::new(LazyHash::new(inputs)),
Arc::new(fonts),
package,
))
}
fn entry(&self) -> Result<EntryOpts> {
let (proj, lock_dir) = self;
let entry = proj
.main
.to_abs_path(lock_dir)
.context("failed to resolve entry file")?;
let root = if let Some(root) = &proj.root {
root.to_abs_path(lock_dir)
.context("failed to resolve root")?
} else {
lock_dir.as_ref().to_owned()
};
if !entry.starts_with(&root) {
bail!("entry file must be in the root directory, {entry:?}, {root:?}");
}
let relative_entry = match entry.strip_prefix(&root) {
Ok(relative_entry) => relative_entry,
Err(_) => bail!("entry path must be inside the root: {}", entry.display()),
};
Ok(EntryOpts::new_rooted(
root.clone(),
Some(relative_entry.to_owned()),
))
}
}
/// Builder for LSP universe.
pub struct LspUniverseBuilder;
impl LspUniverseBuilder {
/// Create [`LspUniverse`] with the given options.
/// See [`LspCompilerFeat`] for instantiation details.
pub fn build(
entry: EntryState,
inputs: ImmutDict,
font_resolver: Arc<TinymistFontResolver>,
package_registry: HttpRegistry,
) -> LspUniverse {
let registry = Arc::new(package_registry);
let resolver = Arc::new(RegistryPathMapper::new(registry.clone()));
LspUniverse::new_raw(
entry,
Some(inputs),
Vfs::new(resolver, SystemAccessModel {}),
registry,
font_resolver,
)
}
/// Resolve fonts from given options.
pub fn only_embedded_fonts() -> Result<TinymistFontResolver> {
let mut searcher = SystemFontSearcher::new();
searcher.resolve_opts(CompileFontOpts {
font_profile_cache_path: Default::default(),
font_paths: vec![],
no_system_fonts: true,
with_embedded_fonts: typst_assets::fonts().map(Cow::Borrowed).collect(),
})?;
Ok(searcher.into())
}
/// Resolve fonts from given options.
pub fn resolve_fonts(args: CompileFontArgs) -> Result<TinymistFontResolver> {
let mut searcher = SystemFontSearcher::new();
searcher.resolve_opts(CompileFontOpts {
font_profile_cache_path: Default::default(),
font_paths: args.font_paths,
no_system_fonts: args.ignore_system_fonts,
with_embedded_fonts: typst_assets::fonts().map(Cow::Borrowed).collect(),
})?;
Ok(searcher.into())
}
/// Resolve package registry from given options.
pub fn resolve_package(
cert_path: Option<ImmutPath>,
args: Option<&CompilePackageArgs>,
) -> HttpRegistry {
HttpRegistry::new(
cert_path,
args.and_then(|args| Some(args.package_path.clone()?.into())),
args.and_then(|args| Some(args.package_cache_path.clone()?.into())),
)
}
}

View file

@ -56,7 +56,7 @@ triomphe.workspace = true
base64.workspace = true
typlite.workspace = true
tinymist-world = { workspace = true }
tinymist-project = { workspace = true, features = ["system"] }
tinymist-project = { workspace = true, features = ["lsp"] }
tinymist-analysis.workspace = true
tinymist-derive.workspace = true
tinymist-std.workspace = true
@ -71,7 +71,6 @@ sha2 = { version = "0.10" }
hex = { version = "0.4" }
[features]
no-content-hint = ["tinymist-project/no-content-hint"]
[lints]
workspace = true

View file

@ -358,7 +358,7 @@ mod type_check_tests {
.map(|bounds| (bounds.name(), bounds))
.collect::<Vec<_>>();
vars.sort_by(|x, y| x.1.var.cmp(&y.1.var));
vars.sort_by(|x, y| x.1.var.strict_cmp(&y.1.var));
for (name, bounds) in vars {
writeln!(f, "{name:?} = {:?}", info.simplify(bounds.as_type(), true))?;
@ -590,7 +590,7 @@ mod call_info_tests {
};
let mut w = ci.arg_mapping.iter().collect::<Vec<_>>();
w.sort_by(|x, y| x.0.span().number().cmp(&y.0.span().number()));
w.sort_by(|x, y| x.0.span().into_raw().cmp(&y.0.span().into_raw()));
for (arg, arg_call_info) in w {
writeln!(f, "{} -> {:?}", arg.clone().into_text(), arg_call_info)?;

View file

@ -37,13 +37,13 @@ impl CompletionPair<'_, '_, '_> {
/// Add completions for all fields on a value.
fn value_field_access_completions(&mut self, target: &LinkedNode) -> Option<()> {
let (value, styles) = self.worker.ctx.analyze_expr(target).into_iter().next()?;
for (name, value, _) in value.ty().scope().iter() {
self.value_completion(Some(name.clone()), value, true, None);
for (name, bind) in value.ty().scope().iter() {
self.value_completion(Some(name.clone()), bind.read(), true, None);
}
if let Some(scope) = value.scope() {
for (name, value, _) in scope.iter() {
self.value_completion(Some(name.clone()), value, true, None);
for (name, bind) in scope.iter() {
self.value_completion(Some(name.clone()), bind.read(), true, None);
}
}
@ -55,7 +55,7 @@ impl CompletionPair<'_, '_, '_> {
// this value's type, so accessing it should not fail.
self.value_completion(
Some(field.into()),
&value.field(field).unwrap(),
&value.field(field, ()).unwrap(),
false,
None,
);
@ -108,15 +108,6 @@ impl CompletionPair<'_, '_, '_> {
}
}
}
Value::Plugin(plugin) => {
for name in plugin.iter() {
self.push_completion(Completion {
kind: CompletionKind::Func,
label: name.clone(),
..Completion::default()
})
}
}
_ => {}
}

View file

@ -95,9 +95,9 @@ impl CompletionPair<'_, '_, '_> {
) {
// Select the source by `comps`
let value = self.worker.ctx.module_by_syntax(source);
let value = comps
.iter()
.fold(value.as_ref(), |value, comp| value?.scope()?.get(comp));
let value = comps.iter().fold(value.as_ref(), |value, comp| {
value?.scope()?.get(comp)?.read().into()
});
let Some(scope) = value.and_then(|v| v.scope()) else {
return;
};
@ -125,9 +125,9 @@ impl CompletionPair<'_, '_, '_> {
self.snippet_completion("*", "*", "Import everything.");
}
for (name, value, _) in scope.iter() {
for (name, bind) in scope.iter() {
if seen.iter().all(|item| item.as_str() != name) {
self.value_completion(Some(name.clone()), value, false, None);
self.value_completion(Some(name.clone()), bind.read(), false, None);
}
}
}

View file

@ -114,7 +114,7 @@ impl FnCompletionFeat {
| Value::Fraction(..)
| Value::Color(..)
| Value::Gradient(..)
| Value::Pattern(..)
| Value::Tiling(..)
| Value::Symbol(..)
| Value::Version(..)
| Value::Str(..)
@ -129,7 +129,6 @@ impl FnCompletionFeat {
| Value::Dict(..)
| Value::Args(..)
| Value::Module(..)
| Value::Plugin(..)
| Value::Dyn(..) => {}
},
Ty::Func(sig) => self.check_sig(sig, pos),
@ -263,7 +262,7 @@ fn fold_ty_kind<'a>(tys: impl Iterator<Item = &'a Ty>) -> CompletionKind {
pub(crate) fn value_to_completion_kind(value: &Value) -> CompletionKind {
match value {
Value::Func(..) => CompletionKind::Func,
Value::Plugin(..) | Value::Module(..) => CompletionKind::Module,
Value::Module(..) => CompletionKind::Module,
Value::Type(..) => CompletionKind::Type,
Value::Symbol(s) => CompletionKind::Symbol(s.get()),
Value::None
@ -278,7 +277,7 @@ pub(crate) fn value_to_completion_kind(value: &Value) -> CompletionKind {
| Value::Fraction(..)
| Value::Color(..)
| Value::Gradient(..)
| Value::Pattern(..)
| Value::Tiling(..)
| Value::Version(..)
| Value::Str(..)
| Value::Bytes(..)

View file

@ -120,7 +120,7 @@ impl CompletionPair<'_, '_, '_> {
if !is_triggered_by_punc(self.worker.trigger_character)
&& matches!(
self.cursor.leaf.kind(),
SyntaxKind::Text | SyntaxKind::MathIdent
SyntaxKind::Text | SyntaxKind::MathIdent | SyntaxKind::MathText
)
{
self.cursor.from = self.cursor.leaf.offset();

View file

@ -49,10 +49,10 @@ impl CompletionPair<'_, '_, '_> {
let captures = visitor.finish();
// Converts the captures into completions.
for (name, value, _) in captures.iter() {
for (name, bind) in captures.iter() {
if !bindings.contains(name) {
let docs = "Parametrizes the captured variable.";
self.value_completion(Some(name.clone()), value, false, Some(docs));
self.value_completion(Some(name.clone()), bind.read(), false, Some(docs));
}
}

View file

@ -28,9 +28,9 @@ impl Defines {
pub fn insert_scope(&mut self, scope: &Scope) {
// filter(Some(value)) &&
for (name, value, _) in scope.iter() {
for (name, bind) in scope.iter() {
if !self.defines.contains_key(name) {
self.insert(name.clone(), Ty::Value(InsTy::new(value.clone())));
self.insert(name.clone(), Ty::Value(InsTy::new(bind.read().clone())));
}
}
}
@ -301,8 +301,8 @@ impl CompletionScopeChecker<'_> {
for name in fields_on(ty) {
self.defines.insert((*name).into(), Ty::Any);
}
for (name, value, _) in ty.scope().iter() {
let ty = Ty::Value(InsTy::new(value.clone()));
for (name, bind) in ty.scope().iter() {
let ty = Ty::Value(InsTy::new(bind.read().clone()));
self.defines.insert(name.into(), ty);
}
}

View file

@ -113,7 +113,7 @@ impl CompletionPair<'_, '_, '_> {
if !self.worker.seen_casts.insert(hash128(&label)) {
continue;
}
let label: EcoString = label.as_str().into();
let label: EcoString = label.resolve().as_str().into();
let completion = Completion {
kind: CompletionKind::Reference,
apply: Some(eco_format!(

View file

@ -144,7 +144,7 @@ fn bib_definition(
key: &str,
) -> Option<Definition> {
let bib_elem = BibliographyElem::find(introspector.track()).ok()?;
let Value::Array(paths) = bib_elem.path().clone().into_value() else {
let Value::Array(paths) = bib_elem.sources.clone().into_value() else {
return None;
};
@ -164,7 +164,7 @@ fn ref_definition(
name: &str,
ref_expr: ast::Expr,
) -> Option<Definition> {
let label = Label::new(name);
let label = Label::construct(name.into());
let sel = Selector::Label(label);
// if it is a label, we put the selection range to itself
@ -243,7 +243,7 @@ pub fn resolve_call_target(ctx: &Arc<SharedContext>, node: &SyntaxNode) -> Optio
let field = access.field().get();
let values = ctx.analyze_expr(target.to_untyped());
if let Some((this, func_ptr)) = values.into_iter().find_map(|(this, _styles)| {
if let Some(Value::Func(func)) = this.ty().scope().get(field) {
if let Some(Value::Func(func)) = this.ty().scope().get(field).map(|b| b.read()) {
return Some((this, func.clone()));
}
@ -288,7 +288,8 @@ fn is_same_native_func(x: Option<&Func>, y: &Func) -> bool {
static WITH_FUNC: LazyLock<Option<&'static Func>> = LazyLock::new(|| {
let fn_ty = Type::of::<Func>();
let Some(Value::Func(func)) = fn_ty.scope().get("with") else {
let bind = fn_ty.scope().get("with")?;
let Value::Func(func) = bind.read() else {
return None;
};
Some(func)
@ -296,7 +297,8 @@ static WITH_FUNC: LazyLock<Option<&'static Func>> = LazyLock::new(|| {
static WHERE_FUNC: LazyLock<Option<&'static Func>> = LazyLock::new(|| {
let fn_ty = Type::of::<Func>();
let Some(Value::Func(func)) = fn_ty.scope().get("where") else {
let bind = fn_ty.scope().get("where")?;
let Value::Func(func) = bind.read() else {
return None;
};
Some(func)
@ -313,7 +315,9 @@ fn value_to_def(value: Value, name: impl FnOnce() -> Option<Interned<str>>) -> O
let decl = Decl::func(s.cast().unwrap());
Definition::new(decl.into(), Some(val))
}
Value::Module(module) => Definition::new_var(module.name().into(), val),
Value::Module(module) => {
Definition::new_var(Interned::new_str(module.name().unwrap()), val)
}
_v => Definition::new_var(name()?, val),
})
}

View file

@ -538,7 +538,7 @@ pub fn func_signature(func: Func) -> Signature {
analyze_closure_signature(closure.clone(), &mut add_param);
None
}
Repr::Element(..) | Repr::Native(..) => {
Repr::Element(..) | Repr::Native(..) | Repr::Plugin(..) => {
for param in func.params().unwrap() {
add_param(Interned::new(ParamTy {
name: param.name.into(),

View file

@ -2,14 +2,14 @@
use comemo::Track;
use ecow::*;
use tinymist_std::typst::TypstDocument;
use tinymist_std::typst::{TypstDocument, TypstPagedDocument};
use typst::engine::{Engine, Route, Sink, Traced};
use typst::eval::Vm;
use typst::foundations::{Context, Label, Scopes, Styles, Value};
use typst::introspection::Introspector;
use typst::model::BibliographyElem;
use typst::syntax::{ast, LinkedNode, Span, SyntaxKind, SyntaxNode};
use typst::World;
use typst_shim::eval::Vm;
/// Try to determine a set of possible values for an expression.
pub fn analyze_expr(world: &dyn World, node: &LinkedNode) -> EcoVec<(Value, Option<Styles>)> {
@ -43,7 +43,7 @@ pub fn analyze_expr_(world: &dyn World, node: &SyntaxNode) -> EcoVec<(Value, Opt
}
}
return typst::trace(world, node.span());
return typst::trace::<TypstPagedDocument>(world, node.span());
}
};
@ -64,6 +64,7 @@ pub fn analyze_import_(world: &dyn World, source: &SyntaxNode) -> (Option<Value>
let traced = Traced::default();
let mut sink = Sink::new();
let engine = Engine {
routines: &typst::ROUTINES,
world: world.track(),
route: Route::default(),
introspector: introspector.track(),
@ -78,9 +79,13 @@ pub fn analyze_import_(world: &dyn World, source: &SyntaxNode) -> (Option<Value>
Scopes::new(Some(world.library())),
Span::detached(),
);
let module = typst_shim::eval::import(&mut vm, source.clone(), source_span, true)
let module = match source.clone() {
Value::Str(path) => typst_shim::eval::import(&mut vm.engine, &path, source_span)
.ok()
.map(Value::Module);
.map(Value::Module),
Value::Module(module) => Some(Value::Module(module)),
_ => None,
};
(Some(source), module)
}
@ -137,9 +142,9 @@ pub fn analyze_labels(document: &TypstDocument) -> (Vec<DynLabel>, usize) {
let split = output.len();
// Bibliography keys.
for (key, detail) in BibliographyElem::keys(document.introspector().track()) {
for (label, detail) in BibliographyElem::keys(document.introspector().track()) {
output.push(DynLabel {
label: Label::new(key.as_str()),
label,
label_desc: detail.clone(),
detail: detail.clone(),
bib_title: detail,

View file

@ -19,7 +19,7 @@ pub fn is_plain_value(value: &Value) -> bool {
| Value::Fraction(..)
| Value::Color(..)
| Value::Gradient(..)
| Value::Pattern(..)
| Value::Tiling(..)
| Value::Symbol(..)
| Value::Version(..)
| Value::Str(..)
@ -44,14 +44,6 @@ pub fn term_value(value: &Value) -> Ty {
}
// todo: term arguments
Value::Args(..) => Ty::Builtin(BuiltinTy::Args),
Value::Plugin(plugin) => {
// todo: create infer variables for plugin functions
let values = plugin
.iter()
.map(|method| (method.as_str().into(), Ty::Func(SigTy::any())))
.collect();
Ty::Dict(RecordTy::new(values))
}
Value::Dict(dict) => {
let values = dict
.iter()
@ -63,7 +55,7 @@ pub fn term_value(value: &Value) -> Ty {
let values = module
.scope()
.iter()
.map(|(k, v, s)| (k.into(), term_value_rec(v, s)))
.map(|(k, b)| (k.into(), term_value_rec(b.read(), b.span())))
.collect();
Ty::Dict(RecordTy::new(values))
}
@ -83,7 +75,6 @@ pub fn term_value_rec(value: &Value, s: Span) -> Ty {
| Value::Auto
| Value::Array(..)
| Value::Args(..)
| Value::Plugin(..)
| Value::Dict(..)
| Value::Module(..)
| Value::Func(..)
@ -99,7 +90,7 @@ pub fn term_value_rec(value: &Value, s: Span) -> Ty {
| Value::Fraction(..)
| Value::Color(..)
| Value::Gradient(..)
| Value::Pattern(..)
| Value::Tiling(..)
| Value::Symbol(..)
| Value::Version(..)
| Value::Str(..)

View file

@ -104,7 +104,7 @@ impl SemanticRequest for InteractCodeContextRequest {
let _ = world.map_shadow_by_id(
mapped_source.id(),
Bytes::from(mapped_source.text().as_bytes()),
Bytes::new(mapped_source.text().as_bytes().to_vec()),
);
world.take_db();
@ -130,7 +130,7 @@ impl SemanticRequest for InteractCodeContextRequest {
.collect();
let _ = world.map_shadow_by_id(
mapped_source.id(),
Bytes::from(source.text().as_bytes()),
Bytes::new(source.text().as_bytes().to_vec()),
);
Some(InteractCodeContextResponse::StyleAt { style })

View file

@ -33,7 +33,15 @@ impl SemanticRequest for CodeLensRequest {
res.push(doc_lens("Profile", vec!["profile".into()]));
res.push(doc_lens("Preview", vec!["preview".into()]));
let is_html = ctx.world.library.features.is_enabled(typst::Feature::Html);
if is_html {
res.push(doc_lens("Export HTML", vec!["export-html".into()]));
} else {
res.push(doc_lens("Export PDF", vec!["export-pdf".into()]));
}
res.push(doc_lens("More ..", vec!["more".into()]));
Some(res)

View file

@ -23,7 +23,7 @@ pub(crate) fn convert_docs(ctx: &SharedContext, content: &str) -> StrResult<EcoS
entry: Some(entry),
inputs: None,
});
w.map_shadow_by_id(w.main(), Bytes::from(content.as_bytes().to_owned()))?;
w.map_shadow_by_id(w.main(), Bytes::from_string(content.to_owned()))?;
// todo: bad performance
w.take_db();

View file

@ -151,6 +151,7 @@ impl DocumentMetricsWorker<'_> {
Some(())
}
_ => None,
}
}

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on t (63..64)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/bracket_strong.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(content, delta: int) => strong"
},
"sortText": "180",
"sortText": "182",
"textEdit": {
"newText": "strong(${1:})",
"range": {
@ -36,7 +35,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(content, delta: int) => strong"
},
"sortText": "181",
"sortText": "183",
"textEdit": {
"newText": "strong[${1:}]",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on ( (71..72)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/builtin_shadow.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(fill-rest: false) => none"
},
"sortText": "126",
"sortText": "127",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on ( (70..71)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/builtin_shadow_existing.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(fill-rest: false) => none"
},
"sortText": "127",
"sortText": "128",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on (23..24)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/colon_markup.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(content, b: content | none, bl: content | none, br: content | none, t: content | none, tl: content | none, tr: content | none) => attach"
},
"sortText": "075",
"sortText": "076",
"textEdit": {
"newText": " attach(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on (23..24)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/colon_math.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(content, b: content | none, bl: content | none, br: content | none, t: content | none, tl: content | none, tr: content | none) => attach"
},
"sortText": "075",
"sortText": "076",
"textEdit": {
"newText": " attach(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (36..37)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/context_code_init.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "127",
"sortText": "128",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (34..35)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/context_init.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "127",
"sortText": "128",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (26..27)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/hash.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "126",
"sortText": "127",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (28..29)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/hash_ident.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "126",
"sortText": "127",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (28..29)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/hash_math.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "126",
"sortText": "127",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (30..31)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/hash_math_ident.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "126",
"sortText": "127",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (40..41)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/let_closure_init.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "128",
"sortText": "129",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (37..38)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/let_fn_init.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "128",
"sortText": "129",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (34..35)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/let_init.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(to: \"even\" | \"odd\" | none, weak: bool) => pagebreak"
},
"sortText": "128",
"sortText": "129",
"textEdit": {
"newText": "pagebreak()${1:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (30..31)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/math_bold2.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(content) => content"
},
"sortText": "086",
"sortText": "087",
"textEdit": {
"newText": "bold(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (28..29)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/math_call_in_call.typ
snapshot_kind: text
---
[
{
@ -31,7 +30,7 @@ snapshot_kind: text
"kind": 3,
"label": "abs",
"labelDetails": {
"description": "(content, size: auto | relative) => content"
"description": "(content, size: relative) => content"
},
"sortText": "058",
"textEdit": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (27..28)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/math_call_in_call2.typ
snapshot_kind: text
---
[
{
@ -13,7 +12,7 @@ snapshot_kind: text
"kind": 3,
"label": "abs",
"labelDetails": {
"description": "(content, size: auto | relative) => content"
"description": "(content, size: relative) => content"
},
"sortText": "057",
"textEdit": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (28..29)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/math_call_in_call3.typ
snapshot_kind: text
---
[
{
@ -13,7 +12,7 @@ snapshot_kind: text
"kind": 3,
"label": "abs",
"labelDetails": {
"description": "(content, size: auto | relative) => content"
"description": "(content, size: relative) => content"
},
"sortText": "055",
"textEdit": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (29..30)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/math_call_in_call4.typ
snapshot_kind: text
---
[
{
@ -13,7 +12,7 @@ snapshot_kind: text
"kind": 3,
"label": "abs",
"labelDetails": {
"description": "(content, size: auto | relative) => content"
"description": "(content, size: relative) => content"
},
"sortText": "055",
"textEdit": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (27..28)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/math_ident_in_call.typ
snapshot_kind: text
---
[
{
@ -13,9 +12,9 @@ snapshot_kind: text
"kind": 3,
"label": "norm",
"labelDetails": {
"description": "(content, size: auto | relative) => content"
"description": "(content, size: relative) => content"
},
"sortText": "221",
"sortText": "229",
"textEdit": {
"newText": "norm(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (28..29)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/math_ident_in_call2.typ
snapshot_kind: text
---
[
{
@ -13,9 +12,9 @@ snapshot_kind: text
"kind": 3,
"label": "norm",
"labelDetails": {
"description": "(content, size: auto | relative) => content"
"description": "(content, size: relative) => content"
},
"sortText": "223",
"sortText": "231",
"textEdit": {
"newText": "norm(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (92..93)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/set.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "052",
"sortText": "053",
"textEdit": {
"newText": "raw(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (86..87)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/set2.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "052",
"sortText": "053",
"textEdit": {
"newText": "raw(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (114..115)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/set_in_show.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "053",
"sortText": "054",
"textEdit": {
"newText": "raw(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (109..110)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/show.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "094",
"sortText": "096",
"textEdit": {
"newText": "raw: ${1:}",
"range": {
@ -36,7 +35,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "095",
"sortText": "097",
"textEdit": {
"newText": "raw.where(${1:}): ${2:}",
"range": {
@ -54,7 +53,7 @@ snapshot_kind: text
{
"kind": 15,
"label": "regex selector",
"sortText": "100",
"sortText": "102",
"textEdit": {
"newText": "regex(\"${1:regex}\"): ${2:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (108..109)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/show2.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "094",
"sortText": "096",
"textEdit": {
"newText": "raw: ${1:}",
"range": {
@ -36,7 +35,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "095",
"sortText": "097",
"textEdit": {
"newText": "raw.where(${1:}): ${2:}",
"range": {
@ -54,7 +53,7 @@ snapshot_kind: text
{
"kind": 15,
"label": "regex selector",
"sortText": "100",
"sortText": "102",
"textEdit": {
"newText": "regex(\"${1:regex}\"): ${2:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (103..104)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/show3.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "094",
"sortText": "096",
"textEdit": {
"newText": "raw: ${1:}",
"range": {
@ -36,7 +35,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "095",
"sortText": "097",
"textEdit": {
"newText": "raw.where(${1:}): ${2:}",
"range": {
@ -54,7 +53,7 @@ snapshot_kind: text
{
"kind": 15,
"label": "regex selector",
"sortText": "100",
"sortText": "102",
"textEdit": {
"newText": "regex(\"${1:regex}\"): ${2:}",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (93..94)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/show_transform.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "173",
"sortText": "175",
"textEdit": {
"newText": "raw(${1:})",
"range": {
@ -36,7 +35,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "174",
"sortText": "176",
"textEdit": {
"newText": "raw.with(${1:})",
"range": {
@ -57,7 +56,7 @@ snapshot_kind: text
"labelDetails": {
"description": "([any], encoding: \"utf8\" | none) => bytes | str"
},
"sortText": "175",
"sortText": "177",
"textEdit": {
"newText": "read(${1:})",
"range": {
@ -78,7 +77,7 @@ snapshot_kind: text
"labelDetails": {
"description": "([any], encoding: \"utf8\" | none) => bytes | str"
},
"sortText": "176",
"sortText": "178",
"textEdit": {
"newText": "read.with(${1:})",
"range": {
@ -96,7 +95,7 @@ snapshot_kind: text
{
"kind": 15,
"label": "replacement",
"sortText": "187",
"sortText": "189",
"textEdit": {
"newText": "[${1:content}]",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (92..93)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/show_transform2.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "173",
"sortText": "175",
"textEdit": {
"newText": "raw(${1:})",
"range": {
@ -36,7 +35,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "174",
"sortText": "176",
"textEdit": {
"newText": "raw.with(${1:})",
"range": {
@ -57,7 +56,7 @@ snapshot_kind: text
"labelDetails": {
"description": "([any], encoding: \"utf8\" | none) => bytes | str"
},
"sortText": "175",
"sortText": "177",
"textEdit": {
"newText": "read(${1:})",
"range": {
@ -78,7 +77,7 @@ snapshot_kind: text
"labelDetails": {
"description": "([any], encoding: \"utf8\" | none) => bytes | str"
},
"sortText": "176",
"sortText": "178",
"textEdit": {
"newText": "read.with(${1:})",
"range": {
@ -96,7 +95,7 @@ snapshot_kind: text
{
"kind": 15,
"label": "replacement",
"sortText": "187",
"sortText": "189",
"textEdit": {
"newText": "[${1:content}]",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (91..92)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/completion/show_transform3.typ
snapshot_kind: text
---
[
{
@ -15,7 +14,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "173",
"sortText": "175",
"textEdit": {
"newText": " raw(${1:})",
"range": {
@ -36,7 +35,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(str, align: alignment, block: bool, lang: none | str, syntaxes: [syntax], tab-size: int, theme: [theme]) => raw"
},
"sortText": "174",
"sortText": "176",
"textEdit": {
"newText": " raw.with(${1:})",
"range": {
@ -57,7 +56,7 @@ snapshot_kind: text
"labelDetails": {
"description": "([any], encoding: \"utf8\" | none) => bytes | str"
},
"sortText": "175",
"sortText": "177",
"textEdit": {
"newText": " read(${1:})",
"range": {
@ -78,7 +77,7 @@ snapshot_kind: text
"labelDetails": {
"description": "([any], encoding: \"utf8\" | none) => bytes | str"
},
"sortText": "176",
"sortText": "178",
"textEdit": {
"newText": " read.with(${1:})",
"range": {
@ -96,7 +95,7 @@ snapshot_kind: text
{
"kind": 15,
"label": "replacement",
"sortText": "187",
"sortText": "189",
"textEdit": {
"newText": " [${1:content}]",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (57..58)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/pkgs/touying-core-slides.typ
snapshot_kind: text
---
[
{
@ -57,7 +56,7 @@ snapshot_kind: text
"labelDetails": {
"description": "(content, gap: length, justify: bool) => repeat"
},
"sortText": "159",
"sortText": "161",
"textEdit": {
"newText": "repeat(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (71..72)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/pkgs/touying-utils-cover-with-rect.typ
snapshot_kind: text
---
[
{
@ -36,7 +35,7 @@ snapshot_kind: text
"labelDetails": {
"description": "type"
},
"sortText": "186",
"sortText": "188",
"textEdit": {
"newText": "stroke(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (63..64)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/pkgs/touying-utils-current-heading.typ
snapshot_kind: text
---
[
{
@ -33,7 +32,7 @@ snapshot_kind: text
"labelDetails": {
"description": "type"
},
"sortText": "089",
"sortText": "090",
"textEdit": {
"newText": "int(${1:})",
"range": {

View file

@ -3,7 +3,6 @@ source: crates/tinymist-query/src/completion.rs
description: Completion on / (71..72)
expression: "JsonRepr::new_pure(results)"
input_file: crates/tinymist-query/src/fixtures/pkgs/touying-utils-markup-text.typ
snapshot_kind: text
---
[
{
@ -69,7 +68,7 @@ snapshot_kind: text
"labelDetails": {
"description": "type"
},
"sortText": "180",
"sortText": "182",
"textEdit": {
"newText": "str(${1:})",
"range": {

View file

@ -2,6 +2,5 @@
source: crates/tinymist-query/src/semantic_tokens_full.rs
expression: "serde_json::to_string(&result).unwrap()"
input_file: crates/tinymist-query/src/fixtures/semantic_tokens/tinymist_issue_601.typ
snapshot_kind: text
---
{"data":[0,0,1,21,4,0,1,3,5,4,0,3,1,10,4,0,1,1,22,4,0,1,1,3,4,0,1,1,22,4,0,1,1,22,4,1,0,1,22,4,0,1,1,22,4,1,0,1,22,4]}
{"data":[0,0,1,21,4,0,1,3,5,4,0,3,1,21,4,0,1,1,22,4,0,1,1,3,4,0,1,1,22,4,0,1,1,22,4,1,0,1,22,4,0,1,1,22,0,1,0,1,22,0]}

View file

@ -325,7 +325,7 @@ impl ExternalDocLink {
Repr::With(w) => {
func = &w.0;
}
Repr::Closure(..) => {
Repr::Closure(..) | Repr::Plugin(..) => {
return None;
}
}

View file

@ -49,6 +49,7 @@ pub fn jump_from_cursor(
point,
})
}
_ => None,
}
}
@ -68,7 +69,12 @@ fn find_in_frame(frame: &Frame, span: Span, min_dis: &mut u64, res: &mut Point)
return Some(pos);
}
if glyph.span.0.id() == span.id() {
let dis = glyph.span.0.number().abs_diff(span.number());
let dis = glyph
.span
.0
.into_raw()
.get()
.abs_diff(span.into_raw().get());
if dis < *min_dis {
*min_dis = dis;
*res = pos;

View file

@ -122,7 +122,7 @@ fn validate_fn_renaming(def: &Definition) -> Option<()> {
match func.inner() {
// todo: rename with site
Repr::With(w) => func = &w.0,
Repr::Closure(..) => return Some(()),
Repr::Closure(..) | Repr::Plugin(..) => return Some(()),
// native functions can't be renamed
Repr::Native(..) | Repr::Element(..) => return None,
}

View file

@ -137,7 +137,11 @@ impl ExprScope {
// ref_expr.of = of.clone();
// ref_expr.val = val.map(|v| Ty::Value(InsTy::new(v.clone())));
// return ref_expr;
(of, val.cloned().map(|val| Ty::Value(InsTy::new(val))))
(
of,
val.cloned()
.map(|val| Ty::Value(InsTy::new(val.read().to_owned()))),
)
}
pub fn merge_into(&self, exports: &mut LexicalScope) {
@ -150,7 +154,7 @@ impl ExprScope {
ExprScope::Module(module) => {
crate::log_debug_ct!("imported: {module:?}");
let v = Interned::new(Ty::Value(InsTy::new(Value::Module(module.clone()))));
for (name, _, _) in module.scope().iter() {
for (name, _) in module.scope().iter() {
let name: Interned<str> = name.into();
exports.insert_mut(name.clone(), select_of(v.clone(), name));
}
@ -158,7 +162,7 @@ impl ExprScope {
ExprScope::Func(func) => {
if let Some(scope) = func.scope() {
let v = Interned::new(Ty::Value(InsTy::new(Value::Func(func.clone()))));
for (name, _, _) in scope.iter() {
for (name, _) in scope.iter() {
let name: Interned<str> = name.into();
exports.insert_mut(name.clone(), select_of(v.clone(), name));
}
@ -166,7 +170,7 @@ impl ExprScope {
}
ExprScope::Type(ty) => {
let v = Interned::new(Ty::Value(InsTy::new(Value::Type(*ty))));
for (name, _, _) in ty.scope().iter() {
for (name, _) in ty.scope().iter() {
let name: Interned<str> = name.into();
exports.insert_mut(name.clone(), select_of(v.clone(), name));
}
@ -460,13 +464,62 @@ impl Ord for Decl {
(Self::Generated(l), Self::Generated(r)) => l.0 .0.cmp(&r.0 .0),
(Self::Module(l), Self::Module(r)) => l.fid.cmp(&r.fid),
(Self::Docs(l), Self::Docs(r)) => l.var.cmp(&r.var).then_with(|| l.base.cmp(&r.base)),
_ => self.span().number().cmp(&other.span().number()),
_ => self.span().into_raw().cmp(&other.span().into_raw()),
};
base.then_with(|| self.name().cmp(other.name()))
}
}
trait StrictCmp {
/// Low-performance comparison but it is free from the concurrency issue.
/// This is only used for making stable test snapshots.
fn strict_cmp(&self, other: &Self) -> std::cmp::Ordering;
}
impl Decl {
pub fn strict_cmp(&self, other: &Self) -> std::cmp::Ordering {
let base = match (self, other) {
(Self::Generated(l), Self::Generated(r)) => l.0 .0.cmp(&r.0 .0),
(Self::Module(l), Self::Module(r)) => l.fid.strict_cmp(&r.fid),
(Self::Docs(l), Self::Docs(r)) => l
.var
.strict_cmp(&r.var)
.then_with(|| l.base.strict_cmp(&r.base)),
_ => self.span().strict_cmp(&other.span()),
};
base.then_with(|| self.name().cmp(other.name()))
}
}
impl StrictCmp for TypstFileId {
fn strict_cmp(&self, other: &Self) -> std::cmp::Ordering {
self.package()
.map(ToString::to_string)
.cmp(&other.package().map(ToString::to_string))
.then_with(|| self.vpath().cmp(other.vpath()))
}
}
impl<T: StrictCmp> StrictCmp for Option<T> {
fn strict_cmp(&self, other: &Self) -> std::cmp::Ordering {
match (self, other) {
(Some(l), Some(r)) => l.strict_cmp(r),
(Some(_), None) => std::cmp::Ordering::Greater,
(None, Some(_)) => std::cmp::Ordering::Less,
(None, None) => std::cmp::Ordering::Equal,
}
}
}
impl StrictCmp for Span {
fn strict_cmp(&self, other: &Self) -> std::cmp::Ordering {
self.id()
.strict_cmp(&other.id())
.then_with(|| self.into_raw().cmp(&other.into_raw()))
}
}
impl PartialOrd for Decl {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))

View file

@ -239,8 +239,8 @@ impl DocsChecker<'_> {
.chain([
Type::of::<typst::visualize::Color>(),
Type::of::<typst::visualize::Gradient>(),
Type::of::<typst::visualize::Pattern>(),
Type::of::<typst::symbols::Symbol>(),
Type::of::<typst::visualize::Tiling>(),
Type::of::<typst::foundations::Symbol>(),
Type::of::<typst::foundations::Version>(),
Type::of::<typst::foundations::Bytes>(),
Type::of::<typst::foundations::Label>(),
@ -287,9 +287,9 @@ impl DocsChecker<'_> {
let val = module.scope().get(name)?;
crate::log_debug_ct!("check doc type annotation: {name:?}");
if let Value::Content(raw) = val {
if let Value::Content(raw) = val.read() {
let annotated = raw.clone().unpack::<typst::text::RawElem>().ok()?;
let annotated = annotated.text().clone().into_value().cast::<Str>().ok()?;
let annotated = annotated.text.clone().into_value().cast::<Str>().ok()?;
let code = typst::syntax::parse_code(&annotated.as_str().replace('\'', "θ"));
let mut exprs = code.cast::<ast::Code>()?.exprs();
let term = self.check_type_expr(module, exprs.next()?);

View file

@ -8,7 +8,7 @@ use tinymist_std::hash::hash128;
use typst::{
foundations::{Element, NativeElement, Value},
model::{EmphElem, EnumElem, HeadingElem, ListElem, StrongElem, TermsElem},
syntax::{Span, SyntaxNode},
syntax::{ast::MathTextKind, Span, SyntaxNode},
utils::LazyHash,
};
@ -424,6 +424,12 @@ impl ExprWorker<'_> {
self.check_math([num, denom].iter())
}
MathRoot(root) => self.check(root.radicand()),
MathText(mathtext) => {
Expr::Type(Ty::Value(InsTy::new(Value::Str(match mathtext.get() {
MathTextKind::Character(c) => c.into(),
MathTextKind::Number(n) => n.to_string().into(),
}))))
}
}
}
@ -742,7 +748,9 @@ impl ExprWorker<'_> {
(_, Some(Value::Module(m))) => {
// todo: dyn resolve src_expr
match m.file_id() {
Some(fid) => Some(Expr::Decl(Decl::module(m.name().into(), fid).into())),
Some(fid) => Some(Expr::Decl(
Decl::module(m.name().unwrap().into(), fid).into(),
)),
None => Some(Expr::Type(Ty::Value(InsTy::new(Value::Module(m))))),
}
}
@ -1162,7 +1170,7 @@ impl ExprWorker<'_> {
// v.select(field.name()).ok()
match v {
Ty::Value(val) => {
Some(Ty::Value(InsTy::new(val.val.field(field.name()).ok()?)))
Some(Ty::Value(InsTy::new(val.val.field(field.name(), ()).ok()?)))
}
_ => None,
}
@ -1202,7 +1210,7 @@ impl ExprWorker<'_> {
let val = scope
.get(name)
.cloned()
.map(|val| Ty::Value(InsTy::new(val)));
.map(|val| Ty::Value(InsTy::new(val.read().clone())));
(None, val)
}

View file

@ -10,7 +10,7 @@ use std::{
use once_cell::sync::Lazy;
use serde_json::{ser::PrettyFormatter, Serializer, Value};
use tinymist_project::CompileFontArgs;
use tinymist_project::{CompileFontArgs, ExportTarget};
use tinymist_std::typst::TypstDocument;
use tinymist_world::package::PackageSpec;
use tinymist_world::vfs::WorkspaceResolver;
@ -155,6 +155,7 @@ pub fn run_with_sources<T>(source: &str, f: impl FnOnce(&mut LspUniverse, PathBu
};
let mut verse = LspUniverseBuilder::build(
EntryState::new_rooted(root.as_path().into(), None),
ExportTarget::Paged,
Default::default(),
Arc::new(
LspUniverseBuilder::resolve_fonts(CompileFontArgs {
@ -187,7 +188,7 @@ pub fn run_with_sources<T>(source: &str, f: impl FnOnce(&mut LspUniverse, PathBu
let pw = root.join(Path::new(&path));
verse
.map_shadow(&pw, Bytes::from(source.as_bytes()))
.map_shadow(&pw, Bytes::from_string(source.to_owned()))
.unwrap();
last_pw = Some(pw);
}

View file

@ -121,7 +121,7 @@ impl Ty {
pub(crate) fn from_param_site(func: &Func, param: &ParamInfo) -> Ty {
use typst::foundations::func::Repr;
match func.inner() {
Repr::Element(..) | Repr::Native(..) => {
Repr::Element(..) | Repr::Native(..) | Repr::Plugin(..) => {
if let Some(ty) = param_mapping(func, param) {
return ty;
}
@ -137,7 +137,7 @@ impl Ty {
use typst::foundations::func::Repr;
match func.inner() {
Repr::Element(elem) => return Ty::Builtin(BuiltinTy::Element(*elem)),
Repr::Closure(_) => {}
Repr::Closure(_) | Repr::Plugin(_) => {}
Repr::With(w) => return Ty::from_return_site(&w.0, ty),
Repr::Native(_) => {}
};

View file

@ -183,7 +183,7 @@ impl Ty {
Ty::Builtin(BuiltinTy::Module(m)) => m.name().clone(),
ty => ty
.value()
.and_then(|v| Some(Interned::new_str(v.name()?)))
.map(|_| Interned::new_str(&self.name()))
.unwrap_or_default(),
}
}
@ -253,7 +253,7 @@ impl Ty {
}
fn is_content_builtin_type(ty: &Type) -> bool {
*ty == Type::of::<Content>() || *ty == Type::of::<typst::symbols::Symbol>()
*ty == Type::of::<Content>() || *ty == Type::of::<typst::foundations::Symbol>()
}
/// A function parameter type
@ -646,6 +646,14 @@ impl Ord for TypeVar {
}
}
impl TypeVar {
/// Low-performance comparison but it is free from the concurrency issue.
/// This is only used for making stable test snapshots.
pub fn strict_cmp(&self, other: &Self) -> std::cmp::Ordering {
self.def.strict_cmp(&other.def)
}
}
impl PartialOrd for TypeVar {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))

View file

@ -196,7 +196,7 @@ impl TypeDescriber {
let Value::Module(m) = &v.val else {
return "module".into();
};
return eco_format!("module({})", m.name());
return eco_format!("module({})", m.name().unwrap());
}
Ty::Value(v) if !is_plain_value(&v.val) => return self.describe(&term_value(&v.val)),
Ty::Value(v) if self.value => return truncated_repr_::<181>(&v.val),

View file

@ -1,8 +1,5 @@
use typst::foundations::{Dict, Module, Scope, Type};
use typst::syntax::FileId;
use typst::{
foundations::{Dict, Module, Scope, Type},
syntax::Span,
};
use super::BoundChecker;
use crate::{syntax::Decl, ty::prelude::*};
@ -56,8 +53,8 @@ impl Iface<'_> {
fn select_scope(scope: Option<&Scope>, key: &str) -> Option<Ty> {
let scope = scope?;
let sub = scope.get(key)?;
let sub_span = scope.get_span(key).unwrap_or_else(Span::detached);
Some(Ty::Value(InsTy::new_at(sub.clone(), sub_span)))
let sub_span = sub.span();
Some(Ty::Value(InsTy::new_at(sub.read().clone(), sub_span)))
}
pub trait IfaceChecker: TyCtx {

View file

@ -7,7 +7,7 @@ use serde::Deserialize;
use serde_yaml as yaml;
use typst::{
diag::{bail, StrResult},
foundations::{Content, Func, Module, Type, Value},
foundations::{Binding, Content, Func, Module, Type, Value},
introspection::MetadataElem,
syntax::Span,
text::{FontInfo, FontStyle},
@ -113,8 +113,8 @@ static GROUPS: Lazy<Vec<GroupData>> = Lazy::new(|| {
.module()
.scope()
.iter()
.filter(|(_, v, _)| matches!(v, Value::Func(_)))
.map(|(k, _, _)| k.clone())
.filter(|(_, v)| matches!(v.read(), Value::Func(_)))
.map(|(k, _)| k.clone())
.collect();
}
}
@ -175,7 +175,7 @@ static LIBRARY: Lazy<Library> = Lazy::new(Library::default);
/// Extract a module from another module.
#[track_caller]
fn get_module<'a>(parent: &'a Module, name: &str) -> StrResult<&'a Module> {
match parent.scope().get(name) {
match parent.scope().get(name).map(|x| x.read()) {
Some(Value::Module(module)) => Ok(module),
_ => bail!("module doesn't contain module `{name}`"),
}
@ -189,7 +189,7 @@ fn resolve_definition(head: &str, base: &str) -> StrResult<String> {
while let Some(name) = parts.peek() {
if category.is_none() {
category = focus.scope().get_category(name);
category = focus.scope().get(name).and_then(Binding::category);
}
let Ok(module) = get_module(focus, name) else {
break;
@ -203,7 +203,7 @@ fn resolve_definition(head: &str, base: &str) -> StrResult<String> {
};
let name = parts.next().ok_or("link is missing first part")?;
let value = focus.field(name)?;
let value = focus.field(name, ())?;
// Handle grouped functions.
if let Some(group) = GROUPS.iter().find(|group| {
@ -222,7 +222,7 @@ fn resolve_definition(head: &str, base: &str) -> StrResult<String> {
let mut route = format!("{}reference/{}/{name}", base, category.name());
if let Some(next) = parts.next() {
if let Ok(field) = value.field(next) {
if let Ok(field) = value.field(next, ()) {
route.push_str("/#definitions-");
route.push_str(next);
if let Some(next) = parts.next() {
@ -283,10 +283,10 @@ static ROUTE_MAPS: Lazy<HashMap<CatKey, String>> = Lazy::new(|| {
(LIBRARY.math.scope(), None, None),
];
while let Some((scope, parent_name, cat)) = scope_to_finds.pop() {
for (name, value, _) in scope.iter() {
let cat = cat.or_else(|| scope.get_category(name));
for (name, bind) in scope.iter() {
let cat = cat.or_else(|| bind.category());
let name = urlify(name);
match value {
match bind.read() {
Value::Func(func) => {
if let Some(cat) = cat {
let Some(name) = func.name() else {
@ -437,6 +437,7 @@ pub fn with_vm<T>(
let traced = Traced::default();
let mut sink = Sink::new();
let engine = Engine {
routines: &typst::ROUTINES,
world,
route: Route::default(),
introspector: introspector.track(),

View file

@ -148,7 +148,7 @@ fn closure_tooltip(leaf: &LinkedNode) -> Option<Tooltip> {
let captures = visitor.finish();
let mut names: Vec<_> = captures
.iter()
.map(|(name, _, _)| eco_format!("`{name}`"))
.map(|(name, _)| eco_format!("`{name}`"))
.collect();
if names.is_empty() {
return None;
@ -193,7 +193,7 @@ fn named_param_tooltip(world: &dyn World, leaf: &LinkedNode) -> Option<Tooltip>
};
// Find metadata about the function.
if let Some(Value::Func(func)) = world.library().global.scope().get(&callee);
if let Some(Value::Func(func)) = world.library().global.scope().get(&callee).map(|x| x.read());
then { (func, named) }
else { return None; }
};

View file

@ -127,6 +127,7 @@ impl PeriscopeRenderer {
Some((SvgText::join(svg_text), width, height))
}
_ => None,
}
}
}

View file

@ -12,7 +12,11 @@ pub(crate) mod well_known {
pub use typst::layout::Abs as TypstAbs;
pub use typst::model::Document as TypstPagedDocument;
pub use typst::Document as TypstDocumentTrait;
pub use typst::layout::PagedDocument as TypstPagedDocument;
pub use typst::html::HtmlDocument as TypstHtmlDocument;
pub use typst::text::Font as TypstFont;
@ -28,13 +32,24 @@ pub(crate) mod well_known {
pub enum TypstDocument {
/// The document compiled with `paged` target.
Paged(Arc<well_known::TypstPagedDocument>),
/// The document compiled with `html` target.
Html(Arc<well_known::TypstHtmlDocument>),
}
impl TypstDocument {
/// Gets the number of pages in the document.
pub fn num_of_pages(&self) -> u32 {
match self {
Self::Paged(doc) => doc.pages.len() as u32,
Self::Html(_doc) => 1u32,
}
}
/// Gets details about the document.
pub fn info(&self) -> &typst::model::DocumentInfo {
match self {
Self::Paged(doc) => &doc.info,
Self::Html(doc) => &doc.info,
}
}
@ -43,6 +58,45 @@ impl TypstDocument {
pub fn introspector(&self) -> &typst::introspection::Introspector {
match self {
Self::Paged(doc) => &doc.introspector,
Self::Html(doc) => &doc.introspector,
}
}
}
impl From<Arc<well_known::TypstPagedDocument>> for TypstDocument {
fn from(doc: Arc<well_known::TypstPagedDocument>) -> Self {
Self::Paged(doc)
}
}
impl From<Arc<well_known::TypstHtmlDocument>> for TypstDocument {
fn from(doc: Arc<well_known::TypstHtmlDocument>) -> Self {
Self::Html(doc)
}
}
impl<'a> TryFrom<&'a TypstDocument> for &'a Arc<well_known::TypstPagedDocument> {
type Error = crate::Error;
fn try_from(doc: &'a TypstDocument) -> Result<Self, Self::Error> {
match doc {
TypstDocument::Paged(doc) => Ok(doc),
TypstDocument::Html(_doc) => {
crate::bail!("The document is compiled with `html` target, not `paged`.")
}
}
}
}
impl<'a> TryFrom<&'a TypstDocument> for &'a Arc<well_known::TypstHtmlDocument> {
type Error = crate::Error;
fn try_from(doc: &'a TypstDocument) -> Result<Self, Self::Error> {
match doc {
TypstDocument::Paged(_doc) => {
crate::bail!("The document is compiled with `paged` target, not `html`.")
}
TypstDocument::Html(doc) => Ok(doc),
}
}
}

View file

@ -34,10 +34,12 @@ tinymist-derive.workspace = true
toml.workspace = true
typst.workspace = true
typst-assets.workspace = true
typst-eval.workspace = true
typst-html.workspace = true
typst-pdf.workspace = true
typst-render.workspace = true
typst-shim.workspace = true
typst-svg.workspace = true
typst-render.workspace = true
notify.workspace = true
[features]

View file

@ -0,0 +1,3 @@
# tinymist-task
Task model of typst for tinymist.

View file

@ -6,21 +6,18 @@ use std::sync::Arc;
use comemo::Track;
use ecow::EcoString;
use tinymist_std::error::prelude::*;
use tinymist_std::typst::TypstPagedDocument;
use tinymist_world::{
args::convert_source_date_epoch, CompileSnapshot, CompilerFeat, ExportComputation,
WorldComputeGraph,
};
use tinymist_std::typst::{TypstDocument, TypstHtmlDocument, TypstPagedDocument};
use tinymist_world::{CompileSnapshot, CompilerFeat, ExportComputation, WorldComputeGraph};
use typst::diag::{SourceResult, StrResult};
use typst::foundations::{Bytes, Content, Datetime, IntoValue, LocatableSelector, Scope, Value};
use typst::foundations::{Bytes, Content, IntoValue, LocatableSelector, Scope, Value};
use typst::layout::Abs;
use typst::routines::EvalMode;
use typst::syntax::{ast, Span, SyntaxNode};
use typst::visualize::Color;
use typst::World;
use typst_pdf::PdfOptions;
use typst_shim::eval::EvalMode;
use typst_eval::eval_string;
use crate::model::{ExportPdfTask, ExportPngTask, ExportSvgTask};
use crate::model::{ExportHtmlTask, ExportPngTask, ExportSvgTask};
use crate::primitives::TaskWhen;
use crate::{ExportTransform, Pages, QueryTask};
@ -40,10 +37,10 @@ pub struct HtmlFlag;
pub struct ExportTimings;
impl ExportTimings {
pub fn needs_run<F: CompilerFeat>(
pub fn needs_run<F: CompilerFeat, D: typst::Document>(
snap: &CompileSnapshot<F>,
timing: Option<TaskWhen>,
docs: Option<&TypstPagedDocument>,
docs: Option<&D>,
) -> Option<bool> {
let s = snap.signal;
let when = timing.unwrap_or(TaskWhen::Never);
@ -56,7 +53,7 @@ impl ExportTimings {
TaskWhen::OnType => Some(s.by_mem_events),
TaskWhen::OnSave => Some(s.by_fs_events),
TaskWhen::OnDocumentHasTitle if s.by_fs_events => {
docs.map(|doc| doc.info.title.is_some())
docs.map(|doc| doc.info().title.is_some())
}
TaskWhen::OnDocumentHasTitle => Some(false),
}
@ -135,7 +132,7 @@ impl<F: CompilerFeat> ExportComputation<F, TypstPagedDocument> for PngExport {
pixmap
.encode_png()
.map(Bytes::from)
.map(Bytes::new)
.context_ut("failed to encode PNG")
}
}
@ -148,6 +145,21 @@ impl<F: CompilerFeat> ExportComputation<F, TypstPagedDocument> for PngExport {
// }
// }
pub struct HtmlExport;
impl<F: CompilerFeat> ExportComputation<F, TypstHtmlDocument> for HtmlExport {
type Output = String;
type Config = ExportHtmlTask;
fn run(
_graph: &Arc<WorldComputeGraph<F>>,
doc: &Arc<TypstHtmlDocument>,
_config: &ExportHtmlTask,
) -> Result<String> {
Ok(typst_html::html(doc)?)
}
}
// impl<F: CompilerFeat> WorldComputable<F> for HtmlExport {
// type Output = Option<String>;
@ -161,12 +173,13 @@ pub struct DocumentQuery;
impl DocumentQuery {
// todo: query exporter
/// Retrieve the matches for the selector.
pub fn retrieve(
pub fn retrieve<D: typst::Document>(
world: &dyn World,
selector: &str,
document: &TypstPagedDocument,
document: &D,
) -> StrResult<Vec<Content>> {
let selector = typst_shim::eval::eval_string(
let selector = eval_string(
&typst::ROUTINES,
world.track(),
selector,
Span::detached(),
@ -185,15 +198,15 @@ impl DocumentQuery {
.map_err(|e| EcoString::from(format!("failed to cast: {}", e.message())))?;
Ok(document
.introspector
.introspector()
.query(&selector.0)
.into_iter()
.collect::<Vec<_>>())
}
fn run_inner<F: CompilerFeat>(
fn run_inner<F: CompilerFeat, D: typst::Document>(
g: &Arc<WorldComputeGraph<F>>,
doc: &Arc<TypstPagedDocument>,
doc: &Arc<D>,
config: &QueryTask,
) -> Result<Vec<Value>> {
let selector = &config.selector;
@ -212,9 +225,20 @@ impl DocumentQuery {
.collect())
}
pub fn get_as_value<F: CompilerFeat>(
pub fn doc_get_as_value<F: CompilerFeat>(
g: &Arc<WorldComputeGraph<F>>,
doc: &Arc<TypstPagedDocument>,
doc: &TypstDocument,
config: &QueryTask,
) -> Result<serde_json::Value> {
match doc {
TypstDocument::Paged(doc) => Self::get_as_value(g, doc, config),
TypstDocument::Html(doc) => Self::get_as_value(g, doc, config),
}
}
pub fn get_as_value<F: CompilerFeat, D: typst::Document>(
g: &Arc<WorldComputeGraph<F>>,
doc: &Arc<D>,
config: &QueryTask,
) -> Result<serde_json::Value> {
let mapped = Self::run_inner(g, doc, config)?;
@ -232,13 +256,13 @@ impl DocumentQuery {
}
}
impl<F: CompilerFeat> ExportComputation<F, TypstPagedDocument> for DocumentQuery {
impl<F: CompilerFeat, D: typst::Document> ExportComputation<F, D> for DocumentQuery {
type Output = SourceResult<String>;
type Config = QueryTask;
fn run(
g: &Arc<WorldComputeGraph<F>>,
doc: &Arc<TypstPagedDocument>,
doc: &Arc<D>,
config: &QueryTask,
) -> Result<SourceResult<String>> {
let pretty = false;
@ -356,19 +380,6 @@ fn parse_color(fill: String) -> anyhow::Result<Color> {
}
}
/// Convert [`chrono::DateTime`] to [`Datetime`]
fn convert_datetime(date_time: chrono::DateTime<chrono::Utc>) -> Option<Datetime> {
use chrono::{Datelike, Timelike};
Datetime::from_ymd_hms(
date_time.year(),
date_time.month().try_into().ok()?,
date_time.day().try_into().ok()?,
date_time.hour().try_into().ok()?,
date_time.minute().try_into().ok()?,
date_time.second().try_into().ok()?,
)
}
#[cfg(test)]
mod tests {

View file

@ -1,7 +1,12 @@
use super::*;
use crate::model::ExportPdfTask;
use tinymist_world::args::convert_source_date_epoch;
use typst::foundations::Datetime;
pub use typst_pdf::pdf;
use typst_pdf::PdfOptions;
pub use typst_pdf::PdfStandard as TypstPdfStandard;
use typst_pdf::Timestamp;
pub struct PdfExport;
impl<F: CompilerFeat> ExportComputation<F, TypstPagedDocument> for PdfExport {
@ -23,7 +28,7 @@ impl<F: CompilerFeat> ExportComputation<F, TypstPagedDocument> for PdfExport {
// todo: Some(pdf_uri.as_str())
Ok(Bytes::from(typst_pdf::pdf(
Ok(Bytes::new(typst_pdf::pdf(
doc,
&PdfOptions {
timestamp: convert_datetime(creation_timestamp),
@ -33,6 +38,19 @@ impl<F: CompilerFeat> ExportComputation<F, TypstPagedDocument> for PdfExport {
}
}
/// Convert [`chrono::DateTime`] to [`Timestamp`]
pub fn convert_datetime(date_time: chrono::DateTime<chrono::Utc>) -> Option<Timestamp> {
use chrono::{Datelike, Timelike};
Some(Timestamp::new_utc(Datetime::from_ymd_hms(
date_time.year(),
date_time.month().try_into().ok()?,
date_time.day().try_into().ok()?,
date_time.hour().try_into().ok()?,
date_time.minute().try_into().ok()?,
date_time.second().try_into().ok()?,
)?))
}
// impl<F: CompilerFeat> WorldComputable<F> for PdfExport {
// type Output = Option<Bytes>;

View file

@ -10,7 +10,7 @@ pub struct TextExport;
impl TextExport {
pub fn run_on_doc(doc: &TypstDocument) -> Result<String> {
Ok(format!("{}", FullTextDigest(doc.clone())))
Ok(format!("{}", FullTextDigest(doc)))
}
}
@ -28,9 +28,9 @@ impl<F: CompilerFeat> ExportComputation<F, TypstPagedDocument> for TextExport {
}
/// A full text digest of a document.
pub struct FullTextDigest(pub TypstDocument);
struct FullTextDigest<'a>(&'a TypstDocument);
impl FullTextDigest {
impl FullTextDigest<'_> {
fn export_frame(f: &mut fmt::Formatter<'_>, doc: &typst::layout::Frame) -> fmt::Result {
for (_, item) in doc.items() {
Self::export_item(f, item)?;
@ -55,9 +55,26 @@ impl FullTextDigest {
Link(..) | Tag(..) | Shape(..) | Image(..) => Ok(()),
}
}
fn export_element(f: &mut fmt::Formatter<'_>, elem: &typst::html::HtmlElement) -> fmt::Result {
for child in elem.children.iter() {
Self::export_html_node(f, child)?;
}
Ok(())
}
impl fmt::Display for FullTextDigest {
fn export_html_node(f: &mut fmt::Formatter<'_>, node: &typst::html::HtmlNode) -> fmt::Result {
use typst::html::HtmlNode::*;
match node {
Tag(_) => Ok(()),
Element(elem) => Self::export_element(f, elem),
Text(t, _) => f.write_str(t.as_str()),
Frame(frame) => Self::export_frame(f, frame),
}
}
}
impl fmt::Display for FullTextDigest<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
TypstDocument::Paged(paged_doc) => {
@ -66,6 +83,10 @@ impl fmt::Display for FullTextDigest {
}
Ok(())
}
TypstDocument::Html(html_doc) => {
Self::export_element(f, &html_doc.root)?;
Ok(())
}
}
}
}

View file

@ -68,6 +68,8 @@ pub enum ProjectTask {
ExportSvg(ExportSvgTask),
/// An export HTML task.
ExportHtml(ExportHtmlTask),
/// An export HTML task.
ExportSvgHtml(ExportHtmlTask),
/// An export Markdown task.
ExportMd(ExportMarkdownTask),
/// An export Text task.
@ -88,6 +90,7 @@ impl ProjectTask {
| Self::ExportPng(..)
| Self::ExportSvg(..)
| Self::ExportHtml(..)
| Self::ExportSvgHtml(..)
| Self::ExportMd(..)
| Self::ExportText(..)
| Self::Query(..) => self.as_export()?.when,
@ -102,6 +105,7 @@ impl ProjectTask {
Self::ExportPng(task) => &task.export,
Self::ExportSvg(task) => &task.export,
Self::ExportHtml(task) => &task.export,
Self::ExportSvgHtml(task) => &task.export,
Self::ExportMd(task) => &task.export,
Self::ExportText(task) => &task.export,
Self::Query(task) => &task.export,
@ -112,7 +116,7 @@ impl ProjectTask {
pub fn extension(&self) -> &str {
match self {
Self::ExportPdf { .. } => "pdf",
Self::Preview(..) | Self::ExportHtml { .. } => "html",
Self::Preview(..) | Self::ExportSvgHtml { .. } | Self::ExportHtml { .. } => "html",
Self::ExportMd { .. } => "md",
Self::ExportText { .. } => "txt",
Self::ExportSvg { .. } => "svg",

View file

@ -236,6 +236,21 @@ impl PathPattern {
}
}
/// Specifies the current export target.
///
/// The design of this configuration is not yet finalized and for this reason it
/// is guarded behind the html feature. Visit the HTML documentation page for
/// more details.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ExportTarget {
/// The current export target is for PDF, PNG, and SVG export.
#[default]
Paged,
/// The current export target is for Html export.
Html,
}
/// A PDF standard that Typst can enforce conformance with.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, ValueEnum, Serialize, Deserialize)]
#[allow(non_camel_case_types)]

View file

@ -55,7 +55,7 @@ impl PathAccessModel for ProxyAccessModel {
})?;
let data = if let Some(data) = data.dyn_ref::<js_sys::Uint8Array>() {
Bytes::from(data.to_vec())
Bytes::new(data.to_vec())
} else {
return Err(FileError::AccessDenied);
};

View file

@ -34,7 +34,7 @@ impl PathAccessModel for SystemAccessModel {
.map_err(f)?
.read_to_end(&mut buf)
.map_err(f)?;
Ok(buf.into())
Ok(Bytes::new(buf))
}
}

View file

@ -45,8 +45,10 @@ impl TypstBrowserUniverse {
let vfs = tinymist_vfs::Vfs::new(resolver, access_model);
// todo: enable html
Self::new_raw(
EntryState::new_rooted(root_dir.into(), None),
false,
inputs,
vfs,
registry,

View file

@ -1,13 +1,14 @@
#![allow(missing_docs)]
use std::any::TypeId;
use std::borrow::Cow;
use std::sync::{Arc, OnceLock};
use ecow::EcoVec;
use parking_lot::Mutex;
use tinymist_std::error::prelude::*;
use tinymist_std::typst::TypstPagedDocument;
use tinymist_std::typst::{TypstHtmlDocument, TypstPagedDocument};
use typst::diag::{At, SourceResult, Warned};
use typst::ecow::EcoVec;
use typst::syntax::Span;
use crate::snapshot::CompileSnapshot;
@ -126,7 +127,7 @@ impl<F: CompilerFeat> WorldComputeGraph<F> {
ins: Result<Arc<T::Output>>,
) -> Result<(), Result<Arc<T::Output>>> {
let entry = self.computed(TypeId::of::<T>()).computed;
let initialized = entry.set(ins.map(|e| Arc::new(e) as AnyArc));
let initialized = entry.set(ins.map(|e| e as AnyArc));
initialized.map_err(WorldComputeEntry::cast)
}
@ -149,9 +150,6 @@ impl<F: CompilerFeat> WorldComputeGraph<F> {
}
}
pub trait Document {}
impl Document for TypstPagedDocument {}
pub trait ExportDetection<F: CompilerFeat, D> {
type Config: Send + Sync + 'static;
@ -171,6 +169,17 @@ pub trait ExportComputation<F: CompilerFeat, D> {
Self::run(g, doc, config)
}
fn cast_run<'a>(
g: &Arc<WorldComputeGraph<F>>,
doc: impl TryInto<&'a Arc<D>, Error = tinymist_std::Error>,
config: &Self::Config,
) -> Result<Self::Output>
where
D: 'a,
{
Self::run(g, doc.try_into()?, config)
}
fn run(
g: &Arc<WorldComputeGraph<F>>,
doc: &Arc<D>,
@ -205,25 +214,51 @@ impl<T> FlagTask<T> {
}
pub type PagedCompilationTask = CompilationTask<TypstPagedDocument>;
pub type HtmlCompilationTask = CompilationTask<TypstHtmlDocument>;
pub struct CompilationTask<D>(std::marker::PhantomData<D>);
impl<F: CompilerFeat> WorldComputable<F> for CompilationTask<TypstPagedDocument> {
type Output = Option<Warned<SourceResult<Arc<TypstPagedDocument>>>>;
impl<F: CompilerFeat, D> WorldComputable<F> for CompilationTask<D>
where
D: typst::Document + Send + Sync + 'static,
{
type Output = Option<Warned<SourceResult<Arc<D>>>>;
fn compute(graph: &Arc<WorldComputeGraph<F>>) -> Result<Self::Output> {
let enabled = graph
.must_get::<FlagTask<CompilationTask<TypstPagedDocument>>>()?
.enabled;
let enabled = graph.must_get::<FlagTask<CompilationTask<D>>>()?.enabled;
Ok(enabled.then(|| {
let mut world = graph.snap.world.clone();
world.set_is_compiling(true);
let compiled = typst::compile(&world);
world.set_is_compiling(false);
// todo: create html world once
let is_paged_compilation = TypeId::of::<D>() == TypeId::of::<TypstPagedDocument>();
let is_html_compilation = TypeId::of::<D>() == TypeId::of::<TypstHtmlDocument>();
let mut world = if is_paged_compilation {
graph.snap.world.paged_task()
} else if is_html_compilation {
graph.snap.world.html_task()
} else {
Cow::Borrowed(&graph.snap.world)
};
world.to_mut().set_is_compiling(true);
let compiled = typst::compile::<D>(world.as_ref());
world.to_mut().set_is_compiling(false);
let exclude_html_warnings = if !is_html_compilation {
compiled.warnings
} else if compiled.warnings.len() == 1
&& compiled.warnings[0]
.message
.starts_with("html export is under active development")
{
EcoVec::new()
} else {
compiled.warnings
};
Warned {
output: compiled.output.map(Arc::new),
warnings: compiled.warnings,
warnings: exclude_html_warnings,
}
}))
}
@ -231,18 +266,25 @@ impl<F: CompilerFeat> WorldComputable<F> for CompilationTask<TypstPagedDocument>
pub struct OptionDocumentTask<D>(std::marker::PhantomData<D>);
impl<F: CompilerFeat> WorldComputable<F> for OptionDocumentTask<TypstPagedDocument> {
type Output = Option<Arc<TypstPagedDocument>>;
impl<F: CompilerFeat, D> WorldComputable<F> for OptionDocumentTask<D>
where
D: typst::Document + Send + Sync + 'static,
{
type Output = Option<Arc<D>>;
fn compute(graph: &Arc<WorldComputeGraph<F>>) -> Result<Self::Output> {
let doc = graph.compute::<CompilationTask<TypstPagedDocument>>()?;
let doc = doc.as_ref().as_ref();
let compiled = doc.and_then(|warned| warned.output.clone().ok());
let doc = graph.compute::<CompilationTask<D>>()?;
let compiled = doc
.as_ref()
.as_ref()
.and_then(|warned| warned.output.clone().ok());
Ok(compiled)
}
}
impl<D> OptionDocumentTask<D> where D: typst::Document + Send + Sync + 'static {}
struct CompilationDiagnostics {
errors: Option<EcoVec<typst::diag::SourceDiagnostic>>,
warnings: Option<EcoVec<typst::diag::SourceDiagnostic>>,
@ -261,6 +303,7 @@ impl CompilationDiagnostics {
pub struct DiagnosticsTask {
paged: CompilationDiagnostics,
html: CompilationDiagnostics,
}
impl<F: CompilerFeat> WorldComputable<F> for DiagnosticsTask {
@ -268,19 +311,33 @@ impl<F: CompilerFeat> WorldComputable<F> for DiagnosticsTask {
fn compute(graph: &Arc<WorldComputeGraph<F>>) -> Result<Self> {
let paged = graph.compute::<PagedCompilationTask>()?.clone();
let html = graph.compute::<HtmlCompilationTask>()?.clone();
Ok(Self {
paged: CompilationDiagnostics::from_result(paged.as_ref()),
paged: CompilationDiagnostics::from_result(&paged),
html: CompilationDiagnostics::from_result(&html),
})
}
}
impl DiagnosticsTask {
pub fn error_cnt(&self) -> usize {
self.paged.errors.as_ref().map_or(0, |e| e.len())
+ self.html.errors.as_ref().map_or(0, |e| e.len())
}
pub fn warning_cnt(&self) -> usize {
self.paged.warnings.as_ref().map_or(0, |e| e.len())
+ self.html.warnings.as_ref().map_or(0, |e| e.len())
}
pub fn diagnostics(&self) -> impl Iterator<Item = &typst::diag::SourceDiagnostic> {
self.paged
.errors
.iter()
.chain(self.paged.warnings.iter())
.chain(self.html.errors.iter())
.chain(self.html.warnings.iter())
.flatten()
}
}
@ -347,7 +404,7 @@ impl<F: CompilerFeat> WorldComputeGraph<F> {
}
/// Compile once from scratch.
pub fn pure_compile(&self) -> Warned<SourceResult<Arc<TypstPagedDocument>>> {
pub fn pure_compile<D: ::typst::Document>(&self) -> Warned<SourceResult<Arc<D>>> {
let res = self.ensure_main();
if let Err(err) = res {
return Warned {
@ -356,7 +413,7 @@ impl<F: CompilerFeat> WorldComputeGraph<F> {
};
}
let res = ::typst::compile(&self.snap.world);
let res = ::typst::compile::<D>(&self.snap.world);
// compile document
Warned {
output: res.output.map(Arc::new),
@ -368,4 +425,14 @@ impl<F: CompilerFeat> WorldComputeGraph<F> {
pub fn compile(&self) -> Warned<SourceResult<Arc<TypstPagedDocument>>> {
self.pure_compile()
}
/// Compile to html once from scratch.
pub fn compile_html(&self) -> Warned<SourceResult<Arc<::typst::html::HtmlDocument>>> {
self.pure_compile()
}
// With **the compilation state**, query the matches for the selector.
// fn query(&mut self, selector: String, document: &TypstDocument) ->
// SourceResult<Vec<Content>> { self.pure_query(world, selector,
// document) }
}

View file

@ -38,6 +38,6 @@ impl<R: ReadAllOnce + Sized> FontLoader for LazyBufferFontLoader<R> {
fn load(&mut self) -> Option<Font> {
let mut buf = vec![];
self.read.take().unwrap().read_all(&mut buf).ok()?;
Font::new(buf.into(), self.index)
Font::new(Bytes::new(buf), self.index)
}
}

View file

@ -136,8 +136,8 @@ impl SystemFontSearcher {
// Source3: add the fonts in memory.
for font_data in opts.with_embedded_fonts {
self.add_memory_font(match font_data {
Cow::Borrowed(data) => Bytes::from_static(data),
Cow::Owned(data) => Bytes::from(data),
Cow::Borrowed(data) => Bytes::new(data),
Cow::Owned(data) => Bytes::new(data),
});
}

View file

@ -368,7 +368,7 @@ impl FontLoader for WebFontLoader {
);
// let blob = pollster::block_on(JsFuture::from(blob.array_buffer())).unwrap();
let blob = font.load()?;
let blob = Bytes::from(js_sys::Uint8Array::new(&blob).to_vec());
let blob = Bytes::new(js_sys::Uint8Array::new(&blob).to_vec());
Font::new(blob, self.index)
}
@ -406,7 +406,7 @@ impl BrowserFontSearcher {
/// Add fonts that are embedded in the binary.
pub fn add_embedded(&mut self) {
for font_data in typst_assets::fonts() {
let buffer = Bytes::from_static(font_data);
let buffer = Bytes::new(font_data);
for font in Font::iter(buffer) {
self.book.push(font.info().clone());
self.fonts.push(FontSlot::with_value(Some(font)));

Some files were not shown because too many files have changed in this diff Show more