Syntax and example sections
This commit is contained in:
parent
ba384e5bb6
commit
b4b022940b
@ -664,7 +664,7 @@ impl FontSearcher {
|
||||
let path = path.as_ref();
|
||||
if let Ok(file) = File::open(path) {
|
||||
if let Ok(mmap) = unsafe { Mmap::map(&file) } {
|
||||
for (i, info) in FontInfo::from_data(&mmap).enumerate() {
|
||||
for (i, info) in FontInfo::iter(&mmap).enumerate() {
|
||||
self.book.push(info);
|
||||
self.fonts.push(FontSlot {
|
||||
path: path.into(),
|
||||
|
@ -7,9 +7,23 @@ use crate::text::{SpaceNode, TextNode, TextSize};
|
||||
|
||||
/// A section heading.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// #set heading(numbering: "I.")
|
||||
///
|
||||
/// = Introduction
|
||||
/// In recent years, ...
|
||||
/// ```
|
||||
///
|
||||
/// # Syntax
|
||||
/// Headings can be created by starting a line with one or multiple equals
|
||||
/// signs. The number of equals signs determines the heading's logical nesting
|
||||
/// depth.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - body: Content (positional, required)
|
||||
/// The heading's contents.
|
||||
///
|
||||
/// - level: NonZeroUsize (named)
|
||||
/// The logical nesting depth of the heading, starting from one.
|
||||
///
|
||||
@ -29,10 +43,31 @@ pub struct HeadingNode {
|
||||
#[node]
|
||||
impl HeadingNode {
|
||||
/// How to number the heading.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// #set heading(numbering: "1.a.")
|
||||
///
|
||||
/// = A section
|
||||
/// == A subsection
|
||||
/// === A sub-subsection
|
||||
/// ```
|
||||
#[property(referenced)]
|
||||
pub const NUMBERING: Option<NumberingPattern> = None;
|
||||
|
||||
/// Whether the heading should appear in the outline.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// #outline()
|
||||
///
|
||||
/// #heading[Normal]
|
||||
/// This is a normal heading.
|
||||
///
|
||||
/// #heading(outlined: false)[Hidden]
|
||||
/// This heading does not appear
|
||||
/// in the outline.
|
||||
/// ```
|
||||
pub const OUTLINED: bool = true;
|
||||
|
||||
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
|
||||
|
@ -8,12 +8,22 @@ use crate::text::{SpaceNode, TextNode};
|
||||
/// # Parameters
|
||||
/// - items: Content (positional, variadic)
|
||||
/// The contents of the list items.
|
||||
///
|
||||
/// - start: NonZeroUsize (named)
|
||||
/// Which number to start the enumeration with.
|
||||
///
|
||||
/// - tight: bool (named)
|
||||
/// Makes the list more compact, if enabled. This looks better if the items
|
||||
/// fit into a single line each.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// #show columns.with(2)
|
||||
/// #list(tight: true)[Tight][List]
|
||||
/// #colbreak()
|
||||
/// #list(tight: false)[Wide][List]
|
||||
/// ```
|
||||
///
|
||||
/// # Tags
|
||||
/// - basics
|
||||
#[func]
|
||||
|
@ -6,14 +6,19 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - cells: Content (positional, variadic)
|
||||
/// The contents of the table cells.
|
||||
///
|
||||
/// - rows: TrackSizings (named)
|
||||
/// Defines the row sizes.
|
||||
///
|
||||
/// - columns: TrackSizings (named)
|
||||
/// Defines the column sizes.
|
||||
///
|
||||
/// - gutter: TrackSizings (named)
|
||||
/// Defines the gaps between rows & columns.
|
||||
///
|
||||
/// - column-gutter: TrackSizings (named)
|
||||
/// Defines the gaps between columns. Takes precedence over `gutter`.
|
||||
///
|
||||
/// - row-gutter: TrackSizings (named)
|
||||
/// Defines the gaps between rows. Takes precedence over `gutter`.
|
||||
///
|
||||
|
@ -105,6 +105,7 @@ pub fn odd(args: &mut Args) -> SourceResult<Value> {
|
||||
/// # Parameters
|
||||
/// - dividend: ToMod (positional, required)
|
||||
/// The dividend of the modulus.
|
||||
///
|
||||
/// - divisor: ToMod (positional, required)
|
||||
/// The divisor of the modulus.
|
||||
///
|
||||
|
@ -77,12 +77,21 @@ pub fn luma(args: &mut Args) -> SourceResult<Value> {
|
||||
///
|
||||
/// If this string is given, the individual components should not be given.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// #let color = rgb("#239dad")
|
||||
/// #text(16pt, color)[*Typst*]
|
||||
/// ```
|
||||
///
|
||||
/// - red: Component (positional)
|
||||
/// The red component.
|
||||
///
|
||||
/// - green: Component (positional)
|
||||
/// The green component.
|
||||
///
|
||||
/// - blue: Component (positional)
|
||||
/// The blue component.
|
||||
///
|
||||
/// - alpha: Component (positional)
|
||||
/// The alpha component.
|
||||
///
|
||||
@ -125,10 +134,13 @@ castable! {
|
||||
/// # Parameters
|
||||
/// - cyan: RatioComponent (positional, required)
|
||||
/// The cyan component.
|
||||
///
|
||||
/// - magenta: RatioComponent (positional, required)
|
||||
/// The magenta component.
|
||||
///
|
||||
/// - yellow: RatioComponent (positional, required)
|
||||
/// The yellow component.
|
||||
///
|
||||
/// - key: RatioComponent (positional, required)
|
||||
/// The key component.
|
||||
///
|
||||
|
@ -22,6 +22,7 @@ pub fn lorem(args: &mut Args) -> SourceResult<Value> {
|
||||
/// # Parameters
|
||||
/// - pattern: NumberingPattern (positional, required)
|
||||
/// A string that defines how the numbering works.
|
||||
///
|
||||
/// - numbers: NonZeroUsize (positional, variadic)
|
||||
/// The numbers to apply the pattern to.
|
||||
///
|
||||
|
@ -5,6 +5,7 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - body: Content (positional, required)
|
||||
/// The content to align.
|
||||
///
|
||||
/// - alignment: Axes<Option<GenAlign>> (positional, settable)
|
||||
/// The alignment along both axes.
|
||||
///
|
||||
|
@ -6,6 +6,7 @@ use crate::text::TextNode;
|
||||
/// # Parameters
|
||||
/// - count: usize (positional, required)
|
||||
/// The number of columns.
|
||||
///
|
||||
/// - body: Content (positional, required)
|
||||
/// The content that should be layouted into the columns.
|
||||
///
|
||||
|
@ -7,8 +7,10 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - body: Content (positional)
|
||||
/// The contents of the box.
|
||||
///
|
||||
/// - width: Rel<Length> (named)
|
||||
/// The width of the box.
|
||||
///
|
||||
/// - height: Rel<Length> (named)
|
||||
/// The height of the box.
|
||||
///
|
||||
@ -78,11 +80,14 @@ impl Inline for BoxNode {}
|
||||
/// # Parameters
|
||||
/// - body: Content (positional)
|
||||
/// The contents of the block.
|
||||
///
|
||||
/// - spacing: Spacing (named, settable)
|
||||
/// The spacing around this block.
|
||||
///
|
||||
/// - above: Spacing (named, settable)
|
||||
/// The spacing between the previous and this block. Takes precedence over
|
||||
/// `spacing`.
|
||||
///
|
||||
/// - below: Spacing (named, settable)
|
||||
/// The spacing between this block and the following one. Takes precedence
|
||||
/// over `spacing`.
|
||||
|
@ -7,14 +7,19 @@ use super::Spacing;
|
||||
/// # Parameters
|
||||
/// - cells: Content (positional, variadic)
|
||||
/// The contents of the table cells.
|
||||
///
|
||||
/// - rows: TrackSizings (named)
|
||||
/// Defines the row sizes.
|
||||
///
|
||||
/// - columns: TrackSizings (named)
|
||||
/// Defines the column sizes.
|
||||
///
|
||||
/// - gutter: TrackSizings (named)
|
||||
/// Defines the gaps between rows & columns.
|
||||
///
|
||||
/// - column-gutter: TrackSizings (named)
|
||||
/// Defines the gaps between columns. Takes precedence over `gutter`.
|
||||
///
|
||||
/// - row-gutter: TrackSizings (named)
|
||||
/// Defines the gaps between rows. Takes precedence over `gutter`.
|
||||
///
|
||||
|
@ -5,18 +5,25 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - body: Content (positional, required)
|
||||
/// The content to pad at the sides.
|
||||
///
|
||||
/// - left: Rel<Length> (named)
|
||||
/// The padding at the left side.
|
||||
///
|
||||
/// - right: Rel<Length> (named)
|
||||
/// The padding at the right side.
|
||||
///
|
||||
/// - top: Rel<Length> (named)
|
||||
/// The padding at the top side.
|
||||
///
|
||||
/// - bottom: Rel<Length> (named)
|
||||
/// The padding at the bottom side.
|
||||
///
|
||||
/// - x: Rel<Length> (named)
|
||||
/// The horizontal padding. Both `left` and `right` take precedence over this.
|
||||
///
|
||||
/// - y: Rel<Length> (named)
|
||||
/// The vertical padding. Both `top` and `bottom` take precedence over this.
|
||||
///
|
||||
/// - rest: Rel<Length> (named)
|
||||
/// The padding for all sides. All other parameters take precedence over this.
|
||||
///
|
||||
|
@ -9,6 +9,7 @@ use crate::text::TextNode;
|
||||
/// # Parameters
|
||||
/// - body: Content (positional, required)
|
||||
/// The contents of the page(s).
|
||||
///
|
||||
/// - paper: Paper (positional, settable)
|
||||
/// The paper size.
|
||||
///
|
||||
|
@ -5,10 +5,13 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - alignment: Axes<Option<GenAlign>> (positional)
|
||||
/// Relative to which position in the parent container to place the content.
|
||||
///
|
||||
/// - body: Content (positional, required)
|
||||
/// The content to place.
|
||||
///
|
||||
/// - dx: Rel<Length> (named)
|
||||
/// The horizontal displacement of the placed content.
|
||||
///
|
||||
/// - dy: Rel<Length> (named)
|
||||
/// The vertical displacement of the placed content.
|
||||
///
|
||||
|
@ -7,6 +7,7 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - amount: Spacing (positional, required)
|
||||
/// How much spacing to insert.
|
||||
///
|
||||
/// - weak: bool (named)
|
||||
/// If true, the spacing collapses at the start or end of a paragraph.
|
||||
/// Moreover, from multiple adjacent weak spacings all but the largest one
|
||||
@ -67,6 +68,7 @@ impl Behave for HNode {
|
||||
/// # Parameters
|
||||
/// - amount: Spacing (positional, required)
|
||||
/// How much spacing to insert.
|
||||
///
|
||||
/// - weak: bool (named)
|
||||
/// If true, the spacing collapses at the start or end of a flow.
|
||||
/// Moreover, from multiple adjacent weak spacings all but the largest one
|
||||
|
@ -8,8 +8,10 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - items: StackChild (positional, variadic)
|
||||
/// The items to stack along an axis.
|
||||
///
|
||||
/// - dir: Dir (named)
|
||||
/// The direction along which the items are stacked.
|
||||
///
|
||||
/// - spacing: Spacing (named)
|
||||
/// Spacing to insert between items where no explicit spacing was provided.
|
||||
///
|
||||
|
@ -7,8 +7,10 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - body: Content (positional, required)
|
||||
/// The content to move.
|
||||
///
|
||||
/// - dx: Rel<Length> (named)
|
||||
/// The horizontal displacement of the content.
|
||||
///
|
||||
/// - dy: Rel<Length> (named)
|
||||
/// The vertical displacement of the content.
|
||||
///
|
||||
@ -61,10 +63,13 @@ impl Inline for MoveNode {}
|
||||
/// # Parameters
|
||||
/// - body: Content (positional, required)
|
||||
/// The content to transform.
|
||||
///
|
||||
/// - angle: Angle (named)
|
||||
/// The amount of rotation.
|
||||
///
|
||||
/// - x: Ratio (named)
|
||||
/// The horizontal scaling factor.
|
||||
///
|
||||
/// - y: Ratio (named)
|
||||
/// The vertical scaling factor.
|
||||
///
|
||||
|
@ -19,6 +19,7 @@ use crate::text::{FontFamily, LinebreakNode, SpaceNode, SymbolNode, TextNode};
|
||||
/// # Parameters
|
||||
/// - items: Content (positional, variadic)
|
||||
/// The individual parts of the formula.
|
||||
///
|
||||
/// - block: bool (named)
|
||||
/// Whether the formula is displayed as a separate block.
|
||||
///
|
||||
@ -309,6 +310,7 @@ impl Texify for AtomNode {
|
||||
/// # Parameters
|
||||
/// - base: Content (positional, required)
|
||||
/// The base to which the accent is applied.
|
||||
///
|
||||
/// - accent: Content (positional, required)
|
||||
/// The accent to apply to the base.
|
||||
///
|
||||
@ -393,6 +395,7 @@ impl Texify for AccNode {
|
||||
/// # Parameters
|
||||
/// - num: Content (positional, required)
|
||||
/// The fraction's numerator.
|
||||
///
|
||||
/// - denom: Content (positional, required)
|
||||
/// The fraction's denominator.
|
||||
///
|
||||
@ -433,6 +436,7 @@ impl Texify for FracNode {
|
||||
/// # Parameters
|
||||
/// - upper: Content (positional, required)
|
||||
/// The binomial's upper index.
|
||||
///
|
||||
/// - lower: Content (positional, required)
|
||||
/// The binomial's lower index.
|
||||
///
|
||||
@ -473,8 +477,10 @@ impl Texify for BinomNode {
|
||||
/// # Parameters
|
||||
/// - base: Content (positional, required)
|
||||
/// The base to which the applies the sub- and/or superscript.
|
||||
///
|
||||
/// - sub: Content (named)
|
||||
/// The subscript.
|
||||
///
|
||||
/// - sup: Content (named)
|
||||
/// The superscript.
|
||||
///
|
||||
|
@ -6,6 +6,7 @@ use crate::text::TextNode;
|
||||
/// # Parameters
|
||||
/// - dest: Destination (positional, required)
|
||||
/// The destination the link points to.
|
||||
///
|
||||
/// - body: Content (positional)
|
||||
/// How the link is represented. Defaults to the destination if it is a link.
|
||||
///
|
||||
|
@ -30,6 +30,7 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - family: EcoString (positional, variadic, settable)
|
||||
/// A prioritized sequence of font families.
|
||||
///
|
||||
/// - body: Content (positional, required)
|
||||
/// Content in which all text is styled according to the other arguments.
|
||||
///
|
||||
|
@ -11,6 +11,7 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - text: EcoString (positional, required)
|
||||
/// The raw text.
|
||||
///
|
||||
/// - block: bool (named)
|
||||
/// Whether the raw text is displayed as a separate block.
|
||||
///
|
||||
|
@ -7,10 +7,13 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - origin: Axes<Rel<Length>> (named)
|
||||
/// The start point of the line.
|
||||
///
|
||||
/// - to: Axes<Rel<Length>> (named)
|
||||
/// The end point of the line.
|
||||
///
|
||||
/// - length: Rel<Length> (named)
|
||||
/// The line's length.
|
||||
///
|
||||
/// - angle: Angle (named)
|
||||
/// The angle at which the line points away from the origin.
|
||||
///
|
||||
|
@ -7,14 +7,19 @@ use crate::prelude::*;
|
||||
/// # Parameters
|
||||
/// - body: Content (positional)
|
||||
/// The content to place into the shape.
|
||||
///
|
||||
/// - width: Rel<Length> (named)
|
||||
/// The shape's width.
|
||||
///
|
||||
/// - height: Rel<Length> (named)
|
||||
/// The shape's height.
|
||||
///
|
||||
/// - size: Length (named)
|
||||
/// The square's side length.
|
||||
///
|
||||
/// - radius: Length (named)
|
||||
/// The circle's radius.
|
||||
///
|
||||
/// - stroke: Smart<Sides<Option<PartialStroke>>> (named)
|
||||
/// How to stroke the shape.
|
||||
///
|
||||
|
@ -1,4 +1,3 @@
|
||||
use proc_macro2::Span;
|
||||
use unscanny::Scanner;
|
||||
|
||||
use super::*;
|
||||
@ -14,12 +13,21 @@ pub fn func(item: syn::Item) -> Result<TokenStream> {
|
||||
|
||||
let tags = tags(&mut docs);
|
||||
let params = params(&mut docs)?;
|
||||
let example = quote_option(example(&mut docs));
|
||||
let syntax = quote_option(section(&mut docs, "Syntax"));
|
||||
|
||||
let docs = docs.trim();
|
||||
if docs.contains("# ") {
|
||||
bail!(item, "Documentation heading not recognized");
|
||||
}
|
||||
|
||||
let info = quote! {
|
||||
::typst::model::FuncInfo {
|
||||
name,
|
||||
docs: #docs,
|
||||
tags: &[#(#tags),*],
|
||||
docs: #docs,
|
||||
example: #example,
|
||||
syntax: #syntax,
|
||||
params: ::std::vec![#(#params),*],
|
||||
}
|
||||
};
|
||||
@ -76,18 +84,18 @@ pub fn func(item: syn::Item) -> Result<TokenStream> {
|
||||
|
||||
/// Extract a section.
|
||||
pub fn section(docs: &mut String, title: &str) -> Option<String> {
|
||||
let needle = format!("# {title}\n");
|
||||
let needle = format!("\n# {title}\n");
|
||||
let start = docs.find(&needle)?;
|
||||
let rest = &docs[start..];
|
||||
let len = rest[1..].find('#').map(|x| 1 + x).unwrap_or(rest.len());
|
||||
let len = rest[1..].find("\n# ").map(|x| 1 + x).unwrap_or(rest.len());
|
||||
let end = start + len;
|
||||
let section = docs[start + needle.len()..].to_owned();
|
||||
let section = docs[start + needle.len()..end].trim().to_owned();
|
||||
docs.replace_range(start..end, "");
|
||||
Some(section)
|
||||
}
|
||||
|
||||
/// Parse the tag section.
|
||||
pub fn tags(docs: &mut String) -> Vec<String> {
|
||||
fn tags(docs: &mut String) -> Vec<String> {
|
||||
section(docs, "Tags")
|
||||
.unwrap_or_default()
|
||||
.lines()
|
||||
@ -96,24 +104,40 @@ pub fn tags(docs: &mut String) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Parse the example section.
|
||||
pub fn example(docs: &mut String) -> Option<String> {
|
||||
Some(
|
||||
section(docs, "Example")?
|
||||
.lines()
|
||||
.skip_while(|line| !line.contains("```"))
|
||||
.skip(1)
|
||||
.take_while(|line| !line.contains("```"))
|
||||
.map(|s| s.trim())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Parse the parameter section.
|
||||
pub fn params(docs: &mut String) -> Result<Vec<TokenStream>> {
|
||||
fn params(docs: &mut String) -> Result<Vec<TokenStream>> {
|
||||
let Some(section) = section(docs, "Parameters") else { return Ok(vec![]) };
|
||||
let mut s = Scanner::new(§ion);
|
||||
let mut infos = vec![];
|
||||
|
||||
while s.eat_if('-') {
|
||||
s.eat_whitespace();
|
||||
let name = s.eat_until(':');
|
||||
s.expect(": ");
|
||||
let ty: syn::Type = syn::parse_str(s.eat_until(char::is_whitespace))?;
|
||||
s.eat_whitespace();
|
||||
let mut named = false;
|
||||
let mut positional = false;
|
||||
let mut required = false;
|
||||
let mut variadic = false;
|
||||
let mut settable = false;
|
||||
|
||||
s.eat_whitespace();
|
||||
let name = s.eat_until(':');
|
||||
s.expect(": ");
|
||||
let ty: syn::Type = syn::parse_str(s.eat_until(char::is_whitespace))?;
|
||||
s.eat_whitespace();
|
||||
s.expect('(');
|
||||
|
||||
for part in s.eat_until(')').split(',').map(str::trim).filter(|s| !s.is_empty()) {
|
||||
match part {
|
||||
"named" => named = true,
|
||||
@ -121,12 +145,7 @@ pub fn params(docs: &mut String) -> Result<Vec<TokenStream>> {
|
||||
"required" => required = true,
|
||||
"variadic" => variadic = true,
|
||||
"settable" => settable = true,
|
||||
_ => {
|
||||
return Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
format!("unknown parameter flag {:?}", part),
|
||||
))
|
||||
}
|
||||
_ => bail!(callsite, "unknown parameter flag {:?}", part),
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,18 +154,20 @@ pub fn params(docs: &mut String) -> Result<Vec<TokenStream>> {
|
||||
|| (named && variadic)
|
||||
|| (required && variadic)
|
||||
{
|
||||
return Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"invalid combination of parameter flags",
|
||||
));
|
||||
bail!(callsite, "invalid combination of parameter flags");
|
||||
}
|
||||
|
||||
s.expect(')');
|
||||
let docs = dedent(s.eat_until("\n-").trim());
|
||||
|
||||
let mut docs = dedent(s.eat_until("\n-").trim());
|
||||
let example = quote_option(example(&mut docs));
|
||||
let docs = docs.trim();
|
||||
|
||||
infos.push(quote! {
|
||||
::typst::model::ParamInfo {
|
||||
name: #name,
|
||||
docs: #docs,
|
||||
example: #example,
|
||||
cast: <#ty as ::typst::model::Cast<
|
||||
::typst::syntax::Spanned<::typst::model::Value>
|
||||
>>::describe(),
|
||||
|
@ -4,12 +4,18 @@ extern crate proc_macro;
|
||||
|
||||
/// Return an error at the given item.
|
||||
macro_rules! bail {
|
||||
(callsite, $fmt:literal $($tts:tt)*) => {
|
||||
return Err(syn::Error::new(
|
||||
proc_macro2::Span::call_site(),
|
||||
format!(concat!("typst: ", $fmt) $($tts)*)
|
||||
))
|
||||
};
|
||||
($item:expr, $fmt:literal $($tts:tt)*) => {
|
||||
return Err(Error::new_spanned(
|
||||
return Err(syn::Error::new_spanned(
|
||||
&$item,
|
||||
format!(concat!("typst: ", $fmt) $($tts)*)
|
||||
))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mod capable;
|
||||
@ -19,9 +25,8 @@ mod node;
|
||||
|
||||
use proc_macro::TokenStream as BoundaryStream;
|
||||
use proc_macro2::{TokenStream, TokenTree};
|
||||
use quote::{quote, quote_spanned};
|
||||
use syn::parse_quote;
|
||||
use syn::{Error, Ident, Result};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use syn::{parse_quote, Ident, Result};
|
||||
|
||||
/// Implement `FuncType` for a type or function.
|
||||
#[proc_macro_attribute]
|
||||
@ -88,3 +93,11 @@ fn documentation(attrs: &[syn::Attribute]) -> String {
|
||||
fn dedent(text: &str) -> String {
|
||||
text.lines().map(str::trim).collect::<Vec<_>>().join("\n")
|
||||
}
|
||||
|
||||
/// Quote an optional value.
|
||||
fn quote_option<T: ToTokens>(option: Option<T>) -> TokenStream {
|
||||
match option {
|
||||
Some(value) => quote! { Some(#value) },
|
||||
None => quote! { None },
|
||||
}
|
||||
}
|
||||
|
@ -333,13 +333,18 @@ fn create_node_set_func(node: &Node) -> syn::ImplItemMethod {
|
||||
fn create_node_properties_func(node: &Node) -> syn::ImplItemMethod {
|
||||
let infos = node.properties.iter().filter(|p| !p.skip).map(|property| {
|
||||
let name = property.name.to_string().replace('_', "-").to_lowercase();
|
||||
let docs = documentation(&property.attrs);
|
||||
let value_ty = &property.value_ty;
|
||||
let shorthand = matches!(property.shorthand, Some(Shorthand::Positional));
|
||||
|
||||
let mut docs = documentation(&property.attrs);
|
||||
let example = quote_option(super::func::example(&mut docs));
|
||||
let docs = docs.trim();
|
||||
|
||||
quote! {
|
||||
::typst::model::ParamInfo {
|
||||
name: #name,
|
||||
docs: #docs,
|
||||
example: #example,
|
||||
cast: <#value_ty as ::typst::model::Cast<
|
||||
::typst::syntax::Spanned<::typst::model::Value>
|
||||
>>::describe(),
|
||||
|
@ -170,7 +170,7 @@ bitflags::bitflags! {
|
||||
|
||||
impl FontInfo {
|
||||
/// Compute metadata for all fonts in the given data.
|
||||
pub fn from_data(data: &[u8]) -> impl Iterator<Item = FontInfo> + '_ {
|
||||
pub fn iter(data: &[u8]) -> impl Iterator<Item = FontInfo> + '_ {
|
||||
let count = ttf_parser::fonts_in_collection(data).unwrap_or(1);
|
||||
(0..count).filter_map(move |index| {
|
||||
let ttf = ttf_parser::Face::parse(data, index).ok()?;
|
||||
@ -179,7 +179,7 @@ impl FontInfo {
|
||||
}
|
||||
|
||||
/// Compute metadata for a single ttf-parser face.
|
||||
pub fn from_ttf(ttf: &ttf_parser::Face) -> Option<Self> {
|
||||
pub(super) fn from_ttf(ttf: &ttf_parser::Face) -> Option<Self> {
|
||||
// We cannot use Name ID 16 "Typographic Family", because for some
|
||||
// fonts it groups together more than just Style / Weight / Stretch
|
||||
// variants (e.g. Display variants of Noto fonts) and then some
|
||||
|
@ -69,6 +69,12 @@ impl Font {
|
||||
})))
|
||||
}
|
||||
|
||||
/// Parse all fonts in the given data.
|
||||
pub fn iter(data: Buffer) -> impl Iterator<Item = Self> {
|
||||
let count = ttf_parser::fonts_in_collection(&data).unwrap_or(1);
|
||||
(0..count).filter_map(move |index| Self::new(data.clone(), index))
|
||||
}
|
||||
|
||||
/// The underlying buffer.
|
||||
pub fn data(&self) -> &Buffer {
|
||||
&self.0.data
|
||||
|
@ -214,6 +214,10 @@ pub struct FuncInfo {
|
||||
pub tags: &'static [&'static str],
|
||||
/// Documentation for the function.
|
||||
pub docs: &'static str,
|
||||
/// The source code of an example, if any.
|
||||
pub example: Option<&'static str>,
|
||||
/// Documentation about this function's syntax, if it has syntax.
|
||||
pub syntax: Option<&'static str>,
|
||||
/// Details about the function's parameters.
|
||||
pub params: Vec<ParamInfo>,
|
||||
}
|
||||
@ -232,6 +236,8 @@ pub struct ParamInfo {
|
||||
pub name: &'static str,
|
||||
/// Documentation for the parameter.
|
||||
pub docs: &'static str,
|
||||
/// The source code of an example, if any.
|
||||
pub example: Option<&'static str>,
|
||||
/// Valid values for the parameter.
|
||||
pub cast: CastInfo,
|
||||
/// Is the parameter positional?
|
||||
|
@ -122,7 +122,7 @@ pub static LANG_ITEMS: OnceCell<LangItems> = OnceCell::new();
|
||||
/// break incremental, but only when different sets of lang items are used in
|
||||
/// the same program. For this reason, if this function is called multiple
|
||||
/// times, the items must be the same.
|
||||
pub(crate) fn set_lang_items(items: LangItems) {
|
||||
pub fn set_lang_items(items: LangItems) {
|
||||
if let Err(items) = LANG_ITEMS.set(items) {
|
||||
let first = hash128(LANG_ITEMS.get().unwrap());
|
||||
let second = hash128(&items);
|
||||
|
@ -213,10 +213,8 @@ impl TestWorld {
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|entry| entry.file_type().is_file())
|
||||
{
|
||||
let buffer: Buffer = fs::read(entry.path()).unwrap().into();
|
||||
for index in 0..ttf_parser::fonts_in_collection(&buffer).unwrap_or(1) {
|
||||
fonts.push(Font::new(buffer.clone(), index).unwrap())
|
||||
}
|
||||
let data = std::fs::read(entry.path()).unwrap();
|
||||
fonts.extend(Font::iter(data.into()));
|
||||
}
|
||||
|
||||
Self {
|
||||
|
Loading…
x
Reference in New Issue
Block a user