先发布 POC 版本,感兴趣的同学可以先看 tests 里面 demo 代码了解用法。
目前实现了:
- 单个 block 渲染的完整功能 (block-string) – 已稳定
- 多个 block 的简单的布局功能 (block-concat, block-stack)。 – 后续会变动
后续计划:
- 目前布局的方式只是简单的在水平和垂直方向连接文本块实现的,代码写起来比较繁琐,后续会优化为基于 ”座标“ 的任意布局。
- 支持多个文本块的部分重叠覆盖的效果。
- 修改为 声明式的S表达式 来定义结构和布局,而非当前”命令式“的使用函数生成。
该包依赖 emacs-kp: GitHub - Kinneyzhang/emacs-kp: Implement of Knuth-plass algorithm in emacs-lisp, support for mixed typesetting of CJK and Latin languages.
另外我一直在思考 ”block“ 这个包名称是否合适,暂时没有想到更合适的名字。
下面是demo图片:
36 个赞
提交了,这个是之前的命名,现在用 block-string-duplines
神奇。感觉可以用来改改 eww 浏览简单网页了。
不过我在第一次允许测试时遇到了变量未定义的问题,手动 C-c C-e
求值 block-utils.el 后问题消除,可能是编译后导致的问题,不过不太清楚是否是 native-comp 而不是 byte-comp。
此外,block.el 里面也许最好添加 (require 'ekp)
。
已修改。这个变量 it 是 dash 里面的 --map 默认使用的 lambda 内的参数,刚刚移除了,现在不依赖 dash.el。(require 'ekp) 在 block-pixel.el 里面添加了。
可用了。
qs,不过我有点畅想 ETML(Emacs Text Markup Language),ECSS(Emacs Cascading Style Sheets)和 Elisp(Emacs Lisp)的未来了 
ETML 这个名字不错诶,含义清晰明了,最终我就是要用 S表达式的结构来表达类似 HTML 的结构和布局,多年前,我写过一个 pp-html,就是做的类似的翻译工作。
然后 html 的基础元素的组合和布局就可以定位为 组件,可以在 ETML 结构中嵌入组件,复用相同的结构和功能;最后再加上按键交互的功能 EJS,还有 EORM 对于数据库操作的封装用作后端存储,完美了,哈哈哈。这些都是 ETAF 要做的事情。
5 个赞
ginqi7
10
使用体验
方法理解
- class block 用于定义一个展示块,返回值是一个 class 对象
- block-string 渲染一个展示块,返回值是一个字符串
- block-stack 垂直渲染多个块,返回值是一个字符串
- block-concat 水平渲染多个块,返回值是一个字符串
问题
- 嵌套使用时,容易出错。提供的各个方法,入参、出参,有的时候是字符串,有的时候是 block。容易混淆
- 嵌套使用时,emacs-kp 可能会对字符串反复格式化,导致对齐不准。
个人建议
- 把 class block 本身就做成嵌套的,就最好不过了。他的 content 既可以是 string 也可以是嵌套的 block
- block-stack 和 block-concat 不 render 成字符串,而是组合成嵌套的 block。
- 等组合完嵌套的 block 之后,使用 (block-render BLOCK),生成字符串。
- 不过这样可能会大大增加 block-render 的复杂度
例子
当前的实现逻辑:
(block-render
(block
(block-stack
(block (block-concat (block "A") (block "B")))
(block (block-concat (block "C") (block "D"))))))
如果 block 本身可以变成嵌套的,那么可以如下实现
(block-render
(block
(list
(list (block "A") (block "B"))
(list (block "C") (block "D"))
))
如果 block-stack 和 block-concat 不 render 成字符串,而是组合成嵌套的 block。可以:
(block-render
(block-stack
(block-concat (block "A") (block "B"))
(block-concat (block "C") (block "D"))))
2 个赞
Kinney
11
很赞:+1:
,正有此意!在最终生成字符串之前,一切都是 block 对象,block 对象可以理解为 doom 树中每个节点,节点可以嵌套其他节点,最基础的节点就类似于基础的html元素,入参是字符串。
Kinney
12
后续我计划优化为,使用下面的 sexp 列表的形式来表示结构布局
'(div
(div "this is header")
(row (col-8 "Forum Book Elpa FAQ Donate Fork Us")
(col-4 "注册 登录"))
(row (col-2 (div "sidebar content"))
(col-10
(row "banner info")
(row (col-5 "left string...")
(col-7
(div "right-top string")
(div "right-middle string")
(row (col-6 "bottom left string")
(col-6 "bottom left string"))))))
(div "this is bottom line..."))
该 sexp 被解析之后,div,row,col-n 都是 block 对象。区别是 div 就是普通的 block 节点;row 会是其中的多个block 先 block-concat,再生成 block 节点;col-n 则是先 block-stack 再生成节点,数字表示宽度比例用来计算当前列的宽度(借鉴经典的12栅格布局)。标签和内容之间用 plist 形式指定各种 :width, :border, :padding, :margin 等属性。
3 个赞
yibie
13
我觉得 ginqi7 的变量名,会更加容易理解一些。
Kinney
14
什么变量名?你是说 block-concat,block-stack 这些嘛,这是底层的函数,还会存在,只不过是在上层做了一层封装,简化名称方便使用。这两种的本质区别是:一个是 “命令式”的(我要做什么),一个是 “声明式”的(我要呈现什么效果)。我觉得声明式的写法对用户更加友好(jquery vs vue/react ..),这也是前端的趋势。当然如果用户不习惯这种写法,也可以直接使用底层的函数。
yibie
16
没,我单纯变量名还是 block-xxx 会比较好理解。毕竟你虽然借用了一些前端的概念,然而行为和表现未必和前端的一致。
fabi
18
利用这个是否可能提高org-mode table的功能, 比如突破其cell不能多行, 行列cell不能span的局限?
或者说有没有可能定义一种新的table形式内嵌到org-mode中?
理论上可以,但需要许多额外的工作来适配各种无法预知的操作和交互,以及 text properties 的存储和还原的问题
这个包只是做了展示层面的工作,更适合在一个只读的buffer中展示表格,然后通过代码的方式来操作数据,也可以实现类似excel的完全的交互方式。让这一切体验很好的前提是:数据单独存储,代码负责渲染属性来实现布局。
在实时编辑的文件中使用的问题是:数据和属性是绑定在一块的,而且用户的行为无法预期,可能会破坏属性,体验不会很好。
2 个赞
大佬,能否实现如图,在边框上加一个 “title” ?