Mangle a string to be a unique string only made of alphanumeric characters and underscores.

This method is injective (two different inputs never produce the same output) and the returned string always respect the following rules:

  • Contains only US-ASCII letters, digits and underscores.
  • Never starts with a digit.
  • Never ends with an underscore.
  • Never contains two contiguous underscores.

Examples:

assert "42_is/The answer!".to_cmangle == "_52d2_is_47dThe_32danswer_33d"
assert "__".to_cmangle == "_95d_95d"
assert "__d".to_cmangle == "_95d_d"
assert "_d_".to_cmangle == "_d_95d"
assert "_42".to_cmangle == "_95d42"
assert "foo".to_cmangle == "foo"
assert "".to_cmangle == ""

Property definitions

core $ Text :: to_cmangle
	# Mangle a string to be a unique string only made of alphanumeric characters and underscores.
	#
	# This method is injective (two different inputs never produce the same
	# output) and the returned string always respect the following rules:
	#
	# * Contains only US-ASCII letters, digits and underscores.
	# * Never starts with a digit.
	# * Never ends with an underscore.
	# * Never contains two contiguous underscores.
	#
	# Examples:
	#
	# ~~~
	# assert "42_is/The answer!".to_cmangle == "_52d2_is_47dThe_32danswer_33d"
	# assert "__".to_cmangle == "_95d_95d"
	# assert "__d".to_cmangle == "_95d_d"
	# assert "_d_".to_cmangle == "_d_95d"
	# assert "_42".to_cmangle == "_95d42"
	# assert "foo".to_cmangle == "foo"
	# assert "".to_cmangle == ""
	# ~~~
	fun to_cmangle: String
	do
		if is_empty then return ""
		var res = new Buffer
		var underscore = false
		var start = 0
		var c = self[0]

		if c >= '0' and c <= '9' then
			res.add('_')
			res.append(c.code_point.to_s)
			res.add('d')
			start = 1
		end
		for i in [start..length[ do
			c = self[i]
			if (c >= 'a' and c <= 'z') or (c >='A' and c <= 'Z') then
				res.add(c)
				underscore = false
				continue
			end
			if underscore then
				res.append('_'.code_point.to_s)
				res.add('d')
			end
			if c >= '0' and c <= '9' then
				res.add(c)
				underscore = false
			else if c == '_' then
				res.add(c)
				underscore = true
			else
				res.add('_')
				res.append(c.code_point.to_s)
				res.add('d')
				underscore = false
			end
		end
		if underscore then
			res.append('_'.code_point.to_s)
			res.add('d')
		end
		return res.to_s
	end
lib/core/text/abstract_text.nit:598,2--662,4