program define ngram_example
  example ngram `0'
end

/* example: runs example in safe isolation, downloading them from your package as needed
 *
 * Nick Guenther <nguenthe@uwaterloo.ca>, 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.
 *
 */
program define example
  // 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

  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.
 *
 * April 2017: THis program uses "ado/plus/stata.trk" to figure out where the files were downloaded from.
 * This is needed, for example, when downloading <click to run> examples on the fly from the same original download location.
 * If there the same package has been downloaded multiple times from different download sites, the earlier versions
 * should be uninstalled using "ado uninstall ngram [xx]" where xx is the package number that "ado" indicates
 */
program define ado_from, rclass

  // 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