/*-------------------------------------------------------------------------------
  strimplify.ado: convert umlauts and delete special characters in string

    Copyright (C) 2011-2012  Daniel Bela (daniel.bela@uni-bamberg.de)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

-------------------------------------------------------------------------------*/
*! strimplify.ado: convert umlauts and delete special characters in string
*! Daniel Bela (daniel.bela@lifbi.de), Leibniz Institute for Educational Trajectories (LIfBi), Germany
*! version 1.2 07 February 2012 - speedup in option -varmode-
*! version 1.1 21 April 2011 - initial release
program define strimplify, rclass
	version 11.1
	syntax anything(name=oldstring id="string" equalok everything) [, VARmode NUMbers NOREPLACE SUFFIX(string) NOCASE VERBOSE]

	// set suffix to <_simple> if empty
	if `"`suffix'"'=="" local suffix "_simple"

	// run procedure (variable mode)
	if `"`varmode'"'=="varmode" {
		if `"`verbose'"'=="verbose" noisily: display as text `"Info: running procedure in variable mode"'
		foreach var of local oldstring {
			confirm string variable `var'
			if `"`noreplace'"'=="noreplace" {
				confirm new variable `var'`suffix'
				quietly: generate `var'`suffix'=""
			}
			tempvar processed groups
			quietly: generate `processed'=0
			quietly: egen `groups'=group(`var'), missing
			summarize `groups', meanonly
			forvalues num=1/`r(max)' {
				preserve
				quietly: keep if `groups'==`num'
				local numstring=`var'
				restore
				if `"`macval(numstring)'"'!="" {
					proc , procoldstring(`"`macval(numstring)'"') `numbers' `nocase' `verbose'
					if `"`noreplace'"'!="noreplace" quietly: replace `var'=`"`r(procnewstring)'"' if `groups'==`num'
					else quietly: replace `var'`suffix'=`"`r(procnewstring)'"' if `groups'==`num'
					quietly: replace `processed'=1 if `groups'==`num'
				}
				else {
					if `"`noreplace'"'!="noreplace" quietly: replace `var'=`""' if `groups'==`num'
					else quietly: replace `var'`suffix'=`""' if `groups'==`num'
					quietly: replace `processed'=1 if `groups'==`num'
				}
			}
			assert `processed'==1
			drop `processed' `groups'
		}
	}

	// run procedure in normal mode
	else {
		if `"`verbose'"'=="verbose" noisily: display as text `"Info: running procedure in normal mode"'
		proc , procoldstring(`oldstring') `numbers' `nocase' `verbose'

		// return results
		return local newstring `r(procnewstring)'
		return local oldstring `r(procoldstring)'
		if `"`verbose'"'=="verbose" noisily: display as text `"Info: procedure complete. Changed string <`r(procoldstring)'> to <`r(procnewstring)'>."'
	}
end

program define proc, rclass
	syntax , procoldstring(string) [NUMBERS NOCASE VERBOSE]
	local procnewstring `"`macval(procoldstring)'"'

	// trim space characters
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: trimming space characters"'
	local procnewstring=trim(`"`macval(procnewstring)'"')

	// replace umlauts
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ä>"'
	local procnewstring: subinstr local procnewstring "ä" "ae", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ö>"'
	local procnewstring: subinstr local procnewstring "ö" "oe", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ü>"'
	local procnewstring: subinstr local procnewstring "ü" "ue", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <Ä>"'
	local procnewstring: subinstr local procnewstring "Ä" "ae", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <Ö>"'
	local procnewstring: subinstr local procnewstring "Ö" "oe", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <Ü>"'
	local procnewstring: subinstr local procnewstring "Ü" "ue", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ß>"'
	local procnewstring: subinstr local procnewstring "ß" "ss", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <à>"'
	local procnewstring: subinstr local procnewstring "à" "a", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <á>"'
	local procnewstring: subinstr local procnewstring "á" "a", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <â>"'
	local procnewstring: subinstr local procnewstring "â" "a", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ç>"'
	local procnewstring: subinstr local procnewstring "ç" "c", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <è>"'
	local procnewstring: subinstr local procnewstring "è" "e", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <é>"'
	local procnewstring: subinstr local procnewstring "é" "e", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ê>"'
	local procnewstring: subinstr local procnewstring "ê" "e", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ë>"'
	local procnewstring: subinstr local procnewstring "ë" "e", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ì>"'
	local procnewstring: subinstr local procnewstring "ì" "i", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <í>"'
	local procnewstring: subinstr local procnewstring "í" "i", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <î>"'
	local procnewstring: subinstr local procnewstring "î" "i", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ò>"'
	local procnewstring: subinstr local procnewstring "ò" "o", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ó>"'
	local procnewstring: subinstr local procnewstring "ó" "o", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ô>"'
	local procnewstring: subinstr local procnewstring "ô" "o", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ù>"'
	local procnewstring: subinstr local procnewstring "ù" "u", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <ú>"'
	local procnewstring: subinstr local procnewstring "ú" "u", all
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: replacing umlaut character <û>"'
	local procnewstring: subinstr local procnewstring "û" "u", all


	// delete special characters
	local specials `""&amp;" "," "#" "$" "." ":" ";" "-" "_" "(" ")" "/" "§" "&" "'" "`" "´" "+" ">" "<" "?" "!" "=" "[" "]" " " "	""'
	foreach char of local specials {
		if `"`verbose'"'=="verbose" noisily: display as text "Info: deleting special character <`macval(char)'>"
		local procnewstring: subinstr local procnewstring "`macval(char)'" "", all
	}

	// delete quotes
	if `"`verbose'"'=="verbose" noisily: display as text `"Info: deleting special character <">"'
	local procnewstring: subinstr local procnewstring `"""' "", all

	// delete numbers if requested
	if `"`numbers'"'=="numbers" {
		forvalues num=0/9 {
			if `"`verbose'"'=="verbose" noisily: display as text `"Info: deleting numeric character <`num'>"'
			local procnewstring: subinstr local procnewstring "`num'" "", all
		}
	}

	// convert to upper case if requested
	if `"`nocase'"'!="nocase" {
		local procnewstring=upper(`"`procnewstring'"')
	}

	// return results
	return local procnewstring `"`procnewstring'"'
	return local procoldstring `"`macval(procoldstring)'"'
end
// EOF