R语言 夸托交叉引用:文本更改时的永久交叉引用

gblwokeq  于 2023-01-18  发布在  其他
关注(0)|答案(2)|浏览(149)

我正在使用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交叉引用文档中有各种各样的选项。但是,我看不到一种方法,使交叉引用文本在章节标题更新时更新,前提是显式标识符保持不变。
这个存在吗?

kx7yvsdv

kx7yvsdv1#

我已经编写了一个Lua filtername_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-idlink-title,在第二个div中,我们需要添加另一个类cell-output-display。类似地,然后使用我们分配给link-id的id来引用使用\nameref{id}生成的表/图像。

---
title: "Cross Referencing the Name"
author: Shafee
format: 
  html: default
  pdf: default
number-sections: true
filters: 
  - name_crossref.lua
---

# Why Quarto is so great {#sec-stack}

`r stringi::stri_rand_lipsum(1)`
See \nameref{sec-stack}.

## How it is so {#how}

`r stringi::stri_rand_lipsum(1)`
See \nameref{how}.

## Images

```{r}
#| classes: link
#| link-id: fig1
#| link-title: My Awesome plot

plot(1:10)

r stringi::stri_rand_lipsum(1)
see \nameref{fig1}

Tables

#| classes: link
#| link-id: tab1
#| link-title: Mtcars Data

head(mtcars)

r stringi::stri_rand_lipsum(1)
see \nameref{tab1}

Markdown Images

:::: {.link link-id="fig2" link-title="Scatter plot of mpg"}
::: {.cell-output-display}

mpg
:::
::::

r stringi::stri_rand_lipsum(4)

see \nameref{fig2}

Markdown Table

:::: {.link link-id="tab2" link-title="Markdown table"}
::: {.cell-output-display}

Col1Col2Col3
ABC
EFG
AGG

: My Caption

:::
::::

r stringi::stri_rand_lipsum(4)

see \nameref{tab2}


* * 名称_交叉引用. lua**

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,

  Div = function(el)
    if el.attributes["link-id"] then
      local id = el.attributes["link-id"]
      local text = el.attributes["link-title"]
      table.insert(data, {id = id, text = text})
    end
  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


##### 生成的输出的第一部分

![](https://i.stack.imgur.com/dJdyO.png)
cedebl8k

cedebl8k2#

经过一些实验,这是一种基于this TeX SE答案的LaTeX方法。
我们在标题中加载nameref包,然后将夸托引用从@sec-stack更改为\nameref{sec-stack}。更改章节标题后,引用仍然存在,例如更改为 * 为什么我喜欢堆栈溢出 *:

---
format:   
  pdf:
    number-sections: true
header-includes:
 \usepackage{nameref}
---

# Why I love Stack Overflow {#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 \nameref{sec-stack}.

缺点是这不是一个原生的夸托解决方案,并且不会呈现为其他格式,例如HTML。但是,它可以工作,并且它是一个简单的一次性正则表达式替换来更改所有引用。我还没有接受这个答案,如果有一个原生的Quarto答案,我会接受。

相关问题