> I have done my best here https://gist.github.com/3516476
Thanks - that's useful. A few comments/questions: * I don't think the spec for processTag is quite right yet - currently you have it returning a transformed object of the same class as the input - but that only works for a limited number of tags. Many tags also need to modify other tags the rocblock. For example the "@intro" tag (a virtual tag added to the start of every rocblock) needs to modify the title, description and details. The @docType tag needs to modify a lot of other pieces. It would be possible to rewrite them to "pull" rather than "push", i.e. so that @title would check @intro, and @keywords would check @docType but I don't think that's as good a design as it means the code for one tag needs to be put in multiple places. * Similarly, I still don't see how tags that operate globally would work. I think that's partly because the model is so focussed on the individual tag - the tag classes become very heavy - that's where all the logic is stored. That's not such a good fit for actions that work on multiple tags in multiple rocblocks. I wonder if we need a alternative model for some tags - instead of being stored in each rocblock, they should be stored globally: setClass("GlobalTag", contains = "Tag", slots = "RocBlock" # pointer back to the rocblock that contained them ) setClass("FamilyTag", contains = "GlobalTag") setClass("IncludeTag", contains = "GlobalTag") setClass("InheritParamsTag", contains = "GlobalTag") # Takes list of tags as input (not sure how dispatch would work) and rocBlocks as input # Returns list of rocblocks as output setGeneric("processGlobalTags") * I think I need to explain the output model a little bit more - the output needs to be by tag, and return an intermediate representation of the output object. More like: setGeneric("outRd") setMethod("outRd", "roxyTag", function(tag, rocblock)) { filename <- getTag(rocblock, "rdname") rdCommand(tag@name, tag@value, path = filename) } This is because the output methods can't write directly to disk - they may need to do some aggregation: * multiple rocblocks may output to the same Rd file with @rdname * all outputs to NAMESPACE need to be sorted and have duplicates removed. Another possible approach could be: setClass("OutputRd") setGeneric("makeOutput", function(input, output) {}) setMethod("makeOutput", c("TagParam", "OutputRd"), ...) setMethod("makeOutput", c("TagImport", "OutputNamespace"), ...) setMethod("makeOutput", c("TagIncludes", "OutputDescription") ...) setMethod("makeOutput", c("RoxyBlock", "Output"), function(input, output) { lapply(input@tags, makeOutput, output = output) } setMethod("makeOutput", c("RoxyPackage", "Output"), function(input, ouput) { unlist(lapply(input@blocks, makeOutput, output = output), recursive = FALSE) } setGeneric("writeOutput", function(output, data) {}) setMethod("writeOutput", c("outputNamespace", "list")) { lines <- sort(unique(unlist(data))) write_if_different(lines, "NAMESPACE") } That would make it easier for the user to specify which sorts of output they want because they could just provide a list of Output objects to roxygenise. > > Object seems a bit awkward because it's part of the rocblock, and is > > currently stored in a list with it's value and it's name. But I don't > > see how you'd dispatch on it, unless you pull it out into a separate > > argument. > > Yes, dispatch is on the object which is part of rocblock (maybe > roxyBlock?). roxyParse is used only internally, so not a big deal. When > iterating, disassembling and calling roxyParse(rblock@object), rblock@doc) > looks fine to me. I think it would still need to be rblock@object@value, but that's ok too. Hadley -- Assistant Professor Department of Statistics / Rice University http://had.co.nz/ _______________________________________________ Roxygen-devel mailing list Roxygen-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/roxygen-devel