mirror of
https://github.com/typst/typst
synced 2025-07-27 22:37:54 +08:00
Compare commits
8 Commits
e8cc9b7375
...
2242b7f598
Author | SHA1 | Date | |
---|---|---|---|
|
2242b7f598 | ||
|
9649def108 | ||
|
d2105dcc35 | ||
|
b790c6d59c | ||
|
b1c79b50d4 | ||
|
4629ede020 | ||
|
627f5b9d4f | ||
|
5661c20580 |
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -1373,7 +1373,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "krilla"
|
||||
version = "0.4.0"
|
||||
source = "git+https://github.com/LaurenzV/krilla?branch=main#d40f81a01ca8f8654510a76effeef12518437800"
|
||||
source = "git+https://github.com/LaurenzV/krilla?branch=main#32d070e737cd8ae4c3aa4ff901d15cb22bd052f3"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bumpalo",
|
||||
@ -1402,7 +1402,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "krilla-svg"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/LaurenzV/krilla?branch=main#d40f81a01ca8f8654510a76effeef12518437800"
|
||||
source = "git+https://github.com/LaurenzV/krilla?branch=main#32d070e737cd8ae4c3aa4ff901d15cb22bd052f3"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"fontdb",
|
||||
|
@ -173,8 +173,11 @@ typst help
|
||||
typst help watch
|
||||
```
|
||||
|
||||
If you prefer an integrated IDE-like experience with autocompletion and instant
|
||||
preview, you can also check out [Typst's free web app][app].
|
||||
If you prefer an integrated IDE-like experience with autocompletion and instant
|
||||
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
|
||||
The main places where the community gathers are our [Forum][forum] and our
|
||||
|
@ -14,8 +14,8 @@ use typst_library::model::{
|
||||
RefElem, StrongElem, TableCell, TableElem, TermsElem,
|
||||
};
|
||||
use typst_library::text::{
|
||||
HighlightElem, LinebreakElem, OverlineElem, RawElem, RawLine, SpaceElem, StrikeElem,
|
||||
SubElem, SuperElem, UnderlineElem,
|
||||
HighlightElem, LinebreakElem, OverlineElem, RawElem, RawLine, SmallcapsElem,
|
||||
SpaceElem, StrikeElem, SubElem, SuperElem, UnderlineElem,
|
||||
};
|
||||
use typst_library::visualize::ImageElem;
|
||||
|
||||
@ -47,6 +47,7 @@ pub fn register(rules: &mut NativeRuleMap) {
|
||||
rules.register(Html, OVERLINE_RULE);
|
||||
rules.register(Html, STRIKE_RULE);
|
||||
rules.register(Html, HIGHLIGHT_RULE);
|
||||
rules.register(Html, SMALLCAPS_RULE);
|
||||
rules.register(Html, RAW_RULE);
|
||||
rules.register(Html, RAW_LINE_RULE);
|
||||
|
||||
@ -390,6 +391,20 @@ const STRIKE_RULE: ShowFn<StrikeElem> =
|
||||
const HIGHLIGHT_RULE: ShowFn<HighlightElem> =
|
||||
|elem, _, _| Ok(HtmlElem::new(tag::mark).with_body(Some(elem.body.clone())).pack());
|
||||
|
||||
const SMALLCAPS_RULE: ShowFn<SmallcapsElem> = |elem, _, styles| {
|
||||
Ok(HtmlElem::new(tag::span)
|
||||
.with_attr(
|
||||
attr::style,
|
||||
if elem.all.get(styles) {
|
||||
"font-variant-caps: all-small-caps"
|
||||
} else {
|
||||
"font-variant-caps: small-caps"
|
||||
},
|
||||
)
|
||||
.with_body(Some(elem.body.clone()))
|
||||
.pack())
|
||||
};
|
||||
|
||||
const RAW_RULE: ShowFn<RawElem> = |elem, _, styles| {
|
||||
let lines = elem.lines.as_deref().unwrap_or_default();
|
||||
|
||||
|
@ -23,10 +23,10 @@ use serde::{Serialize, Serializer};
|
||||
use typst_syntax::Span;
|
||||
use typst_utils::singleton;
|
||||
|
||||
use crate::diag::{SourceResult, StrResult};
|
||||
use crate::diag::{bail, SourceResult, StrResult};
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{
|
||||
func, repr, scope, ty, Context, Dict, IntoValue, Label, Property, Recipe,
|
||||
func, repr, scope, ty, Args, Context, Dict, IntoValue, Label, Property, Recipe,
|
||||
RecipeIndex, Repr, Selector, Str, Style, StyleChain, Styles, Value,
|
||||
};
|
||||
use crate::introspection::{Locatable, Location};
|
||||
@ -479,7 +479,7 @@ impl Content {
|
||||
/// Link the content somewhere.
|
||||
pub fn linked(self, dest: Destination, alt: Option<EcoString>) -> Self {
|
||||
let span = self.span();
|
||||
LinkMarker::new(self, dest.clone(), alt)
|
||||
LinkMarker::new(self, dest.clone(), alt, span)
|
||||
.pack()
|
||||
.spanned(span)
|
||||
.set(LinkElem::current, Some(dest))
|
||||
@ -785,15 +785,27 @@ impl Repr for StyledElem {
|
||||
}
|
||||
|
||||
/// An element that associates the body of a link with the destination.
|
||||
#[elem(Locatable)]
|
||||
#[elem(Locatable, Construct)]
|
||||
pub struct LinkMarker {
|
||||
/// The content.
|
||||
#[internal]
|
||||
#[required]
|
||||
pub body: Content,
|
||||
#[internal]
|
||||
#[required]
|
||||
pub dest: Destination,
|
||||
#[internal]
|
||||
#[required]
|
||||
pub alt: Option<EcoString>,
|
||||
#[internal]
|
||||
#[required]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Construct for LinkMarker {
|
||||
fn construct(_: &mut Engine, args: &mut Args) -> SourceResult<Content> {
|
||||
bail!(args.span, "cannot be constructed manually");
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NativeElement> IntoValue for T {
|
||||
|
@ -37,13 +37,12 @@ pub use crate::__select_where as select_where;
|
||||
|
||||
/// A filter for selecting elements within the document.
|
||||
///
|
||||
/// You can construct a selector in the following ways:
|
||||
/// - you can use an element [function]
|
||||
/// - you can filter for an element function with
|
||||
/// [specific fields]($function.where)
|
||||
/// - you can use a [string]($str) or [regular expression]($regex)
|
||||
/// - you can use a [`{<label>}`]($label)
|
||||
/// - you can use a [`location`]
|
||||
/// To construct a selector you can:
|
||||
/// - use an element [function]
|
||||
/// - filter for an element function with [specific fields]($function.where)
|
||||
/// - use a [string]($str) or [regular expression]($regex)
|
||||
/// - use a [`{<label>}`]($label)
|
||||
/// - use a [`location`]
|
||||
/// - call the [`selector`] constructor to convert any of the above types into a
|
||||
/// selector value and use the methods below to refine it
|
||||
///
|
||||
@ -148,7 +147,9 @@ impl Selector {
|
||||
impl Selector {
|
||||
/// Turns a value into a selector. The following values are accepted:
|
||||
/// - An element function like a `heading` or `figure`.
|
||||
/// - A [string]($str) or [regular expression]($regex).
|
||||
/// - A `{<label>}`.
|
||||
/// - A [`location`].
|
||||
/// - A more complex selector like `{heading.where(level: 1)}`.
|
||||
#[func(constructor)]
|
||||
pub fn construct(
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
use codex::styling::MathVariant;
|
||||
use ecow::EcoString;
|
||||
use typst_utils::NonZeroExt;
|
||||
use unicode_math_class::MathClass;
|
||||
|
||||
@ -47,6 +48,9 @@ use crate::text::{FontFamily, FontList, FontWeight, LocalName, TextElem};
|
||||
/// [main math page]($category/math).
|
||||
#[elem(Locatable, Synthesize, ShowSet, Count, LocalName, Refable, Outlinable)]
|
||||
pub struct EquationElem {
|
||||
/// An alternative description of the mathematical equation.
|
||||
pub alt: Option<EcoString>,
|
||||
|
||||
/// Whether the equation is displayed as a separate block.
|
||||
#[default(false)]
|
||||
pub block: bool,
|
||||
|
@ -88,7 +88,7 @@ use crate::text::{LocalName, TextElem};
|
||||
/// generated.
|
||||
#[elem(Locatable)]
|
||||
pub struct LinkElem {
|
||||
/// A text describing the link.
|
||||
/// An alternative description of the link.
|
||||
pub alt: Option<EcoString>,
|
||||
|
||||
/// The destination the link points to.
|
||||
|
@ -797,7 +797,9 @@ impl Color {
|
||||
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)
|
||||
/// - [`oklab`]($color.oklab)
|
||||
/// - [`oklch`]($color.oklch)
|
||||
|
@ -124,7 +124,7 @@ pub struct ImageElem {
|
||||
/// The height of the image.
|
||||
pub height: Sizing,
|
||||
|
||||
/// A text describing the image.
|
||||
/// An alternative description of the image.
|
||||
pub alt: Option<EcoString>,
|
||||
|
||||
/// How the image should adjust itself to a given area (the area is defined
|
||||
|
@ -9,6 +9,7 @@ use krilla::error::KrillaError;
|
||||
use krilla::geom::PathBuilder;
|
||||
use krilla::page::{PageLabel, PageSettings};
|
||||
use krilla::surface::Surface;
|
||||
use krilla::tagging::TagId;
|
||||
use krilla::{Document, SerializeSettings};
|
||||
use krilla_svg::render_svg_glyph;
|
||||
use typst_library::diag::{bail, error, SourceDiagnostic, SourceResult};
|
||||
@ -373,11 +374,21 @@ fn finish(
|
||||
.collect::<EcoVec<_>>();
|
||||
Err(errors)
|
||||
}
|
||||
KrillaError::DuplicateTagId(_, _) => {
|
||||
unreachable!("duplicate IDs shouldn't be generated")
|
||||
KrillaError::DuplicateTagId(id, loc) => {
|
||||
let span = to_span(loc);
|
||||
let id = display_tag_id(&id);
|
||||
bail!(
|
||||
span, "duplicate tag id `{id}`";
|
||||
hint: "please report this as a bug"
|
||||
)
|
||||
}
|
||||
KrillaError::UnknownTagId(_, _) => {
|
||||
unreachable!("all referenced IDs should be present in the tag tree")
|
||||
KrillaError::UnknownTagId(id, loc) => {
|
||||
let span = to_span(loc);
|
||||
let id = display_tag_id(&id);
|
||||
bail!(
|
||||
span, "unknown tag id `{id}`";
|
||||
hint: "please report this as a bug"
|
||||
)
|
||||
}
|
||||
KrillaError::Image(_, loc) => {
|
||||
let span = to_span(loc);
|
||||
@ -394,6 +405,20 @@ fn finish(
|
||||
}
|
||||
}
|
||||
|
||||
fn display_tag_id(id: &TagId) -> impl std::fmt::Display + use<'_> {
|
||||
typst_utils::display(|f| {
|
||||
if let Ok(str) = std::str::from_utf8(id.as_bytes()) {
|
||||
f.write_str(str)
|
||||
} else {
|
||||
f.write_str("0x")?;
|
||||
for b in id.as_bytes() {
|
||||
write!(f, "{b:x}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts a krilla error into a Typst error.
|
||||
fn convert_error(
|
||||
gc: &GlobalContext,
|
||||
@ -562,16 +587,20 @@ fn convert_error(
|
||||
}
|
||||
// The below errors cannot occur yet, only once Typst supports full PDF/A
|
||||
// and PDF/UA. But let's still add a message just to be on the safe side.
|
||||
ValidationError::MissingAnnotationAltText => error!(
|
||||
Span::detached(),
|
||||
"{prefix} missing annotation alt text";
|
||||
hint: "please report this as a bug"
|
||||
),
|
||||
ValidationError::MissingAltText => error!(
|
||||
Span::detached(),
|
||||
"{prefix} missing alt text";
|
||||
hint: "make sure your images and equations have alt text"
|
||||
),
|
||||
ValidationError::MissingAnnotationAltText(loc) => {
|
||||
let span = to_span(*loc);
|
||||
error!(
|
||||
span, "{prefix} missing annotation alt text";
|
||||
hint: "please report this as a bug"
|
||||
)
|
||||
}
|
||||
ValidationError::MissingAltText(loc) => {
|
||||
let span = to_span(*loc);
|
||||
error!(
|
||||
span, "{prefix} missing alt text";
|
||||
hint: "make sure your images and equations have alt text"
|
||||
)
|
||||
}
|
||||
ValidationError::NoDocumentLanguage => error!(
|
||||
Span::detached(),
|
||||
"{prefix} missing document language";
|
||||
|
@ -6,6 +6,7 @@ use krilla::destination::XyzDestination;
|
||||
use krilla::geom as kg;
|
||||
use typst_library::layout::{Point, Position, Size};
|
||||
use typst_library::model::Destination;
|
||||
use typst_syntax::Span;
|
||||
|
||||
use crate::convert::{FrameContext, GlobalContext};
|
||||
use crate::tags::{self, Placeholder, TagNode};
|
||||
@ -17,6 +18,7 @@ pub(crate) struct LinkAnnotation {
|
||||
pub(crate) alt: Option<String>,
|
||||
pub(crate) quad_points: Vec<kg::Quadrilateral>,
|
||||
pub(crate) target: Target,
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
pub(crate) fn handle_link(
|
||||
@ -70,6 +72,7 @@ pub(crate) fn handle_link(
|
||||
quad_points: vec![quad],
|
||||
alt,
|
||||
target,
|
||||
span: link.span,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ pub(crate) fn handle_start(
|
||||
} else {
|
||||
TagKind::Figure.with_alt_text(alt)
|
||||
}
|
||||
} else if let Some(_) = elem.to_packed::<EquationElem>() {
|
||||
// TODO: alt text
|
||||
TagKind::Formula.into()
|
||||
} else if let Some(equation) = elem.to_packed::<EquationElem>() {
|
||||
let alt = equation.alt.get_as_ref().map(|s| s.to_string());
|
||||
TagKind::Formula.with_alt_text(alt)
|
||||
} else if let Some(table) = elem.to_packed::<TableElem>() {
|
||||
let table_id = gc.tags.next_table_id();
|
||||
let summary = table.summary.get_as_ref().map(|s| s.to_string());
|
||||
@ -176,6 +176,7 @@ pub(crate) fn handle_start(
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let tag = tag.with_location(Some(elem.span().into_raw().get()));
|
||||
push_stack(gc, loc, StackEntryKind::Standard(tag))?;
|
||||
|
||||
Ok(())
|
||||
@ -202,7 +203,8 @@ pub(crate) fn handle_end(gc: &mut GlobalContext, surface: &mut Surface, loc: Loc
|
||||
// PDF/UA compliance of the structure hierarchy is checked
|
||||
// elsewhere. While this doesn't make a lot of sense, just
|
||||
// avoid crashing here.
|
||||
let tag = TagKind::TOCI.into();
|
||||
let tag = TagKind::TOCI
|
||||
.with_location(Some(outline_entry.span().into_raw().get()));
|
||||
gc.tags.push(TagNode::Group(tag, entry.nodes));
|
||||
return;
|
||||
};
|
||||
@ -216,7 +218,8 @@ pub(crate) fn handle_end(gc: &mut GlobalContext, surface: &mut Surface, loc: Loc
|
||||
// PDF/UA compliance of the structure hierarchy is checked
|
||||
// elsewhere. While this doesn't make a lot of sense, just
|
||||
// avoid crashing here.
|
||||
let tag = TagKind::TD(TableDataCell::new()).into();
|
||||
let tag = TagKind::TD(TableDataCell::new())
|
||||
.with_location(Some(cell.span().into_raw().get()));
|
||||
gc.tags.push(TagNode::Group(tag, entry.nodes));
|
||||
return;
|
||||
};
|
||||
@ -324,11 +327,13 @@ pub(crate) fn add_annotations(
|
||||
annotations: Vec<LinkAnnotation>,
|
||||
) {
|
||||
for annotation in annotations.into_iter() {
|
||||
let LinkAnnotation { id: _, placeholder, alt, quad_points, target } = annotation;
|
||||
let LinkAnnotation { id: _, placeholder, alt, quad_points, target, span } =
|
||||
annotation;
|
||||
let annot = krilla::annotation::Annotation::new_link(
|
||||
krilla::annotation::LinkAnnotation::new_with_quad_points(quad_points, target),
|
||||
alt,
|
||||
);
|
||||
)
|
||||
.with_location(Some(span.into_raw().get()));
|
||||
let annot_id = page.add_tagged_annotation(annot);
|
||||
gc.tags.placeholders.init(placeholder, Node::Leaf(annot_id));
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use smallvec::SmallVec;
|
||||
use typst_library::foundations::{Packed, Smart, StyleChain};
|
||||
use typst_library::model::TableCell;
|
||||
use typst_library::pdf::{TableCellKind, TableHeaderScope};
|
||||
use typst_syntax::Span;
|
||||
|
||||
use crate::tags::{TableId, TagNode};
|
||||
|
||||
@ -57,7 +58,7 @@ impl TableCtx {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn insert(&mut self, cell: &TableCell, nodes: Vec<TagNode>) {
|
||||
pub(crate) fn insert(&mut self, cell: &Packed<TableCell>, nodes: Vec<TagNode>) {
|
||||
let x = cell.x.get(StyleChain::default()).unwrap_or_else(|| unreachable!());
|
||||
let y = cell.y.get(StyleChain::default()).unwrap_or_else(|| unreachable!());
|
||||
let rowspan = cell.rowspan.get(StyleChain::default());
|
||||
@ -92,6 +93,7 @@ impl TableCtx {
|
||||
kind,
|
||||
headers: SmallVec::new(),
|
||||
nodes,
|
||||
span: cell.span(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -175,13 +177,14 @@ impl TableCtx {
|
||||
.with_headers(cell.headers),
|
||||
)
|
||||
.with_id(Some(id))
|
||||
.with_location(Some(cell.span.into_raw().get()))
|
||||
}
|
||||
TableCellKind::Footer | TableCellKind::Data => TagKind::TD(
|
||||
TableDataCell::new()
|
||||
.with_span(span)
|
||||
.with_headers(cell.headers),
|
||||
)
|
||||
.into(),
|
||||
.with_location(Some(cell.span.into_raw().get())),
|
||||
};
|
||||
Some(TagNode::Group(tag, cell.nodes))
|
||||
})
|
||||
@ -296,6 +299,7 @@ struct TableCtxCell {
|
||||
kind: Smart<TableCellKind>,
|
||||
headers: SmallVec<[TagId; 1]>,
|
||||
nodes: Vec<TagNode>,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl TableCtxCell {
|
||||
@ -344,7 +348,7 @@ mod tests {
|
||||
fn table<const SIZE: usize>(cells: [TableCell; SIZE]) -> TableCtx {
|
||||
let mut table = TableCtx::new(TableId(324), Some("summary".into()));
|
||||
for cell in cells {
|
||||
table.insert(&cell, Vec::new());
|
||||
table.insert(&Packed::new(cell), Vec::new());
|
||||
}
|
||||
table
|
||||
}
|
||||
@ -416,7 +420,9 @@ mod tests {
|
||||
let id = table_cell_id(TableId(324), x, y);
|
||||
let ids = headers.map(|(x, y)| table_cell_id(TableId(324), x, y));
|
||||
TagNode::Group(
|
||||
TagKind::TH(TableHeaderCell::new(scope).with_headers(ids)).with_id(Some(id)),
|
||||
TagKind::TH(TableHeaderCell::new(scope).with_headers(ids))
|
||||
.with_id(Some(id))
|
||||
.with_location(Some(Span::detached().into_raw().get())),
|
||||
Vec::new(),
|
||||
)
|
||||
}
|
||||
@ -424,7 +430,8 @@ mod tests {
|
||||
fn td<const SIZE: usize>(headers: [(u32, u32); SIZE]) -> TagNode {
|
||||
let ids = headers.map(|(x, y)| table_cell_id(TableId(324), x, y));
|
||||
TagNode::Group(
|
||||
TagKind::TD(TableDataCell::new().with_headers(ids)).into(),
|
||||
TagKind::TD(TableDataCell::new().with_headers(ids))
|
||||
.with_location(Some(Span::detached().into_raw().get())),
|
||||
Vec::new(),
|
||||
)
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
||||
items.push(CategoryItem {
|
||||
name: group.name.clone(),
|
||||
route: subpage.route.clone(),
|
||||
oneliner: oneliner(docs).into(),
|
||||
oneliner: oneliner(docs),
|
||||
code: true,
|
||||
});
|
||||
children.push(subpage);
|
||||
@ -296,7 +296,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
||||
items.push(CategoryItem {
|
||||
name: name.into(),
|
||||
route: subpage.route.clone(),
|
||||
oneliner: oneliner(func.docs().unwrap_or_default()).into(),
|
||||
oneliner: oneliner(func.docs().unwrap_or_default()),
|
||||
code: true,
|
||||
});
|
||||
children.push(subpage);
|
||||
@ -306,7 +306,7 @@ fn category_page(resolver: &dyn Resolver, category: Category) -> PageModel {
|
||||
items.push(CategoryItem {
|
||||
name: ty.short_name().into(),
|
||||
route: subpage.route.clone(),
|
||||
oneliner: oneliner(ty.docs()).into(),
|
||||
oneliner: oneliner(ty.docs()),
|
||||
code: true,
|
||||
});
|
||||
children.push(subpage);
|
||||
@ -637,7 +637,7 @@ fn group_page(
|
||||
let item = CategoryItem {
|
||||
name: group.name.clone(),
|
||||
route: model.route.clone(),
|
||||
oneliner: oneliner(&group.details).into(),
|
||||
oneliner: oneliner(&group.details),
|
||||
code: false,
|
||||
};
|
||||
|
||||
@ -772,8 +772,24 @@ pub fn urlify(title: &str) -> EcoString {
|
||||
}
|
||||
|
||||
/// Extract the first line of documentation.
|
||||
fn oneliner(docs: &str) -> &str {
|
||||
docs.lines().next().unwrap_or_default()
|
||||
fn oneliner(docs: &str) -> EcoString {
|
||||
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.
|
||||
|
@ -86,7 +86,7 @@ pub struct FuncModel {
|
||||
pub name: EcoString,
|
||||
pub title: &'static str,
|
||||
pub keywords: &'static [&'static str],
|
||||
pub oneliner: &'static str,
|
||||
pub oneliner: EcoString,
|
||||
pub element: bool,
|
||||
pub contextual: bool,
|
||||
pub deprecation: Option<&'static str>,
|
||||
@ -139,7 +139,7 @@ pub struct TypeModel {
|
||||
pub name: &'static str,
|
||||
pub title: &'static str,
|
||||
pub keywords: &'static [&'static str],
|
||||
pub oneliner: &'static str,
|
||||
pub oneliner: EcoString,
|
||||
pub details: Html,
|
||||
pub constructor: Option<FuncModel>,
|
||||
pub scope: Vec<FuncModel>,
|
||||
|
@ -127,6 +127,10 @@
|
||||
checks = self'.checks;
|
||||
inputsFrom = [ typst ];
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
rust-analyzer
|
||||
];
|
||||
|
||||
packages = [
|
||||
# A script for quickly running tests.
|
||||
# See https://github.com/typst/typst/blob/main/tests/README.md#making-an-alias
|
||||
|
10
tests/ref/html/smallcaps-all.html
Normal file
10
tests/ref/html/smallcaps-all.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<p><span style="font-variant-caps: small-caps">Test 012</span><br><span style="font-variant-caps: all-small-caps">Test 012</span></p>
|
||||
</body>
|
||||
</html>
|
@ -11,6 +11,6 @@
|
||||
#show smallcaps: set text(fill: red)
|
||||
#smallcaps[Smallcaps]
|
||||
|
||||
--- smallcaps-all ---
|
||||
--- smallcaps-all render html ---
|
||||
#smallcaps(all: false)[Test 012] \
|
||||
#smallcaps(all: true)[Test 012]
|
||||
|
Loading…
x
Reference in New Issue
Block a user