2013-12-20 1 views
89

У меня есть пакет R, который использует roxygen2. У него есть код C в /src, и я только начал работать с Doxygen. Есть ли способ объединить документацию или интегрировать компиляцию с roxygen2? Любые «лучшие практики» для того, где можно разместить документацию кода ?Использование roxygen2 и doxygen в одном пакете?

Поисковый запрос для roxygen2 и doxygen в первую очередь приводит к roxygen аналогичен doxygen. Я нашел несколько пакетов с Doxyfiles, но не последовательная организация. Например, lme4 имеет вывод inst/doc/Doxyfile в папку с именем doxygen за пределами исходного каталога lme4. Существует также Doxyfile в корневом каталоге Матрицы (но в предыдущих версиях была inst. Эта документация также экспортируются за пределами каталога пакета.

Есть ли какая-либо причина не включать C документации внутри упаковки, или почему Doxygen так редко используются в пакетах R, несмотря на широкое использование C

обновления: см связанные roxygen2 feature request

+8

Это не ответ на ваш вопрос, но если вы используете Rcpp вы можете использовать roxygen2 документировать экспортируемые ++ функции C – hadley

+2

Я думаю, Doxygen не используется в пакетах R, потому что люди не документировать их C код. C-код почти никогда не является частью пакета API и R, поэтому люди просто не документируют его. Если вы хотите поместить свои C-документы в пакет, просто сгенерируйте HTML из Makefile и поместите его в inst /. –

+1

Я не знаю roxygen, но, возможно, у него есть некоторый вывод xml, как и doxygen, и вы можете объединить его с некоторым xslt и создать из него полный документ. –

ответ

4

Я лично использую следующий код в пакете «управления данным» Я призываю все мои сценарии. Он содержит документацию по кислороду и примеры. Фактически вы просто вызываете документ() и имеете doxygen, запущенный по коду C, в src/ . Документ помещается в inst/doxygen Так что ваш пакет CRAN готов.

Документация R, предназначенная для R Конечные пользователи не должны смотреть на код C. Я не интегрировал документацию по коду C в классическую документацию R, но, вероятно, было бы хорошей практикой скопировать полученный C документация как «виньетка».

library("testthat") 
    library("devtools") 

    #' @title Replace a value for a given tag on file in memory 
    #' @description Scan the lines and change the value for the named tag if one line has this tag, 
    #' add a line at the end if no line has this tag and return a warning if several lines 
    #' matching the tag 
    #' @param fileStrings A vector with each string containing a line of the file 
    #' @param tag The tag to be searched for 
    #' @param newVal The new value for the tag 
    #' @return The vector of strings with the new value 
    #' @examples 
    #' fakeFileStrings <- c("Hello = world","SURE\t= indeed","Hello = you") 
    #' 
    #' expect_warning(ReplaceTag(fakeFileStrings,"Hello","me")) 
    #' 
    #' newFake <- ReplaceTag(fakeFileStrings,"SURE","me") 
    #' expect_equal(length(newFake), length(fakeFileStrings)) 
    #' expect_equal(length(grep("SURE",newFake)), 1) 
    #' expect_equal(length(grep("me",newFake)), 1) 
    #' 
    #' newFake <- ReplaceTag(fakeFileStrings,"Bouh","frightened?") 
    #' expect_equal(length(newFake), length(fakeFileStrings)+1) 
    #' expect_equal(length(grep("Bouh",newFake)), 1) 
    #' expect_equal(length(grep("frightened?",newFake)), 1) 
    ReplaceTag <- function(fileStrings,tag,newVal){ 
     iLine <- grep(paste0("^",tag,"\\>"),fileStrings) 
     nLines <- length(iLine) 
     if(nLines == 0){ 
      line <- paste0(tag,"\t= ",newVal) 
      iLine <- length(fileStrings)+1 
     }else if (nLines > 0){ 
      line <- gsub("=.*",paste0("= ",newVal),fileStrings[iLine]) 
      if(nLines >1){ 
       warning(paste0("File has",nLines,"for key",tag,"check it up manually")) 
      } 
     } 
     fileStrings[iLine] <- line 
     return(fileStrings) 
    } 
    #' Prepares the R package structure for use with doxygen 
    #' @description Makes a configuration file in inst/doxygen 
    #'  and set a few options: 
    #'  \itemize{ 
    #'  \item{EXTRACT_ALL = YES} 
    #'  \item{INPUT = src/} 
    #'  \item{OUTPUT_DIRECTORY = inst/doxygen/} 
    #'  } 
    #' @param rootFolder The root of the R package 
    #' @return NULL 
    #' @examples 
    #' \dontrun{ 
    #' DoxInit() 
    #' } 
    #' @export 
    DoxInit <- function(rootFolder="."){ 
     doxyFileName <- "Doxyfile" 
     initFolder <- getwd() 
     if(rootFolder != "."){ 
      setwd(rootFolder) 
     } 
     rootFileYes <- length(grep("DESCRIPTION",dir()))>0 
     # prepare the doxygen folder 
     doxDir <- "inst/doxygen" 
     if(!file.exists(doxDir)){ 
      dir.create(doxDir,recursive=TRUE) 
     } 
     setwd(doxDir) 

     # prepare the doxygen configuration file 
     system(paste0("doxygen -g ",doxyFileName)) 
     doxyfile <- readLines("Doxyfile") 
     doxyfile <- ReplaceTag(doxyfile,"EXTRACT_ALL","YES") 
     doxyfile <- ReplaceTag(doxyfile,"INPUT","src/") 
     doxyfile <- ReplaceTag(doxyfile,"OUTPUT_DIRECTORY","inst/doxygen/") 
     cat(doxyfile,file=doxyFileName,sep="\n") 
     setwd(initFolder) 
     return(NULL) 
    } 

    #' devtools document function when using doxygen 
    #' @description Overwrites devtools::document() to include the treatment of 
    #' doxygen documentation in src/ 
    #' @param doxygen A boolean: should doxygen be ran on documents in src? 
    #'  the default is TRUE if a src folder exist and FALSE if not 
    #' @return The value returned by devtools::document() 
    #' @example 
    #' \dontrun{ 
    #' document() 
    #' } 
    #' @export 
    document <- function(doxygen=file.exists("src")){ 
     if(doxygen){ 
      doxyFileName<-"inst/doxygen/Doxyfile" 
      if(!file.exists(doxyFileName)){ 
       DoxInit() 
      } 
      system(paste("doxygen",doxyFileName)) 
     } 
     devtools::document() 
    } 
+0

Спасибо! Наверное, я не понял, что простым решением было переопределить 'devtools :: document', чтобы добавить системный вызов' doxygen path/to/Doxyfile'. Я добавил это в свой пакет. Я также добавил [запрос функции в репозитории roxygen2 github] (https://github.com/klutometis/roxygen/issues/326) @hadley – Abe

+0

Итак - насколько я понимаю, запрос на перенос для этой функции не было [принято] (https://github.com/klutometis/roxygen/pull/398). Поскольку я все же хотел иметь удобный способ создания документации для doxygen, я создал небольшой [R-пакет] (https://github.com/nevrome/rdoxygen) на основе приведенного выше кода. – nevrome