如何用R提取多子文件夹PDF代码并转换为.ipynb格式
解决PDF转Jupyter Notebook格式问题的方案
一、优化PDF文本提取,避免换行丢失
别直接用pdf_text()抽纯文本,改用pdf_data()提取结构化的行信息,能精准保留原PDF的换行和排版:
library(pdftools) pdf_path <- "目标文件.pdf" pdf_data <- pdf_data(pdf_path) # 按页分组拼接每行内容,严格保留换行 txt_content <- lapply(pdf_data, function(page) { # 按y坐标分组,把同一行的文本拼起来 lines <- split(page$text, page$y) sapply(lines, paste, collapse = " ") }) %>% unlist() %>% paste(collapse = "\n") # 保存时用UTF-8编码,避免乱码 writeLines(txt_content, "output.txt", useBytes = TRUE)
如果PDF里有代码块,pdf_data()能更好区分代码和普通文本,方便后续加markdown标记。
二、调整pandoc参数,解决转义和单元格合并问题
- 消除括号前的反斜杠:pandoc默认会转义markdown特殊字符,加
--no-escape参数关闭自动转义,同时指定输入为纯文本格式:
pandoc -s -f plain -t ipynb --no-escape input.txt -o output.ipynb
- 拆分单元格:pandoc默认把纯文本全塞进一个markdown单元格,你需要在提取的txt里用
---(三个短横线)作为单元格分隔符,代码块要包裹在```里(指定语言),比如:
这是第一部分说明文本 --- ```r # 这里是R代码块 print("转换测试")
这是第二部分说明文本
这样转换后会生成三个独立单元格:两个markdown,一个代码。 ## 三、用R批量处理格式标记 如果要处理大量PDF,可以写个正则脚本自动识别代码块并添加标记,同时插入单元格分隔符: ```r # 假设代码块以4个空格缩进或#开头,自动包裹R代码标记 txt_content <- gsub("(^ {4}.*$|^#.*$)", "```r\n\\1\n```", txt_content, perl = TRUE) # 给标题(比如以#开头的行)后面加单元格分隔符 txt_content <- gsub("(^#.*$)", "\\1\n---", txt_content, perl = TRUE)
注意:不同PDF的代码格式不同,需要根据实际调整正则规则,比如Python代码就把r换成python。
四、绕开pandoc,直接用R生成ipynb
.ipynb本质是JSON格式,直接用R构建结构能完全控制单元格类型和内容,彻底避免pandoc的格式问题:
library(jsonlite) # 定义单元格列表,按需添加更多单元格 cells <- list( list( cell_type = "markdown", metadata = list(), source = c("从PDF提取的说明文本") ), list( cell_type = "code", metadata = list(), source = c("# 提取的R代码", "x <- 1:10", "mean(x)") ) ) # 构建完整的notebook结构 notebook <- list( cells = cells, metadata = list( kernelspec = list( display_name = "R", language = "r", name = "ir" ), language_info = list( codemirror_mode = "r", file_extension = ".r", mimetype = "text/x-r-source", name = "R", pygments_lexer = "r", version = "4.3.0" ) ), nbformat = 4, nbformat_minor = 5 ) # 保存为.ipynb文件 write_json(notebook, "output.ipynb", auto_unbox = TRUE, pretty = TRUE)
这种方法适合批量处理时的定制化需求,完全可控。
内容的提问来源于stack exchange,提问作者Pål Bjartan
相关产品推荐
相关产品推荐

