mcpField
R
reladraw

reladraw

github.com/reladraw设计与 UI1.1k212 次安装今天更新
代码仓库

关于 reladraw

reladraw 是一种将文本描述转换为独立 SVG 图表的语言,适合需要明确控制节点位置和连线的设计者与开发者。它不自动安排布局,而是按源文件中的相对位置绘制,并报告重叠等问题。

主要功能

  1. 01以文本定义图表与相对位置
  2. 02生成无运行时依赖的 SVG
  3. 03支持节点、容器、样式与连线
  4. 04检查并报告图形重叠问题
  5. 05提供格式化与语法错误提示

适用场景

  1. 01绘制位置可预测的系统架构图
  2. 02为节点和连线指定明确布局
  3. 03检查图表中的文字或线条重叠
  4. 04格式化并维护 .reladraw 源文件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/reladraw/reladraw --skill reladraw

安装后在 Claude Code 中输入/reladraw确认已加载。

附带文件reference/syntax.md

详细介绍

reladraw

一种用于绘制图表的文本语言。输入源文件,输出独立 SVG,无运行时依赖。

其他图表语言都会把布局交给布局引擎,因此元素最终的位置无法从你写的内容中预测。reladraw 则反其道而行之:文件用人们会直接说出口的方式描述布局(right of api、below worker (gap: tight)、even with queue),工具会严格按此绘制。它绝不自行选择布局、不会为了腾出空间而移动方框,也不会让线绕过任何东西。

这点在这里尤其重要。你看不到生成的 SVG。使用自动布局时,你只能猜测;而使用 reladraw 时,布局就在你刚写下的句子里,如果图示可能无法表达出预期含义,工具会用文字告诉你。

检查是否已安装,以及版本是否与此技能相同

此技能介绍的是 reladraw 0.19.0。每个会话中,在首次渲染前运行一次:

reladraw --version
  • **版本相同:**无需说明。
  • 版本较旧,或无法识别 --version(该选项于 0.17.1 加入):此工具版本早于本页介绍的版本,因此会拒绝部分功能。请告知用户,并提供 npm install -g reladraw@latest。
  • **版本较新:**此技能已过时。请告知用户,并提供 npx skills add reladraw/reladraw -g 以刷新技能。同时继续操作;如果错误提示中给出了替代写法,请以错误提示为准,而非本页内容。

如果尚未安装 reladraw,可以使用 npx reladraw,无需安装;运行 npm install -g reladraw 即可安装。

操作流程

  1. 编写一个 .reladraw 文件。
  2. 运行 reladraw render diagram.reladraw -o diagram.svg。(-o - 会将内容写入标准输出;默认输出路径为输入路径加上 .svg。)
  3. 如果失败,错误会指出行号以及应改成的内容。修正后重新运行。
  4. 如果成功,请阅读它输出的检查结果。每条结果占一行,说明哪些内容可能未能表达预期含义、位置在哪里,以及程度如何:
diagram.reladraw:12: warning(text-overlap): text "statements" covers the top-left corner of node resolver; the overlap is 3 units wide and 2 units tall
diagram.reladraw:9: warning(edge-node-overlap): line api -> db crosses node cache, in and out of its top
  1. 在源文件中逐条修正检查结果,调整元素位置或明确线条的走向,然后重新运行,直到没有检查结果。reladraw check diagram.reladraw 会输出检查结果,但不会写入 SVG。
  2. 交付文件前运行 reladraw format diagram.reladraw。它会根据项目的 .reladraw-format(如果存在)将语句按列对齐并统一间距,但不会改变文件的绘制效果。格式化后,你编写的文件看起来就像用户项目中已有的文件一样。

没有错误且没有检查结果的文件,只表示没有任何元素相互覆盖。这并不代表图示一定清晰:请重新阅读源文件,确认布局表达了你的本意;对于大型图表,请告知用户你已检查检查结果,但没有查看渲染图。

核心理念

文件说明元素的位置,工具严格按此绘制。 间距就是你写下的距离。方框会按其放置关系定位,不会被任何东西推开。线条会在两个方框之间画成直线,除非你指定为直角或曲线,或明确列出经过的位置。任何重叠都会照样绘制,并给出报告。

因此,解决问题的办法始终是在源文件中补充说明,而不是指望工具自行处理。两个方框位于同一位置:将其中一个放到另一个旁边。线条穿过方框:用 via: 指定经过的位置。文字挤在方框旁:增大间距。

编写文件

语句从行首开始。较长的语句可续写到后续缩进行;空行或未缩进的行会结束语句。缩进不会将某个元素放入另一个元素中。// 用于开始注释,也可以写在语句末尾。

语句由一个位置主体(关键字、名称,然后是文本)以及属性和放置关系组成,顺序不限。以冒号结尾的词会开启一个属性,除此之外的内容都不会。

节点
node <name> ["<text>" [(<text settings>)]] [<placement> | <attribute>] ...

省略文本时,节点会显示其名称(node parser 会显示为“parser”)。若要有意留空节点,请写 ""。在文本中,/(两侧各有一个空格的斜杠)表示换行;TCP/IP 和 URL 会保留原样。

主体可以是 shape: rectangle | document | circle | diamond | pill | parallelogram | hexagon | trapezoid | triangle | cylinder | none(none 是普通文本,用于注释和说明;流程图形状没有几何名称时,写作 flow- 加上其含义,例如 flow-subprocess 或 flow-delay;设置放在方括号中,例如 shape: triangle (aim: up)),也可以是 icon: disk | desktop | laptop | package | cubes | cube | database,即没有边框的图片。badge: <icon> 会将图片放在文本旁,作为标签的一部分。集合之外的图片用 icon <name> 声明,并在 """ 标记之间提供 SVG;建议优先使用内置图标。

node dump  "nightly dump"  shape: document
node unit  icon: cube  right of dump
node drive "External HD"  badge: disk  below dump
node aside "a remark that folds" (wrap: 20)  shape: none  right of drive
放置
above X          below X          left of X        right of X
above-left of X  above-right of X below-left of X  below-right of X
even with X      top even with X  bottom even with X  left even with X  right even with X
  • 文件中恰好有一个节点未放置,即锚点。其他节点都相对于某个对象放置,可以是直接相对,也可以通过其他节点间接相对。
  • 间距是精确的:在放置语句的方括号中指定 none、tight、normal(默认值)或 wide,例如 right of a (gap: tight);也可以指定前方的文件单位数值,例如 2 right of a。普通方框的高度约为 4 个单位。
  • 仅指定方向时,也会相对于目标居中。 单独写 right of a 会让方框与 a 等高。该轴上的其他放置语句会取代居中设置:right of a even with b。
  • 每个轴只能指定一次。 同一轴上的两个放置语句会被拒绝。唯一的例外是:right of a left of b 会将方框置于两者之间的空间中央,此时还必须指定高度。
  • 多个目标会合并为一个区域:below a and b 会将节点置于两者下方,并在两者之间居中。
  • 没有任何语句会移动方框。 两个方框都写成 right of a 时,会落在同一位置,并发出提示。请将它们串联起来(b right of a、c right of b),或放入带有布局的容器中。
容器

带点的名称表示子节点:server.api 位于 server 内部,且必须先声明父节点。容器是包围其子节点的方框。可通过以下两种方式之一排列子节点:

node server "Server"  layout: column (widths: match)
node server.api    "API"
node server.worker "Worker"

node lab "Lab"  right of server (gap: wide)
node lab.pc   "PC"
node lab.nas  "NAS"  right of lab.pc (gap: tight)

layout: column 或 layout: row 会按书写顺序排列子节点;其方括号可设置 gap:、widths: match 和 align-children: left | center | right。不指定布局时,恰好有一个子节点未放置,其余子节点都相对于它放置。容器上的 shape: none 会隐藏方框,让这些子节点组成一个可整体放置的形状。

标题默认位于 (inside top),并沿顶部居中;(inside top, align: left) 会将标题放在左上角,(on top) 或 (outside top) 则会将标题放在边框上或边框上方。

文本

文本的所有自有属性都放在其后方的方括号中:color、size(small | normal | large)、wrap(每 n 个字符折行)和 align。

style dim  text: (color: theme-muted)
node grinder "Grinder / [dim]medium-fine[/dim]"
node note "a longer remark that folds" (size: small, wrap: 30)  shape: none  below grinder (gap: tight)

[dim]…[/dim] 会借用某种样式的外观来显示一段文本。样式会将方括号附加到一个键上:style aside text: (size: small, color: theme-muted)。普通文本务必指定 (wrap: n),否则句子会显示为一整行,并横跨旁边的内容。

连线
edge [<name>] <from> -> <to> ["<text>" [(<placement>)]] [attributes]

<-、<-> 和 -- 也可以使用,而且每一端都可以带有标记:a <|-- b、a *--o b、a diamond--> b。from: 和 to: 用于指定书写的第一个和第二个名称所在的一侧:from: right to: left。

  • 默认采用直线,在两个框之间穿过,并经过其中的所有内容;这些内容会被报告。line: (path: square) 或 line: (path: curved) 可根据连线两端各自的框和边来确定路径。
  • via: 列出连线经过的位置:via: cache top 表示从 cache 正上方经过;via: between a and b 表示经过两者之间的点;via: proxy 表示经过某个框的中心。这是让连线绕过某个对象的方法。
  • 文本位于连线中间。 使用 (at: start)、(at: 1/4)、(above edge)、(on: longest level) 或 (above some_box) 来调整位置。文本不会移动框,因此要为带标签的连线留出空间:normal 间距不足以容纳一个词,所以在带标签连线连接的框之间使用 (gap: 12) 或更大的间距。
  • line: (pattern: dashed, thickness: thick, corners: rounded, color: #d2904e);单独使用 line: red 表示颜色。
相对于框的某个部分
node bob      "Bob the builder" (inside top)  height: 7
node bob_link "bob.example.com" (size: small)  inside bob bottom-center  shape: none
node count    "3"  on bob top-right  shape: circle

框的组成部分包括其 text、边 top、bottom、left、right,以及九个点(top-left、top-center、…… center …… bottom-right)。inside 会将节点放在框内并贴近该部分,outside 会将节点放在框外,on 会将节点居中放在该部分上。

样式和颜色
style store  fill: theme-primary-subtle  border: theme-primary  badge: database
node records "Records"  style: store

fill 是框的填充区域,border 是框的轮廓,line 是边的线条,文本的颜色则写在其方括号中。corners: sharp 会将框的圆角变为直角。优先使用主题颜色,它们在浅色和深色主题下都清晰可辨:theme-primary 和 theme-secondary 是强调色,-subtle 是向页面背景柔化后的强调色(用于填充框),theme-muted 是较低调的文本颜色。十六进制或 CSS 颜色在所有主题下都保持不变。

一个完整的小型文件

// A request path, left to right.
style store  fill: theme-primary-subtle  border: theme-primary  badge: database

node browser  "Browser"
node api      "API server"  right of browser (gap: 10)
node db       "Postgres"    right of api (gap: 10)  style: store
node worker   "Worker"      below api (gap: wide)

edge browser -> api  "HTTP"
edge api -> db       "SQL"
edge worker -> db    "writes"  to: bottom  line: (path: square)

node aside "The worker shares the database / but takes no HTTP traffic." (wrap: 30)  shape: none  below worker (gap: tight)

常见问题

  • 两个框以相同方式放置。 node b right of a 和 node c right of a 会将 b 和 c 放在同一位置。将 c 相对于 b 放置,或使用带有 layout: 的容器。
  • 相距很近的框之间有带标签的连线。 文本位于连线上,且不会自动扩大间距,因此会覆盖框并被报告。请为放置位置设置更大的间距。
  • 两个未放置的框。 只能有一个未放置。错误信息会指出这两个框。
  • 重复指定同一坐标轴。 right of a even with a 没问题;below a even with b 对高度作了两次指定,因此会被拒绝。
  • 旧语法。 level with 应写作 even with;节点上的 gap: 应放在放置语句的方括号中;边子句如 below c 和 between a and b 应写作 via: c bottom 和 via: between a and b;contents: 应写作 layout: column (…);节点文本上的 at: 应写作 (inside top, align: left) 等;deck: 是一种容器,应写作 layout: deck cards: "Drive 1" "Drive 2"。这些写法都会被拒绝,并提示应使用的写法。
  • note、box 或 link。 它们不是语句:注释应写作 node … shape: none,关键字是 node 和 edge。
  • 坐标。 不存在坐标。每个位置都相对于图中的其他内容。
  • 用 # 写注释。 它会开启一个十六进制颜色值;注释应使用 //。
  • 根据其他语言猜测语法。 这里没有花括号、分号或子图。如果需要使用此处未介绍的内容,请先查看 reference/syntax.md,不要自行猜测。

参考

reference/syntax.md 是完整的语法参考,涵盖所有结构、点和区域、路径点和命名线段、线束、尺寸、辅助线、绘制顺序、检测结果、语言拒绝的写法及其原因,以及各版本的变更。需要使用本页未涵盖的结构,或错误或检测结果指出了意料之外的行为时,请查阅该文档。

评论

支持 Markdown