Rhelper=function(topic) { library(RGtk2); ## Window and containers window.main=gtkWindow("toplevel",show=FALSE); window.main$setTitle("Rhelper"); window.main$setDefaultSize(800,600); hbox.main=gtkHBoxNew(homogeneous=FALSE); sw1.main=gtkScrolledWindowNew(show=TRUE); sw2.main=gtkScrolledWindowNew(show=TRUE); sw1.main$setPolicy(GtkPolicyType["automatic"],GtkPolicyType["automatic"]); sw2.main$setPolicy(GtkPolicyType["automatic"],GtkPolicyType["automatic"]); sw1.main$setSizeRequest(200,-1); ## Listbox model.main=gtkListStoreNew("gchararray"); listbox.main=gtkTreeViewNewWithModel(model.main); renderer.main=gtkCellRendererTextNew(); column.main=gtkTreeViewColumnNewWithAttributes("",renderer.main,text=0); listbox.main$appendColumn(column.main); selection.main=gtkTreeViewGetSelection(listbox.main); selection.main$setMode(GtkSelectionMode["single"]); setListbox=function(topic,model,column,selection) { helpfile=as.character(help(topic))[1]; pkgname=basename(dirname(dirname(helpfile))); indexfile=file.path(dirname(helpfile),"AnIndex"); fun.name=readLines(indexfile)[-1]; fun.name=gsub("\t.*","",fun.name); if(pkgname!=gsub("Package: ","",column$getTitle())) { model$clear(); for(fname in fun.name) { model$set(model$append()$iter,0,fname); } column$setTitle(paste("Package:",pkgname)); } index=which(fun.name==topic)[1]-1; # iter=.RGtkCall("S_gtk_list_store_insert_with_valuesv",model, # as.integer(index),as.integer(0),list(topic))$iter; # model$remove(iter); # selection$selectIter(iter); iter=model$insert(index)$iter; model$remove(iter); selection$selectIter(iter); } ## TextView buffer.main=gtkTextBufferNew(); textview.main=gtkTextView(buffer=buffer.main,show=TRUE); textview.main$setEditable(FALSE); textview.main$setWrapMode(GtkWrapMode["word"]); textview.main$setLeftMargin(10); textview.main$setRightMargin(10); ## Tags tag.title=buffer.main$createTag("title",foreground="#666666", family="monospace",scale=PANGO_SCALE_XX_LARGE, weight=PangoWeight["bold"],justification="center", pixels_above_lines=20,pixels_below_lines=20); tag.section=buffer.main$createTag("section",foreground="#666666", family="monospace",scale=PANGO_SCALE_X_LARGE, weight=PangoWeight["bold"],pixels_above_lines=15, pixels_below_lines=12); tag.text=buffer.main$createTag("text",scale=PANGO_SCALE_LARGE, family="sans",pixels_above_lines=8,pixels_below_lines=8); tag.code=buffer.main$createTag("code",foreground="#888888", scale=PANGO_SCALE_LARGE,weight=PangoWeight["bold"], family="monospace",pixels_above_lines=8, pixels_below_lines=8); tag.RCODE=buffer.main$createTag("RCODE",scale=PANGO_SCALE_LARGE, family="monospace"); tag.emph=buffer.main$createTag("emph",style="italic", scale=PANGO_SCALE_LARGE,left_margin=50, pixels_above_lines=8,pixels_below_lines=8); tag.bold=buffer.main$createTag("bold",family="sans",scale=PANGO_SCALE_LARGE, weight=PangoWeight["bold"],pixels_above_lines=8, pixels_below_lines=8); tag.arg=buffer.main$createTag("arg",foreground="#888888", scale=PANGO_SCALE_LARGE,weight=PangoWeight["bold"], family="monospace"); tag.discrip=buffer.main$createTag("discrip",scale=PANGO_SCALE_LARGE, family="sans",left_margin=50,pixels_above_lines=8, pixels_below_lines=8); ## Rd parser sections0=c("description","usage","arguments","details","value", "references","note","author","seealso","examples","section", "source","format"); sections0.name=c("Description","Usage","Arguments","Details","Value", "References","Note","Author(s)","See Also","Examples","...", "Source","Format"); getTags=function(section) { f=function(x) { s=if(length(x)==0) "" else if(is.list(x)) list(getTags(x)) else x; names(s)=attr(x,"Rd_tag"); return(s); } tags=unlist(lapply(section,f)); names(tags)=gsub("\\\\","",names(tags)); return(tags); } tidy=function(section,section.title) { section=getTags(section); section=gsub("^ +\n","\n",section); if(section.title=="...") { section.title=section[1]; section=section[-1]; } tags=names(section); index.dontrun=grep("dontrun",tags); section[index.dontrun[1]]=paste("## Not run:", section[index.dontrun[1]]); section[index.dontrun[length(index.dontrun)]]= paste(section[index.dontrun[length(index.dontrun)]], "## End(Not run)",sep="\n"); tags[index.dontrun]="RCODE"; index.pre=grep("preformatted",tags); tags[index.pre]="RCODE"; index.RCODE=grep("^RCODE$",tags); tmp=section[index.RCODE]; tags=gsub("itemize","enumerate",tags); section[grep("enumerate.item",tags)-1]="\n"; index1=grep("^\n$",section); index1=index1[index10; if(flag) section=section[-index.dup]; } return(section); } # Write text writeText=function(topic,buf) { helpfile=as.character(help(topic))[1]; pkgname=basename(dirname(dirname(helpfile))); docname=basename(helpfile); RdDB=file.path(dirname(helpfile),pkgname); Rdobj=tools:::fetchRdDB(RdDB,docname); sections=tools:::RdTags(Rdobj); sections.indices=!grepl("title|name|alias|keyword|concept",sections); sections=sections[sections.indices]; sections=gsub("\\\\","",sections); sections.title=sections0.name[match(sections,sections0)]; contents=mapply(tidy,Rdobj[sections.indices],sections.title,SIMPLIFY=FALSE); buf$setText(""); iter.t=buf$getIterAtOffset(0)$iter; buf$insertWithTagsByName(iter.t, tools:::.Rd_get_metadata(Rdobj,"title"),"title"); buf$insert(iter.t,"\n"); for(i in 1:length(contents)) { buf$insertWithTagsByName(iter.t,contents[[i]][1],"section"); for(j in 2:length(contents[[i]])) { if(names(contents[[i]][j]) %in% c("RCODE","arg","discrip", "code","emph","bold")) { buf$insertWithTagsByName(iter.t,contents[[i]][j], names(contents[[i]][j])); }else if(names(contents[[i]][j])=="link") { tag.link=buffer.main$createTag(NULL,foreground="blue",underline="single", scale=PANGO_SCALE_LARGE,weight=PangoWeight["bold"], family="monospace",pixels_above_lines=8, pixels_below_lines=8); tag.link$setData("link",contents[[i]][j]); buf$insertWithTags(iter.t,contents[[i]][j],tag.link); }else{ buf$insertWithTagsByName(iter.t,contents[[i]][j],"text"); } } } } ## Signal change_text=function(selection,param) { if(!selection$getSelected()$retval) return(FALSE); iter=selection$getSelected()$iter; val=param$model$getValue(iter,0)$value; writeText(val,param$buffer); } link_clicked=function(object,event,param) { if(event$type!=GdkEventType['button-release']-1) return(FALSE); if(event$button!=1) return(FALSE); buffer=object$getBuffer(); iter.bounds=buffer$getSelectionBounds(); if(iter.bounds$start$getOffset()!=iter.bounds$end$getOffset()) return(FALSE); buffer.coords=object$windowToBufferCoords(GtkTextWindowType["widget"],event$x,event$y); iter=object$getIterAtLocation(buffer.coords$buffer.x,buffer.coords$buffer.y)$iter; if(length(iter$getTags())<1) return(FALSE); link=iter$getTags()[[1]]$getData("link"); if(!is.null(link)) { if(!grepl("http",link)) { setListbox(gsub("\"|\'","",link),param$model,param$column,param$selection); }else browseURL(link); } } gSignalConnect(selection.main,"changed",change_text,list(model=model.main,buffer=buffer.main)); gSignalConnect(textview.main,"event-after",link_clicked,list(model=model.main,column=column.main,selection=selection.main)); ## Initialize setListbox(topic,model.main,column.main,selection.main); ## Show window window.main$add(hbox.main); hbox.main$packStart(sw1.main,FALSE,FALSE,2); hbox.main$packStart(sw2.main); sw1.main$add(listbox.main); sw2.main$add(textview.main); window.main$show(); }