core :: Text :: to_cmangle
This method is injective (two different inputs never produce the same output) and the returned string always respect the following rules:
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 == ""
# 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