【问题标题】:Adding automatically/manually sections to package documentation将自动/手动部分添加到包文档中
【发布时间】:2020-08-24 08:58:31
【问题描述】:

我已经构建了我的包并使用devtools::build_manual() 来构建包文档。问题是我的所有功能都在“记录的 R 主题”部分中,但我不知道如何更改它。我的目标是在没有它的情况下拥有几个“记录 R 主题”的部分。我不知道该怎么做,我试着做@describeIn@section,但都没有工作。你知道我该怎么做吗?

UPGRADE vol 1(根据 Abdessabour 的代码)

您好,我想告诉您我非常感谢您的工作,我知道您肯定会花费大量时间来做这件事。我对您的代码有直觉,这太棒了。我有两个关于你的代码的问题,我没有 100% 回答。

(1) 我可以在您的代码中哪里定义我想要的部分?我理解 如何 制作它们背后的直觉,但不太了解 在代码中的确切位置 是制作它们的地方。因此,例如 A 部分中的函数 (1) 和 (2),B 部分中的函数 (3) 和 (4) 等等。

(2) 运行代码后如何创建 pdf。我应该只运行devtools::build_manual() 吗?

升级第 2 卷

嗨!我理解你的思维方式,但我有一个问题想告诉你。假设我的包裹名称为“visualise”。那是“可视化”包文件夹中的文件。

visualise.R 在部分中包含我的函数。我将该文件放入包文件夹中(如您所见)

我尝试通过@import@importClassesFrom@importFrom@importMethodFrom 将该文件导入 R,但它们都不起作用。我认为 R 可能无法识别该文件。我有顾虑,因为在创建 visualise.R 文件后我运行 build_manual(toc="anything") 并在输出中获得默认文档(与 build_manual() 创建的相同)你知道我做错了什么吗?

升级第三卷

我已将 visualise.R 放在 R_HOME 文件夹和 R_HOME/bin 中,但它对这两个选项都不起作用。我把 R_HOME/bin/Rd2pdf 代码的内容放在下面:

tex.mod <- function(pkg='.', file='Rd2.tex',  tocTi = "R{} topics documented:"){
  
  library(stringr)
  #get the package name
  pkg <- devtools::as.package(pkg)$package
  #reads the latex file
  out <- readLines(file)
  # modifies the Table of contents title
  out[rdcont] <- sub("(?<=\\\\Rdcontents\\{).+(?=}$)", tocTi, out[rdcont <- grep('\\\\Rdcontents', out)], perl=T)
  # Gets the defined sections
  sections <- str_replace_all(strcapture(paste0("(?s)^.+?\\\\HeaderA\\{",pkg,"\\}.+?(\\\\begin\\{Section\\}.+\\\\end{Section})\n\\\\inputencoding\\{.+$"), paste0(out, collapse='\n'), data.frame(v=character(0)), perl=T)[1,1],  c('\\\\begin\\{Section\\}\\{(.+?) *\\}\n'='\\1\n', '^\n'='', '\n$'='', '\n%?\n'='\n'))
  # splits sections
  spl <- str_split(sections, '\n?\\\\end.+?(\n|$)')[[1]]
  spl <- str_split(spl[nchar(spl)>0], '\n')
  
  #gets the package description
  pkgdesc <- out[1:rdcont]
  # gets the trailing lines
  trailing <- out[length(out)+(-1:0)]
  # get the descriptions
  outi<- str_split(paste0(out[(rdcont+2):(length(out)-2)], collapse='\n'), '\\\\inputencoding.+\n')[[1]]
  # sets the names to th name of the function/package described
  names(outi) <- str_extract(outi, '(?<=\\\\HeaderA\\{).+?(?=\\})')
  # adds lines to add to the toc file if you want more indentation put section instead of chapter
  outi <- c(outi, sapply(spl, function(x) {v<-paste0("\\myaddcontentsline{toc}{chapter}{\\protect\\textbf{", x[1],"}}"); names(v)<-x[1]; v})) 
  # unlists the names of the sections with their functions
  spl <- unlist(spl)
  # orders them so that the functions that have no section are shown first
  outi <- c(pkgdesc, outi[!(names(outi) %in% spl)], outi[spl], trailing)
  # writes to file
  if (require(data.table)){
    # the data.table way
    fwrite(list( outi), quote=F, sep='\n', file=file, append=F)
  } else {
    # the baseR way
    fileConn<-file(file, open='w')
    writeLines(outi, fileConn)
    close(fileConn)
  }
  
}
..Rd2pdf <- function (args = NULL, quit = TRUE) 
{
    do_cleanup <- function() {
        if (clean) {
            setwd(startdir)
            unlink(build_dir, recursive = TRUE)
        }
        else {
            cat("You may want to clean up by 'rm -Rf ", build_dir, 
                "'\n", sep = "")
        }
    }
    Usage <- function() {
        cat("Usage: R CMD Rd2pdf [options] files", "", "Generate PDF output from the Rd sources specified by files, by", 
            "either giving the paths to the files, or the path to a directory with", 
            "the sources of a package, or an installed package.", 
            "", "Unless specified via option '--output', the basename of the output file", 
            "equals the basename of argument 'files' if this specifies a package", 
            "or a single file, and 'Rd2' otherwise.", "", "The Rd sources are assumed to be ASCII unless they contain \\encoding", 
            "declarations (which take priority) or --encoding is supplied or if using", 
            "package sources, if the package DESCRIPTION file has an Encoding field.", 
            "The output encoding defaults to the package encoding then to 'UTF-8'.", 
            "", "Files are listed in the order given: for a package they are in alphabetic", 
            "order of the \\name sections.", "", "Options:", 
            "  -h, --help\t\tprint short help message and exit", 
            "  -v, --version\t\tprint version info and exit", 
            "      --batch\t\tno interaction", "      --no-clean\tdo not remove created temporary files", 
            "      --no-preview\tdo not preview generated PDF file", 
            "      --encoding=enc    use 'enc' as the default input encoding", 
            "      --outputEncoding=outenc", "                        use 'outenc' as the default output encoding", 
            "      --os=NAME\t\tuse OS subdir 'NAME' (unix or windows)", 
            "      --OS=NAME\t\tthe same as '--os'", "  -o, --output=FILE\twrite output to FILE", 
            "      --force\t\toverwrite output file if it exists", 
            "      --title=NAME\tuse NAME as the title of the document", 
            "      --toc=NAME   use NAME as the title of the Table of contents", 
            "      --no-index\tdo not index output", "      --no-description\tdo not typeset the description of a package", 
            "      --internals\ttypeset 'internal' documentation (usually skipped)", 
            "      --build_dir=DIR\tuse DIR as the working directory", 
            "      --RdMacros=pkglist", "             \t\tpackages from which to get Rd macros", 
            "", "The output papersize is set by the environment variable R_PAPERSIZE.", 
            "The PDF previewer is set by the environment variable R_PDFVIEWER.", 
            "", "Report bugs at <https://bugs.R-project.org>.", 
            sep = "\n")
    }
    options(showErrorCalls = FALSE, warn = 1)
    if (is.null(args)) {
        args <- commandArgs(TRUE)
        args <- paste(args, collapse = " ")
        args <- strsplit(args, "nextArg", fixed = TRUE)[[1L]][-1L]
    }
    startdir <- getwd()
    if (is.null(startdir)) 
        stop("current working directory cannot be ascertained")
    build_dir <- paste0(".Rd2pdf", Sys.getpid())
    title <- ""
    tocTi <- ""
    batch <- FALSE
    clean <- TRUE
    only_meta <- FALSE
    out_ext <- "pdf"
    output <- ""
    enc <- "unknown"
    outenc <- "latin1"
    index <- TRUE
    description <- TRUE
    internals <- FALSE
    files <- character()
    dir <- ""
    force <- FALSE
    pkglist <- NULL
    WINDOWS <- .Platform$OS.type == "windows"
    preview <- Sys.getenv("R_PDFVIEWER", if (WINDOWS) 
        "open"
    else "false")
    OSdir <- if (WINDOWS) 
        "windows"
    else "unix"
    while (length(args)) {
        a <- args[1L]
        if (a %in% c("-h", "--help")) {
            Usage()
            q("no", runLast = FALSE)
        }
        else if (a %in% c("-v", "--version")) {
            cat("Rd2pdf: ", R.version[["major"]], ".", R.version[["minor"]], 
                " (r", R.version[["svn rev"]], ")\n", sep = "")
            cat("", "Copyright (C) 2000-2011 The R Core Team.", 
                "This is free software; see the GNU General Public License version 2", 
                "or later for copying conditions.  There is NO warranty.", 
                sep = "\n")
            q("no", runLast = FALSE)
        }
        else if (a == "--batch") {
            batch <- TRUE
        }
        else if (a == "--no-clean") {
            clean <- FALSE
        }
        else if (a == "--no-preview") {
            preview <- "false"
        }
        else if (a == "--pdf") {
        }
        else if (substr(a, 1, 8) == "--title=") {
            title <- substr(a, 9, 1000)
        }
        else if (substr(a, 1, 6) == "--toc=") {
            tocTi <- sub("--toc=", "", a)
        }
        else if (a == "-o") {
            if (length(args) >= 2L) {
                output <- args[2L]
                args <- args[-1L]
            }
            else stop("-o option without value", call. = FALSE)
        }
        else if (substr(a, 1, 9) == "--output=") {
            output <- substr(a, 10, 1000)
        }
        else if (a == "--force") {
            force <- TRUE
        }
        else if (a == "--only-meta") {
            only_meta <- TRUE
        }
        else if (substr(a, 1, 5) %in% c("--os=", "--OS=")) {
            OSdir <- substr(a, 6, 1000)
        }
        else if (substr(a, 1, 11) == "--encoding=") {
            enc <- substr(a, 12, 1000)
        }
        else if (substr(a, 1, 17) == "--outputEncoding=") {
            outenc <- substr(a, 18, 1000)
        }
        else if (substr(a, 1, 12) == "--build-dir=") {
            build_dir <- substr(a, 13, 1000)
        }
        else if (a == "--no-index") {
            index <- FALSE
        }
        else if (a == "--no-description") {
            description <- FALSE
        }
        else if (a == "--internals") {
            internals <- TRUE
        }
        else if (substr(a, 1, 11) == "--RdMacros=") {
            pkglist <- substr(a, 12, 1000)
        }
        else if (startsWith(a, "-")) {
            message("Warning: unknown option ", sQuote(a))
        }
        else files <- c(files, a)
        args <- args[-1L]
    }
    if (!length(files)) {
        message("no inputs")
        q("no", status = 1L, runLast = FALSE)
    }
    if (WINDOWS) 
        files[1L] <- sub("[\\/]$", "", files[1L])
    if (dir.exists(files[1L])) {
        if (file.exists(file.path(files[1L], "DESCRIPTION"))) {
            cat("Hmm ... looks like a package\n")
            dir <- files[1L]
            if (!nzchar(output)) 
                output <- paste(basename(dir), out_ext, sep = ".")
        }
        else if (file.exists(f <- file.path(files[1L], "DESCRIPTION.in")) && 
            any(grepl("^Priority: *base", readLines(f)))) {
            cat("Hmm ... looks like a package from the R distribution\n")
            dir <- files[1L]
            if (!nzchar(output)) 
                output <- paste(basename(dir), out_ext, sep = ".")
            if (index && basename(dir) == "base") {
                index <- FALSE
                cat("_not_ indexing 'base' package\n")
            }
        }
        else {
            dir <- if (dir.exists(d <- file.path(files[1L], "man"))) 
                d
            else files[1L]
        }
    }
    else {
        if (length(files) == 1L && !nzchar(output)) 
            output <- paste(sub("[.][Rr]d$", "", basename(files)), 
                out_ext, sep = ".")
    }
    if (!nzchar(dir)) 
        dir <- paste(files, collapse = " ")
    if (dir.exists(build_dir) && unlink(build_dir, recursive = TRUE)) {
        cat("cannot write to build dir\n")
        q("no", status = 2L, runLast = FALSE)
    }
    dir.create(build_dir, FALSE)
    if (!nzchar(output)) 
        output <- paste0("Rd2.", out_ext)
    if (file.exists(output) && !force) {
        cat("file", sQuote(output), "exists; please remove it first\n")
        q("no", status = 1L, runLast = FALSE)
    }
    res <- try(tools:::.Rd2pdf(files[1L], file.path(build_dir, "Rd2.tex"), 
        title, batch, description, only_meta, enc, outenc, dir, 
        OSdir, internals, index, pkglist))
    if (inherits(res, "try-error")) 
        q("no", status = 11L, runLast = FALSE)
    if (!batch) 
        cat("Creating", out_ext, "output from LaTeX ...\n")
    setwd(build_dir)
    tocTi <- if(nchar(tocTi)>0) tocTi else "\\R{} topics documented:"
    tex.mod(pkg=files[1L], file="Rd2.tex", tocTi=tocTi)
    res <- try(tools:::texi2pdf("Rd2.tex", quiet = FALSE, index = index))
    if (inherits(res, "try-error")) {
        res <- try(tools:::texi2pdf("Rd2.tex", quiet = FALSE, index = index))
        if (inherits(res, "try-error")) {
            message("Error in running tools::tools:::texi2pdf()")
            do_cleanup()
            q("no", status = 1L, runLast = FALSE)
        }
    }
    setwd(startdir)
    cat("Saving output to", sQuote(output), "...\n")
    file.copy(file.path(build_dir, paste0("Rd2.", out_ext)), 
        output, overwrite = force)
    cat("Done\n")
    do_cleanup()
    if (preview != "false") 
        system(paste(preview, output))
    if (quit) 
        q("no", runLast = FALSE)
}
..Rd2pdf()

升级第 4 卷

我正在使用以下代码:

# modifies the latex of the converted .Rd files
# in order to add sections to the toc
tex.mod <- function(pkg='.', file='Rd2.tex',  tocTi = "R{} topics documented:"){
  
  library(stringr)
  #get the package name
  pkg <- devtools::as.package(pkg)$package
  #reads the latex file
  out <- readLines(file)
  # modifies the Table of contents title
  out[rdcont] <- sub("(?<=\\\\Rdcontents\\{).+(?=}$)", tocTi, out[rdcont <- grep('\\\\Rdcontents', out)], perl=T)
  # Gets the defined sections
  sections <- str_replace_all(strcapture(paste0("(?s)^.+?\\\\HeaderA\\{",pkg,"\\}.+?(\\\\begin\\{Section\\}.+\\\\end{Section})\n(?:\\\\inputencoding\\{|\n?\\\\printindex).+$"), paste0(out, collapse='\n'), data.frame(v=character(0)), perl=T)[1,1],  c('\\\\begin\\{Section\\}\\{(.+?) *\\}\n'='\\1\n', '^\n'='', '\n$'='', '\n%?\n'='\n'))
  
  # splits sections
  spl <- str_split(sections, '\n?\\\\end.+?(\n|$)')[[1]]
  spl <- str_split(spl[nchar(spl)>0], '\n')
  
  #gets the package description
  pkgdesc <- out[1:rdcont]
  # gets the trailing lines
  trailing <- out[length(out)+(-1:0)]
  # get the descriptions
  outi<- str_split(paste0(out[(rdcont+2):(length(out)-2)], collapse='\n'), '\\\\inputencoding.+\n')[[1]]
  # sets the names to th name of the function/package described
  names(outi) <- str_extract(outi, '(?<=\\\\HeaderA\\{).+?(?=\\})')
  # adds lines to add to the toc file if you want more indentation put section instead of chapter
  outi <- c(outi, sapply(spl, function(x) {v <- paste0("\\chapter{", x[1],"}", '\n', "\\myaddcontentsline{toc}{chapter}{\\protect\\textbf{", x[1],"}}"); names(v)<-x[1]; v})) 
  # unlists the names of the sections with their functions
  spl <- unlist(spl)
  # orders them so that the functions that have no section are shown first
  outi <- c(pkgdesc, "\\renewcommand\\thesection{}", outi[!(names(outi) %in% c(spl, pkg))], outi[spl], trailing)
  # writes to file
  if (require(data.table)){
    # the data.table way
    fwrite(list( outi), quote=F, sep='\n', file=file, append=F)
  } else {
    # the baseR way
    fileConn<-file(file, open='w')
    writeLines(outi, fileConn)
    close(fileConn)
  }
  
}

write.fun <- function(fun, path){
  fun.src <- capture.output(fun)
  fun.name <- as.character(substitute(fun))
  fun.src[1] <- paste0(fun.name[length(fun.name)],' <- ', fun.src[1])
  fun.src<-fun.src[!grepl('^<.+?>$',fun.src)]
  if (require(data.table)){
    # the data.table way
    fwrite(list(fun.src), quote=F, sep='\n', file=path, append=T)
  } else {
    # the baseR way
    fileConn<-file(path, open='a')
    writeLines(fun.src, fileConn)
    close(fileConn)
  }
}
# get the location of R_HOME
Rh <- Sys.getenv('R_HOME')
f <- file.path(Rh, 'bin', 'Rd2pdf.overload.R')
file.create(f)

# adds the function to the file
write.fun(tex.mod,f)
write.fun(tools:::..Rd2pdf,f)

# reads the file
out <- readLines(f)
# forces all functions to be loaded from tools
out <- gsub('(?=(.DESCRIPTION_to_latex|.Rdfiles2tex|latex_canonical_encoding|texi2pdf|.Rd2pdf)\\()', "tools:::", out, perl=T)
# add param description to usage
out[i] <- paste(out[i <- grep('--title=NAME', out, fixed=T)], '            "      --toc=NAME\tuse NAME as the title of the Table of contents", ', sep='\n' )
# parses param
out[grep('substr(a, 1, 8) == "--title="', out, fixed=T)+2] <- paste('        }', '        else if (substr(a, 1, 6) == "--toc=") {', '            tocTi <- sub("--toc=", "", a)', '        }', sep='\n')
# adds definition
out[grep('    title <- ""', out, fixed=T)] <- '    title <- ""\n    tocTi <- ""'
# adds call to tex.mod to force modification
out[i] <- paste0(out[i<-grep('setwd\\(build_dir\\)', out)], '\n\ttocTi <- if(nchar(tocTi)>0) tocTi else "\\\\R{} topics documented:"\n\ttex.mod(pkg=files[1L], file="Rd2.tex", tocTi=tocTi)')
# adds call to ..Rd2pdf at the end
out <- c(out, '..Rd2pdf()')
# rewrites the file
fileConn<-file(f, open='w')
writeLines(out, fileConn)
close(fileConn)

# overloading devtools::build_manual
build_manual <- function (pkg = ".", path = NULL, toc=NULL) 
{
  pkg <- devtools::as.package(pkg)
  path <- rlang::`%||%`(path, dirname(pkg$path))
  
  name <- paste0(pkg$package, "_", pkg$version, ".pdf", collapse = " ")
  tryCatch(msg <- callr::rscript(file.path(Sys.getenv("R_HOME"), "bin", "Rd2pdf.overload.R"), cmdargs = paste0('nextArg', paste0(c("--force", 
                                                                                                                                   paste0("--output=", path, "/", name), pkg$path, if(!is.null(toc)) paste0("--toc=",toc)), collapse='nextArg')), fail_on_status = TRUE), 
           error = function(e) {
             cat(e$stderr)
             stop("Failed to build manual", call. = FALSE)
           })
  cat(msg$stdout)
  invisible(msg)
}


write.fun(build_manual, file.path(path.expand('~'), '.Rprofile'))

build_manual(toc="Functions")

带输出:

如您所见,“第一节”和“第二节”被提到了两次,有胆量和没有胆量。我怎么可能只有一个胆子?

【问题讨论】:

  • 这是你want的结果吗?我找到了实现此目的的解决方法
  • 你使用的是 linux、macos 还是 windows?所以我可以编写一个脚本来进行更改
  • 我是windows用户
  • 是的,这是非常有趣的结果。如果也可以对 .Rd 文件进行处理,那就太好了。
  • 我更新了我的答案,因为旧答案是针对另一个问题,并添加了产生该输出的代码。如果您需要详细说明,请发表评论

标签: r devtools roxygen2


【解决方案1】:

我已经写了一个Rscript,它将负责所有要进行的编辑。

解法说明

基本上devtools::build_manual 调用R CMD Rd2pdf 脚本,这个脚本基本上捆绑了参数来调用tools:::..Rd2pdf

所以我所做的是重载tools:::..Rd2pdf 函数并添加一个--toc 参数来更改目录标题,并添加另一个函数tex.mod 在呈现之前修改乳胶这两个函数保存到@ 987654329@ 所以它们可以被修改后的Rd2pdf 使用,修改Rd2pdf 脚本基本上执行Rd2pdf.overload.R 而不是运行tools:::Rd2pdf() 并重载devtools::build_manual 以接受将被传递给的toc 参数Rd2pdf 脚本。

tex.mod 使用 Rd latex 包中定义的 myaddcontentsline 宏重新排序描述并将各节添加到目录中,该包是乳胶宏 addcontentsline 的包装器。

注意:未包含在章节中的功能首先显示。

如何定义部分

部分将通过记录package来定义。
即创建一个名为ur.pkg.name.R 的R 文件并添加包的描述,如下所示:

#' name.of.ur.pkg : A package for doing awesome things.
#'
#' The name.of.ur.pkg package provides two categories of important functions:
#' foo and baz.
#' 
#' @section Foo functions:
#' first.fun
#' second.fun
#' 
#' @section baz functions:
#' third.fun
#' fourth.fun
#' 
#' @docType package
#' @name name.of.ur.pkg
NULL

Rscript:

# modifies the latex of the converted .Rd files
# in order to add sections to the toc
tex.mod <- function(pkg='.', file='Rd2.tex',  tocTi = "R{} topics documented:"){
    
    library(stringr)
    #get the package name
    pkg <- devtools::as.package(pkg)$package
    #reads the latex file
    out <- readLines(file)
    # modifies the Table of contents title
    out[rdcont] <- sub("(?<=\\\\Rdcontents\\{).+(?=}$)", tocTi, out[rdcont <- grep('\\\\Rdcontents', out)], perl=T)
    # Gets the defined sections
    sections <- str_replace_all(strcapture(paste0("(?s)^.+?\\\\HeaderA\\{",pkg,"\\}.+?(\\\\begin\\{Section\\}.+\\\\end{Section})\n(?:\\\\inputencoding\\{|\n?\\\\printindex).+$"), paste0(out, collapse='\n'), data.frame(v=character(0)), perl=T)[1,1],  c('\\\\begin\\{Section\\}\\{(.+?) *\\}\n'='\\1\n', '^\n'='', '\n$'='', '\n%?\n'='\n'))
    
    # splits sections
    spl <- str_split(sections, '\n?\\\\end.+?(\n|$)')[[1]]
    spl <- str_split(spl[nchar(spl)>0], '\n')
    
    #gets the package description
    pkgdesc <- out[1:rdcont]
    # gets the trailing lines
    trailing <- out[length(out)+(-1:0)]
    # get the descriptions
    outi<- str_split(paste0(out[(rdcont+2):(length(out)-2)], collapse='\n'), '\\\\inputencoding.+\n')[[1]]
    # sets the names to th name of the function/package described
    names(outi) <- str_extract(outi, '(?<=\\\\HeaderA\\{).+?(?=\\})')
    # adds lines to add to the toc file if you want more indentation put section instead of chapter
    outi <- c(outi, sapply(spl, function(x) {v<-paste0("\\myaddcontentsline{toc}{chapter}{\\protect\\textbf{", x[1],"}}"); names(v)<-x[1]; v})) 
    # unlists the names of the sections with their functions
    spl <- unlist(spl)
    # orders them so that the functions that have no section are shown first
    outi <- c(pkgdesc, outi[!(names(outi) %in% c(spl, pkg))], outi[spl], trailing)
    # writes to file
    if (require(data.table)){
        # the data.table way
        fwrite(list( outi), quote=F, sep='\n', file=file, append=F)
    } else {
        # the baseR way
        fileConn<-file(file, open='w')
        writeLines(outi, fileConn)
        close(fileConn)
    }
    
}

write.fun <- function(fun, path){
    fun.src <- capture.output(fun)
    fun.name <- as.character(substitute(fun))
    fun.src[1] <- paste0(fun.name[length(fun.name)],' <- ', fun.src[1])
    fun.src<-fun.src[!grepl('^<.+?>$',fun.src)]
    if (require(data.table)){
        # the data.table way
        fwrite(list(fun.src), quote=F, sep='\n', file=path, append=T)
    } else {
        # the baseR way
        fileConn<-file(path, open='a')
        writeLines(fun.src, fileConn)
        close(fileConn)
    }
}
# get the location of R_HOME
Rh <- Sys.getenv('R_HOME')
f <- file.path(Rh, 'bin', 'Rd2pdf.overload.R')
file.create(f)

# adds the function to the file
write.fun(tex.mod,f)
write.fun(tools:::..Rd2pdf,f)

# reads the file
out <- readLines(f)
# forces all functions to be loaded from tools
out <- gsub('(?=(.DESCRIPTION_to_latex|.Rdfiles2tex|latex_canonical_encoding|texi2pdf|.Rd2pdf)\\()', "tools:::", out, perl=T)
# add param description to usage
out[i] <- paste(out[i <- grep('--title=NAME', out, fixed=T)], '            "      --toc=NAME\tuse NAME as the title of the Table of contents", ', sep='\n' )
# parses param
out[grep('substr(a, 1, 8) == "--title="', out, fixed=T)+2] <- paste('        }', '        else if (substr(a, 1, 6) == "--toc=") {', '            tocTi <- sub("--toc=", "", a)', '        }', sep='\n')
# adds definition
out[grep('    title <- ""', out, fixed=T)] <- '    title <- ""\n    tocTi <- ""'
# adds call to tex.mod to force modification
out[i] <- paste0(out[i<-grep('setwd\\(build_dir\\)', out)], '\n\ttocTi <- if(nchar(tocTi)>0) tocTi else "\\\\R{} topics documented:"\n\ttex.mod(pkg=files[1L], file="Rd2.tex", tocTi=tocTi)')
# adds call to ..Rd2pdf at the end
out <- c(out, '..Rd2pdf()')
# rewrites the file
fileConn<-file(f, open='w')
writeLines(out, fileConn)
close(fileConn)

# overloading devtools::build_manual
build_manual <- function (pkg = ".", path = NULL, toc=NULL) 
{
    pkg <- devtools::as.package(pkg)
    path <- rlang::`%||%`(path, dirname(pkg$path))

    name <- paste0(pkg$package, "_", pkg$version, ".pdf", collapse = " ")
    tryCatch(msg <- callr::rscript(file.path(Sys.getenv("R_HOME"), "bin", "Rd2pdf.overload.R"), cmdargs = paste0('nextArg', paste0(c("--force", 
        paste0("--output=", path, "/", name), pkg$path, if(!is.null(toc)) paste0("--toc=",toc)), collapse='nextArg')), fail_on_status = TRUE), 
        error = function(e) {
            cat(e$stderr)
            stop("Failed to build manual", call. = FALSE)
        })
    cat(msg$stdout)
    invisible(msg)
}


write.fun(build_manual, file.path(path.expand('~'), '.Rprofile'))

它会自动将 build_manual 的新定义添加到~/.Rprofile

运行devtools::document()之后就可以了

  • 现在构建您的手动运行build_manual()
  • 现在要使用自定义目录标题构建您的手册,请将 toc 参数传递给调用

【讨论】:

  • @John 希望这能回答你的问题
  • @John 你需要把visualize.R放到R文件夹里然后运行devtools::document(),你能不能把${R_HOME}/bin/Rd2pdf的内容贴出来
  • @John 我的意思是Rd2pdf 脚本不是Rd2pdf.overload.R
  • 好的,在 R cat(readLines(file.path(Sys.getenv('R_HOME'), 'bin', 'Rd2pdf')), sep='\n') 中运行后将以下内容添加到您的问题中。我认为这将显示问题的根源
  • 问题是 Rd2pdf 脚本在 Windows 中不存在,这就是它没有被修改的原因,它与 Rd2pdf.overload.R 具有相同的内容。我会尝试找到它以解决这个问题。
猜你喜欢
  • 2016-06-10
  • 2020-04-06
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
  • 2011-04-30
  • 2016-01-14
  • 1970-01-01
相关资源
最近更新 更多