feat: convert TypstDocument to enum (#1256)

* feat: convert `TypstDocument` to enum

* fix: errors

* build: update cargo.lock

* fix: warnings

* fix: error

* html changes

* Revert "html changes"

This reverts commit f9fc0e4872.

* Revert "Revert "html changes""

This reverts commit 7dc554a9e4.

* use std typst docs

* span

* paged

* paged

* html change

* paged

* html change

* bytes

* paged

* paged

* paged

* html changes

* paged

* html changes

* paged
This commit is contained in:
Myriad-Dreamin 2025-02-03 11:17:58 +08:00 committed by GitHub
parent 30a08e79ab
commit 3bc5f19cf5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 237 additions and 123 deletions

3
Cargo.lock generated
View file

@ -4165,9 +4165,11 @@ version = "0.12.18"
dependencies = [
"base64",
"log",
"reflexo-typst",
"reflexo-vec2svg",
"serde",
"tinymist-query",
"tinymist-std",
]
[[package]]
@ -4651,6 +4653,7 @@ dependencies = [
"serde",
"serde_json",
"tinymist-assets 0.12.18 (registry+https://github.com/rust-lang/crates.io-index)",
"tinymist-std",
"tokio",
"typst",
"typst-assets",

View file

@ -7,9 +7,9 @@ use std::sync::{Arc, OnceLock};
use ecow::{eco_vec, EcoString, EcoVec};
use reflexo_typst::features::{CompileFeature, FeatureSet, WITH_COMPILING_STATUS_FEATURE};
use reflexo_typst::{CompileEnv, CompileReport, Compiler, TypstDocument};
use reflexo_typst::{CompileEnv, CompileReport, Compiler};
use tinymist_std::error::prelude::Result;
use tinymist_std::ImmutPath;
use tinymist_std::{typst::TypstDocument, ImmutPath};
use tinymist_world::vfs::notify::{
FilesystemEvent, MemoryEvent, NotifyDeps, NotifyMessage, UpstreamUpdateEvent,
};
@ -70,7 +70,7 @@ pub struct CompileSnapshot<F: CompilerFeat> {
/// Using world
pub world: CompilerWorld<F>,
/// The last successfully compiled document.
pub success_doc: Option<Arc<TypstDocument>>,
pub success_doc: Option<TypstDocument>,
}
impl<F: CompilerFeat + 'static> CompileSnapshot<F> {
@ -118,7 +118,7 @@ impl<F: CompilerFeat + 'static> CompileSnapshot<F> {
let warned = std::marker::PhantomData.compile(&snap.world, &mut snap.env);
snap.world.set_is_compiling(false);
let (doc, warnings) = match warned {
Ok(doc) => (Ok(doc.output), doc.warnings),
Ok(doc) => (Ok(TypstDocument::Paged(doc.output)), doc.warnings),
Err(err) => (Err(err), EcoVec::default()),
};
CompiledArtifact {
@ -149,7 +149,7 @@ pub struct CompiledArtifact<F: CompilerFeat> {
/// The diagnostics of the document.
pub warnings: EcoVec<SourceDiagnostic>,
/// The compiled document.
pub doc: SourceResult<Arc<TypstDocument>>,
pub doc: SourceResult<TypstDocument>,
/// The depended files.
pub deps: OnceLock<EcoVec<FileId>>,
}
@ -182,7 +182,7 @@ impl<F: CompilerFeat> Clone for CompiledArtifact<F> {
impl<F: CompilerFeat> CompiledArtifact<F> {
/// Returns the last successfully compiled document.
pub fn success_doc(&self) -> Option<Arc<TypstDocument>> {
pub fn success_doc(&self) -> Option<TypstDocument> {
self.doc
.as_ref()
.ok()
@ -736,9 +736,9 @@ pub struct ProjectInsState<F: CompilerFeat, Ext> {
deps: EcoVec<ImmutPath>,
/// The latest compiled document.
pub(crate) latest_doc: Option<Arc<TypstDocument>>,
pub(crate) latest_doc: Option<TypstDocument>,
/// The latest successly compiled document.
latest_success_doc: Option<Arc<TypstDocument>>,
latest_success_doc: Option<TypstDocument>,
/// feature set for compile_once mode.
once_feature_set: Arc<FeatureSet>,
/// Shared feature set for watch mode.

View file

@ -13,11 +13,11 @@ use serde::{Deserialize, Serialize};
use tinymist_derive::BindTyCtx;
use tinymist_project::LspWorld;
use tinymist_std::path::unix_slash;
use tinymist_std::typst::TypstDocument;
use typst::foundations::{
fields_on, format_str, repr, AutoValue, Func, Label, NoneValue, Repr, Scope, StyleChain, Type,
Value,
};
use typst::model::Document;
use typst::syntax::ast::{self, AstNode, Param};
use typst::syntax::{is_id_continue, is_id_start, is_ident};
use typst::text::RawElem;
@ -329,7 +329,7 @@ pub struct CompletionWorker<'a> {
/// The analysis local context.
ctx: &'a mut LocalContext,
/// The compiled document.
document: Option<&'a Document>,
document: Option<&'a TypstDocument>,
/// Whether the completion was explicitly requested.
explicit: bool,
/// The trigger character.
@ -346,7 +346,7 @@ impl<'a> CompletionWorker<'a> {
/// Create a completion worker.
pub fn new(
ctx: &'a mut LocalContext,
document: Option<&'a Document>,
document: Option<&'a TypstDocument>,
explicit: bool,
trigger_character: Option<char>,
) -> Option<Self> {

View file

@ -81,7 +81,7 @@ pub fn definition(
_ => return None,
};
let introspector = &document?.document.introspector;
let introspector = &document?.document.introspector();
bib_definition(ctx, introspector, name)
.or_else(|| ref_definition(introspector, name, ref_expr))
}

View file

@ -2,11 +2,12 @@
use comemo::Track;
use ecow::*;
use tinymist_std::typst::TypstDocument;
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, Document};
use typst::model::BibliographyElem;
use typst::syntax::{ast, LinkedNode, Span, SyntaxKind, SyntaxNode};
use typst::World;
@ -103,11 +104,11 @@ pub struct DynLabel {
/// - All labels and descriptions for them, if available
/// - A split offset: All labels before this offset belong to nodes, all after
/// belong to a bibliography.
pub fn analyze_labels(document: &Document) -> (Vec<DynLabel>, usize) {
pub fn analyze_labels(document: &TypstDocument) -> (Vec<DynLabel>, usize) {
let mut output = vec![];
// Labels in the document.
for elem in document.introspector.all() {
for elem in document.introspector().all() {
let Some(label) = elem.label() else { continue };
let (is_derived, details) = {
let derived = elem
@ -136,7 +137,7 @@ pub fn analyze_labels(document: &Document) -> (Vec<DynLabel>, usize) {
let split = output.len();
// Bibliography keys.
for (key, detail) in BibliographyElem::keys(document.introspector.track()) {
for (key, detail) in BibliographyElem::keys(document.introspector().track()) {
output.push(DynLabel {
label: Label::new(key.as_str()),
label_desc: detail.clone(),

View file

@ -70,7 +70,7 @@ impl StatefulRequest for CompletionRequest {
// assume that the completion is not explicit.
let explicit = false;
let document = doc.as_ref().map(|doc| doc.document.as_ref());
let document = doc.as_ref().map(|doc| &doc.document);
let source = ctx.source_by_path(&self.path).ok()?;
let cursor = ctx.to_typst_pos_offset(&source, self.position, 0)?;
let mut cursor = CompletionCursor::new(ctx.shared_(), &source, cursor)?;

View file

@ -3,10 +3,10 @@ use std::{collections::HashMap, path::PathBuf};
use serde::{Deserialize, Serialize};
use tinymist_std::debug_loc::DataSource;
use tinymist_std::typst::TypstDocument;
use typst::text::{Font, FontStretch, FontStyle, FontWeight};
use typst::{
layout::{Frame, FrameItem},
model::Document,
syntax::Span,
text::TextItem,
};
@ -142,12 +142,16 @@ struct DocumentMetricsWorker<'a> {
}
impl DocumentMetricsWorker<'_> {
fn work(&mut self, doc: &Document) -> Option<()> {
for page in &doc.pages {
self.work_frame(&page.frame)?;
}
fn work(&mut self, doc: &TypstDocument) -> Option<()> {
match doc {
TypstDocument::Paged(paged_doc) => {
for page in &paged_doc.pages {
self.work_frame(&page.frame)?;
}
Some(())
Some(())
}
}
}
fn work_frame(&mut self, frame: &Frame) -> Option<()> {

View file

@ -2,7 +2,7 @@
use std::num::NonZeroUsize;
use typst::model::Document;
use tinymist_std::typst::TypstDocument;
use typst::{
layout::{Frame, FrameItem, Point, Position},
syntax::{LinkedNode, Source, Span, SyntaxKind},
@ -10,38 +10,46 @@ use typst::{
use typst_shim::syntax::LinkedNodeExt;
/// Find the output location in the document for a cursor position.
pub fn jump_from_cursor(document: &Document, source: &Source, cursor: usize) -> Option<Position> {
let node = LinkedNode::new(source.root()).leaf_at_compat(cursor)?;
if node.kind() != SyntaxKind::Text {
return None;
}
pub fn jump_from_cursor(
document: &TypstDocument,
source: &Source,
cursor: usize,
) -> Option<Position> {
match document {
TypstDocument::Paged(paged_doc) => {
let node = LinkedNode::new(source.root()).leaf_at_compat(cursor)?;
if node.kind() != SyntaxKind::Text {
return None;
}
let mut min_dis = u64::MAX;
let mut point = Point::default();
let mut ppage = 0usize;
let mut min_dis = u64::MAX;
let mut point = Point::default();
let mut ppage = 0usize;
let span = node.span();
for (idx, page) in document.pages.iter().enumerate() {
let t_dis = min_dis;
if let Some(point) = find_in_frame(&page.frame, span, &mut min_dis, &mut point) {
return Some(Position {
page: NonZeroUsize::new(idx + 1)?,
let span = node.span();
for (idx, page) in paged_doc.pages.iter().enumerate() {
let t_dis = min_dis;
if let Some(point) = find_in_frame(&page.frame, span, &mut min_dis, &mut point) {
return Some(Position {
page: NonZeroUsize::new(idx + 1)?,
point,
});
}
if t_dis != min_dis {
ppage = idx;
}
}
if min_dis == u64::MAX {
return None;
}
Some(Position {
page: NonZeroUsize::new(ppage + 1)?,
point,
});
}
if t_dis != min_dis {
ppage = idx;
})
}
}
if min_dis == u64::MAX {
return None;
}
Some(Position {
page: NonZeroUsize::new(ppage + 1)?,
point,
})
}
/// Find the position of a span in a frame.

View file

@ -81,9 +81,8 @@ pub use lsp_typst_boundary::*;
mod prelude;
use std::sync::Arc;
use typst::{model::Document as TypstDocument, syntax::Source};
use tinymist_std::typst::TypstDocument;
use typst::syntax::Source;
/// The physical position in a document.
pub type FramePosition = typst::layout::Position;
@ -96,7 +95,7 @@ pub struct VersionedDocument {
/// The version of the document.
pub version: usize,
/// The compiled document.
pub document: Arc<TypstDocument>,
pub document: TypstDocument,
}
/// A request handler with given syntax information.

View file

@ -11,6 +11,7 @@ use std::{
use once_cell::sync::Lazy;
use serde_json::{ser::PrettyFormatter, Serializer, Value};
use tinymist_project::CompileFontArgs;
use tinymist_std::typst::TypstDocument;
use tinymist_world::package::PackageSpec;
use tinymist_world::vfs::WorkspaceResolver;
use tinymist_world::EntryState;
@ -142,7 +143,7 @@ pub fn compile_doc_for_test(
let doc = typst::compile(&world).output.unwrap();
Some(VersionedDocument {
version: 0,
document: Arc::new(doc),
document: TypstDocument::Paged(Arc::new(doc)),
})
}

View file

@ -16,6 +16,8 @@ rust-version.workspace = true
serde.workspace = true
tinymist-query.workspace = true
reflexo-vec2svg.workspace = true
reflexo-typst.workspace = true
tinymist-std.workspace = true
base64.workspace = true
log.workspace = true

View file

@ -10,6 +10,7 @@ use core::fmt;
use base64::Engine;
use reflexo_vec2svg::{ExportFeature, SvgExporter, SvgText};
use tinymist_query::{FramePosition, LocalContext, VersionedDocument};
use tinymist_std::typst::TypstDocument;
struct PeriscopeExportFeature {}
@ -97,32 +98,36 @@ impl PeriscopeRenderer {
doc: VersionedDocument,
pos: FramePosition,
) -> Option<(String, f32, f32)> {
// todo: svg viewer compatibility
type UsingExporter = SvgExporter<PeriscopeExportFeature>;
let mut doc = UsingExporter::svg_doc(&doc.document);
doc.module.prepare_glyphs();
let page0 = doc.pages.get(pos.page.get() - 1)?.clone();
let mut svg_text = UsingExporter::render(&doc.module, &[page0.clone()], None);
match &doc.document {
TypstDocument::Paged(paged_doc) => {
// todo: svg viewer compatibility
type UsingExporter = SvgExporter<PeriscopeExportFeature>;
let mut doc = UsingExporter::svg_doc(paged_doc);
doc.module.prepare_glyphs();
let page0 = doc.pages.get(pos.page.get() - 1)?.clone();
let mut svg_text = UsingExporter::render(&doc.module, &[page0.clone()], None);
// todo: let typst.ts expose it
let svg_header = svg_text.get_mut(0)?;
// todo: let typst.ts expose it
let svg_header = svg_text.get_mut(0)?;
let y_center = pos.point.y.to_pt() as f32;
let y_lo = y_center - self.p.y_above;
let y_hi = y_center + self.p.y_below;
let y_center = pos.point.y.to_pt() as f32;
let y_lo = y_center - self.p.y_above;
let y_hi = y_center + self.p.y_below;
let width = page0.size.x.0;
let height = y_hi - y_lo;
let width = page0.size.x.0;
let height = y_hi - y_lo;
*svg_header = SvgText::Plain(header_inner(
page0.size.x.0,
y_lo,
y_hi,
self.p.scale,
self.p.invert_color == "always",
));
*svg_header = SvgText::Plain(header_inner(
page0.size.x.0,
y_lo,
y_hi,
self.p.scale,
self.p.invert_color == "always",
));
Some((SvgText::join(svg_text), width, height))
Some((SvgText::join(svg_text), width, height))
}
}
}
}

View file

@ -14,6 +14,9 @@ pub use read::*;
mod marker;
pub use marker::*;
#[cfg(feature = "typst")]
pub mod typst;
/// An immutable string.
pub type ImmutStr = Arc<str>;
/// An immutable byte slice.

View file

@ -0,0 +1,58 @@
//! Re-export of the typst crate.
pub(crate) mod well_known {
pub use typst::foundations::Bytes;
pub use typst::utils::LazyHash;
/// Although this is not good to expose this, we make an alias here to
/// let it as a part of typst-ts.
pub use typst::syntax::FileId as TypstFileId;
pub use typst::World as TypstWorld;
pub use typst::layout::Abs as TypstAbs;
pub use typst::model::Document as TypstPagedDocument;
pub use typst::text::Font as TypstFont;
pub use typst::foundations::Dict as TypstDict;
pub use typst::foundations::Datetime as TypstDatetime;
pub use typst::{diag, foundations, syntax};
}
/// The enum of all well-known Typst documents.
#[derive(Debug, Clone)]
pub enum TypstDocument {
/// The document compiled with `paged` target.
Paged(Arc<well_known::TypstPagedDocument>),
}
impl TypstDocument {
/// Gets details about the document.
pub fn info(&self) -> &typst::model::DocumentInfo {
match self {
Self::Paged(doc) => &doc.info,
}
}
/// Gets the introspector that can be queried for elements and their
/// positions.
pub fn introspector(&self) -> &typst::introspection::Introspector {
match self {
Self::Paged(doc) => &doc.introspector,
}
}
}
use std::sync::Arc;
pub use well_known::*;
/// The prelude of the Typst module.
pub mod prelude {
pub use comemo::Prehashed;
pub use ecow::{eco_format, eco_vec, EcoString, EcoVec};
}

View file

@ -1,8 +1,9 @@
use std::{collections::BTreeMap, path::Path, sync::Arc};
use reflexo_typst::{vector::font::GlyphId, TypstDocument, TypstFont};
use reflexo_typst::{vector::font::GlyphId, TypstFont};
use sync_lsp::LspResult;
use tinymist_project::LspCompileSnapshot;
use tinymist_std::typst::TypstDocument;
use typst::{syntax::VirtualPath, World};
use crate::world::{base::ShadowApi, EntryState, TaskInputs};
@ -993,7 +994,10 @@ impl ServerState {
.map_err(internal_error)?;
log::debug!("sym doc: {sym_doc:?}");
Some(trait_symbol_fonts(&sym_doc.output, &symbols_ref))
Some(trait_symbol_fonts(
&TypstDocument::Paged(sym_doc.output),
&symbols_ref,
))
};
let mut glyph_def = String::new();
@ -1111,7 +1115,8 @@ fn trait_symbol_fonts(
impl Worker<'_> {
fn work(&mut self, doc: &TypstDocument) {
for (pg, s) in doc.pages.iter().zip(self.symbols.iter()) {
let TypstDocument::Paged(paged_doc) = doc;
for (pg, s) in paged_doc.pages.iter().zip(self.symbols.iter()) {
self.active = s;
self.work_frame(&pg.frame);
}

View file

@ -15,6 +15,7 @@ use tinymist_project::{
ExportTransform, LspCompiledArtifact, Pages, ProjectTask, QueryTask,
};
use tinymist_std::error::prelude::*;
use tinymist_std::typst::TypstDocument;
use tokio::sync::mpsc;
use typlite::Typlite;
use typst::foundations::IntoValue;
@ -76,7 +77,7 @@ impl ExportTask {
TaskWhen::Never => false,
TaskWhen::OnType => s.by_mem_events,
TaskWhen::OnSave => s.by_fs_events,
TaskWhen::OnDocumentHasTitle => s.by_fs_events && doc.info.title.is_some(),
TaskWhen::OnDocumentHasTitle => s.by_fs_events && doc.info().title.is_some(),
};
if !need_export {
@ -186,7 +187,8 @@ impl ExportTask {
let doc = &doc;
// static BLANK: Lazy<Page> = Lazy::new(Page::default);
let first_page = doc.pages.first().unwrap();
let TypstDocument::Paged(paged_doc) = &doc;
let first_page = paged_doc.pages.first().unwrap();
Ok(match kind2 {
Preview(..) => vec![],
// todo: more pdf flags
@ -202,7 +204,7 @@ impl ExportTask {
// todo: Some(pdf_uri.as_str())
typst_pdf::pdf(
doc,
paged_doc,
&PdfOptions {
timestamp: convert_datetime(creation_timestamp),
..Default::default()
@ -219,8 +221,9 @@ impl ExportTask {
one,
}) => {
let pretty = false;
let elements = reflexo_typst::query::retrieve(&snap.world, &selector, doc)
.map_err(|e| anyhow::anyhow!("failed to retrieve: {e}"))?;
let elements =
reflexo_typst::query::retrieve(&snap.world, &selector, paged_doc)
.map_err(|e| anyhow::anyhow!("failed to retrieve: {e}"))?;
if one && elements.len() != 1 {
bail!("expected exactly one element, found {}", elements.len());
}
@ -243,7 +246,7 @@ impl ExportTask {
}
}
ExportHtml(ExportHtmlTask { export: _ }) => {
reflexo_vec2svg::render_svg_html::<DefaultExportFeature>(doc).into_bytes()
reflexo_vec2svg::render_svg_html::<DefaultExportFeature>(paged_doc).into_bytes()
}
ExportText(ExportTextTask { export: _ }) => {
format!("{}", FullTextDigest(doc.clone())).into_bytes()
@ -261,7 +264,7 @@ impl ExportTask {
if is_first {
typst_svg::svg(first_page).into_bytes()
} else {
typst_svg::svg_merged(doc, merged_gap).into_bytes()
typst_svg::svg_merged(paged_doc, merged_gap).into_bytes()
}
}
ExportPng(ExportPngTask { export, ppi, fill }) => {
@ -281,7 +284,7 @@ impl ExportTask {
let pixmap = if is_first {
typst_render::render(first_page, ppi / 72.)
} else {
typst_render::render_merged(doc, ppi / 72., merged_gap, Some(fill))
typst_render::render_merged(paged_doc, ppi / 72., merged_gap, Some(fill))
};
pixmap

View file

@ -15,13 +15,14 @@ use hyper_util::server::graceful::GracefulShutdown;
use lsp_types::notification::Notification;
use parking_lot::Mutex;
use reflexo_typst::debug_loc::SourceSpanOffset;
use reflexo_typst::{error::prelude::*, Error, TypstDocument};
use reflexo_typst::{error::prelude::*, Error};
use serde::Serialize;
use serde_json::Value as JsonValue;
use sync_lsp::just_ok;
use tinymist_assets::TYPST_PREVIEW_HTML;
use tinymist_project::ProjectInsId;
use tinymist_std::error::IgnoreLogging;
use tinymist_std::typst::TypstDocument;
use tokio::sync::{mpsc, oneshot};
use typst::layout::{Frame, FrameItem, Point, Position};
use typst::syntax::{LinkedNode, Source, Span, SyntaxKind};
@ -50,9 +51,10 @@ pub struct PreviewCompileView {
}
impl typst_preview::CompileView for PreviewCompileView {
fn doc(&self) -> Option<Arc<TypstDocument>> {
fn doc(&self) -> Option<TypstDocument> {
self.snap.doc.clone().ok()
}
fn status(&self) -> typst_preview::CompileStatus {
match self.snap.doc {
Ok(_) => typst_preview::CompileStatus::CompileSuccess,
@ -95,7 +97,7 @@ impl typst_preview::CompileView for PreviewCompileView {
let column = src_loc.pos.column;
let doc = self.snap.success_doc();
let Some(doc) = doc.as_deref() else {
let Some(doc) = doc.as_ref() else {
return vec![];
};
@ -799,19 +801,23 @@ fn jump_from_cursor(document: &TypstDocument, source: &Source, cursor: usize) ->
let mut p = Point::default();
let span = node.span();
let mut positions: Vec<Position> = vec![];
for (i, page) in document.pages.iter().enumerate() {
let mut min_dis = u64::MAX;
if let Some(pos) = find_in_frame(&page.frame, span, &mut min_dis, &mut p) {
if let Some(page) = NonZeroUsize::new(i + 1) {
positions.push(Position { page, point: pos });
match document {
TypstDocument::Paged(paged_doc) => {
let mut positions: Vec<Position> = vec![];
for (i, page) in paged_doc.pages.iter().enumerate() {
let mut min_dis = u64::MAX;
if let Some(pos) = find_in_frame(&page.frame, span, &mut min_dis, &mut p) {
if let Some(page) = NonZeroUsize::new(i + 1) {
positions.push(Position { page, point: pos });
}
}
}
log::info!("jump_from_cursor: {positions:#?}");
positions
}
}
log::info!("jump_from_cursor: {positions:#?}");
positions
}
/// Find the position of a span in a frame.

View file

@ -1,11 +1,10 @@
//! Text export utilities.
use core::fmt;
use reflexo_typst::TypstDocument;
use std::sync::Arc;
use tinymist_std::typst::TypstDocument;
/// A full text digest of a document.
pub struct FullTextDigest(pub Arc<TypstDocument>);
pub struct FullTextDigest(pub TypstDocument);
impl FullTextDigest {
fn export_frame(f: &mut fmt::Formatter<'_>, doc: &typst::layout::Frame) -> fmt::Result {
@ -32,9 +31,13 @@ impl FullTextDigest {
impl fmt::Display for FullTextDigest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for page in self.0.pages.iter() {
Self::export_frame(f, &page.frame)?;
match &self.0 {
TypstDocument::Paged(paged_doc) => {
for page in paged_doc.pages.iter() {
Self::export_frame(f, &page.frame)?;
}
Ok(())
}
}
Ok(())
}
}

View file

@ -6,7 +6,8 @@ use std::sync::Arc;
use reflexo_typst::{debug_loc::SourceSpanOffset, exporter_utils::map_err};
use serde::{Deserialize, Serialize};
use typst::{model::Document, syntax::Span, text::TextItem};
use tinymist_std::typst::TypstDocument;
use typst::{syntax::Span, text::TextItem};
use unicode_script::{Script, UnicodeScript};
/// Words count for a document.
@ -25,7 +26,7 @@ pub struct WordsCount {
}
/// Count words in a document.
pub fn word_count(doc: &Document) -> WordsCount {
pub fn word_count(doc: &TypstDocument) -> WordsCount {
// the mapping is still not use, so we prevent the warning here
let _ = TextContent::map_back_spans;
@ -97,7 +98,7 @@ pub struct TextExporter {}
impl TextExporter {
/// Collect text content from a document.
pub fn collect(&self, output: &Document) -> typst::diag::SourceResult<String> {
pub fn collect(&self, output: &TypstDocument) -> typst::diag::SourceResult<String> {
let w = std::io::BufWriter::new(Vec::new());
let mut d = TextExportWorker { w };
@ -113,11 +114,15 @@ struct TextExportWorker {
}
impl TextExportWorker {
fn doc(&mut self, doc: &Document) -> io::Result<()> {
for page in doc.pages.iter() {
self.frame(&page.frame)?;
fn doc(&mut self, doc: &TypstDocument) -> io::Result<()> {
match doc {
TypstDocument::Paged(paged_doc) => {
for page in paged_doc.pages.iter() {
self.frame(&page.frame)?;
}
Ok(())
}
}
Ok(())
}
fn frame(&mut self, doc: &typst::layout::Frame) -> io::Result<()> {
@ -159,7 +164,7 @@ pub struct TextContent {
/// A string of the content for slicing.
pub content: String,
/// annotating document.
pub doc: Arc<Document>,
pub doc: Arc<TypstDocument>,
}
impl TextContent {
@ -197,9 +202,13 @@ struct SpanMapper {
}
impl SpanMapper {
fn doc(&mut self, doc: &Document) {
for page in doc.pages.iter() {
self.frame(&page.frame);
fn doc(&mut self, doc: &TypstDocument) {
match doc {
TypstDocument::Paged(paged_doc) => {
for page in paged_doc.pages.iter() {
self.frame(&page.frame);
}
}
}
}

View file

@ -13,6 +13,7 @@ rust-version.workspace = true
[dependencies]
typst.workspace = true
tinymist-assets.workspace = true
tinymist-std.workspace = true
typst-assets.workspace = true
comemo.workspace = true

View file

@ -4,8 +4,8 @@ use std::sync::Arc;
use reflexo_typst::debug_loc::{
CharPosition, DocumentPosition, ElementPoint, SourceLocation, SourceSpanOffset,
};
use reflexo_typst::TypstDocument;
use reflexo_vec2svg::IncrSvgDocServer;
use tinymist_std::typst::TypstDocument;
use tokio::sync::{broadcast, mpsc};
use super::{editor::EditorActorRequest, webview::WebviewActorRequest};
@ -138,6 +138,9 @@ impl RenderActor {
log::info!("RenderActor: document is not ready");
continue;
};
let TypstDocument::Paged(document) = document;
let data = if has_full_render {
if let Some(data) = self.renderer.pack_current() {
data

View file

@ -15,8 +15,8 @@ use futures::sink::SinkExt;
use once_cell::sync::OnceCell;
use reflexo_typst::debug_loc::SourceSpanOffset;
use reflexo_typst::Error;
use reflexo_typst::TypstDocument as Document;
use serde::{Deserialize, Serialize};
use tinymist_std::typst::TypstDocument;
use tokio::sync::{broadcast, mpsc};
use typst::{layout::Position, syntax::Span};
@ -355,7 +355,7 @@ pub struct MemoryFilesShort {
pub trait CompileView: Send + Sync {
/// Get the compiled document.
fn doc(&self) -> Option<Arc<Document>>;
fn doc(&self) -> Option<TypstDocument>;
/// Get the compile status.
fn status(&self) -> CompileStatus;

View file

@ -1,8 +1,8 @@
use std::num::NonZeroUsize;
use reflexo_typst::debug_loc::DocumentPosition;
use reflexo_typst::TypstDocument;
use serde::{Deserialize, Serialize};
use tinymist_std::typst::TypstDocument;
use typst::foundations::{Content, NativeElement, Packed, StyleChain};
use typst::introspection::Introspector;
use typst::model::HeadingElem;
@ -140,7 +140,7 @@ struct OutlineItem {
}
pub fn outline(interner: &mut SpanInternerImpl, document: &TypstDocument) -> Outline {
let outline = get_outline(&document.introspector);
let outline = get_outline(document.introspector());
let mut items = Vec::with_capacity(outline.as_ref().map_or(0, Vec::len));
for heading in outline.iter().flatten() {