Skip to content

Conversation

zombiezen
Copy link

This document summarizes #130 and #131 for future readers. I tried to minimize the use of jargon and included representative examples to introduce each concept.

After careful consideration, I included a short glossary to introduce some terms. The prose kept coming out clunky when I tried to define the terms in the middle of defining "standalone", so introducing them upfront seemed like a clearer flow. Rather than use the term "pair", I borrowed the term "element" from HTML since the concept is analogous.

Fixes #65

This document summarizes mustache#130 and mustache#131 for future readers.
I tried to minimize the use of jargon
and included representative examples to introduce each concept.

After careful consideration, I included a short glossary to introduce some terms.
The prose kept coming out clunky when I tried to define the terms in the middle of defining "standalone",
so introducing them upfront seemed like a clearer flow.
Rather than use the term "pair",
I borrowed the term "element" from HTML since the concept is analogous.

Fixes mustache#65
@zombiezen
Copy link
Author

PTAL @jgonggrijp

@jgonggrijp
Copy link
Member

What does "PTAL" mean?

@zombiezen
Copy link
Author

Sorry, "Please Take A Look."

Copy link
Member

@jgonggrijp jgonggrijp left a comment

Choose a reason for hiding this comment

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

I like what you're doing here.

I can tell that you're trying to stay concise and it's working. In some ways, the text is perhaps a bit too dense. Some redundancy and additional clarifications, illustrations and (ironically) whitespace wouldn't hurt. Regarding the latter point, I suggest splitting a few paragraphs by just adding blank lines.

There a few other things I'd like you to add:

  • A rationale. Why is whitespace handling in Mustache the way it is?
  • References to this document in the overviews of the partials and inheritance specs.
  • A reference to this document in the README.
  • A "further reading" heading at the end of this document with (at least) a reference to #130.
  • (Optional) some hints at how whitespace handling can be implemented correctly, since this is documentation intended for implementation developers.

I'm convinced that this will have added value. Keep up the good work!

## Terms

<dl>
<dt>element</dt>
Copy link
Member

Choose a reason for hiding this comment

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

I somewhat agree that "element" covers the meaning better than "tag pair", but I wish there was a less HTML-centric term that we could use instead. Some people feel that Mustache is prioritizing HTML over other target languages because of escaping and I would rather avoid reinforcing that perception if possible.

I have not come up with another idea yet but will keep trying. Please help!

<dt>element</dt>
<dd>A section, inverted section, parent, or block tag plus its content up to and including its associated end tag. For example, <code>{{$foo}}bar{{/foo}}</code> is a single block element.</dd>
<dt>argument block</dt>
<dd>A block element that is a direct child of a parent tag.</dd>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<dd>A block element that is a direct child of a parent tag.</dd>
<dd>A block element that is a direct child of a parent element.</dd>

(or whatever other term for "element " we come up with).

This could probably also use an example ({{$}}...{{/}}) to clarify what you mean by "block".

<dt>argument block</dt>
<dd>A block element that is a direct child of a parent tag.</dd>
<dt>parameter block</dt>
<dd>A block element that is not a direct child of a parent tag.</dd>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<dd>A block element that is not a direct child of a parent tag.</dd>
<dd>A block element that is not a direct child of a parent element.</dd>


A tag is considered **standalone** if the tag is the only text on the line except whitespace.
Interpolation tags are never considered standalone.
The leading whitespace, trailing whitespace, and line ending of a standalone tag are ignored.
Copy link
Member

Choose a reason for hiding this comment

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

"Ignored" could be further clarified. I would say that this whitespace is not part of the literal template content, but could be considered part of the tag delimiters instead.

Comment on lines +52 to +53
are considered standalone if the start tag has zero or more whitespace characters preceding it on its line
and its associated end tag has zero or more whitespace characters following it on its line.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
are considered standalone if the start tag has zero or more whitespace characters preceding it on its line
and its associated end tag has zero or more whitespace characters following it on its line.
are considered standalone if the start tag has nothing except for whitespace characters preceding it on its line
and its associated end tag has nothing but whitespace characters following it on its line.

I don't think it would hurt to include "clearance" in the glossary, but this works.

Copy link

Choose a reason for hiding this comment

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

what about this?...

{{#foo}}{{#bar}}{{! This line entirely dropped? }}
  text
{{/bar}}{{/foo}}{{! This line entirely dropped? }}

This strikes me as a case in which the 1st and 3rd lines could be ignored whether or not they have the comment tags on them.

And this?...

{{! comment }} {{=| |=}}

Copy link
Member

Choose a reason for hiding this comment

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

Yes that would make more sense, but this is historical baggage that we can no longer escape in the 1.x release series. The rules already work that way due to existing tests, this markdown text is only clarifying how it works.

Comment on lines +94 to +95
If a block tag is at the end of a line (ignoring any trailing whitespace)
and it is either part of an argument block or part of a standalone parameter block,
Copy link
Member

Choose a reason for hiding this comment

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

This wording is a bit confusing because it can be read as if you're only talking about nested blocks, i.e., blocks within blocks.

Comment on lines +98 to +99
Mustache implementations must ignore the occurrence of the block element's intrinsic indentation
at the beginning of each line of the block element's content.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe more explicit:

Suggested change
Mustache implementations must ignore the occurrence of the block element's intrinsic indentation
at the beginning of each line of the block element's content.
At compile time, Mustache implementations must remove the occurrence of the block element's intrinsic indentation
from the beginning of each line of the block element's content.

Comment on lines +101 to +107
When a standalone partial tag or standalone parent element is expanded,
the leading whitespace on the start tag's line is prepended to each line of the expanded template.
A similar behavior occurs for standalone parameter blocks.
If a standalone parameter block's start tag is at the end of a line (possibly with trailing whitespace),
then its intrinsic indentation is prepended to each line of the argument block that is overriding it.
Otherwise, the leading whitespace of the standalone parameter block's start tag
is prepended to each line of the argument block that is overriding it.
Copy link
Member

Choose a reason for hiding this comment

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

Two things:

  1. When no block is provided from the outside, a block's own contents are expanded in place. The intrinsic indentation (which was previously removed) or the leading indentation should still be added to each line in that case. With the current wording, this is a bit unclear because someone might interpret a defaulted block as not overridden.
  2. The indentation is added to each line of the template that will be expanded in place, before that template is rendered. That part is crucial, but is not yet explicit in this text.

@zombiezen
Copy link
Author

Thanks for the feedback. This is still on my radar to address, but I've been swamped these past couple weeks. I'll have something soon.

@cgay
Copy link

cgay commented Jul 18, 2025

This PR has been extremely helpful for me as I learn Mustache and implement it for another language. Thanks! I look forward to it being merged.

(And I'll just throw this out there too, while I'm making comments: Huge thanks for providing YAML/JSON tests. It only took about 30 minutes to implement a full test suite using them.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

clarify what is meant by standalone

3 participants