
Zulip 消息格式化完全指南扩展 Markdown 语法与渲染 HTML 规范【免费下载链接】zulipZulip server and web application. Open-source team chat that helps teams stay productive and focused.项目地址: https://gitcode.com/GitHub_Trending/zu/zulipZulip 在标准 Markdown 基础上实现了功能扩展的消息标记语言用于编写消息、提及用户与群组、链接到频道/主题/消息、插入图片与音视频媒体等。本文以 Zulip 官方 API 文档 api_docs/message-formatting.md 为骨架系统讲解每一种消息格式化特性的 Markdown 语法、服务端渲染产出的 HTML 结构以及各特性引入与演进的版本/feature level并结合仓库源码zerver/lib/markdown/init.py、zerver/views/message_send.py、zerver/lib/events.py给出实现层面的印证。读完本文你将掌握 Zulip 消息从 Markdown 输入到 HTML 输出的完整规范能够据此实现兼容的第三方客户端渲染逻辑。背景消息渲染的整体架构Zulip 的消息格式化特性属于扩展版 Markdown同时包含少量 HTML 层级的特殊行为。完整的用户侧功能说明以帮助中心的 Markdown 格式化文档为主帮助中心另有「Format your message using Markdown」专题而本 API 文档的角色是特性变更日志changelog与渲染输出规范——它面向 API 客户端开发者详细说明每种语法最终渲染出的 HTML 结构以及这些结构随版本变化的历史。对于任何希望验证 Markdown 语法渲染结果的开发者Zulip 提供了Render a messageAPI 端点传入消息内容即可返回当前版本服务端渲染出的 HTML。对应后端实现在 zerver/views/message_send.py 的render_message_backendtyped_endpoint def render_message_backend( request: HttpRequest, user_profile: UserProfile, *, content: Annotated[str, StringConstraints(max_lengthsettings.MAX_MESSAGE_LENGTH)], ) - HttpResponse: message Message() message.sender user_profile message.realm user_profile.realm message.content content ... rendering_result render_message_markdown(message, content, realmuser_profile.realm) return json_success(request, data{rendered: rendering_result.rendered_content})真正的 Markdown 转换核心是 zerver/lib/markdown/init.py 中的render_message_markdown见 L2756-L2792它包裹markdown_convert并接收发送者是否为机器人、是否开启表情符号转译、提醒词自动机、URL 预览数据、提及数据等上下文。该文件基于 Python-Markdown 框架实现了大量自定义 inline/block 处理器Timestamp、UserMentionPattern、UserGroupMentionPattern、StreamPattern、StreamTopicPattern、StreamTopicMessagePattern、InlineImageProcessor、InlineVideoProcessor等这正是下文中各类 HTML 结构的直接来源。Zulip 的 API 文档约定使用feature level标注变更点如feature level 33客户端可依据 feature level 判断服务端行为版本。下文各节中凡标注 feature level 的变更均以当前仓库所对应版本为准。代码块与data-code-language变更记录自 Zulip 4.0feature level 33起代码块外层 HTMLdiv元素会附带data-code-language属性记录用于语法高亮的编程语言。该字段服务于代码块相关的Code playgrounds代码游乐场功能。渲染示例实际结构见 zerver/tests/fixtures/markdown_test_cases.json 中的测试用例div classcodehilite>span classtimestamp-errorInvalid time format: invalid/span现在lt;time:invalidgt;实现印证见 zerver/lib/markdown/init.py 的Timestamp类对输入调用datetime.fromisoformat失败即返回转义字面量解析成功则生成 HTML5time元素设置 UTC 化后的datetime属性并将原文保留为元素文本便于纯文本客户端至少显示原始输入class Timestamp(markdown.inlinepatterns.Pattern): def handleMatch(self, match: Match[str]) - Element | str: time_input_string match.group(time) try: timestamp datetime.fromisoformat(time_input_string) except ValueError: return flt;time:{time_input_string}gt; # 有效的 ISO 8601 时间戳 → time 元素 time_element Element(time) ... time_element.set(datetime, timestamp.isoformat().replace(00:00, Z)) time_element.text markdown.util.AtomicString(time_input_string) return time_element可见带时区信息的时间戳会先转为 UTC不带时区的时间戳默认按 UTC 处理转换失败如溢出同样回退为字面文本。链接到频道、主题与消息Zulip 的标记语言支持用可读性强的 Markdown 语法链接到频道channel、主题topic与消息message。核心语法形态为#**频道名**、#**频道名主题名**、#**频道名主题名消息ID**。基础语法与对应 HTML以频道announcestream-id 为 9为例各形态的渲染 HTML 如下!-- 语法#**announce** -- a classstream>!-- 语法#**announce** -- a classstream-topic>span aria-labelsmiling face classemoji emoji-263a roleimg titlesmiling face:smiling_face:/span注意事项在 Zulip 1.9.2 之前版本发送的消息中Unicode emoji没有role与aria-label属性客户端不应依赖这两个字段必然存在POST /register响应的server_emoji_data_url键包含服务端维护的Unicode 码点 ↔ emoji 名称映射表。代码层面见 zerver/lib/markdown/init.py 的make_emoji生成classemoji emoji-{codepoint}、title、roleimg、aria-label的 spantitle与aria-label中的下划线会替换为空格同时POSSIBLE_EMOJI_RE源自 Unicode 技术报告 TR51 的 EBNF负责识别复杂 emoji 序列含区域指示符、变体选择符、ZWJ 序列、标签序列等。自定义 emoji 的 HTML 结构自定义 emoji 在 HTML 中用同样带.emoji类的img标签表示srcURL 需相对 Zulip 服务器主机名解析!-- Realm 专属配置的自定义 emoji -- img alt:example_custom_emoji: classemoji titleexample_custom_emoji src/user_avatars/2/emoji/images/dbe43627.png !-- 内置自定义 emoji如 :zulip: -- img alt:zulip: classemoji titlezulip src/static/generated/emoji/images/emoji/unicode/zulip.png图片Zulip 对图片的处理有两种形态链接派生的预览与Markdown 图片语法二者都会经过服务端缩略图thumbnail管线。链接派生的图片预览当消息中包含指向已上传图片的链接时Zulip 会额外插入一个图片预览元素div classmessage_inline_image a href/user_uploads/path/to/example.png titleexample.png img>img altexample image classinline-image >div classmessage_inline_image a href/user_uploads/path/to/example.png titleexample.png img classimage-loading-placeholder >img altexample image classinline-image image-loading-placeholder >div classmessage_inline_image a href/user_uploads/path/to/example.heic titleexample.heic img>img altexample HEIC image classinline-image >div classmessage_inline_image message_inline_video a href/user_uploads/path/to/video.mp4 video preloadmetadata src/user_uploads/path/to/video.mp4 /video /a /div实现层面见 zerver/lib/markdown/init.py 附近的InlineVideoProcessor。音频播放器当 Markdown 媒体语法与音频Content-Type的上传文件搭配使用时Zulip 会生成 HTML5audio播放器元素。目前支持的 MIME 类型为audio/aac、audio/flac、audio/mpeg、audio/wav及其audio/x-wav、audio/vnd.wave变体。例如file.mp3渲染为audio controls preloadmetadata src/user_uploads/path/to/file.mp3 titlefile.mp3 /audioURL 重写如果 Zulip 服务器重写了音频文件的 URL会通过data-original-url参数提供原始 URL。服务器对所有非上传文件的音频 URL 都会这样做audio controls preloadmetadata >span classuser-mention>span classuser-mention silent>span classtopic-mentiontopic/span**channel**频道通配符span classuser-mention channel-wildcard-mention >span classuser-group-mention >span classuser-group-mention silent >span classuser-group-mention silent >div classmessage_inline_ref a hrefhttps://www.dropbox.com/sh/cm39k9e04z7fhim/AAAII5NK-9daee3FcF41anEua?dl titleSaves img src/path/to/folder_dropbox.png /a divdiv classmessage_inline_image_titleSaves/div desc classmessage_inline_image_desc/desc /div /div已移除的遗留头像标记在 Zulip 4.0feature level 24从未被文档化、且语法不统一的!avatar()与!gravatar()标记语法被移除。相关文档导航以下仓库内文档可进一步深入消息渲染的完整 API 端点说明可查阅 zerver/openapi/zulip.yaml 中render-message与send-message的 OpenAPI 定义包含请求/响应结构及示例Markdown 渲染测试用例集中在 zerver/tests/fixtures/markdown_test_cases.json覆盖代码块高亮、语言规范化、提及、链接等大量输入-输出配对是验证客户端渲染行为是否符合服务端规范的第一手资料频道/主题/消息链接的端到端渲染断言可参考 zerver/tests/test_channel_creation.py搜索与 URL 的near/with操作符语义可参考 API 文档中关于窄化narrow与 Zulip URL 的章节仓库内对应文档为 api_docs/construct-narrow.md 与 api_docs/zulip-urls.md用户侧完整功能说明代码块、emoji、剧透、全局时间、提及、图片/视频/网站预览、自定义 emoji、频道通配符提及、屏蔽用户等以帮助中心为主题展开客户端接入时建议以本文描述的渲染 HTML 规范为准功能行为细节再对照帮助中心确认。结语Zulip 的消息格式化规范经过多版本迭代已相当精细从代码块的data-code-language到全局时间的 ISO 8601 约束从频道/主题/消息链接的near/with操作符演进到data-stream-id的弃用从图片缩略化管线到音视频媒体元素再到权限模型精细的提及系统。这些行为均可在 zerver/lib/markdown/init.py 中找到对应实现并由 zerver/tests/fixtures/markdown_test_cases.json 等测试用例锁定输出格式。对于任何希望构建 Zulip 兼容客户端的团队本文列出的 HTML 结构、属性语义与版本行为是必须逐条对齐的契约。【免费下载链接】zulipZulip server and web application. Open-source team chat that helps teams stay productive and focused.项目地址: https://gitcode.com/GitHub_Trending/zu/zulip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考