将 automatically/manually 节添加到包文档
Adding automatically/manually sections to package documentation
我已经构建了我的包并使用 devtools::build_manual()
构建了包文档。问题是我的所有功能都在 'R topics documented' 部分,但我不知道如何更改它。我的目标是让几个部分没有 'R topics documented'。我不确定该怎么做,我尝试了 @describeIn
和 @section
,但都没有用。你知道我该怎么做吗?
UPGRADE vol 1(在 Abdessabour 的代码之后)
您好,我想告诉您我非常感谢您的工作,我知道您肯定花了很多时间做这件事。我对你的代码有直觉,它很棒。我有两个关于您的代码的问题,我 100% 都没有回答。
(1) 我可以在您的代码中的哪个位置定义我想要的部分?我理解 如何 它们是如何制作的,但不太理解 代码中 正是制作它们的地方。因此,例如 A 部分中的功能 (1) 和 (2) 功能 B 部分中的 (3) 和 (4) 等等。
(2) 如何在 运行 编译您的代码后创建 pdf。我应该只 运行 devtools::build_manual()
就这样吗?
升级第 2 卷
嗨!我理解你的思维方式,但我有一个问题想告诉你。假设我的包裹名称为 'visualise'。这是 'visualise' 包文件夹中的文件。
visualise.R 在部分中包含我的功能。我将该文件放入包文件夹中(如上所示)
我试图通过 @import
、@importClassesFrom
、@importFrom
、@importMethodFrom
将该文件导入 R,但它们都不起作用。我认为 R 可能无法识别该文件。我很担心,因为在创建 visualise.R 文件后我 运行 build_manual(toc="anything")
并且在输出中我得到了默认文档(与 build_manual()
创建的相同)你知道我是什么吗我做错了吗?
升级第 3 卷
我已将 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")
输出:
大家可以看到“第一节”和“第二节”提到了两次,壮胆不壮胆。我怎么可能只有一个底气?
我写了一个 Rscript
来处理所有要进行的编辑。
解法说明
基本上 devtools::build_manual
调用 R CMD Rd2pdf
脚本,这个脚本基本上捆绑了参数以调用 tools:::..Rd2pdf
.
所以我所做的是重载 tools:::..Rd2pdf
函数并添加一个 --toc
参数来更改目录标题,并添加另一个函数 tex.mod
来修改乳胶渲染这两个函数被保存到 ${R_HOME}/bin/Rd2pdf.overload.R
所以他们可以被修改后的 Rd2pdf
使用,修改 Rd2pdf
脚本基本上执行 Rd2pdf.overload.R
而不是 运行ning tools:::Rd2pdf()
并重载 devtools::build_manual
以接受将传递给 Rd2pdf
脚本的 toc
参数。
tex.mod
使用 myaddcontentsline
定义的 myaddcontentsline
宏对描述进行重新排序,并将这些部分添加到 toc .
注意:未包含在章节中的功能首先显示。
如何定义部分
部分将通过记录 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
脚本:
# 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()
- 现在要使用自定义 Table 内容标题构建您的手册,将 toc 参数传递给调用
我已经构建了我的包并使用 devtools::build_manual()
构建了包文档。问题是我的所有功能都在 'R topics documented' 部分,但我不知道如何更改它。我的目标是让几个部分没有 'R topics documented'。我不确定该怎么做,我尝试了 @describeIn
和 @section
,但都没有用。你知道我该怎么做吗?
UPGRADE vol 1(在 Abdessabour 的代码之后)
您好,我想告诉您我非常感谢您的工作,我知道您肯定花了很多时间做这件事。我对你的代码有直觉,它很棒。我有两个关于您的代码的问题,我 100% 都没有回答。
(1) 我可以在您的代码中的哪个位置定义我想要的部分?我理解 如何 它们是如何制作的,但不太理解 代码中 正是制作它们的地方。因此,例如 A 部分中的功能 (1) 和 (2) 功能 B 部分中的 (3) 和 (4) 等等。
(2) 如何在 运行 编译您的代码后创建 pdf。我应该只 运行 devtools::build_manual()
就这样吗?
升级第 2 卷
嗨!我理解你的思维方式,但我有一个问题想告诉你。假设我的包裹名称为 'visualise'。这是 'visualise' 包文件夹中的文件。
visualise.R 在部分中包含我的功能。我将该文件放入包文件夹中(如上所示)
我试图通过 @import
、@importClassesFrom
、@importFrom
、@importMethodFrom
将该文件导入 R,但它们都不起作用。我认为 R 可能无法识别该文件。我很担心,因为在创建 visualise.R 文件后我 运行 build_manual(toc="anything")
并且在输出中我得到了默认文档(与 build_manual()
创建的相同)你知道我是什么吗我做错了吗?
升级第 3 卷
我已将 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")
输出:
大家可以看到“第一节”和“第二节”提到了两次,壮胆不壮胆。我怎么可能只有一个底气?
我写了一个 Rscript
来处理所有要进行的编辑。
解法说明
基本上 devtools::build_manual
调用 R CMD Rd2pdf
脚本,这个脚本基本上捆绑了参数以调用 tools:::..Rd2pdf
.
所以我所做的是重载 tools:::..Rd2pdf
函数并添加一个 --toc
参数来更改目录标题,并添加另一个函数 tex.mod
来修改乳胶渲染这两个函数被保存到 ${R_HOME}/bin/Rd2pdf.overload.R
所以他们可以被修改后的 Rd2pdf
使用,修改 Rd2pdf
脚本基本上执行 Rd2pdf.overload.R
而不是 运行ning tools:::Rd2pdf()
并重载 devtools::build_manual
以接受将传递给 Rd2pdf
脚本的 toc
参数。
tex.mod
使用 myaddcontentsline
定义的 myaddcontentsline
宏对描述进行重新排序,并将这些部分添加到 toc .
注意:未包含在章节中的功能首先显示。
如何定义部分
部分将通过记录 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
脚本:
# 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()
- 现在要使用自定义 Table 内容标题构建您的手册,将 toc 参数传递给调用