本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点。本篇讲解 Markdown 在 Shadow Widget 中的应用。

Markdown 在 Shadow Widget 中的应用

Shadow Widget 中 Markdown 采用 John Gruber 的 Markdown 语法规则。由于 markdown 支持 <tag> 带标签的书写方式,我们就不必外寻特别的扩展方法,需要功能扩展的地方,都用 html 标签的形式解决。

Shadow Widget 不只用 markdown 表达文本段落,重要的是,它还用 markdown 实施界面编程。为达到这个目标,我们先对 John Gruber 的 markdown 语法做一点优化。

优化 markdown 语法

常规 markdown 语法都支持用 > 表达当前段落缩进一级。比如:

 > 这一段缩进一个级别。

 > > 这一段缩进两个级别。

这样的 markdown 文本在独立的 *.txt*.md 文件中书写没问题,但如果挪到 html 网页文件中,字母 '>' 会保存为转义格式 "&gt;"。所以,我们分析 markdown 语法时,要增加对 "&gt;" 表示缩进的兼容处理。

从更严格角度去看,字母 '>' 规则算得上一个 Bug,因为 markdown 要内置支持 <tag> 标签,就不该将 '<''>' 用作特殊语义标记,否则有损严谨性。

Shadow Widget 把转义标签也纳入到 markdown 文本内容中,需要以更严谨的方式表达缩进一级,我们引用 "::" 表示法,拿它替换 '>'。比如:

 :: 这一段缩进一个级别。

 :: :: 这一段缩进两个级别。

把转义标签嵌到 markdown 文本中

Markdown 语法支持 <tag> 标签,转义标签自然能用 markdown 书写,比如:

<pre $=MarkedDiv key='marked' width='{0.9999}'>### 嵌入描述界面的转义标签

<div $=P key='p' width='{0.9999}'>
<span $=Button key='test1'>test 1</span>
<span $=Button key='test2'>test 2</span>
</div> 本例在 markdown 文本定义了 **两个按钮** 界面。 ### 嵌入一个引用 <div key='pie' $='.body.auto1.pie_chart'></div> 在外部定义的构件(`.body.auto1.pie_chart`)将插入到 markdown 正文中使用。
</pre>

使用 markdown 的构件是 Div 类构件,在 markdown 嵌入转义标签的首层节点要求是 "非行内构件",Panel 类、Div 类、P 类均可。嵌入的由转义标签描述的界面,表现为一种 "段落",与 markdown 描述的各段落一起按顺序排列。上面例子生成的节点树如下:

    marked            // MarkedDiv
+-- markdown paragraph
+-- p // P
| +-- test1 // Button
| +-- test2 // Button
+-- markdown paragraph
+-- pie
+-- markdown paragraph

在 markdown 中嵌入转义标签,使 markdown 的表达能力变得异常强大,Shadow Widget 编程能表达的界面都能嵌进来。嵌入的转义标签甚至还可是 markdown 构件,层层嵌套,深度没有限制。

两个 markdown 基础类

Shadow Widget 内置提供 T.MarkedDivT.MarkedTable 两个最基础的 WTC 类定义,所有凡支持 markdown 的扩展 WTC 类都应从这两个基类开始继承。

在转义标签描述一个 markdown 节点,建议用 <pre> 标签,<div> 也管用,但用 <pre> 可以让 markdown 文本少些特殊字符被转义。<pre> 标签的内容,遇到 "<"">" 仍会转义,但用 <div> 表达时,如果内容有换行或嵌套的标签,会有麻烦。

所以,下面两种转义标签,我们选择第一种优于第二种:

<pre $=MarkedDiv>Hello, world</pre>
<div $=MarkedDiv>Hello, world</div>

MarkedDiv 常用来表达一维数据定义,MarkedTable 表达二维数据,行是一维,列是另一维。这两种构件都定义有 duals.nodes 属性,对于前者,用 comp.duals.nodes[n] 的方式提取由转义标签定义的各节点,对于后者,用 comp.duals.nodes[row][col] 提取第 row 行 col 列的经转义标签定义的节点。

markdown 兼顾了机器可读与人类可读的需求

Markdown 被设计出来,主要用来简化网页内容编辑的,许多用户(尤其是作家)并不熟悉 html 标签,让他使用 <p><table> 撰写文章会很困难,有了 Markdown 语法,普通人花 10 分钟学一下,就能编写具有漂亮界面的网文了。

Shadow Widget 继承 markdown 这个优势,同时,在不引入太复杂操作前提下,努力提升界面表现力。从原理上讲,markdown 可嵌入大部分 html 标签,如 <div>, <p>, <table> 等,表现复杂用户界面不是问题,问题是复杂的标签只有前端开发人员会用。现在 Shadow Widget 把界面设计可视化了,未经编程训练的普通人也能通过拖入样板创建组件,再修改组件属性来设计界面,所以,Shadow Widget 这项改进具有重大现实意义。

在 markdown 文本中嵌入特定界面,比如下面的直方统计图:

典型操作步骤如下:

  1. 在隐藏的胶片页(设计态仍可见)中,拖入直方图样板,创建一个组件,然后选中该组件,在 property 页修改属性,或点击浮动按钮配置特定属性。

  2. 为这个组件指定 key 值,然后点击 浮动按钮,拷贝对它的 "引用描述"。

  3. 在 markdown 内容编辑器中粘帖 "引用描述" 文本即可。

经过这几个步骤,直方图就嵌入到 markdown 文本中了。

Markdown 在 Shadow Widget 中应用广泛,就像 markdown 能简化文章写作一下,它一样简化编程中的界面设计。其表达形式对机器可读,同时,对开发人员也是易读易理解的,对它做修改直接改文本,很方便。

一个复杂些的例子

比如下面组件,点击左侧列表中的项目,右侧将展示相应页的内容(注:下面是图片,不能点击看交互效果)。

它的实现原理大致是,用如下 MarkedDiv 定义 item A/B/C 三项内容:

<pre $=MarkedDiv key="mark">
<pre $=MarkedDiv title="item A">Page A
</pre> <pre $=MarkedDiv title="item B">Page B
</pre> <pre $=MarkedDiv title="item C">Page C
</pre>
</pre>

然后用 $for="item in duals('./mark').nodes" 循环语句,取这 3 个 element 的 props.title 值显示到左侧列表,用 NavPanel 与 GroundPanel 构造可选导航页,各内容页同样用 $for="item in duals('./mark').nodes" 取得。

如果把这种界面做成样板,用户使用时,拖进来就创建一个组件,然后选中 key 为 mark 的 MarkedDiv 构件,点击 "edit markdown" 浮动按钮,然后在弹出的 markdown 编辑器中修改文本。这样,我们能很方便的创建同样式导航页界面。

(非正经入门系列至此完结,本文是最后一篇)


本专栏历史文章:

  1. 介绍一项让 React 可以与 Vue 抗衡的技术

  2. React 可视化开发工具 Shadow Widget 非正经入门(之一:React 三宗罪)

  3. React 可视化开发工具 Shadow Widget 非正经入门(之二:分离界面设计)

  4. React 可视化开发工具 Shadow Widget 非正经入门(之三:双源属性与数据驱动)

  5. React 可视化开发工具 Shadow Widget 非正经入门(之四:flux、mvc、mvvm)

  6. React 可视化开发工具 Shadow Widget 非正经入门(之五:指令式界面设计)

React 可视化开发工具 Shadow Widget 非正经入门(之六:markdown)的更多相关文章

  1. React 可视化开发工具 Shadow Widget 非正经入门(之五:指令式界面设计)

    本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点.本篇解释 Shadow Widget 中类 Vue 的控制指令,与指令式界面设计相关. 1. 指令式界面设计 Vue 与 A ...

  2. React 可视化开发工具 shadow-widget 的非可视开发方法

    Shadow Widget 提倡在可视设计器中开发用户界面,输出转义标签,而非 JSX.许多童鞋可能不知道 SW 同样支持用 JSX 设计界面,开发体验比原生 React 编程好出很多,本文就介绍这方 ...

  3. eclipseGUI的可视化开发工具插件

    一   各种GUI开发插件的特色 Eclipse并不自带GUI的可视化开发工具,那么如果要在Eclipse进行可视化的GUI开发,就需要依靠第三方的插件. 1. Visual Editor Eclip ...

  4. wxwidget wxpython 可视化开发工具

    wxwidget官方建议的工具集合:http://wiki.wxwidgets.org/Tools 支持wxpython可视化开发工具 wxFormBuilder wxGlade wxDesigner ...

  5. iOS程序员的React Native开发工具集

    本文整理了React Native iOS开发过程中有用的工具.服务.测试.库以及网站等. 工具 你可以选择不同的开发环境:DECO.EXPO或者你可以使用Nuclide+Atom,目前我使用EXPO ...

  6. React-Native(二):React Native开发工具vs code配置

    从网上翻阅了一些开发react-native的开发工具时,发现其实可选的工具还是比较多的Sublime Text,WebStrom,Atom+Nuclide,vs code 等.因为我用.net生态环 ...

  7. React Native开发工具Nuclide使用

    之前写RN的时候首选webstorm,这是之前做前端已经习惯的工具,其实RN开发官网推荐的是Nuclide工具, Nuclide是Fackbook专门为React开发IDE,今天也来尝试下,如果对we ...

  8. React等开发工具记录

    React Native :React 起源于 Facebook 的内部项目,结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生 ...

  9. React Native 开发工具篇

    正文 概述:开发RN的工具有很多,选择性也比较多,比如Facebook专门为React开发的IDE:Nuclide,还有做前端比较熟悉的WebStorm.Sublime Text 3.VS Code等 ...

随机推荐

  1. Java:Collections

    说明 工具类,提供了许多静态方法,用于操作集合. 模块:java.util.Collections 方法:全是static方法,使用时直接Collections.xxx( ... ) 返回值类型 方法 ...

  2. Python简单入门心得(一)

    很久之前就对Python感兴趣了,但是一直没时间学习,最近两天还有点时间,于是网上看了下视频,Python不愧是强类型的编程语言,对每一行的缩进的都有很严格的要求,比如一个判断,如果条件语句else不 ...

  3. 有关base64的作业

    1.有关Base64的介绍:Base64这个术语最初是在"MIME内容传输编码规范"中提出的.Base64不是一种加密算法,虽然编码后的字符串看起来有点加密的赶脚.它实际上是一种& ...

  4. JVM内存模型及GC机制

    一.JVM简介 1.1什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各 ...

  5. java的三大特性----封装、集成、多态

    当我们被问到你对java的封装.继承.多态是什么看法的时候,你会想到什么? 想到的会不会是封装就是将类的成员属性用privet修饰一下,达到私有化的目的,只暴露方法,从而达到成员变量私有化的目的. 而 ...

  6. LGP3281口胡

    当你看到一个东西的时候,GF 有可能比 DP 更方便.处理贡献也有可能比 DP 更方便. 这个题意明显是让我们计算 \(S(r)-S(l-1)\) 之类的东西( 所以直接考虑前缀的答案就好了( 考虑将 ...

  7. CF1278F题解

    这不是傻逼题吗?????? 考虑到第一张是王牌的概率为 \(\frac{1}{m}\),答案就是: \[\sum_{i=0}^n\binom{n}{i}(\frac{1}{m})^i(1-\frac{ ...

  8. 6月12日 python学习总结 框架

    1. 登录功能的实现 1. form表单提交数据的注意事项: 1. 是form不是from,必须要有method和action 2. 所有获取用户输入的表单标签要放在form表单里面,表单标签必须要有 ...

  9. 如果一个service服务出现异常,无响应,如何定位,定位过程

    假设一个service服务出现异常,要如何定位

  10. [SPDK/NVMe存储技术分析]011 - 内核态ib_post_send()源码剖析

    OFA定义了一组标准的Verbs,并在用户态提供了一个标准库libibverbs.例如将一个工作请求(WR)放置到发送队列的Verb API是ibv_post_send(), 但是在Linux内核,对 ...