diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 36f4957fc2..e5d99538b1 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -6,6 +6,7 @@ - [Lexical structure](lexical-structure.md) - [Input format](input-format.md) + - [Frontmatter](frontmatter.md) - [Keywords](keywords.md) - [Identifiers](identifiers.md) - [Comments](comments.md) diff --git a/src/frontmatter.md b/src/frontmatter.md new file mode 100644 index 0000000000..388f9232f5 --- /dev/null +++ b/src/frontmatter.md @@ -0,0 +1,58 @@ +r[frontmatter] +# Frontmatter + +r[frontmatter.syntax] +```grammar,lexer +@root FRONTMATTER -> + FRONTMATTER_FENCE HORIZONTAL_WHITESPACE* INFOSTRING? HORIZONTAL_WHITESPACE* LF + (FRONTMATTER_LINE LF )* + FRONTMATTER_FENCE[^matched-fence] HORIZONTAL_WHITESPACE* LF + +FRONTMATTER_FENCE -> `-`{3..255} + +INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )* + +FRONTMATTER_LINE -> (~INVALID_FRONTMATTER_LINE_START (~INVALID_FRONTMATTER_LINE_CONTINUE)*)? + +INVALID_FRONTMATTER_LINE_START -> (FRONTMATTER_FENCE[^escaped-fence] | CR | LF) + +INVALID_FRONTMATTER_LINE_CONTINUE -> CR | LF + +HORIZONTAL_WHITESPACE -> + U+0009 // horizontal tab, `'\t'` + | U+0020 // space, `' '` +``` + +[^matched-fence]: The closing fence must have the same number of `-` as the opening fence +[^escaped-fence]: A `FRONTMATTER_FENCE` at the beginning of a `FRONTMATTER_LINE` is only invalid if it has the same or more `-` as the `FRONTMATTER_FENCE` + +r[frontmatter.intro] +Frontmatter is an optional section for content intended for external tools without requiring these tools to have full knowledge of the Rust grammar. + +```rust +#!/usr/bin/env cargo +--- +[dependencies] +fastrand = "2" +--- + +fn main() { + let num = fastrand::i32(..); + println!("{num}"); +} +``` + +r[frontmatter.document] +Frontmatter may only be preceded by a [shebang] and [whitespace]. + +r[frontmatter.fence] +The delimiters are referred to as a *fence*. The opening and closing fences must be at the start of a line. They must be a matching pair of hyphens (`-`), from 3 to 255. A fence may be followed by horizontal whitespace. + +r[frontmatter.infostring] +Following the opening fence may be an infostring for identifying the intention of the contained content. An infostring may be followed by horizontal whitespace. + +r[frontmatter.body] +The body of the frontmatter may contain any content except for a line starting with as many or more hyphens (`-`) than in the fences or carriage returns. + +[shebang]: input-format.md#shebang-removal +[whitespace]: whitespace.md diff --git a/src/input-format.md b/src/input-format.md index 2432da0339..98bc99d929 100644 --- a/src/input-format.md +++ b/src/input-format.md @@ -54,6 +54,11 @@ fn main() { r[input.shebang.inner-attribute] As an exception, if the `#!` characters are followed (ignoring intervening [comments] or [whitespace]) by a `[` token, nothing is removed. This prevents an [inner attribute] at the start of a source file being removed. +r[input.frontmatter] +## Frontmatter removal + +After some [whitespace], [frontmatter] may next appear in the input. + r[input.tokenization] ## Tokenization @@ -64,7 +69,7 @@ The resulting sequence of characters is then converted into tokens as described > > - Byte order mark removal. > - CRLF normalization. -> - Shebang removal when invoked in an item context (as opposed to expression or statement contexts). +> - Shebang and frontmatter removal when invoked in an item context (as opposed to expression or statement contexts). > > The [`include_str!`] and [`include_bytes!`] macros do not apply these transformations. @@ -73,4 +78,5 @@ The resulting sequence of characters is then converted into tokens as described [comments]: comments.md [Crates and source files]: crates-and-source-files.md [_shebang_]: https://en.wikipedia.org/wiki/Shebang_(Unix) +[frontmatter]: frontmatter.md [whitespace]: whitespace.md diff --git a/src/items/modules.md b/src/items/modules.md index 3cc015025b..2164051f84 100644 --- a/src/items/modules.md +++ b/src/items/modules.md @@ -123,7 +123,7 @@ r[items.mod.attributes] ## Attributes on modules r[items.mod.attributes.intro] -Modules, like all items, accept outer attributes. They also accept inner attributes: either after `{` for a module with a body, or at the beginning of the source file, after the optional BOM and shebang. +Modules, like all items, accept outer attributes. They also accept inner attributes: either after `{` for a module with a body, or at the beginning of the source file, after the optional BOM, shebang, and frontmatter. r[items.mod.attributes.supported] The built-in attributes that have meaning on a module are [`cfg`], [`deprecated`], [`doc`], [the lint check attributes], [`path`], and [`no_implicit_prelude`]. Modules also accept macro attributes.