V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
chingli
V2EX  ›  分享创造

InkMark,全新设计的一种轻量级的标记语言

  •  
  •   chingli · 2021-08-25 16:17:20 +08:00 · 3171 次点击
    这是一个创建于 974 天前的主题,其中的信息可能已经有所发展或是发生改变。

    去年 6 月的时候,我在这里说准备设计一种轻量级标记语言,当时反响一般,我想主要原因是那时我自己都还没有把要做的事情完全想明白。一晃一年多时间都过去了,终于写出这个标记语言的初稿,并将它叫做 InkMark

    相对于其他各种轻量级标记语言,InkMark 具有以下特性:

    • 具有几乎与 HTML 相匹配的文档内容描述能力。理论上来说,InkMark 可以表示 HTML 中所有类型的元素,以及为元素添加任意属性。
    • 很好地在简单和功能强大之间取得平衡。InkMark 的元素标记法包括完整模式和简写模式,其完整模式像 HTML 一样功能强大,而简写模式则像 Markdown 一样简单,且可以按统一的规则由完整模式过渡到简写模式。
    • 简写模式使用独特的“标记符号加方括号对接龙”形式的语法。例如,在其他轻量级标记语言中,常用 **着重强调** 表示要 着重强调 的文本,Inkmark 中却使用 *[着重强调] 达到同样的效果。
    • 能够用于科学技术报告、学术论文、书籍的书写。通常这些学术文档篇幅巨大,结构复杂,含有大量的图像、表格、公式和参考文献,需要对这些内容标注题注、自动编号,并在文档其他位置进行交叉引用和索引。
    • 具有灵活的文档组织能力。各个文档可独立编写和呈现,之后不必改变就可以合并在一起形成更长的主文档。无论是论坛帖子、博客文章、期刊论文、报告或书籍,其书写体验基本一致。
    • 注重语义的表述,不直接指定显示格式。如该语言关心你文本中的一行文字是普通段落、标题还是引文,但却不关心你的段落对齐方式,以及首行是否缩进等。
    • 尽可能保持语法的一致性和对称性。使用户能根据一定的规则来理解和学习其语法,避免产生歧义,降低语法学习和解析器实现的难度。
    • 良好的中文支持。其语法在换行、空格及标点处理,东西方文字混排等方面都更符合中文用户的使用习惯。
    • 当使用相对高级的功能时,所生成 HTML 文本的正确显示需要依赖特定的层叠样式表( CSS )甚至 JavaScript 代码。如通常要借助 MathJax 这类 JavaScript 数学显示引擎才能正确地显示文档中的公式,带编号公式的合理显示布局(通常公式和编号显示在同一行内,公式居中对齐,编号右对齐)也需要借助额外的 CSS 实现,而一些自定义类独有的显示方式也需要借助 CSS 实现。
    • 更加复杂。功能强大必然带来复杂性的提升,因此针对其全部功能的学习及解析器的实现将非常困难。InkMark 的复杂性主要表现于两种元素标记模式的融合共存,自动编号、引用、索引相关功能的实现,以及灵活的文档组织。

    InkMark 不像 Markdown 几乎为每种常用元素定义了简单且直观的标记方法,它很“死板”,几乎是为所有元素定义了相同的标记规则。因此 InkMark 不如 Markdown 那么直观,也不如 Markdown 那样特别适合编写程序开发文档。但 InkMark 的标记规则相对更容易学习,并且其表达能力要强得多。其元素内容的边界范围也更加明确,不容易产生歧义。当只使用常用的标记功能时,它几乎和 Markdown 一样简单。

    和 HTML 相比,InkMark 的完整模式几乎具有和 HTML 相匹配的描述能力,但元素边界不如 HTML 那样通过起始和结束标签项明晰标示。而 InkMark 的简写模式则要比 HTML 简单得多,适合手工书写,且源代码也更易读。InkMark 能做到在完整模式和简单模式间无缝切换,很好地在简单和功能强大间取得了平衡;不过两者进行切换的规则需要额外的学习成本。另外,针对学术文档的书写这一特殊目的,InkMark 通过加入一些自定义元素大大增强了其表达能力。

    相对于 LaTeX 这种专业的学术论文排版系统,InkMark 主要专注于为文本添加常用的结构和语义,而其他更多的功能,如文本和页面样式,则大多交给其他程序(如和网页关联的层叠样式表 CSS )来完成。因此,其功能要远远少于 LaTeX,但也简单得多。


    目前我只是用 HTML 格式写了一个长长的文档,真的是很长很长的一个文档,干这个事的难度比我预想的大多了。暂时先把这个文档发布在我的博客上:

    InkMark:一种轻量级的标记语言

    这么长的文档,里面肯定有表述错误,请大家不吝指出!

    我自己没有精力编写该语言的解析器,我只是先把这个文档放出来,看看大家的反馈。如果反响不错,将会进一步投入精力,并希望能有更多的人参与这项工作。

    期待大家的讨论,谢谢!

    第 1 条附言  ·  2021-08-25 17:03:14 +08:00

    我自己也拿不准:我究竟是设计了一个怪胎,还是一个简单强大的标记语言。

    因为我自己对这些规则很熟悉,用 InkMark 替代 Markdown 写学术类的内容,真的是舒服太多了。但对于其他人,要掌握起来恐怕还是不容易。

    因此,如果将来写 InkMark 的帮助文档,肯定不能像我现在设计 InkMark 写的文档这样,而是应该从简单到复杂逐渐讲起。比如,分 5 级,当别人学会以后,分别告诉对方你入门了、小成了、变成熟练工了、成为大师了、无敌至尊了——举个庸俗的例子而已。

    第 2 条附言  ·  2021-08-25 17:50:52 +08:00

    以下是一些示例:

    段落就是直接写,用空行分割的文字。
    
    换行直接用回车就行了:
    
    远远的街灯明了,
    好像闪着无数的明星。
    天上的明星现了,
    好像点着无数的街灯。
    
    标题用 = 标记而不是 #:
    
    = 一级标题
    == 二级标题
    
    行内元素标记:*[着重强调]、/[强调]、-[删除]、+[插入]、`[代码]、?[注释]、^[上标]、_[下标]。
    
    链接:@[V2EX][https://www.v2ex.com/]
    
    * 无序列表项 1
    * 无序列表项 2
    / 无序列表项 2 中的第二个段落
    * 无序列表项 3
        ** 无序列表项 3-1
        ** 无序列表项 3-2
    
    代码:
    
    ` [
    package main
    
    import "fmt"
    
    func main() {
    	fmt.Printf("Hello, 世界!\n")
    }
    ] [Go]
    
    自动编号的参考文献:
    
    #[张三, 李四, 王老五, 等. 示例文章标题 [J]. 示例期刊名称, 2021, 33(8): 335-341.][reference][number="[{{#}}]"][template="^[ {{#}} ]"]
    
    以上文献将显示为 [2] 的形式。
    
    引用以上自动编号:#[label="编号标签"][ref="reference"][template="{{#}}"]
    
    内部具有一个图像、一个图像标题、一段图像描述文字的图像框:
    
    & [src="https://inkmark.org/path/to/picture.png"][caption="图像标题"][alt="替换文字"][description="用一个段落对图像信息进行描述。"]
    
    最简单形式的带标题带编号的表格:
    
    ++ [
    -! 第 1 行第 1 列 ! 第 1 行第 2 列 ! 第 1 行第 3 列
    -! 第 2 行第 1 列 | 第 2 行第 2 列 | 第 2 行第 3 列
    -! 第 3 行第 1 列 | 第 3 行第 2 列 | 第 3 行第 3 列
    ][表格标题][label="table"][number="表 {{=}}.{{#}}"]
    
    
    第 3 条附言  ·  2021-08-26 09:09:13 +08:00

    我又写了个 InkMark 简介,这次是从简单到复杂逐步进阶介绍的:

    https://chingli.com/coding/inkmark-a-brief-introduction/

    33 条回复    2021-09-06 13:40:20 +08:00
    renmu123
        1
    renmu123  
       2021-08-25 16:30:47 +08:00 via Android
    我觉得你是什么都想要,既想要 md 的简洁,也想要 html 的表达力,也想要 latex 的排版。贪多嚼不烂啊,很难把握好这三者之间的度,你要考虑好可能得受众群体
    humpy
        2
    humpy  
       2021-08-25 16:37:58 +08:00
    既然方括号在你的语言里这么重要,不如叫 BracketMark 😜
    chingli
        3
    chingli  
    OP
       2021-08-25 16:50:22 +08:00
    @renmu123 我主要是在 Markdown 和 HTML 之间取得平衡,的确很难把握。但我现在的构想已经做到了:写简单文档时,真的就像 Markdown 一样简单,其规则甚至比 Markdown 还简单(但不如 Markdown 美观);随着需求的增加,慢慢去了解一些更复杂的功能,发现还是可以做到。

    @humpy 淘气,你说的这个名字不好听。
    oott123
        4
    oott123  
       2021-08-25 17:35:45 +08:00 via Android
    是有点怪。我个人感觉这玩意更适合当某种模板引擎,去和 pug 竞争,而非文档领域。另外我觉得你应该直接贴一些示例出来,翻了半天才看到示例。
    stimw
        5
    stimw  
       2021-08-25 17:44:19 +08:00 via Android
    我觉得写英语文档在英语社区推广,比在中文社区推广容易得多。
    chingli
        6
    chingli  
    OP
       2021-08-25 17:51:31 +08:00
    @oott123 是的。应该弄个简单的例子。我附加了一点点。
    chingli
        7
    chingli  
    OP
       2021-08-25 17:59:00 +08:00   ❤️ 1
    @stimw 嗯,的确。因为我暂时没有精力写一个入门介绍文档,导致很多人都不会仔细去看和推敲。

    不过写个中文文档都耗费了很大精力,写英文就更难了。因为要考虑很多细节,感觉这个东西比做个博士论文还累。
    Kilerd
        8
    Kilerd  
       2021-08-25 18:36:25 +08:00
    太复杂了。 简单的用 md,复杂的我肯定就直接上 latex 了
    eason1874
        9
    eason1874  
       2021-08-25 18:44:56 +08:00   ❤️ 2
    乖乖,跳过前言直接看示例,看了几分钟才发现滚动条还在上面,全部得有五六万字,认真看完都得一小时了吧。

    轻量级应用是不需要说明设计思想的,只需要使用说明和示例。轻不轻,用户能直观感受到。

    Markup 重语义,Markdown 重阅读,你是什么都重。看样子是思考了很多,但是还没有确定侧重点,做不了取舍,于是做出来一个大杂烩。

    你要是想做偏学术类的轻量级标记语言,建议直接继承 Markdown 通用语法,把设计重点放在学术表达的部分。
    namelosw
        10
    namelosw  
       2021-08-25 18:50:00 +08:00
    我感觉 Markdown 作为轻量标记其实已经很不错了,唯一的明显缺点就是标准混乱且解析有歧义

    如果不考虑轻量标记的话,Markdown 最大的问题是很多元素不能很好地自我嵌套。

    不过一旦有自我嵌套就会啰嗦一些,不然是括号眼晕打着麻烦,不然是缩进容易写错。
    Tink
        11
    Tink  
       2021-08-25 18:51:56 +08:00 via Android
    主要是得有人用
    chingli
        12
    chingli  
    OP
       2021-08-25 20:15:19 +08:00
    @Kilerd LaTeX 比这个复杂多了,我认为有点不适合现代的面向 Web 的写作。

    @eason1874
    这个也没有太复杂,主要是我确实是从设计思想的角度写了比较多,没有从初学者的角度写。

    学术写作还是比较复杂的,面对复杂的问题,也往往只能有复杂的解决方案。

    可以看看 CommonMark 的规范,如果用 Chrome 的打印功能,A4 纸默认样式下也要 114 页了,我这个才写了 71 页。

    @namelosw 真要写复杂的学术内容,Markdown 还是差很远,并且好多都是系统性的问题,改不动啊。

    V2EX 的用户大部分都是搞编程开发的,对复杂的学术文档的写作需求的理解并不是很清晰。看来我的确需要从初学者的角度再写一个文档,这样才能让大家明白我究竟想怎么做。
    namelosw
        13
    namelosw  
       2021-08-25 21:00:24 +08:00
    @chingli 我能理解你的这个定位。LaTeX 重得有点没必要,Markdown 有时候不太够用。

    Markup 主要分两种,一种是偏读写的,一种是偏结构的。

    Markdown 的问题:
    1. 偏读写:缺少结构,我看你主要靠 [] 嵌套解决这个问题。
    2. 不太够用:应该提高扩展性而非功能,我看你有类似 directive 一样的东西来增加扩展性。

    不过有个问题是全靠 <></> 或者 [] () 之类的的元素,就会写起来比较不爽。如果觉得不会不爽的话,其实 LISP 就已经是最好的 Markup 了。如果像 Markdown 一样不靠 [] () 嵌套,一方面表现力下降,另外一方面需要减少符号,比如 & 很常用,如果作为特殊符号就要经常转义。个人感觉缩进可能是一个比较好的折中方案,只是不知道非程序员是不是很容易把缩进搞混(虽然很多人抱怨缩进,但是我就没见过 Python 程序员日常会把缩进搞混的)。

    我看你好像不是 IT 人员,可以推荐几个值得参考的 markup ( just in case 你没看到这几个竞品):

    1. Jade:一个模板语言,更像 HTML,用的缩进形式。https://jade-lang.com/

    2. reStructuredText:Python 社区很常用,主观感受流行度可能仅次于 Markdown 。https://docutils.sourceforge.io/rst.html

    3. Org Mode:Emacs 内置的 markup,用户很多,扩展也很多,除了当 markup 之外更多做 GTD,日程管理,有时候还会当简单的 Excel 用等等。GitHub 除了支持 Markdown 之外其实也支持 Org 。https://orgmode.org/

    4. Scribble:Racket 社区的通用 markup,本质上是 Racket 的一个库 /语言,因为是 LISP 所以扩展性很强。https://docs.racket-lang.org/scribble/

    5. MDX:这个不太算 markup,本质上是一个 Markdown + JSX 预处理器,但是这样其实就相当于 Markdown + React,那么威力一下就提高了。不过 Markdown 和 JSX 之间其实结合的并不好,很多时候从 JSX 里面套回 Markdown 虽然可行但很别扭(不过这个是 Markdown 的问题,用了 HTML 里面就不能再用 Markdown 了)。https://mdxjs.com/
    AX5N
        14
    AX5N  
       2021-08-26 02:37:15 +08:00
    感觉设计得挺烂的,而且连解析器都没有,你是不是从来就没用过?如果你自己都没用过,那你怎么知道你设计的东西哪里有问题,哪里可以妥协,哪里不能妥协?你先拿你这个 mark 去把各种类型的文档都写几遍,凑个万把字再说吧。

    (我用我自己设计的标记语言写过几十万字(2Mb)的内容)
    GiantHard
        15
    GiantHard  
       2021-08-26 08:38:25 +08:00 via Android
    感觉你这个 markup 的定位有点类似 asciidoctor
    chingli
        16
    chingli  
    OP
       2021-08-26 09:06:18 +08:00
    @namelosw 你都说到点子上了。我设计的这个东西的确解决了你所说的 Markdown 的两个问题,但太多的方括号使其看起来有点丑陋。

    我现在只是部分解决了方括号过多导致丑陋的问题,就是规定若块级元素只占一行时,可以不写方括号。另外,当列表项元素包含多个段落时,也可以通过使用斜线表示的接力棒 / 标记而不使用方括号。

    虽然用方括号很丑陋,但是针对我想解决的问题,我找不出更好的方法。比如,学术文档中往往一个表格单元格内还包括多个段落,我找不出除了用括号外能更好地包括这多个段落的方法。另外,我也找不出不使用括号而给元素添加属性的好方法——为元素添加属性在实现复杂的功能时真的很有用。用括号还有一个好处,就是元素内容的边界清晰,学术内容可能包含各种标点符号,像常规的用 *强调* 形式的标记方法,很可能和内容中的乘号相混淆。

    Markdown 中的缩进规则是比较复杂的,我觉得除了程序开发人员,其他人员对多少个空格根本不敏感。我常常给学生们改 Word 论文,其中存在太多的胡乱用空格的情况。甚至好多时候,文档中多出一些空格他们都会视而不见。因此,我从最初的设计时,就排除了利用行首和行尾水平空白作为标记的方式,即完全忽略标记内容开始和结尾的空白。

    我也看了许多已有的标记语言(但没有全部看完),都不如 Markdown 那样简单明了。大多数标记语言大都针对每个元素类型设计了独特的标记规则,标记方法太多,不好记忆,在 InkMark 中也不够用。我这里力求规则一致。但这个文档看起来仍然复杂,主要是因为自动编号元素有点复杂了(其中的 number 和 template 属性看起来有点像模板语言),以及对属性的支持使得格式有点凌乱。

    另外,我在设计时,也并不是一直想着要简单。因为复杂的问题往往必然只能有复杂的解决方法。看看 MediaWiki 的标记语法,虽然基本语法比较简单,但完全不够用,必须配合使用 HTML 以及模板,大多数维基页面都充斥着这些复杂的混合标记。所以我不如一开始就把一些功能设计得稍微复杂一点,可扩展性强一点。当然,我现暂时在还不敢往里面加模板功能,那样就太复杂了。

    对于非编程开发人员,我现在第一担心的是他们能不能分清行内元素和块级元素,而我设计的这个标记语法在进行标记时,必须首先能区分这两类元素。
    chingli
        17
    chingli  
    OP
       2021-08-26 09:07:17 +08:00
    @AX5N 请不吝指出问题。

    这么复杂的一个东西,我若不是思考及实践很久,是弄不出来的。我现在是把整个思考过程都清晰地写出来了,这并不容易。我自己也用这个语言记笔记,期间对其设计语法作出了很多改进。但只要持续思考,就必然仍有很多改进的空间。我的确没有写出其解析器,我没有精力,并且也不是应该首先做的事情。

    您既然设计过同类的语言,肯定很容易看出这个东西的缺点。我把这个东西放这里就是找别人批评的,很期待你的详细点评,不过还是应该以和我同样的设计出发点,即写作复杂的学术文档的角度来进行评价。
    tysb777
        18
    tysb777  
       2021-08-26 10:01:55 +08:00
    支持一下
    2i2Re2PLMaDnghL
        19
    2i2Re2PLMaDnghL  
       2021-08-26 15:23:26 +08:00
    这是不是不能在代码块中写那些方括号不对称的语言?
    或者说,能不能写这一段代码?

    `[
    s.find("]")
    ][Python]

    写学术类的内容,pfm 挺好的
    chingli
        20
    chingli  
    OP
       2021-08-26 15:50:11 +08:00
    @2i2Re2PLMaDnghL 嗯,的确存在这个问题。目前的做法是对方括号进行转义。Markdown 中 `s.find("`")` 似乎也存在同样的问题,无解啊。

    BTW: pfm 是什么啊?
    2i2Re2PLMaDnghL
        21
    2i2Re2PLMaDnghL  
       2021-08-26 15:57:52 +08:00
    @chingli pandoc-flavored markdown
    我记得哪个 markdown 分支是可以 ``s.find("`")`` 来绕过的,可以无限叠加,只会匹配相同数量的。
    而对于里面恰好是一个 js template 那种,也可以 `` `12+34=${12+34}` `` 这样前后各加 1 个空格,会抹掉这两个空格。
    chingli
        22
    chingli  
    OP
       2021-08-26 16:07:07 +08:00
    @2i2Re2PLMaDnghL 我原来也是想着在 InkMark 中可选性地允许多层方括号,但要求左右两侧的方括号数目必须相等,这样可以规避该问题。例如:

    ` [[
    s.find("]")
    ]][Python]

    后来觉得规则太多,就没有用。现在其实还是应该考虑一下这个规则。
    henryhu
        23
    henryhu  
       2021-08-26 16:18:27 +08:00
    tldr
    zjm947373
        24
    zjm947373  
       2021-08-26 17:29:52 +08:00
    😃一般这种事情被大多数人不看好的地方,其实不是一个东西的设计是否优秀,而是很多人只停留在设计上面,匆匆地宣布自己设计了什么,应该反过来先基于这种标记语言做一个非常好用的、优秀的编辑器 /记事本软件等,再回头来吹自己所设计的语言不迟
    chingli
        25
    chingli  
    OP
       2021-08-26 22:55:53 +08:00
    @zjm947373 有道理!
    leokino
        26
    leokino  
       2021-08-27 04:06:17 +08:00
    如果没有形成 Specification,没有写 reference parser,这个工作其实还非常早期。
    leokino
        27
    leokino  
       2021-08-27 04:13:35 +08:00
    作者对于[][]部分元素渲染的构思以及表格的展示还是很有创意的,但是其他部分略显多余,包括对其他 @链接元素的定义。这个标准独立存在的可能性不大,作者可以将上述两部分抽离出来,作为 Markdown 的插件实现,前景会更好一点。
    chingli
        28
    chingli  
    OP
       2021-08-27 09:17:00 +08:00
    @leokino 作者对于[][]部分元素渲染的构思以及表格的展示还是很有创意的。乱码了,不知道你写的“[][]”是什么。
    leokino
        29
    leokino  
       2021-08-27 10:59:15 +08:00
    @chingli 就是用 [=div][] 的形式表记 html 的想法。
    yakun4566
        30
    yakun4566  
       2021-08-27 15:05:14 +08:00
    别发了,学不动了 /:doge
    althoughghgh
        31
    althoughghgh  
       2021-08-27 18:24:20 +08:00
    和 asciidoc 很像,它可以自定义扩展,加入自己的符号,输出的 html 也是可定制,模块化的
    给主流语言写 parser 很困难把,另外还得弄个编辑器,不然也没人用
    chingli
        32
    chingli  
    OP
       2021-08-29 10:12:28 +08:00
    我准备再如下几方面改进:

    1. 原来设定完全不用行首的水平空白作为标记,现在放弃这样做。许多时候,行首空白还是很有用的,适当利用行首空白进行标记能使文档更加美观。
    2. 进一步多参考 Markdown 以及其他标记语言的优点,让显示效果更漂亮一点。
    3. 想办法简化自动编号、图、表、公式、参考文献的表达,但还是想办法保留对编号的各种设置,毕竟这个东西真的很有用。
    4. 设法使文档书写过程中基本可以不用转义。
    5. 改个名字!

    不过,还是要保留目前这种方括号对接龙的标记语法(只是对部分块级元素,可以通过简化而不写方括号),以及对额外的元素类型、属性的支持,从而使其具有与 HTML 相匹配的表达能力。毕竟,如果不这样,就没有存在的必要了。

    谢谢各位!
    sccbhxc
        33
    sccbhxc  
       2021-09-06 13:40:20 +08:00
    楼主加油
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1317 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 17:48 · PVG 01:48 · LAX 10:48 · JFK 13:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.