diff --git a/crates/typst-library/src/html/mod.rs b/crates/typst-library/src/html/mod.rs index 1d88781c1..16013dcbc 100644 --- a/crates/typst-library/src/html/mod.rs +++ b/crates/typst-library/src/html/mod.rs @@ -7,6 +7,7 @@ pub use self::dom::*; use ecow::EcoString; use crate::foundations::{elem, Content, Module, Scope}; +use crate::introspection::Locatable; /// Create a module with all HTML definitions. pub fn module() -> Module { @@ -38,7 +39,7 @@ pub fn module() -> Module { /// A div with _Typst content_ inside! /// ] /// ``` -#[elem(name = "elem")] +#[elem(name = "elem", Locatable)] pub struct HtmlElem { /// The element's tag. #[required] diff --git a/crates/typst-library/src/introspection/introspector.rs b/crates/typst-library/src/introspection/introspector.rs index 9751dfcb8..a8e87124a 100644 --- a/crates/typst-library/src/introspection/introspector.rs +++ b/crates/typst-library/src/introspection/introspector.rs @@ -388,6 +388,8 @@ impl IntrospectorBuilder { ); } + dbg!(elems.len()); + self.finalize(elems) } diff --git a/crates/typst-library/src/layout/grid/mod.rs b/crates/typst-library/src/layout/grid/mod.rs index 6616c3311..245451bac 100644 --- a/crates/typst-library/src/layout/grid/mod.rs +++ b/crates/typst-library/src/layout/grid/mod.rs @@ -13,6 +13,7 @@ use crate::foundations::{ cast, elem, scope, Array, CastInfo, Content, Context, Fold, FromValue, Func, IntoValue, NativeElement, Packed, Reflect, Resolve, Show, Smart, StyleChain, Value, }; +use crate::introspection::Locatable; use crate::layout::{ Alignment, BlockElem, Length, OuterHAlignment, OuterVAlignment, Rel, Sides, Sizing, }; @@ -136,7 +137,7 @@ use crate::visualize::{Paint, Stroke}; /// /// Furthermore, strokes of a repeated grid header or footer will take /// precedence over regular cell strokes. -#[elem(scope, Show)] +#[elem(scope, Locatable, Show)] pub struct GridElem { /// The column sizes. /// @@ -462,7 +463,7 @@ impl TryFrom for GridItem { /// If `repeat` is set to `true`, the header will be repeated across pages. For /// an example, refer to the [`table.header`]($table.header) element and the /// [`grid.stroke`]($grid.stroke) parameter. -#[elem(name = "header", title = "Grid Header")] +#[elem(name = "header", title = "Grid Header", Locatable)] pub struct GridHeader { /// Whether this header should be repeated across pages. #[default(true)] @@ -479,7 +480,7 @@ pub struct GridHeader { /// itself on every page of the table. /// /// No other grid cells may be placed after the footer. -#[elem(name = "footer", title = "Grid Footer")] +#[elem(name = "footer", title = "Grid Footer", Locatable)] pub struct GridFooter { /// Whether this footer should be repeated across pages. #[default(true)] @@ -646,7 +647,7 @@ pub struct GridVLine { /// which allows you, for example, to apply styles based on a cell's position. /// Refer to the examples of the [`table.cell`]($table.cell) element to learn /// more about this. -#[elem(name = "cell", title = "Grid Cell", Show)] +#[elem(name = "cell", title = "Grid Cell", Locatable, Show)] pub struct GridCell { /// The cell's body. #[required] diff --git a/crates/typst-library/src/layout/hide.rs b/crates/typst-library/src/layout/hide.rs index eca33471a..dafff06cd 100644 --- a/crates/typst-library/src/layout/hide.rs +++ b/crates/typst-library/src/layout/hide.rs @@ -1,6 +1,7 @@ use crate::diag::SourceResult; use crate::engine::Engine; use crate::foundations::{elem, Content, Packed, Show, StyleChain}; +use crate::introspection::Locatable; /// Hides content without affecting layout. /// @@ -14,7 +15,7 @@ use crate::foundations::{elem, Content, Packed, Show, StyleChain}; /// Hello Jane \ /// #hide[Hello] Joe /// ``` -#[elem(Show)] +#[elem(Locatable, Show)] pub struct HideElem { /// The content to hide. #[required] diff --git a/crates/typst-library/src/layout/repeat.rs b/crates/typst-library/src/layout/repeat.rs index 9579f1856..ab042ceb1 100644 --- a/crates/typst-library/src/layout/repeat.rs +++ b/crates/typst-library/src/layout/repeat.rs @@ -1,6 +1,7 @@ use crate::diag::SourceResult; use crate::engine::Engine; use crate::foundations::{elem, Content, NativeElement, Packed, Show, StyleChain}; +use crate::introspection::Locatable; use crate::layout::{BlockElem, Length}; /// Repeats content to the available space. @@ -24,7 +25,7 @@ use crate::layout::{BlockElem, Length}; /// Berlin, the 22nd of December, 2022 /// ] /// ``` -#[elem(Show)] +#[elem(Locatable, Show)] pub struct RepeatElem { /// The content to repeat. #[required] diff --git a/crates/typst-library/src/math/mod.rs b/crates/typst-library/src/math/mod.rs index 2e6d42b13..5daa3e358 100644 --- a/crates/typst-library/src/math/mod.rs +++ b/crates/typst-library/src/math/mod.rs @@ -28,6 +28,7 @@ use typst_utils::singleton; use unicode_math_class::MathClass; use crate::foundations::{elem, Content, Module, NativeElement, Scope}; +use crate::introspection::Locatable; use crate::layout::{Em, HElem}; use crate::text::TextElem; @@ -109,7 +110,7 @@ pub fn module() -> Module { pub trait Mathy {} /// A math alignment point: `&`, `&&`. -#[elem(title = "Alignment Point", Mathy)] +#[elem(title = "Alignment Point", Mathy, Locatable)] pub struct AlignPointElem {} impl AlignPointElem { @@ -136,7 +137,7 @@ impl AlignPointElem { /// /// $x loves y and y loves 5$ /// ``` -#[elem(Mathy)] +#[elem(Mathy, Locatable)] pub struct ClassElem { /// The class to apply to the content. #[required] diff --git a/crates/typst-library/src/math/root.rs b/crates/typst-library/src/math/root.rs index ad111700b..15ef8c55d 100644 --- a/crates/typst-library/src/math/root.rs +++ b/crates/typst-library/src/math/root.rs @@ -1,6 +1,7 @@ use typst_syntax::Span; use crate::foundations::{elem, func, Content, NativeElement}; +use crate::introspection::Locatable; use crate::math::Mathy; /// A square root. @@ -22,7 +23,7 @@ pub fn sqrt( /// ```example /// $ root(3, x) $ /// ``` -#[elem(Mathy)] +#[elem(Mathy, Locatable)] pub struct RootElem { /// Which root of the radicand to take. #[positional] diff --git a/crates/typst-library/src/model/cite.rs b/crates/typst-library/src/model/cite.rs index 29497993d..7d118d59f 100644 --- a/crates/typst-library/src/model/cite.rs +++ b/crates/typst-library/src/model/cite.rs @@ -43,7 +43,7 @@ use crate::text::{Lang, Region, TextElem}; /// This function indirectly has dedicated syntax. [References]($ref) can be /// used to cite works from the bibliography. The label then corresponds to the /// citation key. -#[elem(Synthesize)] +#[elem(Locatable, Synthesize)] pub struct CiteElem { /// The citation key that identifies the entry in the bibliography that /// shall be cited, as a label. diff --git a/crates/typst-library/src/model/emph.rs b/crates/typst-library/src/model/emph.rs index 45097b340..73744381f 100644 --- a/crates/typst-library/src/model/emph.rs +++ b/crates/typst-library/src/model/emph.rs @@ -4,6 +4,7 @@ use crate::foundations::{ elem, Content, NativeElement, Packed, Show, StyleChain, TargetElem, }; use crate::html::{tag, HtmlElem}; +use crate::introspection::Locatable; use crate::text::{ItalicToggle, TextElem}; /// Emphasizes content by toggling italics. @@ -29,7 +30,7 @@ use crate::text::{ItalicToggle, TextElem}; /// This function also has dedicated syntax: To emphasize content, simply /// enclose it in underscores (`_`). Note that this only works at word /// boundaries. To emphasize part of a word, you have to use the function. -#[elem(title = "Emphasis", keywords = ["italic"], Show)] +#[elem(title = "Emphasis", keywords = ["italic"], Locatable, Show)] pub struct EmphElem { /// The content to emphasize. #[required] diff --git a/crates/typst-library/src/model/enum.rs b/crates/typst-library/src/model/enum.rs index f1f93702b..0b5211d5f 100644 --- a/crates/typst-library/src/model/enum.rs +++ b/crates/typst-library/src/model/enum.rs @@ -10,6 +10,7 @@ use crate::foundations::{ Styles, TargetElem, }; use crate::html::{attr, tag, HtmlElem}; +use crate::introspection::Locatable; use crate::layout::{Alignment, BlockElem, Em, HAlignment, Length, VAlignment, VElem}; use crate::model::{ ListItemLike, ListLike, Numbering, NumberingPattern, ParElem, ParbreakElem, @@ -71,7 +72,7 @@ use crate::model::{ /// Enumeration items can contain multiple paragraphs and other block-level /// content. All content that is indented more than an item's marker becomes /// part of that item. -#[elem(scope, title = "Numbered List", Show)] +#[elem(scope, title = "Numbered List", Locatable, Show)] pub struct EnumElem { /// Defines the default [spacing]($enum.spacing) of the enumeration. If it /// is `{false}`, the items are spaced apart with @@ -271,7 +272,7 @@ impl Show for Packed { } /// An enumeration item. -#[elem(name = "item", title = "Numbered List Item")] +#[elem(name = "item", title = "Numbered List Item", Locatable)] pub struct EnumItem { /// The item's number. #[positional] diff --git a/crates/typst-library/src/model/figure.rs b/crates/typst-library/src/model/figure.rs index 5a137edbd..5dce63cf8 100644 --- a/crates/typst-library/src/model/figure.rs +++ b/crates/typst-library/src/model/figure.rs @@ -470,7 +470,7 @@ impl Outlinable for Packed { /// caption: [A rectangle], /// ) /// ``` -#[elem(name = "caption", Synthesize, Show)] +#[elem(name = "caption", Locatable, Synthesize, Show)] pub struct FigureCaption { /// The caption's position in the figure. Either `{top}` or `{bottom}`. /// diff --git a/crates/typst-library/src/model/footnote.rs b/crates/typst-library/src/model/footnote.rs index dfa3933bb..773f67467 100644 --- a/crates/typst-library/src/model/footnote.rs +++ b/crates/typst-library/src/model/footnote.rs @@ -192,7 +192,7 @@ cast! { /// page run is a sequence of pages without an explicit pagebreak in between). /// For this reason, set and show rules for footnote entries should be defined /// before any page content, typically at the very start of the document. -#[elem(name = "entry", title = "Footnote Entry", Show, ShowSet)] +#[elem(name = "entry", title = "Footnote Entry", Locatable, Show, ShowSet)] pub struct FootnoteEntry { /// The footnote for this entry. Its location can be used to determine /// the footnote counter state. diff --git a/crates/typst-library/src/model/link.rs b/crates/typst-library/src/model/link.rs index ea85aa945..3d9dc5e55 100644 --- a/crates/typst-library/src/model/link.rs +++ b/crates/typst-library/src/model/link.rs @@ -9,7 +9,7 @@ use crate::foundations::{ StyleChain, Styles, TargetElem, }; use crate::html::{attr, tag, HtmlElem}; -use crate::introspection::Location; +use crate::introspection::{Locatable, Location}; use crate::layout::Position; use crate::text::TextElem; @@ -38,7 +38,7 @@ use crate::text::TextElem; /// # Syntax /// This function also has dedicated syntax: Text that starts with `http://` or /// `https://` is automatically turned into a link. -#[elem(Show)] +#[elem(Locatable, Show)] pub struct LinkElem { /// The destination the link points to. /// diff --git a/crates/typst-library/src/model/list.rs b/crates/typst-library/src/model/list.rs index 3c3afd338..a36be3cfc 100644 --- a/crates/typst-library/src/model/list.rs +++ b/crates/typst-library/src/model/list.rs @@ -7,6 +7,7 @@ use crate::foundations::{ Smart, StyleChain, Styles, TargetElem, Value, }; use crate::html::{tag, HtmlElem}; +use crate::introspection::Locatable; use crate::layout::{BlockElem, Em, Length, VElem}; use crate::model::{ParElem, ParbreakElem}; use crate::text::TextElem; @@ -42,7 +43,7 @@ use crate::text::TextElem; /// followed by a space to create a list item. A list item can contain multiple /// paragraphs and other block-level content. All content that is indented /// more than an item's marker becomes part of that item. -#[elem(scope, title = "Bullet List", Show)] +#[elem(scope, title = "Bullet List", Locatable, Show)] pub struct ListElem { /// Defines the default [spacing]($list.spacing) of the list. If it is /// `{false}`, the items are spaced apart with @@ -178,7 +179,7 @@ impl Show for Packed { } /// A bullet list item. -#[elem(name = "item", title = "Bullet List Item")] +#[elem(name = "item", title = "Bullet List Item", Locatable)] pub struct ListItem { /// The item's body. #[required] diff --git a/crates/typst-library/src/model/outline.rs b/crates/typst-library/src/model/outline.rs index 489c375e6..03d301135 100644 --- a/crates/typst-library/src/model/outline.rs +++ b/crates/typst-library/src/model/outline.rs @@ -368,7 +368,7 @@ pub trait Outlinable: Refable { /// With show-set and show rules on outline entries, you can richly customize /// the outline's appearance. See the /// [section on styling the outline]($outline/#styling-the-outline) for details. -#[elem(scope, name = "entry", title = "Outline Entry", Show)] +#[elem(scope, name = "entry", title = "Outline Entry", Locatable, Show)] pub struct OutlineEntry { /// The nesting level of this outline entry. Starts at `{1}` for top-level /// entries. diff --git a/crates/typst-library/src/model/par.rs b/crates/typst-library/src/model/par.rs index cf31b5195..ed4f333e4 100644 --- a/crates/typst-library/src/model/par.rs +++ b/crates/typst-library/src/model/par.rs @@ -93,7 +93,7 @@ use crate::model::Numbering; /// let $a$ be the smallest of the /// three integers. Then, we ... /// ``` -#[elem(scope, title = "Paragraph")] +#[elem(scope, title = "Paragraph", Locatable)] pub struct ParElem { /// The spacing between lines. /// diff --git a/crates/typst-library/src/model/strong.rs b/crates/typst-library/src/model/strong.rs index 16d04ba97..ba795b33f 100644 --- a/crates/typst-library/src/model/strong.rs +++ b/crates/typst-library/src/model/strong.rs @@ -4,6 +4,7 @@ use crate::foundations::{ elem, Content, NativeElement, Packed, Show, StyleChain, TargetElem, }; use crate::html::{tag, HtmlElem}; +use crate::introspection::Locatable; use crate::text::{TextElem, WeightDelta}; /// Strongly emphasizes content by increasing the font weight. @@ -24,7 +25,7 @@ use crate::text::{TextElem, WeightDelta}; /// simply enclose it in stars/asterisks (`*`). Note that this only works at /// word boundaries. To strongly emphasize part of a word, you have to use the /// function. -#[elem(title = "Strong Emphasis", keywords = ["bold", "weight"], Show)] +#[elem(title = "Strong Emphasis", keywords = ["bold", "weight"], Locatable, Show)] pub struct StrongElem { /// The delta to apply on the font weight. /// diff --git a/crates/typst-library/src/model/table.rs b/crates/typst-library/src/model/table.rs index 6f4461bd4..94a794a16 100644 --- a/crates/typst-library/src/model/table.rs +++ b/crates/typst-library/src/model/table.rs @@ -10,7 +10,7 @@ use crate::foundations::{ TargetElem, }; use crate::html::{attr, tag, HtmlAttrs, HtmlElem, HtmlTag}; -use crate::introspection::Locator; +use crate::introspection::{Locatable, Locator}; use crate::layout::grid::resolve::{table_to_cellgrid, Cell, CellGrid, Entry}; use crate::layout::{ show_grid_cell, Abs, Alignment, BlockElem, Celled, GridCell, GridFooter, GridHLine, @@ -121,7 +121,7 @@ use crate::visualize::{Paint, Stroke}; /// [Robert], b, a, b, /// ) /// ``` -#[elem(scope, Show, LocalName, Figurable)] +#[elem(scope, Locatable, Show, LocalName, Figurable)] pub struct TableElem { /// The column sizes. See the [grid documentation]($grid) for more /// information on track sizing. @@ -486,7 +486,7 @@ impl TryFrom for TableItem { /// [7.34], [57], [2], /// ) /// ``` -#[elem(name = "header", title = "Table Header")] +#[elem(name = "header", title = "Table Header", Locatable)] pub struct TableHeader { /// Whether this header should be repeated across pages. #[default(true)] @@ -505,7 +505,7 @@ pub struct TableHeader { /// totals, or other information that should be visible on every page. /// /// No other table cells may be placed after the footer. -#[elem(name = "footer", title = "Table Footer")] +#[elem(name = "footer", title = "Table Footer", Locatable)] pub struct TableFooter { /// Whether this footer should be repeated across pages. #[default(true)] @@ -548,7 +548,7 @@ pub struct TableFooter { /// [19:00], [Day 1 Attendee Mixer], /// ) /// ``` -#[elem(name = "hline", title = "Table Horizontal Line")] +#[elem(name = "hline", title = "Table Horizontal Line", Locatable)] pub struct TableHLine { /// The row above which the horizontal line is placed (zero-indexed). /// Functions identically to the `y` field in [`grid.hline`]($grid.hline.y). @@ -593,7 +593,7 @@ pub struct TableHLine { /// use the [table's `stroke`]($table.stroke) field or [`table.cell`'s /// `stroke`]($table.cell.stroke) field instead if the line you want to place is /// part of all your tables' designs. -#[elem(name = "vline", title = "Table Vertical Line")] +#[elem(name = "vline", title = "Table Vertical Line", Locatable)] pub struct TableVLine { /// The column before which the horizontal line is placed (zero-indexed). /// Functions identically to the `x` field in [`grid.vline`]($grid.vline). @@ -714,7 +714,7 @@ pub struct TableVLine { /// [Vikram], [49], [Perseverance], /// ) /// ``` -#[elem(name = "cell", title = "Table Cell", Show)] +#[elem(name = "cell", title = "Table Cell", Locatable, Show)] pub struct TableCell { /// The cell's body. #[required] diff --git a/crates/typst-library/src/model/terms.rs b/crates/typst-library/src/model/terms.rs index 3df74cd9e..2679a9500 100644 --- a/crates/typst-library/src/model/terms.rs +++ b/crates/typst-library/src/model/terms.rs @@ -7,6 +7,7 @@ use crate::foundations::{ Styles, TargetElem, }; use crate::html::{tag, HtmlElem}; +use crate::introspection::Locatable; use crate::layout::{Em, HElem, Length, Sides, StackChild, StackElem, VElem}; use crate::model::{ListItemLike, ListLike, ParElem, ParbreakElem}; use crate::text::TextElem; @@ -27,7 +28,7 @@ use crate::text::TextElem; /// # Syntax /// This function also has dedicated syntax: Starting a line with a slash, /// followed by a term, a colon and a description creates a term list item. -#[elem(scope, title = "Term List", Show)] +#[elem(scope, title = "Term List", Locatable, Show)] pub struct TermsElem { /// Defines the default [spacing]($terms.spacing) of the term list. If it is /// `{false}`, the items are spaced apart with @@ -205,7 +206,7 @@ impl Show for Packed { } /// A term list item. -#[elem(name = "item", title = "Term List Item")] +#[elem(name = "item", title = "Term List Item", Locatable)] pub struct TermItem { /// The term described by the list item. #[required] diff --git a/crates/typst-library/src/text/deco.rs b/crates/typst-library/src/text/deco.rs index 485d0edcf..2f6fd0324 100644 --- a/crates/typst-library/src/text/deco.rs +++ b/crates/typst-library/src/text/deco.rs @@ -3,6 +3,7 @@ use smallvec::smallvec; use crate::diag::SourceResult; use crate::engine::Engine; use crate::foundations::{elem, Content, Packed, Show, Smart, StyleChain}; +use crate::introspection::Locatable; use crate::layout::{Abs, Corners, Length, Rel, Sides}; use crate::text::{BottomEdge, BottomEdgeMetric, TextElem, TopEdge, TopEdgeMetric}; use crate::visualize::{Color, FixedStroke, Paint, Stroke}; @@ -13,7 +14,7 @@ use crate::visualize::{Color, FixedStroke, Paint, Stroke}; /// ```example /// This is #underline[important]. /// ``` -#[elem(Show)] +#[elem(Locatable, Show)] pub struct UnderlineElem { /// How to [stroke] the line. /// @@ -99,7 +100,7 @@ impl Show for Packed { /// ```example /// #overline[A line over text.] /// ``` -#[elem(Show)] +#[elem(Locatable, Show)] pub struct OverlineElem { /// How to [stroke] the line. /// @@ -191,7 +192,7 @@ impl Show for Packed { /// ```example /// This is #strike[not] relevant. /// ``` -#[elem(title = "Strikethrough", Show)] +#[elem(title = "Strikethrough", Locatable, Show)] pub struct StrikeElem { /// How to [stroke] the line. /// @@ -268,7 +269,7 @@ impl Show for Packed { /// ```example /// This is #highlight[important]. /// ``` -#[elem(Show)] +#[elem(Locatable, Show)] pub struct HighlightElem { /// The color to highlight the text with. /// diff --git a/crates/typst-library/src/text/raw.rs b/crates/typst-library/src/text/raw.rs index d5c07424d..45e759023 100644 --- a/crates/typst-library/src/text/raw.rs +++ b/crates/typst-library/src/text/raw.rs @@ -18,6 +18,7 @@ use crate::foundations::{ PlainText, Show, ShowSet, Smart, StyleChain, Styles, Synthesize, TargetElem, }; use crate::html::{tag, HtmlElem}; +use crate::introspection::Locatable; use crate::layout::{BlockBody, BlockElem, Em, HAlignment}; use crate::loading::{DataSource, Load}; use crate::model::{Figurable, ParElem}; @@ -76,6 +77,7 @@ use crate::World; scope, title = "Raw Text / Code", Synthesize, + Locatable, Show, ShowSet, LocalName, @@ -619,7 +621,7 @@ impl RawTheme { /// It allows you to access various properties of the line, such as the line /// number, the raw non-highlighted text, the highlighted text, and whether it /// is the first or last line of the raw block. -#[elem(name = "line", title = "Raw Text / Code Line", Show, PlainText)] +#[elem(name = "line", title = "Raw Text / Code Line", Locatable, Show, PlainText)] pub struct RawLine { /// The line number of the raw line inside of the raw block, starts at 1. #[required] diff --git a/crates/typst-library/src/text/shift.rs b/crates/typst-library/src/text/shift.rs index dbf1be8a1..fb40cb818 100644 --- a/crates/typst-library/src/text/shift.rs +++ b/crates/typst-library/src/text/shift.rs @@ -3,6 +3,7 @@ use ecow::EcoString; use crate::diag::SourceResult; use crate::engine::Engine; use crate::foundations::{elem, Content, Packed, SequenceElem, Show, StyleChain}; +use crate::introspection::Locatable; use crate::layout::{Em, Length}; use crate::text::{variant, SpaceElem, TextElem, TextSize}; use crate::World; @@ -15,7 +16,7 @@ use crate::World; /// ```example /// Revenue#sub[yearly] /// ``` -#[elem(title = "Subscript", Show)] +#[elem(title = "Subscript", Locatable, Show)] pub struct SubElem { /// Whether to prefer the dedicated subscript characters of the font. /// @@ -74,7 +75,7 @@ impl Show for Packed { /// ```example /// 1#super[st] try! /// ``` -#[elem(title = "Superscript", Show)] +#[elem(title = "Superscript", Locatable, Show)] pub struct SuperElem { /// Whether to prefer the dedicated superscript characters of the font. /// diff --git a/crates/typst-library/src/visualize/image/mod.rs b/crates/typst-library/src/visualize/image/mod.rs index 258eb96f3..2e227def1 100644 --- a/crates/typst-library/src/visualize/image/mod.rs +++ b/crates/typst-library/src/visualize/image/mod.rs @@ -21,6 +21,7 @@ use crate::foundations::{ cast, elem, func, scope, Bytes, Cast, Content, Derived, NativeElement, Packed, Show, Smart, StyleChain, }; +use crate::introspection::Locatable; use crate::layout::{BlockElem, Length, Rel, Sizing}; use crate::loading::{DataSource, Load, Readable}; use crate::model::Figurable; @@ -44,7 +45,7 @@ use crate::text::LocalName; /// ], /// ) /// ``` -#[elem(scope, Show, LocalName, Figurable)] +#[elem(scope, Locatable, Show, LocalName, Figurable)] pub struct ImageElem { /// A [path]($syntax/#paths) to an image file or raw bytes making up an /// image in one of the supported [formats]($image.format).