EasyBeetl——结构化创建Beetl表达式


EasyBeetl——结构化创建Beetl表达式

项目地址

Demo地址

部署

项目源码可以直接部署到任何服务端容器:Apache、Nginx、Nodejs…..

但是不能直接在本地用浏览器以 File 协议打开

如果需要本地使用,可以在Releases下载 easybeetl-win32-x64,解压后在根目录运行 easybeetl.exe 即可

使用

前言

所有涉及到“起点”、“终点”的下标概念,需要注意,下标要从 0 开始数,而“终点”通常是不被包括的

例如:”helloworld”中的 “ow” 子串,起点是下标 4,因为从 0 开始数,所以下标要比自然顺序(5)少了1。而终点则是 6,因为终点的下标不被包括,所以4~5 这一串字符的终点是 5 + 1 = 6

类型

easybeetl 将 beetl 表达式分为三种类型:

  1. 字符串
  2. 变量或数值
  3. 其他(又称为表达式)

1. 字符串

字符串类型就是需要加引号的数据,例如 "hello"

根据引号类型的不同,字符串又被细分为两种类型:单引号字符串和双引号字符串

2. 变量或数值

变量或数值等不需要双引号的数据,例如 15variable

3. 表达式

除了上述两种类型以外,所有的其他类型都归类为表达式

  • beetl 函数是表达式:isEmpty(xxx)
  • 参数是表达式:10, 20

按钮

demo演示地址中有3个按钮

image-20221218115000383

image-20221218115016143

image-20221218115023094

  • 新建/重置,用来重新创建 beetl 表达式
  • 获取stack,是开发时用来debug的
  • 渲染,将创建的beetl输出到 F12 控制台

demo 中以“行”表示每一段独立的 easybeetl
image-20221218115205207

同一层级的“行”,左边的颜色相同

image-20221218115235303

右边有两个按钮,添加按钮代表这在当前行的后面(同一层级)添加一个新行

元素

行内有三个元素:方法、类型、填充值

类型

其中,只有类型为字符串或者变量或数值才需要填充值,若类型为表达式,那么将自动创建下一层级的行

方法

方法分为5大类:核心方法、基本方法、字符串方法、数组方法、正则方法

其中后4类为 beetl函数,而核心方法则是基本语法

核心方法

描述语法符号
表达式以字符或变量开头表达式以字符或变量开头
字符串拼接+
参数拼接,
创建If?
If = True:
If = False:
数值运算加法+
数值运算减法-
数值运算乘法*
数值运算除法/
括号()
方法或属性调用的小数点.

基本方法

描述参数列表
获取当前时间
返回指定日期日期, 格式化规则
打印一个对象对象
打印一个对象并换行对象
打印文件文件地址
nvl对象, 字符串
判断为空对象
判断不为空对象
截取数字或日期对象, 位数或格式
保留小数对象, 位数
转换为整型对象
转换为长整型对象
转换为浮点数对象
创建迭代器初始值, 结束值, 步长
转换为json对象
获取指定cookie对象对象

字符串方法

描述参数列表
判断是否以XX开头对象, 查找的字符串xx
判断是否以XX结尾对象, 查找的字符串xx
获取字符串长度对象
截取从某个位置到末尾对象, 起点
截取指定两个位置间的字符串对象, 起点, 终点
以某个字符分割字符串为数组对象, 正则表达式
判断是否存在某串字符对象, 匹配字符串
全部英文转大写对象
全部英文转小写对象
替换部分字符串对象, 匹配字符串, 替换字符串
格式化字符串对象, 数量相符的参数
去掉字符串尾部空格对象
格式化日期对象, 格式
获取指定字符串第一次出现下标对象
获取指定字符串最后一次出现下标对象

数组方法

描述参数列表
返回数组的一部分数组, 起点, 终点
删除数组的某个元素数组, 元素
向数组添加一个元素数组, 元素
判断数组是否包含某元素数组, 元素
转化成数组任意数量参数
将java集合转换为数组数组

正则方法

描述参数列表
判断是否匹配对象, 表达式
替换对象, 表达式, 替换的字符串
查找第一个匹配的对象, 表达式
查找所有匹配的对象, 表达式
切分字符串返回列表对象, 表达式
切分字符串返回列表并限制个数对象, 表达式, 最多个数

每一层级的开头默认方法都是“表达式以字符或变量开头”,这个方法的作用是,不对填充值做任何处理

要进行字符串的拼接操作,例如 "a" + "b",那么在这一段中,”a” 应该使用的方法是:表达式以字符或变量开头

而 “b” 应该使用的是:字符串拼接

当然如果你以表达式开头,那么自然不用选择这个方法

总结

  1. 对于每一层级,开头的第一行,如果类型是字符串、变量或表达式,那么方法要选择“表达式以字符或变量开头”,而如果类型是表达式,那么选择对应的方法即可

  2. 对于字符串拼接,需要选择“字符串拼接”方法,但是要注意的是,上一条规则优先级更高,也就是说当前层级第一行的那个字符串或变量,要选择“表达式以字符或变量开头”。而如果第一行是表达式,第二行才是字符串拼接,那么第二行直接选“字符串拼接”即可

  3. 对于方法的变量,如果只有单个变量,直接填入方法的这一行中的“填充值”这一栏,也就是从左往右第三个单元格。如果有多个变量,那么参数列表的类型是表达式,与字符串拼接规则一样,不同的是,方法需要选择“参数拼接”

  4. Demo地址中,添加新行时,每个层级第一行默认方法“表达式以字符或变量开头”,其他行默认“字符串拼接”。

    如果上一行是“创建If”,那么创建的新行默认是“If=True”
    如果上一行是“If=True”,那么创建的新行默认是“If=False”

    如果不是最外层,那么默认“参数拼接”

示例

例1

有一个变量 name,当 name 不为空时,返回自身,否则返回“姓名为空”

根据需求,可以手写出 beetl 表达式:${(isNotEmpty(name)?name:"姓名为空")}

如果用 easybeetl,可以如下操作:

image-20221219171059160

image-20221219171115476

例2

给定两个变量 name 和 age,最终要呈现的结果是:姓名:XXX,年龄:XX

手写结果:${"姓名:"+(isNotEmpty(name)?name:"空")+","+(isNotEmpty(age)?age:"空")}

easybeetl:

image-20221219171300394

image-20221219171306152

例3

有一个字符串变量 invoice,其可能以“发票”两个字结尾,也可能没有。要求删除发票两个字

有两个思路:要么使用 replace 替换“发票”,要么就进行复杂的判断,下面都用easybeetl给出演示

  1. replace

    image-20221219171559532

    image-20221219171606271

  2. 复杂判断

    image-20221219171825368

    image-20221219171830281

添加自定义方法

EasyBeetl 提供了添加自定义方法的入口:extend.json,格式如下

[
  {
    "value": "say",
    "text": "这是自定义方法示例",
    "params": "参数列表"
  }
]

extend.json 是一个数组,每一个元素都是一个方法

value:方法名

text:选择框中显示的描述

params:选择框中显示的参数列表

如果使用 electron 打包的版本,extend.json 在根目录下的 /resources/app/extend.json 位置

开发

EasyBeetl 的核心是 easybeetl.js

项目源码中,index.htmlmethod.html 是网页端的实现方式

下面对 easybeetl 的数据结构与算法进行介绍

数据结构

类型

EasyBeetl 将常规 beetl 表达式 ${…..} 大括号内的内容拆分为三种类型:字符串、变量或数值、其他(又称为表达式)

他们的区别表现为,字符串仅需要在两边加上双引号,变量或数值则保持原样不变,而表达式则需要经过 EasyBeetl 的复杂操作进行最终渲染

除了表现形式上的区别,在逻辑区别上,字符串变量或数值的是最细的粒度,而表达式可以进行嵌套


内容

对于每一段内容,使用三个属性来表示:

  1. type,即上述类型
  2. method,使用的方法
  3. value,值

e.g.

let example = {
    type: 'string_double',
    value: 'hello',
    method: 'appendString'
}

type 有四种值:

  • 字符串:’string_double’或’string_single’,分别代表双引号和单引号字符串
  • 变量或数值:’variable’
  • 表达式:’expression’

value 有两种值:

  • 字符串:对应类型(字符串、变量或数值)的值
  • 数组:对应类型(表达式)的嵌套

method 对应 easybeetl.js 中 core 里面的所有方法(除了 exec )

方法

easybeetl.js 中的 core 提供了很多拼接语句的方法,这些方法对应上述“内容”结构中的 method 字段

easybeetl.js 默认最外层内容为:

{
    type: "placeholder",
    value: []
}

通过导入 easybeetl 并调用 build 方法可以获得一个全新的 placeholder

对于此数据结构,在 easybeetl 中称为 stack

easybeetl 提供了另外四个可供调用的方法:

  1. render(stack),将 stack 渲染成 beetl 表达式

  2. add(stack, pos, obj),将一段“内容”添加到 stack

    pos 是一个数组,每一个数字代表其在每一层对应的下标,其中 placeholder 是最顶层,往这一层添加“内容”,pos数组只需要拥有一个元素

  3. remove(stack, pos),删除指定位置的“内容”及其嵌套“内容”

  4. set(stack, pos, options),设置指定位置“内容”的值,不改变对象引用

算法

stack 是树状结构,EasyBeetl 通过 dfs 算法进行遍历来构造 beetl 表达式


文章作者: ❤纱雾
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ❤纱雾 !
评论
  目录