Richard Markup v4 帮助文档

来自个人维基
2021年6月23日 (三) 11:34的版本

(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转至: 导航搜索

Richard Markup是我设计的一门带逻辑和流程控制的文本标记语言。在v4的语法中,行首加|的是文本,不加的是逻辑,与v3正相反。

目录

基本语法

文件的开头是头部信息,记录了文件格式的版本:

<?richard-markup v4?>

随后是若干个“语句”。以|开头的语句是文本,运行时会直接输出它的内容,如:

|Hello, world!

不加|的行是块状逻辑,解释器会对它进行运算:

print 1 + 2

print语句会输出后面的内容。

还有一种行内逻辑,可以写在文本里:

|1 + 2 = {print 1+2}

这样会输出:

1 + 2 = 3

在行内逻辑里的print不会自动添加换行符,类似Python 3中给print()传了参数end=""。不过每一行“文本”的末尾会自动换行。

另一种语句是函数定义。函数可以写成这样:

def main:
    |Hello, world!

这是一个块状函数,在函数名后用冒号表示内容开始。与Python类似,Richard Markup v3使用缩进来表示代码块。

此外,还有一种行内函数,它只能有一行文本,写成这样:

def an_inline_function {|Hello, world!}

函数没有参数时可以省略函数名后的括号。关于参数的使用后文会讲到。

可以用#来表示注释,不过不能写在一行文本的末尾。

|Lorem ipsum dolor sit amet.
|这个不是注释:#Hashtag
# 一条没有用的注释
def foo: # 注释
    # 还是没有用的注释
    print 114514 # 臭块状逻辑
def bar {|sth} # 这里也可以注释

为了方便讲解,后文中的例子会省略头部信息。

字面量 变量

可以使用数字、布尔值、字符串、列表等字面量,写法与Python中一致:

print 1
print 1.25
print True
print False
print None
print "Hello, world!"
print '"Hello"'
print [1, 2, 3]

以上程序输出:

1
1.25
True
False
None
Hello, world!
"Hello"
[1, 2, 3]

仍然与Python类似,我们可以创建变量:

a = 114514
a += 1919810
print a

没有global语句;名称以$开头的变量都是全局变量。

def foo:
    $bar = 3
    baz = 4

$bar = 1
baz = 2
foo()
print $bar # 输出:3
print baz # 输出:2

文本字面量

有时我们还需要在逻辑中引用文本。文本和字符串是不同的,因为文本里面可以嵌入逻辑(禁止套娃!)。文本字面量{| ... }表示(类似行内函数):

def main:
    print {|Hello.}
    |Hello, {print {|Roy}}!
    print {|{print {|{print {|{print {|禁止套娃!}}}}}}}

输出:

Hello.
Hello, Roy!
禁止套娃!

直到文本被print时,它里面的逻辑才会执行。在这个例子中,文本被直接print出来了,跟直接写没什么区别。一般的用法是把文本赋值给变量,或作为参数传递。

a = {|Richard的XP系统是[数据删除]!}
print a
print a
print a
|重要的事情说三遍(迫真

运算符

Richard Markup v4中的运算符有(运算顺序由先到后):

  1. 索引和函数调用――a[b]a(...),左结合
  2. 乘方――a**b,右结合
  3. 正负――+a-a,右结合
  4. 乘除――a * ba / ba // ba % b,左结合
  5. 加减――a + ba - b,左结合
  6. 比较――a == ba < ba <= ba > ba >= ba != b,无结合律
  7. 逻辑非――not a,右结合
  8. 逻辑与――a and b,左结合
  9. 逻辑或――a or b,左结合
  10. 赋值――a = ba += ba -= ba *= ba /= ba //= ba %= ba **= b,右结合
  11. 逗号——a, b,左结合

除赋值和逗号外,这些运算符的用法都与Python相同,因此像1 < x < 2这样的连续比较运算是可以使用的。

赋值操作在Python中不是运算符,但在这里是。逗号运算a, b永远返回b,但a也会运行。因此可以:

a = 1, b = 2

这样就相当于:

a = 1
b = 2

但如果像Python那样写

a, b = 1, 2

效果会变成:

a
b = 1
2

赋值运算的返回值是修改后的值,因此我们可以:

a = b = 1

也就是

a = (b = 1)

这样相当于:

b = 1
a = b

不过,赋值运算的左手边依然只能是单个变量,不能是表达式。

函数参数

函数参数的写法与Python基本相同,只是没有参数的函数定义可以省略括号。

def function_with_parameter(param):
    # ...

通过给参数指定默认值可以把它变成一个可选参数,可选参数必需排在最后:

def function_with_parameters(param1, param2="默认值"):
    # ...

流程控制

在块状逻辑中,if――elif――else块这样表示:

if condition:
    sth
elif condition2:
    sth2
else:
    sth3

行内写法则是{if condition|text|else text},没有elif了,不过可以在else里再套一个if

也有forwhileRange函数的用法与Python里的range相同。

for i in Range(10):
    print i

i = 1
while i <= 10000000:
    print i
    i *= 2

|{for i in Range(10)|{print i} }

一个FizzBuzz程序:

for a in Range(1, 101):
    modThree = a % 3
    modFive = a % 5
if modThree != 0 && modFive != 0:
    print a
else:
    |{if modThree == 0|Fizz}{if modFive == 0|Buzz}

~特殊变量

通过给~color~bgcolor赋值,可以更改颜色:

~color="red", ~bgcolor="#114514"
|Hello, world!

使用这种方法,颜色设置会对整个当前一层缩进(包括当前一层缩进中包含的子缩进)生效。还可以用let手动制造一层缩进,使设置只对里面的文本生效:

|这行字是初始颜色
let ~color="red", ~bgcolor="white":
    |这行是白底红字
|这行又是初始颜色
let:
    ~color="red", ~bgcolor="white"
    |这样写也可以

如果需要用if决定不同颜色,建议创建一个临时变量来解决:

if condition:
    _color="blue"
else
    _color="red"
~color=_color

如果要对一行内的部分文字设置颜色,仍然可以用let

def main:
    |你好,我是{let ~color="#33bfab"|DGCK81LNN}。
    |{let|{~color="#33bfab"}这样}也可以

或者让颜色对这一行的其余部分都生效:

def main:
    |你好,{~color=white}世界!
    # “世界!”是白色

可用的特殊变量有:

属性 含义 可能的值 默认值
~color 字体颜色 0到15的整数,或CSS颜色值字符串 空字符串
~bgcolor 文字背景高亮颜色 0到15的整数,或CSS颜色值字符串 空字符串
~delay 每显示一个字符后延时的毫秒数 自然数 45
~pause 每显示一行后延时的毫秒数 自然数或None None

~pauseNone时,等待用户按任意键再继续。(也可以调用Pause()来手动等待按任意键。)

颜色为空或无法识别时,字体颜色默认为7,背景颜色默认为0。用整数表示颜色时依照:

含义 含义
0 "#000000" 8 "#555555"
1 "#0000aa" 9 "#5555ff"
2 "#00aa00" 10 "#55ff55"
3 "#00aaaa" 11 "#55ffff"
4 "#aa0000" 12 "#ff5555"
5 "#aa00aa" 13 "#ff55ff"
6 "#aaaa00" 14 "#ffff55"
7 "#aaaaaa" 15 "#ffffff"

内建函数

为了避免命名冲突,考虑到Richard Markup没有“类”的概念(Python中类名一般以大写字母开头),内建函数都以大写字母开头。很多内建函数的用途与Python中的同名函数相同,但原理不同。

函数名 用途
Int 转换成数字并向下取整
Float 转换成数字