这篇文章主要是为了消除一些误解,顺便宣传一下国内使用者寥寥无几的GNU TEXMACS系统。

排版,一个不应该存在的问题

本文探讨的是【写作系统】。在所谓的【写作】和【排版】之间,是有一道不可逾越的鸿沟的。【写作】时,我们只需要集中精力来【写作】即可。这里的【写作】可以被定义为【输入文本和符号】。【输入文本和符号】这个定义要求我们不能手工调节【文本和符号的属性】,也即是字号、行间距、字体之类的东西。

【写作】时,不应该进行【排版】,但【排版】的问题却是实实在在地【存在】着的。比如说,如何使得本段的标题【排版,一个不应该存在的问题】字号比文章的字号更大、并加粗呢?如果我想要加粗某一个词语,又该怎么做呢?斜体又该如何创造呢?

在这里,计算机科学的一个基本思想–抽象–发挥了它的威力。我们可以将文本的【属性】抽象为两个层次,也就是说

  • 逻辑层,文本的性质是什么。比如说,【排版,一个不应该存在的问题】的性质是【二级标题】,其他文本的性质是【正文】,加了粗的文本的性质是【加粗文本】。
  • 展示层,具有某种性质的文本应该如何展示。比如说,【二级标题】应该具有的属性是【居中、字号为2号、加定长的下划线等等】。

有了这样的抽象以后,我们就无需自己【决定展示层】,我们只需要【决定逻辑层】即可。而相比于指定具体文本的【格式】来说,指定具体文本的【性质】是简单地多的。

那么,应该如何指定文本的【性质】呢?答案就是输入【控制字符】。以书写本文所采用的Markdown系统为例,本文开头的的源码是:

---
author: ayanamists
date: 2020-08-20
title: 谈谈写作软件
---

这篇文章主要是为了消除一些误解,顺便宣传一下国内使用者寥寥无几的GNU TEXMACS系统。

## 排版,一个不应该存在的问题

【排版,一个不应该存在的问题】这个标题的【性质】是如何被指定的呢?答案很简单–使用##符号。这个符号指示后面的文本是一个【二级标题】。既然有【二级标题】,那么自然也就有【一级标题】。实际上,markdown一直可以支持到6级标题:

# a
## aa
### aaa
#### aaaa
##### aaaaa
###### aaaaaa

在本博客的设定中,这些东西会被渲染成以下形式:

a

aa

aaa

aaaa

aaaaa
aaaaaa

这样一来,【展示层】和【逻辑层】的分离就用这种非常自然的手段达到了。从【带有控制字符的文本,即源代码】到【最终展示出来的文件】的过程,被称为【渲染】。

在markdown中,还有其他的很多控制字符,不过这些东西都很简单,例如说,【无序列表】可以这样写:

+ 事物1
+ 事物2

它会被渲染为:

  • 事物1
  • 事物2

【有序列表】可以这样写:

1. 事物1
2. 事物2

它会被渲染为:

  1. 事物1
  2. 事物2

可以看到,这些东西都非常简单。

更进一步:可视化编辑

读到这里,读者也许会有些疑问,难道对于作者来说,写文章是在【带控制字符的文本,或者说源代码】吗?在2019年10月我刚刚接触到markdown时,确实是如此。我在vscode中编辑markdown代码,那三篇数据结构的笔记就是这样写出来的:

1

时至今日,我已经不再使用它了,而是使用更加简单的写作软件–Typora。

Typora主要实现了两个功能:

  • 可视化编辑,所见即所得
  • 用快捷键来加快编辑速度。

下面我们就来重点描述一下这两个特性。

所谓的【可视化编辑】,就是说,我们编辑的文本是【被渲染以后】的文本。比如说,我现在所写的这篇博客是这样的:

2

它实际上编辑的仍然是markdown代码。按下ctrl+/,可以看到文章的源代码:

3

在非源代码模式下,要插入【具有某种属性的文本】,有两种方式。以插入一个无序列表为例:

  1. 用鼠标操作GUI:

    g

  2. 按下ctrl+shift+]快捷键:

    k

这样一来,只要你记忆了为数不多的快捷键,你就可以极为流畅地在好看的GUI中进行编辑了。

不过,这种【可视化编辑】并不是完全【所见即所得】的,由于我的博客和Typora的配置不同,Typora中的效果不是我的博客最终展示出来的效果。

在Typora中,也可以更改【主题】,来选择最好看的【展示层配置】:

theme

真正的麻烦事:公式编辑

下面所说的【公式】,指的是【不能直接通过键盘输入的东西】。比如说

\(a^2\) 带有上标的式子无法通过键盘输入。

\(\forall\) 这个【任意】无法通过键盘输入。

为了解决这个问题,Donald Ervin Knuth发明了TeX系统,它也采用了我们上面所说的【逻辑层和表示层】思想,比如说,在Tex中,

\forall

表示的就是【任意】,它会被【渲染】为:

\[\forall\]

写一个逻辑表达式:

\forall{x},P(x)

它会被渲染为:

\[\forall{x},P(x)\]

在tex\latex\markdown中,都是用$$或者$来指示【被围住的块是要渲染的公式】:

gongshi

TeX系统以及衍生出的LaTeX系统是世界上使用最为广泛的数学排版系统。但是,它有不少问题:

  • 符号没有语义,例如在TeX中没有【整除】符号, 表达【整除】的是【竖线】
  • 语法猥琐,容易产生编译错误,无法调试
  • 写矩阵一类的东西非常麻烦
  • 多个公式对齐也很麻烦

下面,我们来介绍基本解决了以上问题的、写作系统的【终极形态】– GNU TEXMACS

GNU TEXMACS:结构化编辑

一篇文章,或者说一本书是有一个大致固定的结构的。对于文章来说,最简单的结构是【标题+正文】,稍微麻烦一点的结构是【标题+(次级标题+正文)+(次级标题+正文)】。GNU TEXMACS把这种【结构】融入到了编辑的过程中。

面对一个空的文档,GNU TEXMACS会指示你写标题:

t1

点击【标题】,我们进入了【标题环境】:

t2

随便打一个标题:

t3

按下键盘上的enter键,我们惊奇地发现,它自动地进入了【作者】环境:

t4

输入作者,按下left键,离开【标题环境】。

再次按下enter键,GNU TEXMACS会提示我们写摘要:

t5

我一般不写摘要,所以直接无视这个提示。之后,GNU TEXMACS就不会再给你文档结构上的指示了(在【普通文档】模式下)。

经过上面的一番解说,读者应该明白了【结构化编辑】大概是什么意思。下面我们介绍GNU TEXMACS中【结构化编辑】思想的杀手级应用 – 数学公式输入。

按下alt+$键可以进入单行公式环境:

t6

如果你要打之前提到的【任意】符号,应该如何去做呢?我们知道,\(\forall\)符号是倒着的A, 所以先打一个大写的A:

t7

然后,按下tab,它会变成非斜体的A:

t7

再次按下tab,我们惊喜地发现,它竟然变成了【任意】符号!

t8

这就是GNU TEXMACS在数学符号输入上的第一个创新 – 类似符号轮换。

在输入一个符号以后,按下tab是做类似符号轮换,按下别的符号会怎么样呢?我们这里来打一个【大于等于号】:

首先输入一个大于号:

t9

然后,按下键盘上的=号,我们再次惊奇地发现:

t10

大于号也可以极为方便地打出来。

下面,我们来说一个GNU TEXMACS最好用的功能:公式表格。

首先来看看效果:

t11

如果读者使用过TeX的矩阵,就会知道这样输入矩阵是多么的简单。

这是如何做到的呢?首先,按下alt+t键,我们可以插入一个【表格】。这个【表格】有五种形式,可以用tab键轮换:

t12

这是无边框格式;

t13

这是圆括号格式;

t14

这是行列式格式;

t15

这是方括号(一般矩阵用这个)格式;

t16

这是选择(比如说分段函数之类的)格式;

在任何一种格式下,按下esc+left是在左边插入一个新的单元格:

t15

其他esc+方向键是向对应方向插入单元格。

GNU TEXMACS还有很多好用的功能,这里就不一一介绍了。总之,【结构化编辑】的思想在最大程度上简化了输入,只要你记忆了那些快捷键,整个输入过程将变得极为流畅。

总结

我认为,一个优秀的写作系统,应该有以下特点:

  • 分离了【写作】与【排版】,写作时无需关心具体格式
  • 提供了足够好看的默认板式,用户不需要调整,开箱即用
  • 即使是源码也有足够的可读性
  • 提供了可视化编辑系统,无特殊需要不编辑源码
  • 提供结构化编辑功能,最大程度地简化用户输入
  • 能够自由输出PDF、markdown、html等等格式,一处写作处处展示
  • 提供演草系统,给写作者把笔纸扔掉的机会
  • 最理想的数学系统的符号是完全语义化的,并可以作为mathematica之类的前端,让写作者彻底把笔纸扔掉。