【typst-rs】Typst CLI Eval 命令实现解析

张开发
2026/4/7 22:43:43 15 分钟阅读

分享文章

【typst-rs】Typst CLI Eval 命令实现解析
这是一个Rust语言中的Typst文档处理命令解析模块用于在Typst文档上下文中执行表达式求值。主要功能这个eval函数用于执行Typst文档的查询命令主要功能是编译Typst文档支持分页PDF或HTML格式在文档上下文中执行一个表达式输出表达式的计算结果完整代码usecomemo::Track;useecow::eco_format;usetypst::diag::{HintedStrResult,SourceResult,Warned};usetypst::foundations::{Context,Output,Scope,StyleChain,Value};usetypst::syntax::{Span,SyntaxMode};usetypst::{World,engine::Sink,introspection::Introspector};usetypst_eval::eval_string;usetypst_html::HtmlDocument;usetypst_layout::PagedDocument;usecrate::args::{EvalCommand,Target};usecrate::compile::print_diagnostics;usecrate::set_failed;usecrate::world::SystemWorld;/// Execute a query command.pubfneval(command:staticEvalCommand)-HintedStrResult(){letmutworldSystemWorld::new(command.r#in.as_ref(),command.world,command.process)?;// Reset everything and ensure that the main file is present.world.reset();world.source(world.main()).map_err(|err|err.to_string())?;// Compile the main file and get the introspector.letWarned{output,mutwarnings}matchcommand.target{Target::Pagedtypst::compile::PagedDocument(world).map(|result|result.map(|output|Box::new(output)asBoxdynOutput)),Target::Htmltypst::compile::HtmlDocument(world).map(|result|result.map(|output|Box::new(output)asBoxdynOutput)),};matchoutput{// Retrieve and print evaluation results.Ok(document){letmutsinkSink::new();leteval_resultevaluate_expression(command.expression.clone(),mutsink,world,document.introspector(),);leterrorsmatcheval_result{Err(errors)errors.as_slice(),Ok(value){letserializedcrate::serialize(value,command.format,command.pretty)?;println!({serialized});[]}};// Collect additional warnings from evaluating the expression.warnings.extend(sink.warnings());print_diagnostics(world,errors,warnings,command.process.diagnostic_format,).map_err(|err|eco_format!(failed to print diagnostics ({err})))?;}// Print diagnostics.Err(errors){set_failed();print_diagnostics(world,errors,warnings,command.process.diagnostic_format,).map_err(|err|eco_format!(failed to print diagnostics ({err})))?;}}Ok(())}/// Evaluates the expression with code syntax mode and no scope.fnevaluate_expression(expression:String,sink:mutSink,world:dynWorld,introspector:dynIntrospector,)-SourceResultValue{eval_string(typst::ROUTINES,world.track(),sink.track_mut(),introspector.track(),Context::new(None,Some(StyleChain::new(world.library().styles))).track(),expression,Span::detached(),SyntaxMode::Code,Scope::default(),)}代码结构解析1. 初始化世界环境letmutworldSystemWorld::new(command.r#in.as_ref(),command.world,command.process)?;world.reset();world.source(world.main()).map_err(|err|err.to_string())?;创建SystemWorld实例管理文件系统、字体等资源重置状态并确保主文件存在2. 编译文档matchcommand.target{Target::Pagedtypst::compile::PagedDocument(world),Target::Htmltypst::compile::HtmlDocument(world),}根据目标类型编译为分页文档PDF或HTML文档3. 执行表达式求值leteval_resultevaluate_expression(command.expression.clone(),mutsink,world,document.introspector(),// 提供文档内省能力);4. 核心求值函数 -evaluate_expressionfnevaluate_expression(...)-SourceResultValue{eval_string(typst::ROUTINES,// Typst内置函数world.track(),// 文件追踪用于增量编译sink.track_mut(),// 警告收集器introspector.track(),// 文档内省查询元素位置等Context::new(...),// 样式上下文expression,// 要执行的表达式Span::detached(),// 位置信息分离状态SyntaxMode::Code,// 代码语法模式Scope::default(),// 空作用域)}5. 结果处理成功序列化结果并打印支持自定义格式和美化输出失败打印诊断信息错误和警告关键依赖项说明依赖用途comemo::Track增量编译的追踪机制typst::World抽象文件系统接口typst::Introspector文档内省查询元素位置、计数等typst_html::HtmlDocumentHTML文档输出typst_layout::PagedDocument分页文档输出典型使用场景# 查询文档中的标题数量typstevaldocument.typ--expressionquery(heading).len()# 获取特定元素位置typstevaldocument.typ--expressionlocate(here).position()设计特点增量编译支持通过Track特性实现双目标输出同时支持分页和HTML文档表达式求值可以在编译后的文档上下文中执行Typst代码诊断友好完整的错误和警告报告机制总结这个模块本质上是Typst CLI工具中eval子命令的实现用于在Typst文档环境中执行脚本表达式。它允许用户在不修改原始文档的情况下动态查询文档的各种属性和元素信息。

更多文章