开发工具文档【免费下载链接】quarto-cliOpen-source scientific and technical publishing system built on Pandoc.项目地址https://gitcode.com/gh_mirrors/qu/quarto-cli点击查看免费下载在 Quarto 中crossref.custom允许你定义自己的浮动对象类别float environment为任意内容块分配编号、题注caption与引用前缀并在 PDF/LaTeX 输出中自动生成对应的\newfloat浮动环境。本文以仓库中针对 GitHub issue #8711 编写的 smoke-all 回归测试文档 tests/docs/smoke-all/2024/02/12/8711.pdf.md 为主体完整拆解其 YAML 配置、正文标记语法、LaTeX 代码注入机制与回归验证方式帮助读者在自己的文档中安全地使用自定义交叉引用并理解latex-env命名上的关键限制。一、文档定位一份 smoke-all 回归测试用例该文档位于仓库的冒烟测试目录tests/docs/smoke-all/下其路径命名遵循日期 / issue 编号 / 目标格式的约定2024/02/12/8711.pdf.md表示这是 2024 年 2 月 12 日针对 issue #8711 的、目标输出为 PDF 的测试用例。该测试由 tests/smoke/smoke-all.test.ts 驱动渲染tests/timing-for-ci.txt中记录了./smoke/smoke-all.test.ts -- docs/smoke-all/2024/02/12/8711.pdf.md这一调用方式。关于 #8711该 issue 反映的问题是用户为自定义交叉引用类别命名latex-env: output时会与 LaTeXlongtable宏包发生命名冲突导致渲染失败。本测试文档正是围绕这一 Bug 的回归验证它在同一篇文档中同时放置了knitr::kable(mtcars)渲染出的长表格以及一个使用自定义 float 类别的输出块并特意将自定义环境命名为notoutput以避开冲突。文档开头声明了format: pdf与keep-md: true即渲染 PDF 的同时保留中间 Markdown因此这份.pdf.md文件本身就是渲染产物完整记录了测试输入YAML 前置元数据 正文的结构。二、YAML 前置元数据解析crossref.custom 配置该测试文档的核心配置如下--- title: Untitled format: pdf: keep-md: true crossref: custom: - kind: float key: out latex-env: notoutput reference-prefix: Output ---crossref.custom是一个数组每一项声明一种自定义交叉引用类别。其字段定义可在 src/resources/schema/document-crossref.yml 中找到Schema 明确规定kind、reference-prefix、key三个字段为必填项required: [kind, reference-prefix, key]其余字段可选字段类型默认值说明kind枚举float—必填交叉引用类别目前仅支持floatkey字符串—必填引用标签的前缀如fig、tbl、lst本文为outreference-prefix字符串—必填渲染引用时的前缀文本本文为Outputcaption-prefix字符串取reference-prefix题注中使用的前缀省略时复用reference-prefixlatex-env字符串无LaTeX 输出中自定义 float 环境的名称本文为notoutputcaption-locationtop/bottom/marginbottom题注相对浮动内容的位置latex-list-of-file-extension字符串loref-typeLaTeX 收集列表条目用的辅助文件扩展名latex-list-of-description字符串取reference-prefix自定义列表标题中对对象的描述文本space-before-numbering布尔true为false时前缀与编号之间不留空格测试中只使用了四个字段kind: float声明浮动类别key: out使标签以out-开头正文中对应#out-2reference-prefix: Output决定引用文本为 Outputlatex-env: notoutput指定 LaTeX 环境名。关于这些字段的完整语义与默认值Schema 文件 src/resources/schema/document-crossref.yml 是权威依据。三、正文结构与关键写法配置之外正文展示了三种内容形态分别对应表格、代码输出和自定义浮动块1. R 代码单元与长表格knitr::kable(mtcars)该单元由 knitr 引擎执行输出为一个 32 行 × 11 列的管道表格pipe table包含mpg、cyl、disp、hp、drat、wt、qsec、vs、am、gear、carb等变量mtcars是 R 内置数据集测试仅使用其前几行作为样例。在 LaTeX 输出中这份宽表格会由 Pandoc 渲染为longtable环境这正是与latex-env: output冲突的对象。2. 自定义浮动块与交叉引用::: {#out-2} ::: {.cell} ::: {.cell-output .cell-output-stdout}Call: aov(formula yield ~ block N * P K, data npk)Terms: block N P K N:P Residuals Sum of Squares 343.2950 189.2817 8.4017 95.2017 21.2817 218.9033 Deg. of Freedom 5 1 1 1 1 14Residual standard error: 3.954232 Estimated effects may be unbalanced::: ::: Sample ANOVA output ::: See out-2要点如下块引用目标::: {#out-2}是一个带 ID 的 fenced divout-前缀对应 YAML 中key: out2是自动分配或手动指定的编号最终引用形式为out-2代码输出单元格内部嵌套.cell与.cell-output .cell-output-stdout承载一次aov()方差分析的 stdout 输出题注文本div 内 Sample ANOVA output 一行作为该浮动块的题注引用语法正文末行See out-2使用key语法产生交叉引用渲染后在 PDF 中呈现为 Output 2前缀取自reference-prefix编号取自out-2。四、源码级原理crossref.custom 如何被解析理解上述配置如何生效需要追踪渲染管线中负责自定义交叉引用的 Lua 过滤器。核心实现在 src/resources/filters/crossref/custom.lua 的initialize_custom_crossref_categories(meta)函数中读取文档元数据meta[crossref][custom]若存在则设置全局标志flags.has_custom_crossrefs true遍历数组中的每一项通过映射表把 YAML 字段kebab-case转换为内部对象字段snake_case例如reference-prefix→name、caption-prefix→prefix、key→ref_type、latex-env→latex_envcaption-location缺省时补为bottomprefix缺省时复用name调用add_crossref_category(obj_entry)注册该类别。该函数定义在 src/resources/filters/mainstateinit.lua 中它将类别插入crossref.categories.all并重建按ref_type与按name索引的两个查找表by_ref_type/by_name。引用解析阶段由 src/resources/filters/crossref/refs.lua 的resolveRefs()处理遇到out-2这类引用时先从标签前缀反查类别refType(label)再按输出格式生成引用文本——LaTeX 输出注入\ref{label}若类别定义了custom_ref_command则注入对应自定义命令AsciiDoc 输出生成labelTypst 输出生成#ref(label, ...)其余格式则在 HTML/渲染层手工拼接前缀与编号。前缀文本的格式化逻辑位于 src/resources/filters/crossref/format.lua其titlePrefix()依据类别的space_before_numbering决定前缀与编号之间是否插入不间断空格。五、LaTeX 注入细节newfloat、floatstyle 与题注位置当输出格式为 PDF/LaTeX 时src/resources/filters/crossref/custom.lua 中quarto.doc.isFormat(pdf)分支Quarto 会向生成文档的导言区注入一段 LaTeX 代码为每个自定义类别声明一个真正的浮动环境\usepackage{float} \floatstyle{plain} \ifundefined{cchapter}{\newfloat{notoutput}{h}{loout}}{\newfloat{notoutput}{h}{loout}[chapter]} \floatname{notoutput}{Output}其中\newfloat{env}{h}{aux}借助float宏包声明新浮动环境辅助文件扩展名缺省为loref_type即loout若文档有\chapter结构如 book 项目则追加[chapter]使编号按章节重置\floatname{env}{Output}设置浮动环境的显示名称其文本取自reference-prefix或caption-prefix每个类别还会生成一个\listofenvs命令用于输出该对象的列表List of Outputs。caption-location选项会改变浮动样式默认bottom使用\floatstyle{plain}当配置为top时过滤器额外注入\floatstyle{plaintop}与\restylefloat{env}把题注移动到浮动块顶部src/resources/filters/crossref/custom.lua 中cap_location top分支。此外当space-before-numbering: false且前缀文本含空格时典型场景如reference-prefix: Table S过滤器会定义\quartoreftyperef这样的自定义引用命令、引入caption宏包并声明\DeclareCaptionLabelFormat确保题注与引用中前缀和编号之间都不留空格。六、关键限制latex-env 不得命名为 output这是 #8711 测试文档最核心的验证点。src/resources/filters/crossref/custom.lua 中有一段专门注释引用 issue 讨论并强制校验-- https://github.com/quarto-dev/quarto-cli/issues/8711#issuecomment-1946763141 -- using the name output for a new float environment -- very specifically causes problems with the longtable package, so we disallow it here. if env_name output then fail(The value output is not allowed for the latex-env entry in a custom float environment, as it conflicts with the longtable package. Please choose a different value.) return end即longtable宏包内部使用了名为output的环境/计数器若用户自定义的 float 环境也叫output生成的 LaTeX 将无法编译。由于 Schema 目前不支持否定式断言这个限制无法在 src/resources/schema/document-crossref.yml 中静态表达因此以运行时校验的形式实现在过滤器代码里——遇到该值会直接报错并终止。这也解释了测试文档为何刻意选择latex-env: notoutput既验证了自定义 float 类别与longtable表格在同一文档中共存的能力又规避了被禁用的保留名称。七、回归验证机制keep-md 与 ensureFileRegexMatches同一 issue 在仓库中留有三个验证变体可对照学习文件输出格式验证方式tests/docs/smoke-all/2024/02/12/8711.pdf.mdpdfkeep-md: true渲染 PDF 并保留中间 Markdowntests/docs/smoke-all/2024/02/13/8711.pdf.mdlatexensureFileRegexMatches断言存在\begin{longtable}tests/docs/smoke-all/2024/02/16/8711.pdf.mdlatexkeep-md: true断言同时存在\begin{longtable}与\begin{tabular}后两个变体在 YAML 中通过_quarto.tests.latex.ensureFileRegexMatches声明了对渲染产物的正则断言_quarto: tests: latex: ensureFileRegexMatches: - [\\\\begin\\{longtable] - []第一组正则必须命中第二组必须为空不允许匹配。其含义是即使文档中存在自定义 float 环境notoutputknitr::kable(mtcars)生成的宽表仍必须以longtable环境正常输出不能被自定义浮动环境或float宏包破坏。这正是一份回归测试应有的姿态——验证修复禁用output之后原有长表格能力不受影响。同时02/16 变体还验证了longtable与普通tabular表格在同一文档中并存。八、实战在自己的文档中定义自定义 float 类别参考仓库内更完整的示例 tests/docs/crossrefs/v1.4/custom-categories/diagrams.qmd一篇文档可以同时注册多个自定义类别crossref: custom: - kind: float key: dia reference-prefix: Diagram latex-env: diagram latex-list-of-file-extension: lod - kind: float key: vid reference-prefix: Video latex-env: video latex-list-of-file-extension: lov - kind: float key: supptbl reference-prefix: Table S space-before-numbering: false latex-env: supptbl latex-list-of-file-extension: lost随后用::: {#dia-1}、::: {#vid-1}、::: {#supptbl-1}包裹任意内容Mermaid 图、视频 shortcode、表格等并在正文中用dia-1、vid-1、supptbl-1引用。该示例还演示了space-before-numbering: false与自定义latex-list-of-file-extension的配合用法。实战中请特别注意以下约束kind目前只能是floatSchema 未开放其他类型latex-env禁止命名为output与longtable宏包冲突命名时避开longtable内部使用的保留字引用标签前缀要全局唯一key决定了 div ID 与引用标签的命名空间如dia、vid、supptbl避免与内置的fig、tbl、lst、eq、sec等冲突caption-location、space-before-numbering等选项只在 LaTeX 输出中产生对应的浮动样式调整HTML 等其他格式的行为以过滤器默认逻辑为准。总结crossref.custom是 Quarto 交叉引用体系中面向高级用户的扩展点它把自定义对象类别从 YAML 配置一路打通到 LaTeX 浮动环境的生成与引用解析。本文所依托的 #8711 测试文档不仅演示了完整的配置与正文写法更以回归测试的形式固化了latex-env命名的边界条件——理解这一限制能帮助你在实际项目中避免踩坑并借助ensureFileRegexMatches等测试机制为自己的文档建立可验证的渲染保障。赞分享开发工具文档【免费下载链接】quarto-cliOpen-source scientific and technical publishing system built on Pandoc.项目地址https://gitcode.com/gh_mirrors/qu/quarto-cli点击查看免费下载相关推荐Quarto CLI高级功能交叉引用、浮动图表、悬停引用的终极指南Quarto CLI高级功能交叉引用、浮动图表、悬停引用的终极指南 Quarto CLI是一个基于Pandoc的开源科学和技术出版系统提供了强大的文档编写和开发工具文档pandoc 如何解析 LaTeX 自定义环境\newenvironment从 8573 号回归测试看宏展开原理pandoc 如何解析 LaTeX 自定义环境\newenvironment从 8573 号回归测试看宏展开原理 导读 在把 LaTeX 文档转换为 Ma文档开发工具CLISphinx 代码块标题caption、命名锚点与交叉引用基于 caption.rst 测试用例的源码级解析Sphinx 代码块标题caption、命名锚点与交叉引用基于 caption.rst 测试用例的源码级解析 导读 本文以 Sphinx 仓库中的集成测试文档开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考