September 15, 2016

Handlebars Language Specification

1Scope#

This document is a work in progress draft of the Handlebars templating language specification.

2Lexical Grammar#

2.1Comments#

Syntax

Comment::{{!SourceCharactersuntil }} {{!--SourceCharactersuntil --}}

2.2Literals#

2.2.1Null Literals#

Syntax

NullLiteral::null

2.2.2Undefined Literals#

Syntax

UndefinedLiteral::undefined

2.2.3Boolean Literals#

Syntax

BooleanLiteral::true false

2.2.4String Literals#

Syntax

StringLiteral::'SingleQuotedStringCharactersopt' "DoubleQuotedStringCharactersopt" SingleQuotedStringCharacters::SingleQuotedStringCharacterSingleQuotedStringCharactersopt SingleQuotedStringCharacter::SourceCharacterbut not one of ' or \ \' DoubleQuotedStringCharacters::DoubleQuotedStringCharacterDoubleQuotedStringCharactersopt DoubleQuotedStringCharacter::SourceCharacterbut not one of " or \ \"

2.2.5Numeric Literals#

Syntax

NumericLiteral::-optDecimalDigits -optDecimalDigits.DecimalDigits DecimalDigits::DecimalDigitsDecimalDigit DecimalDigit DecimalDigit::one of0123456789

3Syntactic Grammar#

Root:Program Program:StatementList [empty] StatementList:StatementListStatement Statement Statement:Mustache Block RawBlock Partial PartialBlock Content Comment Content:TODO RawBlock:RawBlockStartRawContentRawBlockEnd RawBlockStart:{{{{HelperNameParamListoptHashPairListopt}}}} RawContent:TODO RawBlockEnd:{{{{/HelperName}}}} Block:BlockStartProgramInverseChainoptBlockEnd InvertedBlockStartProgramInverseoptBlockEnd BlockStart:{{~opt#HelperNameParamListoptHashPairListoptBlockParamsopt~opt}} InvertedBlockStart:{{~opt^HelperNameParamListoptHashPairListoptBlockParamsopt~opt}} BlockEnd:{{~opt/HelperName~opt}} InverseChain:InverseChainStartProgramInverseChainopt Inverse InverseChainStart:{{~optelseHelperNameParamListoptHashPairListoptBlockParamsopt~opt}} Inverse:InverseSeparatorProgram InverseSeparator:{{~optelse~opt}} {{~opt^~opt}} Mustache:{{~optHelperNameParamListoptHashPairListopt~opt}} {{~opt{HelperNameParamListoptHashPairListopt}~opt}} {{~opt&HelperNameParamListoptHashPairListopt~opt}} Partial:{{~opt>PartialNameParamListoptHashPairListopt~opt}} PartialBlock:PartialBlockStartProgramBlockEnd PartialBlockStart:{{~opt#>PartialNameParamListoptHashPairListopt~opt}} ParamList:ParamListParam Param Param:HelperName Subexpression Subexpression:(HelperNameParamListoptHashPairListopt) HashPairList:HashPairListHashPair HashPair HashPair:Identifier=Param BlockParams:as|BlockParamList| BlockParamList:BlockParamListIdentifier Identifier Identifier:TODO HelperName:PathExpression DataExpression StringLiteral NumericLiteral BooleanLiteral NullLiteral UndefinedLiteral PartialName:HelperName Subexpression DataExpression:@PathSegments PathExpression:PathSegments PathSegments:PathSegmentsPathSeparatorIdentifier Identifier PathSeparator:/ . TODO:Placeholder for missing productions

4Handlebars Specification Types#

4.1The Host Specification Type#

namespace interface Host {
  interface Meta {}

  interface DynamicScope {
    child(): DynamicScope;
  }
}

4.2The HostValue Specification Type#

The HostValue type represents any value representable in the host environment

4.3The Destroyable Specification Type#

interface Destroyable {
  destroy(): void;
}

4.4The Reference Specification Type#

interface Reference {
  value(): HostValue;
  get(name: string): Reference;
}

4.5The Appendable Specification Type#

interface Appendable {
  type Host;
  type State;

  create(args: Args, dynamicScope: Self::Host::DynamicScope): Self::State;
  self(state: Self::State): Reference;
  invoke(appender: Appender);
  getDestructor(state: Self::State): Destroyable;
}

4.6The Appender Specification Type#

interface Appender {
  append(appendable: Appendable): void;
}

5Statements#

5.1StatementList#

5.1.1Runtime Semantics: Evaluation#

StatementList:StatementListStatement
  1. let sl = Eval( StatementList )
  2. let s = Eval( Statement )
  3. return Join(s, sl)
StatementList:[empty]
  1. return Ok([])

5.2Content#

5.2.1Static Semantics: Value#

Content::TODO

5.2.2Runtime Semantics: Evaluation#

Content::TODO
  1. let ref = new Reference( Value(Content) )
  2. let appender = context.realm.appender
  3. let appendable = TODO
  4. appender.append( appendable )

6Handlebars Language: Templates and Components#

6.1Templates#

Syntax

Program:StatementListopt

6.2Evalution Records#

interface EvaluationRecord<Host> {
  realm: Realm;
  scope: Scope;
  code: Code;
  meta: Host::Meta;
}

6.3Realms#

interface Realm<Host> {
  intrinsics: Host::Instrinsics;
  globals: Reference;
  meta: Host::RealmMeta;
  appender: Host::Appender;
}

6.4Scopes#

interface Scope {
  parent: Option<Scope>;
  createBinding(name: string): void;
  initializeBinding(name: string, ref: Reference): void;
  hasBinding(name: string): boolean;
  getBindingReference(name: string): Reference;
  bindSelf(ref: Reference): void;
  getSelf(): Reference;
}

6.5TemplateEvaluation( template: Program, root: Reference, realm: Realm )#

  1. let context = new CodeExecutionContext()
  2. context.realm = realm
  3. context.template = template
  4. context.scope = new Scope( root )