- PVSM.RU - https://www.pvsm.ru -

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

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

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

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

Осторожно: страшный код

const fs = require('fs');

const jsAll = /<?jss+([Ss]*?)s+?>/mg;
const jsInject = /<?=s*([Ss]*?)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);
    }
}

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

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

Автор: призывник

Источник [6]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/pesochnitsa/256832

Ссылки в тексте:

[1] Код: https://github.com/AlexStrNik/JSTE/blob/master/jste/parser.js

[2] страничку: https://alexstrnik.github.io/JSTE/jste/playground/

[3] небольшую документацию: https://github.com/AlexStrNik/JSTE/blob/master/jste/Readme.md

[4] NPM: https://www.npmjs.com/package/jste

[5] пару примеров: https://github.com/AlexStrNik/JSTE/blob/master/jste/examples/First.md

[6] Источник: http://habrahabr.ru/sandbox/112494/