github.com/consensys/gnark-crypto@v0.14.0/utils/supsub.go (about) 1 package utils 2 3 import ( 4 "bytes" 5 "fmt" 6 ) 7 8 // The following is taken from https://github.com/lynn9388/supsub 9 // developed by lynn9388@gmail.com under Apache 2.0. 10 // It provides a mapping from normal unicode text to superscript 11 // and subscript. 12 13 var superscripts = map[rune]rune{ 14 // Superscripts - Superscripts and Subscripts 15 // https://www.unicode.org/charts/PDF/U2070.pdf 16 '\u0030': '\u2070', 17 '\u0069': '\u2071', 18 '\u0034': '\u2074', 19 '\u0035': '\u2075', 20 '\u0036': '\u2076', 21 '\u0037': '\u2077', 22 '\u0038': '\u2078', 23 '\u0039': '\u2079', 24 '\u002b': '\u207a', 25 '\u2212': '\u207b', 26 '\u003d': '\u207c', 27 '\u0028': '\u207d', 28 '\u0029': '\u207e', 29 '\u006e': '\u207f', 30 31 // Latin superscript modifier letters - Spacing Modifier Letters 32 // https://www.unicode.org/charts/PDF/U02B0.pdf 33 '\u0068': '\u02b0', 34 '\u0266': '\u02b1', 35 '\u006a': '\u02b2', 36 '\u0072': '\u02b3', 37 '\u0279': '\u02b4', 38 '\u027b': '\u02b5', 39 '\u0281': '\u02b6', 40 '\u0077': '\u02b7', 41 '\u0079': '\u02b8', 42 43 // Additions based on 1989 IPA - Spacing Modifier Letters 44 // https://www.unicode.org/charts/PDF/U02B0.pdf 45 '\u0263': '\u02e0', 46 '\u006c': '\u02e1', 47 '\u0073': '\u02e2', 48 '\u0078': '\u02e3', 49 '\u0295': '\u02e4', 50 51 // Latin superscript modifier letters - Phonetic Extensions 52 // https://www.unicode.org/charts/PDF/U1D00.pdf 53 '\u0041': '\u1d2c', 54 '\u00c6': '\u1d2d', 55 '\u0042': '\u1d2e', 56 '\u0044': '\u1d30', 57 '\u0045': '\u1d31', 58 '\u018e': '\u1d32', 59 '\u0047': '\u1d33', 60 '\u0048': '\u1d34', 61 '\u0049': '\u1d35', 62 '\u004a': '\u1d36', 63 '\u004b': '\u1d37', 64 '\u004c': '\u1d38', 65 '\u004d': '\u1d39', 66 '\u004e': '\u1d3a', 67 '\u004f': '\u1d3c', 68 '\u0222': '\u1d3d', 69 '\u0050': '\u1d3e', 70 '\u0052': '\u1d3f', 71 '\u0054': '\u1d40', 72 '\u0055': '\u1d41', 73 '\u0057': '\u1d42', 74 '\u0061': '\u1d43', // '\u0061'(a) '\u1d43'(ᵃ) '\u00aa'(ª) 75 '\u0250': '\u1d44', 76 '\u0251': '\u1d45', 77 '\u1d02': '\u1d46', 78 '\u0062': '\u1d47', 79 '\u0064': '\u1d48', 80 '\u0065': '\u1d49', 81 '\u0259': '\u1d4a', 82 '\u025b': '\u1d4b', 83 '\u1d08': '\u1d4c', 84 '\u0067': '\u1d4d', 85 '\u006b': '\u1d4f', 86 '\u006d': '\u1d50', 87 '\u014b': '\u1d51', 88 '\u006f': '\u1d52', // '\u006f'(o) '\u1d52'(ᵒ) '\u00ba'(º) 89 '\u0254': '\u1d53', 90 '\u1d16': '\u1d54', 91 '\u1d17': '\u1d55', 92 '\u0070': '\u1d56', 93 '\u0074': '\u1d57', 94 '\u0075': '\u1d58', 95 '\u1d1d': '\u1d59', 96 '\u026f': '\u1d5a', 97 '\u0076': '\u1d5b', 98 '\u1d25': '\u1d5c', 99 100 // Greek superscript modifier letters - Phonetic Extensions 101 // https://www.unicode.org/charts/PDF/U1D00.pdf 102 '\u03b2': '\u1d5d', 103 '\u03b3': '\u1d5e', 104 '\u03b4': '\u1d5f', 105 '\u03c6': '\u1d60', 106 '\u03c7': '\u1d61', 107 108 // Caucasian linguistics - Phonetic Extensions 109 // https://www.unicode.org/charts/PDF/U1D00.pdf 110 '\u043d': '\u1d78', 111 112 // Modifier letters - Phonetic Extensions Supplement 113 // https://www.unicode.org/charts/PDF/U1D80.pdf 114 '\u0252': '\u1d9b', 115 '\u0063': '\u1d9c', 116 '\u0255': '\u1d9d', 117 '\u00f0': '\u1d9e', 118 '\u025c': '\u1d9f', 119 '\u0066': '\u1da0', 120 '\u025f': '\u1da1', 121 '\u0261': '\u1da2', 122 '\u0265': '\u1da3', 123 '\u0268': '\u1da4', 124 '\u0269': '\u1da5', 125 '\u026a': '\u1da6', 126 '\u1d7b': '\u1da7', 127 '\u029d': '\u1da8', 128 '\u026d': '\u1da9', 129 '\u1d85': '\u1daa', 130 '\u029f': '\u1dab', 131 '\u0271': '\u1dac', 132 '\u0270': '\u1dad', 133 '\u0272': '\u1dae', 134 '\u0273': '\u1daf', 135 '\u0274': '\u1db0', 136 '\u0275': '\u1db1', 137 '\u0278': '\u1db2', 138 '\u0282': '\u1db3', 139 '\u0283': '\u1db4', 140 '\u01ab': '\u1db5', 141 '\u0289': '\u1db6', 142 '\u028a': '\u1db7', 143 '\u1d1c': '\u1db8', 144 '\u028b': '\u1db9', 145 '\u028c': '\u1dba', 146 '\u007a': '\u1dbb', 147 '\u0290': '\u1dbc', 148 '\u0291': '\u1dbd', 149 '\u0292': '\u1dbe', 150 '\u03b8': '\u1dbf', 151 152 // Latin-1 punctuation and symbols - C1 Controls and Latin-1 Supplement 153 // https://www.unicode.org/charts/PDF/U0080.pdf 154 //'\u0061': '\u00aa', // '\u0061'(a) '\u1d43'(ᵃ) '\u00aa'(ª) 155 '\u0032': '\u00b2', 156 '\u0033': '\u00b3', 157 '\u0031': '\u00b9', 158 //'\u006f': '\u00ba', // '\u006f'(o) '\u1d52'(ᵒ) '\u00ba'(º) 159 } 160 var subscripts = map[rune]rune{ 161 // Subscripts - Superscripts and Subscripts 162 // https://www.unicode.org/charts/PDF/U2070.pdf 163 '\u0030': '\u2080', 164 '\u0031': '\u2081', 165 '\u0032': '\u2082', 166 '\u0033': '\u2083', 167 '\u0034': '\u2084', 168 '\u0035': '\u2085', 169 '\u0036': '\u2086', 170 '\u0037': '\u2087', 171 '\u0038': '\u2088', 172 '\u0039': '\u2089', 173 '\u002b': '\u208a', 174 '\u2212': '\u208b', 175 '\u003d': '\u208c', 176 '\u0028': '\u208d', 177 '\u0029': '\u208e', 178 '\u0061': '\u2090', 179 '\u0065': '\u2091', 180 '\u006f': '\u2092', 181 '\u0078': '\u2093', 182 '\u0259': '\u2094', 183 184 // Subscripts for UPA - Superscripts and Subscripts 185 // https://www.unicode.org/charts/PDF/U2070.pdf 186 '\u0068': '\u2095', 187 '\u006b': '\u2096', 188 '\u006c': '\u2097', 189 '\u006d': '\u2098', 190 '\u006e': '\u2099', 191 '\u0070': '\u209a', 192 '\u0073': '\u209b', 193 '\u0074': '\u209c', 194 195 // Latin subscript modifier letters - Phonetic Extensions 196 // https://www.unicode.org/charts/PDF/U1D00.pdf 197 '\u0069': '\u1d62', 198 '\u0072': '\u1d63', 199 '\u0075': '\u1d64', 200 '\u0076': '\u1d65', 201 202 // Greek subscript modifier letters - Phonetic Extensions 203 // https://www.unicode.org/charts/PDF/U1D00.pdf 204 '\u03b2': '\u1d66', 205 '\u03b3': '\u1d67', 206 '\u03c1': '\u1d68', 207 '\u03c6': '\u1d69', 208 '\u03c7': '\u1d6a', 209 } 210 211 // sup converts a rune to superscript. It returns the superscript or the 212 // original rune and a error if there is no corresponding superscript. 213 func sup(r rune) (rune, error) { 214 s, ok := superscripts[r] 215 if !ok { 216 return r, fmt.Errorf("no corresponding superscript: %c", r) 217 } 218 return s, nil 219 } 220 221 // ToSuperscript converts a string to superscript to the utmost. It will use original 222 // rune if there has no corresponding superscript for a letter. 223 func ToSuperscript(s string) string { 224 buf := bytes.NewBuffer(make([]byte, 0, len(s)*3)) 225 for _, r := range s { 226 sup, _ := sup(r) 227 buf.WriteRune(sup) 228 } 229 return buf.String() 230 } 231 232 // sub converts a rune to subscript. It returns the subscript or the original 233 // rune and a error if there is no corresponding subscript. 234 func sub(r rune) (rune, error) { 235 s, ok := subscripts[r] 236 if !ok { 237 return r, fmt.Errorf("no corresponding subscript: %c", r) 238 } 239 return s, nil 240 } 241 242 // ToSubscript converts a string to subscript to the utmost. It will use original 243 // rune if there has no corresponding subscript for a letter. 244 func ToSubscript(s string) string { 245 buf := bytes.NewBuffer(make([]byte, 0, len(s)*3)) 246 for _, r := range s { 247 sub, _ := sub(r) 248 buf.WriteRune(sub) 249 } 250 return buf.String() 251 }