RE: ACTION 614-12: Smart Quotes

Before responding further, let me copy Liam's proposal from the original member list to the current public list in case others are listening in.

Mike is responding to this proposal, which was prepared by Liam.

Jonathan

This is revised to take Mike Kay's comments into account and to be more formal.

I've omitted justification and use cases, but will note this syntax also
means we don't have to try and incorporate literal JSON syntax into the
XQuery grammar directly, because we can meet all of our use cases/needs
using foreign blocks and a parse-json() function. An implementation can
obviously optimize a call to parse-json() with a string literal.

I didn't use Mike Kay's suggested name "computed string constructor"
because currently those all use curly braces in exactly the way we need
to avoid in order to support JSON :-) so I went for Extended string
constructor and (as Mike suggested) Literal string constructor.

It might go in or after 3.16.5 Constructor Functions, e.g.


3.16.5.1 Extended String Constructors


An <term>Extended String Constructor</term> is an alternate syntax for
string construction in which the result of evaluating embedded
expressions can be included. The syntax is suitable for containing
fragments of JavaScript, JSON, CSS, SPARQL or other languages that might
use curly braces, double and single quotes, or be difficult or tedious
to construct directly in XQuery using other mechanisms.

[201] ExtStringConstructor ::= "~~$" . ExtStringText "$~~"
[203] ExtStringText := ((Char* - "${") | "${" Expr "}")*

An extended string constructor allows embedded expressions, marked as
${ Expr }. Conceptually, they are processed by the following steps:

1. Each consecutive sequence of literal characters in the attribute
content is processed as a string literal containing those characters.

Note: & is not recognized as special; $ is only recognized when
immediately followed by "{".

Line endings are processed as elsewhere in XQuery; no other processing
is performed on literal characters.

2. Each enclosed expression within ${ up to the matching } is evaluated
as for enclosed expressions in attribute constructors:

<!--* copied from 3.9.1.1 *-->
a. Atomization is applied to the value of the enclosed expression,
converting it to a sequence of atomic values.

b. If the result of atomization is an empty sequence, the result is the
zero-length string. Otherwise, each atomic value in the atomized
sequence is cast into a string.

c. The individual strings resulting from the previous step are merged
into a single string by concatenating them with a single space character
between each pair.
<!--* end of copied text *-->

3. Adjacent strings resulting from the above steps are concatenated with
no intervening blanks.


Note: a foreign block could be included within such an expression, and
its end delimiter would not end the outer foreign block.

A <term>literal string constructor</term> is similar to the extended
string constructor but does not support enclosed expressions: it can
contain any sequence of characters allowed in an XQuery document, and no
special characters are recognized inside it. The result has type
xs:string.

[202] LiteralStringConstructor := "~~!" (Char* - "!~~") "!~~"

Line endings within a literal string constructor are normalized as elsewhere in
XQuery.


Examples:

The following example from json.org adds a session ID
member that is generated dynamically:

    declare variable $json := ~~$ {"menu": {
      "id": "file",
      "value": "File",
      "popup": {
        "menuitem": [
          {"value": "New", "onclick": "CreateNewDoc()"},
          {"value": "Open", "onclick": "OpenDoc()"},
          {"value": "Close", "onclick": "CloseDoc()"},
          {"callback": null },
          {"session-id": ${ get-session-id() } }
        ]
      }
    }} $~~ ;

The foreign text blocks can be used anywhere a string
or string-valued expression can be used:

    string-join(
        for $i in ("hello", ~!world!~~) return $i,
        " "
    )

The construct can be nested:

    string-length(~~$There were ${ count($e/attendee) }
     daleks in attendance at the party, and
     ${ concat($e/attendee[1]/name, ~~$-dalek$~~) } won
     the Exterminate-My-Leader competition.$~~)

[end of proposal]

Liam


Received on Thursday, 10 September 2015 16:13:28 UTC