使用markdown,knitr和胶水从data.frame中自动格式化好格式的歌词书

时间:2018-07-12 16:24:36

标签: r markdown r-markdown knitr bookdown

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

您有一组存储在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>

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

换句话说,是否有一种方法可以一行一行地打印歌词行(\ 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循环分别打印每一行。但是应该有更好的解决方案)我希望印刷诗歌的方式。

1 个答案:

答案 0 :(得分:1)

  

换句话说,是否有一种方法可以一行一行地打印歌词行(\ 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>"))
}
```

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