printer.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* eslint-disable new-cap */
  2. import Visitor from './visitor';
  3. export function print(ast) {
  4. return new PrintVisitor().accept(ast);
  5. }
  6. export function PrintVisitor() {
  7. this.padding = 0;
  8. }
  9. PrintVisitor.prototype = new Visitor();
  10. PrintVisitor.prototype.pad = function(string) {
  11. let out = '';
  12. for (let i = 0, l = this.padding; i < l; i++) {
  13. out += ' ';
  14. }
  15. out += string + '\n';
  16. return out;
  17. };
  18. PrintVisitor.prototype.Program = function(program) {
  19. let out = '',
  20. body = program.body,
  21. i,
  22. l;
  23. if (program.blockParams) {
  24. let blockParams = 'BLOCK PARAMS: [';
  25. for (i = 0, l = program.blockParams.length; i < l; i++) {
  26. blockParams += ' ' + program.blockParams[i];
  27. }
  28. blockParams += ' ]';
  29. out += this.pad(blockParams);
  30. }
  31. for (i = 0, l = body.length; i < l; i++) {
  32. out += this.accept(body[i]);
  33. }
  34. this.padding--;
  35. return out;
  36. };
  37. PrintVisitor.prototype.MustacheStatement = function(mustache) {
  38. return this.pad('{{ ' + this.SubExpression(mustache) + ' }}');
  39. };
  40. PrintVisitor.prototype.Decorator = function(mustache) {
  41. return this.pad('{{ DIRECTIVE ' + this.SubExpression(mustache) + ' }}');
  42. };
  43. PrintVisitor.prototype.BlockStatement = PrintVisitor.prototype.DecoratorBlock = function(
  44. block
  45. ) {
  46. let out = '';
  47. out += this.pad(
  48. (block.type === 'DecoratorBlock' ? 'DIRECTIVE ' : '') + 'BLOCK:'
  49. );
  50. this.padding++;
  51. out += this.pad(this.SubExpression(block));
  52. if (block.program) {
  53. out += this.pad('PROGRAM:');
  54. this.padding++;
  55. out += this.accept(block.program);
  56. this.padding--;
  57. }
  58. if (block.inverse) {
  59. if (block.program) {
  60. this.padding++;
  61. }
  62. out += this.pad('{{^}}');
  63. this.padding++;
  64. out += this.accept(block.inverse);
  65. this.padding--;
  66. if (block.program) {
  67. this.padding--;
  68. }
  69. }
  70. this.padding--;
  71. return out;
  72. };
  73. PrintVisitor.prototype.PartialStatement = function(partial) {
  74. let content = 'PARTIAL:' + partial.name.original;
  75. if (partial.params[0]) {
  76. content += ' ' + this.accept(partial.params[0]);
  77. }
  78. if (partial.hash) {
  79. content += ' ' + this.accept(partial.hash);
  80. }
  81. return this.pad('{{> ' + content + ' }}');
  82. };
  83. PrintVisitor.prototype.PartialBlockStatement = function(partial) {
  84. let content = 'PARTIAL BLOCK:' + partial.name.original;
  85. if (partial.params[0]) {
  86. content += ' ' + this.accept(partial.params[0]);
  87. }
  88. if (partial.hash) {
  89. content += ' ' + this.accept(partial.hash);
  90. }
  91. content += ' ' + this.pad('PROGRAM:');
  92. this.padding++;
  93. content += this.accept(partial.program);
  94. this.padding--;
  95. return this.pad('{{> ' + content + ' }}');
  96. };
  97. PrintVisitor.prototype.ContentStatement = function(content) {
  98. return this.pad("CONTENT[ '" + content.value + "' ]");
  99. };
  100. PrintVisitor.prototype.CommentStatement = function(comment) {
  101. return this.pad("{{! '" + comment.value + "' }}");
  102. };
  103. PrintVisitor.prototype.SubExpression = function(sexpr) {
  104. let params = sexpr.params,
  105. paramStrings = [],
  106. hash;
  107. for (let i = 0, l = params.length; i < l; i++) {
  108. paramStrings.push(this.accept(params[i]));
  109. }
  110. params = '[' + paramStrings.join(', ') + ']';
  111. hash = sexpr.hash ? ' ' + this.accept(sexpr.hash) : '';
  112. return this.accept(sexpr.path) + ' ' + params + hash;
  113. };
  114. PrintVisitor.prototype.PathExpression = function(id) {
  115. let path = id.parts.join('/');
  116. return (id.data ? '@' : '') + 'PATH:' + path;
  117. };
  118. PrintVisitor.prototype.StringLiteral = function(string) {
  119. return '"' + string.value + '"';
  120. };
  121. PrintVisitor.prototype.NumberLiteral = function(number) {
  122. return 'NUMBER{' + number.value + '}';
  123. };
  124. PrintVisitor.prototype.BooleanLiteral = function(bool) {
  125. return 'BOOLEAN{' + bool.value + '}';
  126. };
  127. PrintVisitor.prototype.UndefinedLiteral = function() {
  128. return 'UNDEFINED';
  129. };
  130. PrintVisitor.prototype.NullLiteral = function() {
  131. return 'NULL';
  132. };
  133. PrintVisitor.prototype.Hash = function(hash) {
  134. let pairs = hash.pairs,
  135. joinedPairs = [];
  136. for (let i = 0, l = pairs.length; i < l; i++) {
  137. joinedPairs.push(this.accept(pairs[i]));
  138. }
  139. return 'HASH{' + joinedPairs.join(', ') + '}';
  140. };
  141. PrintVisitor.prototype.HashPair = function(pair) {
  142. return pair.key + '=' + this.accept(pair.value);
  143. };
  144. /* eslint-enable new-cap */