Skip to content

Conversation

@epage
Copy link
Contributor

@epage epage commented Aug 21, 2025

Tracking issue: rust-lang/rust#136889

- [Input format](input-format.md)
- [Keywords](keywords.md)
- [Identifiers](identifiers.md)
- [Frontmatter](frontmatter.md)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not stable yet: rust-lang/rust#136889

- [Input format](input-format.md)
- [Keywords](keywords.md)
- [Identifiers](identifiers.md)
- [Frontmatter](frontmatter.md)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this under "Lexical structure" because this shebang is there

Comment on lines 7 to 8
FRONTMATTER?
InnerAttribute*
Item*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used comments as my guide which were mostly SCREAMING_CASE. Unsure when things should be SCREAMING_CASE vs UpperCamelCase.

Comment on lines 7 to 8
FRONTMATTER?
InnerAttribute*
Item*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Despite shebang's not having being here, I assumed I should put FRONTMATTER here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason shebang isn't there is that shebangs are ignored at the start of any file, not just in the file which defines a crate.

If that's true for frontmatter too, input-format.md might be a better place to say how frontmatter.md fits in.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing.

input-format.md is specifically under the section for lexical analysis.

crates-and-source-files.md includes what looks like its the AST but its specifically scoped to the crate root. r[crate-items] talks generally about any rust source file.

So, like shebang, I'll leave this out but this feels like something that could be cleaned up.

Comment on lines 39 to 40
r[frontmatter.body]
The body of the frontmatter may contain any content except for a line starting with as many or more dashes (`-`) than in the fences.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This follows the RFC rather than rustc's current implementation, see rust-lang/rust#141367

# Crates and source files

r[crate.syntax]
```grammar,items
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: it took me a while before I found the appropriate documentation for this.

I quickly went to CONTRIBUTING.md but skipped over the link to the authoring page because it was at the end of the intro. I skimmed the sections until I found "Adding Documentation" which seemed to describe my situation but I found no link.

Eventually I found authoring.md and thankfully I read thoroughly enough to notice the "Grammar" section at the bottom. At that point, I was mostly able to interpret the results to figure out what I needed (e.g. the limitations of ~, what to search for to understand how to do footnotes).

As noted at https://github.com/rust-lang/reference/pull/1974/files#r2292171963, it doesn't really give a style guidance on casing.

Comment on lines 6 to 19
FRONTMATTER ->
FRONTMATTER_FENCE INFOSTRING? LF
(FRONTMATTER_LINE LF )*
FRONTMATTER_FENCE[^matched-fence] LF
FRONTMATTER_FENCE -> `---` `-`*
INFOSTRING -> XID_Start ( XID_Continue | `.` )*
FRONTMATTER_LINE -> (~INVALID_FRONTMATTER_LINE_START (~INVALID_FRONTMATTER_LINE_CONTINUE)*)?
INVALID_FRONTMATTER_LINE_START -> (FRONTMATTER_FENCE[^escaped-fence] | LF)
INVALID_FRONTMATTER_LINE_CONTINUE -> LF
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was unsure whether to create a new rule for non-newline whitespace and specify that in every location or not.

@ehuss ehuss added the S-waiting-on-stabilization Waiting for a stabilization PR to be merged in the main Rust repository label Aug 21, 2025
@epage epage force-pushed the frontmatter branch 2 times, most recently from 161b0fa to 61afc85 Compare August 22, 2025 13:54
Comment on lines 6 to 19
FRONTMATTER ->
FRONTMATTER_FENCE INFOSTRING? LF
(FRONTMATTER_LINE LF )*
FRONTMATTER_FENCE[^matched-fence] LF
FRONTMATTER_FENCE -> `---` `-`*
INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )*
FRONTMATTER_LINE -> (~INVALID_FRONTMATTER_LINE_START (~INVALID_FRONTMATTER_LINE_CONTINUE)*)?
INVALID_FRONTMATTER_LINE_START -> (FRONTMATTER_FENCE[^escaped-fence] | LF)
INVALID_FRONTMATTER_LINE_CONTINUE -> LF
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking more on this, I feel like I should be explicit where frontmatter whitespace is allowed.

I assume I should then pull out a whitespace grammar rule to build on that.

Comment on lines 6 to 19
FRONTMATTER ->
FRONTMATTER_FENCE INFOSTRING? LF
(FRONTMATTER_LINE LF )*
FRONTMATTER_FENCE[^matched-fence] LF
FRONTMATTER_FENCE -> `---` `-`*
INFOSTRING -> (XID_Start | `_`) ( XID_Continue | `-` | `.` )*
FRONTMATTER_LINE -> (~INVALID_FRONTMATTER_LINE_START (~INVALID_FRONTMATTER_LINE_CONTINUE)*)?
INVALID_FRONTMATTER_LINE_START -> (FRONTMATTER_FENCE[^escaped-fence] | LF)
INVALID_FRONTMATTER_LINE_CONTINUE -> LF
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something that i don't make explicit is CR. In most places that can be chalked up to whitespace except for INVALID_FRONTMATTER_LINE_START and INVALID_FRONTMATTER_LINE_CONTINUE.

epage added a commit to epage/rust-reference that referenced this pull request Sep 4, 2025
I created productions for `END_OF_LINE`, `IGNORABLE_CODE_POINT`, and
`HORIZONTAL_WHITESPACE` as that is how the unicode standard is written
and in preparation for rust-lang#1974 which will make use of
`HORIZONTAL_WHITESPACE`
epage added a commit to epage/rust-reference that referenced this pull request Sep 5, 2025
I created productions for `END_OF_LINE`, `IGNORABLE_CODE_POINT`, and
`HORIZONTAL_WHITESPACE` as that is how the unicode standard is written
and in preparation for rust-lang#1974 which will make use of
`HORIZONTAL_WHITESPACE`
epage added a commit to epage/rust-reference that referenced this pull request Sep 8, 2025
This does not create any new productions, instead preferring comments.
rust-lang#1974 will involve pulling out the horizontal
whitespace into a separate production.

Comment wording (and casing) is modeled off of
https://www.unicode.org/reports/tr31/#R3a.
I left off a "unicode" prefix for ASCII items as they are likely common
enough in that context that specifying them as "unicode" could cause
more confusion.
traviscross pushed a commit to epage/rust-reference that referenced this pull request Sep 23, 2025
This does not create any new productions, instead preferring comments.
rust-lang#1974 will involve pulling out the horizontal
whitespace into a separate production.

Comment wording (and casing) is modeled off of
https://www.unicode.org/reports/tr31/#R3a.
I left off a "unicode" prefix for ASCII items as they are likely common
enough in that context that specifying them as "unicode" could cause
more confusion.
@traviscross traviscross added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label Oct 4, 2025
epage added 3 commits October 9, 2025 14:01
This reverts commit 60eb145.

This re-formats our Whitespace to be centered on Unicode's defintion.

This makes it easy to compare with the standard and helps with
Frontmatter.
Unlike regular Rust, Frontmatter cares about the type of Whitespace.
Even if we want to duplicate the definition, having them formatted
similarly makes them easy to compare.
I'm splitting out `HORIZONTAL_WHITESPACE` to make it easier to connect
the concept in frontmatter with `WHITESPACE`.

In doing this, I found it awkward to only pull out part when the
comments are there.
I either needed a redundant comment to start a section, re-arrange out
of order from Unicode, or split out all classes.
I did the latter.
Copy link
Contributor

@traviscross traviscross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. Before digging into the rest, let me ask some questions about changes here related to layout, organization, and style.

Comment on lines 7 to 32
U+0009 // Horizontal tab, `'\t'`
| U+000A // Line feed, `'\n'`
| U+000B // Vertical tab
| U+000C // Form feed
| U+000D // Carriage return, `'\r'`
| U+0020 // Space, `' '`
| U+0085 // Next line
| U+200E // Left-to-right mark
| U+200F // Right-to-left mark
| U+2028 // Line separator
| U+2029 // Paragraph separator
TAB -> U+0009 // Horizontal tab, `'\t'`
LF -> U+000A // Line feed, `'\n'`
CR -> U+000D // Carriage return, `'\r'`
END_OF_LINE
| IGNORABLE_CODE_POINT
| HORIZONTAL_WHITESPACE
END_OF_LINE ->
LF
| U+000B // vertical tabulation
| U+000C // form feed
| CR
| U+0085 // Unicode next line
| U+2028 // Unicode LINE SEPARATOR
| U+2029 // Unicode PARAGRAPH SEPARATOR
IGNORABLE_CODE_POINT ->
U+200E // Unicode LEFT-TO-RIGHT MARK
| U+200F // Unicode RIGHT-TO-LEFT MARK
HORIZONTAL_WHITESPACE ->
TAB
| U+0020 // space ' '
TAB -> U+0009 // horizontal tab ('\t')
LF -> U+000A // line feed ('\n')
CR -> U+000D // carriage return ('\r')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In these sort of grammar productions that are essentially lists, we generally find it more clear to not mix terminals and non-terminals even if that leads to some duplication. As applied here, that would suggest inlining LF and CR in END_OF_LINE and TAB in HORIZONTAL_WHITESPACE. Does that make sense, or are there non-obvious problems with that here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see it both ways.

Extra abstractions can make things less clear.

Lack of use of abstractions highlights a difference which can also be confusing or make searching more difficult.

Which gets me thinking, with how thin this abstraction is, should we even have a production for TAB, LF, or CR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fairly common in grammars to have separate for TAB, LF, and CR, even if duplicated. I'd suggest keeping these three but inlining the terminals into the other productions.

Comment on lines 16 to 18
| U+0085 // Unicode next line
| U+2028 // Unicode LINE SEPARATOR
| U+2029 // Unicode PARAGRAPH SEPARATOR
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my copy of the Unicode Character Database, I see:

0085;<control>;Cc;0;B;;;;;N;NEXT LINE (NEL);;;;
2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;;
2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;;

In a somewhat more pretty form:

That is, in the database, U+0085 has a null name and a name alias of "NEXT LINE|NEL", U+2028 has a name of "LINE SEPARATOR" and a null name alias, and U+2029 has a name of "PARAGRAPH SEPARATOR" and a null name alias.

Given that, is there a reason that we need to capitalize these differently, or could we perhaps align the capitalization with Reference norms without losing something important here?

I do see, in The Unicode Standard, Version 17.0.0, §5.8.1 "Definitions", Table 5-1 that all of "next line", "line separator", and "paragraph separator" are presented in lowercase, but that doesn't seem to explain why we might want to treat these differently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was to match how they are specified where it talks about the different categories of whitespace, see https://www.unicode.org/reports/tr31/#R3a-1

Copy link
Contributor

@traviscross traviscross Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me that the capitalization and other matters of presentation there are intended to be more normative than the capitalization in the Unicode Character Database (which is normatively part of the Unicode standard).

To my eyes, it looks like they made the editorial choice in tr31 to notate code point names as presented in the database, and then where the name is null, to present the primary code point alias in parentheses and in lowercase (and to elide secondary aliases). This presentation was, I'm guessing, intended to notate this difference between names and aliases.

Is there a reason that it's important to follow the presentation in tr31 exactly? If so, I'd expect that we'd want to follow the convention with the parentheses as well.

However, it's not clear to me that it's important, for our purposes, to make this distinction between code point names and code point aliases. If that's right, and there's not, then I'd prefer we render these according to our normal conventions for comments, i.e., in sentence case (especially as the authors of Unicode standards documents also seem to treat the capitalizations as malleable).

But, is that right, or is there an important reason we need to distinguish, for our purposes, code point names and aliases (where the name is null)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason that it's important to follow the presentation in tr31 exactly? If so, I'd expect that we'd want to follow the convention with the parentheses as well.

That is the document we are referring back to on this page.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, understood. How would you then apply that to the points and questions raised above?

Comment on lines 24 to 26
HORIZONTAL_WHITESPACE ->
TAB
| U+0020 // space ' '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the grammar productions above for frontmatter, it seems that only HORIZONTAL_WHITESPACE is used (and LF, of course). If we were willing to accept some duplication, i.e. by defining HORIZONTAL_WHITESPACE directly in terms of terminals (that also would appear under WHITESPACE), does that work for defining frontmatter without these other changes, or is there a reason these other changes to the layout, organization, and styling of the WHITESPACE grammar are important for defining frontmatter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think duplicating an entry like HORIZONTAL_WHITESPACE is anti-user.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think duplicating an entry like HORIZONTAL_WHITESPACE is anti-user.

Obviously we strive to be pro-user. However, I'm not clear how this stylistic choice would be anti-user. If you could please elaborate, I'd appreciate it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First off, I am not a DRY absolutist. Things having the appearance of duplication isn't a reason to de-duplicate but we should work towards understanding the underlying principles and requirements and de-duplicate those where it works well and reducing the burden of duplication where it doesn't work well (e.g. having two definitions next to each other). In this case, we are working off of an item (whitespace) that is defined in three categories that is then defined as literals that natural leads to a way to divide things up to not duplicate knowledge.

I see this is similar to but worse than #1974 (comment)

At least with TAB, the abstraction is thin (too thin as I suggested in that thread). Here, we'd be duplicating a lot of the definition. This puts a burden on the user to match up the entries to

  1. Understand that one is a superset of the other
  2. Understand what the role of the items mean

When seeing duplication like this, it is natural to expect there to a reason for it and that reason to be there are differences. For me, this makes me doubt myself and pore over something more, wasting my time and making me not confident that I understand what I'm working off of, and more annoyed in the process.

I suspect this will also be a honey trap for contributors who will see this and then submit PRs to do what I did.

@epage epage force-pushed the frontmatter branch 5 times, most recently from 3d69944 to d7203a4 Compare October 30, 2025 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: The marked PR is awaiting review from a maintainer S-waiting-on-stabilization Waiting for a stabilization PR to be merged in the main Rust repository

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants