@@ -427,6 +427,7 @@ An _expression_ MUST begin with U+007B LEFT CURLY BRACKET `{`
427427and end with U+007D RIGHT CURLY BRACKET ` } ` .
428428An _ expression_ MUST NOT be empty.
429429An _ expression_ cannot contain another _ expression_ .
430+ An _ expression_ MAY contain one more _ attributes_ .
430431
431432A ** _ <dfn >literal-expression</dfn >_ ** contains a _ literal_ ,
432433optionally followed by an _ annotation_ .
@@ -438,9 +439,9 @@ An **_<dfn>annotation-expression</dfn>_** contains an _annotation_ without an _o
438439
439440``` abnf
440441expression = literal-expression / variable-expression / annotation-expression
441- literal-expression = "{" [s] literal [s annotation] [s] "}"
442- variable-expression = "{" [s] variable [s annotation] [s] "}"
443- annotation-expression = "{" [s] annotation [s] "}"
442+ literal-expression = "{" [s] literal [s annotation] *(s attribute) [s] "}"
443+ variable-expression = "{" [s] variable [s annotation] *(s attribute) [s] "}"
444+ annotation-expression = "{" [s] annotation *(s attribute) [s] "}"
444445```
445446
446447There are several types of _ expression_ that can appear in a _ message_ .
@@ -638,14 +639,14 @@ unrecognized _reserved-annotations_ or _private-use-annotations_ have no meaning
638639
639640```abnf
640641reserved-annotation = reserved-annotation-start reserved-body
641- reserved-annotation-start = "!" / "@" / "%" / "*" / "+"
642- / "<" / ">" / "?" / "~"
642+ reserved-annotation-start = "!" / "%" / "*" / "+" / "<" / ">" / "?" / "~"
643643
644644reserved-body = *([s] 1*(reserved-char / reserved-escape / quoted))
645645reserved-char = %x00-08 ; omit HTAB and LF
646646 / %x0B-0C ; omit CR
647647 / %x0E-19 ; omit SP
648- / %x21-5B ; omit \
648+ / %x21-3F ; omit @
649+ / %x41-5B ; omit \
649650 / %x5D-7A ; omit { | }
650651 / %x7E-D7FF ; omit surrogates
651652 / %xE000-10FFFF
@@ -656,7 +657,12 @@ reserved-char = %x00-08 ; omit HTAB and LF
656657** _ <dfn >Markup</dfn >_ ** _ placeholders_ are _ pattern_ parts
657658that can be used to represent non-language parts of a _ message_ ,
658659such as inline elements or styling that should apply to a span of parts.
659- Markup comes in three forms:
660+
661+ _ Markup_ MUST begin with U+007B LEFT CURLY BRACKET ` { `
662+ and end with U+007D RIGHT CURLY BRACKET ` } ` .
663+ _ Markup_ MAY contain one more _ attributes_ .
664+
665+ _ Markup_ comes in three forms:
660666
661667** _ <dfn >Markup-open</dfn >_ ** starts with U+0023 NUMBER SIGN ` # ` and
662668represents an opening element within the _ message_ ,
@@ -673,8 +679,8 @@ is a _pattern_ part ending a span.
673679Unlike the other forms, it does not include _ options_ .
674680
675681``` abnf
676- markup = "{" [s] markup-open [s] ["/"] "}"
677- / "{" [s] markup-close [s] "}"
682+ markup = "{" [s] markup-open *(s attribute) [s] ["/"] "}"
683+ / "{" [s] markup-close *(s attribute) [s] "}"
678684markup-open = "#" identifier *(s option)
679685markup-close = "/" identifier
680686```
@@ -691,6 +697,42 @@ _Markup_ _placeholders_ can appear in any order without making the _message_ inv
691697However, specifications or implementations defining _markup_ might impose requirements
692698on the pairing, ordering, or contents of _markup_ during _formatting_.
693699
700+ ## Attributes
701+
702+ **_Attributes_ are reserved for standardization by future versions of this specification.**
703+ Examples in this section are meant to be illustrative and
704+ might not match future requirements or usage.
705+
706+ An **_<dfn>attribute</dfn>_** is an _identifier_ with an optional value
707+ that appears in an _expression_ or in _markup_.
708+
709+ _Attributes_ are prefixed by a U+0040 COMMERCIAL AT `@` sign,
710+ followed by an _identifier_.
711+ An _attribute_ MAY have a _value_ which is separated from the _identifier_
712+ by an U+003D EQUALS SIGN `=` along with optional whitespace.
713+ The _value_ of an _attribute_ can be either a _literal_ or a _variable_.
714+
715+ Multiple _attributes_ are permitted in an _expression_ or _markup_.
716+ Each _attribute_ is separated by whitespace.
717+
718+ ```abnf
719+ attribute = "@" identifier [[s] "=" [s] (literal / variable)]
720+ ```
721+
722+ > Examples of _ expressions_ and _ markup_ with _ attributes_ :
723+ >
724+ > A _ message_ including a _ literal_ that should not be translated:
725+ >
726+ > ```
727+ > In French, "{|bonjour| @translate=no}" is a greeting
728+ > ```
729+ >
730+ > A _message_ with _markup_ that should not be copied:
731+ >
732+ > ```
733+ > Have a {+span @can-copy}great and wonderful{-span @can-copy} birthday!
734+ > ```
735+
694736## Other Syntax Elements
695737
696738This section defines common elements used to construct _messages_.
0 commit comments