这是上一个问题的扩展:使用R在Rmarkdown中自动生成预格式化文本。任务如下:
您有一个存储在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>
挑战在于,如果您使用R在Rmarkdown中自动生成预格式化文本的代码,它将把所有歌词打印成一行:歌词行\n。。。\nlyrics lineN
换句话说,有没有一种方法可以逐行打印歌词(line\n…\lyrics 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()
函数并没有用<br>
代替n
,这是我们想要的。
所以,如果你用它来生成诗歌的html,你会遇到同样的问题——你会得到一个长的串联行,而不是一首有很多行的诗歌。
PS。解决这个问题的一种方法是将原始文本字符串拆分为多个单行字符串(例如,使用str_split(dt$text, 'n')
,然后使用for
循环分别打印每一行。但我希望应该有更好的方法打印诗句。
换句话说,有没有一种方法可以逐行打印歌词(line\n…\nlyrics lineN(,而不是一行一行地打印?
它是串联的,因为这是一个markdown规则,需要在每行的末尾有两个空格。
我的解决方案是在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}nn"))
cat(glue::glue("## {song}nn"))
cat(glue::glue("<pre>{lyrics}</pre>"))
}
```
输出
源rmd
或者,用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],"nn"))
cat(paste0("## ",dt$song[i],"nn"))
cat(paste0("> ",dt$text[i]))
cat("nn")
}
```