ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Mermaid Directives 深度解析:用 %%{init}%% 指令在图形代码内覆盖主题与图表配置的完整机制

Mermaid Directives 深度解析:用 %%{init}%% 指令在图形代码内覆盖主题与图表配置的完整机制 Mermaid Directives 深度解析用 %%{init}%% 指令在图形代码内覆盖主题与图表配置的完整机制【免费下载链接】mermaidGeneration of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown项目地址: https://gitcode.com/GitHub_Trending/me/mermaid本文以 Mermaid 官方的 Directives 文档 为主体系统讲解%%{init: ...}%%指令的语法结构、init/initialize的合并规则、通用与图表专属两类配置项的写法theme、fontFamily、logLevel、flowchart、sequence并结合当前仓库源码还原指令的完整生命周期从正则匹配、预处理提取、安全清洗sanitize到与站点配置、frontmatter 的合并优先级帮助你在编写图表时精准控制单图外观并理解哪些配置项因安全原因不可被指令覆盖。一、Directives 的定位写在图里的配置覆盖层Directives指令让图表作者能够在渲染之前、直接以文本形式改变图表外观。它的价值在于书写时可用指令就写在图表文本中和图形定义一起流转无需额外的 JS 调用叠加在默认配置之上指令修改的是全局默认配置和图表专属配置属于“单图级”individual level覆盖部分配置不可覆盖出于安全原因某些配置项不允许通过指令修改同时你还有权定义“允许图表作者覆盖的配置集合”。需要注意的是官方文档开头明确标注了弃用警告Directives 从 v10.5.0 起已弃用deprecated建议改用 frontmatter 中的config键来传递配置详见 Configuration 文档。也就是说在当前仓库中 Directives 仍被完整实现和测试后文会给出源码证据但新项目中推荐的新写法是 YAML frontmatter--- config: theme: forest --- graph LR A--B本文仍按原文档脉络完整讲解 Directives 本身并补充两条机制在源码中如何并存的事实。二、两类可被指令覆盖的配置Mermaid 支持两类可被指令覆盖的配置原文档“Types of Directives options”一节1. General/Top Level configurations通用/顶层配置作用于所有图表的通用配置其中最常通过指令使用的包括themefontFamilylogLevelsecurityLevelstartOnLoadsecure2. Diagram-specific configurations图表专属配置只作用于特定图表类型的配置。例如mirrorActors是SequenceDiagram专属配置控制参与者是否镜像显示因此它只能出现在sequence这一层。原文档提示并非所有配置项都在文档中列全完整列表应参考源码中的 packages/mermaid/src/defaultConfig.ts原文档给出的外部 GitHub 链接在此统一替换为仓库内路径。三、指令的声明语法%% {directive_text} %%一条指令始终以两个%符号开头和结尾即%% {directive_text} %%。指令文本的结构是一个以init为根的嵌套键值对映射JSON 对象顶层放通用General配置深一层、以图表类型为 key放该图表的专属配置。完整结构示例原文档原样保留%%{ init: { theme: dark, fontFamily: monospace, logLevel: info, htmlLabels: true, flowchart: { curve: linear }, sequence: { mirrorActors: true } } }%%也可以写在一行内%%{init: { **insert configuration options here** } }%%例如%%{init: { sequence: { mirrorActors:false }}}%%注意原文档 Notes作为参数传入的 JSON 对象必须是合法的键值对且键要加引号否则会被忽略合法的键值对可参考 config 文档。源码印证指令如何被识别在 diagram-api/regexes.ts 中定义了识别指令的正则export const directiveRegex /%{2}{\s*(?:(\w)\s*:|(\w))\s*(?:(\w)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;它匹配%%{ ... %%}的成对结构并捕获形如init:或initialize:的键名同文件还定义了frontMatterRegexJekyll 风格 frontmatter与anyCommentRegex这与下文“指令与 frontmatter 合并”的源码路径一一对应。四、指令的解析与合并规则init与initialize等价且会被合并init和initialize都可作为初始化指令的键且解析后会被归并为同一条指令。原文档示例解析后会生成一个单一的%%init%%JSON 对象合并两条指令并对重复的logLevel取最后一次出现的值{ logLevel: fatal, theme: dark, startOnLoad: true }该对象随后会交给mermaid.initialize(...)用于渲染。最小示例logLevel 与 theme这条指令声明将logLevel设为debug、theme设为dark直接改变渲染结果的外观。五、典型配置项逐例讲解以下四个小节完整继承原文档“Directive Examples”中的示例与参数说明。5.1 通过指令修改 theme将theme改为forest%%{init: { theme: forest } }%%可选值default、base、dark、forest、neutral默认值是default。源码侧theme的取值与内置主题一一对应config.ts 中的updateCurrentConfig会检查sumOfDirectives.theme in theme命中后调用theme[cfg.theme].getThemeVariables(...)生成该主题的变量集再合并进指令里自定义的themeVariables——这就是“指令改主题”在底层的落点。5.2 通过指令修改 fontFamily%%{init: { fontFamily: Trebuchet MS, Verdana, Arial, Sans-Serif } }%%一个有意思的源码细节addDirective中专门处理了fontFamily——如果指令带了fontFamily却没有themeVariables它会自动把fontFamily复制进themeVariables.fontFamily见 config.ts 中addDirective函数。这解释了为什么“顶层写 fontFamily”能真正影响字体渲染而不必手工写主题变量。5.3 通过指令修改 logLevel%%{init: { logLevel: 2 } }%%logLevel的取值原文档列表完整保留1debug2info3warn4error5only fatal errors默认值是5。5.4 通过指令修改 flowchart 配置常用 flowchart 配置原文档列表htmlLabels已弃用建议改在根级别设置curvelinear/curvediagramPaddingnumberuseMaxWidthnumber。完整列表参见 packages/mermaid/src/defaultConfig.ts。只覆盖 flowchart 配置不碰通用配置的写法%%{init: { htmlLabels: true, flowchart: { curve: linear } } }%%Warning原文档原文Deprecated:flowchart.htmlLabels自 v11.12.3 起弃用。请改用全局htmlLabels配置。例如不要写flowchart: { htmlLabels: true }而是把htmlLabels: true放在顶层。这个弃用规则在源码中有对应实现config.ts 的getEffectiveHtmlLabels函数按根级 htmlLabels → flowchart.htmlLabels → 默认 true的优先级取值且一旦检测到config.flowchart.htmlLabels已设置就会通过issueWarning打印flowchart.htmlLabels is deprecated. Please use global htmlLabels instead.的警告。5.5 通过指令修改 Sequence 图配置常用 sequence 配置原文档列表完整保留widthnumberheightnumbermessageAlignleft、center、rightmirrorActorsbooleanuseMaxWidthbooleanrightAnglesbooleanshowSequenceNumbersbooleanwrapboolean先看默认wrap默认为false启用wrap并把width设为 300%%{init: { sequence: { wrap: true} } }%%应用该片段后长消息会在参与者之间换行显示图表整体宽度被约束在 300px 附近。六、源码纵深指令从文本到生效配置的完整链路结合当前仓库源码Directives 的完整生命周期如下文件路径均可在当前仓库中查看6.1 预处理阶段提取、合并、删除preprocess.ts 中的processDirectives是入口用utils.detectInit(code)检测%%init%%指令并解析为对象见 utils.ts 中detectInit与removeDirectives同时检测wrap类指令%%{wrap: true}%%若存在则把initDirective.wrap置为true调用removeDirectives(code)把指令文本从源码中删除避免指令内容进入图形解析器最后由cleanAndMerge(frontmatter.config, directive)将frontmatter 的config与 directive 结果合并——这正是“v10.5.0 后推荐 frontmatter、但 directives 仍然可用”两条机制在源码层的会合点。6.2 配置合并阶段addDirective与优先级mermaidAPI.ts 在解析出图表元数据后调用configApi.addDirective(processed.config ?? {})注释明确写着 “Important that we do not create the diagram until after the directives have been included”——即先注入指令再创建图表对象保证图表拿到的配置已包含指令覆盖。config.ts 中的updateCurrentConfig给出优先级事实从源码结构看defaultConfig siteConfig(来自 mermaid.initialize) 按顺序累积的 directives以siteConfig为基底深拷贝assignWithDepth逐条sanitize(d)后依次assignWithDepth进sumOfDirectives——多条指令中后者覆盖前者与第四节logLevel: fatal覆盖debug的行为一致再把sumOfDirectives叠加到基底上形成currentConfig。reset()会清空directives并把配置重置回siteConfig保证渲染下一张图时不会串味。6.3 安全边界两层 sanitize文档说“出于安全原因部分配置不可用指令修改”源码里这是两层具体实现第一层secure 键保护config.ts 的sanitizesecure及siteConfig.secure数组中列出的键若在指令中出现会被直接删除日志记录 “Denied attempt to modify a secure key”删除所有以__开头的键防原型污染删除任何包含、或url(data:的字符串值防 XSS / base64 内嵌 SVG 脚本。第二层白名单 值校验utils/sanitizeDirective.ts 的sanitizeDirective键白名单不在defaultConfig.ts导出的configKeys中的键一律删除——这就是“不是所有配置都能被指令改变”的真正原因可用键集合严格等于默认配置暴露的键危险键模式startsWith(__)、含proto、含constr的键被删除字典型配置的值校验nodeColorssankey 的 CSS 颜色、filenameIcons/extensionIconstreeView 的 iconify 图标引用按DICTIONARY_CONFIG_PATTERNS中的正则校验值不合规的条目被删除CSS 相关键themeCSS、fontFamily、altFontFamily会经sanitizeCss做花括号配平检查不平衡时替换为{ /* ERROR: Unbalanced CSS */ }themeVariables 值校验值需匹配/^[\d #%(),.;A-Za-z]$/否则清空为。6.4 E2E 佐证仓库的端到端测试套件里存在专门的 conf-and-directives 用例目录其中 settings-from-initialize-nodes-should-be-green.mmd 验证%%initialize%%指令确实能改变渲染结果节点着色与文档中“init/initialize等价”的说明互为印证。七、实践建议与要点回顾单图覆盖用指令全局覆盖用mermaid.initialize指令的作用域是“当前图”适合把主题、字体、wrap 等外观决策写在图表文本里随文档流转新代码优先 frontmatter由于 Directives 自 v10.5.0 起标记弃用frontmatter 的config键是官方推荐写法当前版本中两者并存且最终在cleanAndMerge处汇合重复键取最后一个多条init/initialize合并时后值覆盖前值写多条指令时注意顺序键名必须合法JSON 键要加引号否则被忽略且键必须存在于 defaultConfig.ts 的键集合中否则被 sanitize 静默删除安全键改不了secure、原型污染模式、含标签或data:URL 的字符串都会被清洗试图通过这些通道注入样式/脚本是无效的弃用项要迁移flowchart.htmlLabels已弃用v11.12.3改用顶层htmlLabels源码会打印对应警告。核心事实速查表主题说明依据指令语法%%{init: {...} }%%init/initialize等价docs/config/directives.md、diagram-api/regexes.ts生效时序预处理提取 → 删除指令文本 → 先注入配置再建图preprocess.ts、mermaidAPI.ts合并优先级defaultConfig siteConfig directives后写覆盖config.tsupdateCurrentConfig可用键集合以defaultConfig.ts的configKeys白名单为准utils/sanitizeDirective.ts安全清洗secure 键、__/proto/constr 键、/data:字符串、CSS 配平、themeVariables 值校验config.ts、utils/sanitizeDirective.ts推荐写法frontmatterconfig键directives 自 v10.5.0 弃用docs/config/directives.md、docs/config/configuration.md【免费下载链接】mermaidGeneration of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown项目地址: https://gitcode.com/GitHub_Trending/me/mermaid创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表