swapm

code generation for the rest of us

npm install swapm
20 downloads in the last month

Swap'Em

Code generation for the rest of us

Features

  • Language agnostic
  • Mustache Templates + JSON
  • Inline templates & data
  • Simple project integration

Install

npm install -g swapm

Initialize Project

cd project/
swapm --init

this will create a project/swapm directory where your data & templates live.

Injection

An injection point consists of an open and close tag. The open tag must state the template and data to use.

[=[template: "template_name", data: "data_name"]=]

[=[end]=]
  • The template is rendered and injected between the two tags.
  • Injection tags can span multiple lines.
  • The syntax used to comment out a tag cannot be on its own line.

Good

/* [=[template: "foo", data:{
  baz: "hello world"
}]=] */

// [=[end]=]

Bad

/*
[=[template: "foo", data:{
  baz: "hello world"
}]=]
 */ <-- this will get cut

/* <-- this too
[=[end]=]
*/

Data

  • All data is in JSON format.
  • There are three ways to define data.

Inline

[=[template: "my_template", data:{
  foo: "bar",
  bar: [1, 2, 3, 4]
}]=]

[=[end]=]

Source block

[#my_data=[{
  foo: "bar",
  bar: [1, 2, 3, 4]
}]=]

Json file

File: project/swapm/data/my_data.json

{
  foo: "bar",
  bar: [1, 2, 3, 4]
}

Templates

  • Mustache is the templating engine used.
  • There are two ways of defining a template

Source block

[@my_template=[
  Foo: {{foo}}
  Bars: {{#bar}}{{.}}{{/bar}}
]=]

.tmpl file

File: project/swapm/templates/my_template.tmpl

Foo: {{foo}}
Bars: {{#bar}}{{.}}{{/bar}}

Computed Properties

This is a mustache feature but it's essential to know when using swapm.

/*

[#foo_data=[{
  items: [
    { a: 1, b: 2 },
    { a: 3, b: 4 },
    { a: 5, b: 6 }
  ],
  addAtoB: function() {
    return this.a + this.b;
  }
}]=]

[@foo_tmpl=[
  {{#items}}
    Sum: {{addAtoB}}
  {{/items}}
]=]

*/

// [=[template: "foo_tmpl", data: "foo_data"]=]

// [=[end]=]

Example

Source File: project/foo.h

#ifndef FOO_H_
#define FOO_H_

#include <libpq-fe.h>
#include <libpqtypes.h>

/*
[@foo_mysql=[
#define QUERY "SELECT {{#stuff}}{{name}}{{^last}}, {{/last}}{{/stuff}} FROM my_table"
]=]
*/

// [=[template: "foo_sql", data: "my_data"]=]

// [=[end]=]

class Foo {
private:

// [=[template: "foo_members", data: "my_data"]=]

// [=[end]=]

public:
  Foo(PGresult * res);
  virtual ~Foo();
};

#endif /* FOO_H_ */

Data File: project/swapm/data/my_data.json

{
  stuff: [
    { name: "id", type: "int8"  },
    { name: "bar",type: "float4", last: true }
  ],
  pgType: function() {
    return ["\tPG", this.type, " * _", this.name, ";"].join('');
  }
}

Template: project/swapm/templates/foo_members.tmpl

{{#stuff}}
  PG{{type}} * _{{name}};
{{/stuff}}

this will have the same result

{{#stuff}}
  {{pgType}}
{{/stuff}}

Generate

swapm *.h

Output

#ifndef FOO_H_
#define FOO_H_

#include <libpq-fe.h>
#include <libpqtypes.h>

/*
[@foo_mysql=[
#define QUERY "SELECT {{#stuff}}{{name}}{{^last}}, {{/last}}{{/stuff}} FROM my_table"
]=]
*/

// [=[template: "foo_sql", data: "my_data"]=]

#define QUERY "SELECT id, bar FROM my_table"

// [=[end]=]

class Foo {
private:

// [=[template: "foo_members", data: "my_data"]=]

    PGint8 * _id;
    PGfloat4 * _bar;

// [=[end]=]

public:
  Foo(PGresult * res);
  virtual ~Foo();
};

#endif /* FOO_H_ */

Warning

this is a work in progress and it might eat your code.

npm loves you