使用 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>"))
}
```
或者,将\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")
}
```
这是上一个问题的扩展:
您在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>
挑战在于,如果您使用
换句话说,有没有办法逐行打印歌词行 (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>"))
}
```
或者,将\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")
}
```