WackoWiki Markup
其他语言 Deutsch[link1], Español[link2] and Русский[link3].这篇比较长的文章介绍了“Wacko 标记”是如何出现的,以及为什么它现在是这个样子的。如果你不知道什么是“Wacko 标记”,尤其是不清楚什么是“wiki”,你应该先到 WackoWiki 项目站点阅读几篇 documentation[link4] 的文章,特别是关于 wiki-concept[link5] 的那篇文章。
1. 关于 Wacko 标记
简而言之,Wacko 标记是一种特殊的文本格式化方式,它只需最少的特殊字符并尽量不破坏“源文本”的可读性,就能在程序转换后得到漂亮的 HTML。Wacko 标记的功能足以对大大小小的页面进行完整的排版。除了传统的“斜体”“粗体”“下划线”和“删除线”等修饰外,还有列表(包括多级列表)、标题、表格、图片、引用高亮等多种标记方式。
Wacko 标记用于 WackoWiki 引擎以及其他开发者的项目中。若要将 Wacko 标记嵌入你的项目,只需下载并集成以下组件:
- Wacko 格式化器[link6],一个将 Wacko 标记转换为 HTML 的 PHP 类;
- 可视化编辑器[link7],用于 wiki 的编辑器。该项为可选,但与 Wacko 格式化器结合使用非常方便。
本文的源文本采用 Wacko 标记格式撰写,可供查看[link8]。
2. 基本原则
尽管(我们是 WackoWiki 的作者、开发者)最初从 WakkaWiki[link9] 项目继承了 Wacko 标记(该项目此前位于 http://wakkawiki.de,现在已不可用),但我们是基于一组清晰的原则对其进行了发展,这些原则决定了它日后的成功。因此,标记规则的形成虽然是“进化式”的,但始终由少量原则引导,使得标记保持便捷与自然。
这些原则旨在实现以下目标:
- 降低“意外触发”的概率(即普通文本被误识别为标记);
- 实现直观且易于记忆的标记;
- 保护被格式化文本的环境,减少作者误输入造成的问题。
2.1. 语义应通过语法表达
任何 wiki 标记都基于“所想即所得”(WYTIWYG)的原则,因此每条 Wacko 标记规则都试图用自身的语法反映语义。由于整个排版是通过可在键盘上输入的简单文本符号完成的,我们尝试找到能够反映含义的组合:-
**bold**—— 用星号表示粗体,显得与周围文本“分离”; -
//italics//—— 斜体由 // 这种“编织线”表示; -
--strikethrough--与__underlining__分别表示删除线和下划线; - 列表的书写方式与我们在文本输入域中习惯写列表时很相似。
2.2. 成对字符
如你所见,上述所有实例都包含成对出现的字符。得益于这一原则,从其他编辑器“直接粘贴”的文本通常不需要特殊预处理——这样的文本很少会恰好包含成对字符。某些情形下会使用三连、四连乃至五六连字符来表示不同级别的标题。字符越多,标题层级越深。
2.3. 标记与内部文本接触
你可能是那种在键入破折号时总用“两个减号”写法(像这样:--)的人。无论如何,作者显然也属于这一类。而大量文本中既作为破折号又作为其他用途出现的双减号并不少见。“标记应与内部文本接触”的原则可避免将“普通文本”误转换为标记。并非所有标记规则都采用了这一原则,但对那些单个成对字符在“源代码”中有可能出现的标记(例如删除线)尤其重要。
例如:
--which is how it works-- 会产生删除线,而如果写成 -- we do so-- —— 文本就不会被识别为删除线。需要指出的是,本规则与前后规则的目标均是尽量减少标记处理的“意外触发”,即避免文本中的某些字符被误认为是标记的一部分。
2.4. 换行表示文本片段结束
与 OpenWiki 标记不同,Wacko 标记中“源代码”的换行被字面理解为换行(两个换行表示新段落)。因此,我们将换行视为某个完结文本片段(如一句话或一段)的结束。一些 Wacko 标记规则(如改变字体样式的规则:粗体、斜体、下划线等,以及标题)大多数仅作用于被换行限制的文本片段。采用该原则可以同时解决三类问题:
- 降低“意外触发”的概率;
- 简化对标记的理解(因为选区的“开始”和“结束”相距不远);
- 降低“字体样式”在长文本中的作用,使其主要用于小范围文本格式化——这有助于提升最终效果的可读性。
2.5. “损坏”的标记不应破坏周围的 HTML
上述原则使我们能解决一个很重要的问题——“保护”格式化文本周围的 HTML 不被可能的格式错误破坏。凭借“粘性”规则,我们几乎总能判定标记的“开始”和“结束”位置,从而一次性插入两个 HTML 标签(或根本不插入)。对于那些不易成对的 Wacko 标记规则,应尽力保证最终结果的“紧凑性”。事实证明,我们做到了这一点。2.6. 必须能准确写出我想写的内容
任何标记都应能“转义”,即让标记规则被忽略、文本片段原样通过格式化。这篇文章就是需要这种“转义”的典型例子。2.7. 尽量减少键盘布局切换
最后但同样重要的是,对于讲俄语的用户来说,这一原则在便利性上尤其关键(对英语用户也要兼顾)。原则要点是选择那些大多数(尤其是高频)规则可以在俄语输入布局下直接输入的字符组合,同时也要考虑对英语读者的可访问性。
因此,原始的引用语法
[[WikiLink Textual description]] 找到了对应的替代写法 ((WikiLink Text on link)),可在英文和俄文输入布局下使用。许多 wiki 标记规则都具备这一有益特性。3. 标记规则
在应用这些原则后,我们开发并改进了原有规则集,仔细研究了不同的 wiki 引擎。如果敢自夸,我会说最终的 wiki 标记融合了各类优秀规则,同时保持精简与简单。实际上,经过我们的努力,标记确实吸收了众多优秀规则,仍保持简洁。本章简要说明我们如何确立若干关键标记规则。
3.1. 单行标记
单行标记指那些使用在“普通文本”中常见符号、并用于文本局部排版的规则:- 粗体、斜体、下划线
- 小号 和
等宽文本 - 标题(与换行分割相关)
- 链接(其文本通常也应保持“简短”)
- 度数 和 上标/下标(仅在单词内有效)
3.2. 多行标记
其余标记规则作用于较长的文本片段,通常因为它们的语义和表现形式应用于大段文本。It's, like, astrikethrough.a quote that captures the entire paragraph.
Or
3.3. 标记取消
标记取消有两种实现方式:- 用“成对字符”进行块级取消
""; - 用转义符(在被取消序列前输入特殊字符)即波浪号
~。
如果你打开本篇文章的 !/source[link8],会发现标记取消非常常见——否则我们就无法展示未经处理的标记示例了。
3.4. 引用与图片
Wacko 标记会自动将文本中的 URL 转为超链接。如果可以明显判断某 URL 是图片(例如以 .jpg 或 .gif 结尾)——则使用 <img> 标签将图片插入到格式化后的文本中。这很方便,允许你直接从剪贴板插入链接并获得不错的结果。对于带说明的链接有两种常见写法:
-
((URL 说明文本)) -
[[URL 说明文本]]—— 功能相同,但不够方便 -
((Wiki Reference With Spaces == 说明文本))—— 允许在 wiki 链接的“左侧”包含空格(方括号写法也支持此功能)
Wiki Link Concept[link10] 使得插入站内链接更为简便,Wacko 标记也考虑到了这一点。所有非“站内”链接会被立即识别为“外部”链接,电子邮件地址亦同。
图片说明的写法与链接说明类似:
-
((picture.jpg 说明))用于设置图片标题 -
((URL small_picture.jpg))用于将图片作为链接插入
3.5. 列表结构
人们最自然地如何书写无序、有序以及嵌套列表?
|
你期望得到:
|
缩进选择为两个字符,基于“成对字符”原则,这种字符在普通文本中几乎不会出现。其他一些 wiki 格式使用五到六个空格——你可以想象在 <textarea> 中第三级嵌套会是什么样子!
c2.com 的原始做法使用制表符,但我们认为这不合理:在大多数界面中 Tab 用于导航,有些浏览器根本无法在输入域中输入制表符。
有序列表的编号会自动生成,这使得删除项目、添加新项或改变层级变得容易。如果需要一个从数字三开始的有序列表,可以这样写:
1.#3 Like this。- Like this.
3.6. 表格标记
表格是任何标记中最难处理的部分之一。最好的方案是一组模拟表格竖线网格的规则。这样比用连字符、加号和竖线绘制整个网格要简单,而且源代码仍然可读。关于表格标记的更多信息请参见 Wacko markup syntax[link11],其中有示例。遗憾的是,表格标记是 Wacko 标记中最“脆弱”的部分,在某些情况下可能破坏页面外部环境的结构。这是我们为语法清晰和解析速度所愿意付出的代价。
4. 标记的发展
首先,上文并未描述所有标记规则,仅列出最重要的。如有遗漏,请先查阅文档 ((/Doc/English/Formatting) 以获取更完整的说明)。如果现有规则不足以满足需求,则应扩展标记。大多数我们新增的规则正是如此产生的。4.1. 何时应更改现有标记?
永远不要。这里指的是在不引入新规则的前提下修改已有规则。更改已有标记的行为可能会严重打扰已经习惯该标记的人们。试想如果某些站点上
<b> 被当作 <a> 使用,反之亦然,那将多混乱。当然,如果某个项目内的某条规则确实极大地妨碍了你的工作,你可以考虑替换它。但在替换/移除规则时,要考虑熟悉标准标记的所有用户将如何接受这些变动!
4.2. 何时值得引入新的标记实体?
尽量少引入。Wacko 标记有“高亮器(highlighters)”的概念,它们是可插件式的实体,可以很容易地添加而不占用“主标记空间”——即成对字符。下文将描述高亮器的概念。
若未经充分考虑就新增成对字符,会让用户不得不重新记忆这些变化。正因为开发者对每条新规则的后果深思熟虑,用户才能无障碍地使用 Wacko 标记。
若你想扩展标记,最好联系该格式的作者——他们可能已有想法,或愿意采纳你的建议。协调一致的行动总是更有效。
5. 复杂转换与服务功能
Wacko 标记的设计思想(源自 WakkaWiki 并由作者扩展)提供了两种方式,可以显著增强标记能力并在页面中嵌入复杂功能。这两种方式是我们主要推荐给希望扩展标记规则的开发者的方式。此外,使用这些方法不需要深入解析 Wacko 格式化器的内部实现。
5.1. 高亮器的概念
“高亮器”是一个允许开发者实现复杂文本块转换逻辑的概念,并让用户方便地将该文本块以特定格式呈现的机制。在 Wacko 标记正文中,高亮器的使用形式如
%%(html)<div class="test">testdiv</div>...%% —— 即使用成对字符 %%,并在括号中指明将要对高亮块内容调用哪个高亮函数。开发者编写这些函数,函数接收一个文本变量,对其进行某些转换,然后返回结果。
通常此语法用于各种文本“着色”——用于语法高亮、聊天记录或电子邮件的标记、插入某些特殊文本块等。
该概念既是扩展标记的简单方式,也是:
- 无需使用额外“成对字符”的方式;
- 无需了解格式化器细节的方式。
5.2. Actions(动作)的概念
“动作”是一个允许开发者实现复杂功能(可能需要与用户交互),并允许用户在页面中合适位置便捷调用该功能的概念。在 Wacko 标记正文中,“动作”写法如
{{changes page="/Dev"}} —— 使用成对字符 {{,随后指定动作名及附加参数。开发者以与编写高亮器相同的方式编写这些函数。
在 WackoWiki 中,借助“动作”实现了大量与页面交互的功能(构建目录、列出最近更改/评论、搜索等)。
该概念允许在页面中“嵌入”复杂功能,而无需深入了解 Wacko 格式化器的实现细节。
5.3. Interwiki — 链接标记的扩展
还可以通过添加类似((repository:address)) 或 ((repository:address 链接文本)) 的规则来扩展链接语法。在此类写法中,地址由两部分组成:“存储”与“该存储中的名称”。例如,指向 LiveJournal[link12] 的地址可写为 ((lj:mendokusee)),若要指向英文单词的翻译,可写 ((lingvo:fascinating))。此概念(以及我们许多标记)继承自 wiki,最初用于指向其他 wiki 节点。我们发现它对其他用途也很有用。
当然,还有其它实现类似功能的方法。不同站点采用过下列标记格式:
-
[[ljuser romochka]](来源:http://ilyabirman.ru/meanwhile/wikihelp) -
[[xpointUser280 Vladimir Palant]](来源:http://xpoint.ru/help/formatting.xhtml) -
[[php ereg_replace]](来源:http://xpoint.ru/help/formatting.xhtml)
带冒号的 interwiki 变体(repository:address)在许多系统中被使用,已成事实上的标准,因此我们认为它更为正确。此外,interwiki 不会与常见的
[[Link Description]] 产生冲突。6. 技术细节
本文不是详细介绍 Wacko 格式化器[link6] 工作原理的场所,但有几点主要内容值得提及。首先,格式化器本身基于正则表达式(即兼容 Perl 的正则表达式)并采用“递归解析”原则。也就是说,它尝试将文本分解为“最大”的标记片段,然后对这些片段内部再次进行解析。这也意味着你不能嵌套使用相同的标记规则:例如,像这样
**example **nested** markup** 的写法无法工作。但你也会同意,这种嵌套通常并非必要。其次,格式化器为更好地防止“意外触发”而分多轮处理。第一轮是一组简化规则,用于“转义”文本片段,禁止对其进行标记。在同一轮中,所有“高亮器”会被识别并保护,从而防止高亮器与其他标记相互重叠。第二轮则处理其余规则。
第三,格式化器支持对格式化结果进行缓存。由于某些标记需与用户交互或链接到页面(不同用户可能有不同处理方式),因此缓存时会生成一个只包含链接与“动作”等相关规则的“半成品”结果。最后一轮格式化是最快的一次,不需要递归,在显示页面内容时基于该“半成品”完成链接标记和插入“动作”。
若你对格式化更深层次的细节感兴趣,欢迎查阅 代码格式[link6]。
7. 注意事项
本文旨在说明 Wacko 标记规则为何以及如何被发明,为什么会采用“成对字符”,并希望使用 Wacko 标记编辑格式的新项目能遵循其背后的原则。如有疑问,欢迎在评论中提出或直接联系本文作者。
此致敬意,WackoWiki 团队[link13] 及本文作者敬上。
- KusoMendokusee[link14]
- RomanIvanov[link15]
8. 参考资料
1. WackoWiki 项目[link16]2. Formatter[link6] 有关所述标记的说明
3. Visual Editor[link7] 有关所述标记的说明
2. WakkaWiki[link17] —— WackoWiki 的历史渊源
3. OpenWiki[link18] —— Wacko 标记语法的另一个历史渊源
4. Description of wiki concepts[link5]
5. Wacko-Markup Syntax[link11]
8. 经典标记示例[link19] (载于 c2.com)
9. WikiName[link10] —— 维基链接的概念
- [link1] https://wackowiki.org/doc/Doc/Deutsch/Markup
- [link2] https://wackowiki.org/doc/Doc/Español/Markup
- [link3] https://wackowiki.org/doc/Doc/Русский/Разметка
- [link4] https://wackowiki.org/doc/Doc/English
- [link5] https://wackowiki.org/doc/Doc/English/WikiConcept
- [link6] https://wackowiki.org/doc/Dev/Projects/WackoFormatter
- [link7] https://wackowiki.org/doc/Dev/Projects/WikiEdit
- [link8] https://wackowiki.org/doc/Doc/简体中文/Markup/source
- [link9] https://wackowiki.org/doc/Doc/English/WakkaWiki
- [link10] https://wackowiki.org/doc/Doc/English/WikiName
- [link11] https://wackowiki.org/doc/Doc/English/Formatting
- [link12] http://livejournal.com
- [link13] https://wackowiki.org/doc/Org/Team
- [link14] https://wackowiki.org/doc/Users?profile=KusoMendokusee
- [link15] https://wackowiki.org/doc/Users?profile=RomanIvanov
- [link16] https://wackowiki.org
- [link17] https://web.archive.org/web/20050211022800/http://www.wakkawiki.de/WakkaWiki
- [link18] https://web.archive.org/web/20060202001402/http://openwiki.com/
- [link19] https://c2.com/cgi/wiki?TextFormattingExamples