* Create a valid slug for the anchor. * * @param line The line to create the slug for. * @return std::string The slug. */
| 183 | * @return std::string The slug. |
| 184 | */ |
| 185 | static std::string MakeAnchorSlug(const std::string &line) |
| 186 | { |
| 187 | std::string r = "#"; |
| 188 | uint state = 0; |
| 189 | for (char c : line) { |
| 190 | if (state == 0) { |
| 191 | /* State 0: Skip leading hashmarks and spaces. */ |
| 192 | if (c == '#') continue; |
| 193 | if (c == ' ') continue; |
| 194 | state = 1; |
| 195 | } |
| 196 | if (state == 2) { |
| 197 | /* State 2: Wait for a non-space/dash character. |
| 198 | * When found, output a dash and that character. */ |
| 199 | if (c == ' ' || c == '-') continue; |
| 200 | r += '-'; |
| 201 | state = 1; |
| 202 | } |
| 203 | if (state == 1) { |
| 204 | /* State 1: Normal text. |
| 205 | * Lowercase alphanumerics, |
| 206 | * spaces and dashes become dashes, |
| 207 | * everything else is removed. */ |
| 208 | if (isalnum(c)) { |
| 209 | r += tolower(c); |
| 210 | } else if (c == ' ' || c == '-') { |
| 211 | state = 2; |
| 212 | } |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | return r; |
| 217 | } |
| 218 | |
| 219 | /** |
| 220 | * Find any hyperlinks in a given line. |