[gnome-software/155-allow-some-markup-in-release-notes-in-appdata] gs-appstream: Support more markup in the description text
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/155-allow-some-markup-in-release-notes-in-appdata] gs-appstream: Support more markup in the description text
- Date: Thu, 4 Nov 2021 09:18:39 +0000 (UTC)
commit 1312cc4286029ea172ef2d401a86b30a9718ef44
Author: Milan Crha <mcrha redhat com>
Date: Thu Nov 4 09:49:55 2021 +0100
gs-appstream: Support more markup in the description text
Get to what the AppStream standard supports at the moment:
https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-description
Plus add the 'b' tag for the bold text.
lib/gs-appstream.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 59 insertions(+), 9 deletions(-)
---
diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c
index e0b9cc8c5..9867b426f 100644
--- a/lib/gs-appstream.c
+++ b/lib/gs-appstream.c
@@ -61,33 +61,83 @@ node_set_to_next (XbNode **node)
*node = g_steal_pointer (&next_node);
}
+/* Returns escaped text */
+static gchar *
+gs_appstream_format_description_text (XbNode *node)
+{
+ g_autoptr(GString) str = g_string_new (NULL);
+ const gchar *node_text;
+
+ if (node == NULL)
+ return NULL;
+
+ node_text = xb_node_get_text (node);
+ if (node_text != NULL && *node_text != '\0') {
+ g_autofree gchar *escaped = g_markup_escape_text (node_text, -1);
+ g_string_append (str, escaped);
+ }
+
+ for (g_autoptr(XbNode) n = xb_node_get_child (node); n != NULL; node_set_to_next (&n)) {
+ const gchar *start_elem = "", *end_elem = "";
+ g_autofree gchar *text = NULL;
+ if (g_strcmp0 (xb_node_get_element (n), "b") == 0) {
+ start_elem = "<b>";
+ end_elem = "</b>";
+ } else if (g_strcmp0 (xb_node_get_element (n), "em") == 0 ||
+ g_strcmp0 (xb_node_get_element (n), "i") == 0) {
+ start_elem = "<i>";
+ end_elem = "</i>";
+ } else if (g_strcmp0 (xb_node_get_element (n), "code") == 0 ||
+ g_strcmp0 (xb_node_get_element (n), "tt") == 0) {
+ start_elem = "<tt>";
+ end_elem = "</tt>";
+ }
+
+ /* These can be nested */
+ text = gs_appstream_format_description_text (n);
+ if (text != NULL) {
+ g_string_append_printf (str, "%s%s%s", start_elem, text, end_elem);
+ }
+
+ node_text = xb_node_get_tail (n);
+ if (node_text != NULL && *node_text != '\0') {
+ g_autofree gchar *escaped = g_markup_escape_text (node_text, -1);
+ g_string_append (str, escaped);
+ }
+ }
+
+ if (str->len == 0)
+ return NULL;
+
+ return g_string_free (g_steal_pointer (&str), FALSE);
+}
+
static gchar *
gs_appstream_format_description (XbNode *root, GError **error)
{
g_autoptr(GString) str = g_string_new (NULL);
for (g_autoptr(XbNode) n = xb_node_get_child (root); n != NULL; node_set_to_next (&n)) {
- /* support <p>, <ul>, <ol> and <li>, ignore all else */
+ /* support <p>, <em>, <code>, <ul>, <ol> and <li>, ignore all else */
if (g_strcmp0 (xb_node_get_element (n), "p") == 0) {
- const gchar *node_text = xb_node_get_text (n);
-
+ g_autofree gchar *escaped = gs_appstream_format_description_text (n);
/* Treat a self-closing paragraph (`<p/>`) as
* nonexistent. This is consistent with Firefox. */
- if (node_text != NULL)
- g_string_append_printf (str, "%s\n\n", node_text);
+ if (escaped != NULL)
+ g_string_append_printf (str, "%s\n\n", escaped);
} else if (g_strcmp0 (xb_node_get_element (n), "ul") == 0) {
g_autoptr(GPtrArray) children = xb_node_get_children (n);
for (guint i = 0; i < children->len; i++) {
XbNode *nc = g_ptr_array_index (children, i);
if (g_strcmp0 (xb_node_get_element (nc), "li") == 0) {
- const gchar *node_text = xb_node_get_text (nc);
+ g_autofree gchar *escaped = gs_appstream_format_description_text (nc);
/* Treat a self-closing `<li/>` as an empty
* list element (equivalent to `<li></li>`).
* This is consistent with Firefox. */
g_string_append_printf (str, " • %s\n",
- (node_text != NULL) ? node_text : "");
+ (escaped != NULL) ? escaped : "");
}
}
g_string_append (str, "\n");
@@ -96,12 +146,12 @@ gs_appstream_format_description (XbNode *root, GError **error)
for (guint i = 0; i < children->len; i++) {
XbNode *nc = g_ptr_array_index (children, i);
if (g_strcmp0 (xb_node_get_element (nc), "li") == 0) {
- const gchar *node_text = xb_node_get_text (nc);
+ g_autofree gchar *escaped = gs_appstream_format_description_text (nc);
/* Treat self-closing elements as with `<ul>` above. */
g_string_append_printf (str, " %u. %s\n",
i + 1,
- (node_text != NULL) ? node_text : "");
+ (escaped != NULL) ? escaped : "");
}
}
g_string_append (str, "\n");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]