【问题标题】:Create index of definitions / theorems at end of bookdown book在 bookdown 书的末尾创建定义/定理索引
【发布时间】:2016-11-22 07:08:20
【问题描述】:

为了方便读者,我想在我的 bookdown 书的末尾,用 Markdown 写一个简单的书体定义列表或索引。即使用自定义块创建的,如下所示:

```{definition, bar, echo=T}
A bar is defined here as a foo-like thing.
```

(我需要定义,但其他人可能喜欢定理列表等。不知道图表列表是否可以以相同的方式涵盖?)

感谢@yihui 我知道knitr::all_labels(engine == 'definition') 是我的朋友。

所以我可以在本书末尾的任何地方执行此操作,通常在末尾:

```{r comment="",results="asis",echo=FALSE}
knitr::all_labels(engine == 'definition') %>% unlist %>% paste0("\n\n","\\@ref(def:",.,"): ",.,"\n\n",collapse="\n\n") %>% cat

```

打印这个:

1: bar

2: foobar

带有可点击的数字。没关系。但是,如果在每个标签之后也可以打印实际定义,那不是很好吗? (块的内容在 knitr::all_labels(engine == 'definition') 中不可用)

【问题讨论】:

    标签: r markdown knitr bookdown


    【解决方案1】:

    这是一个使用输出格式bookdown::html_document2 的示例,它也应该适用于任何其他书籍输出格式:

    ---
    title: "Test Definitions"
    output: bookdown::html_document2
    ---
    
    ```{r setup, include=FALSE}
    def_list = list()
    knitr::knit_hooks$set(engine = function(before, options) {
      if (before && options$engine == 'definition') {
        # collect definition terms from options$name
        def_list[[options$label]] <<- options$name
      }
      NULL
    })
    ```
    
    ```{definition, d1, name='Foo'}
    Foo is defined as ...
    ```
    
    ```{definition, d2, name='Bar'}
    Bar is defined as ...
    ```
    
    All definitions in this document:
    
    ```{r echo=FALSE, results='asis'}
    def_list = unlist(def_list)
    cat(sprintf('- \\@ref(def:%s) %s', names(def_list), def_list), sep = '\n')
    ```
    

    输出:

    基本思想是使用块挂钩来收集定义标签和名称,并在最后打印出来。您不必使用块选项name。它可以是任意选项,例如termname 选项很特殊,因为定义的名称将打印在输出中。如果你不喜欢这样,你可以使用,例如,term

    ```{definition, d2, term='Bar'}
    Bar is defined as ...
    ```
    

    【讨论】:

    • 太棒了...所以是否可以使用相同的钩子来收集块的 contents 以便能够打印定义中的内容最后的定义列表,不只是名称和链接?我想我可以尝试在文档末尾使用类似 ref.label 的东西来重新使用定义块内容
    • chunk的内容不能从chunk hook中获取,但是你可以从knitr:::knit_code$get(a_vector_of_chunk_labels)获取它
    • 有没有办法使用all_labels() 访问用code 填充的空块的内容? knitr::opts_chunk$get("code") 之类的东西?
    • 此代码示例仅适用于一个列表,例如 options$engine = 'definition'。但是如何添加另一个列表,比如“定理”?将列表更改为 thm_list() 和 options$engine == 'theorem' 并相应地更改最后一个块对我不起作用。
    【解决方案2】:

    完美,再加上一辉的建议,这也打印出定义,无需费心名称,只需标签即可:

    ```{definition, 'Bar',echo=T,cache=F}
    Bar is defined as something
    ```
    
    ```{definition, 'Bar2',echo=T,cache=F}
    Bar2 is defined as something else.
    ```
    
    Here are all the definitions in this book.
    
    ```{r comment="",results="asis",echo=FALSE,cache=F}
    
    
    for(x in knitr::all_labels(engine == 'definition')){
       paste0("\n\n","\\@ref(def:",x,"): ",x,"\n\n>",knitr:::knit_code$get(x),collapse="\n\n") %>% cat
    } 
    
    ```
    

    ...产生这个:

    这是本书中的所有定义。

    1:条形

    Bar 被定义为某物

    2:小节2

    Bar2 被定义为别的东西。

    【讨论】:

      猜你喜欢
      • 2020-01-21
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多