[draw] Implement a more generic markup parser
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
1e7e4663a5
commit
a4159bbaf7
|
@ -126,13 +126,14 @@ awesome_SOURCES = \
|
||||||
common/xutil.c common/xutil.h \
|
common/xutil.c common/xutil.h \
|
||||||
common/configopts.h common/configopts.c \
|
common/configopts.h common/configopts.c \
|
||||||
common/xscreen.h common/xscreen.c \
|
common/xscreen.h common/xscreen.c \
|
||||||
|
common/draw.c common/draw.h \
|
||||||
|
common/markup.c common/markup.h \
|
||||||
common/list.h \
|
common/list.h \
|
||||||
structs.h \
|
structs.h \
|
||||||
client.c client.h \
|
client.c client.h \
|
||||||
titlebar.c titlebar.h \
|
titlebar.c titlebar.h \
|
||||||
placement.c placement.h \
|
placement.c placement.h \
|
||||||
focus.c focus.h \
|
focus.c focus.h \
|
||||||
common/draw.c common/draw.h \
|
|
||||||
event.c event.h \
|
event.c event.h \
|
||||||
layout.c layout.h \
|
layout.c layout.h \
|
||||||
awesome.c awesome.h \
|
awesome.c awesome.h \
|
||||||
|
@ -165,6 +166,7 @@ bin_PROGRAMS += awesome-message
|
||||||
awesome_message_SOURCES = \
|
awesome_message_SOURCES = \
|
||||||
common/swindow.c common/swindow.h \
|
common/swindow.c common/swindow.h \
|
||||||
common/draw.c common/draw.h \
|
common/draw.c common/draw.h \
|
||||||
|
common/markup.c common/markup.h \
|
||||||
common/util.h common/util.c \
|
common/util.h common/util.c \
|
||||||
common/version.h common/version.c \
|
common/version.h common/version.c \
|
||||||
common/configopts.h common/configopts.c \
|
common/configopts.h common/configopts.c \
|
||||||
|
@ -178,6 +180,7 @@ bin_PROGRAMS += awesome-menu
|
||||||
awesome_menu_SOURCES = \
|
awesome_menu_SOURCES = \
|
||||||
common/swindow.c common/swindow.h \
|
common/swindow.c common/swindow.h \
|
||||||
common/draw.c common/draw.h \
|
common/draw.c common/draw.h \
|
||||||
|
common/markup.c common/markup.h \
|
||||||
common/util.h common/util.c \
|
common/util.h common/util.c \
|
||||||
common/version.h common/version.c \
|
common/version.h common/version.c \
|
||||||
common/configopts.h common/configopts.c \
|
common/configopts.h common/configopts.c \
|
||||||
|
|
129
common/draw.c
129
common/draw.c
|
@ -44,6 +44,7 @@
|
||||||
#include "common/draw.h"
|
#include "common/draw.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
#include "common/xutil.h"
|
#include "common/xutil.h"
|
||||||
|
#include "common/markup.h"
|
||||||
|
|
||||||
/** Convert text from any charset to UTF-8 using iconv
|
/** Convert text from any charset to UTF-8 using iconv
|
||||||
* \param iso the ISO string to convert
|
* \param iso the ISO string to convert
|
||||||
|
@ -223,117 +224,31 @@ typedef struct
|
||||||
xcolor_t bg_color;
|
xcolor_t bg_color;
|
||||||
} draw_parser_data_t;
|
} draw_parser_data_t;
|
||||||
|
|
||||||
static void
|
|
||||||
draw_text_markup_parse_start_element(GMarkupParseContext *context __attribute__ ((unused)),
|
|
||||||
const gchar *element_name,
|
|
||||||
const gchar **attribute_names,
|
|
||||||
const gchar **attribute_values,
|
|
||||||
gpointer user_data,
|
|
||||||
GError **error __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
draw_parser_data_t *p = (draw_parser_data_t *) user_data;
|
|
||||||
char *newtext;
|
|
||||||
int i = 0;
|
|
||||||
ssize_t len;
|
|
||||||
|
|
||||||
if(!a_strcmp(element_name, "bg"))
|
|
||||||
{
|
|
||||||
for(i = 0; attribute_names[i]; i++)
|
|
||||||
if(!p->has_bg_color && !a_strcmp(attribute_names[i], "color"))
|
|
||||||
p->has_bg_color = draw_color_new(p->connection, p->phys_screen,
|
|
||||||
attribute_values[i], &p->bg_color);
|
|
||||||
}
|
|
||||||
else if(a_strcmp(element_name, "markup"))
|
|
||||||
{
|
|
||||||
if(!(len = asprintf(&newtext, "%s<%s ", NONULL(p->text), element_name)))
|
|
||||||
return;
|
|
||||||
len++; /* add \0 that asprintf does not return in len */
|
|
||||||
for(i = 0; attribute_names[i]; i++)
|
|
||||||
{
|
|
||||||
len += a_strlen(attribute_names[i]) + a_strlen(attribute_values[i]) + 5;
|
|
||||||
p_realloc(&newtext, len);
|
|
||||||
a_strcat(newtext, len, attribute_names[i]);
|
|
||||||
a_strcat(newtext, len, "=\"");
|
|
||||||
a_strcat(newtext, len, attribute_values[i]);
|
|
||||||
a_strcat(newtext, len, "\" ");
|
|
||||||
}
|
|
||||||
p_realloc(&newtext, ++len);
|
|
||||||
a_strcat(newtext, len, ">");
|
|
||||||
p_delete(&p->text);
|
|
||||||
p->text = newtext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
draw_text_markup_parse_end_element(GMarkupParseContext *context __attribute__ ((unused)),
|
|
||||||
const gchar *element_name,
|
|
||||||
gpointer user_data,
|
|
||||||
GError **error __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
draw_parser_data_t *p = (draw_parser_data_t *) user_data;
|
|
||||||
char *newtext;
|
|
||||||
|
|
||||||
if(a_strcmp(element_name, "markup")
|
|
||||||
&& a_strcmp(element_name, "bg"))
|
|
||||||
{
|
|
||||||
asprintf(&newtext, "%s</%s>", p->text, element_name);
|
|
||||||
p_delete(&p->text);
|
|
||||||
p->text = newtext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
draw_text_markup_parse_text(GMarkupParseContext *context __attribute__ ((unused)),
|
|
||||||
const gchar *text,
|
|
||||||
gsize text_len,
|
|
||||||
gpointer user_data,
|
|
||||||
GError **error __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
draw_parser_data_t *p = (draw_parser_data_t *) user_data;
|
|
||||||
ssize_t len, rlen;
|
|
||||||
|
|
||||||
len = a_strlen(p->text);
|
|
||||||
rlen = len + 1 + text_len;
|
|
||||||
p_realloc(&p->text, rlen);
|
|
||||||
if(len)
|
|
||||||
a_strncat(p->text, rlen, text, len);
|
|
||||||
else
|
|
||||||
a_strncpy(p->text, rlen, text, text_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
draw_text_markup_expand(draw_parser_data_t *data,
|
draw_text_markup_expand(draw_parser_data_t *data,
|
||||||
const char *str, ssize_t slen)
|
const char *str, ssize_t slen)
|
||||||
{
|
{
|
||||||
GMarkupParseContext *mkp_ctx;
|
const char *elements[] = { "bg", NULL};
|
||||||
GMarkupParser parser =
|
markup_parser_data_t *p;
|
||||||
{
|
int i;
|
||||||
/* start_element */
|
|
||||||
draw_text_markup_parse_start_element,
|
|
||||||
/* end_element */
|
|
||||||
draw_text_markup_parse_end_element,
|
|
||||||
/* text */
|
|
||||||
draw_text_markup_parse_text,
|
|
||||||
/* passthrough */
|
|
||||||
NULL,
|
|
||||||
/* error */
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
mkp_ctx = g_markup_parse_context_new(&parser, 0, data, NULL);
|
p = markup_parser_data_new(elements, countof(elements));
|
||||||
|
|
||||||
if(!g_markup_parse_context_parse(mkp_ctx, "<markup>", -1, &error)
|
if(!markup_parse(p, str, slen))
|
||||||
|| !g_markup_parse_context_parse(mkp_ctx, str, slen, &error)
|
|
||||||
|| !g_markup_parse_context_parse(mkp_ctx, "</markup>", -1, &error)
|
|
||||||
|| !g_markup_parse_context_end_parse(mkp_ctx, &error))
|
|
||||||
{
|
|
||||||
warn("unable to parse text: %s\n", error->message);
|
|
||||||
g_error_free(error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
g_markup_parse_context_free(mkp_ctx);
|
/* bg */
|
||||||
|
if(p->attribute_values[0])
|
||||||
|
for(i = 0; p->attribute_values[0][i]; i++)
|
||||||
|
if(!strcmp(p->attribute_values[0][i], "color"))
|
||||||
|
data->has_bg_color = draw_color_new(data->connection, data->phys_screen,
|
||||||
|
p->attribute_values[0][i], &data->bg_color);
|
||||||
|
|
||||||
|
/* stole text */
|
||||||
|
data->text = p->text;
|
||||||
|
p->text = NULL;
|
||||||
|
|
||||||
|
markup_parser_data_delete(&p);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -343,11 +258,7 @@ draw_text_markup_expand(draw_parser_data_t *data,
|
||||||
* \param area area to draw to
|
* \param area area to draw to
|
||||||
* \param align alignment
|
* \param align alignment
|
||||||
* \param padding padding to add before drawing the text
|
* \param padding padding to add before drawing the text
|
||||||
* \param font font to use
|
|
||||||
* \param text text to draw
|
* \param text text to draw
|
||||||
* \param enable shadow
|
|
||||||
* \param fg foreground color
|
|
||||||
* \param bg background color
|
|
||||||
* \return area_t with width and height are set to what used
|
* \return area_t with width and height are set to what used
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@ -374,7 +285,7 @@ draw_text(DrawCtx *ctx,
|
||||||
else
|
else
|
||||||
utf8 = a_strdup(text);
|
utf8 = a_strdup(text);
|
||||||
|
|
||||||
bzero(&parser_data, sizeof(parser_data));
|
p_clear(&parser_data, 1);
|
||||||
parser_data.connection = ctx->connection;
|
parser_data.connection = ctx->connection;
|
||||||
parser_data.phys_screen = ctx->phys_screen;
|
parser_data.phys_screen = ctx->phys_screen;
|
||||||
if(draw_text_markup_expand(&parser_data, utf8, len))
|
if(draw_text_markup_expand(&parser_data, utf8, len))
|
||||||
|
@ -1015,7 +926,7 @@ draw_text_extents(xcb_connection_t *conn, int default_screen, font_t *font, cons
|
||||||
else
|
else
|
||||||
utf8 = a_strdup(text);
|
utf8 = a_strdup(text);
|
||||||
|
|
||||||
bzero(&parser_data, sizeof(parser_data));
|
p_clear(&parser_data, 1);
|
||||||
parser_data.connection = conn;
|
parser_data.connection = conn;
|
||||||
parser_data.phys_screen = default_screen;
|
parser_data.phys_screen = default_screen;
|
||||||
if(draw_text_markup_expand(&parser_data, utf8, len))
|
if(draw_text_markup_expand(&parser_data, utf8, len))
|
||||||
|
|
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* markup.c - markup functions
|
||||||
|
*
|
||||||
|
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* asprintf */
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "common/markup.h"
|
||||||
|
|
||||||
|
/** Callback to invoke when the opening tag of an element is seen.
|
||||||
|
* Here is just copies element elements we do not care about, and copies
|
||||||
|
* values we care.
|
||||||
|
* \param context the context of GMarkup
|
||||||
|
* \param element_name element name
|
||||||
|
* \param attribute_names array of attribute names
|
||||||
|
* \param attribute_values array of attribute values
|
||||||
|
* \param user_data pointer to user data, here a markup_parser_data_t pointer
|
||||||
|
* \param error a GError
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
markup_parse_start_element(GMarkupParseContext *context __attribute__ ((unused)),
|
||||||
|
const gchar *element_name,
|
||||||
|
const gchar **attribute_names,
|
||||||
|
const gchar **attribute_values,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
markup_parser_data_t *p = (markup_parser_data_t *) user_data;
|
||||||
|
char *newtext;
|
||||||
|
int i, j;
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
for(i = 0; p->elements[i]; i++)
|
||||||
|
if(!a_strcmp(element_name, p->elements[i]))
|
||||||
|
{
|
||||||
|
for(j = 0; attribute_names[j]; j++);
|
||||||
|
p->attribute_names[i] = p_new(char *, j);
|
||||||
|
p->attribute_values[i] = p_new(char *, j);
|
||||||
|
|
||||||
|
for(j = 0; attribute_names[j]; j++)
|
||||||
|
{
|
||||||
|
p->attribute_names[i][j] = a_strdup(attribute_names[j]);
|
||||||
|
p->attribute_values[i][j] = a_strdup(attribute_values[j]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(a_strcmp(element_name, "markup"))
|
||||||
|
{
|
||||||
|
if(!(len = asprintf(&newtext, "%s<%s ", NONULL(p->text), element_name)))
|
||||||
|
return;
|
||||||
|
len++; /* add \0 that asprintf does not return in len */
|
||||||
|
for(i = 0; attribute_names[i]; i++)
|
||||||
|
{
|
||||||
|
len += a_strlen(attribute_names[i]) + a_strlen(attribute_values[i]) + 5;
|
||||||
|
p_realloc(&newtext, len);
|
||||||
|
a_strcat(newtext, len, attribute_names[i]);
|
||||||
|
a_strcat(newtext, len, "=\"");
|
||||||
|
a_strcat(newtext, len, attribute_values[i]);
|
||||||
|
a_strcat(newtext, len, "\" ");
|
||||||
|
}
|
||||||
|
p_realloc(&newtext, ++len);
|
||||||
|
a_strcat(newtext, len, ">");
|
||||||
|
p_delete(&p->text);
|
||||||
|
p->text = newtext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Callback to invoke when the closing tag of an element is seen. Note that
|
||||||
|
* this is also called for empty tags like <empty/>.
|
||||||
|
* Here is just copies element elements we do not care about.
|
||||||
|
* \param context the context of GMarkup
|
||||||
|
* \param element_name element name
|
||||||
|
* \param user_data pointer to user data, here a markup_parser_data_t pointer
|
||||||
|
* \param error a GError
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
markup_parse_end_element(GMarkupParseContext *context __attribute__ ((unused)),
|
||||||
|
const gchar *element_name,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
markup_parser_data_t *p = (markup_parser_data_t *) user_data;
|
||||||
|
char *newtext;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; p->elements[i]; i++)
|
||||||
|
if(!a_strcmp(element_name, p->elements[i]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(a_strcmp(element_name, "markup"))
|
||||||
|
{
|
||||||
|
asprintf(&newtext, "%s</%s>", p->text, element_name);
|
||||||
|
p_delete(&p->text);
|
||||||
|
p->text = newtext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Callback to invoke when some text is seen (text is always inside an
|
||||||
|
* element). Note that the text of an element may be spread over multiple calls
|
||||||
|
* of this function. If the G_MARKUP_TREAT_CDATA_AS_TEXT flag is set, this
|
||||||
|
* function is also called for the content of CDATA marked sections.
|
||||||
|
* Here it recopies blindly the text in the text attribute of user_data.
|
||||||
|
* \param context the context of GMarkup
|
||||||
|
* \param text the text
|
||||||
|
* \param text_len the text length
|
||||||
|
* \param user_data pointer to user data, here a markup_parser_data_t pointer
|
||||||
|
* \param error a GError
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
markup_parse_text(GMarkupParseContext *context __attribute__ ((unused)),
|
||||||
|
const gchar *text,
|
||||||
|
gsize text_len,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
markup_parser_data_t *p = (markup_parser_data_t *) user_data;
|
||||||
|
ssize_t len, rlen;
|
||||||
|
|
||||||
|
len = a_strlen(p->text);
|
||||||
|
rlen = len + 1 + text_len;
|
||||||
|
p_realloc(&p->text, rlen);
|
||||||
|
if(len)
|
||||||
|
a_strncat(p->text, rlen, text, len);
|
||||||
|
else
|
||||||
|
a_strncpy(p->text, rlen, text, text_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a markup_parser_data_t structure with elements list.
|
||||||
|
* \param elements an array of elements to look for, NULL terminated
|
||||||
|
* \param number of elements in the array (without NULL)
|
||||||
|
* \return a pointer to an allocated markup_parser_data_t which must be freed
|
||||||
|
* with markup_parser_data_delete()
|
||||||
|
*/
|
||||||
|
markup_parser_data_t *
|
||||||
|
markup_parser_data_new(const char **elements, ssize_t nelem)
|
||||||
|
{
|
||||||
|
markup_parser_data_t *p;
|
||||||
|
|
||||||
|
p = p_new(markup_parser_data_t, 1);
|
||||||
|
|
||||||
|
p->elements = elements;
|
||||||
|
p->attribute_names = p_new(char **, nelem);
|
||||||
|
p->attribute_values = p_new(char **, nelem);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Delete a markup_parser_data_t allocated.
|
||||||
|
* \param p markup_parser_data_t pointer address
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
markup_parser_data_delete(markup_parser_data_t **p)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for(i = 0; (*p)->elements[i]; i++)
|
||||||
|
if((*p)->attribute_names[i])
|
||||||
|
{
|
||||||
|
for(j = 0; (*p)->attribute_names[i][j]; j++);
|
||||||
|
{
|
||||||
|
p_delete(&(*p)->attribute_names[i][j]);
|
||||||
|
p_delete(&(*p)->attribute_values[i][j]);
|
||||||
|
}
|
||||||
|
p_delete(&(*p)->attribute_names[i]);
|
||||||
|
p_delete(&(*p)->attribute_values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_delete(&(*p)->text);
|
||||||
|
p_delete(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Parse markup defined in data on the string str.
|
||||||
|
* \param data a markup_parser_data_t allocated by markup_parser_data_new()
|
||||||
|
* \param str a string to parse markup from
|
||||||
|
* \param slen str length
|
||||||
|
* \return true if success, false otherwise
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
markup_parse(markup_parser_data_t *data, const char *str, ssize_t slen)
|
||||||
|
{
|
||||||
|
GMarkupParseContext *mkp_ctx;
|
||||||
|
GMarkupParser parser =
|
||||||
|
{
|
||||||
|
/* start_element */
|
||||||
|
markup_parse_start_element,
|
||||||
|
/* end_element */
|
||||||
|
markup_parse_end_element,
|
||||||
|
/* text */
|
||||||
|
markup_parse_text,
|
||||||
|
/* passthrough */
|
||||||
|
NULL,
|
||||||
|
/* error */
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
mkp_ctx = g_markup_parse_context_new(&parser, 0, data, NULL);
|
||||||
|
|
||||||
|
if(!g_markup_parse_context_parse(mkp_ctx, "<markup>", -1, &error)
|
||||||
|
|| !g_markup_parse_context_parse(mkp_ctx, str, slen, &error)
|
||||||
|
|| !g_markup_parse_context_parse(mkp_ctx, "</markup>", -1, &error)
|
||||||
|
|| !g_markup_parse_context_end_parse(mkp_ctx, &error))
|
||||||
|
{
|
||||||
|
warn("unable to parse text: %s\n", error->message);
|
||||||
|
g_error_free(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_markup_parse_context_free(mkp_ctx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* markup.h - markup header
|
||||||
|
*
|
||||||
|
* Copyright © 2008 Julien Danjou <julien@danjou.info>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AWESOME_COMMON_MARKUP_H
|
||||||
|
#define AWESOME_COMMON_MARKUP_H
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *text;
|
||||||
|
const char **elements;
|
||||||
|
char ***attribute_names;
|
||||||
|
char ***attribute_values;
|
||||||
|
} markup_parser_data_t;
|
||||||
|
|
||||||
|
markup_parser_data_t * markup_parser_data_new(const char **, ssize_t);
|
||||||
|
void markup_parser_data_delete(markup_parser_data_t **);
|
||||||
|
bool markup_parse(markup_parser_data_t *data, const char *, ssize_t);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
Loading…
Reference in New Issue