[iegitaddmd] better error message

[iegitaddmd] better error message

Co-authored-by: Luiza Andrade <3e25dce60d6313c358f2ba3c7da4f9a53677fa7f@worldbank.org>

*! version 6.3 5NOV2019 DIME Analytics dimeanalytics@worldbank.org

cap program drop   iegitaddmd
	program define iegitaddmd

qui {
	syntax , folder(string) [comparefolder(string) customfile(string) all skip replace AUTOmatic DRYrun skipfolders(string)]

	/******************************
	*******************************
		Test user input
	*******************************
	******************************/

	******************************
	*	Test input: folder

	*Test that folder exist
	mata : st_numscalar("r(dirExist)", direxists("`folder'"))

	if (`r(dirExist)' == 0) | (length("`folder'")<=10) {

		noi di as error `"{phang}The folder used in [folder(`folder')] does not exist or you have not entered the full path. For example, full paths on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}. Important: Specify the whole file path to the repository folder, not just {it:C:/} or {it:/user/} as that would create the placeholder file in every empty folder on your computer!{p_end}"'
		error 693
		exit
	}

	* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
	local folderStd			= subinstr(`"`folder'"',"\","/",.)

	******************************
	*	Test input: comparefolder

	if !missing("`comparefolder'") {
		mata : st_numscalar("r(dirExist)", direxists("`comparefolder'"))

		if (`r(dirExist)' == 0) | (length("`comparefolder'")<=10) {

			noi di as error `"{phang}The folder used in [comaparefolder(`comparefolder')] does not exist or you have not entered the full path. For example, full paths on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}. Important: Specify the whole file path to the repository folder, not just {it:C:/} or {it:/user/} as that would create the placeholder file in every empty folder on your computer!{p_end}"'
			error 693
			exit
		}

		* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
		local comparefolderStd	= subinstr(`"`comparefolder'"',"\","/",.)

		*Get the name of the last folder in both folder() and comparefolder()
		local thisLastSlash = strpos(strreverse(`"`folderStd'"'),"/")
		local thisFolder 	= substr(`"`folderStd'"', (-1 * `thisLastSlash')+1 ,.)
		local compLastSlash = strpos(strreverse(`"`comparefolderStd'"'),"/")
		local compFolder 	= substr(`"`comparefolderStd'"', (-1 * `compLastSlash')+1 ,.)

		*The last folder name should always be the same for folder() and
		* comparefolder() otherwise there it is likely that the to paths
		* point to differnet starting points in the two fodler trees that
		* are to be compared.
		if ("`compFolder'" != "`thisFolder'") {
			noi di as error `"{phang}The last folder [`thisFolder'] in [folder(`folder')] is not identical to the last folder [`compFolder'] in [comparefolder(`comparefolder')]. This is an indication that the the two fodler trees to be compared are not two versions of the same folder tree.{p_end}"'
			error 693
			exit
		}
	}

	******************************
	*	Test input: customfile

	*Test that file exist if not using default file
	if "`customfile'" != "" {
		*File option used test if file exists
		capture confirm file "`customfile'"
		if _rc {
			*File does not exist, throw error
			noi di as error `"{phang}File "`customfile'" was not found. Remember that you must enter the full path. For example, on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}.{p_end}"'
			error 693
			exit
		}

		* Get the name of file (include path to keep )
		* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
		local customFileStd	= subinstr("`customfile'","\","/",.)
		*Find the last slash in the file name
		local lastSlash = strpos(strreverse(`"`customFileStd'"'),"/")
		*Use that position to get the file name. Multiply with minus one as we count from the back
		local customFileName = substr(`"`customFileStd'"', (-1 * `lastSlash')+1 ,.)
		*Used for the recursive call of the command when there is a subfolder
		local customFileRecurse `"customfile(`customFileStd')"'

		*Path and name of thile regardless if customfile were used
		local newPlaceholderFile `"`customFileName'"'
	}
	else {
		*Path and name of thile regardless if customfile were not used
		local newPlaceholderFile "README.md"
	}

	******************************
	*	Test input: skip & replace

	*Options skip and replace cannot be used at the same time
	if !missing("`skip'") & !missing("`replace'") {
		noi di as error `"{phang}The options skip and replace may not be used at the same time.{p_end}"'
		error 198
		exit
	}

	*Options all, skip and replace cannot be used together with comparefolder()
	if !missing("`comparefolder'") & (!missing("`all'") | !missing("`skip'") | !missing("`replace'")) {
		noi di as error `"{phang}The options all, skip and replace may not be used when option comparefolder() is used.{p_end}"'
		error 198
		exit
	}

	* Test that paths are not used in skip folder. I.e. no slashes are used
	local anyslash = strpos("`skipfolders'","/") + strpos("`skipfolders'","\")
	if `anyslash' {
		noi di as error `"{phang}The options [skipfolders(`skipfolders')] may not include forward or backward slashes, i.e., it may not include paths. Only folder names are accepted.{p_end}"'
		error 198
		exit
	}

	*Add .git folder to folders to be skipped
	local skipfolders `skipfolders' ".git"

	/******************************
	*******************************
		List Files and folders
	*******************************
	******************************/

	******************************
	*	List all files and folders

	*List files, directories and other files
	local flist : dir `"`folderStd'"' files "*"	, respectcase
	local dlist : dir `"`folderStd'"' dirs  "*" , respectcase
	local olist : dir `"`folderStd'"' other "*"	, respectcase

	/******************************
	*******************************
		Exectute command without compare option
	*******************************
	******************************/

	if missing("`comparefolder'") {

		******************************
		*	Call command recursively on all sub-folders

		*Use the command on each subfolder to this folder (if any)
		foreach dir of local dlist {
			*Test if directory is in
			if `:list dir in skipfolders' {
				noi di as result "{pstd}SKIPPED: Folder [`folder'/`dir'] is skipped. See option skipvars() in {help iegitaddmd}.{p_end}"
			}
			else {
				*Recursive call on each subfolder
				noi iegitaddmd , folder(`"`folderStd'/`dir'"') `all' `customFileRecurse' `skip' `replace' `automatic' `dryrun' skipfolders(`skipfolders')
			}
		}

		******************************
		*	Evaluate if file will be crated in this folder

		*Test if all of those lists are empty, meaning there are
		* no folders or files in this folder
		if `"`flist'`dlist'`olist'"' == "" noi writePlaceholder, folder(`"`folderStd'"') newfilename("`newPlaceholderFile'") customfiletocopy(`"`customFileStd'"') `automatic' `dryrun'

		*If the folder is not empty, test if option all were used.
		else if ("`all'" == "all") {

			*Test if a file with exactly that name is already used
			cap confirm file `"`folderStd'/`newPlaceholderFile'"'

			* No file with this name exists in this folder, create file without further ado
			if _rc != 0 noi writePlaceholder, folder(`"`folderStd'"') newfilename("`newPlaceholderFile'") customfiletocopy(`"`customFileStd'"') `automatic' `dryrun'

			* File exist, but no sintructions on how to deal with this has been given, throw error
			else if missing("`skip'") & missing("`replace'")  {
				noi di as error `"{phang}The file  `newPlaceholderFile' already exists. Either remove option {it:all} or use either option {it:skip} or {it:replace}. See help file before using either of these options unless you are already familiar with them.{p_end}"'
				error 602
			}

			* File exist, and instruction is to replace, create files and overwrite as needed
			else if !missing("`replace'") noi writePlaceholder,  folder(`"`folderStd'"') newfilename("`newPlaceholderFile'") customfiletocopy(`"`customFileStd'"') `automatic' `dryrun'

			* File exist, and instruction is to skip, do nothing
			else if !missing("`skip'") {
					*Nothing is done, this if-block is only included for readability and completion
			}

			* The code should nevere get to this point
			else  {
				noi di as error `"{phang}Coding error in if-chain in "All" block.Please report this error to dimeanalytics@worldbank.org or here: https://github.com/worldbank/ietoolkit/issues/new{p_end}"'
				error 602
			}
		}
		else {
			* Folder is not empty and option all is not used, so do nothing in this folder
		}
	}
	/******************************
	*******************************
		Exectute command with compare option
	*******************************
	******************************/

	else if !missing("`comparefolder'") {

		*List folders that are in comparefolder() but not in in folder()
		local comp_dlist : dir `"`comparefolderStd'"' dirs  "*" , respectcase
		local only_in_cdlist : list comp_dlist - dlist

		*Loop over all folders only in comparefolder()
		foreach dir of local only_in_cdlist {
			*Find all leaf folders. A leaf folder is a folder with no
			*sub-folder. Think of the folder structure as a tree, and
			*each folder with no sub-folders is an end of a branch where
			*you find leaves.
			noi findLeafFolders, folder(`"`comparefolderStd'/`dir'"')

			*Loop over all leaves and create accordingly
			foreach leaf in `r(leaves)' {
				*Leaf exist in compare folder, create the path to the leaf
				* to be created in the corresponding folder
				local folderleaf = subinstr(`"`leaf'"',`"`comparefolderStd'"', `"`folder'"', 1)

				*Create placeholder file in this new leaf
				noi writePlaceholder, folder(`"`folderleaf'"') newfilename("`newPlaceholderFile'") customfiletocopy(`"`customFileStd'"') `automatic' `dryrun'
			}
		}

		*When using the comparfolder() option, only recurse over files that exist in
		*both folder() and comparefolder(). Folders only in folder() are not relevant
		*when comapring. And folders only in comaprefolder() have already been addressed.
		local in_both_dlists : list comp_dlist & dlist
		foreach dir of local in_both_dlists {
			*Recursive call on each subfolder
			noi iegitaddmd , folder(`"`folderStd'/`dir'"') comparefolder(`"`comparefolder'/`dir'"') `customFileRecurse' `automatic' `dryrun' skipfolders(`skipfolders')
		}
	}
}

end

*Write a README.md file when iegitaddmd finds an empty folder
cap program drop writePlaceholder
program define   writePlaceholder

qui {
	syntax , folder(string) newfilename(string) [customfiletocopy(string) automatic dryrun]

	*Reset locals to be used in this command
	local dryrun_prompt ""
	local createfile ""

	*Create message to show in dryrun mode
	if !missing("`dryrun'") local dryrun_prompt " NO FILE WILL BE CREATED AS OPTION {bf:dryrun} IS USED!"

	*If manual was used, get manual confirmation for each file
	if missing("`automatic'") {
		noi di ""
		global confirmation "" //Reset global

		*Keep aslking for input until the input is either Y, y, N, n or BREAK
		while (upper("${confirmation}") != "Y" & upper("${confirmation}") != "N" & "${confirmation}" != "BREAK") {
		  noi di as txt "{pstd}You are about to create a file [`newfilename'] in the folder [`folder']. If the folder does not exist it will be created. Do you want to do that? To confirm type {bf:Y} and hit enter, to abort type {bf:N} and hit enter. Type {bf:BREAK} and hit enter to stop the code. See option {help iegitaddmd:automatic} to not be prompted before creating files.`dryrun_prompt'{p_end}", _request(confirmation)
		}
		*Copy user input to local
		local createfile = upper("${confirmation}")
		* If user wrote "BREAK" then exit the code
		if ("`createfile'" == "BREAK") error 1
	}
	*Automtic is used, always create the file
	else local createfile "Y"

	*Manual was used and input was N, no file were creaetd
	if 	("`createfile'" == "N") noi di as result "{pstd}No file or folder created.{p_end}"

	*Dryrun, list where file would have been created
	else if !missing("`dryrun'") noi di as result "{pstd}DRY RUN! Without option {bf:dryrun} file [`folder'/`newfilename'] would have been created.{p_end}"

	*If "manual" were used and input was Y or if manual was not used, create the file
	else if ("`createfile'" == "Y") {

		*Recursively create folder if needed
		noi rmkdir, folder(`"`folder'"')

		*Copy custom file if custom file is used
		if !missing(`"`customfile'"') copy "`customfile'" `"`folder'/`newfilename'"', replace
		*Custom file is not used, so cretae defeault file
		else {
			*Create file
			tempname 	newHandle
			cap file close 	`newHandle'
			file open  	`newHandle' using "`folder'/`newfilename'", text write replace
			*Write the content to the file
			file write  `newHandle' ///
				"# Placeholder file" _n _n ///
				"This file has been created automatically by the command **iegitaddmd** from the Stata package [**ietoolkit**](https://worldbank.github.io/ietoolkit) to make GitHub sync this folder. GitHub does not sync empty folders or folders that only contain ignored files, but in research projects it is often important to share the full standardized folder structure along with the actual files. This command is intended to be used with **iefolder**, but it can be used in any folder structure intended to be shared on GitHub." _n _n ///
				"In recently started projects, it is typical to create data folders, script folders (do-files, r-files) and output folders, among others. The output folders are initially empty, but the script files might include a file path to them for later use. If an output folder is empty and another collaborator clones the repository, then the output folder expected by the scripts will not be included by GitHub in the cloned repository, and the script will not run properly." _n _n ///
				"## You should replace the content of this placeholder file" _n _n ///
				"The text in this file should be replaced with text that describes the intended use of this folder. This file is written in markdown (.md) format, which is suitable for GitHub syncing (unlike .doc/.docx). If the file is named *README.md*, GitHub automatically displays its contents when someone navigates to the containing folder on GitHub.com using a web browser." _n _n ///
				"If you are new to markup languages (markdown, html etc.) then this [Markdown Tutorial](https://www.markdowntutorial.com/) is a great place to start. If you have some experience with markup languages, then this [Markdown Cheat Sheet](https://guides.github.com/pdfs/markdown-cheatsheet-online.pdf) is a great resource." _n _n ///
				"## Add similar files in other folders" _n _n ///
				"The Stata command **iegitaddmd** does not add anything to folders that already have content unless this is explicitly requested using the option `all`. It is best practice to create a *README.md* file in any folders that have content, for example, in folders which purpose might not obvious to someone using the repository for the first time. Again, if the file is named *README.md*, then the content of the file will be shown in the browser when someone explores the repository on GitHub.com. This is a very good way to document your code and your data work." _n _n ///
				"Another great use of a *README.md* file is to use it as a documentation on how the folder it sits in and its subfolders are organized,  where its content can be found, and where new content is meant to be saved. For example, if you have a folder called `/Baseline/`, then you can give a short description of the activities conducted during the baseline and where data, scripts and outputs related to it can be found." _n _n ///
				"## Removing this file" _n _n ///
				"Our recommendation is to not remove this file, as GitHub may stop syncing the parent folder unless the folder now has other content. We recommend to not even remove this file when content that is committed to this repository is added to this folder and the file can be removed without breaking the GitHub functionality, as it is better practice to replace the content of this file with content describing this specific folder rather than deleting it." _n _n

			*Closing the file
			file close 		`newHandle'
		}
		*Output that the file was created
		noi di as result "{pstd}File [`folder'/`newfilename'] created.{p_end}"
	}
}
end

*Write a README.md file when iegitaddmd finds an empty folder
cap program drop findLeafFolders
program define   findLeafFolders, rclass

qui {
	syntax, folder(string)

	local dlist : dir `"`folder'"' dirs  "*" , respectcase

	if missing(`"`dlist'"') {
		*This is a leaf, pass it back
		return local leaves `""`folder'""'
	}
	else {
		local return_leaves
		foreach dir of local dlist {
			*Recursive call on each subfolder
			findLeafFolders, folder(`"`folder'/`dir'"')
			local return_leaves `"`return_leaves' `r(leaves)'"'
		}
		return local leaves `"`return_leaves'"'
	}
}
end

*Recursively call parent folders in folderpath needed to be created until
* folder found that already exist, then creaet all subfolders.
cap program drop rmkdir
program define   rmkdir, rclass

qui {
	syntax, folder(string) [folderstocreate(string)]

	*Test if this folder exists
	mata : st_numscalar("r(dirExist)", direxists(`"`folder'"'))

	*Folder does not exist, find parent folder and make recursive call
	if (`r(dirExist)' == 0) {
		*Get the parent folder of folder
		local lastSlash = strpos(strreverse(`"`folder'"'),"/")
		local parentFolder = substr(`"`folder'"',1,strlen("`folder'")-`lastSlash')
		local thisFolder = substr(`"`folder'"', (-1 * `lastSlash')+1 ,.)

		*Make the coll recursivly on the parent folder and add this folder to folderstocreate()
		noi rmkdir , folder(`"`parentFolder'"') folderstocreate(`""`thisFolder'" `folderstocreate'"')
	}
	*Folder exist, create sub-folders to create if any
	else {
		*Create the folders needed
		foreach dir of local folderstocreate {
			mkdir "`folder'/`dir'"
			local folder "`folder'/`dir'"
		}
	}
}
end

*! version 6.3 5NOV2019 DIME Analytics dimeanalytics@worldbank.org

cap program drop   iegitaddmd
	program define iegitaddmd

qui {
	syntax , folder(string) [comparefolder(string) customfile(string) all skip replace AUTOmatic DRYrun skipfolders(string)]

	/******************************
	*******************************
		Test user input
	*******************************
	******************************/

	******************************
	*	Test input: folder

	*Test that folder exist
	mata : st_numscalar("r(dirExist)", direxists("`folder'"))

	if (`r(dirExist)' == 0) | (length("`folder'")<=10) {

		noi di as error `"{phang}The folder used in [folder(`folder')] does not exist or you have not entered the full path. For example, full paths on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}. Important: Specify the whole file path to the repository folder, not just {it:C:/} or {it:/user/} as that would create the placeholder file in every empty folder on your computer!{p_end}"'
		error 693
		exit
	}

	* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
	local folderStd			= subinstr(`"`folder'"',"\","/",.)

	******************************
	*	Test input: comparefolder

	if !missing("`comparefolder'") {
		mata : st_numscalar("r(dirExist)", direxists("`comparefolder'"))

		if (`r(dirExist)' == 0) | (length("`comparefolder'")<=10) {

			noi di as error `"{phang}The folder used in [comaparefolder(`comparefolder')] does not exist or you have not entered the full path. For example, full paths on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}. Important: Specify the whole file path to the repository folder, not just {it:C:/} or {it:/user/} as that would create the placeholder file in every empty folder on your computer!{p_end}"'
			error 693
			exit
		}

		* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
		local comparefolderStd	= subinstr(`"`comparefolder'"',"\","/",.)

		*Get the name of the last folder in both folder() and comparefolder()
		local thisLastSlash = strpos(strreverse(`"`folderStd'"'),"/")
		local thisFolder 	= substr(`"`folderStd'"', (-1 * `thisLastSlash')+1 ,.)
		local compLastSlash = strpos(strreverse(`"`comparefolderStd'"'),"/")
		local compFolder 	= substr(`"`comparefolderStd'"', (-1 * `compLastSlash')+1 ,.)

		*The last folder name should always be the same for folder() and
		* comparefolder() otherwise there it is likely that the to paths
		* point to differnet starting points in the two fodler trees that
		* are to be compared.
		if ("`compFolder'" != "`thisFolder'") {
			noi di as error `"{phang}The last folder [`thisFolder'] in [folder(`folder')] is not identical to the last folder [`compFolder'] in [comparefolder(`comparefolder')]. This is an indication that the the two fodler trees to be compared are not two versions of the same folder tree.{p_end}"'
			error 693
			exit
		}
	}

	******************************
	*	Test input: customfile

	*Test that file exist if not using default file
	if "`customfile'" != "" {
		*File option used test if file exists
		capture confirm file "`customfile'"
		if _rc {
			*File does not exist, throw error
			noi di as error `"{phang}File "`customfile'" was not found. Remember that you must enter the full path. For example, on most Windows computers it starts with {it:C:/} and on most Mac computers with {it:/user/}.{p_end}"'
			error 693
			exit
		}

		* Get the name of file (include path to keep )
		* File paths can have both forward and/or back slash. We'll standardize them so they're easier to handle
		local customFileStd	= subinstr("`customfile'","\","/",.)
		*Find the last slash in the file name
		local lastSlash = strpos(strreverse(`"`customFileStd'"'),"/")
		*Use that position to get the file name. Multiply with minus one as we count from the back
		local customFileName = substr(`"`customFileStd'"', (-1 * `lastSlash')+1 ,.)
		*Used for the recursive call of the command when there is a subfolder
		local customFileRecurse `"customfile(`customFileStd')"'

		*Path and name of thile regardless if customfile were used
		local newPlaceholderFile `"`customFileName'"'
	}
	else {
		*Path and name of thile regardless if customfile were not used
		local newPlaceholderFile "README.md"
	}

	******************************
	*	Test input: skip & replace

	*Options skip and replace cannot be used at the same time
	if !missing("`skip'") & !missing("`replace'") {
		noi di as error `"{phang}The options skip and replace may not be used at the same time.{p_end}"'
		error 198
		exit
	}

	*Options all, skip and replace cannot be used together with comparefolder()
	if !missing("`comparefolder'") & (!missing("`all'") | !missing("`skip'") | !missing("`replace'")) {
		noi di as error `"{phang}The options all, skip and replace may not be used when option comparefolder() is used.{p_end}"'
		error 198
		exit
	}

	* Test that paths are not used in skip folder. I.e. no slashes are used
	local anyslash = strpos("`skipfolders'","/") + strpos("`skipfolders'","\")
	if `anyslash' {
		noi di as error `"{phang}The options [skipfolders(`skipfolders')] may not include forward or backward slashes, i.e. may not include paths. Only folder names.{p_end}"'
		error 198
		exit
	}

	*Add .git folder to folders to be skipped
	local skipfolders `skipfolders' ".git"

	/******************************
	*******************************
		List Files and folders
	*******************************
	******************************/

	******************************
	*	List all files and folders

	*List files, directories and other files
	local flist : dir `"`folderStd'"' files "*"	, respectcase
	local dlist : dir `"`folderStd'"' dirs  "*" , respectcase
	local olist : dir `"`folderStd'"' other "*"	, respectcase

	/******************************
	*******************************
		Exectute command without compare option
	*******************************
	******************************/

	if missing("`comparefolder'") {

		******************************
		*	Call command recursively on all sub-folders

		*Use the command on each subfolder to this folder (if any)
		foreach dir of local dlist {
			*Test if directory is in
			if `:list dir in skipfolders' {
				noi di as result "{pstd}SKIPPED: Folder [`folder'/`dir'] is skipped. See option skipvars() in {help iegitaddmd}.{p_end}"
			}
			else {
				*Recursive call on each subfolder
				noi iegitaddmd , folder(`"`folderStd'/`dir'"') `all' `customFileRecurse' `skip' `replace' `automatic' `dryrun' skipfolders(`skipfolders')
			}
		}

		******************************
		*	Evaluate if file will be crated in this folder

		*Test if all of those lists are empty, meaning there are
		* no folders or files in this folder
		if `"`flist'`dlist'`olist'"' == "" noi writePlaceholder, folder(`"`folderStd'"') newfilename("`newPlaceholderFile'") customfiletocopy(`"`customFileStd'"') `automatic' `dryrun'

		*If the folder is not empty, test if option all were used.
		else if ("`all'" == "all") {

			*Test if a file with exactly that name is already used
			cap confirm file `"`folderStd'/`newPlaceholderFile'"'

			* No file with this name exists in this folder, create file without further ado
			if _rc != 0 noi writePlaceholder, folder(`"`folderStd'"') newfilename("`newPlaceholderFile'") customfiletocopy(`"`customFileStd'"') `automatic' `dryrun'

			* File exist, but no sintructions on how to deal with this has been given, throw error
			else if missing("`skip'") & missing("`replace'")  {
				noi di as error `"{phang}The file  `newPlaceholderFile' already exists. Either remove option {it:all} or use either option {it:skip} or {it:replace}. See help file before using either of these options unless you are already familiar with them.{p_end}"'
				error 602
			}

			* File exist, and instruction is to replace, create files and overwrite as needed
			else if !missing("`replace'") noi writePlaceholder,  folder(`"`folderStd'"') newfilename("`newPlaceholderFile'") customfiletocopy(`"`customFileStd'"') `automatic' `dryrun'

			* File exist, and instruction is to skip, do nothing
			else if !missing("`skip'") {
					*Nothing is done, this if-block is only included for readability and completion
			}

			* The code should nevere get to this point
			else  {
				noi di as error `"{phang}Coding error in if-chain in "All" block.Please report this error to dimeanalytics@worldbank.org or here: https://github.com/worldbank/ietoolkit/issues/new{p_end}"'
				error 602
			}
		}
		else {
			* Folder is not empty and option all is not used, so do nothing in this folder
		}
	}
	/******************************
	*******************************
		Exectute command with compare option
	*******************************
	******************************/

	else if !missing("`comparefolder'") {

		*List folders that are in comparefolder() but not in in folder()
		local comp_dlist : dir `"`comparefolderStd'"' dirs  "*" , respectcase
		local only_in_cdlist : list comp_dlist - dlist

		*Loop over all folders only in comparefolder()
		foreach dir of local only_in_cdlist {
			*Find all leaf folders. A leaf folder is a folder with no
			*sub-folder. Think of the folder structure as a tree, and
			*each folder with no sub-folders is an end of a branch where
			*you find leaves.
			noi findLeafFolders, folder(`"`comparefolderStd'/`dir'"')

			*Loop over all leaves and create accordingly
			foreach leaf in `r(leaves)' {
				*Leaf exist in compare folder, create the path to the leaf
				* to be created in the corresponding folder
				local folderleaf = subinstr(`"`leaf'"',`"`comparefolderStd'"', `"`folder'"', 1)

				*Create placeholder file in this new leaf
				noi writePlaceholder, folder(`"`folderleaf'"') newfilename("`newPlaceholderFile'") customfiletocopy(`"`customFileStd'"') `automatic' `dryrun'
			}
		}

		*When using the comparfolder() option, only recurse over files that exist in
		*both folder() and comparefolder(). Folders only in folder() are not relevant
		*when comapring. And folders only in comaprefolder() have already been addressed.
		local in_both_dlists : list comp_dlist & dlist
		foreach dir of local in_both_dlists {
			*Recursive call on each subfolder
			noi iegitaddmd , folder(`"`folderStd'/`dir'"') comparefolder(`"`comparefolder'/`dir'"') `customFileRecurse' `automatic' `dryrun' skipfolders(`skipfolders')
		}
	}
}

end

*Write a README.md file when iegitaddmd finds an empty folder
cap program drop writePlaceholder
program define   writePlaceholder

qui {
	syntax , folder(string) newfilename(string) [customfiletocopy(string) automatic dryrun]

	*Reset locals to be used in this command
	local dryrun_prompt ""
	local createfile ""

	*Create message to show in dryrun mode
	if !missing("`dryrun'") local dryrun_prompt " NO FILE WILL BE CREATED AS OPTION {bf:dryrun} IS USED!"

	*If manual was used, get manual confirmation for each file
	if missing("`automatic'") {
		noi di ""
		global confirmation "" //Reset global

		*Keep aslking for input until the input is either Y, y, N, n or BREAK
		while (upper("${confirmation}") != "Y" & upper("${confirmation}") != "N" & "${confirmation}" != "BREAK") {
		  noi di as txt "{pstd}You are about to create a file [`newfilename'] in the folder [`folder']. If the folder does not exist it will be created. Do you want to do that? To confirm type {bf:Y} and hit enter, to abort type {bf:N} and hit enter. Type {bf:BREAK} and hit enter to stop the code. See option {help iegitaddmd:automatic} to not be prompted before creating files.`dryrun_prompt'{p_end}", _request(confirmation)
		}
		*Copy user input to local
		local createfile = upper("${confirmation}")
		* If user wrote "BREAK" then exit the code
		if ("`createfile'" == "BREAK") error 1
	}
	*Automtic is used, always create the file
	else local createfile "Y"

	*Manual was used and input was N, no file were creaetd
	if 	("`createfile'" == "N") noi di as result "{pstd}No file or folder created.{p_end}"

	*Dryrun, list where file would have been created
	else if !missing("`dryrun'") noi di as result "{pstd}DRY RUN! Without option {bf:dryrun} file [`folder'/`newfilename'] would have been created.{p_end}"

	*If "manual" were used and input was Y or if manual was not used, create the file
	else if ("`createfile'" == "Y") {

		*Recursively create folder if needed
		noi rmkdir, folder(`"`folder'"')

		*Copy custom file if custom file is used
		if !missing(`"`customfile'"') copy "`customfile'" `"`folder'/`newfilename'"', replace
		*Custom file is not used, so cretae defeault file
		else {
			*Create file
			tempname 	newHandle
			cap file close 	`newHandle'
			file open  	`newHandle' using "`folder'/`newfilename'", text write replace
			*Write the content to the file
			file write  `newHandle' ///
				"# Placeholder file" _n _n ///
				"This file has been created automatically by the command **iegitaddmd** from the Stata package [**ietoolkit**](https://worldbank.github.io/ietoolkit) to make GitHub sync this folder. GitHub does not sync empty folders or folders that only contain ignored files, but in research projects it is often important to share the full standardized folder structure along with the actual files. This command is intended to be used with **iefolder**, but it can be used in any folder structure intended to be shared on GitHub." _n _n ///
				"In recently started projects, it is typical to create data folders, script folders (do-files, r-files) and output folders, among others. The output folders are initially empty, but the script files might include a file path to them for later use. If an output folder is empty and another collaborator clones the repository, then the output folder expected by the scripts will not be included by GitHub in the cloned repository, and the script will not run properly." _n _n ///
				"## You should replace the content of this placeholder file" _n _n ///
				"The text in this file should be replaced with text that describes the intended use of this folder. This file is written in markdown (.md) format, which is suitable for GitHub syncing (unlike .doc/.docx). If the file is named *README.md*, GitHub automatically displays its contents when someone navigates to the containing folder on GitHub.com using a web browser." _n _n ///
				"If you are new to markup languages (markdown, html etc.) then this [Markdown Tutorial](https://www.markdowntutorial.com/) is a great place to start. If you have some experience with markup languages, then this [Markdown Cheat Sheet](https://guides.github.com/pdfs/markdown-cheatsheet-online.pdf) is a great resource." _n _n ///
				"## Add similar files in other folders" _n _n ///
				"The Stata command **iegitaddmd** does not add anything to folders that already have content unless this is explicitly requested using the option `all`. It is best practice to create a *README.md* file in any folders that have content, for example, in folders which purpose might not obvious to someone using the repository for the first time. Again, if the file is named *README.md*, then the content of the file will be shown in the browser when someone explores the repository on GitHub.com. This is a very good way to document your code and your data work." _n _n ///
				"Another great use of a *README.md* file is to use it as a documentation on how the folder it sits in and its subfolders are organized,  where its content can be found, and where new content is meant to be saved. For example, if you have a folder called `/Baseline/`, then you can give a short description of the activities conducted during the baseline and where data, scripts and outputs related to it can be found." _n _n ///
				"## Removing this file" _n _n ///
				"Our recommendation is to not remove this file, as GitHub may stop syncing the parent folder unless the folder now has other content. We recommend to not even remove this file when content that is committed to this repository is added to this folder and the file can be removed without breaking the GitHub functionality, as it is better practice to replace the content of this file with content describing this specific folder rather than deleting it." _n _n

			*Closing the file
			file close 		`newHandle'
		}
		*Output that the file was created
		noi di as result "{pstd}File [`folder'/`newfilename'] created.{p_end}"
	}
}
end

*Write a README.md file when iegitaddmd finds an empty folder
cap program drop findLeafFolders
program define   findLeafFolders, rclass

qui {
	syntax, folder(string)

	local dlist : dir `"`folder'"' dirs  "*" , respectcase

	if missing(`"`dlist'"') {
		*This is a leaf, pass it back
		return local leaves `""`folder'""'
	}
	else {
		local return_leaves
		foreach dir of local dlist {
			*Recursive call on each subfolder
			findLeafFolders, folder(`"`folder'/`dir'"')
			local return_leaves `"`return_leaves' `r(leaves)'"'
		}
		return local leaves `"`return_leaves'"'
	}
}
end

*Recursively call parent folders in folderpath needed to be created until
* folder found that already exist, then creaet all subfolders.
cap program drop rmkdir
program define   rmkdir, rclass

qui {
	syntax, folder(string) [folderstocreate(string)]

	*Test if this folder exists
	mata : st_numscalar("r(dirExist)", direxists(`"`folder'"'))

	*Folder does not exist, find parent folder and make recursive call
	if (`r(dirExist)' == 0) {
		*Get the parent folder of folder
		local lastSlash = strpos(strreverse(`"`folder'"'),"/")
		local parentFolder = substr(`"`folder'"',1,strlen("`folder'")-`lastSlash')
		local thisFolder = substr(`"`folder'"', (-1 * `lastSlash')+1 ,.)

		*Make the coll recursivly on the parent folder and add this folder to folderstocreate()
		noi rmkdir , folder(`"`parentFolder'"') folderstocreate(`""`thisFolder'" `folderstocreate'"')
	}
	*Folder exist, create sub-folders to create if any
	else {
		*Create the folders needed
		foreach dir of local folderstocreate {
			mkdir "`folder'/`dir'"
			local folder "`folder'/`dir'"
		}
	}
}
end


iegraph helpfile - links to two way options

{smcl}
{* 31 May 2017}{...}
{hline}
help for {hi:iegraph}
{hline}

{title:Title}

{phang2}{cmdab:iegraph} {hline 2} Generates graphs based on regressions with treatment dummies common in impact evaluations.

{title:Syntax}

{phang2}
{cmdab:iegraph} {varlist}
, [ {cmdab:basicti:tle(}{it:string}{cmd:)} {cmdab:varl:abels}
{cmdab:save(}{it:string}{cmd:)} {cmdab:grey:scale} {cmdab:yzero}
{cmd:noconfbars} {cmdab:confbarsnone(}{it:varlist}{cmd:)}
{cmd:norestore} {cmdab:baropt:ions(}{it:string}{cmd:)}
{it:{help scatter##twoway_options:twoway_scatter_options}}
]

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt :{cmdab:basicti:tle(}{it:string}{cmd:)}} Manually sets the title of the graph.{p_end}
{synopt :{cmdab:varl:abels}} Uses variable labels for legends instead of variable names.{p_end}
{synopt :{cmdab:save(}{it:string}{cmd:)}} Sets the filename and the directory to which the graph will be set/exported.{p_end}
{synopt :{cmdab:grey:scale}} Uses greyscales for the bars instead of colors.{p_end}
{synopt :{cmdab:yzero}} Forces y-axis on the graph to start at 0.{p_end}
{synopt :{cmd:noconfbars}} Removes the confidence interval bars from graphs for all treatments.{p_end}
{synopt :{cmdab:confbarsnone(}{it:varlist}{cmd:)}} Removes confidence interval bars from only the {it:varlist} listed.{p_end}
{synopt :{cmd:norestore}} Allows you to debug your two way graph settings on the data set prepared by iegraph. To be used with {it:r(cmd)}.{p_end}
{synoptline}

{pstd}Any twoway graph scatter options that can be used with normal twoway graph scatter commands can
	also be used. If any of these commands conflict with any of the built in options,
	then the user specified settings have precedence. See example 2 for details.{p_end}

{marker desc}
{title:Description}

{pstd}{cmdab:iegraph} This command creates bar graphs on the basis of the coefficients
	of treatment dummies in regression results. This command is developed for reading
	stored results from two types of impact evaluation regression models, but there
	are countless of other examples where the command also can be used. {cmd:iegraph} must
	be used immediately after running the regression or as long as the regression result is
	still stored in or restored to Stata's {help ereturn} results.

{pstd}{bf:Model 1: OLS with Treatment Dummies}{break}The most typical impact evaluation regression is
	to have the outcome variable as the dependent variable and one dummy for each
	treatment arm where control is the omitted category. These regressions can also include
	covariates, fixed effects etc., but as long as the treatment status is defined by
	mutually exclusive dummy variables. See especially examples 1 and 2 below. This command
	works with any number of treatment arms but works best from two arms (treatment
	and control) to five treatment arms (4 different treatments and control). More
	arms than that may result in a still correct but perhaps cluttered graph.

{pstd}{bf:Model 2: Difference-in-Differences}{break}Another typical regression model in impact
	evaluations are difference-in-difference (Diff-in-Diff) models with two treatment arms (treatment
	and control) and two time periods. If the Diff-in-Diff regression is specified as having the
	outcome variable as the dependent variable and three dummy variables (time, treatment
	and timeXtreatment) as the independent variables, then this command will produce a nice
	graph. Controls, treatment effects etc. may be added to the regression model. See especially example 3.

{pstd}{bf:Graph Output}{break}The graph generated by this command is created using the following values. The
	control bar is the mean of the outcome variable for the control group. It is not
	the constant from the regression as those are not identical if, for example, fixed effects
	and covariates were used. For each treatment group the bar is the sum of the value
	of the control bar and the beta coefficient in the regression of the corresponding
	treatment dummy. The confidence intervals are calculated from the variance in the
	beta coefficients in the regression.{p_end}

{pstd}The graph also includes the N for each treatment arm in the regression and uses
	that value as labels on the x-axis. Stars are added to this value if the corresponding
	coefficient is statistically different from zero in the regression{p_end}

{marker optslong}
{title:Options}

{phang}{cmdab:basicti:tle(}{it:string}{cmd:)} Manually sets the title of the graph. To
	apply formatting like title size, position, etc., use Stata's buil
	in {help title_options:title() option} instead.{p_end}

{phang}{cmdab:varl:abels} Sets the legends to the variable labels for the
	variables instead of the variable names.{p_end}

{phang}{cmdab:save(}{it:string}{cmd:)} Sets the filename and the directory to which
	the graph will be set. If the filename ends with no extension or '.gph', it will be
	saved in the graph format. Extensions(png,pdf,tif,wmf,emf,ps,and eps) will be exported.
	Wmf and Emf are only available for the Windows version of Stata. Png and Tif for all
	versions of Stata except Console.{p_end}

{phang}{cmdab:grey:scale} Uses greyscales for the bars instead of colors. The color
	of the control bar will be black and the treatment bar will run in equal shade
	differences from light grey to dark grey.{p_end}

{phang}{cmdab:yzero} Manually sets the y-axis of the graph to start at zero
	instead of the Stata default. In many cases, we expect that neither the default
	settings nor this option will make the axes look perfect, but you may use Stata's built
	in {help axis_option:axis options} that allow you to set the axes to perfectly fit
	your data.{p_end}

{phang}{cmd:noconfbars} Removes the confidence interval bars from graphs for all
	treatments. The default value for the confidence interval bars is 95%. {p_end}

{phang}{cmdab:confbarsnone(}{it:varlist}{cmd:)} Removes confidence interval bars
	from only the {it:varlist} listed. The remaining variables in the graphs which
	have not been specified in {cmdab:confbarsnone} will still have the confidence
	interval bars. {p_end}

{phang}{cmdab:norestore} Returns the data set that iegraph prepares to create
	the graph. This is helpful when de-bugging how one of Stata's many graph
	options can be applied to an iegraph graph. This option is meant to be
	used in combination with the {help return:returned result} in {it:r(cmd)}. {it:r(cmd)}
	gives you the line of code iegraph prepares to create the graph and {cmdab:norestore} gives you
	access to the data that code is meant to be used on. This approach will help
	you de-bug how to apply Stata's built in graph options to an iegraph graph.
	Note that this option deletes any unsaved changes made to your data.{p_end}

{marker optslong}
{title:Examples}

{pstd} {hi:Example 1.}

{pmore} {inp:regress} {it:outcomevar treatment_dummy}{break}
		{inp:iegraph} {it:treatment_dummy} , {inp:basictitle({it:"Treatment Effect on Outcome"})}

{pmore}In the example above, there are only two treatment arms (treatment and
		control). {it:treatment_dummy} has a 1 for all treatment observations and
		a 0 for all control observations. The graph will have one bar for control and
		it shows the mean for {it:outcomevar} for all observations in control. The
		second bar in the graph will be the sum of that mean and the coefficient
		for {it:treatment_dummy} in the regression. The graph will also have the
		title: Treatment Effect on Outcome.

{pstd} {hi:Example 2.}

{pmore} {inp:regress} {it:income tmt_1 tmt_2 age education}{inp:, cluster(}{it:district}{inp:)}{break}
		{inp:iegraph} {it:tmt_1 tmt_2}{inp:, noconfbars yzero basictitle({it:"Treatment effect on income"}) }

{pmore}In the example above, the treatment effect on income in researched. There
		are three treatment arms; control, treatment 1 ({it:tmt_1}) and treatment
		2 ({it:tmt_2}). It is important that no observation has the value 1 in
		both {it:tmt_1} and {it:tmt_2} (i.e. no observation is in more than one
		treatment) and some observations must have the value 0 in both {it:tmt_1}
		and {it:tmt_2} (i.e. control observations). The variables {it:age} and
		{it:education} are covariates (control variables) and are not included
		in {cmd:iegraph}. {inp:noconfbars} omits the confidence interval bars
		, and {inp:yzero} sets the y-axis to start at 0.

{pstd} {hi:Example 3.}

{pmore} {inp:regress} {it:chld_wght time treat timeXtreat}{break}
		{inp:iegraph} {it:time treat timeXtreat} {inp:, basictitle({it:"Treatment effect on Child Weight (Diff-in-Diff)"})}

{pmore}In the example above, the data set is a panel data set with two time
		periods and the regression estimates the treatment effect on child weight
		using a Difference-in-Differences model.
		The dummy variable {it:time} indicates if it is time period 0 or 1.
		The dummy variable {it:treat} indicates if the observation is treatment
		or control. {it:timeXtreat} is the interaction term of {it:time}
		and {it:treat}. This the standard way to set up a Difference-in-Differences
		regression model.

{pstd} {hi:Example 4.}

{pmore} {inp:regress} {it:harvest T1 T2 T3 } {break}
		{inp:iegraph} {it:T1 T2 T3} {inp:, basictitle({it:"Treatment effect on harvest"})
		xlabel(,angle(45)) yzero ylabel(minmax) save({it:"Graph1.gph"})}

{pmore}The example above shows how to save a graph to disk. It also shows that
	most two-way graph options can be used. In this example the {cmd:iegraph}
	option {cdm:yzero} conflicts with the two-way option {cmd:ylabel(minmax)}.
	In such a case the user specified option takes precedence over {cmd:iegraph}
	options like {cdm:yzero}.

{title:Acknowledgements}

{phang}We would like to acknowledge the help in testing and proofreading we received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Luiza Cardoso De Andrade{break}Michael Orevba{break}Ahmad Zia Wahdat{break}

{title:Authors}

{phang}Kristoffer Bjarkefur & Mrijan Rimal, The World Bank, DECIE

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit iegraph" in the subject line to:{break}
		 kbjarkefur@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through
		 the github repository of ietoolkit:{break}
		 {browse "https://github.com/worldbank/ietoolkit"}

{smcl}
{* 31 May 2017}{...}
{hline}
help for {hi:iegraph}
{hline}

{title:Title}

{phang2}{cmdab:iegraph} {hline 2} Generates graphs based on regressions with treatment dummies common in impact evaluations.

{title:Syntax}

{phang2}
{cmdab:iegraph} {varlist}
, [ {cmdab:basicti:tle(}{it:string}{cmd:)} {cmdab:varl:abels}
{cmdab:save(}{it:string}{cmd:)} {cmdab:grey:scale} {cmdab:yzero}
{cmd:noconfbars} {cmdab:confbarsnone(}{it:varlist}{cmd:)}
{cmd:norestore} {cmdab:baropt:ions(}{it:string}{cmd:)}
{it:{help scatter##twoway_options:twoway_scatter_options}}
]

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt :{cmdab:basicti:tle(}{it:string}{cmd:)}} Manually sets the title of the graph.{p_end}
{synopt :{cmdab:varl:abels}} Uses variable labels for legends instead of variable names.{p_end}
{synopt :{cmdab:save(}{it:string}{cmd:)}} Sets the filename and the directory to which the graph will be set/exported.{p_end}
{synopt :{cmdab:grey:scale}} Uses greyscales for the bars instead of colors.{p_end}
{synopt :{cmdab:yzero}} Forces y-axis on the graph to start at 0.{p_end}
{synopt :{cmd:noconfbars}} Removes the confidence interval bars from graphs for all treatments.{p_end}
{synopt :{cmdab:confbarsnone(}{it:varlist}{cmd:)}} Removes confidence interval bars from only the {it:varlist} listed.{p_end}
{synopt :{cmd:norestore}} Allows you to debug your two way graph settings on the data set prepared by iegraph. To be used with {it:r(cmd)}.{p_end}
{synoptline}

{pstd}Any twoway graph scatter options that can be used with normal twoway graph scatter commands can
	also be used. If any of these commands conflict with any of the built in options,
	then the user specified settings have precedence. See example 2 for details.{p_end}

{marker desc}
{title:Description}

{pstd}{cmdab:iegraph} This command creates bar graphs on the basis of the coefficients
	of treatment dummies in regression results. This command is developed for reading
	stored results from two types of impact evaluation regression models, but there
	are countless of other examples where the command also can be used. {cmd:iegraph} must
	be used immediately after running the regression or as long as the regression result is
	still stored in or restored to Stata's {help ereturn} results.

{pstd}{bf:Model 1: OLS with Treatment Dummies}{break}The most typical impact evaluation regression is
	to have the outcome variable as the dependent variable and one dummy for each
	treatment arm where control is the omitted category. These regressions can also include
	covariates, fixed effects etc., but as long as the treatment status is defined by
	mutually exclusive dummy variables. See especially examples 1 and 2 below. This command
	works with any number of treatment arms but works best from two arms (treatment
	and control) to five treatment arms (4 different treatments and control). More
	arms than that may result in a still correct but perhaps cluttered graph.

{pstd}{bf:Model 2: Difference-in-Differences}{break}Another typical regression model in impact
	evaluations are difference-in-difference (Diff-in-Diff) models with two treatment arms (treatment
	and control) and two time periods. If the Diff-in-Diff regression is specified as having the
	outcome variable as the dependent variable and three dummy variables (time, treatment
	and timeXtreatment) as the independent variables, then this command will produce a nice
	graph. Controls, treatment effects etc. may be added to the regression model. See especially example 3.

{pstd}{bf:Graph Output}{break}The graph generated by this command is created using the following values. The
	control bar is the mean of the outcome variable for the control group. It is not
	the constant from the regression as those are not identical if, for example, fixed effects
	and covariates were used. For each treatment group the bar is the sum of the value
	of the control bar and the beta coefficient in the regression of the corresponding
	treatment dummy. The confidence intervals are calculated from the variance in the
	beta coefficients in the regression.{p_end}

{pstd}The graph also includes the N for each treatment arm in the regression and uses
	that value as labels on the x-axis. Stars are added to this value if the corresponding
	coefficient is statistically different from zero in the regression{p_end}

{marker optslong}
{title:Options}

{phang}{cmdab:basicti:tle(}{it:string}{cmd:)} Manually sets the title of the graph. This
	can be overwritten using twoway scatter's title feature for more options like title size, position
	, etc.{p_end}

{phang}{cmdab:varl:abels} Sets the legends to the variable labels for the
	variables instead of the variable names.{p_end}

{phang}{cmdab:save(}{it:string}{cmd:)} Sets the filename and the directory to which
	the graph will be set. If the filename ends with no extension or '.gph', it will be
	saved in the graph format. Extensions(png,pdf,tif,wmf,emf,ps,and eps) will be exported.
	Wmf and Emf are only available for the Windows version of Stata. Png and Tif for all
	versions of Stata except Console.{p_end}

{phang}{cmdab:grey:scale} Uses greyscales for the bars instead of colors. The color
	of the control bar will be black and the treatment bar will run in equal shade
	differences from light grey to dark grey.{p_end}

{phang}{cmdab:yzero} Manually sets the y-axis of the graph to start at zero
	instead of the Stata default.{p_end}

{phang}{cmd:noconfbars} Removes the confidence interval bars from graphs for all
	treatments. The default value for the confidence interval bars is 95%. {p_end}

{phang}{cmdab:confbarsnone(}{it:varlist}{cmd:)} Removes confidence interval bars
	from only the {it:varlist} listed. The remaining variables in the graphs which
	have not been specified in {cmdab:confbarsnone} will still have the confidence
	interval bars. {p_end}

{phang}{cmdab:norestore} Returns the data set that iegraph prepares to create
	the graph. This is helpful when de-bugging how one of Stata's many graph
	options can be applied to an iegraph graph. This option is meant to be
	used in combination with the {help return:returned result} in {it:r(cmd)}. {it:r(cmd)}
	gives you the line of code iegraph prepares to create the graph and {cmdab:norestore} gives you
	access to the data that code is meant to be used on. This approach will help
	you de-bug how to apply Stata's built in graph options to an iegraph graph.
	Note that this option deletes any unsaved changes made to your data.{p_end}

{marker optslong}
{title:Examples}

{pstd} {hi:Example 1.}

{pmore} {inp:regress} {it:outcomevar treatment_dummy}{break}
		{inp:iegraph} {it:treatment_dummy} , {inp:basictitle({it:"Treatment Effect on Outcome"})}

{pmore}In the example above, there are only two treatment arms (treatment and
		control). {it:treatment_dummy} has a 1 for all treatment observations and
		a 0 for all control observations. The graph will have one bar for control and
		it shows the mean for {it:outcomevar} for all observations in control. The
		second bar in the graph will be the sum of that mean and the coefficient
		for {it:treatment_dummy} in the regression. The graph will also have the
		title: Treatment Effect on Outcome.

{pstd} {hi:Example 2.}

{pmore} {inp:regress} {it:income tmt_1 tmt_2 age education}{inp:, cluster(}{it:district}{inp:)}{break}
		{inp:iegraph} {it:tmt_1 tmt_2}{inp:, noconfbars yzero basictitle({it:"Treatment effect on income"}) }

{pmore}In the example above, the treatment effect on income in researched. There
		are three treatment arms; control, treatment 1 ({it:tmt_1}) and treatment
		2 ({it:tmt_2}). It is important that no observation has the value 1 in
		both {it:tmt_1} and {it:tmt_2} (i.e. no observation is in more than one
		treatment) and some observations must have the value 0 in both {it:tmt_1}
		and {it:tmt_2} (i.e. control observations). The variables {it:age} and
		{it:education} are covariates (control variables) and are not included
		in {cmd:iegraph}. {inp:noconfbars} omits the confidence interval bars
		, and {inp:yzero} sets the y-axis to start at 0.

{pstd} {hi:Example 3.}

{pmore} {inp:regress} {it:chld_wght time treat timeXtreat}{break}
		{inp:iegraph} {it:time treat timeXtreat} {inp:, basictitle({it:"Treatment effect on Child Weight (Diff-in-Diff)"})}

{pmore}In the example above, the data set is a panel data set with two time
		periods and the regression estimates the treatment effect on child weight
		using a Difference-in-Differences model.
		The dummy variable {it:time} indicates if it is time period 0 or 1.
		The dummy variable {it:treat} indicates if the observation is treatment
		or control. {it:timeXtreat} is the interaction term of {it:time}
		and {it:treat}. This the standard way to set up a Difference-in-Differences
		regression model.

{pstd} {hi:Example 4.}

{pmore} {inp:regress} {it:harvest T1 T2 T3 } {break}
		{inp:iegraph} {it:T1 T2 T3} {inp:, basictitle({it:"Treatment effect on harvest"})
		xlabel(,angle(45)) yzero ylabel(minmax) save({it:"Graph1.gph"})}

{pmore}The example above shows how to save a graph to disk. It also shows that
	most two-way graph options can be used. In this example the {cmd:iegraph}
	option {cdm:yzero} conflicts with the two-way option {cmd:ylabel(minmax)}.
	In such a case the user specified option takes precedence over {cmd:iegraph}
	options like {cdm:yzero}.

{title:Acknowledgements}

{phang}We would like to acknowledge the help in testing and proofreading we received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Luiza Cardoso De Andrade{break}Michael Orevba{break}Ahmad Zia Wahdat{break}

{title:Authors}

{phang}Kristoffer Bjarkefur & Mrijan Rimal, The World Bank, DECIE

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit iegraph" in the subject line to:{break}
		 kbjarkefur@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through
		 the github repository of ietoolkit:{break}
		 {browse "https://github.com/worldbank/ietoolkit"}