typst_shim/nightly/
syntax.rs

1//! Typst Syntax
2use std::ops::Range;
3use std::path::Path;
4
5use typst::syntax::DiagSpan;
6use typst::syntax::DiagSpanKind;
7use typst::syntax::LinkedNode;
8use typst::syntax::RootedPath;
9use typst::syntax::Side;
10use typst::syntax::Source;
11use typst::syntax::VirtualPath;
12use typst::syntax::VirtualRoot;
13use typst::syntax::package::PackageSpec;
14
15pub use crate::path::resolve_path_from_id;
16
17/// Get the byte range for a diagnostic span within a source file.
18pub fn source_range(source: &Source, span: impl Into<DiagSpan>) -> Option<Range<usize>> {
19    match span.into().get() {
20        DiagSpanKind::Detached => None,
21        DiagSpanKind::Number { id, num, sub_range } if id == source.id() => {
22            source.range(num, sub_range)
23        }
24        DiagSpanKind::Range { id, range } if id == source.id() => Some(range),
25        _ => None,
26    }
27}
28
29/// The `LinkedNodeExt` trait is designed for compatibility between new and old
30/// versions of `typst`.
31pub trait LinkedNodeExt: Sized {
32    /// Get the leaf at the specified byte offset.
33    fn leaf_at_compat(&self, cursor: usize) -> Option<Self>;
34}
35
36impl LinkedNodeExt for LinkedNode<'_> {
37    fn leaf_at_compat(&self, cursor: usize) -> Option<Self> {
38        self.leaf_at(cursor, Side::Before)
39    }
40}
41
42/// The `VirtualPathExt` trait is designed for compatibility between new and old
43/// versions of `typst`.
44pub trait VirtualPathExt {
45    /// Get the underlying path with a leading `/` or `\`.
46    fn as_rooted_path_compat(&self) -> &Path;
47
48    /// Get the underlying path without a leading `/` or `\`.
49    fn as_rootless_path_compat(&self) -> &Path;
50}
51
52impl VirtualPathExt for VirtualPath {
53    fn as_rooted_path_compat(&self) -> &Path {
54        Path::new(self.get_with_slash())
55    }
56
57    fn as_rootless_path_compat(&self) -> &Path {
58        Path::new(self.get_without_slash())
59    }
60}
61
62/// The `RootedPathExt` trait is designed for compatibility between new and old
63/// versions of `typst`.
64pub trait RootedPathExt {
65    /// The package the path resides in, if any.
66    fn package_compat(&self) -> Option<&PackageSpec>;
67}
68
69impl RootedPathExt for RootedPath {
70    fn package_compat(&self) -> Option<&PackageSpec> {
71        match self.root() {
72            VirtualRoot::Project => None,
73            VirtualRoot::Package(package) => Some(package),
74        }
75    }
76}