打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
公众号排版新姿势——使用Org-mode一键生成
userphoto

2024.03.22 湖北

关注

我的博客基本上都会同步到微信公众号,但是我从来不用公众号后台提供的编辑器,一个原因是它不好用,另一个原因是我已经写好了markdown文本格式,不想再在富文本编辑器里做一次排版工作了。过去我一直在使用 https://github.com/doocs/md ,但因为一些问题,我想从Markdown格式迁移到Org格式,找了一下没发现有可以将Org转换到公众号格式的工具,于是打算自己写一个工具用于转换。

界面预览

preview

仓库地址:https://github.com/Eliot00/mp-org

目前的UI和功能都还比较简单,只是将Org文本贴进去,预览一下样式,再复制粘贴到公众号后台。

原理

微信公众号编辑器支持直接粘贴富文本内容。所谓富文本,顾名思义就是除了文字以外,还包含字体、大小、颜色、对齐方式等样式信息。如果可以从Org文本生成一个富文本内容,那么就可以做到编辑Org格式文本,再一键复制到公众号发布了。

DSL转换

首先需要做的,是两种不同DSL之间的转换。什么是DSL?

DSL(Domain-specific language,领域专用语言),是一种专门为了某个特定领域或应用场景而定制的计算机语言。相比通用编程语言,DSL更加小巧、简单、高度专注于特定问题域。它旨在提高开发效率,让程序员或最终用户能够用更自然的方式表达意图。标记语言是DSL的一种典型形式,主要用于对文本内容进行注释和赋予含义。标记语言使用一组预先定义好的结构化标记,将文档划分为不同的逻辑区块,并对每个区块的类型和语义做出约定,最经典的一种标记语言就是HTML(HyperText Markup Language 超文本标记语言)。

Org也是一种标记语言,举个例子,Org格式规定将一段文本用星号包起来,例如 *bold*,就表示这段文本应当加粗,支持Org格式的应用,如Emacs就可以通过解析Org文档,获取这个信息,从而在界面上将这段文本加粗显示。

那为什么要从Org格式转换到HTML格式呢?因为微信支持HTML格式的富文本,并且HTML可以和另一个DSL——CSS结合,描述更丰富的样式信息。

具体的做法是通过一种叫做Parser的程序,将Org转换成一种树形结构,称为AST(Abstract syntax tree,抽象语法树)。例如一段Org文本:

* Example
some text
- item1
- item2

可以解析成这样一种结构:

{
    'type': 'org-data',
    'children': [
    {
        'type': 'section',
        'children': [
        {
            'type': 'headline',
            'level': 1,
            'children': [
            {
                'type': 'text',
                'value': 'Example'
            }
            ]
        },
        {
            'type': 'paragraph',
            'children': [
            {
                'type': 'text',
                'value': 'some text\n'
            }
            ]
        },
        {
            'type': 'plain-list',
            'children': [
            {
                'type': 'list-item',
                'children': [
                {
                    'type': 'paragraph',
                    'children': [
                    {
                        'type': 'text',
                        'value': 'item1\n'
                    }
                    ]
                }
                ]
            },
            {
                'type': 'list-item',
                'children': [
                {
                    'type': 'paragraph',
                    'children': [
                    {
                        'type': 'text',
                        'value': 'item2'
                    }
                    ]
                }
                ]
            }
            ]
        }
        ]
    }
    ]
}

通过遍历这棵树的节点,可以递归地将其转换成HTML。

<h1>Example</h1>
<p>some text</p>
<ul>
    <li>
    <p>item1</p>
    </li>
    <li>
    <p>item2</p>
    </li>
</ul>

CSS内联

只是用HTML表示一个节点是标题还是无序列表,所携带的样式信息还是太少了。要想描述文本的字体、大小、颜色、间距等细节,还需要借助CSS(Cascading Style Sheets,层叠样式表)进行渲染控制。但是注意,我们不能单独写一个CSS文件上传到公众号后台,要想直接将使用CSS定义了样式的HTML复制到公众号后台,需要使用HTML的内联CSS语法:

<p style='color: red;'>hello</p>

在从Org转换到HTML的过程中,可以直接为要生成的元素写死内联样式,但是为了扩展性(也许用户需要自定义CSS样式),在实际的代码中是在转换过程完成后,再将一个单独的CSS文本解析注入到已有的HTML文本中去的。

拷贝富文本

生成了内联样式的HTML后,怎么把它复制到公众号编辑器里呢?如果你直接打开一个网页,右键查看源代码,把这个源代码复制到公众号,会发现只是复制了HTML的源码文本,而不是最终呈现的富文本样式。怎么把富文本复制到系统的剪切板?其实只需要很短的代码就可以实现:

const type = 'text/html';
const blob = new Blob([htmlStr], { type });
const data = [new ClipboardItem({ [type]: blob })];
navigator.clipboard.write(data);

Roadmap

目前这个工具的功能还是非常简单的,后续打算把之前用过的markdown转换的工具的功能都移植过来:

  • · 链接转换:订阅号不支持外链,只允许内部其他图文链接,要分开处理,外链转成脚注,内部链接不变

  • · 自定义样式

  • · 图片上传OSS,可以和picgo之类的工具结合一下

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Dreamweaver cs6初级培训视频教程
CSS实用教程
Dreamweaver使用CSS样式表设置网页
使用sigil制作epub格式电子书
最好用的离线markdown编辑器Haroopad介绍
Markdown懒办法排版微信公众号文章
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服