npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vlr/razor

v2.0.4

Published

Second order generator, made for generation of source code in TS/JS/CS languages

Downloads

5

Readme

@vlr/razor

Template engine, implemented as second order generator, i.e. generator of generators.
Usually template engines work by following formula:

const Output = F(template, data);

Given that one template is most of the time used with a lot of data objects, this function can be transformed into one-argument function by partial application. Like this:

// this is a function that takes two-argument function 
// and returns partially applied one-argument function
const partial = (F, template) => { return  (data) => F(template, data); }

// partially applied function is "cached" in variable
const Fpartial = partial(F, template);

// same result as in first example
Output1 = Fpartial(data1);
Output2 = Fpartial(data2);

Then, usually template engines are offering to do sort of precompilation instead of partially applied function. This gives a bit of optimization to the process.
And Razor, instead of precompilation, generates a code that would concatenate strings to produce an output, i.e. will work as first-order code generator. Hence the definition - razor is a second order generator.

Terminology

This library, template engine or second-order generator, is called "razor" throughout this readme.
Output of razor's work, i.e. first order generator is called "generator".
Output of generator's work will simply be called an "output".

Usage and Options

Razor is designed to be used as a transformation function that transforms one string into another string. Template into source code of generator. Simplest way to use it is within gulp task, along with gulp-transform plugin, or any other plugin of choice

import { transform } from "@vlr/gulp-transform";
import { generate } from "@vlr/razor";

export function runRazor(): NodeJS.ReadWriteStream {
  const src = "./" + settings.src;
  const razorFiles = src + "/**/*.rzr";
  return gulp.src(razorFiles)
    .pipe(transform(file => (
      { 
        ...file, 
        contents: generate(file.contents), 
        extension: ".ts"
      })))
    .pipe(gulp.dest(src));
}

Razor options

3 options can be specified to razor.

const options = {
  quotes: "\"", // or "'"
  linefeed: "\n", // or "\r\n", "\r",
  language: "ts" // or "js", "cs"
}

Quotes is the character to be used when generator imports from the export part of the razor library.
Language is the programming language in which source code of generator will be made. C-sharp will not be supported in first release. Default is ts.
Linefeed is the symbol to be used in source code of generator. Default is unix linefeed.

Generator options

2 options can be specified to generator.

const options = {
  quotes: "\"", // or "'"
  linefeed: "\n", // or "\r\n", "\r"
}

Linefeed is the symbol to be printed to output.
Quotes is the symbol to be printed to output in place of all unescaped quotes and apostrophes. If this option is not provided, output will contain the symbol from the template.

Key symbol and escapes

Razor uses "@" or "at" symbol as key symbol as it is amongst the most rarely used symbols in source code.
Also it is used as an escape symbol paired like this:
@} - output will contain } at that position
@" - output will contain " at that position, regardless of "quotes" option
@' - the same as previous, but with apostrophe

Configuration

There are 2 configurations that can only be provided at the start of the template.

@import { MyData } from "./myFile"
@define myEntity(data: MyData)

First will be put into generator as is.
Second is a definition of generator function. "Options" parameter will be added trailing your parameters.
Generator is then to be called like that

const output = myEntity.generate(data, options);

If definition is not provided, then default "generator" name will be used

Razor mnemonics

Expression

// template
public class @data.name { }

// output, given that data.name contained word "MyClass"
public class MyClass { }

Explicit expression

Sometimes part of the word needs to be specified

// template
public class My@(data.name)Class { }

// output, guess what data.name contains
public class MyWonderfulClass { }

Injection

This is useful for adding some manual code to generator.

// template
@{ const employee = data.employee; }
console.log("@employee.name @employee.age");

// output
console.log("Peter 20");

Conditional clause

Depending on contents of data object, insides will appear in output or not.

// template
console.log(@if(data.enoughExperience) {"SeniorDev"} else {"Junior"});

// alternative template
@if(data.enoughExperience){
console.log("SeniorDev");
} else {
console.log("Junior");
}

Enumeration clause

Produces one line of the output per enumerated item.

// template
@for(let item in data.items){
  console.log("@item.name");
}

// output
  console.log("item1");
  console.log("item2");

Escaped brace

If you need to produce a brace inside enumeration or conditional clauses.

// template
@for(let item in data.items){
  for(let user of users){
    console.log("@item.name");
  @}
}

// output 
  for(let user of users){
    console.log("item1");
  }
  for(let user of users){
    console.log("item2");
  }

Cascading

When you have 2 generators, there is an operator to call one from another, this will also support indentation, unlike using it as expression

  // template1
@define t1(item)

console.log("@item.name 1");
console.log("@item.name 2");


  // template2
  // notice long indent here
@import { t1 } from "./template1"
@for(let item of data.items){
        @[t1(item)]
}

  // output
        console.log("item1 1");
        console.log("item1 2");
        console.log("item2 1");
        console.log("item2 2");