我正在使用Quarto创建一个长PDF报告。我想包括两种格式的交叉引用:
1.至章节/图号,例如
如 * 第3.1节 * 所述
1.至章节/图标题,例如
如 * 我的真棒部分 * 所述。
可以像这样实现:
---
format:
pdf:
number-sections: true
---
# Why Stack Overflow is so great {#sec-stack}
I can use style 1, the section number, with the explicit ID, e.g. as seen in @sec-stack.
I can use style 2, the section title, with a link [Why Stack Overflow is so great].
I can also custom text with [Custom text before the link][Why Stack Overflow is so great].
这将产生所需的输出:
问题
问题是文档是由多个作者重新起草的,如果一个章节标题从 * 为什么Stack Overflow如此伟大 * 更改为 * 为什么我喜欢Stack Overflow *,它将使用第二种样式(章节标题)来破坏交叉引用。
我正在寻找一种方法来引用一个使用显式标识符@sec-stack
的节,并让它显示标题而不是节号。这将是类似[@sec-stack]
而不是@sec-stack
。
在Quarto交叉引用文档中有各种各样的选项。但是,我看不到一种方法,使交叉引用文本在章节标题更新时更新,前提是显式标识符保持不变。
这个存在吗?
2条答案
按热度按时间kx7yvsdv1#
我已经编写了一个Lua filter
name_crossref.lua
来获取交叉引用文本,而不是章节/图/表编号。下面的方法适用于HTML和PDF输出格式。用法:
1.对于节或子节标题,它的使用非常简单,我们只需要使用
\nameref{sec-id}
,其中sec-id
是在标题中使用的节标识符,如#sec-id
1.对于从代码块生成的图像或表格,我们需要使用一些块选项。我们需要使用
link
作为代码块类,需要定义一个id,以便稍后使用link-id
交叉引用图像或表格,并且需要定义将用作与link-title
的交叉引用文本的标题。然后使用我们分配给link-id
的id引用使用\nameref{id}
生成的表/映像。1.对于用markdown语法或markdown表添加的图像,使用这个过滤器有点笨拙。(使用pandoc div语法创建,
::::
用于外部div,:::
用于内部div)。在第一个div中,我们必须添加link
类,link-id
,link-title
,在第二个div中,我们需要添加另一个类cell-output-display
。类似地,然后使用我们分配给link-id
的id来引用使用\nameref{id}
生成的表/图像。r stringi::stri_rand_lipsum(1)
see \nameref{fig1}
Tables
r stringi::stri_rand_lipsum(1)
see \nameref{tab1}
Markdown Images
:::: {.link link-id="fig2" link-title="Scatter plot of mpg"}
::: {.cell-output-display}
:::
::::
r stringi::stri_rand_lipsum(4)
see \nameref{fig2}
Markdown Table
:::: {.link link-id="tab2" link-title="Markdown table"}
::: {.cell-output-display}
: My Caption
:::
::::
r stringi::stri_rand_lipsum(4)
see \nameref{tab2}
local str = pandoc.utils.stringify
function get_header_data(data)
local get_headers = {
Header = function(el)
local id = el.identifier
local text = str(el.content):gsub("^[%d.]+ ", "")
table.insert(data, {id = id, text = text})
end,
return get_headers
end
function change_ref(data)
local change_rawinline = {
RawInline = function(el)
for key, value in pairs(data) do
if el.text:match("\nameref{(.*)}") == value.id then
local target = "#" .. value.id
local link = pandoc.Link(value.text, target)
return link
end
end
end
}
return change_rawinline
end
local function add_div_id(div)
return {
Div = function(elem)
if elem.classes:includes("cell-output-display")
or elem.classes:includes("cell-output-stdout")then
elem.identifier = div.attributes["link-id"]
return elem
end
end
}
end
function Div(el)
if el.classes:includes('link') then
return el:walk(add_div_id(el))
end
end
function Pandoc(doc)
local header_data = {}
doc:walk(get_header_data(header_data))
return doc:walk(change_ref(header_data))
end
cedebl8k2#
经过一些实验,这是一种基于this TeX SE答案的LaTeX方法。
我们在标题中加载
nameref
包,然后将夸托引用从@sec-stack
更改为\nameref{sec-stack}
。更改章节标题后,引用仍然存在,例如更改为 * 为什么我喜欢堆栈溢出 *:缺点是这不是一个原生的夸托解决方案,并且不会呈现为其他格式,例如HTML。但是,它可以工作,并且它是一个简单的一次性正则表达式替换来更改所有引用。我还没有接受这个答案,如果有一个原生的Quarto答案,我会接受。