【Typst】3.Typst脚本语法

article/2025/6/7 1:11:05

概述

Typst的核心就是它在标记语法的基础上提供了一个灵活强大的脚本语言,来支持复杂的排版操作。

本节就以一个脚本语言的角度,介绍一下Typst脚本的核心语法。

系列目录

  • 1.Typst概述
  • 2.Typst标记语法和基础样式
  • 3.Typst脚本语法
  • 4.导入、包含和读取
  • 5.文档结构元素与函数
  • 6.布局函数

字面量

// 字面量
#(2)         // 整型字面量
#(3.14)      // 浮点型字面量
#("你好")    // 字符串字面量
#(true)      // 布尔类型字面量
#(none)      // 空字面量

类型判断

// 类型判断
#type(12)                 \ // int
#type(12.5)               \ // float
#type(1>2)                \ // bool
#type("hello")            \ // str
#type(<glacier>)          \ // label
#type([Hi])               \ // content
#type(x => x + 1)         \ // function
#type(type)               \ // type
#type(datetime.today())   \ // datetime

表达式

// 表达式
1+2*5 = #(1+2*5)  // 1+2*5 = 11
#(1==2)           // false

变量和函数

// 变量
#let a = 12    // 申明
#a // 12       // 使用// 函数
#let add(a,b) = [#(a+b)]    // 定义
#add(12,45) // 57           // 调用#{let str1 = [张三]let str2 = [你好]str1 + str2
}

控制语句

#for i in range(30,100) {box(str(i),fill:blue) + " " + str.from-unicode(i) + "\n"}

注释

// 单行注释
/*
多行注释
*/

数字

Typst包含两种数字类型,整型integer和浮点型float:

  • 整型integer:代表整数,可以是负数、零或正数。 由于 Typst 使用 64 位来存储整数,整数不能小于 -9223372036854775808 或大于 9223372036854775807
  • 浮点型float:一个实数的有限精度表示。Typst 使用 64 位来存储浮点数。

数字进制和科学计算法

// 数字进制
#(100)    // 十进制100
#(0xFF)   // 十六进制 = 255
#(0o77)   // 八进制 = 63
#(0b11)   // 二进制 = 3
// 科学计数法
#(6e2)     // 600
#(2.3e5)   // 230000

计算函数库calc

计算232的值:

#(calc.pow(2,32))

字符串

字符串可以看做是由若干字符按顺序组成的字符数组。

所有长度和索引都以 UTF-8 字符为单位。 索引从零开始,负索引会回到字符串的末尾。

string{len() -> integer   // 字符串在UTF-8编码字节中的长度first() -> any     // 返回字符串中第一个字符last() -> any      // 返回字符串中最后一个字符at(                // 返回定索引位置的字符index:int,           // 索引default: any,         // 超出索引范围后返回的默认值) -> anyslice(             // 截取子字符串start:integer,end:integer,count: integer,) -> stringclusters() -> array    // 返回单个字符组成的数组codepoints() -> array  // 返回单个字符Unicode码组成的数组contains(pattern:string/regex) -> boolean  //判断字符串是否包含指定的模式starts-with(pattern:string/regex) -> boolean //判断字符串是否以指定的模式开始ends-with(pattern:string/regex) -> boolean //判断字符串是否以指定的模式结尾find(pattern:string/regex) -> string/none // 在字符串中搜索指定的模式,并以字符串形式返回第一个匹配项,如果没有匹配项,则返回 none。position(pattern:string/regex) -> integer/none //在字符串中搜索指定的模式,并返回第一个匹配项的索引,如果没有匹配项则返回 none。match(pattern:string/regex) -> dictionary/none //在字符串中搜索指定的模式,并返回一个包含第一个匹配项详细信息的字典,如果没有匹配项则返回 none。matches(pattern:string/regex) -> array  在字符串中搜索指定的模式,并返回一个包含所有匹配项详细信息的字典数组value.replace(                  // 查找并替换匹配的字符串pattern:string/regex,          // 查找的字符串或模式replacement:string/function,   // 替换的内容或处理函数count: integer,                // 替换指定的前几项) -> stringtrim(    // 从字符串的一侧或两侧移除匹配模式的内容,并返回替换结果pattern:string/regex,          // 查找的字符串或模式at: alignment,                // 可以使用 start 或 end 来仅修剪字符串的开头或结尾。如果省略,则会修剪字符串的两侧。repeat: boolean,              //决定是重复移除模式的匹配项还是只移除一次。默认为 true。) -> stringsplit(pattern:string/regex) -> array  // 按字符串或模式进行切分,返回数组
}

其中,match()matches()方法的字典形式:

(start: int,   // 匹配项的起始偏移量end:int,      // 匹配项的结束偏移量text: string  // 匹配的文本captures: array // 包含每个匹配的捕获组的字符串。 数组的第一项包含第一个匹配的捕获组,而不是整个匹配!除非 pattern 是带有捕获组的正则表达式,否则此项为空。
)

转义字符

// 转义字符
#("\"")    // "
#("\\")    // \
#("\n")    // 换行
#("\r")    // 回车
#("\t")    // 制表符
#("\u{2665}")    // unicode字符 ❤

基础用法

#("这是字符串")             // 这是字符串#("这是字符串" + "2")       //  这是字符串2
#("这是字符串" + 2)         //  【报错】
#("这是字符串" + str(2))    //这是字符串2#("这是字符串," * 2)  //  这是字符串,这是字符串,#let str1 = "这是字符串"#str1.len()      // 15
#("123".len())   // 3
#("abc".len())   // 3#str1.at(0)      // 这#str1.clusters()   // ("这", "是", "字", "符", "串")
#str1.codepoints() // ("这", "是", "字", "符", "串")#(
"
第一行
第二行
第三行
".split("\r\n")
)  // ("","第一行","第二行","第三行","")

特殊符号和表情符号

Typst提供了symemoji两个模块来辅助特殊字符和表情符号的书写。

#sym.eq         // 等于
#sym.eq.not     // 不等于#sym.gt         // 大于
#sym.gt.eq      // 大于等于
#sym.gt.eq.not  // 不大于等于#sym.lt         // 小于
#sym.lt.eq      // 小于等于
#sym.lt.eq.not  // 不小于等于

对于等于、大于、小于的缩写理解和记忆:

大于   greater than   //gt
小于   less than      //lt
等于   equal to       //eq
#emoji.a
#emoji.alien#emoji.face
#emoji.face.angry
#emoji.face.clown

// 单箭头
#sym.arrow
#sym.arrow.l
#sym.arrow.r
#sym.arrow.t
#sym.arrow.b// 帽子
#sym.arrowhead
#sym.arrowhead.t
#sym.arrowhead.b// 多箭头
#sym.arrows
#sym.arrows.ll
#sym.arrows.lll

数组和字典

数组

以下是Typst数组类型及其所有方法的总结:

array{len() -> int       // 数组的长度first() -> any     // 返回数组中的第一项last() -> any      // 返回数组中的最后一项at(                // 返回数组中指定索引位置的项int,           // 索引default: any,      // 默认值) -> anypush(any)          // 在数组末尾添加一个值。pop() -> any       // 从数组中移除并返回最后一个项value.insert(      // 在数组的指定索引位置插入一个值int,               // 插入位置any,               // 要插入的内容)remove(int) -> any   // 删除指定位置的值并返回value.slice(         // 获取数组的切片start:int,          // 起始索引(包括在内)end:int,            // 结束索引(不包括在内)count: inte,        // 要提取的项数。) -> arraycontains(any) -> boolean  //判断数组是否包含指定的值/*-- 搜索 --*/ // 搜索给定函数find(function) -> any/none     // 返回true的第一项position(function) -> int/none // 返回true的第一项的索引filter(function) -> array      // 返回true元素的新数组map(function) -> array         // 对所有元素操作后的新数组enumerate() -> array           // 返回(index,value)形式数组zip(array) -> array            // 合并数组fold(        // 使用累加器函数将所有项折叠成一个单一的值。  init:any,         // 初始值folder:function,  // 折叠函数) -> anysum(default:any) -> any      // 所有项求和(累加)product(default:any) -> any  // 累乘any(function) -> boolean     // 数组中任意一项满足函数条件all(function) -> boolean     // 数组中所有项满足函数条件flatten() -> array     //将所有嵌套数组合并为一个扁平的数组rev() -> array         // 返回逆序的新数组join(  // 将数组中的所有项合并为一个项separator:any,    // 分隔符last: any,         // 最后两项之间的替代分隔符) -> anysorted(function) -> array   // 按函数规则排序后的数组
}

数组的基础用法

数组用括号包裹,以逗号分隔:

// 数组
#(1,2,3)                  // (1,2,3)
#("你好",12,[这里是内容])  // ("你好",12,[这里是内容])

像上面这样不用let申明数组变量,则直接原样输出。

#let arr2 = ("你好",12,[这里是内容])    // 申明数组变量// 获取数组长度
#arr2.len()            // 3// 获取元素
#arr2.at(0)           // 你好
#arr2.first()          // 你好
#arr2.last()           // 这里是内容// 判断是否包含元素
#("你好" in arr2)      // true
#arr2.contains("你好") // true// 特殊方法
#arr2.enumerate()  // ((0"你好"),(1,12),(2,[这里是内容]))// 遍历
#for value in arr2 {[#value]
}

因篇幅所限,以及与GDSCript获其他脚本语言的类似性,这里不赘述其他数组方法的示例。

不声明变量直接调用方法也是可以的:

#(1,2,3).at(0)   // 1

字典

dictionary{len() -> integer                     // 字典中键值对的数量at(key:string,default: any,) -> any  // 获取指定键的值insert(key:string,value:any,)        // 插入新的键值对到字典remove(key:string) -> any            // 从字典删除指定键的键值对keys() -> array                      // 字典中所有键组成的数组(按插入顺序)values() -> array                    // 字典中所有值组成的数组(按插入顺序)pairs() -> array                     // 键值对组成的数组(按插入顺序)
}
// 申明字典变量
#let dic = (name:"张三",sex:"男",age:12
)// 获取字典键值对个数
#dic.len()      // 3// 获取元素
#dic.at("name") // 张三
#dic.name       // 张三// 获取键获值的数组
#dic.keys()     // ("name","sex","age")
#dic.values()   // ("张三","男",12)// 特殊
#dic.pairs()    // (("name","张三"),("sex","男"),("age",12))

数组与字典的解构赋值

//申明一个字典
#let pp = (name:"张三",sex:"男",age:45
)
//解构赋值
#let (name,sex,age) = pp//输出成员
#name
#sex
#age

可以看到所谓解构赋值,就是一次性批量申明变量,然后对应字典或数组的元素。

日期时间

datetime的方法

datetime{display(pattern:string) -> string  // 给定格式显示日期时间year() -> integer/none             // 返回日期时间中的年,不存在返回nonemonth() -> integer/none            // 返回日期时间中的月,不存在返回noneday() -> integer/none              // 返回日期时间中的日,不存在返回noneweekday() -> integer/none          // 返回日期时间的周几数字,不存在返回nonehour() -> integer/none             // 返回日期时间中的小时,不存在返回noneminute() -> integer/none		   // 返回日期时间中的分钟,不存在返回nonesecond() -> integer/none           // 返回日期时间中的秒数,不存在返回none
}

datetime的构造

日期时间类型可以使用datetime()函数构造,可以看做是datetime类型的构造函数:

datetime(year:         //年份month:        //月份day:          //日期week_number:  //周数weekday:      //星期hour:         //小时minute:       //分钟second:       //秒数
)

你可以指定其中的全部或部分。

// 构造日期
#let date = datetime(year: 2025,    // 年month: 6,      // 月day: 1         // 日
)// 构造时间
#let time = datetime(hour: 15,      // 时minute: 27,    // 分second: 57     // 秒
)

datetime的显示

直接调用变量并不会显示日期时间,而需要用datetimedisplay()方法:

#date // datetime( year: 2025, month: 6, day: 1)
#time // datetime( hour: 15, minute: 27, second: 57)#date.display()       // 2025-06-01
#time.display()       // 15:27:57
#date_time.display()  // 2025-06-01 15:27:57

display()方法采用默认显示格式:

  • 如果只指定了日期,格式为[year]-[month]-[day]
  • 如果只指定了时间,格式为 [hour]:[minute]:[second]
  • 如果你同时指定了日期和时间,格式为 [year]-[month]-[day] [hour]:[minute]:[second]

可以在display()方法中传入自定义的显示格式:

#date.display("[year]年[month]月[day]日")       // 2025年06月01日

还可以设定显示参数:

#date.display("[year repr:last_two]年[month]月[day]日")       // 25年06月01日
通用参数

yearmonthdayhourminutesecondweek_number,都可以指定padding参数:

参数作用可选值
padding指定填充方式zero:默认,位数不够前面补零
space :位数不够前面补空格
none:位数不够不补零
#date.display("[year]年[month padding:none]月[day padding:none]日")   // 2025年6月1日
#date.display("[year]年[month padding:zero]月[day padding:zero]日")   // 25年06月01日
#date.display("[year]年[month padding:space]月[day padding:space]日")  // 2025年 6月 1日
year的参数
参数作用可选值
reprfull显示完整年份
last_two只显示最后两位
sign指定何时显示符号。automatic
mandatory
month的参数
参数作用可选值
repr指定月份是否以数字或单词形式显示。 不幸的是,选择单词表示时,目前仅能显示英文版本。未来计划支持本地化numerical
long
short
hour的参数
参数作用可选值
repr决定小时以 24 小时制还是 12 小时制显示2424小时制
1212小时制
week_number的参数
参数作用可选值
repr周数范围ISO周数范围为 1 至 53
sunday 周数范围为 0 至 53
monday周数范围为 0 至 53
weekday的参数
参数作用可选值
repr。 对于 longshort,会显示相应的英文名称(与月份类似,目前不支持其他语言)。 对于 sundaymonday,将显示数字值(分别假设星期日和星期一为一周的第一天)。long星期几的英文名称
short星期几的英文名称
sunday星期几的数字值(以星期日为每周第一天)
monday星期几的数字值(以星期一为每周第一天)
one_indexed设定周的数值表示从 0 还是 1 开始。truefalse
period的参数
参数作用可选值
case定义时间段的大小写显示。lowerupper

http://www.hkcw.cn/article/DOLBtSbQrY.shtml

相关文章

Java 文件操作 和 IO(5)-- 综合案例练习 -- 示例三

文章目录 题目描述&#xff1a;扫描指定目录&#xff0c;并找到文件名称或文件内容中包含指定字符的所有普通文件&#xff08;不包含目录&#xff09;结果案例演示&#xff1a;设计思路&#xff1a;总体的思路&#xff1a;使用代码&#xff0c;分步实现1. 准备工作&#xff08;…

微深节能 筒仓卸料小车远程智能控制系统 格雷母线

微深节能筒仓卸料小车远程智能控制系统——格雷母线高精度定位解决方案 在现代化筒仓物料管理中&#xff0c;卸料小车的精准定位与远程控制是提升效率、保障安全的关键。武汉市微深节能科技有限公司推出的格雷母线高精度位移测量系统&#xff0c;为筒仓卸料小车提供远程智能控…

股票指数期货的变动与股票价格指数的关系是什么?

很多小伙伴刚接触金融投资的时候&#xff0c;常常会听到“股票指数期货”和“股票价格指数”这两个词&#xff0c;但搞不清楚它们之间的关系。今天&#xff0c;我就给大家讲讲&#xff0c;这两个东西到底是什么关系。 一、股票价格指数是个什么&#xff1f; 股票价格指数&…

2025LitCTF re wp复现

LitCTF2025 wp&&复现 easy_rc4 魔改RC4&#xff0c;直接在异或处下条件断点&#xff0c;动调获取密钥流 FeatureExtraction 定位到main 前面都是一些初始化函数以及把输入的char型字符串转成int型数据 关键加密在sub_401722(Block, des) 加密逻辑就是 unsigned in…

Lovable + Cursor:零基础搭建专业应用的秘密武器

🚀 Lovable + Cursor:零基础搭建专业应用的秘密武器 为什么你需要这个工作流? 想象一下这样的场景:你用Lovable快速搭建了一个漂亮的网页原型,但当你想要添加更复杂的功能时,却发现自己被限制住了。或者你在Cursor里写代码很顺手,但每次从零开始设计界面都让你头疼不…

ARM GIC V3概述

中断类型 locality- specific peripheral interrupt&#xff08;LPI&#xff09;&#xff1a;LPI是一个有针对性的外设中断&#xff0c;通过affinity路由到特定的PE。 为非安全group1中断边沿触发可以通过its进行路由没有active状态&#xff0c;所以不需要明确的停用操作LPI总…

Docker部署与应用、指令

部署 【Docker】在 Ubuntu 22.04 以下版本上安装 Docker 的详细指南_ubuntu 安装docker-CSDN博客 应用 使用指定镜像创建并运行一个新容器 --name&#xff0c;指定容器名称 -d 代表后台运行 nginx 代表容器镜像名 docker ps 查看运行的容器 -a 查看…

内网横向之RDP缓存利用

RDP&#xff08;远程桌面协议&#xff09;在连接过程中会缓存凭据&#xff0c;尤其是在启用了 "保存密码" 或 "凭据管理器" 功能时。这个缓存的凭据通常是用于自动填充和简化后续连接的过程。凭据一般包含了用户的用户名和密码信息&#xff0c;或者是经过加…

从计量到通信,DJSF1352-D为快充桩系统提供了怎样的解决方案?

摘要 随着新能源汽车保有量的不断攀升&#xff0c;直流充电桩成为城市交通与能源基础设施的重要组成部分。电能计量作为充电桩运营、结算和安全管理的核心环节&#xff0c;对计量设备提出了更高的要求。安科瑞DJSF1352D导轨式直流电能表&#xff0c;凭借高精度、高稳定性和通信…

0518蚂蚁暑期实习上机考试题1:数组操作

题目 小红认为一个长度为 n 的数组 a 是好的&#xff0c;当且仅当对于任意的 i &#xff0c;均满足相等&#xff0c;其中数组下标 i 从 1 开始&#xff0c;小红每次可以对一个数加 1 或者减 1 &#xff0c;求把给定的数组变成好数组的最少操作次数。 输入描述&#xff1a;第一…

深入对比主流Java Web服务器与框架

目录 一、核心技术对比概览 二、深度解析与应用场景 1. Apache Tomcat - 企业级标准容器 2. Netty - 高性能网络编程框架 3. Undertow - 轻量级嵌入式服务器 4. Vert.x - 响应式应用框架 5. Play Framework - 全栈Web框架 三、性能基准测试对比&#xff08;参考数据&am…

晶台光耦在手机PD快充上的应用

光耦&#xff08;光电隔离器&#xff09;作为关键电子元件&#xff0c;在手机PD快充中扮演信号隔离与传输的“安全卫士”。其通过光信号实现电气隔离&#xff0c;保护手机电路免受高电压损害&#xff0c;同时支持实时信号反馈&#xff0c;优化充电效率。 晶台品牌推出KL817、KL…

EscapeX:去中心化游戏,开启极限娱乐新体验

VEX 平台推出全新去中心化游戏 EscapeX&#xff08;数字逃脫&#xff09;&#xff0c;创新性地将大逃杀玩法与区块链技术相融合。用户不仅能畅享紧张刺激的解谜过程&#xff0c;更能在去中心化、公正透明的环境中参与游戏。EscapeX 的上线&#xff0c;为 VEX 生态注入全新活力&…

服务端定时器的学习(一)

一、定时器 1、定时器是什么&#xff1f; 定时器不仅存在于硬件领域&#xff0c;在软件层面&#xff08;客户端、网页和服务端&#xff09;也普遍应用&#xff0c;核心功能都是高效管理大量延时任务。不同应用场景下&#xff0c;其实现方式和使用方法有所差异。 2、定时器解…

Axure形状类组件图标库(共8套)

点击下载《月下倚楼图标库(形状组件)》 原型效果&#xff1a;https://axhub.im/ax9/02043f78e1b4386f/#g1 摘要 本图标库集锦精心汇集了8套专为Axure设计的形状类图标资源&#xff0c;旨在为产品经理、UI/UX设计师以及开发人员提供丰富多样的设计素材&#xff0c;提升原型设计…

CET6 仔细阅读 24年12月第一套-C1 大脑这一块

文章 There are hundreds of personality quizzes online that assert they can ascertain whether the right or left half of your brain is dominant. Left-brained people are supposedly logical and excel at language and math while right- brained people are more i…

【JavaWeb】SpringBoot原理

1 配置优先级 在前面&#xff0c;已经学习了SpringBoot项目当中支持的三类配置文件&#xff1a; application.properties application.yml application.yaml 在SpringBoot项目当中&#xff0c;我们要想配置一个属性&#xff0c;通过这三种方式当中的任意一种来配置都可以&a…

硬件工程师笔记——555定时器应用Multisim电路仿真实验汇总

目录 一 555定时器基础知识 二、引脚功能 三、工作模式 1. 单稳态模式&#xff1a; 2. 双稳态模式&#xff08;需要外部电路辅助&#xff09;&#xff1a; 3. 无稳态模式&#xff08;多谐振荡器&#xff09;&#xff1a; 4. 可控脉冲宽度调制&#xff08;PWM&#xff09…

基于springboot的图书管理系统的设计与实现

其他源码获取可以看首页&#xff1a;代码老y 个人简介&#xff1a;专注于毕业设计项目定制开发&#xff1a;springbootvue系统&#xff0c;Java微信小程序&#xff0c;javaSSM系统等技术开发&#xff0c;并提供远程调试部署、代码讲解、文档指导、ppt制作等技术指导。源码获取&…

一个html实现数据库自定义查询

使用场景 应用上线后甲方频繁的找开发查询数据库数据&#xff0c;且没有固定的查询规律&#xff0c;产品经理也没有规划报表需求。 实现方案 后端开放自定义sql查询&#xff0c;屏蔽所有数据库的高危操作&#xff0c;将常用查询的sql放在一个html中的js中直接查询&#xff0…