ember-material-icons
Version:
Google Material icons for your ember-cli app
110 lines (89 loc) • 2.9 kB
text/typescript
import { parse } from "handlebars";
import builders from "./builders";
import print from "./generation/print";
import traverse, { NodeVisitor } from "./traversal/traverse";
import { BaseNode } from "./types/nodes";
import Walker from "./traversal/walker";
import {
EventedTokenizer,
EntityParser,
HTML5NamedCharRefs as namedCharRefs
} from "simple-html-tokenizer";
import handlebarsNodeVisitors from "./parser/handlebars-node-visitors";
import tokenizerEventHandlers from "./parser/tokenizer-event-handlers";
import { Program } from "./types/nodes";
export const syntax = {
parse: preprocess,
builders,
print,
traverse,
Walker
};
export function preprocess(html: string | hbs.AST.Program, options?): Program {
let ast = (typeof html === 'object') ? html : parse(html);
let combined = new Parser(html, options).acceptNode(ast);
if (options && options.plugins && options.plugins.ast) {
for (let i = 0, l = options.plugins.ast.length; i < l; i++) {
let plugin = new options.plugins.ast[i](options);
plugin.syntax = syntax;
combined = plugin.transform(combined);
}
}
return combined;
}
const entityParser = new EntityParser(namedCharRefs);
export class Parser {
private elementStack = [];
private options: Object;
private source: string[];
public currentAttribute = null;
public currentNode = null;
public tokenizer = new EventedTokenizer(this, entityParser);
constructor(source, options: Object = {}) {
this.options = options;
if (typeof source === 'string') {
this.source = source.split(/(?:\r\n?|\n)/g);
}
}
acceptNode(node: hbs.AST.Program): Program;
acceptNode(node): Object {
return this[node.type](node);
}
currentElement(): Object {
return this.elementStack[this.elementStack.length - 1];
}
sourceForMustache(mustache): string {
let firstLine = mustache.loc.start.line - 1;
let lastLine = mustache.loc.end.line - 1;
let currentLine = firstLine - 1;
let firstColumn = mustache.loc.start.column + 2;
let lastColumn = mustache.loc.end.column - 2;
let string = [];
let line;
if (!this.source) {
return '{{' + mustache.path.id.original + '}}';
}
while (currentLine < lastLine) {
currentLine++;
line = this.source[currentLine];
if (currentLine === firstLine) {
if (firstLine === lastLine) {
string.push(line.slice(firstColumn, lastColumn));
} else {
string.push(line.slice(firstColumn));
}
} else if (currentLine === lastLine) {
string.push(line.slice(0, lastColumn));
} else {
string.push(line);
}
}
return string.join('\n');
}
}
for (let key in handlebarsNodeVisitors) {
Parser.prototype[key] = handlebarsNodeVisitors[key];
}
for (let key in tokenizerEventHandlers) {
Parser.prototype[key] = tokenizerEventHandlers[key];
}