prog define displaygph
*!	program displaygph   Version 1.52 (2Feb2023) by Mead Over
*	This program is a utility to display multiple Stata graphs quickly
*	The graphs are displayed as tabs in a Stata Graph window unless
*	the -combine- option is selected, which presents all the graphs
*	together in a single thumbnail image
*
*	Syntax: displaygph [pattern] [, memory gph detail combine noaltshrink dropall saving(string) asis]
*
*	[pattern] is a template for the names of the graphs to be displayed
*	The default -pattern- is "*"
*
*	Options:
*		memory - display the graphs currently in memory
*		gph - display the graphs that are stored as *.gph files in the current folder
*		detail - list a detailed description of each graph
*		combine- display all the listed graphs as thumbnails in a single window
*		combine2(string)- name the combined graph with the name designated -string-. Default is to name it -__combined-
*		noAltshrink - used with combine, suppresses -altshrink- option
*		dropall - close any existing graph window before displaying graphs
*		saving(path,[replace])
*			 - with the -memory- option, save all the graphs in memory to the folder specified by the path
*			 - with the -combine- option, save the combined graph
*		asis - only relevant with the -saving() option.  See -help graph save-.
*		findgph - Since -graph dir [pattern], gph- only works in the current directory,
*			the option -findgph- enables -displaygph- to display -gph- files in
*			another directory and then return to the current directory when finished.
*			Saved graphs goes to current directory unless a path
*			is specified in the -saving- option.
*		notegphs - Add a note to the combined graph which lists the names of the included graphs.
*
	version 12
	syntax [anything] [, Memory Gph Detail DROPALL Saving(string) Combine noAltshrink  ///
		Findgph(string) Combine2(string) NOTEgphs]  //  added in versions 1.41 , 1.50

	if "`c(os)'"~="MacOSX" {
		qui set autotabgraphs on
	}
	capture gr drop __combined
	capture gr drop "`combine2'"

	if "`dropall'"~="" {
		if "`gph'" == "" {
			di as err "The option -dropall- requires the -gph- option."
			exit 198
		}
		graph drop _all
	}

	if ("`combine'"~="" | "`combine2'"~="")  {
		di as txt _n "Assembling thumbnails of all of the following graphs. " ///
				_n "If there are several graphs to combine, this may take a minute or two..." _n
	}
	if "`saving'"~="" {
		local path = trim(substr(`"`saving'"',1,strpos(`"`saving'"',",")-1))
		local lastpathchar = substr(`"`path'"',length(`"`path'"'),1)
		if "`lastpathchar'"~="\" & "`lastpathchar'"~="/" & `"`path'"'~="" & `"`path'"'~="*" {
			local path = trim(`"`path'"') + "/"
		}
		if strmatch(`"`saving'"',`"*,*replace*"') {
			local replace replace
		}
		if strmatch(`"`saving'"',`"*,*asis*"') {
			local asis asis
		}
	}
	local altshrink = cond("`altshrink'"=="","altshrink","")
	if "`memory'"~="" | "`gph'"=="" {  // Default is to display the memory graphs
		if `"`findgph'"'~="" {
			di as err "The option -findgph- is only permitted with the -gph- option."
			exit 198
		}
		graph dir `anything' , memory `detail'
			local memgphlist `"`r(list)'"'
		if trim(`"`memgphlist'"')=="" {
			di as err "There are no memory graphs which fit the pattern: " as res `"`anything'"'  ///
				_n as err "Graph names are case sensitive, so check the capitalization in your pattern"  ///
				_n as err "Here are the graphs currently in memory:"
				graph dir , memory
		}
		if ("`combine'"=="" & "`combine2'"=="") {
			window manage close graph _all
			foreach pic of local memgphlist {
				gr di `pic'
				if "`saving'"~="" {
					if `"`path'"'=="*" | `"`path'"'=="" {
						gr save `"`pic'.gph"', `asis' `replace'
					}
					else {
						gr save `"`path'`pic'.gph"', `asis' `replace'
					}
				}

			}
		}
	}
	if "`gph'"~="" {  //  -saving() option irrelevant, since all are already saved
		if `"`findgph'"'~= "" {  // Enable gr dir [pattern] to find the gph files elsewhere
			local wrkngdir `c(pwd)'
			cd `"`findgph'"'
			local whichfolder specified
		}
		else {
			local whichfolder current
		}
		if "`anything'"=="*" | "`anything'"=="*.*" | "`anything'"=="*.gph" {
			local anything
		}
		graph dir `anything' , gph `detail'
			local discgphlist `"`r(list)'"'
		if trim(`"`discgphlist'"')=="" {
			di as err "There are no graphs in the `whichfolder' folder which fit the pattern: " as res "`anything'"  ///
				_n as err "Graph names are case sensitive, so check the capitalization in your pattern"  ///
				_n as err "Here are the graph files in the `whichfolder' folder, if any."
				graph dir , gph
		}
		if ("`combine'"=="" & "`combine2'"=="") {
			foreach pic of local discgphlist {
				gr use `"`pic'"'
			}
		}
	}

	if ("`combine'"~="" | "`combine2'"~="") & trim(`"`memgphlist'`discgphlist'"')~="" {
	    local cmbname = cond("`combine2'"=="","__combined","`combine2'")

		if "`notegphs'"~="" wrapgphlist `memgphlist' `discgphlist'

		gr combine `memgphlist' `discgphlist',  name(`cmbname', replace) `altshrink' `r(gphnote)'

		if "`saving'"~=""  {
			gr save `"`path'`cmbname'.gph"', `replace' `asis'
		}
	}
	if `"`findgph'"'~= "" {  // Change directory back to the original working directory
		cd `"`wrkngdir'"'
	}

end

prog define wrapgphlist, rclass

	syntax anything

	cap which linewrap
	if _rc == 0 {
		linewrap , longstring(Names of the graphs displayed as thumbnails: `anything') maxlength(129) stack

		local gphnote `"note(`r(stack)', span size(vsmall))"'

	}
	else {
		di as txt "When using the option -notegphs- with the -combine- option,"  ///
			_n "the names of some of the graphs may be hidden to the right"  ///
			_n "of the margin in the combined image." ///
			_n "To enable -displaygph- to wrap the list of graphs," ///
			_n "so that all the names are visible, find and optionally install"  ///
			_n `"the user-contributed program -linewrap- by clicking {stata "view net describe linewrap, from(http://digital.cgdev.org/doc/stata/MO/Misc)":here}."'

		local gphnote `"note("Names of the graphs displayed as thumbnails: `anything'", span size(vsmall))"'

	}

	return local gphnote `gphnote'

end  /*  End of program wrapgphlist  */

*	Version 1.1	Option -altshrink- added for passthrough to the -gr combine- command
*	Version 1.2	Option -dropall- added
*	Version 1.3	Option -saving- added
*	Version 1.32 Option -saving- debugged
*	Version 1.33 Move -window manage close- command outside the -foreach pic- loop
*	Version 1.34 exclude the set autotabgraphs command for MacOS
*	Version 1.35 Add version 12 designation
*	Version 1.36 Accommodate blanks in filenames, enable saving of combined graph.
*	Version 1.37 Changes the "altshrink" option from optionally on to optionally off
*	Version 1.38 (6 June 2014) Corrects some typos in the comments
*	Version 1.39 (10 Feb 2015) Require only Stata version 10.2 instead of version 12
*	Version 1.40 (13 Mar 2016) Add warning in lines 62 & 102 about case sensitivity
*					when no graphs are found matching a pattern
*	Version 1.41 (12Feb2019) Add the -findgph- option.  to enable -displaygph- to
*		display -gph- files in another directory and then return to the
*		current working directory when finished.
*		Also return version requirement to Stata version 12.
*	Version 1.42 (3Mar2021) Allow the -asis- option to appear inside the saving option.
*		Specify the -gph- file extension in lines 80, 83.
*		Add the filename (default to __combined.gph) to gr combine saving option in line 121
*	Version 1.50 (5Mar2021) Allow for both option -combine- and option -combine(name)-
*		But -name- is only the name of the memory graph (with default __combined)
*		Saving option should determine the path to all saved files, including the combined gph.
*		Fix bug in path parsing by moving the code for -lastpathchar- up to lines 48-52
*	Version 1.51 (25May2021) Add "`combine2'"=="" to the "`combine'"=="" conditions.
*		Add the -notegphs- option.
*	Version 1.52 (2Feb2023) Fix bug in option -dropall-