*! Version 3.0 <13dec2017>
*! Author: R.Andres Castaneda -- acastanedaa@worldbank.org
*! Author: Santiago Garriga   -- santiago.garriga@psestudent.eu

/* *===========================================================================
Do2screen: Program to display do-files in result's screen
-------------------------------------------------------------------
Created: 		06Feb2013	(Santiago Garriga & Andres Castaneda)
Modified: 	29Dec2015	(Santiago Garriga & Andres Castaneda)
Modified: 	26Apr2016	(Andres Castaneda)
Modified: 	15aug2017	(Andres Castaneda)
Modified: 	23sep2017	(Andres Castaneda)
version:		02.3
Dependencies: 	THE WORLD BANK
*===========================================================================*/
version 14

program define do2screen, rclass

syntax  [using/],								      ///
[															        ///
VARiables(string)							        ///
find(string)								          ///
lines(int 5) 								          ///
range(numlist min=1 max=2)	          ///
folder(string)							          ///
text(string)								          ///
replace											          ///
labels timer								          ///
noprevious	comments  		            ///
varout(passthru)	nolinenumbers       ///
lrep(passthru) rrep(passthru)         ///
dblq(passthru) SCALARname(passthru)   ///
]

* ========================================================
* ===============================1.ERROR Messages=========
* =========================================================

* Display Options (Find, Variables and Range)

qui {
	preserve
	timer clear
	local aux = 0
	cap confirm existence `variables'
	if (_rc == 0 ) local ++aux
	cap confirm existence `find'
	if (_rc == 0 ) local ++aux
	cap confirm existence `range'
	if (_rc == 0 ) local ++aux

	if (`aux' > 1) {
		disp in red "Options variable, find and range are mutually exclusive. " ///
		" You must chose only one of them"
		error
	}

	if (`aux' == 0) {
		disp in red "You should choose at least one option: variable, find and range."
		error
	}

	if (!missing("`previous'") & missing("`variables'")) {
		disp in red "noprevious option must be specified with variables option"
		error
	}
	if (!missing("`previous'") & (!missing("`find'") | !missing("`range'"))) {
		disp in red "noprevious option cannot be specified with option find or range"
		error
	}


	* ===============================================================
	* ============2. Set Default Options=============================
	* ===============================================================

	* Folder
	if (`"`folder'"' != `""') {
		if regexm(`"`folder'"', `"[\]$"') ///
		local folder = reverse(substr(reverse(`"`folder'"'), 2, .))
		if regexm(`"`folder'"', `"[a-zA-Z0-9]$"') local folder "`folder'/"
		local cdir "`c(pwd)'"
		cd "`folder'"
	}

	* Range and lines (default option for the range)
	if ("`range'" != "" ) {
		local start: word 1 of `range'
		if (wordcount("`range'") == 1) {
			local end = `start' + `lines'
		} //  range == 1
		else {
			local end: word 2 of `range'
			local lines = `end' - `start'
		} // range == 2
	}

	* text option is selected
	if ("`text'" != "") {
		tempname textfile
		if (regexm("`text'","^.*\.txt$") == 0 ) local text "`text'.txt"
		log using "`text'", text name(`textfile') `replace'
	}


	* If using
	if (`"`using'"' == `""') local dofiles: dir . files "*.do"

	if `"`using'"' != `""' {
		local dofiles `""`using'""'
		if (substr(reverse(`dofiles'),1,3) != "od.") {
			local dofiles `"`dofiles'.do"'

		}
	}


	* scalar name
	if ("`scalarname'" == "") local scalarname = "scalarname(s_varcode)"

	* ===================================================================
	* ====================3. Run sub-programs============================
	* ===================================================================

	foreach dofile of local dofiles {

		noi dis as text _new "{p 4 4 2}{cmd:do-file:} "	in y  "  `dofile'" 	 ///
		`"{browse "`folder'`dofile'":{space 10}Open }"'" {p_end}"
		noi dis as text "{hline 96}"

		cap noi do2screen_display, variables(`variables')     ///
		find(`"`find'"') dofile(`dofile') range(`range')    ///
		lines(`lines') start(`start') end(`end') `previous' ///
		`labels' `varout' `lrep' `rrep' `dblq' `scalarname' ///
		`comments' `linenumbers'
	}

	/*================================================================
	3.2 Display option
	=================================================================*/


	* Close text file
	if ("`text'" != "") {
		log close `textfile'
		noi disp as text `"note: results saved to `text'"'
	}

	if ("`folder'" != "") cd "`cdir'"

	if ("`timer'" != "") noi timer list

} // end of qui
end

* ==============================================================================
* =========================do2screen_display program============================
* ==============================================================================

program define do2screen_display, rclass

syntax [anything]								///
[if] [in],										///
[															///
variables(string)							///
find(string)									///
range(numlist)	lrep(string)	///
lines(numlist)	rrep(string)	///
start(numlist)	dblq(string)	///
end(numlist)									///
dofile(string)								///
labels	SCALARname(string)		///
noprevious	comments				  ///
varout(string) nolinenumbers  ///
]

qui {

	/*====================================================================
	1: Initial conditions
	====================================================================*/

	*--------------------1.1: Load Information of the do-file

	tempfile h
	filefilter "`dofile'" `h', from(\n) to(\n\BS\BS\RQ\RQ\BS\BS\BS) replace

	import delimited using `h', clear  ///
	delimiters("thisisadelimiter,itshouldworkfine", asstring)
	rename v1 oricode
	replace oricode = subinstr(oricode, `"\\''\\\"', "", .)
	gen oriline = _n
	gen selection = .

	gen precode = oricode

	*** comments long comments
	timer on 2
	if ("`comments'" == "") {
		tempvar o c open close open1 close1

		gen `o'        = 1 if (regexm(oricode, `"/\*"'))
		gen `c'        = 1 if (regexm(oricode, `"\*/"'))

		gen `open'     = sum(`o') if `o' == 1
		gen `close'    = sum(`c') if `c' == 1
		clonevar `open1'  = `open'
		clonevar `close1' = `close'

		replace `open1'  = `open1'[_n-1]  if `open1' ==.
		replace `close1' = `close1'[_n-1] if `close1' ==.
		replace `close'  = `close' - 1    if `close1' > `open1'

		count if regexm(precode, `"/\*[^(/\*).]*\*/"')
		while r(N)>0 {
			replace precode = regexr(precode, `"/\*[^(/\*).]*\*/"', " ")
			count if regexm(precode, `"/\*[^(/\*).]*\*/"')
		}

		levelsof `open' if (`open' != `close'), local(sections)
		foreach section of local sections {
			sum oriline if (`open' == `section' | `close' == `section'), meanonly
			replace precode = "" if inrange(oriline, r(min),r(max) )
		}
	}
	timer off 2

	// fix precode
	replace precode = ltrim(rtrim(itrim(precode)))
	replace precode = subinstr(precode, "`=char(9)'", " ",.)
	if ("`lrep'" == "") local lrep "LlLl"
	if ("`rrep'" == "") local rrep "RrRr"
	if ("`dblq'" == "") local dblq "DQDQ"

	replace precode = subinstr(precode, char(96), "`lrep'",.)  // replace `
	replace precode = subinstr(precode, char(39), "`rrep'",.)  // replace '
	replace precode = subinstr(precode, char(34), "`dblq'",.)  // replace '

	// Delimiter
	timer on 3
	gen line = .
	gen code = ""
	sum oriline, meanonly
	local maxline = r(max)

	local i = 0
	local u = 1
	local delimit =0
	qui while (`i' < `maxline') {
		local ++i
		local line = precode[`i']
		if regexm(`"`macval(line)'"', `"^[ ]*$"')  {
			replace line = `u' in `u'
			replace code = "" in `u'
			local ++u
			continue
		}
		if regexm(`"`macval(line)'"', "#[ ]?delimit[ ]?;") {
			local delimit = 1
			continue
		}
		if regexm(`"`macval(line)'"', "#[ ]?delimit[ ]?cr") {
			local delimit = 0
			continue
		}
		if (`delimit' == 0) {
			replace line = `u' in `u'
			replace code = `"`macval(line)'"' in `u'
			local ++u
		}
		else {
			if regexm(`"`macval(line)'"', ";") {
				tokenize `"`macval(line)'"', parse(;)
				local s = 1
				while (`"``s''"' != "") {
					if  (`"``s''"' != ";" & `"``=`s'+1''"' != "") {
						replace line = `u' in `u'
						if (`s' == 1) replace code = `"`trailcode' ``s''"' in `u'
						else replace code = `"``s''"' in `u'
						local ++u
					}
					local ++s
				}
				// when the last part of code is not ;
				if (`"``--s''"' != ";") local trailcode `"``s''"'
				else                  local trailcode ""
			} // end of ; in line

			else {
				local trailcode "`trailcode'"
				while !regexm(`"`macval(line)'"', ";") & `i' < `maxline' {
					local trailcode `"`trailcode' `macval(line)'"'
					local ++i
					local line = precode[`i']
				}
				local --i
			} // end of lines without ;

		} // end of delimit end of lines when ; is there

	}  // end of delimit
	timer off 3

	replace code = subinstr(code, ";", "",.)
	clonevar origcode = code  // anchor
	drop if line == .
	compress

	/*====================================================================
	2: Algorithm for Variables condition
	====================================================================*/

	if ("`variables'" != "" ) { // Condition if the user wants to see specific variable

		local crlf "`=char(10)'`=char(13)'"

		timer on 4
		foreach var of local variables { // analysis for each variable desired

			replace code = origcode  // use anchor for new variables
			replace selection = .
			*--------------------2.1: Initial conditions of algorithm
			tempname D
			matrix `D'=J(1,1000,1)
			local i=1

			local mainvar "`var'"
			local doughter`var' "nope"	  // e.g., ipcf is doughter of itf, which is `var'
			local prevars`var' "`var'"


			*--------------------2.2:
			local stay = 1

			** create variable to check that no variable is checked more than once
			tempvar content
			gen `content' = ""
			local cc = 0

			qui while (`stay' == 1) {

				if ("`previous'" == "noprevious") local stay = 0
				local j=`D'[1,`i']
				if (`"`: word `j' of `prevars`var'''"' != `""') {

					local var : word `j' of `prevars`var''
					if ("`var'" == "`doughter`var''") {
						disp in red "variable `var' presents circular creation [i.e, x = f(X)]"
						matrix `D'[1,`i']=`D'[1,`i']+1
						continue
					}

					* Exclusion of `varout' in analysis
					if ("`var'" == "`varout'") {
						matrix `D'[1,`i']=`D'[1,`i']+1
						continue
					}

					** Identify whether one variable has been already checked
					count if `content' == "`var'"
					if r(N) == 0 {
						local ++cc
						replace `content' = "`var'" in `cc'
					}
					else {
						* disp in w "variable `var' already checked. "
						matrix `D'[1,`i']=`D'[1,`i']+1
						continue
					}


					** exclusion
					**** Code to identify previous variables
					local way1 = 0
					local way2 = 0
					local fline ""

					tempvar a
					gen `a' = ""
					* gen, egen, replace
					replace `a' = regexs(2) if ///
					regexm(code, `"^(.*[:]?[ ]*[a-z]+ `var'[ ]*=)([ a-z0-9\.\("]+.*)$"')

					* rename
					replace `a' = regexs(1) if ///
					regexm(code, `"[ ]*ren[ame]*[ ]+\(?([a-zA-Z_]*[a-zA-Z0-9_ ]*)\)?[ ]+\(?([a-zA-Z_]*[a-zA-Z0-9_ ]*`var'[a-zA-Z_]*[a-zA-Z0-9_ ]*)\)?"')

					* encode, destring, and similar commands
					replace `a' = regexs(1) if ///
					regexm(code, `"(^.*),.*[a-z]+\(([a-zA-Z0-9_ ]*[ ]+`var'|[ ]*`var')([ ]*\)|[ ]+[a-zA-Z0-9_ ]*\))"')

					replace `a' = "" if regexm(code, `"^[ ]*(egen|gen).*,.*`var'"')

					sum line if `a' != `""', meanonly
					if r(N) != 0 {
						levelsof line if (`a' != `""'), local(tlines)
						foreach tline of local tlines {
							* noi disp in red `a'[`tline']
							local fline "`fline' `: disp `a'[`tline']'"
						}
					}
					if (`"`fline'"' != `""') local way1 = 1

					** In case variable is not created
					if (`way1' == 0 & `way2' == 0) {
						matrix `D'[1,`i']=`D'[1,`i']+1
						local var "`doughter`var''"
						continue
					}

					*** Code for after the variable is created****
					if ("`mainvar'" == "`var'") {
						sum line if `a' != `""', meanonly
						local bfrlines = r(max)
						do2screen_aftervar `var' , `labels'
					}
					else do2screen_aftervar `var' , `labels' maxline(`bfrlines')
					replace selection = 1 if (`a' != `""' & line <= `bfrlines')

					**************************
					** creation of variables
					*************************

					local tofind = `"`fline'"'

					lstrfun tofind, regexr(`"`tofind'"', `"[a-zA-Z]+\("', "")	// functions opening
					foreach symb in ")" "+" "-" "/" "*" ">=" "<=" ">" "<" "==" "!=" ///
					"~=" " if " " . " " ." "|" "(" "&" "#" "%" "^"  {
						local tofind: subinstr local tofind "`symb'" "  ", all  // functions closing
					}
					lstrfun tofind, regexr(`"`tofind'"', `" \[[ ]*[a-z]+[ ]*=[ ]*[a-zA-Z0-9]+[ ]*\]"', "")	// weigths
					lstrfun tofind, regexr(`"`tofind'"', `"^.*="', "")			// everything before equal
					lstrfun tofind, regexr(`"`tofind'"', `",.*"', "")			// everything after comma

					* number with decimals
					local b ""
					foreach x of local tofind {
						if !regexm(`"`x'"', `"[0-9]+\.[0-9]+"')  local b "`b' `x'"
					}
					local tofind `"`b'"'

					* Regular Numbers
					local c ""
					foreach x of local tofind {
						if !regexm(`"`x'"', `"^[0-9]+"')  local c "`c' `x'"
					}
					local tofind `"`c'"'

					local tofind = ltrim(rtrim(itrim(`"`tofind'"')))
					local tofind: list uniq tofind


					* noi disp in g "prevar of `var': " in y `"`tofind'"'

					if (`"`tofind'"' != `""') {

						local eqvars = 0
						local d ""
						foreach nvar of local tofind {
							if ("`nvar'" != "`var'") local d "`d' `nvar'"
							else local eqvars = 1
						}
						local tofind `"`d'"'

						local tofind = ltrim(rtrim(itrim(`"`tofind'"')))  // just in case
						local tofind: list uniq tofind  // just in case



						* if (`eqvars' == 0) {
						if (`"`tofind'"' != `""') {
							local prevars`var' "`tofind'"
							foreach nvar of local tofind {
								local doughter`nvar' "`var'"
							}
							* local oldvar "`var'"
							local ++i
						}
						else {
							matrix `D'[1,`i']=`D'[1,`i']+1
							local var "`doughter`var''"
						}
					}
					else {
						matrix `D'[1,`i']=`D'[1,`i']+1
						local var "`doughter`var''"
					}
				}
				else {
					matrix `D'[1,`i']=1
					local i=`i'-1
					if (`i'==0) continue, break
					matrix `D'[1,`i']=`D'[1,`i']+1
					local var "`doughter`var''"
				}

			} // end of while stay == 1

			local crlf "`=char(10)'`=char(13)'"
			replace code = subinstr(code, "`lrep'", char(96),.)  // replace back `
			replace code = subinstr(code, "`rrep'", char(39),.)  // replace back '
			replace code = subinstr(code, "`dblq'", char(34),.)  // replace "

			replace code = subinstr(code, "`=char(96)'", "`=char(92)'`=char(96)'",.)
			scalar s_varcode = ""
			levelsof line if selection == 1, local(lines)

			noi disp as text _new "Line   {c |}" _col(20) "{cmd: Writing code for:} {result: `mainvar'}"
			noi disp as text "{hline 7}{c +}{hline 90}"
			local linenumber ""
			foreach line of local lines {
				if ("`linenumbers'" == "") {
					local space: disp _dup(`=6-length("`line'")') " "
					local linenumber "`space'`line': "
				}
				local lcode: disp code[`line']
				scalar s_varcode = s_varcode + `"`crlf'`linenumber'`lcode'"'
				* noi disp in g "`space'`line':" in y " `lcode'"
				noi disp in g `"`linenumber'"' in y `" `lcode'"'
			}

			* noi disp in y s_varcode
			* noi tabdisp line if `check' == 1, cell(code)
			noi disp as text  _col(60) "{hline 10}" " (end of analysis of `mainvar')" _newline

		} // End of variables loop
		timer off 4
	} 	// End of variables conditions


	/* -----------------------------------
	If 'find' option is selected
	-----------------------------------*/

	if ( `"`find'"' != `""' ) { // lookfor whatever the user needs to see
		replace code = subinstr(code, "`=char(96)'", "`=char(92)'`=char(96)'",.)
		local t = 0
		foreach tofind of local find { // analysis for each variable desired
			local ++t
			replace selection = .

			* Display title and horizontal lines
			noi di as text _new  "Line {c |}		{cmd: Writing code for:}  {result: `tofind'}"
			noi di as text "{hline 5}{c +}{hline 90}"

			replace selection = -1 if  strpos(code,`"`tofind'"')!=0
			count if selection == -1
			if (r(N) >= 1) {
				levelsof line if selection == -1, local(nlines)
				local section = 0
				foreach line of local nlines {		// lines where tofind was found

					scalar `scalarname' = ""
					local ++section		// number of sections for the same finding
					foreach i of numlist 0/`lines' {

						local space: disp _dup(`=4-length("`=`line'+`i''")') " "
						local lcode: disp code[`=`line'+`i'']
						scalar `scalarname' = `scalarname' + `"`crlf'`space'`=`line'+`i'': `lcode'"'

					}

					noi disp in y `scalarname'
					noi di as text  _column(35)  "{hline 10}" ///
					" (end of section `section' for `tofind') " "{hline 10}" _newline

				}  // end of loop for line with foreach

			}  // end of of condition when something found.
			else {
				noi disp in red "nothing found for " in y " `tofind'"
			}
			noi di as text  _column(60)  "{hline 10}" " (end of analysis of `tofind')" _newline
		} // End of tofind loop
	} // end of find condition


	/* -----------------------------------
	If 'range' option is selected
	-----------------------------------*/
	if ( "`range'" != "" ) { // look for whatever the user needs to see

		* Display title and horizontal lines
		noi di as text _new  "Line {c |}		{cmd: Writing code between lines:}  {result: `start' & `end'}"
		noi di as text "{hline 5}{c +}{hline 90}"

		local crlf "`=char(10)'`=char(13)'"
		replace code = subinstr(code, "`=char(96)'", "`=char(92)'`=char(96)'",.)
		scalar `scalarname' = ""

		foreach line of numlist `start'/`end' {
			local space: disp _dup(`=4-length("`line'")') " "
			local lcode: disp code[`line']
			scalar `scalarname' = `scalarname' + `"`crlf'`space'`line': `lcode'"'
		}

		noi disp in y `scalarname'
		noi di as text  _column(45)  "{hline 10}" " (end of analysis of lines between `start' & `end')" _newline
	} // end of range condition

}
end

/*====================================================================
4: identification of code after creation
====================================================================*/

program do2screen_aftervar, rclass

syntax anything(name=var), [labels maxline(numlist)]

if ("`maxline'" == "") local maxline = _N

qui {


	* drop
	cap replace selection = 1 if (regexm(code, `"^[ ]*drop[ ]+[a-zA-Z0-9_ ]*`var'"')) ///
	& line < `maxline'

	*----------------------4.2: Display Labels
	if (!missing("`labels'")) {
		cap replace selection = 1 if (regexm(code, ///
		`"^[ ]*l(a|ab|abe|abel)[ ]+va(r|ri|ria|riab|riabl|riable)[ ]+`var'[ ]+.*"')) ///
		& line < `maxline'

		cap replace selection = 1 if (regexm(code, ///
		`"^[ ]*l(a|ab|abe|abel)[ ]+val(u|ue|ues)[ ]+.*`var'"')) ///
		& line < `maxline'
	}

	*----------------------4.3: Foreach loops

	cap replace selection = 2 ///
	if (regexm(code, `"^[ ]*foreach[ ]+[a-zA-Z0-9_]+[ ]+(in|of)[ ]+.*`var'.*{$"')) ///
	& line < `maxline'

	count if selection == 2
	if (r(N) >= 1) {
		levelsof line if selection == 2, local(nlines)
		foreach line of local nlines {
			local inloop = 0
			local i = 0
			while (`inloop' == 0) {
				local ++i
				local loopline: disp code[`=`line'+`i'']
				if (regexm(`"`macval(loopline)'"',`"}"') == 1) local inloop = 1
				replace selection = 1 in `=`line'+`i''
			} // end of while
		} // end of loop for line with foreach
	}
	replace selection = 1 if selection == 2

}
end

exit

><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><

* =============================================================================
* ============================History of the file==============================
* =============================================================================
*! Version 2.4    <20nov2017>
*! Version 2.3    <23sep2017>
*! Version 2.2    <15aug2017>
*! Version 2.1    <26Apr2016>
*! Version 2.0    <29Dec2015>
*! Version 1.1    <05Mar2015>
*! Version 0.0    <06Feb2015>


*---------- NOTES--------------------
dom_2004_enft_v01_m_v03_a_sedlac_02
bol_2006_eh_v01_m_v02_a_sedlac_02

local using dom_2004_enft_v01_m_v03_a_sedlac_02.do
do2screen using `using', var(casa)


do2screen using test.do, var(edlev)
do2screen using test.do, var(secondary)


do2screen using test2.do, var(ho7)
do2screen using test2.do, var(ho7a)



tempvar a
gen `a' = regexs(2) if regexm(code, `"^(.*[:]?[ ]*[a-z]+ `var'[ ]*=)([ a-z0-9\.\("]+.*)$"')

sum line if `a' != `""', meanonly
if r(N) != 0 {
	if ("`mainvar'" == "`var'") local bfrlines = r(max)
	levelsof line if (`a' != `""'), local(tlines)
	foreach tline of local tlines {
		* noi disp in red `a'[`tline']
		local fline "`fline' `: disp `a'[`tline']'"
	}
}
if (`"`fline'"' != `""') local way1 = 1
else {		// in case of other way to generate variables
	tempvar b
	gen `b' = regexm(code, `"^.*,.*[a-z]+\(([a-zA-Z0-9_ ]*[ ]+`var'|[ ]*`var')([ ]*\)|[ ]+[a-zA-Z0-9_ ]*\))"')
	sum line if `b' == 1, meanonly
	if r(N) != 0 {
		if ("`mainvar'" == "`var'") local bfrlines = r(max)
		local fline: disp code[r(min)]
		local way2 = 1
	}
}






drop _all
set obs 500000
tempname myfile
local file "`dofile'"

gen oriline = .
gen strL oricode = ""



file open `myfile' using `file'  , read
file read `myfile' oriline
local i = 1

timer on 1
qui while r(eof)==0 {
	replace oriline = `i' in `i'
	replace oricode = `"`macval(oriline)'"' in `i'
	file read `myfile' oriline
	local ++i
}
timer off 1





*-------------------4.1: Comments;

* A. Beginning with Opening and closing comments in the same line;
cap replace selection = 3 if (regexm(code, `"^[ ]*(/\*.*\*/)(.*)"');

* B. Begin comment in one line and closing in other line;
replace selection = 4 if regexm(code, `"^(.*)/\*"');

count if selection  == 4;
if (r(N) > 1 ) {;
	levelsof line if selection == 4, local(lines);
	foreach line of local lines {;
		local inloop = 0;
		local i = -1 ;
		while (`inloop' == 0) {;
			local ++i;
			if regexm(code, `"^(.*)/\*"') in `=`line'+`i''
			local partA = regexs(1);
			if regexm(code, `"^(.*)(\*/)(.*)$"') in `=`line'+`i''
			local partB = regexs(3);
			if regexm(code, `"\*/"') in `=`line'+`i'' local inloop = 1;
		};

		if regexm(`"`partA' `partB'"', "^.* `var' .*") {;
			replace code = `"`partA' `partB'"' in `line';
			replace selection = 1 in `line';
			if (`i'!= 0) replace code = "" in `=`line'+1'/`=`line'+`i'';
		};
		else replace code = "" in `line'/`=`line'+`i'';
	} ; // end of line loop;
} ; // end of ;
replace selection = . if selection == 4;

* C. Identify * comments;
replace code = "" if regexm(code, `"^[ ]*\*"');

* D. Identify comments at the end of the line //;
replace code = regexs(1) if regexm(code, `"^(.*)(//.*)"');

* E. comment /*  */ after and in the middle of the line of code. Ex. gen var = var2 /* gen var1 */;

count if regexm(code, `".*/\*.*\*/.*"');
while r(N) > 0 {;
	replace code = regexs(1) + " " + regexs(3)  if regexm(code, `"^(.*)(/\*.*\*/)(.*)"');
	count if regexm(code, `".*/\*.*\*/.*"');
};

replace code = ltrim(rtrim(itrim(code)));

*----------------------4.2.1:  General comments;

cap replace selection = 1 `in' if (regexm(code,
`"^.*(:)?[ ]*(egen|g|g(e|en|ene|ener|enera|enerat|enerate)|replace|loc|loc(a|al))[ ]*(byte|int|long|float|double)?[ ]+`var'[ ]?=[ ]?"'));

cap replace selection = 1 `in'   if (regexm(code,
`"^[ ]*recode.*[ ]*(g|g(e|en|ene|ener|enera|enerat|enerate))\(([a-zA-Z0-9_ ]*[ ]+`var'|[ ]*`var')([ ]*\)|[ ]+[a-zA-Z0-9_ ]*\))"'));

cap replace selection = 1  `in'  if (regexm(code,
`"^[ ]*(en|(en|de(c|co|cod|code))).*[ ]*(g|g(e|en|ene|ener|enera|enerat|enerate))\([ ]*`var'[ ]*\)"'));

cap replace selection = 1  `in'  if (regexm(code,
`"^[ ]*(de|to)string(.*)(g|g(e|en|ene|ener|enera|enerat|enerate))\(([a-zA-Z0-9_ ]*[ ]+`var'|[ ]*`var')([ ]*\)|[ ]+[a-zA-Z0-9_ ]*\))"'));

cap replace selection = 1 `in'   if (regexm(code,
`"^[ ]*(de|to)string[ ]+([a-zA-Z0-9_ ]*[ ]+`var'|`var')([ ]*,|[ ]+[a-zA-Z0-9_ ]*,).*replace"'));

cap replace selection = 1 `in'   if (regexm(code,
`"^[ ]*re(n|na|nam|name)[ ]+[a-zA-Z0-9_]+[ ]+`var'[ ]*($|,.*)"'));

/*
cap replace selection = 1 `in'   if (regexm(code,
`"^[ ]*re(n|na|nam|name)[ ]+\(.*\)[ ]+\(([a-zA-Z0-9_ ]*[ ]+`var'|`var')([ ]*\)|[ ]+[a-zA-Z0-9_ ]*\))[ ]*($|,.*)"'));
*/
cap replace selection = 1 `in'   if (regexm(code,
`"^[ ]*re(n|na|nam|name)[ ]+[a-zA-Z_]+[a-zA-Z0-9_]*[ ]+`var'[ ]*($|,.*)"'));

cap replace selection = 1 `in'   if (regexm(code,
`"^[ ]*re(n|na|nam|name)[ ]+\(.*\)[ ]+\([a-zA-Z_]*[a-zA-Z0-9_ ]*`var'.*\)[ ]*($|,.*)"'));

cap replace selection = 1 `in'   if (regexm(code,
`"^[ ]*re(n|na|nam|name)[ ][a-zA-Z_]*[a-zA-Z0-9_ ]*`var'.*[ ]*,(u[per]*|l[ower]*|p[rope]*)"'));


cap replace selection = 2  if (regexm(code,
`"^[ ]*foreach[ ]+[a-zA-Z0-9_]+[ ]+(in|of (varlist|newlist|local|numlist))[ ]+([a-zA-Z0-9_ ]*[ ]+`var'|`var')([ ]*|[ ]+[a-zA-Z0-9_ ]*)"'));