mirror of
https://github.com/typst/typst
synced 2025-07-27 22:37:54 +08:00
Compare commits
11 Commits
dfe6e4ae47
...
3c99acf4ff
Author | SHA1 | Date | |
---|---|---|---|
|
3c99acf4ff | ||
|
b790c6d59c | ||
|
b1c79b50d4 | ||
|
4629ede020 | ||
|
5a1f539b2d | ||
|
fc098322f9 | ||
|
89650af4b2 | ||
|
44bb2da462 | ||
|
54809020bf | ||
|
fee95dd0b0 | ||
|
8684daa17c |
@ -173,8 +173,11 @@ typst help
|
|||||||
typst help watch
|
typst help watch
|
||||||
```
|
```
|
||||||
|
|
||||||
If you prefer an integrated IDE-like experience with autocompletion and instant
|
If you prefer an integrated IDE-like experience with autocompletion and instant
|
||||||
preview, you can also check out [Typst's free web app][app].
|
preview, you can also check out our [free web app][app]. Alternatively, there is
|
||||||
|
a community-created language server called
|
||||||
|
[Tinymist](https://myriad-dreamin.github.io/tinymist/) which is integrated into
|
||||||
|
various editor extensions.
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
The main places where the community gathers are our [Forum][forum] and our
|
The main places where the community gathers are our [Forum][forum] and our
|
||||||
|
@ -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 {
|
||||||
|
@ -6,10 +6,11 @@ use typst::engine::Sink;
|
|||||||
use typst::foundations::{Content, IntoValue, LocatableSelector, Scope};
|
use typst::foundations::{Content, IntoValue, LocatableSelector, Scope};
|
||||||
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 typst_html::HtmlDocument;
|
||||||
|
|
||||||
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<_>>())
|
||||||
|
@ -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
|
||||||
|
@ -117,6 +117,8 @@ use crate::foundations::{func, Array, Context, LocatableSelector, Value};
|
|||||||
/// ]
|
/// ]
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// ## Retrieving a specific field
|
||||||
|
///
|
||||||
/// Frequently, you're interested in only one specific field of the resulting
|
/// Frequently, you're interested in only one specific field of the resulting
|
||||||
/// elements. In the case of the `metadata` element, the `value` field is the
|
/// elements. In the case of the `metadata` element, the `value` field is the
|
||||||
/// interesting one. You can extract just this field with the `--field`
|
/// interesting one. You can extract just this field with the `--field`
|
||||||
@ -134,6 +136,12 @@ use crate::foundations::{func, Array, Context, LocatableSelector, Value};
|
|||||||
/// $ typst query example.typ "<note>" --field value --one
|
/// $ typst query example.typ "<note>" --field value --one
|
||||||
/// "This is a note"
|
/// "This is a note"
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Querying for a specific export target
|
||||||
|
///
|
||||||
|
/// In case you need to query a document when exporting for a specific target,
|
||||||
|
/// you can use the `--target` argument. Valid values are `paged`, and `html`
|
||||||
|
/// (if the [`html`]($html) feature is enabled).
|
||||||
#[func(contextual)]
|
#[func(contextual)]
|
||||||
pub fn query(
|
pub fn query(
|
||||||
engine: &mut Engine,
|
engine: &mut Engine,
|
||||||
|
@ -797,7 +797,9 @@ impl Color {
|
|||||||
components
|
components
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the constructor function for this color's space:
|
/// Returns the constructor function for this color's space.
|
||||||
|
///
|
||||||
|
/// Returns one of:
|
||||||
/// - [`luma`]($color.luma)
|
/// - [`luma`]($color.luma)
|
||||||
/// - [`oklab`]($color.oklab)
|
/// - [`oklab`]($color.oklab)
|
||||||
/// - [`oklch`]($color.oklch)
|
/// - [`oklch`]($color.oklch)
|
||||||
|
@ -242,7 +242,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
items.push(CategoryItem {
|
items.push(CategoryItem {
|
||||||
name: group.name.clone(),
|
name: group.name.clone(),
|
||||||
route: subpage.route.clone(),
|
route: subpage.route.clone(),
|
||||||
oneliner: oneliner(docs).into(),
|
oneliner: oneliner(docs),
|
||||||
code: true,
|
code: true,
|
||||||
});
|
});
|
||||||
children.push(subpage);
|
children.push(subpage);
|
||||||
@ -296,7 +296,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
items.push(CategoryItem {
|
items.push(CategoryItem {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
route: subpage.route.clone(),
|
route: subpage.route.clone(),
|
||||||
oneliner: oneliner(func.docs().unwrap_or_default()).into(),
|
oneliner: oneliner(func.docs().unwrap_or_default()),
|
||||||
code: true,
|
code: true,
|
||||||
});
|
});
|
||||||
children.push(subpage);
|
children.push(subpage);
|
||||||
@ -306,7 +306,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
|||||||
items.push(CategoryItem {
|
items.push(CategoryItem {
|
||||||
name: ty.short_name().into(),
|
name: ty.short_name().into(),
|
||||||
route: subpage.route.clone(),
|
route: subpage.route.clone(),
|
||||||
oneliner: oneliner(ty.docs()).into(),
|
oneliner: oneliner(ty.docs()),
|
||||||
code: true,
|
code: true,
|
||||||
});
|
});
|
||||||
children.push(subpage);
|
children.push(subpage);
|
||||||
@ -637,7 +637,7 @@ fn group_page(
|
|||||||
let item = CategoryItem {
|
let item = CategoryItem {
|
||||||
name: group.name.clone(),
|
name: group.name.clone(),
|
||||||
route: model.route.clone(),
|
route: model.route.clone(),
|
||||||
oneliner: oneliner(&group.details).into(),
|
oneliner: oneliner(&group.details),
|
||||||
code: false,
|
code: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -772,8 +772,24 @@ pub fn urlify(title: &str) -> EcoString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the first line of documentation.
|
/// Extract the first line of documentation.
|
||||||
fn oneliner(docs: &str) -> &str {
|
fn oneliner(docs: &str) -> EcoString {
|
||||||
docs.lines().next().unwrap_or_default()
|
let paragraph = docs.split("\n\n").next().unwrap_or_default();
|
||||||
|
let mut depth = 0;
|
||||||
|
let mut period = false;
|
||||||
|
let mut end = paragraph.len();
|
||||||
|
for (i, c) in paragraph.char_indices() {
|
||||||
|
match c {
|
||||||
|
'(' | '[' | '{' => depth += 1,
|
||||||
|
')' | ']' | '}' => depth -= 1,
|
||||||
|
'.' if depth == 0 => period = true,
|
||||||
|
c if period && c.is_whitespace() && !docs[..i].ends_with("e.g.") => {
|
||||||
|
end = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_ => period = false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EcoString::from(&docs[..end]).replace("\r\n", " ").replace("\n", " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The order of types in the documentation.
|
/// The order of types in the documentation.
|
||||||
|
@ -86,7 +86,7 @@ pub struct FuncModel {
|
|||||||
pub name: EcoString,
|
pub name: EcoString,
|
||||||
pub title: &'static str,
|
pub title: &'static str,
|
||||||
pub keywords: &'static [&'static str],
|
pub keywords: &'static [&'static str],
|
||||||
pub oneliner: &'static str,
|
pub oneliner: EcoString,
|
||||||
pub element: bool,
|
pub element: bool,
|
||||||
pub contextual: bool,
|
pub contextual: bool,
|
||||||
pub deprecation: Option<&'static str>,
|
pub deprecation: Option<&'static str>,
|
||||||
@ -139,7 +139,7 @@ pub struct TypeModel {
|
|||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub title: &'static str,
|
pub title: &'static str,
|
||||||
pub keywords: &'static [&'static str],
|
pub keywords: &'static [&'static str],
|
||||||
pub oneliner: &'static str,
|
pub oneliner: EcoString,
|
||||||
pub details: Html,
|
pub details: Html,
|
||||||
pub constructor: Option<FuncModel>,
|
pub constructor: Option<FuncModel>,
|
||||||
pub scope: Vec<FuncModel>,
|
pub scope: Vec<FuncModel>,
|
||||||
|
@ -127,6 +127,10 @@
|
|||||||
checks = self'.checks;
|
checks = self'.checks;
|
||||||
inputsFrom = [ typst ];
|
inputsFrom = [ typst ];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
rust-analyzer
|
||||||
|
];
|
||||||
|
|
||||||
packages = [
|
packages = [
|
||||||
# A script for quickly running tests.
|
# A script for quickly running tests.
|
||||||
# See https://github.com/typst/typst/blob/main/tests/README.md#making-an-alias
|
# See https://github.com/typst/typst/blob/main/tests/README.md#making-an-alias
|
||||||
|
Loading…
x
Reference in New Issue
Block a user