mirror of
https://github.com/typst/typst
synced 2025-08-16 16:08:32 +08:00
Compare commits
7 Commits
ea336a6ac7
...
94a497a01f
Author | SHA1 | Date | |
---|---|---|---|
|
94a497a01f | ||
|
9829bd8326 | ||
|
43c3d5d3af | ||
|
14a0565d95 | ||
|
bd2e76e11d | ||
|
14928ef962 | ||
|
d55abf0842 |
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -1702,9 +1702,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.70"
|
||||
version = "0.10.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6"
|
||||
checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"cfg-if",
|
||||
@ -1743,9 +1743,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.105"
|
||||
version = "0.9.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc"
|
||||
checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -82,7 +82,7 @@ native-tls = "0.2"
|
||||
notify = "8"
|
||||
once_cell = "1"
|
||||
open = "5.0.1"
|
||||
openssl = "0.10"
|
||||
openssl = "0.10.72"
|
||||
oxipng = { version = "9.0", default-features = false, features = ["filetime", "parallel", "zopfli"] }
|
||||
palette = { version = "0.7.3", default-features = false, features = ["approx", "libm"] }
|
||||
parking_lot = "0.12.1"
|
||||
|
26
README.md
26
README.md
@ -113,7 +113,7 @@ Typst's CLI is available from different sources:
|
||||
|
||||
- You can install Typst through different package managers. Note that the
|
||||
versions in the package managers might lag behind the latest release.
|
||||
- Linux:
|
||||
- Linux:
|
||||
- View [Typst on Repology][repology]
|
||||
- View [Typst's Snap][snap]
|
||||
- macOS: `brew install typst`
|
||||
@ -177,22 +177,22 @@ If you prefer an integrated IDE-like experience with autocompletion and instant
|
||||
preview, you can also check out [Typst's free web app][app].
|
||||
|
||||
## Community
|
||||
The main place where the community gathers is our [Discord server][discord].
|
||||
Feel free to join there to ask questions, help out others, share cool things
|
||||
you created with Typst, or just to chat.
|
||||
The main places where the community gathers are our [Forum][forum] and our
|
||||
[Discord server][discord]. The Forum is a great place to ask questions, help
|
||||
others, and share cool things you created with Typst. The Discord server is more
|
||||
suitable for quicker questions, discussions about contributing, or just to chat.
|
||||
We'd be happy to see you there!
|
||||
|
||||
Aside from that there are a few places where you can find things built by
|
||||
the community:
|
||||
|
||||
- The official [package list](https://typst.app/docs/packages)
|
||||
- The [Awesome Typst](https://github.com/qjcg/awesome-typst) repository
|
||||
[Typst Universe][universe] is where the community shares templates and packages.
|
||||
If you want to share your own creations, you can submit them to our
|
||||
[package repository][packages].
|
||||
|
||||
If you had a bad experience in our community, please [reach out to us][contact].
|
||||
|
||||
## Contributing
|
||||
We would love to see contributions from the community. If you experience bugs,
|
||||
feel free to open an issue. If you would like to implement a new feature or bug
|
||||
fix, please follow the steps outlined in the [contribution guide][contributing].
|
||||
We love to see contributions from the community. If you experience bugs, feel
|
||||
free to open an issue. If you would like to implement a new feature or bug fix,
|
||||
please follow the steps outlined in the [contribution guide][contributing].
|
||||
|
||||
To build Typst yourself, first ensure that you have the
|
||||
[latest stable Rust][rust] installed. Then, clone this repository and build the
|
||||
@ -243,6 +243,8 @@ instant preview. To achieve these goals, we follow three core design principles:
|
||||
[docs]: https://typst.app/docs/
|
||||
[app]: https://typst.app/
|
||||
[discord]: https://discord.gg/2uDybryKPe
|
||||
[forum]: https://forum.typst.app/
|
||||
[universe]: https://typst.app/universe/
|
||||
[tutorial]: https://typst.app/docs/tutorial/
|
||||
[show]: https://typst.app/docs/reference/styling/#show-rules
|
||||
[math]: https://typst.app/docs/reference/math/
|
||||
|
@ -2,6 +2,7 @@ use comemo::Track;
|
||||
use ecow::{eco_format, EcoString};
|
||||
use serde::Serialize;
|
||||
use typst::diag::{bail, HintedStrResult, StrResult, Warned};
|
||||
use typst::engine::Sink;
|
||||
use typst::foundations::{Content, IntoValue, LocatableSelector, Scope};
|
||||
use typst::layout::PagedDocument;
|
||||
use typst::syntax::Span;
|
||||
@ -58,6 +59,8 @@ fn retrieve(
|
||||
let selector = eval_string(
|
||||
&typst::ROUTINES,
|
||||
world.track(),
|
||||
// TODO: propagate warnings
|
||||
Sink::new().track_mut(),
|
||||
&command.selector,
|
||||
Span::detached(),
|
||||
EvalMode::Code,
|
||||
|
@ -101,6 +101,7 @@ pub fn eval(
|
||||
pub fn eval_string(
|
||||
routines: &Routines,
|
||||
world: Tracked<dyn World + '_>,
|
||||
sink: TrackedMut<Sink>,
|
||||
string: &str,
|
||||
span: Span,
|
||||
mode: EvalMode,
|
||||
@ -121,7 +122,6 @@ pub fn eval_string(
|
||||
}
|
||||
|
||||
// Prepare the engine.
|
||||
let mut sink = Sink::new();
|
||||
let introspector = Introspector::default();
|
||||
let traced = Traced::default();
|
||||
let engine = Engine {
|
||||
@ -129,7 +129,7 @@ pub fn eval_string(
|
||||
world,
|
||||
introspector: introspector.track(),
|
||||
traced: traced.track(),
|
||||
sink: sink.track_mut(),
|
||||
sink,
|
||||
route: Route::default(),
|
||||
};
|
||||
|
||||
|
@ -263,13 +263,13 @@ fn handle(
|
||||
/// Wrap the nodes in `<html>` and `<body>` if they are not yet rooted,
|
||||
/// supplying a suitable `<head>`.
|
||||
fn root_element(output: Vec<HtmlNode>, info: &DocumentInfo) -> SourceResult<HtmlElement> {
|
||||
let head = head_element(info);
|
||||
let body = match classify_output(output)? {
|
||||
OutputKind::Html(element) => return Ok(element),
|
||||
OutputKind::Body(body) => body,
|
||||
OutputKind::Leafs(leafs) => HtmlElement::new(tag::body).with_children(leafs),
|
||||
};
|
||||
Ok(HtmlElement::new(tag::html)
|
||||
.with_children(vec![head_element(info).into(), body.into()]))
|
||||
Ok(HtmlElement::new(tag::html).with_children(vec![head.into(), body.into()]))
|
||||
}
|
||||
|
||||
/// Generate a `<head>` element.
|
||||
@ -302,6 +302,24 @@ fn head_element(info: &DocumentInfo) -> HtmlElement {
|
||||
);
|
||||
}
|
||||
|
||||
if !info.author.is_empty() {
|
||||
children.push(
|
||||
HtmlElement::new(tag::meta)
|
||||
.with_attr(attr::name, "authors")
|
||||
.with_attr(attr::content, info.author.join(", "))
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
if !info.keywords.is_empty() {
|
||||
children.push(
|
||||
HtmlElement::new(tag::meta)
|
||||
.with_attr(attr::name, "keywords")
|
||||
.with_attr(attr::content, info.keywords.join(", "))
|
||||
.into(),
|
||||
)
|
||||
}
|
||||
|
||||
HtmlElement::new(tag::head).with_children(children)
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ pub use {
|
||||
indexmap::IndexMap,
|
||||
};
|
||||
|
||||
use comemo::TrackedMut;
|
||||
use ecow::EcoString;
|
||||
use typst_syntax::Spanned;
|
||||
|
||||
@ -297,5 +298,14 @@ pub fn eval(
|
||||
for (key, value) in dict {
|
||||
scope.bind(key.into(), Binding::new(value, span));
|
||||
}
|
||||
(engine.routines.eval_string)(engine.routines, engine.world, &text, span, mode, scope)
|
||||
|
||||
(engine.routines.eval_string)(
|
||||
engine.routines,
|
||||
engine.world,
|
||||
TrackedMut::reborrow_mut(&mut engine.sink),
|
||||
&text,
|
||||
span,
|
||||
mode,
|
||||
scope,
|
||||
)
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use typst_syntax::FileId;
|
||||
use crate::diag::{bail, DeprecationSink, StrResult};
|
||||
use crate::foundations::{repr, ty, Content, Scope, Value};
|
||||
|
||||
/// An module of definitions.
|
||||
/// A module of definitions.
|
||||
///
|
||||
/// A module
|
||||
/// - be built-in
|
||||
|
@ -39,11 +39,25 @@ use crate::foundations::{
|
||||
/// #type(image("glacier.jpg")).
|
||||
/// ```
|
||||
///
|
||||
/// The type of `10` is `int`. Now, what is the type of `int` or even `type`?
|
||||
/// The type of `{10}` is `int`. Now, what is the type of `int` or even `type`?
|
||||
/// ```example
|
||||
/// #type(int) \
|
||||
/// #type(type)
|
||||
/// ```
|
||||
///
|
||||
/// Unlike other types like `int`, [none] and [auto] do not have a name
|
||||
/// representing them. To test if a value is one of these, compare your value to
|
||||
/// them directly, e.g:
|
||||
/// ```example
|
||||
/// #let val = none
|
||||
/// #if val == none [
|
||||
/// Yep, it's none.
|
||||
/// ]
|
||||
/// ```
|
||||
///
|
||||
/// Note that `type` will return [`content`] for all document elements. To
|
||||
/// programmatically determine which kind of content you are dealing with, see
|
||||
/// [`content.func`].
|
||||
#[ty(scope, cast)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Type(Static<NativeTypeData>);
|
||||
|
@ -8,15 +8,35 @@ use crate::foundations::{repr, ty, Repr};
|
||||
|
||||
/// A ratio of a whole.
|
||||
///
|
||||
/// Written as a number, followed by a percent sign.
|
||||
/// A ratio is written as a number, followed by a percent sign. Ratios most
|
||||
/// often appear as part of a [relative length]($relative), to specify the size
|
||||
/// of some layout element relative to the page or some container.
|
||||
///
|
||||
/// # Example
|
||||
/// ```example
|
||||
/// #set align(center)
|
||||
/// #scale(x: 150%)[
|
||||
/// Scaled apart.
|
||||
/// ]
|
||||
/// #rect(width: 25%)
|
||||
/// ```
|
||||
///
|
||||
/// However, they can also describe any other property that is relative to some
|
||||
/// base, e.g. an amount of [horizontal scaling]($scale.x) or the
|
||||
/// [height of parentheses]($math.lr.size) relative to the height of the content
|
||||
/// they enclose.
|
||||
///
|
||||
/// # Scripting
|
||||
/// Within your own code, you can use ratios as you like. You can multiply them
|
||||
/// with various other types as shown below:
|
||||
///
|
||||
/// | Multiply by | Example | Result |
|
||||
/// |-----------------|-------------------------|-----------------|
|
||||
/// | [`ratio`] | `{27% * 10%}` | `{2.7%}` |
|
||||
/// | [`length`] | `{27% * 100pt}` | `{27pt}` |
|
||||
/// | [`relative`] | `{27% * (10% + 100pt)}` | `{2.7% + 27pt}` |
|
||||
/// | [`angle`] | `{27% * 100deg}` | `{27deg}` |
|
||||
/// | [`int`] | `{27% * 2}` | `{54%}` |
|
||||
/// | [`float`] | `{27% * 0.37037}` | `{10%}` |
|
||||
/// | [`fraction`] | `{27% * 3fr}` | `{0.81fr}` |
|
||||
///
|
||||
/// When ratios are displayed in the document, they are rounded to two
|
||||
/// significant digits for readability.
|
||||
#[ty(cast)]
|
||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub struct Ratio(Scalar);
|
||||
|
@ -14,17 +14,58 @@ use crate::layout::{Abs, Em, Length, Ratio};
|
||||
/// addition and subtraction of a length and a ratio. Wherever a relative length
|
||||
/// is expected, you can also use a bare length or ratio.
|
||||
///
|
||||
/// # Example
|
||||
/// ```example
|
||||
/// #rect(width: 100% - 50pt)
|
||||
/// # Relative to the page
|
||||
/// A common use case is setting the width or height of a layout element (e.g.,
|
||||
/// [block], [rect], etc.) as a certain percentage of the width of the page.
|
||||
/// Here, the rectangle's width is set to `{25%}`, so it takes up one fourth of
|
||||
/// the page's _inner_ width (the width minus margins).
|
||||
///
|
||||
/// #(100% - 50pt).length \
|
||||
/// #(100% - 50pt).ratio
|
||||
/// ```example
|
||||
/// #rect(width: 25%)
|
||||
/// ```
|
||||
///
|
||||
/// Bare lengths or ratios are always valid where relative lengths are expected,
|
||||
/// but the two can also be freely mixed:
|
||||
/// ```example
|
||||
/// #rect(width: 25% + 1cm)
|
||||
/// ```
|
||||
///
|
||||
/// If you're trying to size an element so that it takes up the page's _full_
|
||||
/// width, you have a few options (this highly depends on your exact use case):
|
||||
///
|
||||
/// 1. Set page margins to `{0pt}` (`[#set page(margin: 0pt)]`)
|
||||
/// 2. Multiply the ratio by the known full page width (`{21cm * 69%}`)
|
||||
/// 3. Use padding which will negate the margins (`[#pad(x: -2.5cm, ...)]`)
|
||||
/// 4. Use the page [background](page.background) or
|
||||
/// [foreground](page.foreground) field as those don't take margins into
|
||||
/// account (note that it will render the content outside of the document
|
||||
/// flow, see [place] to control the content position)
|
||||
///
|
||||
/// # Relative to a container
|
||||
/// When a layout element (e.g. a [rect]) is nested in another layout container
|
||||
/// (e.g. a [block]) instead of being a direct descendant of the page, relative
|
||||
/// widths become relative to the container:
|
||||
///
|
||||
/// ```example
|
||||
/// #block(
|
||||
/// width: 100pt,
|
||||
/// fill: aqua,
|
||||
/// rect(width: 50%),
|
||||
/// )
|
||||
/// ```
|
||||
///
|
||||
/// # Scripting
|
||||
/// You can multiply relative lengths by [ratios]($ratio), [integers]($int), and
|
||||
/// [floats]($float).
|
||||
///
|
||||
/// A relative length has the following fields:
|
||||
/// - `length`: Its length component.
|
||||
/// - `ratio`: Its ratio component.
|
||||
///
|
||||
/// ```example
|
||||
/// #(100% - 50pt).length \
|
||||
/// #(100% - 50pt).ratio
|
||||
/// ```
|
||||
#[ty(cast, name = "relative", title = "Relative Length")]
|
||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Rel<T: Numeric = Length> {
|
||||
|
@ -6,7 +6,7 @@ use std::num::NonZeroUsize;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
|
||||
use comemo::Tracked;
|
||||
use comemo::{Track, Tracked};
|
||||
use ecow::{eco_format, EcoString, EcoVec};
|
||||
use hayagriva::archive::ArchivedStyle;
|
||||
use hayagriva::io::BibLaTeXError;
|
||||
@ -20,7 +20,7 @@ use typst_syntax::{Span, Spanned};
|
||||
use typst_utils::{Get, ManuallyHash, NonZeroExt, PicoStr};
|
||||
|
||||
use crate::diag::{bail, error, At, FileError, HintedStrResult, SourceResult, StrResult};
|
||||
use crate::engine::Engine;
|
||||
use crate::engine::{Engine, Sink};
|
||||
use crate::foundations::{
|
||||
elem, Bytes, CastInfo, Content, Derived, FromValue, IntoValue, Label, NativeElement,
|
||||
OneOrMultiple, Packed, Reflect, Scope, Show, ShowSet, Smart, StyleChain, Styles,
|
||||
@ -999,6 +999,8 @@ impl ElemRenderer<'_> {
|
||||
(self.routines.eval_string)(
|
||||
self.routines,
|
||||
self.world,
|
||||
// TODO: propagate warnings
|
||||
Sink::new().track_mut(),
|
||||
math,
|
||||
self.span,
|
||||
EvalMode::Math,
|
||||
|
@ -55,6 +55,7 @@ routines! {
|
||||
fn eval_string(
|
||||
routines: &Routines,
|
||||
world: Tracked<dyn World + '_>,
|
||||
sink: TrackedMut<Sink>,
|
||||
string: &str,
|
||||
span: Span,
|
||||
mode: EvalMode,
|
||||
|
@ -52,3 +52,9 @@ _Tiger!_
|
||||
#eval(mode: "math", "f(a) = cases(a + b\, space space x >= 3,a + b\, space space x = 5)")
|
||||
|
||||
$f(a) = cases(a + b\, space space x >= 3,a + b\, space space x = 5)$
|
||||
|
||||
--- issue-6067-eval-warnings ---
|
||||
// Test that eval shows warnings from the executed code.
|
||||
// Warning: 7-11 no text within stars
|
||||
// Hint: 7-11 using multiple consecutive stars (e.g. **) has no additional effect
|
||||
#eval("**", mode: "markup")
|
||||
|
Loading…
x
Reference in New Issue
Block a user