Началось все с того, что я решил выучить PHP, а что из этого вышло — смотрите ниже.
После прочтения уроков по php, я захотел написать свой шаблонизатор для Express с синтаксисом очень похожим на php.
Идея моей реализации простая — на место html подставлять функцию, при выполнение которой на экран будет добавлен этот htm, в качестве аргументов этой функции передавать тот код, который встраивается в специальных inline блоках (<?=
, ?>
) в html, которые в свою очередь встраивают javascript значения в html. А весь остальной код собирать в один файл и при рендеринге скармливать интерпретатору.Выдумывать синтаксис не стал, взял из php заменив лишь <?php
на <?js
. Код
этого шаблонизатора ужасен для прочтения — на всякий случай, имя встраиваемых функций начинаются тремя символами долларов, чередующихся с пробелом ($_$_$_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);
}
}
С написанием песочницы проблем не возникло. Быстро собрав браузерную версию кода, написал страничку, которую затем опубликовал на git pages. С подсветкой синтаксиса тоже не было проблем — благо синтаксис моего шаблонизатора мало чем отличается от php и html.
Напоследок оставлю ссылки на небольшую документацию, NPM и пару примеров. Работы еще много, в планах написать плагины для InteliJ и других редакторов, доработать документацию и сделать хотя бы пару сайтов для примера. Но надеюсь что сообщество оценит мой труд (желательно положительно). Об ошибках и предложениях пишите в комментариях, с радостью отвечу на все.
Автор: призывник