const pres = stx`<presence type="${type}" xmlns="jabber:client"><show>${show}</show></presence>`
connection.send(pres);
const msg = stx`<message
from='sender@example.org'
id='hgn27af1'
to='recipient@example.org'
type='chat'>
<body>Hello world</body>
</message>`;
connection.send(msg);
Templates may be indented freely. The whitespace written between their tags
is formatting and is removed. However, whitespace which arrives through a `${}`
value (and is not itself inside a template) is considered content and kept.
So the rule to write by is that whitespace you want on the wire goes inside
the `${}`.
stx`<div xmlns="${XHTML}">${[link1, '\n', link2]}</div>` // kept
stx`<div xmlns="${XHTML}">${link1}
${link2}</div>` // removed
Which way the template's own indentation around a `${}` goes is decided by
what the value puts against it, not by how the value was written. Indentation
against text is part of that text and is kept; indentation against an element
separates elements and is formatting, so it is removed. A string and markup
which begins and ends in text therefore lay out alike:
stx`<c>
${'hello'}
</c>` // <c> holds a line break, "hello", a line break
stx`<c>
${unsafeXML('hello')}
</c>` // the same
stx`<c>
${unsafeXML('<p>hello</p>')}
</c>` // <c> holds only the <p>
Each end is read on its own, so markup which begins in text and ends in an
element keeps the indentation before it and loses the indentation after it.
Whitespace inside the value is its own either way and is never touched.
Two things are exempt, because their whitespace is read rather than laid
out: an XHTML-IM `<body>`, the one in the XHTML namespace, where a run of
whitespace between two inline elements separates words, and any subtree
marked `xml:space="preserve"`. The latter is also how to keep whitespace in
a string passed to {@link Stanza.toElement}, where there is no `${}` to put
it in. Either may opt out again with `xml:space="default"`.
A value interpolated at document level, where no element encloses it, is
the exception to all of the above. It is the stanza rather than content
within one, so it is considered markup like a template's and its whitespace
is stripped the same way:
const xhtml = `<title type="xhtml"><div xmlns="${XHTML}">
<a href="${a}">@bob</a>\n<a href="${b}">link</a>
</div></title>`;
stx`<message xmlns="jabber:client">${unsafeXML(xhtml)}</message>`
// the line break between the two <a> elements is kept
stx`${unsafeXML(`<message xmlns="jabber:client">${xhtml}</message>`)}`
// it is stripped, along with the template's own indentation
The two are told apart by where the whitespace came from, and at document
level that is no longer knowable. `xml:space="preserve"` is the only handle
there, so mark the elements whose whitespace matters before passing the markup in.
Whitespace between XHTML elements is fragile in general, since it collapses
to a single space when rendered and this library is not the only thing
which may drop it. The business rules of XEP-0071 recommend writing a line
break as `<br/>` and whitespace which carries meaning as the equivalent
number of no-break spaces, which survives regardless.
Tagged template literal function which generates Stanza objects