首页 > 解决方案 > 使用markdown、knitr和glue从data.frame自动生成格式良好的歌词书

问题描述

这是上一个问题的扩展:Automating the generation of preformated text in Rmarkdown using R。这是任务:

您有一个存储在 中的歌词集合data.frame,其列是:歌词(\n每行末尾有很多)、歌曲名称、歌曲专辑、音乐作者、词作者、年份等...

现在你想使用markdown(or bookdown) 和glue包自动生成一本格式精美的诗歌书,它应该生成这样的 html:

<h1> Album name </h1>

<h2> Song name </h2>

<blockquote>
<cite>
Music: author_music <br>
Words: author_words
</cite>
<pre>
lyrics-line1
...
lyrics-lineN 
</pre>
</blockquote>

挑战在于,如果您使用Automating the generation of preformated text in Rmarkdown using R 中的代码,它会将所有歌词打印为一行:歌词行\n...\nlyrics-lineN

换句话说,有没有办法逐行打印歌词行 (line\n ... \nlyrics-lineN),而不是一个连接的行?

这是可用于获取要播放的歌词数据的代码:

library(data.table); library(magrittr); library(knitr); library(stringr);library(dplyr)
dt <- fread("https://s3.amazonaws.com/assets.datacamp.com/blog_assets/prince_raw_data.csv")
dt <- dt[301:303,2:6] #take three songs only 
dt %>% names
dt %>% kable() # just to view the lyrics in your console.

注意:该kable()函数不会替换\n<br>我们想要的。
所以如果你用它来生成你的诗歌的 html,你会遇到同样的问题 - 而不是一个有很多行的诗句,你会得到一个长的连接行。

PS。避免该问题的一种方法是将原始文本字符串拆分为许多单行字符串(例如,通过使用str_split(dt$text, '\n')然后使用for循环分别打印每一行。但我希望应该有更好的打印诗句的方法。

标签: rmarkdownr-markdownknitrbookdown

解决方案


换句话说,有没有办法逐行打印歌词行 (line\n ... \nlyrics-lineN),而不是一个连接的行?

它是连接的,因为这是一个降价规则,每行末尾需要两个空格。

<pre> <\pre>我的解决方案是在您周围添加原始 html 标记,dt$text以保护它们不被 markdown 语法解析:

(但是我注意到这<pre>会将文本呈现为代码块,嗯)

```{r echo=FALSE, results='asis'}
for (i in 1:nrow(dt)){
  album = dt$album[i]
  song = dt$song[i]
  lyrics = dt$text[i]

  cat(glue::glue("# {album}\n\n"))
  cat(glue::glue("## {song}\n\n"))
  cat(glue::glue("<pre>{lyrics}</pre>"))
}
```

输出

源 rmd

或者,替换\n\n(在 \n 之前插入两个空格),不带glue

```{r echo=FALSE, results='asis'}

dt$text <- gsub("\n","  \n",dt$text)

for (i in 1:nrow(dt)){
  cat(paste0("# ",dt$album[i],"\n\n"))
  cat(paste0("## ",dt$song[i],"\n\n"))
  cat(paste0("> ",dt$text[i]))
  cat("\n\n")
}
```

推荐阅读