/* svmacines_example: download and run the requested sample code from the svmachines package */ /* */ /* To use this with a different package, just replace every "svmachines". */ program define svmachines_example version 13 example svmachines `0' end /* example: runs example in safe isolation, downloading them from your package as needed * * Nick Guenther , June 2015. * BSD License. * * Your examples must be in .do files named `example'_example.do * and should be listed in your package's ancillary files (with "f"). * * For example, if you have invented "triple dog dare" * regression in a package "tddr", you might make a * triple_dog_dare_regression_79_example.do. * In your tddr.pkg file list * f triple_dog_dare_regression_79_example.do * which will cause it to be an ancillary file and not get installed with the rest of the package. * In your .sthlp file, after a manually-made copy of the code, put * {it:({stata "example tddr triple_dog_dare_regression_79":click to run})} * (you can use 'example' anywhere you like, of course, but it's most obvious use is * in glue for helpfiles, which can only run one command at a time). * * When the user clicks that link, it will download to their working directory, run * and then clean up after itself as if it never did, except that the file will be handy * for the user to inspect and play with. * * TODO: * [ ] consider making the convention `pkg'_`example'_example.do */ program define example version 13 // parse arguments gettoken pkg 0 : 0 gettoken example 0 : 0 capture findfile `example'_example.do if(_rc != 0) { // download ancillaries, which should include the examples di as txt "Downloading `pkg' ancillary files" ado_from `pkg' capture noisily net get `pkg', from(`r(from)') capture findfile `example'_example.do if(_rc != 0) { di as error "Unable to find `example' example." exit 3 } } // save the user's dataset // if the user actually wants to run the example into their current session they can just "do" it a second time qui snapshot save // this is faster(?) than preserve, and seems to be just as effective, although it requires manual restoration at the end local snapshot = `r(snapshot)' //preserve qui clear // run example capture noisily do `example'_example.do, nostop qui snapshot restore `snapshot' //restore // this is unneeded, because this runs automatically at scope end end /* ado_from: return the URL or path that a package was installed from. * This is to glue over that 'net get' doesn't do this already. * */ program define ado_from, rclass version 13 // parse arguments gettoken pkg 0 : 0 local from = "" local curpkg = "" tempname fd // scan stata.trk for the source // this is not a full stata.trk parser, it only implements what I need // a typical entry looks like // ... // e // S http://fmwww.bc.edu/repec/bocode/p // N psidtools.pkg // ... // the loop ends when we run off the end of the file or we have found // the matching package and its source qui findfile stata.trk file open `fd' using "`r(fn)'", read text while(!("`curpkg'"=="`pkg'.pkg" & "`from'"!="")) { file read `fd' line if(r(eof) != 0) { di as error "`pkg' not found in stata.trk" exit 9 } // extract line type gettoken T line : line if("`T'"=="S") { // source line; record from gettoken from : line } else if("`T'"=="e") { // end of package; clear state local from = "" local curpkg = "" } else if("`T'"=="N") { // package file name gettoken curpkg : line } } // assumption: the stata.trk file should have defined an S line in each pkg block // if not, something bad happened assert "`from'"!="" return clear return local from = "`from'" end