#ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "enventor_private.h" struct indent_s { Eina_Strbuf *strbuf; Evas_Object *entry; redoundo_data *rd; }; typedef struct indent_line_s { Eina_Stringshare *str; Eina_Bool indent_apply; int indent_depth; } indent_line; /*****************************************************************************/ /* Internal method implementation */ /*****************************************************************************/ static int indent_depth_get(indent_data *id EINA_UNUSED, char *src, int pos) { const char *quot = "\""; const int quot_len = 1; if (!src || (pos < 1)) return 0; int depth = 0; char *cur = (char *) src; char *end = ((char *) src) + pos; while (cur && (cur < end)) { //Skip "" range if (*cur == *quot) { cur += quot_len; cur = strstr(cur, quot); if (!cur) return depth; cur += quot_len; } if (*cur == '{') depth++; else if (*cur == '}') depth--; cur++; } return depth; } static void indent_insert_br_case(indent_data *id) { Evas_Object *entry = id->entry; Evas_Object *tb = elm_entry_textblock_get(entry); Evas_Textblock_Cursor *cur = evas_object_textblock_cursor_get(tb); const char *text = evas_textblock_cursor_paragraph_text_get(cur); char *utf8 = elm_entry_markup_to_utf8(text); Eina_Strbuf* diff = id->strbuf; eina_strbuf_reset(diff); int rd_cur_pos = evas_textblock_cursor_pos_get(cur); if (strlen(utf8) > 0) { evas_textblock_cursor_paragraph_char_first(cur); int i = 0; while (utf8[i] == ' ') { eina_strbuf_append(diff, evas_textblock_cursor_content_get(cur)); evas_textblock_cursor_char_delete(cur); i++; } } free(utf8); redoundo_text_push(id->rd, eina_strbuf_string_get(diff), rd_cur_pos, 0, EINA_FALSE); int space = indent_space_get(id); if (space <= 0) return; //Alloc Empty spaces char *p = alloca(space + 1); memset(p, ' ', space); p[space] = '\0'; redoundo_text_push(id->rd, p, elm_entry_cursor_pos_get(entry), 0, EINA_TRUE); elm_entry_entry_insert(entry, p); } static void indent_insert_tab_case(indent_data *id) { Evas_Object *entry = id->entry; Evas_Object *tb = elm_entry_textblock_get(entry); Evas_Textblock_Cursor *cur_orig = evas_object_textblock_cursor_get(tb); Evas_Textblock_Cursor *cur = evas_object_textblock_cursor_new(tb); char *utf8 = NULL; int utf8_len = 0; char *p = NULL; Eina_Bool insert_indent_space = EINA_FALSE; //Remove inserted "". evas_textblock_cursor_pos_set(cur, evas_textblock_cursor_pos_get(cur_orig)); evas_textblock_cursor_char_prev(cur); if (!strncmp(evas_textblock_cursor_content_get(cur), TAB, TAB_LEN)) { //Cancel added "" from redoundo. redoundo_n_diff_cancel(id->rd, 1); evas_textblock_cursor_char_delete(cur); } evas_textblock_cursor_pos_set(cur, evas_textblock_cursor_pos_get(cur_orig)); /* Spaces for indent are not required. Insert spaces for tab. */ int space = indent_space_get(id); if (space <= 0) goto end; evas_textblock_cursor_paragraph_prev(cur); evas_textblock_cursor_paragraph_next(cur); utf8 = evas_textblock_cursor_range_text_get(cur, cur_orig, EVAS_TEXTBLOCK_TEXT_PLAIN); /* There is no paragraph. Insert spaces for indent. */ if (!utf8) { insert_indent_space = EINA_TRUE; goto end; } utf8_len = strlen(utf8); /* Paragraph is shorter than spaces for indent. Insert spaces for indent. */ if (utf8_len < space) insert_indent_space = EINA_TRUE; end: if (insert_indent_space) { //Allocate spaces for indent. p = alloca(space - utf8_len + 1); memset(p, ' ', space - utf8_len); p[space - utf8_len] = '\0'; } else { //Allocate spaces for tab. p = alloca(TAB_SPACE + 1); memset(p, ' ', TAB_SPACE); p[TAB_SPACE] = '\0'; } redoundo_text_push(id->rd, p, elm_entry_cursor_pos_get(entry), 0, EINA_TRUE); elm_entry_entry_insert(entry, p); if (utf8) free(utf8); evas_textblock_cursor_free(cur); } static void indent_insert_bracket_case(indent_data *id, int cur_line) { Evas_Object *entry = id->entry; Evas_Object *tb = elm_entry_textblock_get(entry); Evas_Textblock_Cursor *cur = evas_object_textblock_cursor_new(tb); evas_textblock_cursor_line_set(cur, cur_line - 1); const char *text = evas_textblock_cursor_paragraph_text_get(cur); char *utf8 = elm_entry_markup_to_utf8(text); int len = strlen(utf8) - 1; if (len < 0) return; while (len) { if (utf8[len] == '}') break; len--; } int space = indent_space_get(id); if (space == len) { free(utf8); return; } int i = 0; if (len > space) { evas_textblock_cursor_paragraph_char_last(cur); evas_textblock_cursor_char_prev(cur); while (i < (len - space)) { if ((utf8[(len - 1) - i] == ' ') && (utf8[(len - 2) - i] == ' ')) { evas_textblock_cursor_char_prev(cur); evas_textblock_cursor_char_delete(cur); } else break; i++; } //leftover if (space == 0 && utf8[0] == ' ') { evas_textblock_cursor_char_prev(cur); evas_textblock_cursor_char_delete(cur); } } else { //Alloc Empty spaces space = (space - len); char *p = alloca(space + 1); memset(p, ' ', space); p[space] = '\0'; evas_textblock_cursor_text_prepend(cur, p); } elm_entry_calc_force(entry); evas_textblock_cursor_free(cur); free(utf8); } static Eina_List * indent_code_line_list_create(indent_data *id EINA_UNUSED, const char *utf8) { Eina_List *code_line_list = NULL; indent_line *code_line = NULL; char *utf8_ptr = NULL; char *utf8_end = NULL; char *utf8_lexem = NULL; char *utf8_appended = NULL; Eina_Bool keep_lexem = EINA_FALSE; //Single line comment begins in the beginning of the line. Eina_Bool single_comment_begin = EINA_FALSE; //Single line comment begins in the middle of the line. Eina_Bool single_comment_middle = EINA_FALSE; //Multi line comment begins in the beginning of the line. Eina_Bool multi_comment_begin = EINA_FALSE; //Multi line comment begins in the middle of the line. Eina_Bool multi_comment_middle = EINA_FALSE; //Multi line comment ends in the line. Eina_Bool multi_comment_end = EINA_FALSE; //Macro begins in the beginning of the line. Eina_Bool macro_begin = EINA_FALSE; //Macro begins in the middle of the line. Eina_Bool macro_middle = EINA_FALSE; int cur_indent_depth = 0; int new_indent_depth = 0; if (!utf8) return NULL; utf8_ptr = (char *)utf8; utf8_end = utf8_ptr + strlen(utf8); /* Create a list of code line strings from inserted string. Each code line string is generated based on lexeme. Here, lexeme starts with nonspace character and ends with newline. */ for ( ; utf8_ptr < utf8_end; utf8_ptr++) { if (*utf8_ptr == '\n') { if (!keep_lexem) utf8_lexem = utf8_ptr; keep_lexem = EINA_FALSE; code_line = (indent_line *)calloc(1, sizeof(indent_line)); char *append_begin = NULL; if (!utf8_appended) append_begin = (char *)utf8; if (single_comment_begin || multi_comment_begin || macro_begin || macro_middle) { if (!append_begin) append_begin = utf8_appended + 1; code_line->indent_apply = EINA_FALSE; } else { if (!append_begin) append_begin = utf8_lexem; //Newline only string does not need indentation. if (utf8_ptr == append_begin) code_line->indent_apply = EINA_FALSE; else code_line->indent_apply = EINA_TRUE; } code_line->str = eina_stringshare_add_length(append_begin, utf8_ptr - append_begin + 1); code_line->indent_depth = cur_indent_depth; cur_indent_depth = new_indent_depth; code_line_list = eina_list_append(code_line_list, code_line); utf8_appended = utf8_ptr; if (single_comment_begin) single_comment_begin = EINA_FALSE; if (single_comment_middle) single_comment_middle = EINA_FALSE; if (multi_comment_middle) { multi_comment_middle = EINA_FALSE; multi_comment_begin = EINA_TRUE; } if (multi_comment_end) { multi_comment_begin = EINA_FALSE; multi_comment_middle = EINA_FALSE; multi_comment_end = EINA_FALSE; } //Check if macro ends. if (macro_begin || macro_middle) { if (*(utf8_ptr - 1) != '\\') { macro_begin = EINA_FALSE; macro_middle = EINA_FALSE; } } } else if ((*utf8_ptr != ' ') && (*utf8_ptr != '\t') && (*utf8_ptr != '\r')) { if (!keep_lexem) { utf8_lexem = utf8_ptr; keep_lexem = EINA_TRUE; } //Check if current character is outside of line comment. if ((!single_comment_begin && !single_comment_middle) && ((!multi_comment_begin && !multi_comment_middle) || (multi_comment_end))) { if ((*utf8_ptr == '/') && (utf8_ptr + 1 < utf8_end)) { //Check if single line comment begins. if (*(utf8_ptr + 1) == '/') { if (utf8_ptr == utf8_lexem) single_comment_begin = EINA_TRUE; else single_comment_middle = EINA_TRUE; } //Check if multi line comment begins. else if (*(utf8_ptr + 1) == '*') { if (utf8_ptr == utf8_lexem) multi_comment_begin = EINA_TRUE; else multi_comment_middle = EINA_TRUE; } } else if (*utf8_ptr == '#') { if (utf8_ptr == utf8_lexem) macro_begin = EINA_TRUE; else macro_middle = EINA_TRUE; } else if (*utf8_ptr == '{') new_indent_depth++; else if (*utf8_ptr == '}') { new_indent_depth--; /* Indentation depth decreases from the current code line if string begins with '}'. */ if (utf8_ptr == utf8_lexem) cur_indent_depth = new_indent_depth; } } //Check if multi line comment ends. if (multi_comment_begin || multi_comment_middle) { if ((*utf8_ptr == '*') && (utf8_ptr + 1 < utf8_end) && (*(utf8_ptr + 1) == '/')) { multi_comment_end = EINA_TRUE; } } } } /* Append rest of the input string which does not end with newline. */ if (!utf8_appended || (utf8_appended < utf8_end - 1)) { char *append_begin = NULL; if (!utf8_appended) append_begin = (char *)utf8; code_line = (indent_line *)calloc(1, sizeof(indent_line)); if (single_comment_begin || multi_comment_begin || macro_begin) { if (!append_begin) append_begin = utf8_appended + 1; code_line->indent_apply = EINA_FALSE; } else { if (!append_begin) { //Only spaces are in the rest of the input string. if (utf8_lexem <= utf8_appended) { append_begin = utf8_appended + 1; code_line->indent_apply = EINA_FALSE; } //Non-space characters are in the rest of the input string. else { append_begin = utf8_lexem; code_line->indent_apply = EINA_TRUE; } } else code_line->indent_apply = EINA_TRUE; } code_line->str = eina_stringshare_add_length(append_begin, utf8_end - append_begin); code_line->indent_depth = cur_indent_depth; code_line_list = eina_list_append(code_line_list, code_line); } return code_line_list; } static int indent_text_auto_format(indent_data *id, const char *insert) { int line_cnt = 0; //FIXME: To improve performance, change logic not to translate text. char *utf8 = evas_textblock_text_markup_to_utf8(NULL, insert); int utf8_size = strlen(utf8); Evas_Object *tb = elm_entry_textblock_get(id->entry); Evas_Textblock_Cursor *cur_start = evas_object_textblock_cursor_new(tb); Evas_Textblock_Cursor *cur_end = evas_object_textblock_cursor_get(tb); int tb_cur_pos = 0; Eina_List *code_line_list = indent_code_line_list_create(id, utf8); indent_line *code_line = NULL; free(utf8); if (!code_line_list) goto end; /* Check if indentation should be applied to the first code line. Indentation is applied if prior string has only spaces. */ code_line= eina_list_data_get(code_line_list); if (code_line->indent_apply) { Evas_Textblock_Cursor *check_start = evas_object_textblock_cursor_new(tb); Evas_Textblock_Cursor *check_end = evas_object_textblock_cursor_new(tb); tb_cur_pos = evas_textblock_cursor_pos_get(cur_end); evas_textblock_cursor_pos_set(check_end, tb_cur_pos - utf8_size); evas_textblock_cursor_pos_set(check_start, tb_cur_pos - utf8_size); evas_textblock_cursor_line_char_first(check_start); char *check_range = evas_textblock_cursor_range_text_get(check_start, check_end, EVAS_TEXTBLOCK_TEXT_PLAIN); evas_textblock_cursor_free(check_start); evas_textblock_cursor_free(check_end); Eina_Bool nonspace_found = EINA_FALSE; if (check_range) { int check_len = strlen(check_range); int index = 0; for ( ; index < check_len; index++) { if (check_range[index] != ' ') { nonspace_found = EINA_TRUE; break; } } free(check_range); } if (nonspace_found) { code_line->indent_apply = EINA_FALSE; } else { int str_len = eina_stringshare_strlen(code_line->str); int index = 0; for ( ; index < str_len; index++) { if ((code_line->str[index] != ' ') && (code_line->str[index] != '\t') && (code_line->str[index] != '\r')) break; } if (index < str_len) { char *new_str = strdup(&code_line->str[index]); if (new_str) { eina_stringshare_del(code_line->str); code_line->str = eina_stringshare_add(new_str); free(new_str); } } } } tb_cur_pos = evas_textblock_cursor_pos_get(cur_end); evas_textblock_cursor_pos_set(cur_start, tb_cur_pos - utf8_size); evas_textblock_cursor_range_delete(cur_start, cur_end); //Cancel last added diff, that was created when text pasted into entry. redoundo_n_diff_cancel(id->rd, 1); evas_textblock_cursor_line_char_first(cur_start); //Move cursor to the position where the inserted string will be prepended. code_line= eina_list_data_get(code_line_list); if (code_line->indent_apply) { evas_textblock_cursor_line_char_first(cur_start); int space_pos_start = evas_textblock_cursor_pos_get(cur_start); int space_pos_end = evas_textblock_cursor_pos_get(cur_end); if (space_pos_start < space_pos_end) { //Delete prior spaces. char *prior_space = evas_textblock_cursor_range_text_get(cur_start, cur_end, EVAS_TEXTBLOCK_TEXT_MARKUP); if (prior_space) { evas_textblock_cursor_range_delete(cur_start, cur_end); tb_cur_pos = evas_textblock_cursor_pos_get(cur_end); /* Add data about removal of prior spaces into the redoundo queue. */ redoundo_text_push(id->rd, prior_space, tb_cur_pos, 0, EINA_FALSE); free(prior_space); } } } else { tb_cur_pos = evas_textblock_cursor_pos_get(cur_end); evas_textblock_cursor_pos_set(cur_start, tb_cur_pos); } int space = indent_space_get(id); Eina_List *l = NULL; Eina_Strbuf *buf = id->strbuf; eina_strbuf_reset(buf); EINA_LIST_FOREACH(code_line_list, l, code_line) { Eina_Stringshare *line_str = code_line->str; if (code_line->indent_apply == EINA_FALSE) { eina_strbuf_append_printf(buf, "%s", line_str); } else { int cur_space = space + (code_line->indent_depth * TAB_SPACE); if (cur_space <= 0) { eina_strbuf_append_printf(buf, "%s", line_str); } else { char *p = alloca(cur_space + 1); memset(p, ' ', cur_space); p[cur_space] = '\0'; eina_strbuf_append_printf(buf, "%s%s", p, line_str); memset(p, 0x0, cur_space); } } eina_stringshare_del(line_str); free(code_line); } eina_list_free(code_line_list); char *utf8_buf = eina_strbuf_string_steal(buf); char *newline_ptr = utf8_buf; line_cnt = 1; newline_ptr = strstr(newline_ptr, "\n"); while (newline_ptr) { line_cnt++; newline_ptr = strstr(newline_ptr + 1, "\n"); } //FIXME: To improve performance, change logic not to translate text. char *markup_buf = evas_textblock_text_utf8_to_markup(NULL, utf8_buf); free(utf8_buf); //Initialize cursor position to the beginning of the pasted string. tb_cur_pos = evas_textblock_cursor_pos_get(cur_start); evas_textblock_cursor_pos_set(cur_end, tb_cur_pos); evas_object_textblock_text_markup_prepend(cur_start, markup_buf); //Add data about formatted change into the redoundo queue. redoundo_text_push(id->rd, markup_buf, tb_cur_pos, 0, EINA_TRUE); free(markup_buf); //Update cursor position to the end of the pasted string. tb_cur_pos = evas_textblock_cursor_pos_get(cur_start); evas_textblock_cursor_pos_set(cur_end, tb_cur_pos); end: evas_textblock_cursor_free(cur_start); return line_cnt; } /*****************************************************************************/ /* Externally accessible calls */ /*****************************************************************************/ indent_data * indent_init(Eina_Strbuf *strbuf, edit_data *ed) { indent_data *id = malloc(sizeof(indent_data)); if (!id) { mem_fail_msg(); return NULL; } id->strbuf = strbuf; id->entry = edit_entry_get(ed); id->rd = edit_redoundo_get(ed); if (!id->entry || !id->rd) EINA_LOG_ERR("Should be called after edit entry and redoundo is initialized!"); return id; } void indent_term(indent_data *id) { free(id); } int indent_space_get(indent_data *id) { //Get the indentation depth int pos = elm_entry_cursor_pos_get(id->entry); char *src = elm_entry_markup_to_utf8(elm_entry_entry_get(id->entry)); int space = indent_depth_get(id, src, pos); if (space < 0) space = 0; space *= TAB_SPACE; free(src); return space; } void indent_delete_apply(indent_data *id, const char *del, int cur_line) { if (del[0] != ' ') return; Evas_Object *tb = elm_entry_textblock_get(id->entry); Evas_Textblock_Cursor *cur = evas_object_textblock_cursor_new(tb); evas_textblock_cursor_line_set(cur, cur_line - 1); const char *text = evas_textblock_cursor_paragraph_text_get(cur); char *utf8 = elm_entry_markup_to_utf8(text); char *last_markup = NULL; Eina_Strbuf* diff = id->strbuf; eina_strbuf_reset(diff); int rd_cur_pos = evas_textblock_cursor_pos_get(cur); int len = 0; if (utf8) len = strlen(utf8); if (len <= 0) goto end; evas_textblock_cursor_paragraph_char_last(cur); last_markup = evas_textblock_cursor_content_get(cur); if (last_markup && !strncmp(last_markup, "
", 5)) evas_textblock_cursor_char_prev(cur); while (len > 0) { if (utf8[(len - 1)] == ' ') { eina_strbuf_append(diff, evas_textblock_cursor_content_get(cur)); evas_textblock_cursor_char_delete(cur); evas_textblock_cursor_char_prev(cur); } else break; len--; } redoundo_text_push(id->rd, eina_strbuf_string_get(diff), rd_cur_pos, 0, EINA_FALSE); elm_entry_calc_force(id->entry); end: evas_textblock_cursor_free(cur); if (utf8) free(utf8); if (last_markup) free(last_markup); } /* Check if indentation of input text is correct. Return EINA_TRUE if indentation is correct. Return EINA_FALSE if indentation is not correct. */ Eina_Bool indent_text_check(indent_data *id EINA_UNUSED, const char *utf8) { char *utf8_ptr = NULL; char *utf8_end = NULL; int utf8_size = 0; int depth = 0; int space = 0; Eina_Bool nonspace_found = EINA_FALSE; Eina_Bool comment_found = EINA_FALSE; Eina_Bool macro_found = EINA_FALSE; if (!utf8) return EINA_TRUE; utf8_ptr = (char *)utf8; utf8_size = strlen(utf8); utf8_end = (char *)utf8 + utf8_size; /* Check indentation spaces of each line. Indentation spaces are checked within line comment and macro. */ while (utf8_ptr < utf8_end) { comment_found = EINA_FALSE; macro_found = EINA_FALSE; if (*utf8_ptr == '}') { depth--; if (depth < 0) depth = 0; } //Tab is not allowed. if (*utf8_ptr == '\t') return EINA_FALSE; else if (*utf8_ptr == ' ') { if (!nonspace_found) space++; } else if (*utf8_ptr == '\n') { //Do not allow space only line. if (!nonspace_found && (space > 0)) return EINA_FALSE; //Do not allow newline at the end. if (utf8_ptr == utf8_end - 1) return EINA_FALSE; space = 0; nonspace_found = EINA_FALSE; } else if (*utf8_ptr != '\r') { char *comment_end = NULL; //Check line comment if ((*utf8_ptr == '/') && (utf8_ptr + 1 < utf8_end)) { //Start of single line comment. if (*(utf8_ptr + 1) == '/') { comment_found = EINA_TRUE; comment_end = strstr(utf8_ptr + 2, "\n"); if (comment_end) comment_end--; } //Start of multi line comment. else if (*(utf8_ptr + 1) == '*') { comment_found = EINA_TRUE; comment_end = strstr(utf8_ptr + 2, "*/"); if (comment_end) comment_end++; } if (comment_found) { if (comment_end) utf8_ptr = comment_end; else return EINA_TRUE; } } //Check macro else if (*utf8_ptr == '#') { macro_found = EINA_TRUE; char *macro_end = utf8_ptr; while (macro_end) { char *backslash = strstr(macro_end + 1, "\\"); macro_end = strstr(macro_end + 1, "\n"); if (macro_end) { if (!backslash || (macro_end < backslash)) break; } } if (macro_end) { macro_end--; utf8_ptr = macro_end; } else return EINA_TRUE; } if (comment_found || macro_found) { if (!nonspace_found) nonspace_found = EINA_TRUE; } //No line comment and No macro. else { if (!nonspace_found) { if (space != depth * TAB_SPACE) return EINA_FALSE; nonspace_found = EINA_TRUE; } if (*utf8_ptr == '}') { if ((utf8_ptr + 1 < utf8_end) && (*(utf8_ptr + 1) != '\n')) return EINA_FALSE; } else if (*utf8_ptr == ';') { if (utf8_ptr + 1 < utf8_end && *(utf8_ptr + 1) != '\n') return EINA_FALSE; } if (*utf8_ptr == '{') { char *bracket_right_ptr = utf8_ptr + 1; while (bracket_right_ptr < utf8_end) { if (*bracket_right_ptr != ' ' && *bracket_right_ptr != '\t') break; bracket_right_ptr++; } if (bracket_right_ptr < utf8_end && *bracket_right_ptr != '\n') { //Check block name after '{'. Eina_Bool block_name_found = EINA_FALSE; if (*bracket_right_ptr == '\"') block_name_found = EINA_TRUE; else if (bracket_right_ptr + 4 < utf8_end) { if (!strncmp(bracket_right_ptr, "name:", 5)) block_name_found = EINA_TRUE; else if (!strncmp(bracket_right_ptr, "state:", 5)) block_name_found = EINA_TRUE; } if (!block_name_found) return EINA_FALSE; } } } } if (!comment_found && !macro_found && (*utf8_ptr == '{')) depth++; utf8_ptr++; } return EINA_TRUE; } /* Create indented markup text from input utf8 text. Count the number of lines of indented text. Return created indented markup text. */ char * indent_text_create(indent_data *id, const char *utf8, int *indented_line_cnt) { if (!utf8) { if (indented_line_cnt) *indented_line_cnt = 0; return NULL; } Eina_List *code_line_list = indent_code_line_list_create(id, utf8); if (!code_line_list) { if (indented_line_cnt) *indented_line_cnt = 0; return NULL; } indent_line *code_line = NULL; Eina_List *l = NULL; Eina_Strbuf *buf = id->strbuf; eina_strbuf_reset(buf); EINA_LIST_FOREACH(code_line_list, l, code_line) { Eina_Stringshare *line_str = code_line->str; if (!code_line->indent_apply) { eina_strbuf_append_printf(buf, "%s", line_str); } else { int space = code_line->indent_depth * TAB_SPACE; if (space <= 0) { eina_strbuf_append_printf(buf, "%s", line_str); } else { char *p = alloca(space + 1); memset(p, ' ', space); p[space] = '\0'; eina_strbuf_append_printf(buf, "%s%s", p, line_str); memset(p, 0x0, space); } } eina_stringshare_del(line_str); free(code_line); } eina_list_free(code_line_list); char *utf8_buf = eina_strbuf_string_steal(buf); char *newline_ptr = utf8_buf; int line_cnt = 1; newline_ptr = strstr(newline_ptr, "\n"); while (newline_ptr) { line_cnt++; newline_ptr = strstr(newline_ptr + 1, "\n"); } //FIXME: This translation may cause low performance. char *indented_markup = evas_textblock_text_utf8_to_markup(NULL, utf8_buf); free(utf8_buf); if (indented_line_cnt) *indented_line_cnt = line_cnt; return indented_markup; } int indent_insert_apply(indent_data *id, const char *insert, int cur_line) { int len = strlen(insert); if (len == 0) { return 0; } else if (len == 1) { if (insert[0] == '}') indent_insert_bracket_case(id, cur_line); return 0; } else { if (!strcmp(insert, EOL)) { indent_insert_br_case(id); return 1; } else if (!strcmp(insert, TAB)) { indent_insert_tab_case(id); return 0; } else if (!strcmp(insert, QUOT)) return 0; else if (!strcmp(insert, LESS)) return 0; else if (!strcmp(insert, GREATER)) return 0; else if (!strcmp(insert, AMP)) return 0; else { int increase = indent_text_auto_format(id, insert); if (increase > 0) increase--; return increase; } } }