eql

command
v2.9.20+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 9, 2016 License: MIT Imports: 10 Imported by: 0

README

Embedded qlang (eql)

eql 全称 embedded qlang,是类似 erubis/erb 的东西。结合 go generate 可很方便地让 Go 支持模板(不是 html template,是指语言特性中的泛型)。

eql 程序

命令行:

eql <template_file> [-o <output_file>] [--key1=val1 --key2=val2 ...]
eql <template_dir> [-o <output_dir>] [--key1=val1 --key2=val2 ...]

其中

  • <template_file>: 要解析的 eql 文件,也就是模板文件。
  • <template_dir>: 要解析的 template package,也就是整个目录是一个模板。
  • <output_file>: 要生成的渲染后的文件。如果没有指定则为 stdout。
  • <output_dir>: 要生成的渲染后的目标目录。如果没有指定则为对 <template_dir> 进行渲染后的值。
  • --key1=val1 --key2=val2 ...: 渲染涉及到的模板变量的值。

样例

单文件模板
  • example.eql: 展示 eql 语法的样例,下文将详细介绍。
目录模板
  • $set.v1: 以集合类为例展示如何构建一个 template package。

语法

插入 qlang 代码
<%
    // 在此插入 qlang 代码
%>
输出 qlang 表达式
<%= qlang_expr %>

你可以理解为这只是插入 qlang 代码的一种简写手法。它等价于:

<% print(qlang_expr) %>
输出一个变量
$var

你可以理解为这只是插入 qlang 代码的一种简写手法。它等价于:

<% print(var) %>

特别地,我们用 $$ 表示普通字符 $。也就是说:

$$

等价于:

<% print('$') %>

用 eql 实现 Go 对泛型的支持

我们举例说明。假设我们现在实现了一个 Go 的模板类,文件名为 example.eql,内容如下:

package eql_test

import (
	<%= eql.imports(imports) %>
	"encoding/binary"
)

// -----------------------------------------------------------------------------

type $module string

func (p $module) write(out $Writer, b []byte) {

	_, err := out.Write(b)
	if err != nil {
		panic(err)
	}
}

<% if Writer == "*bytes.Buffer" { %>
func (p $module) flush(out $Writer) {
}
<% } else { %>
func (p $module) flush(out $Writer) {

	err := out.Flush()
	if err != nil {
		panic(err)
	}
}
<% } %>

// -----------------------------------------------------------------------------

这个模板里面,有 3 个模板变量:

  • imports: 需要额外引入的 package 列表,用 , 分隔。
  • module: 模板类的类名。
  • Writer: 模板类的用到的参数类型。

有了这个模板,我们就可以用如下命令生成具体的类:

eql example.eql -o example_bytes.go --imports=bytes --module=modbytes --Writer="*bytes.Buffer"

这会生成 example_bytes.go 文件,内容如下:

package eql_test

import (
	"bytes"
	"encoding/binary"
)

// -----------------------------------------------------------------------------

type modbytes string

func (p modbytes) write(out *bytes.Buffer, b []byte) {

	_, err := out.Write(b)
	if err != nil {
		panic(err)
	}
}

func (p modbytes) flush(out *bytes.Buffer) {
}

// -----------------------------------------------------------------------------

再试试换一个 Writer:

eql example.eql -o example_bufio.go --imports=bufio --module=modbufio --Writer="*bufio.Writer"

我们得到 example_bufio.go,内容如下:

package eql_test

import (
	"bufio"
	"encoding/binary"
)

// -----------------------------------------------------------------------------

type modbufio string

func (p modbufio) write(out *bufio.Writer, b []byte) {

	_, err := out.Write(b)
	if err != nil {
		panic(err)
	}
}

func (p modbufio) flush(out *bufio.Writer) {

	err := out.Flush()
	if err != nil {
		panic(err)
	}
}

// -----------------------------------------------------------------------------
结合 go generate

结合 go generate 工具,我们就可以很好地支持 Go 泛型了。

例如假设我们在 foo.go 里面引用了 Writer = *bufio.Writer 版本的实现,则只需要在 foo.go 文件中插入以下代码:

//go:generate eql example.eql -o example_bufio.go --imports=bufio --module=module --Writer=*bufio.Writer

如此,你只需要在 foo.go 所在的目录执行 go generate 就可以生成 example_bufio.go 文件了。

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL