(src: string)
| 140 | // ---------- Ruby ---------- |
| 141 | |
| 142 | function stripRuby(src: string): string { |
| 143 | const out = src.split(''); |
| 144 | let i = 0; |
| 145 | const n = src.length; |
| 146 | let atLineStart = true; |
| 147 | |
| 148 | while (i < n) { |
| 149 | const c = src[i]!; |
| 150 | |
| 151 | // =begin / =end block comments must be at start of line (after optional whitespace) |
| 152 | if (atLineStart && c === '=' && src.startsWith('=begin', i)) { |
| 153 | const start = i; |
| 154 | // consume to matching =end at line start |
| 155 | i += '=begin'.length; |
| 156 | while (i < n) { |
| 157 | if (src[i] === '\n') { |
| 158 | // check next line for =end |
| 159 | let j = i + 1; |
| 160 | while (j < n && (src[j] === ' ' || src[j] === '\t')) j++; |
| 161 | if (src.startsWith('=end', j)) { |
| 162 | i = j + '=end'.length; |
| 163 | // consume rest of that line |
| 164 | while (i < n && src[i] !== '\n') i++; |
| 165 | break; |
| 166 | } |
| 167 | } |
| 168 | i++; |
| 169 | } |
| 170 | blankRange(out, start, i, src); |
| 171 | atLineStart = i > 0 && src[i - 1] === '\n'; |
| 172 | continue; |
| 173 | } |
| 174 | |
| 175 | // String literals |
| 176 | if (c === '"' || c === "'") { |
| 177 | const quote = c; |
| 178 | i++; |
| 179 | while (i < n && src[i] !== quote) { |
| 180 | if (src[i] === '\\' && i + 1 < n) { |
| 181 | i += 2; |
| 182 | continue; |
| 183 | } |
| 184 | if (src[i] === '\n') break; |
| 185 | i++; |
| 186 | } |
| 187 | if (i < n && src[i] === quote) i++; |
| 188 | atLineStart = false; |
| 189 | continue; |
| 190 | } |
| 191 | |
| 192 | // Line comment |
| 193 | if (c === '#') { |
| 194 | const start = i; |
| 195 | while (i < n && src[i] !== '\n') i++; |
| 196 | blankRange(out, start, i, src); |
| 197 | atLineStart = false; |
| 198 | continue; |
| 199 | } |
no test coverage detected