Remove some unused markup functions

Mon, 23 Jun 2025 23:13:43 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Mon, 23 Jun 2025 23:13:43 -0500
changeset 43268
515f561d53bd
parent 43267
b304fee44acb
child 43269
1523eab3b5a0

Remove some unused markup functions

Testing Done:
Called in the turtles.

Reviewed at https://reviews.imfreedom.org/r/4029/

libpurple/purplemarkup.c file | annotate | diff | comparison | revisions
libpurple/purplemarkup.h file | annotate | diff | comparison | revisions
libpurple/tests/test_markup.c file | annotate | diff | comparison | revisions
--- a/libpurple/purplemarkup.c	Mon Jun 23 22:36:53 2025 -0500
+++ b/libpurple/purplemarkup.c	Mon Jun 23 23:13:43 2025 -0500
@@ -24,7 +24,7 @@
 
 #include "util.h"
 
-const char *
+static const char *
 purple_markup_unescape_entity(const char *text, int *length)
 {
 	const char *pln;
@@ -83,559 +83,6 @@
 	return pln;
 }
 
-struct purple_parse_tag {
-	char *src_tag;
-	char *dest_tag;
-	gboolean ignore;
-};
-
-/* NOTE: Do not put `do {} while(0)` around this macro (as this is the method
-         recommended in the GCC docs). It contains 'continue's that should
-         affect the while-loop in purple_markup_html_to_xhtml and doing the
-         above would break that.
-         Also, remember to put braces in constructs that require them for
-         multiple statements when using this macro. */
-#define ALLOW_TAG_ALT(x, y) if(!g_ascii_strncasecmp(c, "<" x " ", strlen("<" x " "))) { \
-						const char *o = c + strlen("<" x); \
-						const char *p = NULL, *q = NULL, *r = NULL; \
-						/* o = iterating over full tag \
-						 * p = > (end of tag) \
-						 * q = start of quoted bit \
-						 * r = < inside tag \
-						 */ \
-						GString *innards = g_string_new(""); \
-						while(o && *o) { \
-							if(!q && (*o == '\"' || *o == '\'') ) { \
-								q = o; \
-							} else if(q) { \
-								if(*o == *q) { /* end of quoted bit */ \
-									char *unescaped = g_strndup(q+1, o-q-1); \
-									char *escaped = g_markup_escape_text(unescaped, -1); \
-									g_string_append_printf(innards, "%c%s%c", *q, escaped, *q); \
-									g_free(unescaped); \
-									g_free(escaped); \
-									q = NULL; \
-								} else if(*c == '\\') { \
-									o++; \
-								} \
-							} else if(*o == '<') { \
-								r = o; \
-							} else if(*o == '>') { \
-								p = o; \
-								break; \
-							} else { \
-								innards = g_string_append_c(innards, *o); \
-							} \
-							o++; \
-						} \
-						if(p && !r) { /* got an end of tag and no other < earlier */\
-							if(*(p-1) != '/') { \
-								struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \
-								pt->src_tag = x; \
-								pt->dest_tag = y; \
-								tags = g_list_prepend(tags, pt); \
-							} \
-							if(xhtml) { \
-								xhtml = g_string_append(xhtml, "<" y); \
-								xhtml = g_string_append(xhtml, innards->str); \
-								xhtml = g_string_append_c(xhtml, '>'); \
-							} \
-							c = p + 1; \
-						} else { /* got end of tag with earlier < *or* didn't get anything */ \
-							if(xhtml) \
-								xhtml = g_string_append(xhtml, "&lt;"); \
-							if(plain) \
-								plain = g_string_append_c(plain, '<'); \
-							c++; \
-						} \
-						g_string_free(innards, TRUE); \
-						continue; \
-					} \
-					if(!g_ascii_strncasecmp(c, "<" x, strlen("<" x)) && \
-							(*(c+strlen("<" x)) == '>' || \
-							 !g_ascii_strncasecmp(c+strlen("<" x), "/>", 2))) { \
-						if(xhtml) \
-							xhtml = g_string_append(xhtml, "<" y); \
-						c += strlen("<" x); \
-						if(*c != '/') { \
-							struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1); \
-							pt->src_tag = x; \
-							pt->dest_tag = y; \
-							tags = g_list_prepend(tags, pt); \
-							if(xhtml) \
-								xhtml = g_string_append_c(xhtml, '>'); \
-						} else { \
-							if(xhtml) \
-								xhtml = g_string_append(xhtml, "/>");\
-						} \
-						c = strchr(c, '>') + 1; \
-						continue; \
-					}
-/* Don't forget to check the note above for ALLOW_TAG_ALT. */
-#define ALLOW_TAG(x) ALLOW_TAG_ALT(x, x)
-void
-purple_markup_html_to_xhtml(const char *html, char **xhtml_out,
-						  char **plain_out)
-{
-	GString *xhtml = NULL;
-	GString *plain = NULL;
-	GString *url = NULL;
-	GString *cdata = NULL;
-	GList *tags = NULL, *tag;
-	const char *c = html;
-	char quote = '\0';
-
-#define CHECK_QUOTE(ptr) if (*(ptr) == '\'' || *(ptr) == '\"') \
-			quote = *(ptr++); \
-		else \
-			quote = '\0';
-
-#define VALID_CHAR(ptr) (*(ptr) && *(ptr) != quote && (quote || (*(ptr) != ' ' && *(ptr) != '>')))
-
-	g_return_if_fail(xhtml_out != NULL || plain_out != NULL);
-
-	if(xhtml_out)
-		xhtml = g_string_new("");
-	if(plain_out)
-		plain = g_string_new("");
-
-	while(c && *c) {
-		if(*c == '<') {
-			if(*(c+1) == '/') { /* closing tag */
-				tag = tags;
-				while(tag) {
-					struct purple_parse_tag *pt = tag->data;
-					if(!g_ascii_strncasecmp((c+2), pt->src_tag, strlen(pt->src_tag)) && *(c+strlen(pt->src_tag)+2) == '>') {
-						c += strlen(pt->src_tag) + 3;
-						break;
-					}
-					tag = tag->next;
-				}
-				if(tag) {
-					while(tags) {
-						struct purple_parse_tag *pt = tags->data;
-						if(xhtml && !pt->ignore)
-							g_string_append_printf(xhtml, "</%s>", pt->dest_tag);
-						if(plain && purple_strequal(pt->src_tag, "a")) {
-							/* if this is a link, we have to add the url to the plaintext, too */
-							if (cdata && url &&
-									(!g_string_equal(cdata, url) && (g_ascii_strncasecmp(url->str, "mailto:", 7) != 0 ||
-									                                 g_utf8_collate(url->str + 7, cdata->str) != 0)))
-							{
-								char *unescaped = purple_unescape_html(url->str);
-								g_string_append_printf(plain, " <%s>",
-								                       g_strstrip(unescaped));
-								g_free(unescaped);
-							}
-							if (cdata) {
-								g_string_free(cdata, TRUE);
-								cdata = NULL;
-							}
-
-						}
-						if(tags == tag)
-							break;
-						tags = g_list_delete_link(tags, tags);
-						g_free(pt);
-					}
-					g_free(tag->data);
-					tags = g_list_delete_link(tags, tag);
-				} else {
-					/* a closing tag we weren't expecting...
-					 * we'll let it slide, if it's really a tag...if it's
-					 * just a </ we'll escape it properly */
-					const char *end = c+2;
-					while(*end && g_ascii_isalpha(*end))
-						end++;
-					if(*end == '>') {
-						c = end+1;
-					} else {
-						if(xhtml)
-							xhtml = g_string_append(xhtml, "&lt;");
-						if(plain)
-							plain = g_string_append_c(plain, '<');
-						c++;
-					}
-				}
-			} else { /* opening tag */
-				ALLOW_TAG("blockquote");
-				ALLOW_TAG("cite");
-				ALLOW_TAG("div");
-				ALLOW_TAG("em");
-				ALLOW_TAG("h1");
-				ALLOW_TAG("h2");
-				ALLOW_TAG("h3");
-				ALLOW_TAG("h4");
-				ALLOW_TAG("h5");
-				ALLOW_TAG("h6");
-				/* we only allow html to start the message */
-				if(c == html) {
-					ALLOW_TAG("html");
-				}
-				ALLOW_TAG_ALT("i", "em");
-				ALLOW_TAG_ALT("italic", "em");
-				ALLOW_TAG("li");
-				ALLOW_TAG("ol");
-				ALLOW_TAG("p");
-				ALLOW_TAG("pre");
-				ALLOW_TAG("q");
-				ALLOW_TAG("span");
-				ALLOW_TAG("ul");
-
-
-				/* we skip <HR> because it's not legal in XHTML-IM.  However,
-				 * we still want to send something sensible, so we put a
-				 * linebreak in its place. <BR> also needs special handling
-				 * because putting a </BR> to close it would just be dumb. */
-				if((!g_ascii_strncasecmp(c, "<br", 3)
-							|| !g_ascii_strncasecmp(c, "<hr", 3))
-						&& (*(c+3) == '>' ||
-							!g_ascii_strncasecmp(c+3, "/>", 2) ||
-							!g_ascii_strncasecmp(c+3, " />", 3))) {
-					c = strchr(c, '>') + 1;
-					if(xhtml)
-						xhtml = g_string_append(xhtml, "<br/>");
-					if(plain && *c != '\n')
-						plain = g_string_append_c(plain, '\n');
-					continue;
-				}
-				if(!g_ascii_strncasecmp(c, "<b>", 3) || !g_ascii_strncasecmp(c, "<bold>", strlen("<bold>")) || !g_ascii_strncasecmp(c, "<strong>", strlen("<strong>"))) {
-					struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
-					if (*(c+2) == '>')
-						pt->src_tag = "b";
-					else if (*(c+2) == 'o')
-						pt->src_tag = "bold";
-					else
-						pt->src_tag = "strong";
-					pt->dest_tag = "span";
-					tags = g_list_prepend(tags, pt);
-					c = strchr(c, '>') + 1;
-					if(xhtml)
-						xhtml = g_string_append(xhtml, "<span style='font-weight: bold;'>");
-					continue;
-				}
-				if(!g_ascii_strncasecmp(c, "<u>", 3) || !g_ascii_strncasecmp(c, "<underline>", strlen("<underline>"))) {
-					struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
-					pt->src_tag = *(c+2) == '>' ? "u" : "underline";
-					pt->dest_tag = "span";
-					tags = g_list_prepend(tags, pt);
-					c = strchr(c, '>') + 1;
-					if (xhtml)
-						xhtml = g_string_append(xhtml, "<span style='text-decoration: underline;'>");
-					continue;
-				}
-				if(!g_ascii_strncasecmp(c, "<s>", 3) || !g_ascii_strncasecmp(c, "<strike>", strlen("<strike>"))) {
-					struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
-					pt->src_tag = *(c+2) == '>' ? "s" : "strike";
-					pt->dest_tag = "span";
-					tags = g_list_prepend(tags, pt);
-					c = strchr(c, '>') + 1;
-					if(xhtml)
-						xhtml = g_string_append(xhtml, "<span style='text-decoration: line-through;'>");
-					continue;
-				}
-				if(!g_ascii_strncasecmp(c, "<sub>", 5)) {
-					struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
-					pt->src_tag = "sub";
-					pt->dest_tag = "span";
-					tags = g_list_prepend(tags, pt);
-					c = strchr(c, '>') + 1;
-					if(xhtml)
-						xhtml = g_string_append(xhtml, "<span style='vertical-align:sub;'>");
-					continue;
-				}
-				if(!g_ascii_strncasecmp(c, "<sup>", 5)) {
-					struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
-					pt->src_tag = "sup";
-					pt->dest_tag = "span";
-					tags = g_list_prepend(tags, pt);
-					c = strchr(c, '>') + 1;
-					if(xhtml)
-						xhtml = g_string_append(xhtml, "<span style='vertical-align:super;'>");
-					continue;
-				}
-				if (!g_ascii_strncasecmp(c, "<img", 4) && (*(c+4) == '>' || *(c+4) == ' ')) {
-					const char *p = c + 4;
-					GString *src = NULL, *alt = NULL;
-#define ESCAPE(from, to)        \
-		CHECK_QUOTE(from); \
-		while (VALID_CHAR(from)) { \
-			int len; \
-			if ((*from == '&') && (purple_markup_unescape_entity(from, &len) == NULL)) \
-				to = g_string_append(to, "&amp;"); \
-			else if (*from == '\'') \
-				to = g_string_append(to, "&apos;"); \
-			else \
-				to = g_string_append_c(to, *from); \
-			from++; \
-		}
-
-					while (*p && *p != '>') {
-						if (!g_ascii_strncasecmp(p, "src=", 4)) {
-							const char *q = p + 4;
-							if (src)
-								g_string_free(src, TRUE);
-							src = g_string_new("");
-							ESCAPE(q, src);
-							p = q;
-						} else if (!g_ascii_strncasecmp(p, "alt=", 4)) {
-							const char *q = p + 4;
-							if (alt)
-								g_string_free(alt, TRUE);
-							alt = g_string_new("");
-							ESCAPE(q, alt);
-							p = q;
-						} else {
-							p++;
-						}
-					}
-#undef ESCAPE
-					if ((c = strchr(p, '>')) != NULL)
-						c++;
-					else
-						c = p;
-					/* src and alt are required! */
-					if(src && xhtml)
-						g_string_append_printf(xhtml, "<img src='%s' alt='%s' />", g_strstrip(src->str), alt ? alt->str : "");
-					if(alt) {
-						if(plain) {
-							char *unescaped = purple_unescape_html(alt->str);
-							plain = g_string_append(plain, unescaped);
-							g_free(unescaped);
-						}
-						if(!src && xhtml) {
-							xhtml = g_string_append(xhtml, alt->str);
-						}
-						g_string_free(alt, TRUE);
-					}
-					g_string_free(src, TRUE);
-					continue;
-				}
-				if (!g_ascii_strncasecmp(c, "<a", 2) && (*(c+2) == '>' || *(c+2) == ' ')) {
-					const char *p = c + 2;
-					struct purple_parse_tag *pt;
-					while (*p && *p != '>') {
-						if (!g_ascii_strncasecmp(p, "href=", 5)) {
-							const char *q = p + 5;
-							if (url)
-								g_string_free(url, TRUE);
-							url = g_string_new("");
-							if (cdata)
-								g_string_free(cdata, TRUE);
-							cdata = g_string_new("");
-							CHECK_QUOTE(q);
-							while (VALID_CHAR(q)) {
-								int len;
-								if ((*q == '&') && (purple_markup_unescape_entity(q, &len) == NULL))
-									url = g_string_append(url, "&amp;");
-								else if (*q == '"')
-									url = g_string_append(url, "&quot;");
-								else
-									url = g_string_append_c(url, *q);
-								q++;
-							}
-							p = q;
-						} else {
-							p++;
-						}
-					}
-					if ((c = strchr(p, '>')) != NULL)
-						c++;
-					else
-						c = p;
-					pt = g_new0(struct purple_parse_tag, 1);
-					pt->src_tag = "a";
-					pt->dest_tag = "a";
-					tags = g_list_prepend(tags, pt);
-					if(xhtml)
-						g_string_append_printf(xhtml, "<a href=\"%s\">", url ? g_strstrip(url->str) : "");
-					continue;
-				}
-#define ESCAPE(from, to)        \
-		CHECK_QUOTE(from); \
-		while (VALID_CHAR(from)) { \
-			int len; \
-			if ((*from == '&') && (purple_markup_unescape_entity(from, &len) == NULL)) \
-				to = g_string_append(to, "&amp;"); \
-			else if (*from == '\'') \
-				to = g_string_append_c(to, '\"'); \
-			else \
-				to = g_string_append_c(to, *from); \
-			from++; \
-		}
-				if(!g_ascii_strncasecmp(c, "<font", 5) && (*(c+5) == '>' || *(c+5) == ' ')) {
-					const char *p = c + 5;
-					GString *style = g_string_new("");
-					struct purple_parse_tag *pt;
-					while (*p && *p != '>') {
-						if (!g_ascii_strncasecmp(p, "back=", 5)) {
-							const char *q = p + 5;
-							GString *color = g_string_new("");
-							ESCAPE(q, color);
-							g_string_append_printf(style, "background: %s; ", color->str);
-							g_string_free(color, TRUE);
-							p = q;
-						} else if (!g_ascii_strncasecmp(p, "color=", 6)) {
-							const char *q = p + 6;
-							GString *color = g_string_new("");
-							ESCAPE(q, color);
-							g_string_append_printf(style, "color: %s; ", color->str);
-							g_string_free(color, TRUE);
-							p = q;
-						} else if (!g_ascii_strncasecmp(p, "face=", 5)) {
-							const char *q = p + 5;
-							GString *face = g_string_new("");
-							ESCAPE(q, face);
-							g_string_append_printf(style, "font-family: %s; ", g_strstrip(face->str));
-							g_string_free(face, TRUE);
-							p = q;
-						} else if (!g_ascii_strncasecmp(p, "size=", 5)) {
-							const char *q = p + 5;
-							int sz;
-							const char *size = "medium";
-							CHECK_QUOTE(q);
-							sz = atoi(q);
-							switch (sz)
-							{
-							case 1:
-							  size = "xx-small";
-							  break;
-							case 2:
-							  size = "small";
-							  break;
-							case 3:
-							  size = "medium";
-							  break;
-							case 4:
-							  size = "large";
-							  break;
-							case 5:
-							  size = "x-large";
-							  break;
-							case 6:
-							case 7:
-							  size = "xx-large";
-							  break;
-							default:
-							  break;
-							}
-							g_string_append_printf(style, "font-size: %s; ", size);
-							p = q;
-						} else {
-							p++;
-						}
-					}
-					if ((c = strchr(p, '>')) != NULL)
-						c++;
-					else
-						c = p;
-					pt = g_new0(struct purple_parse_tag, 1);
-					pt->src_tag = "font";
-					pt->dest_tag = "span";
-					tags = g_list_prepend(tags, pt);
-					if(style->len && xhtml)
-						g_string_append_printf(xhtml, "<span style='%s'>", g_strstrip(style->str));
-					else
-						pt->ignore = TRUE;
-					g_string_free(style, TRUE);
-					continue;
-				}
-#undef ESCAPE
-				if (!g_ascii_strncasecmp(c, "<body ", 6)) {
-					const char *p = c + 6;
-					gboolean did_something = FALSE;
-					while (*p && *p != '>') {
-						if (!g_ascii_strncasecmp(p, "bgcolor=", 8)) {
-							const char *q = p + 8;
-							struct purple_parse_tag *pt = g_new0(struct purple_parse_tag, 1);
-							GString *color = g_string_new("");
-							CHECK_QUOTE(q);
-							while (VALID_CHAR(q)) {
-								color = g_string_append_c(color, *q);
-								q++;
-							}
-							if (xhtml)
-								g_string_append_printf(xhtml, "<span style='background: %s;'>", g_strstrip(color->str));
-							g_string_free(color, TRUE);
-							if ((c = strchr(p, '>')) != NULL)
-								c++;
-							else
-								c = p;
-							pt->src_tag = "body";
-							pt->dest_tag = "span";
-							tags = g_list_prepend(tags, pt);
-							did_something = TRUE;
-							break;
-						}
-						p++;
-					}
-					if (did_something) continue;
-				}
-				/* this has to come after the special case for bgcolor */
-				ALLOW_TAG("body");
-				if(!g_ascii_strncasecmp(c, "<!--", strlen("<!--"))) {
-					char *p = strstr(c + strlen("<!--"), "-->");
-					if(p) {
-						if(xhtml)
-							xhtml = g_string_append(xhtml, "<!--");
-						c += strlen("<!--");
-						continue;
-					}
-				}
-
-				if(xhtml)
-					xhtml = g_string_append(xhtml, "&lt;");
-				if(plain)
-					plain = g_string_append_c(plain, '<');
-				c++;
-			}
-		} else if(*c == '&') {
-			char buf[7];
-			const char *pln;
-			int len;
-
-			if ((pln = purple_markup_unescape_entity(c, &len)) == NULL) {
-				len = 1;
-				g_snprintf(buf, sizeof(buf), "%c", *c);
-				pln = buf;
-			}
-			if(xhtml)
-				xhtml = g_string_append_len(xhtml, c, len);
-			if(plain)
-				plain = g_string_append(plain, pln);
-			if(cdata)
-				cdata = g_string_append_len(cdata, c, len);
-			c += len;
-		} else {
-			if(xhtml)
-				xhtml = g_string_append_c(xhtml, *c);
-			if(plain)
-				plain = g_string_append_c(plain, *c);
-			if(cdata)
-				cdata = g_string_append_c(cdata, *c);
-			c++;
-		}
-	}
-	if(xhtml) {
-		for (tag = tags; tag ; tag = tag->next) {
-			struct purple_parse_tag *pt = tag->data;
-			if(!pt->ignore)
-				g_string_append_printf(xhtml, "</%s>", pt->dest_tag);
-		}
-	}
-	g_clear_list(&tags, g_free);
-	if(xhtml_out)
-		*xhtml_out = g_string_free_and_steal(xhtml);
-	if(plain_out)
-		*plain_out = g_string_free_and_steal(plain);
-	if(url)
-		g_string_free(url, TRUE);
-	if (cdata)
-		g_string_free(cdata, TRUE);
-#undef CHECK_QUOTE
-#undef VALID_CHAR
-}
-
 /* The following are probably reasonable changes:
  * - \n should be converted to a normal space
  * - in addition to <br>, <p> and <div> etc. should also be converted into \n
@@ -1126,126 +573,3 @@
 
 	return g_string_free_and_steal(ret);
 }
-
-char *
-purple_markup_slice(const char *str, guint x, guint y)
-{
-	GString *ret;
-	GQueue *q;
-	guint z = 0;
-	gboolean appended = FALSE;
-	gunichar c;
-	char *tag;
-
-	g_return_val_if_fail(str != NULL, NULL);
-	g_return_val_if_fail(x <= y, NULL);
-
-	if (x == y)
-		return g_strdup("");
-
-	ret = g_string_new("");
-	q = g_queue_new();
-
-	while (*str && (z < y)) {
-		c = g_utf8_get_char(str);
-
-		if (c == '<') {
-			char *end = strchr(str, '>');
-
-			if (!end) {
-				g_string_free(ret, TRUE);
-				while ((tag = g_queue_pop_head(q)))
-					g_free(tag);
-				g_queue_free(q);
-				return NULL;
-			}
-
-			if (!g_ascii_strncasecmp(str, "<img ", 5)) {
-				z += strlen("[Image]");
-			} else if (!g_ascii_strncasecmp(str, "<br", 3)) {
-				z += 1;
-			} else if (!g_ascii_strncasecmp(str, "<hr>", 4)) {
-				z += strlen("\n---\n");
-			} else if (!g_ascii_strncasecmp(str, "</", 2)) {
-				/* pop stack */
-				char *tmp;
-
-				tmp = g_queue_pop_head(q);
-				g_free(tmp);
-				/* z += 0; */
-			} else {
-				/* push it unto the stack */
-				char *tmp;
-
-				tmp = g_strndup(str, end - str + 1);
-				g_queue_push_head(q, tmp);
-				/* z += 0; */
-			}
-
-			if (z >= x) {
-				g_string_append_len(ret, str, end - str + 1);
-			}
-
-			str = end;
-		} else if (c == '&') {
-			char *end = strchr(str, ';');
-			if (!end) {
-				g_string_free(ret, TRUE);
-				while ((tag = g_queue_pop_head(q)))
-					g_free(tag);
-				g_queue_free(q);
-
-				return NULL;
-			}
-
-			if (z >= x)
-				g_string_append_len(ret, str, end - str + 1);
-
-			z++;
-			str = end;
-		} else {
-			if (z == x && z > 0 && !appended) {
-				GList *l = q->tail;
-
-				while (l) {
-					tag = l->data;
-					g_string_append(ret, tag);
-					l = l->prev;
-				}
-				appended = TRUE;
-			}
-
-			if (z >= x)
-				g_string_append_unichar(ret, c);
-			z++;
-		}
-
-		str = g_utf8_next_char(str);
-	}
-
-	while ((tag = g_queue_pop_head(q))) {
-		char *name;
-
-		name = purple_markup_get_tag_name(tag);
-		g_string_append_printf(ret, "</%s>", name);
-		g_free(name);
-		g_free(tag);
-	}
-
-	g_queue_free(q);
-	return g_string_free_and_steal(ret);
-}
-
-char *
-purple_markup_get_tag_name(const char *tag)
-{
-	int i;
-	g_return_val_if_fail(tag != NULL, NULL);
-	g_return_val_if_fail(*tag == '<', NULL);
-
-	for (i = 1; tag[i]; i++)
-		if (tag[i] == '>' || tag[i] == ' ' || tag[i] == '/')
-			break;
-
-	return g_strndup(tag+1, i-1);
-}
--- a/libpurple/purplemarkup.h	Mon Jun 23 22:36:53 2025 -0500
+++ b/libpurple/purplemarkup.h	Mon Jun 23 23:13:43 2025 -0500
@@ -34,20 +34,6 @@
 G_BEGIN_DECLS
 
 /**
- * purple_markup_html_to_xhtml:
- * @html:       The HTML markup.
- * @dest_xhtml: The destination XHTML output.
- * @dest_plain: The destination plain-text output.
- *
- * Converts HTML markup to XHTML.
- *
- * Since: 2.0
- */
-PURPLE_AVAILABLE_IN_ALL
-void purple_markup_html_to_xhtml(const char *html, char **dest_xhtml,
-							   char **dest_plain);
-
-/**
  * purple_markup_strip_html:
  * @str: The string to strip HTML from.
  *
@@ -117,70 +103,6 @@
 PURPLE_AVAILABLE_IN_ALL
 char *purple_unescape_html(const char *html);
 
-/**
- * purple_markup_slice:
- * @str: The input NUL terminated, HTML, UTF-8 (or ASCII) string.
- * @x: The character offset into an unformatted version of str to begin at.
- * @y: The character offset (into an unformatted version of str) of one past
- *     the last character to include in the slice.
- *
- * Returns a newly allocated substring of the HTML UTF-8 string "str".
- * The markup is preserved such that the substring will have the same
- * formatting as original string, even though some tags may have been
- * opened before "x", or may close after "y". All open tags are closed
- * at the end of the returned string, in the proper order.
- *
- * Note that x and y are in character offsets, not byte offsets, and
- * are offsets into an unformatted version of str. Because of this,
- * this function may be sensitive to changes in GtkIMHtml and may break
- * when used with other UI's. libpurple users are encouraged to report and
- * work out any problems encountered.
- *
- * Returns: The HTML slice of string, with all formatting retained.
- *
- * Since: 2.0
- */
-PURPLE_AVAILABLE_IN_ALL
-char *purple_markup_slice(const char *str, guint x, guint y);
-
-/**
- * purple_markup_get_tag_name:
- * @tag: The string starting a HTML tag.
- *
- * Returns a newly allocated string containing the name of the tag
- * located at "tag". Tag is expected to point to a '<', and contain
- * a '>' sometime after that. If there is no '>' and the string is
- * not NUL terminated, this function can be expected to segfault.
- *
- * Returns: A string containing the name of the tag.
- *
- * Since: 2.0
- */
-PURPLE_AVAILABLE_IN_ALL
-char *purple_markup_get_tag_name(const char *tag);
-
-/**
- * purple_markup_unescape_entity:
- * @text:   A string containing an HTML entity.
- * @length: If not %NULL, the string length of the entity is stored in this location.
- *
- * Returns a constant string of the character representation of the HTML
- * entity pointed to by @text. For example, purple_markup_unescape_entity("&amp;amp;")
- * will return "&amp;". The @text variable is expected to point to an '&amp;',
- * the first character of the entity. If given an unrecognized entity, the function
- * returns %NULL.
- *
- * Note that this function, unlike purple_unescape_html(), does not search
- * the string for the entity, does not replace the entity, and does not
- * return a newly allocated string.
- *
- * Returns: A constant string containing the character representation of the given entity.
- *
- * Since: 2.0
- */
-PURPLE_AVAILABLE_IN_ALL
-const char * purple_markup_unescape_entity(const char *text, int *length);
-
 G_END_DECLS
 
 #endif /* PURPLE_MARKUP_H */
--- a/libpurple/tests/test_markup.c	Mon Jun 23 22:36:53 2025 -0500
+++ b/libpurple/tests/test_markup.c	Mon Jun 23 23:13:43 2025 -0500
@@ -31,206 +31,6 @@
 } MarkupTestData;
 
 static void
-test_purple_markup_html_to_xhtml(void) {
-	int i;
-	MarkupTestData data[] = {
-		{
-			"<a>",
-			"<a href=\"\"></a>",
-			"",
-		}, {
-			"<A href='URL'>ABOUT</a>",
-			"<a href=\"URL\">ABOUT</a>",
-			"ABOUT <URL>",
-		}, {
-			"<a href='URL'>URL</a>",
-			"<a href=\"URL\">URL</a>",
-			"URL",
-		}, {
-			"<a href='mailto:mail'>mail</a>",
-			"<a href=\"mailto:mail\">mail</a>",
-			"mail",
-		}, {
-			"<A href='\"U&apos;R&L'>ABOUT</a>",
-			"<a href=\"&quot;U&apos;R&amp;L\">ABOUT</a>",
-			"ABOUT <\"U'R&L>",
-		}, {
-			"<img src='SRC' alt='ALT'/>",
-			"<img src='SRC' alt='ALT' />",
-			"ALT",
-		}, {
-			"<img src=\"'S&apos;R&C\" alt=\"'A&apos;L&T\"/>",
-			"<img src='&apos;S&apos;R&amp;C' alt='&apos;A&apos;L&amp;T' />",
-			"'A'L&T",
-		}, {
-			"<unknown>",
-			"&lt;unknown>",
-			"<unknown>",
-		}, {
-			"&eacute;&amp;",
-			"&eacute;&amp;",
-			"&eacute;&",
-		}, {
-			"<h1>A<h2>B</h2>C</h1>",
-			"<h1>A<h2>B</h2>C</h1>",
-			"ABC",
-		}, {
-			"<h1><h2><h3><h4>",
-			"<h1><h2><h3><h4></h4></h3></h2></h1>",
-			"",
-		}, {
-			"<italic/>",
-			"<em/>",
-			"",
-		}, {
-			"</",
-			"&lt;/",
-			"</",
-		}, {
-			"</div>",
-			"",
-			"",
-		}, {
-			"<hr/>",
-			"<br/>",
-			"\n",
-		}, {
-			"<hr>",
-			"<br/>",
-			"\n",
-		}, {
-			"<br />",
-			"<br/>",
-			"\n",
-		}, {
-			"<br>INSIDE</br>",
-			"<br/>INSIDE",
-			"\nINSIDE",
-		}, {
-			"<div></div>",
-			"<div></div>",
-			"",
-		}, {
-			"<div/>",
-			"<div/>",
-			"",
-		}, {
-			"<div attr='\"&<>'/>",
-			"<div attr='&quot;&amp;&lt;&gt;'/>",
-			"",
-		}, {
-			"<div attr=\"'\"/>",
-			"<div attr=\"&apos;\"/>",
-			"",
-		}, {
-			"<div/> < <div/>",
-			"<div/> &lt; <div/>",
-			" < ",
-		}, {
-			"<div>x</div>",
-			"<div>x</div>",
-			"x",
-		}, {
-			"<b>x</b>",
-			"<span style='font-weight: bold;'>x</span>",
-			"x",
-		}, {
-			"<bold>x</bold>",
-			"<span style='font-weight: bold;'>x</span>",
-			"x",
-		}, {
-			"<strong>x</strong>",
-			"<span style='font-weight: bold;'>x</span>",
-			"x",
-		}, {
-			"<u>x</u>",
-			"<span style='text-decoration: underline;'>x</span>",
-			"x",
-		}, {
-			"<underline>x</underline>",
-			"<span style='text-decoration: underline;'>x</span>",
-			"x",
-		}, {
-			"<s>x</s>",
-			"<span style='text-decoration: line-through;'>x</span>",
-			"x",
-		}, {
-			"<strike>x</strike>",
-			"<span style='text-decoration: line-through;'>x</span>",
-			"x",
-		}, {
-			"<sub>x</sub>",
-			"<span style='vertical-align:sub;'>x</span>",
-			"x",
-		}, {
-			"<sup>x</sup>",
-			"<span style='vertical-align:super;'>x</span>",
-			"x",
-		}, {
-			"<FONT>x</FONT>",
-			"x",
-			"x",
-		}, {
-			"<font face=\"'Times&gt;New & Roman'\">x</font>",
-			"<span style='font-family: \"Times&gt;New &amp; Roman\";'>x</span>",
-			"x",
-		}, {
-			"<font back=\"'color&gt;blue&red'\">x</font>",
-			"<span style='background: \"color&gt;blue&amp;red\";'>x</span>",
-			"x",
-		}, {
-			"<font color=\"'color&gt;blue&red'\">x</font>",
-			"<span style='color: \"color&gt;blue&amp;red\";'>x</span>",
-			"x",
-		}, {
-			"<font size=1>x</font>",
-			"<span style='font-size: xx-small;'>x</span>",
-			"x",
-		}, {
-			"<font size=432>x</font>",
-			"<span style='font-size: medium;'>x</span>",
-			"x",
-		}, {
-			"<!--COMMENT-->",
-			"<!--COMMENT-->",
-			"COMMENT-->",
-		}, {
-			"<br  />",
-			"&lt;br  />",
-			"<br  />",
-		}, {
-			"<hr  />",
-			"&lt;hr  />",
-			"<hr  />"
-		}, {
-			NULL, NULL, NULL,
-		}
-	};
-
-	for(i = 0; data[i].markup; i++) {
-		char *xhtml = NULL, *plaintext = NULL;
-
-		purple_markup_html_to_xhtml(data[i].markup, &xhtml, &plaintext);
-
-		g_assert_cmpstr(data[i].xhtml, ==, xhtml);
-		g_free(xhtml);
-
-		g_assert_cmpstr(data[i].plaintext, ==, plaintext);
-		g_free(plaintext);
-
-		/* Check only asking for xhtml works. */
-		purple_markup_html_to_xhtml(data[i].markup, &xhtml, NULL);
-		g_assert_cmpstr(data[i].xhtml, ==, xhtml);
-		g_free(xhtml);
-
-		/* Check only asking for plaintext works. */
-		purple_markup_html_to_xhtml(data[i].markup, NULL, &plaintext);
-		g_assert_cmpstr(data[i].plaintext, ==, plaintext);
-		g_free(plaintext);
-	}
-}
-
-static void
 test_purple_markup_strip_html(void) {
 	MarkupTestData data[] = {
 		{
@@ -284,8 +84,6 @@
 	g_test_init(&argc, &argv, NULL);
 	g_test_set_nonfatal_assertions();
 
-	g_test_add_func("/util/markup/html-to-xhtml",
-	                test_purple_markup_html_to_xhtml);
 	g_test_add_func("/util/markup/strip-html",
 	                test_purple_markup_strip_html);
 

mercurial