mirror of
https://github.com/typst/typst
synced 2025-08-18 00:48:34 +08:00
Compare commits
6 Commits
4307ac3f79
...
84fe10239d
Author | SHA1 | Date | |
---|---|---|---|
|
84fe10239d | ||
|
0264534928 | ||
|
44bb2da462 | ||
|
54809020bf | ||
|
fee95dd0b0 | ||
|
8684daa17c |
@ -155,6 +155,10 @@ pub struct QueryCommand {
|
|||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub pretty: bool,
|
pub pretty: bool,
|
||||||
|
|
||||||
|
/// The target to compile for.
|
||||||
|
#[clap(long, default_value_t)]
|
||||||
|
pub target: Target,
|
||||||
|
|
||||||
/// World arguments.
|
/// World arguments.
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub world: WorldArgs,
|
pub world: WorldArgs,
|
||||||
@ -457,6 +461,18 @@ pub enum OutputFormat {
|
|||||||
|
|
||||||
display_possible_values!(OutputFormat);
|
display_possible_values!(OutputFormat);
|
||||||
|
|
||||||
|
/// The target to compile for.
|
||||||
|
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, ValueEnum)]
|
||||||
|
pub enum Target {
|
||||||
|
/// PDF and image formats.
|
||||||
|
#[default]
|
||||||
|
Paged,
|
||||||
|
/// HTML.
|
||||||
|
Html,
|
||||||
|
}
|
||||||
|
|
||||||
|
display_possible_values!(Target);
|
||||||
|
|
||||||
/// Which format to use for diagnostics.
|
/// Which format to use for diagnostics.
|
||||||
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, ValueEnum)]
|
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, ValueEnum)]
|
||||||
pub enum DiagnosticFormat {
|
pub enum DiagnosticFormat {
|
||||||
|
@ -4,12 +4,13 @@ use serde::Serialize;
|
|||||||
use typst::diag::{bail, HintedStrResult, StrResult, Warned};
|
use typst::diag::{bail, HintedStrResult, StrResult, Warned};
|
||||||
use typst::engine::Sink;
|
use typst::engine::Sink;
|
||||||
use typst::foundations::{Content, IntoValue, LocatableSelector, Scope};
|
use typst::foundations::{Content, IntoValue, LocatableSelector, Scope};
|
||||||
|
use typst::html::HtmlDocument;
|
||||||
use typst::layout::PagedDocument;
|
use typst::layout::PagedDocument;
|
||||||
use typst::syntax::{Span, SyntaxMode};
|
use typst::syntax::{Span, SyntaxMode};
|
||||||
use typst::World;
|
use typst::{Document, World};
|
||||||
use typst_eval::eval_string;
|
use typst_eval::eval_string;
|
||||||
|
|
||||||
use crate::args::{QueryCommand, SerializationFormat};
|
use crate::args::{QueryCommand, SerializationFormat, Target};
|
||||||
use crate::compile::print_diagnostics;
|
use crate::compile::print_diagnostics;
|
||||||
use crate::set_failed;
|
use crate::set_failed;
|
||||||
use crate::world::SystemWorld;
|
use crate::world::SystemWorld;
|
||||||
@ -22,12 +23,17 @@ pub fn query(command: &QueryCommand) -> HintedStrResult<()> {
|
|||||||
world.reset();
|
world.reset();
|
||||||
world.source(world.main()).map_err(|err| err.to_string())?;
|
world.source(world.main()).map_err(|err| err.to_string())?;
|
||||||
|
|
||||||
let Warned { output, warnings } = typst::compile(&world);
|
let Warned { output, warnings } = match command.target {
|
||||||
|
Target::Paged => typst::compile::<PagedDocument>(&world)
|
||||||
|
.map(|output| output.map(|document| retrieve(&world, command, &document))),
|
||||||
|
Target::Html => typst::compile::<HtmlDocument>(&world)
|
||||||
|
.map(|output| output.map(|document| retrieve(&world, command, &document))),
|
||||||
|
};
|
||||||
|
|
||||||
match output {
|
match output {
|
||||||
// Retrieve and print query results.
|
// Retrieve and print query results.
|
||||||
Ok(document) => {
|
Ok(data) => {
|
||||||
let data = retrieve(&world, command, &document)?;
|
let data = data?;
|
||||||
let serialized = format(data, command)?;
|
let serialized = format(data, command)?;
|
||||||
println!("{serialized}");
|
println!("{serialized}");
|
||||||
print_diagnostics(&world, &[], &warnings, command.process.diagnostic_format)
|
print_diagnostics(&world, &[], &warnings, command.process.diagnostic_format)
|
||||||
@ -51,10 +57,10 @@ pub fn query(command: &QueryCommand) -> HintedStrResult<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve the matches for the selector.
|
/// Retrieve the matches for the selector.
|
||||||
fn retrieve(
|
fn retrieve<D: Document>(
|
||||||
world: &dyn World,
|
world: &dyn World,
|
||||||
command: &QueryCommand,
|
command: &QueryCommand,
|
||||||
document: &PagedDocument,
|
document: &D,
|
||||||
) -> HintedStrResult<Vec<Content>> {
|
) -> HintedStrResult<Vec<Content>> {
|
||||||
let selector = eval_string(
|
let selector = eval_string(
|
||||||
&typst::ROUTINES,
|
&typst::ROUTINES,
|
||||||
@ -77,7 +83,7 @@ fn retrieve(
|
|||||||
.cast::<LocatableSelector>()?;
|
.cast::<LocatableSelector>()?;
|
||||||
|
|
||||||
Ok(document
|
Ok(document
|
||||||
.introspector
|
.introspector()
|
||||||
.query(&selector.0)
|
.query(&selector.0)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<Vec<_>>())
|
.collect::<Vec<_>>())
|
||||||
|
@ -130,7 +130,14 @@ fn complete_markup(ctx: &mut CompletionContext) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start of a reference: "@|" or "@he|".
|
// Start of a reference: "@|".
|
||||||
|
if ctx.leaf.kind() == SyntaxKind::Text && ctx.before.ends_with("@") {
|
||||||
|
ctx.from = ctx.cursor;
|
||||||
|
ctx.label_completions();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An existing reference: "@he|".
|
||||||
if ctx.leaf.kind() == SyntaxKind::RefMarker {
|
if ctx.leaf.kind() == SyntaxKind::RefMarker {
|
||||||
ctx.from = ctx.leaf.offset() + 1;
|
ctx.from = ctx.leaf.offset() + 1;
|
||||||
ctx.label_completions();
|
ctx.label_completions();
|
||||||
@ -1644,6 +1651,19 @@ mod tests {
|
|||||||
test_with_doc(world, pos, doc.as_ref())
|
test_with_doc(world, pos, doc.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn test_with_addition(
|
||||||
|
initial_text: &str,
|
||||||
|
addition: &str,
|
||||||
|
pos: impl FilePos,
|
||||||
|
) -> Response {
|
||||||
|
let mut world = TestWorld::new(initial_text);
|
||||||
|
let doc = typst::compile(&world).output.ok();
|
||||||
|
let end = world.main.text().len();
|
||||||
|
world.main.edit(end..end, addition);
|
||||||
|
test_with_doc(&world, pos, doc.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn test_with_doc(
|
fn test_with_doc(
|
||||||
world: impl WorldLike,
|
world: impl WorldLike,
|
||||||
@ -1709,15 +1729,24 @@ mod tests {
|
|||||||
.must_exclude(["bib"]);
|
.must_exclude(["bib"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_autocomplete_ref_function() {
|
||||||
|
test_with_addition("x<test>", " #ref(<)", -2).must_include(["test"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_autocomplete_ref_shorthand() {
|
||||||
|
test_with_addition("x<test>", " @", -1).must_include(["test"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_autocomplete_ref_shorthand_with_partial_identifier() {
|
||||||
|
test_with_addition("x<test>", " @te", -1).must_include(["test"]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_autocomplete_ref_identical_labels_returns_single_completion() {
|
fn test_autocomplete_ref_identical_labels_returns_single_completion() {
|
||||||
let mut world = TestWorld::new("x<test> y<test>");
|
let result = test_with_addition("x<test> y<test>", " @t", -1);
|
||||||
let doc = typst::compile(&world).output.ok();
|
|
||||||
|
|
||||||
let end = world.main.text().len();
|
|
||||||
world.main.edit(end..end, " @t");
|
|
||||||
|
|
||||||
let result = test_with_doc(&world, -1, doc.as_ref());
|
|
||||||
let completions = result.completions();
|
let completions = result.completions();
|
||||||
let label_count =
|
let label_count =
|
||||||
completions.iter().filter(|c| c.kind == CompletionKind::Label).count();
|
completions.iter().filter(|c| c.kind == CompletionKind::Label).count();
|
||||||
|
@ -151,6 +151,13 @@ pub struct Warned<T> {
|
|||||||
pub warnings: EcoVec<SourceDiagnostic>,
|
pub warnings: EcoVec<SourceDiagnostic>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Warned<T> {
|
||||||
|
/// Maps the output, keeping the same warnings.
|
||||||
|
pub fn map<R, F: FnOnce(T) -> R>(self, f: F) -> Warned<R> {
|
||||||
|
Warned { output: f(self.output), warnings: self.warnings }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An error or warning in a source or text file.
|
/// An error or warning in a source or text file.
|
||||||
///
|
///
|
||||||
/// The contained spans will only be detached if any of the input source files
|
/// The contained spans will only be detached if any of the input source files
|
||||||
|
Loading…
x
Reference in New Issue
Block a user