Appearance
自定义宏命令的创建
0 术语理解
恭喜!阅读到这里说明您已经是Liii STEM的高级用户了,为了使用更高级的功能,我们需要对以下的术语进行区分(注意到此处的术语定义与 《Liii STEM快速入门》里的术语有些区别):
环境 (Environment)
结构的具象化,在指定的区域内,输入的内容的结构具有特定的结构。这个区域就是环境。也就是说在不同的环境下,输入相同的内容,呈现的效果有所不同。
标记 (Markup)
标记就是环境的名称。例如:section
焦点 (Focus)
焦点就是光标所在的环境(蓝色框所展示的)。
排版原语(Primitive)
是Liii STEM样式语言的内置基本操作,不可再分。例如:<with|> 、<if|>、<equal|>
宏(Macro)
宏是原语的组合,可以被定制的。例如:<assign|test-equal|<macro|arg1|arg2|msg|<if|<equal|arg1|arg2>|Same quantity:arg1|Not equal:msg>>>
标签(Tag)
标签是Liii STEM中的基本排版单位,用于描述文档的结构和格式。
结构 (Structure)
输入的内容在原语/宏的作用下呈现出来的效果。
结构化输入/移动
它要求Liii STEM能够理解文档的内在逻辑结构(如数学公式、代码块、表格或章节等),并允许用户直接对这些逻辑单元进行操作。例如,在表格环境中,结构化插入命令Alt + ← 和 Alt + → 可能用于插入列, Alt + ↑ 和 Alt + ↓ 用于插入行。删除的操作也相同,Alt+Backspace 和 Alt+Delete可用于结构化后向或前向删除,也就是向前删除光标前的一列,光标后的一列。
Liii STEM 支持自定义宏,以及从 中直接导入宏。以下指南将带您了解宏并掌握使用宏的方法。
1 什么是宏?
在数学公式编辑中,我们已经掌握了如何标注公式等。为什么要在已有的公式上再加一层标注呢?其中一个的原因是我们希望引入缩写来简化冗长的名称或复杂的符号,从而节省输入的时间。通过定义宏,我们也可以实现这一点。
- 宏(Macro)是一段我们根据自己的需求,预先录制的命令或代码片段,用来自动执行重复性任务。
再举个简单的例子。假设您在文章中需要多次提到 Southern University of Science and Technology ,那么您可以在 Liii STEM 中引入一个新的宏 sustech 作为以上五个单词的缩写,定义完成的宏可以重复使用,这大大减轻了您输入的压力。

2 宏使用的基本方法
创建一个宏
在菜单栏依次点击 工具 → 宏命令→ 新建宏 。

点击 enter-name ,输入您想定义的宏的 名称 。
在 enter-body 部分,输入宏的 内容 。
最后点击 使用→ 确认。

按 \ 进入命令模式,输入您定义的宏名称,敲击 回车 ,完成宏的创建与使用。
添加参数
打开 Macro editor 将面板左下角调至 数学 ,您可以定义数学类型的宏。

您还可以添加额外的 宏参数 ,从而在每次使用宏时,在参数位置能够输入不同的内容。例如,每次都可以更改上述图片中矩阵的符号 x 和 n 。具体方法如下。

定义现有的宏
Liii STEM 中有许多已定义的宏,您可以通过点击焦点(当前环境)工具栏的 Preference for tag → 编辑宏 打开 宏编辑器,进行个性化的定义。
如果您操作熟练或是需要编辑较为复杂的宏,推荐您使用以下两种方法,详见本指南第 4 章 。
- 将 Macro editor 面板左下角调至
源码来编辑宏。 - 在 导言区 内编辑宏,详见本指南第 3 章。
3 在导言区编辑宏
进入导言区
菜单栏点击 文档 → 部分 → 显示序言 。
或在 MacBook 中使用快捷键 Alt + Cmd + P,在 Windows 系统中可使用快捷键 Ctrl + Shift + P。

在导言区编辑宏
进入导言区后,您可以看到您此前创建的宏。
此时,您可以直接在导言区对其进行修改参数、名称以及内容等编辑操作。

在导言区创建宏
您在导言区也可以直接创建宏,具体如下。
进行上述操作后,会出现 <assign||> 字样,在第一个 | 后输入宏的名称,在第二个 | 后添加宏的内容。

一些常见的 tips:
- 定义参数时需要使用
macro命令(输入\+macro)将宏内容套起来,之后您可以使用Alt+→添加宏参数。 - 定义宏时,中间可以嵌套您已经定义好的宏。对于一些复杂的宏,如矩阵,您可以在输入
\+matrix后点击模式工具栏中的激活,此时可以展开宏等结构方便您快速编辑。

- 通过 math 命令(
\+math)可以进入数学模式编辑,进入数学模式后您可以调用一些在数学模式下可调用的宏。 - 通过导言区创建宏可以方便您使用
if等条件判断指令。
如下是一个通过导言区创建宏的示例,该宏实现了判断两个参数是否相等的功能:
bash
<assign|test-equal|<macro|arg1|arg2|msg|<if|<equal|arg1|arg2>|Same quantity:arg1|Not equal:msg>>>
4 从 中导入宏
我们支持从 直接导入宏,具体方法如下。

5 Mogan 样式语言
在上文中,我们列举了很多宏命令的例子,也介绍了您应该在导言区中创建和编辑宏,这一节的教您这些操作具体如何完成。
赋值
你可以使用 assign 原语永久更改环境变量的值,如下例所示:
bash
<assign|hi|<macro|Hi there!>>你也可以用with原语局部更改一个或多个环境变量的值:
bash
<with|font-series|bold|color|red|Bold red text>with原语也可以用于宏的局部重定义:
bash
<with|strong|<macro|body|<with|font-series|bold|color|red|body>>|<strong|strong> text>value原语用于检索环境变量的值,如下面的增加计数器的代码所示:
- 说明:赋值语句的左侧和环境变量的值都以绿色强调,宏参数通过棕色强调。
宏展开
普通宏使用以下方式定义:
bash
<assign|my-macro|<macro|x1|...|xn|body>>在这样的赋值之后,my-macro变成了一个具有n个参数的新原语,可以用以下方式调用:
bash
<my-macro|y1|...|yn>在宏的主体内部,可以用arg原语检索宏的参数值。注意,<arg|name>默认渲染成 name:
bash
<assign|hello|<macro|name|Hello name, you look nice today!>>渲染之后如图: 
调用的效果如图: 
可以在Hello后面写入参数。
可以使用比预期更少或者更多的参数调用宏。多余的参数将被忽略。缺少的参数取空值uninit原语:
bash
<assign|hey|
<macro|first|second|
<if|
<equal|second|?>|
Hey <arg|first>, you look lonely today...|
Hey <arg|first> and <arg|second>, you form a nice couple!>>>渲染后效果如图: 
调用的效果如图: 
允许将宏作为环境变量的值:
bash
<assign|my-macro-copy|my-macro>格式化原语
大多数 Mogan 的标签可以分为两个主要的分类:行内标签和块级标签。行内标签用于小段文本,而块级标签可以包含跨越多个段落的文本。例如,frac是一个典型的行内标签,而Theorem是一个典型的块级标签。有些标签(如strong)在其参数为行内时是行内的,否则是块级的。 最基本的行内标签和块级标签分别为:concat和document。分别用于行内连接和段落的垂直序列.
concat和document标签非常常见,他们的名称是默认隐藏的。
编写宏时,了解标签的行内或块级性质非常重要。因为块级标签在水平连接内的渲染方式不恰当。
- 如果你需要用行内的文本包围块级标签,那么必须用
surround原语:
bash
<assign|my-theorem|
<macro|body|
<surround|<no-indent><with|font-series|bold|Theorem. >|<right-flush>|
body>>>渲染后效果如图: 
调用的效果如图: 
有时你可能希望强制标签成为块级。例如:
bash
<assign|very-important|<macro|body|<with|font-series|bold|color|red|body>>>既可以作为行内标签使用,也可以作为块级环境使用。当光标放在with原语之前并按回车,你得到:
bash
<assign|very-important|
<macro|body|
<with|font-series|bold|color|red|
<document|body>>>>渲染后效果如图: 
调用的效果如图: 
标签的另一个重要属性是它们可以包含表格内容。例如,考虑eqnarray*:
bash
<assign|eqnarray*|
<macro|body|
<with|par-mode|center|mode|math|math-display|true|par-sep|0.45fn|
<surround|<no-page-break*><vspace*|0.5fn>|<vspace|0.5fn><no-indent*>|
<tformat|
<twith|table-hyphen|y>
<twith|table-width|1par>
<twith|table-min-cols|3>
<twith|table-max-cols|3>
<cwith|1|-1|1|1|cell-hpart|1>
<cwith|1|-1|-1|-1|cell-hpart|1>
body>>>>>surround的使用表明eqnarray*是一个块级环境,而tformat的使用指定它也是一个表格环境。此外,twith和cwith用于进一步的格式化信息。
此处可以简单的描述一下表格的标签结构。
基本表格结构标签
示例:
bash
<tabular|
<tformat|
<table|
<row|<cell|A1>|<cell|B1>>
<row|<cell|A2>|<cell|B2>>>>>渲染后效果如图: 
调用的效果如图: 
- 完整的表格语法:
bash
<tabular|
<tformat|
<!-- 表格级属性设置 -->
<twith|属性名|属性值>
<twith|属性名|属性值>
...
<!-- 单元格级属性设置 -->
<cwith|行范围|列范围|属性名|属性值>
<cwith|行范围|列范围|属性名|属性值>
...
<!-- 表格内容 -->
<table|
<row|<cell||>|<cell||>>|
<row|<cell||>|<cell||>>>>>想要了解更多底层语言,可参考:快速入门 Scheme。