* Returns true if closer is the closer of base.
*/
#define _FORMAT_IS_CLOSER_OF(base, closer, closer_len) \
- (!strncmp(base + 1, closer, closer_len) && \
- (!base[closer_len + 1] || \
- (base[closer_len + 1] == '=') || \
- _is_white(base[closer_len + 1])))
+ (!strncmp(base, closer, closer_len) && \
+ (!base[closer_len] || \
+ (base[closer_len] == '=') || \
+ _is_white(base[closer_len])))
/*FIXME: document the structs and struct items. */
struct _Evas_Object_Style_Tag
Evas_Object_Textblock_Node_Text *text_node;
size_t offset;
unsigned char anchor : 2;
+ Eina_Bool opener : 1;
+ Eina_Bool own_closer : 1;
Eina_Bool visible : 1;
Eina_Bool format_change : 1;
Eina_Bool is_new : 1;
s = str;
- /* get rid of anything +s or -s off the start of the string */
- while ((*s == ' ') || (*s == '+') || (*s == '-')) s++;
+ /* get rid of any spaces at the start of the string */
+ while (*s == ' ') s++;
while ((item = _format_parse(&s)))
{
if ((c->format_stack) && (c->format_stack->next))
{
Eina_List *redo_nodes = NULL;
- format++; /* Skip the '-' */
/* Generic pop, should just pop. */
if (((format[0] == ' ') && !format[1]) ||
int handled = 0;
s = n->format;
- if (!strncmp(s, "+ item ", 7))
+ if (!strncmp(s, "item ", 5))
{
// one of:
// item size=20x10 href=name
if (!handled)
{
Eina_Bool push_fmt = EINA_FALSE;
- if (s[0] == '+')
+ if (n->opener && !n->own_closer)
{
fmt = _layout_format_push(c, fmt, n);
- s++;
push_fmt = EINA_TRUE;
}
- else if (s[0] == '-')
+ else if (!n->opener)
{
fmt = _layout_format_pop(c, n->orig_format);
- s++;
}
while ((item = _format_parse(&s)))
{
const char *fstr = fnode->orig_format;
/* balance < 0 means we gave up and everything should be
* invalidated */
- if (*fstr == '+')
+ if (fnode->opener && !fnode->own_closer)
{
balance++;
if (!fstack)
start_n = fnode->text_node;
fstack = eina_list_prepend(fstack, fnode);
}
- else if (*fstr == '-')
+ else if (!fnode->opener)
{
size_t fstr_len;
- /* Skip the '-' */
- fstr++;
fstr_len = strlen(fstr);
/* Generic popper, just pop */
if (((fstr[0] == ' ') && !fstr[1]) || !fstr[0])
* @param fnode the format node to process.
*/
static void
-_markup_get_format_append(Evas_Object_Textblock *o __UNUSED__, Eina_Strbuf *txt, Evas_Object_Textblock_Node_Format *fnode)
+_markup_get_format_append(Eina_Strbuf *txt, Evas_Object_Textblock_Node_Format *fnode)
{
eina_strbuf_append_char(txt, '<');
{
const char *s;
- int pop = 0;
// FIXME: need to escape
s = fnode->orig_format;
- if (*s == '-') pop = 1;
- while ((*s == ' ') || (*s == '+') || (*s == '-')) s++;
- if (pop) eina_strbuf_append_char(txt, '/');
+ if (!fnode->opener && !fnode->own_closer)
+ eina_strbuf_append_char(txt, '/');
eina_strbuf_append(txt, s);
}
eina_strbuf_append_char(txt, '>');
tmp_ch = text[off];
text[off] = 0; /* Null terminate the part of the string */
_markup_get_text_append(txt, text);
- _markup_get_format_append(o, txt, fnode);
+ _markup_get_format_append(txt, fnode);
text[off] = tmp_ch; /* Restore the char */
text += off;
if (fnode->visible)
{
const char *fstr = fmt->orig_format;
- if (fstr && (*fstr == '+'))
+ if (fmt->opener && !fmt->own_closer)
{
fstack = eina_list_prepend(fstack, fmt);
}
- else if (fstr && (*fstr == '-'))
+ else if (fstr && !fmt->opener)
{
size_t fstr_len;
- /* Skip the '-' */
- fstr++;
fstr_len = strlen(fstr);
/* Generic popper, just pop */
if (((fstr[0] == ' ') && !fstr[1]) || !fstr[0])
fnode->anchor = ANCHOR_NONE;
if (!s) return;
- if (s[0] == '+' || s[0] == '-')
+ if (!fnode->own_closer)
{
- is_opener = (s[0] == '+');
- s++;
+ is_opener = fnode->opener;
fnode->format_change = EINA_TRUE;
}
}
- if (fstr && (*fstr == '+'))
+ if (fmt->opener && !fmt->own_closer)
{
formats = eina_list_prepend(formats, fmt);
}
- else if (fstr && (*fstr == '-'))
+ else if (fstr && !fmt->opener)
{
Evas_Object_Textblock_Node_Format *fnode;
size_t fstr_len;
- /* Skip the '-' */
- fstr++;
fstr_len = strlen(fstr);
/* Generic popper, just pop */
if (((fstr[0] == ' ') && !fstr[1]) || !fstr[0])
{
Evas_Object_Textblock_Node_Format *n;
const char *format = _format;
+ const char *pre_stripped_format = NULL;
n = calloc(1, sizeof(Evas_Object_Textblock_Node_Format));
/* Create orig_format and format */
match = _style_match_tag(o->style, format, format_len, &replace_len);
if (match)
{
- if ((match[0] == '+') || (match[0] == '-'))
+ if (match[0] != '-')
{
- char *norm_format;
- norm_format = malloc(format_len + 2 + 1);
- memcpy(norm_format, match, 2);
- memcpy(norm_format + 2, format, format_len);
- norm_format[format_len + 2] = '\0';
- n->orig_format =
- eina_stringshare_add_length(norm_format, format_len + 2);
- free(norm_format);
- }
- else
- {
- n->orig_format =
- eina_stringshare_add_length(format, format_len);
+ n->opener = EINA_TRUE;
+ if (match[0] != '+')
+ {
+ n->own_closer = EINA_TRUE;
+ }
}
- n->format = eina_stringshare_add(match);
+
+ pre_stripped_format = match;
}
else
{
- char *norm_format;
-
- norm_format = malloc(format_len + 2 + 1);
- if (norm_format)
+ if (format[0] == '/')
{
- if (format[0] == '/')
- {
- memcpy(norm_format, "- ", 2);
- memcpy(norm_format + 2, format + 1, format_len - 1);
- norm_format[format_len + 2 - 1] = '\0';
- }
- else
- {
- memcpy(norm_format, "+ ", 2);
- memcpy(norm_format + 2, format, format_len);
- norm_format[format_len + 2] = '\0';
- }
- n->orig_format = eina_stringshare_add(norm_format);
- free(norm_format);
+ format++;
+ format_len--;
+ }
+ else
+ {
+ n->opener = EINA_TRUE;
}
- n->format = eina_stringshare_ref(n->orig_format);
}
+
+ n->orig_format = eina_stringshare_add_length(format, format_len);
+
+ if (!pre_stripped_format)
+ pre_stripped_format = n->orig_format;
}
/* Just use as is, it's a special format. */
else
{
- n->orig_format = eina_stringshare_add(format);
- n->format = eina_stringshare_ref(n->orig_format);
+ const char *tmp = format;;
+ if (format[0] != '-')
+ {
+ n->opener = EINA_TRUE;
+ if (format[0] != '+')
+ {
+ n->own_closer = EINA_TRUE;
+ }
+ }
+ if ((*tmp == '+') || (*tmp == '-'))
+ {
+ tmp++;
+ while (*tmp == ' ') tmp++;
+ }
+ n->orig_format = eina_stringshare_add(tmp);
+ pre_stripped_format = n->orig_format;
}
+ /* Strip format */
+ {
+ const char *tmp = pre_stripped_format;
+ if ((*tmp == '+') || (*tmp == '-'))
+ {
+ tmp++;
+ while (*tmp == ' ') tmp++;
+ }
+ n->format = eina_stringshare_add(tmp);
+ }
format = n->format;
_evas_textblock_format_is_visible(n, format);
should_merge = EINA_TRUE;
}
/* If a singnular, mark as invisible, so we'll delete it. */
- if (!format || ((*format != '+') && (*format != '-')))
+ if (!format || last_fmt->own_closer)
{
last_fmt->visible = EINA_FALSE;
}
EAPI char *
evas_textblock_cursor_content_get(const Evas_Textblock_Cursor *cur)
{
- const Eina_Unicode *ustr;
- Eina_Unicode buf[2];
- char *s;
if (!cur || !cur->node) return NULL;
if (evas_textblock_cursor_format_is_visible_get(cur))
{
- size_t len;
- const char *fstr;
+ Eina_Strbuf *buf;
+ Evas_Object_Textblock_Node_Format *fnode;
char *ret;
- int pop = 0;
- fstr = evas_textblock_node_format_text_get(
- _evas_textblock_node_visible_at_pos_get(
- evas_textblock_cursor_format_get(cur)));
-
- if (!fstr)
- return NULL;
+ fnode = _evas_textblock_node_visible_at_pos_get(
+ evas_textblock_cursor_format_get(cur));
- if (*fstr == '-') pop = 1;
- while ((*fstr == ' ') || (*fstr == '+') || (*fstr == '-')) fstr++;
- len = strlen(fstr);
-
- {
- char *tmp;
- if (pop)
- {
- ret = tmp = malloc(len + 3 + 1); /* </> and the null */
- memcpy(tmp, "</", 2);
- tmp += 2;
- }
- else
- {
- ret = tmp = malloc(len + 2 + 1); /* <> and the null */
- *tmp = '<';
- tmp++;
- }
- memcpy(tmp, fstr, len);
- memcpy(tmp + len, ">", 2); /* Including the null */
- }
+ buf = eina_strbuf_new();
+ _markup_get_format_append(buf, fnode);
+ ret = eina_strbuf_string_steal(buf);
+ eina_strbuf_free(buf);
return ret;
}
+ else
+ {
+ const Eina_Unicode *ustr;
+ Eina_Unicode buf[2];
+ char *s;
- ustr = eina_ustrbuf_string_get(cur->node->unicode);
- buf[0] = ustr[cur->pos];
- buf[1] = 0;
- s = eina_unicode_unicode_to_utf8(buf, NULL);
+ ustr = eina_ustrbuf_string_get(cur->node->unicode);
+ buf[0] = ustr[cur->pos];
+ buf[1] = 0;
+ s = eina_unicode_unicode_to_utf8(buf, NULL);
- return s;
+ return s;
+ }
}
static char *
_evas_textblock_cursor_range_text_markup_get(const Evas_Textblock_Cursor *cur1, const Evas_Textblock_Cursor *_cur2)
{
- Evas_Object_Textblock *o;
Evas_Object_Textblock_Node_Text *tnode;
Eina_Strbuf *buf;
Evas_Textblock_Cursor *cur2;
if (!cur1 || !cur1->node) return NULL;
if (!_cur2 || !_cur2->node) return NULL;
if (cur1->obj != _cur2->obj) return NULL;
- o = (Evas_Object_Textblock *)(cur1->obj->object_data);
if (evas_textblock_cursor_compare(cur1, _cur2) > 0)
{
const Evas_Textblock_Cursor *tc;
tmp_ch = text[off];
text[off] = 0; /* Null terminate the part of the string */
_markup_get_text_append(buf, text);
- _markup_get_format_append(o, buf, fnode);
+ _markup_get_format_append(buf, fnode);
text[off] = tmp_ch; /* Restore the char */
text += off;
if (fnode->visible)
EAPI const char *
evas_textblock_node_format_text_get(const Evas_Object_Textblock_Node_Format *fmt)
{
+ static char *ret = NULL;
+ char *tmp;
+
if (!fmt) return NULL;
- return fmt->orig_format;
+
+ if (ret) free(ret);
+ ret = malloc(strlen(fmt->orig_format) + 2 + 1);
+ tmp = ret;
+
+ if (fmt->opener && !fmt->own_closer)
+ {
+ *(tmp++) = '+';
+ *(tmp++) = ' ';
+ }
+ else if (!fmt->opener)
+ {
+ *(tmp++) = '-';
+ *(tmp++) = ' ';
+ }
+ strcpy(tmp, fmt->orig_format);
+ return ret;
}
EAPI void