使用 markdown、knitr 和 glue 从 data.frame 中自动编排精美的歌词集

Automated nicely formated book of lyrics from data.frame using markdown, knitr and glue

这是上一个问题的扩展:。这是任务:

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

现在您想使用 markdown(或 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>

挑战在于,如果您使用 中的代码,它会将所有歌词打印为一长行: lyrics-line\n...\n歌词行 N

换句话说,有没有办法逐行打印歌词行 (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 循环分别打印每一行。但是应该有更好的方法我希望打印诗句的方式。

In other words, is there a way to print lyrics lines (line\n ... \nlyrics-lineN) line by line, rather than one concatenated line ?

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

我的解决方案是在 dt$text 周围添加原始 html 标签<pre> <\pre> 以保护它们不被 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>"))
}
```

output

source 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")
}
```