| 181 | } |
| 182 | |
| 183 | std::string escape_for_turtle(const std::u32string& input) { |
| 184 | std::ostringstream escaped; |
| 185 | escaped << "\""; |
| 186 | |
| 187 | for (auto& c : input) { |
| 188 | switch (c) { |
| 189 | case '\\': |
| 190 | escaped << "\\\\"; |
| 191 | break; |
| 192 | case '\"': |
| 193 | escaped << "\\\""; |
| 194 | break; |
| 195 | case '\n': |
| 196 | escaped << "\\n"; |
| 197 | break; |
| 198 | case '\r': |
| 199 | escaped << "\\r"; |
| 200 | break; |
| 201 | case '\t': |
| 202 | escaped << "\\t"; |
| 203 | break; |
| 204 | default: |
| 205 | if (c < 0x20 || c > 0x7E) { |
| 206 | escaped << "\\u" |
| 207 | << std::hex << std::setw(4) << std::setfill('0') |
| 208 | << (c & 0xFFFF); |
| 209 | } else { |
| 210 | escaped.put(c); |
| 211 | } |
| 212 | break; |
| 213 | } |
| 214 | } |
| 215 | escaped << "\""; |
| 216 | return escaped.str(); |
| 217 | } |
| 218 | |
| 219 | template <typename Fn, typename... Ts> |
| 220 | std::string capture_output(Fn fn, Ts... ts) { |