4.1 初版Scanner (token) 只能 扫描普通字符串
const templateStr=`<h3>我今天买了一部{{thing}}手机,花了我{{money}}元,心情好{{mood}}啊</h3>`;
初步实现普通字符串的扫描和生成token
export default class Scanner { constructor(templateStr) { this.templateStr = templateStr; this.index = 0; //指针初始位置 this.tail = templateStr; //一开始就是模板字符串 } /** * @tag {string} 指定tag?和stopTag有啥关系呢 * @returns {undefined} * 走过指定内容,无返回值 */ scan(tag) { //先执行scanUntil 在执行scan if (this.tail.indexOf(tag) !== 0) return; this.index += tag.length; //tag有多长 index执行后移几位 this.tail = this.templateStr.slice(this.index); } /** * @stopTag{string} 扫描结束标记 * @returns {string} 让指针进行扫描,直到遇见指定标记stopTag结束,返回结束之前扫描经过的文字 * 双指针算法 本质 */ scanUntil(stopTag) { // `<h3>我今天买了一部{{thing}}手机,花了我{{money}}元,心情好{{mood}}啊</h3>`; //记录一下每次执行scanUntil方法时候index值 const indexBackup = this.index; //当尾巴字符串不是以指定stopTag作为开头 说明还没有扫描到stopTag 那么继续 while (this.tail.indexOf(stopTag) !== 0 && this.eos()) { this.index++; this.tail = this.templateStr.slice(this.index); } //返回结束之前扫描经过的文字 return this.templateStr.slice(indexBackup, this.index); } //指针是否到头 end of string eos() { return this.index < this.templateStr.length; } }
生成tokens
import Scanner from "@/my_mustache/Scanner";
export default function parseTemplate2Tokes(templateStr) {
console.log("templateStr :", templateStr);
let tokens = [];
const scanner = new Scanner(templateStr);
let word;
//当指针没有走到头 继续
while (scanner.eos()) {
word = scanner.scanUntil("{{");
if (word) tokens.push(["text", word]);
scanner.scan("{{"); //跳过左{{
// console.log(scanner);
word = scanner.scanUntil("}}");
if (word) {
//word 就是{{}} 双大括号里面的内容
if (word[0] === "#") tokens.push(["#", word.slice(1)]);
else if (word[0] === "/") tokens.push(["/", word.substring(1)]);
else tokens.push(["name", word]);
}
scanner.scan("}}"); //跳过左{{
}
return tokens;
}