summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2021-01-19 21:27:23 -0500
committerJune McEnroe <june@causal.agency>2021-01-19 21:27:23 -0500
commita3ee3ce9314d95f939c9bd39dd8b83becd4c7fc5 (patch)
tree686c43b9b0e2590bc0fc80d52fdad83e2663ae3d
parentDon't use a pager if reading standard input (diff)
downloadsrc-a3ee3ce9314d95f939c9bd39dd8b83becd4c7fc5.tar.gz
src-a3ee3ce9314d95f939c9bd39dd8b83becd4c7fc5.zip
Map tags to IDs using only [[:alnum:]-._]
-rw-r--r--bin/htagml.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/bin/htagml.c b/bin/htagml.c
index f6971de4..8b7255ab 100644
--- a/bin/htagml.c
+++ b/bin/htagml.c
@@ -14,6 +14,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <ctype.h>
 #include <err.h>
 #include <regex.h>
 #include <stdbool.h>
@@ -51,6 +52,16 @@ static size_t escape(bool esc, const char *ptr, size_t len) {
 	return len;
 }
 
+static void id(const char *tag) {
+	for (const char *ch = tag; *ch; ++ch) {
+		if (isalnum(*ch) || strchr("-._", *ch)) {
+			putchar(*ch);
+		} else {
+			putchar('_');
+		}
+	}
+}
+
 static char *hstrstr(const char *haystack, const char *needle) {
 	while (haystack) {
 		char *elem = strchr(haystack, '<');
@@ -152,7 +163,7 @@ int main(int argc, char *argv[]) {
 		if (index) {
 			if (!tag) continue;
 			printf("<li><a class=\"tag\" href=\"#");
-			escape(true, tag->tag, strlen(tag->tag));
+			id(tag->tag);
 			printf("\">");
 			escape(true, tag->tag, strlen(tag->tag));
 			printf("</a></li>\n");
@@ -181,9 +192,9 @@ int main(int argc, char *argv[]) {
 		}
 		escape(!pipe, buf, match - buf);
 		printf("<a class=\"tag\" id=\"");
-		escape(true, tag->tag, strlen(tag->tag));
+		id(tag->tag);
 		printf("\" href=\"#");
-		escape(true, tag->tag, strlen(tag->tag));
+		id(tag->tag);
 		printf("\">");
 		match += escape(!pipe, match, mlen);
 		printf("</a>");