JSTE — как я писал свою версию EJS

Началось все с того, что я решил выучить PHP, а что из этого вышло — смотрите ниже.


После прочтения уроков по php, я захотел написать свой шаблонизатор для Express с синтаксисом очень похожим на php.


Идея моей реализации простая — на место html подставлять функцию, при выполнение которой на экран будет добавлен этот htm, в качестве аргументов этой функции передавать тот код, который встраивается в специальных inline блоках (<?=, ?>) в html, которые в свою очередь встраивают javascript значения в html. А весь остальной код собирать в один файл и при рендеринге скармливать интерпретатору.Выдумывать синтаксис не стал, взял из php заменив лишь <?php на <?js. Код
этого шаблонизатора ужасен для прочтения — на всякий случай, имя встраиваемых функций начинаются тремя символами долларов, чередующихся с пробелом ($_$_$_code001_$_$_$).
Те, кому стало интересно могут заглянуть под спойлер.


Осторожно: страшный код
const fs = require('fs');

const jsAll = /<\?js\s+([\S\s]*?)\s+\?>/mg;
const jsInject = /<\?=\s*([\S\s]*?)\s*\?>/mg;

function read(path) {
    return fs.readFileSync(path,'utf-8');
}

function evalute(noncode) {
    let noncodes = noncode.replace(jsInject,'$%&').split('$%&').filter(function(i){return i});
    let evals = noncode.match(jsInject);
    let evs = [];
    let evrs = [];
    let fnoncode = '';
    for(c in noncodes){
        fnoncode+=noncodes[c];
        if(c < noncodes.length-1){
            fnoncode += "$_$_$_"+evals[c].replace('<?=','').replace('?>','')+"_$_$_$";
            evs.push("$_$_$_"+evals[c].replace('<?=','').replace('?>','')+"_$_$_$");
            evrs.push(""+evals[c].replace('<?=','').replace('?>','')+"");
        }
    }
    return [fnoncode,evrs,evs];
}

function parse(text,document) {
    documen = {
        write:function (txt, arn, args) {
            for (an in arn){
                txt = txt.replace(arn[an],args[an]);
            }
            document.write(txt);
    }};
    let codes = text.match(jsAll);
    let noncode = text.replace(jsAll,'$%&');
    let fcode = '';
    let $_$_$_fcs_$_$_$ = {};

    let prevdata = noncode.shift();
    let qrt = evalute(prevdata);
    fcode+="$_$_$_fcs_$_$_$['$_$_$_code"+"prev"+"_$_$_$'](["+qrt[1].join(',')+"]);\n";
    $_$_$_fcs_$_$_$["$_$_$_code"+"prev"+"_$_$_$"]=function(txt,arn){return function(args){documen.write(txt,arn,args)}};
    $_$_$_fcs_$_$_$["$_$_$_code"+"prev"+"_$_$_$"]=$_$_$_fcs_$_$_$["$_$_$_code"+"prev"+"_$_$_$"](qrt[0],qrt[2]);

    for(c in codes){
        fcode+=codes[c].replace('<?js','').replace('?>','');
        if(c < codes.length-1){
            let qrt = evalute(noncode.shift());
            fcode+="$_$_$_fcs_$_$_$['$_$_$_code"+c+"_$_$_$'](["+qrt[1].join(',')+"]);\n";
            $_$_$_fcs_$_$_$["$_$_$_code"+c+"_$_$_$"]=function(txt,arn){return function(args){documen.write(txt,arn,args)}};
            $_$_$_fcs_$_$_$["$_$_$_code"+c+"_$_$_$"]=$_$_$_fcs_$_$_$["$_$_$_code"+c+"_$_$_$"](qrt[0],qrt[2]);
        }
    }
    if(noncode.length>0){
        let postdata = noncode.join('\n');
        let qrt = evalute(postdata);
        fcode+="$_$_$_fcs_$_$_$['$_$_$_code"+"post"+"_$_$_$'](["+qrt[1].join(',')+"]);\n";
        $_$_$_fcs_$_$_$["$_$_$_code"+"post"+"_$_$_$"]=function(txt,arn){return function(args){documen.write(txt,arn,args)}};
        $_$_$_fcs_$_$_$["$_$_$_code"+"post"+"_$_$_$"]=$_$_$_fcs_$_$_$["$_$_$_code"+"post"+"_$_$_$"](qrt[0],qrt[2]);
    }
    return function () {
        eval(fcode);
    }
}

С написанием песочницы проблем не возникло. Быстро собрав браузерную версию кода, написал страничку, которую затем опубликовал на git pages. С подсветкой синтаксиса тоже не было проблем — благо синтаксис моего шаблонизатора мало чем отличается от php и html.


Напоследок оставлю ссылки на небольшую документацию, NPM и пару примеров. Работы еще много, в планах написать плагины для InteliJ и других редакторов, доработать документацию и сделать хотя бы пару сайтов для примера. Но надеюсь что сообщество оценит мой труд (желательно положительно). Об ошибках и предложениях пишите в комментариях, с радостью отвечу на все.

Метки:
javascript, express.js, веб-дизайн, php