mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Less style properties
This commit is contained in:
parent
0a41844cc4
commit
a7a4cae294
@ -7,7 +7,7 @@ use std::fmt::Write;
|
|||||||
use self::tex::{layout_tex, Texify};
|
use self::tex::{layout_tex, Texify};
|
||||||
use crate::layout::BlockSpacing;
|
use crate::layout::BlockSpacing;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::text::FontFamily;
|
use crate::text::{FallbackList, FontFamily, TextNode};
|
||||||
|
|
||||||
/// A piece of a mathematical formula.
|
/// A piece of a mathematical formula.
|
||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Debug, Clone, Hash)]
|
||||||
@ -20,9 +20,6 @@ pub struct MathNode {
|
|||||||
|
|
||||||
#[node(Show, Finalize, LayoutInline, Texify)]
|
#[node(Show, Finalize, LayoutInline, Texify)]
|
||||||
impl MathNode {
|
impl MathNode {
|
||||||
/// The math font family.
|
|
||||||
#[property(referenced)]
|
|
||||||
pub const FAMILY: FontFamily = FontFamily::new("NewComputerModernMath");
|
|
||||||
/// The spacing above display math.
|
/// The spacing above display math.
|
||||||
#[property(resolve, shorthand(around))]
|
#[property(resolve, shorthand(around))]
|
||||||
pub const ABOVE: Option<BlockSpacing> = Some(Ratio::one().into());
|
pub const ABOVE: Option<BlockSpacing> = Some(Ratio::one().into());
|
||||||
@ -44,11 +41,7 @@ impl Show for MathNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> {
|
fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> {
|
||||||
Ok(if self.display {
|
Ok(self.clone().pack())
|
||||||
self.clone().pack().aligned(Axes::with_x(Some(Align::Center.into())))
|
|
||||||
} else {
|
|
||||||
self.clone().pack()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,13 +50,20 @@ impl Finalize for MathNode {
|
|||||||
&self,
|
&self,
|
||||||
_: Tracked<dyn World>,
|
_: Tracked<dyn World>,
|
||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
realized: Content,
|
mut realized: Content,
|
||||||
) -> SourceResult<Content> {
|
) -> SourceResult<Content> {
|
||||||
Ok(if self.display {
|
realized = realized.styled(
|
||||||
realized.spaced(styles.get(Self::ABOVE), styles.get(Self::BELOW))
|
TextNode::FAMILY,
|
||||||
} else {
|
FallbackList(vec![FontFamily::new("NewComputerModernMath")]),
|
||||||
realized
|
);
|
||||||
})
|
|
||||||
|
if self.display {
|
||||||
|
realized = realized
|
||||||
|
.aligned(Axes::with_x(Some(Align::Center.into())))
|
||||||
|
.spaced(styles.get(Self::ABOVE), styles.get(Self::BELOW))
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(realized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,8 @@ use rex::parser::color::RGBA;
|
|||||||
use rex::render::{Backend, Cursor, Renderer};
|
use rex::render::{Backend, Cursor, Renderer};
|
||||||
use typst::font::Font;
|
use typst::font::Font;
|
||||||
|
|
||||||
use super::MathNode;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::text::{variant, LinebreakNode, SpaceNode, TextNode};
|
use crate::text::{families, variant, LinebreakNode, SpaceNode, TextNode};
|
||||||
|
|
||||||
/// Turn a math node into TeX math code.
|
/// Turn a math node into TeX math code.
|
||||||
#[capability]
|
#[capability]
|
||||||
@ -42,17 +41,21 @@ pub fn layout_tex(
|
|||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
) -> SourceResult<Frame> {
|
) -> SourceResult<Frame> {
|
||||||
// Load the font.
|
// Load the font.
|
||||||
let font = world
|
let variant = variant(styles);
|
||||||
.book()
|
let mut font = None;
|
||||||
.select(styles.get(MathNode::FAMILY).as_str(), variant(styles))
|
for family in families(styles) {
|
||||||
.and_then(|id| world.font(id))
|
font = world.book().select(family, variant).and_then(|id| world.font(id));
|
||||||
.expect("failed to find math font");
|
if font.as_ref().map_or(false, |font| font.math().is_some()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare the font context.
|
// Prepare the font context.
|
||||||
|
let font = font.expect("failed to find suitable math font");
|
||||||
let ctx = font
|
let ctx = font
|
||||||
.math()
|
.math()
|
||||||
.map(|math| FontContext::new(font.ttf(), math))
|
.map(|math| FontContext::new(font.ttf(), math))
|
||||||
.expect("font is not suitable for math");
|
.expect("failed to create font context");
|
||||||
|
|
||||||
// Layout the formula.
|
// Layout the formula.
|
||||||
let em = styles.get(TextNode::SIZE);
|
let em = styles.get(TextNode::SIZE);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
use typst::font::FontWeight;
|
||||||
|
|
||||||
use crate::layout::{BlockNode, BlockSpacing};
|
use crate::layout::{BlockNode, BlockSpacing};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::text::{FontFamily, TextNode, TextSize};
|
use crate::text::{TextNode, TextSize};
|
||||||
|
|
||||||
/// A section heading.
|
/// A section heading.
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
@ -14,32 +16,10 @@ pub struct HeadingNode {
|
|||||||
|
|
||||||
#[node(Show, Finalize)]
|
#[node(Show, Finalize)]
|
||||||
impl HeadingNode {
|
impl HeadingNode {
|
||||||
/// The heading's font family. Just the normal text family if `auto`.
|
/// Whether the heading appears in the outline.
|
||||||
#[property(referenced)]
|
pub const OUTLINED: bool = true;
|
||||||
pub const FAMILY: Leveled<Smart<FontFamily>> = Leveled::Value(Smart::Auto);
|
/// Whether the heading is numbered.
|
||||||
/// The color of text in the heading. Just the normal text color if `auto`.
|
pub const NUMBERED: bool = true;
|
||||||
#[property(referenced)]
|
|
||||||
pub const FILL: Leveled<Smart<Paint>> = Leveled::Value(Smart::Auto);
|
|
||||||
/// The size of text in the heading.
|
|
||||||
#[property(referenced)]
|
|
||||||
pub const SIZE: Leveled<TextSize> = Leveled::Mapping(|level| {
|
|
||||||
let size = match level.get() {
|
|
||||||
1 => 1.4,
|
|
||||||
2 => 1.2,
|
|
||||||
_ => 1.0,
|
|
||||||
};
|
|
||||||
TextSize(Em::new(size).into())
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Whether text in the heading is strengthend.
|
|
||||||
#[property(referenced)]
|
|
||||||
pub const STRONG: Leveled<bool> = Leveled::Value(true);
|
|
||||||
/// Whether text in the heading is emphasized.
|
|
||||||
#[property(referenced)]
|
|
||||||
pub const EMPH: Leveled<bool> = Leveled::Value(false);
|
|
||||||
/// Whether the heading is underlined.
|
|
||||||
#[property(referenced)]
|
|
||||||
pub const UNDERLINE: Leveled<bool> = Leveled::Value(false);
|
|
||||||
|
|
||||||
/// The spacing above the heading.
|
/// The spacing above the heading.
|
||||||
#[property(referenced, shorthand(around))]
|
#[property(referenced, shorthand(around))]
|
||||||
@ -55,11 +35,6 @@ impl HeadingNode {
|
|||||||
pub const BELOW: Leveled<Option<BlockSpacing>> =
|
pub const BELOW: Leveled<Option<BlockSpacing>> =
|
||||||
Leveled::Value(Some(Ratio::new(0.55).into()));
|
Leveled::Value(Some(Ratio::new(0.55).into()));
|
||||||
|
|
||||||
/// Whether the heading appears in the outline.
|
|
||||||
pub const OUTLINED: bool = true;
|
|
||||||
/// Whether the heading is numbered.
|
|
||||||
pub const NUMBERED: bool = true;
|
|
||||||
|
|
||||||
fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> {
|
fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
body: args.expect("body")?,
|
body: args.expect("body")?,
|
||||||
@ -101,30 +76,17 @@ impl Finalize for HeadingNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut map = StyleMap::new();
|
let mut map = StyleMap::new();
|
||||||
map.set(TextNode::SIZE, resolve!(Self::SIZE));
|
map.set(TextNode::SIZE, {
|
||||||
|
let size = match self.level.get() {
|
||||||
|
1 => 1.4,
|
||||||
|
2 => 1.2,
|
||||||
|
_ => 1.0,
|
||||||
|
};
|
||||||
|
TextSize(Em::new(size).into())
|
||||||
|
});
|
||||||
|
map.set(TextNode::WEIGHT, FontWeight::BOLD);
|
||||||
|
|
||||||
if let Smart::Custom(family) = resolve!(Self::FAMILY) {
|
realized = realized.styled_with_map(map).spaced(
|
||||||
map.set_family(family, styles);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Smart::Custom(fill) = resolve!(Self::FILL) {
|
|
||||||
map.set(TextNode::FILL, fill);
|
|
||||||
}
|
|
||||||
|
|
||||||
if resolve!(Self::STRONG) {
|
|
||||||
realized = realized.strong();
|
|
||||||
}
|
|
||||||
|
|
||||||
if resolve!(Self::EMPH) {
|
|
||||||
realized = realized.emph();
|
|
||||||
}
|
|
||||||
|
|
||||||
if resolve!(Self::UNDERLINE) {
|
|
||||||
realized = realized.underlined();
|
|
||||||
}
|
|
||||||
|
|
||||||
realized = realized.styled_with_map(map);
|
|
||||||
realized = realized.spaced(
|
|
||||||
resolve!(Self::ABOVE).resolve(styles),
|
resolve!(Self::ABOVE).resolve(styles),
|
||||||
resolve!(Self::BELOW).resolve(styles),
|
resolve!(Self::BELOW).resolve(styles),
|
||||||
);
|
);
|
||||||
|
@ -7,31 +7,34 @@ pub struct LinkNode {
|
|||||||
/// The destination the link points to.
|
/// The destination the link points to.
|
||||||
pub dest: Destination,
|
pub dest: Destination,
|
||||||
/// How the link is represented.
|
/// How the link is represented.
|
||||||
pub body: Option<Content>,
|
pub body: Content,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LinkNode {
|
impl LinkNode {
|
||||||
/// Create a link node from a URL with its bare text.
|
/// Create a link node from a URL with its bare text.
|
||||||
pub fn from_url(url: EcoString) -> Self {
|
pub fn from_url(url: EcoString) -> Self {
|
||||||
Self { dest: Destination::Url(url), body: None }
|
let mut text = url.as_str();
|
||||||
|
for prefix in ["mailto:", "tel:"] {
|
||||||
|
text = text.trim_start_matches(prefix);
|
||||||
|
}
|
||||||
|
let shorter = text.len() < url.len();
|
||||||
|
let body = TextNode::packed(if shorter { text.into() } else { url.clone() });
|
||||||
|
Self { dest: Destination::Url(url), body }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[node(Show, Finalize)]
|
#[node(Show, Finalize)]
|
||||||
impl LinkNode {
|
impl LinkNode {
|
||||||
/// The fill color of text in the link. Just the surrounding text color
|
|
||||||
/// if `auto`.
|
|
||||||
pub const FILL: Smart<Paint> = Smart::Auto;
|
|
||||||
/// Whether to underline the link.
|
|
||||||
pub const UNDERLINE: Smart<bool> = Smart::Auto;
|
|
||||||
|
|
||||||
fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> {
|
fn construct(_: &mut Vm, args: &mut Args) -> SourceResult<Content> {
|
||||||
let dest = args.expect::<Destination>("destination")?;
|
let dest = args.expect::<Destination>("destination")?;
|
||||||
let body = match dest {
|
Ok(match dest {
|
||||||
Destination::Url(_) => args.eat()?,
|
Destination::Url(url) => match args.eat()? {
|
||||||
Destination::Internal(_) => Some(args.expect("body")?),
|
Some(body) => Self { dest: Destination::Url(url), body },
|
||||||
};
|
None => Self::from_url(url),
|
||||||
Ok(Self { dest, body }.pack())
|
},
|
||||||
|
Destination::Internal(_) => Self { dest, body: args.expect("body")? },
|
||||||
|
}
|
||||||
|
.pack())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field(&self, name: &str) -> Option<Value> {
|
fn field(&self, name: &str) -> Option<Value> {
|
||||||
@ -40,10 +43,7 @@ impl LinkNode {
|
|||||||
Destination::Url(url) => Value::Str(url.clone().into()),
|
Destination::Url(url) => Value::Str(url.clone().into()),
|
||||||
Destination::Internal(loc) => Value::Dict(loc.encode()),
|
Destination::Internal(loc) => Value::Dict(loc.encode()),
|
||||||
}),
|
}),
|
||||||
"body" => Some(match &self.body {
|
"body" => Some(Value::Content(self.body.clone())),
|
||||||
Some(body) => Value::Content(body.clone()),
|
|
||||||
None => Value::None,
|
|
||||||
}),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,23 +53,13 @@ impl Show for LinkNode {
|
|||||||
fn unguard_parts(&self, id: RecipeId) -> Content {
|
fn unguard_parts(&self, id: RecipeId) -> Content {
|
||||||
Self {
|
Self {
|
||||||
dest: self.dest.clone(),
|
dest: self.dest.clone(),
|
||||||
body: self.body.as_ref().map(|body| body.unguard(id)),
|
body: self.body.unguard(id),
|
||||||
}
|
}
|
||||||
.pack()
|
.pack()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> {
|
fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> SourceResult<Content> {
|
||||||
Ok(self.body.clone().unwrap_or_else(|| match &self.dest {
|
Ok(self.body.clone())
|
||||||
Destination::Url(url) => {
|
|
||||||
let mut text = url.as_str();
|
|
||||||
for prefix in ["mailto:", "tel:"] {
|
|
||||||
text = text.trim_start_matches(prefix);
|
|
||||||
}
|
|
||||||
let shorter = text.len() < url.len();
|
|
||||||
TextNode::packed(if shorter { text.into() } else { url.clone() })
|
|
||||||
}
|
|
||||||
Destination::Internal(_) => Content::empty(),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,26 +67,9 @@ impl Finalize for LinkNode {
|
|||||||
fn finalize(
|
fn finalize(
|
||||||
&self,
|
&self,
|
||||||
_: Tracked<dyn World>,
|
_: Tracked<dyn World>,
|
||||||
styles: StyleChain,
|
_: StyleChain,
|
||||||
mut realized: Content,
|
realized: Content,
|
||||||
) -> SourceResult<Content> {
|
) -> SourceResult<Content> {
|
||||||
let mut map = StyleMap::new();
|
Ok(realized.styled(TextNode::LINK, Some(self.dest.clone())))
|
||||||
map.set(TextNode::LINK, Some(self.dest.clone()));
|
|
||||||
|
|
||||||
if let Smart::Custom(fill) = styles.get(Self::FILL) {
|
|
||||||
map.set(TextNode::FILL, fill);
|
|
||||||
}
|
|
||||||
|
|
||||||
if match styles.get(Self::UNDERLINE) {
|
|
||||||
Smart::Auto => match &self.dest {
|
|
||||||
Destination::Url(_) => true,
|
|
||||||
Destination::Internal(_) => false,
|
|
||||||
},
|
|
||||||
Smart::Custom(underline) => underline,
|
|
||||||
} {
|
|
||||||
realized = realized.underlined();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(realized.styled_with_map(map))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use syntect::highlighting::{
|
|||||||
use syntect::parsing::SyntaxSet;
|
use syntect::parsing::SyntaxSet;
|
||||||
use typst::syntax;
|
use typst::syntax;
|
||||||
|
|
||||||
use super::{FontFamily, Hyphenate, LinebreakNode, TextNode};
|
use super::{FallbackList, FontFamily, Hyphenate, LinebreakNode, TextNode};
|
||||||
use crate::layout::{BlockNode, BlockSpacing};
|
use crate::layout::{BlockNode, BlockSpacing};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -24,9 +24,6 @@ impl RawNode {
|
|||||||
/// The language to syntax-highlight in.
|
/// The language to syntax-highlight in.
|
||||||
#[property(referenced)]
|
#[property(referenced)]
|
||||||
pub const LANG: Option<EcoString> = None;
|
pub const LANG: Option<EcoString> = None;
|
||||||
/// The raw text's font family.
|
|
||||||
#[property(referenced)]
|
|
||||||
pub const FAMILY: FontFamily = FontFamily::new("IBM Plex Mono");
|
|
||||||
/// The spacing above block-level raw.
|
/// The spacing above block-level raw.
|
||||||
#[property(resolve, shorthand(around))]
|
#[property(resolve, shorthand(around))]
|
||||||
pub const ABOVE: Option<BlockSpacing> = Some(Ratio::one().into());
|
pub const ABOVE: Option<BlockSpacing> = Some(Ratio::one().into());
|
||||||
@ -119,14 +116,16 @@ impl Finalize for RawNode {
|
|||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
mut realized: Content,
|
mut realized: Content,
|
||||||
) -> SourceResult<Content> {
|
) -> SourceResult<Content> {
|
||||||
let mut map = StyleMap::new();
|
realized = realized.styled(
|
||||||
map.set_family(styles.get(Self::FAMILY).clone(), styles);
|
TextNode::FAMILY,
|
||||||
|
FallbackList(vec![FontFamily::new("IBM Plex Mono")]),
|
||||||
|
);
|
||||||
|
|
||||||
if self.block {
|
if self.block {
|
||||||
realized = realized.spaced(styles.get(Self::ABOVE), styles.get(Self::BELOW));
|
realized = realized.spaced(styles.get(Self::ABOVE), styles.get(Self::BELOW));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(realized.styled_with_map(map))
|
Ok(realized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,7 +552,7 @@ pub fn variant(styles: StyleChain) -> FontVariant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve a prioritized iterator over the font families.
|
/// Resolve a prioritized iterator over the font families.
|
||||||
fn families(styles: StyleChain) -> impl Iterator<Item = &str> + Clone {
|
pub fn families(styles: StyleChain) -> impl Iterator<Item = &str> + Clone {
|
||||||
const FALLBACKS: &[&str] = &[
|
const FALLBACKS: &[&str] = &[
|
||||||
"ibm plex sans",
|
"ibm plex sans",
|
||||||
"twitter color emoji",
|
"twitter color emoji",
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
@ -43,11 +43,10 @@ multiline.
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Test styling.
|
// Test styling.
|
||||||
|
#show heading.where(level: 5): it => {
|
||||||
|
text(family: "Roboto", fill: eastern, it.body + [!])
|
||||||
|
}
|
||||||
|
|
||||||
= Heading
|
= Heading
|
||||||
|
|
||||||
#set heading(family: "Roboto", fill: eastern)
|
|
||||||
#show heading: it => it.body
|
|
||||||
#show strong: it => it.body + [!]
|
|
||||||
|
|
||||||
===== Heading 🌍
|
===== Heading 🌍
|
||||||
#heading(level: 5)[Heading]
|
#heading(level: 5)[Heading]
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
// Test styles with closure.
|
|
||||||
|
|
||||||
---
|
|
||||||
#set heading(
|
|
||||||
size: 10pt,
|
|
||||||
around: 0.65em,
|
|
||||||
fill: lvl => if even(lvl) { red } else { blue },
|
|
||||||
)
|
|
||||||
|
|
||||||
= Heading 1
|
|
||||||
== Heading 2
|
|
||||||
=== Heading 3
|
|
||||||
==== Heading 4
|
|
||||||
|
|
||||||
---
|
|
||||||
// Test in constructor.
|
|
||||||
#heading(
|
|
||||||
level: 3,
|
|
||||||
size: 10pt,
|
|
||||||
strong: lvl => {
|
|
||||||
assert(lvl == 3)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
)[Level 3]
|
|
||||||
|
|
||||||
---
|
|
||||||
// Error: 22-26 expected string or auto or function, found length
|
|
||||||
#set heading(family: 10pt)
|
|
||||||
= Heading
|
|
||||||
|
|
||||||
---
|
|
||||||
// Error: 29-38 cannot add integer and string
|
|
||||||
#set heading(strong: lvl => lvl + "2")
|
|
||||||
= Heading
|
|
||||||
|
|
||||||
---
|
|
||||||
// Error: 22-34 expected string or auto, found boolean
|
|
||||||
#set heading(family: lvl => false)
|
|
||||||
= Heading
|
|
||||||
|
|
||||||
---
|
|
||||||
// Error: 22-37 missing argument: b
|
|
||||||
#set heading(family: (a, b) => a + b)
|
|
||||||
= Heading
|
|
||||||
|
|
||||||
---
|
|
||||||
// Error: 22-30 unexpected argument
|
|
||||||
#set heading(family: () => {})
|
|
||||||
= Heading
|
|
@ -13,8 +13,9 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Test full reset.
|
// Test full reset.
|
||||||
#set heading(size: 1em, strong: false, around: none)
|
#set heading(around: none)
|
||||||
#show heading: [B]
|
#show heading: [B]
|
||||||
|
#show heading: text.with(size: 10pt, weight: 400)
|
||||||
A [= Heading] C
|
A [= Heading] C
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -28,8 +29,8 @@ my heading?
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Test integrated example.
|
// Test integrated example.
|
||||||
#set heading(size: 1em)
|
|
||||||
#show heading: it => {
|
#show heading: it => {
|
||||||
|
set text(10pt)
|
||||||
move(dy: -1pt)[📖]
|
move(dy: -1pt)[📖]
|
||||||
h(5pt)
|
h(5pt)
|
||||||
if it.level == 1 {
|
if it.level == 1 {
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
#set par(indent: 12pt, leading: 5pt)
|
#set par(indent: 12pt, leading: 5pt)
|
||||||
#set heading(size: 10pt, above: 8pt)
|
#set heading(above: 8pt)
|
||||||
|
#show heading: text.with(size: 10pt)
|
||||||
|
|
||||||
The first paragraph has no indent.
|
The first paragraph has no indent.
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ call #link("tel:123") for more information.
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Test that the period is trimmed.
|
// Test that the period is trimmed.
|
||||||
|
#show link: underline
|
||||||
https://a.b.?q=%10#. \
|
https://a.b.?q=%10#. \
|
||||||
Wahttp://link \
|
Wahttp://link \
|
||||||
Nohttps:\//link \
|
Nohttps:\//link \
|
||||||
@ -23,20 +24,19 @@ Nohttp\://comment
|
|||||||
|
|
||||||
---
|
---
|
||||||
// Styled with underline and color.
|
// Styled with underline and color.
|
||||||
#set link(fill: rgb("283663"))
|
#show link: it => underline(text(fill: rgb("283663"), it))
|
||||||
You could also make the
|
You could also make the
|
||||||
#link("https://html5zombo.com/")[link look way more typical.]
|
#link("https://html5zombo.com/")[link look way more typical.]
|
||||||
|
|
||||||
---
|
---
|
||||||
// Transformed link.
|
// Transformed link.
|
||||||
#set page(height: 60pt)
|
#set page(height: 60pt)
|
||||||
#set link(underline: false)
|
|
||||||
#let mylink = link("https://typst.org/")[LINK]
|
#let mylink = link("https://typst.org/")[LINK]
|
||||||
My cool #move(dx: 0.7cm, dy: 0.7cm, rotate(10deg, scale(200%, mylink)))
|
My cool #move(dx: 0.7cm, dy: 0.7cm, rotate(10deg, scale(200%, mylink)))
|
||||||
|
|
||||||
---
|
---
|
||||||
// Link containing a block.
|
// Link containing a block.
|
||||||
#link("https://example.com/", underline: false, block[
|
#link("https://example.com/", block[
|
||||||
My cool rhino
|
My cool rhino
|
||||||
#move(dx: 10pt, image("/res/rhino.png", width: 1cm))
|
#move(dx: 10pt, image("/res/rhino.png", width: 1cm))
|
||||||
])
|
])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user