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

@ -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(())
}
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 {
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)]