- palmcsv export filter
- fixes
+Michael Krolikowski <mkroli@yahoo.de>
+ - built-in vcard import filter
+
+Raphaël Droz <raphael.droz+floss@gmail.com>
+ - custom output format
+ - reworked ldif input/output
+ - vcard import filter through libvformat
+ - fixes
+
+Thorsten Wißmann <edu@thorsten-wissmann.de>
+ - color support
+ - mouse support
+
+Fabio Zanini <fabio.zanini@fastmail.fm>
+ - merge entries
+ - duplicated entries removal
+ - mutt "groups"
+ - fixes
- extra-fields deletion bugfix (Jorrit Tijben)
- additinal keybinding (Hagen Fuchs)
- autotools update (Fabio Zanini)
+ - case-sensitive ldif fields parsing (Christian Brabandt)
+ - ldif standard input support (Raphaël Droz)
+ - ldif extensible field management rewritting (Raphaël Droz)
0.6.0
- configurable views (Cedric Duval)
A more comprehensive list of changes can be found in the ChangeLog file.
--
-
-0.6.0pre2:
+Git:
+ * support for mouse
+ * support for a colored UI
+ * added "groups" as a default field
+ * the UI now support merging selected entries [key M]
+ and removing duplicates [key U]
+ * a "custom" output filter allow the specification of an output
+ format using placeholders
+ * search-next is now bound to "/" too
+ * some output filters can now be used in the context
+ of --mutt-query. This is the case of "vcard" and "custom"
+ [ no --query option has been created and --mutt-query is fully
+ backward compatible ]
+ * ldif output filter has been fixed [output modified] in multiple
+ ways, does not force output to latin1 anymore and support input
+ from stdin.
+ * vcard input/output support:
+ An original input filter implementation was provided soon
+ after 0.6.0pre2.
+ In 2012, an optional build-time option to link against libvformat
+ was added for the very same task: parsing vcard.
+ - It depends on the --enable-vformat ./configure switch
+ - It's only used as an input filter, especially useful to
+ deal with multi-valued fields and encoded characters.
+
+0.6.0pre2 (2010-07-22):
+ * Added anniversary as a default field
+ * Display dates according to current locale
* The four following configuration options have been deprecated and will
no longer be accepted by abook:
* emailpos
Marc Tardif
Gerfried Fuchs
Josef Schugt
-Michael Krolikowski
-Fabio Zanini
See also AUTHORS
}
if(! selected_item_filter.func)
selected_item_filter = select_output_item_filter("muttq");
- else if (! strcmp(outformat, "custom") && *custom_format) {
+ else if (! strcmp(outformat, "custom")) {
+ if(! *custom_format) {
+ fprintf(stderr, _("Invalid custom format string\n"));
+ exit(EXIT_FAILURE);
+ }
parsed_custom_format = (char *)malloc(FORMAT_STRING_LEN * sizeof(char*));
custom_format_fields = (enum field_types *)malloc(FORMAT_STRING_MAX_FIELDS * sizeof(enum field_types *));
parse_custom_format(custom_format, parsed_custom_format, custom_format_fields);
puts (_(" (default: text)"));
puts (_(" --outfile <file> destination file"));
puts (_(" (default: stdout)"));
+ puts (_(" --outformatstr <str> format to use for \"custom\" --outformat"));
+ puts (_(" (default: \"{nick} ({name}): {mobile}\")"));
puts (_(" --formats list available formats"));
}
printf("Not found\n");
quit_mutt_query(EXIT_FAILURE);
}
- putchar('\n');
+ // mutt expects a leading line containing
+ // a message about the query.
+ // Others output filter supporting query (vcard, custom)
+ // don't needs this.
+ if(!strcmp(selected_item_filter.filtname, "muttq"))
+ putchar('\n');
while(i >= 0) {
e_write_item(stdout, i, selected_item_filter.func);
i = find_item(str, i + 1, search_fields);
{"url", N_("URL"), FIELD_STRING}, /* URL */
{"notes", N_("Notes"), FIELD_STRING}, /* NOTES */
{"anniversary", N_("Anniversary day"), FIELD_DATE}, /* ANNIVERSARY */
- {"groups", N_("Groups"), FIELD_LIST}, /* GROUPS */
+ {"groups", N_("Groups"), FIELD_LIST}, /* GROUPS */
{0} /* ITEM_FIELDS */
};
return 0;
}
-// see enum field_types @database.h
-static char *conv_table[] = {
- "name",
- "email",
- "address",
- "address2",
- "city",
- "state",
- "zip",
- "country",
- "phone",
- "workphone",
- "fax",
- "mobile",
- "nick",
- "url",
- "notes",
- "anniversary",
- 0 /* ITEM_FIELDS */
-};
-
+// see also enum field_types @database.h
+extern abook_field standard_fields[];
static int
find_field_enum(char *s) {
- int i = 0;
- while (conv_table[i]) {
- if(!safe_strcmp(conv_table[i], s))
- return i;
- i++;
- }
- // failed
- return -1;
+ int i = -1;
+ while(standard_fields[++i].key)
+ if(!strcmp(standard_fields[i].key, s))
+ return i;
+ return -1;
}
/* Convert a string with named placeholders to
exit(EXIT_FAILURE);
}
+ char tmp[1] = { 0 };
char *p, *start, *field_name = NULL;
p = start = s;
while(*p) {
if(*p == '{') {
start = ++p;
+
+ if(! *start) goto cannotparse;
p = strchr(start, '}');
- if(! *p) {
- fprintf(stderr, _("parse_custom_format: invalid format\n"));
- exit(EXIT_FAILURE);
- }
+ if(! p) goto cannotparse;
strcat(fmt_string, "%s");
field_name = strndup(start, (size_t)(p-start));
*ft = find_field_enum(field_name);
}
ft++;
- p++;
- start = p;
- } else {
+ start = ++p;
+ }
+
+ else if(*p == '\\') {
+ ++p;
+ if(! *p) tmp[0] = '\\'; // last char is a '\' ?
+ else if(*p == 'n') *tmp = '\n';
+ else if(*p == 't') *tmp = '\t';
+ else if(*p == 'r') *tmp = '\r';
+ else if(*p == 'v') *tmp = '\v';
+ else if(*p == 'b') *tmp = '\b';
+ else if(*p == 'a') *tmp = '\a';
+ else *tmp = *p;
+ strncat(fmt_string, tmp, 1);
+ start = ++p;
+ }
+
+ // if no '\' following: quick mode using strchr/strncat
+ else if(! strchr(start, '\\')) {
p = strchr(start, '{');
- if(p && *p) {
+ if(p) { // copy until the next placeholder
strncat(fmt_string, start, (size_t)(p-start));
start = p;
}
- else {
+ else { // copy till the end
strncat( fmt_string,
start,
FORMAT_STRING_LEN - strlen(fmt_string) - 1 );
break;
}
}
+
+ // otherwise character by character
+ else {
+ strncat(fmt_string, p, 1);
+ start = ++p;
+ }
}
- *ft = 66;
+
+ *ft = ITEM_FIELDS;
+ return;
+
+ cannotparse:
+ fprintf(stderr, _("%s: invalid format, index %ld\n"), __FUNCTION__, (start - s));
+ free(fmt_string);
+ while(*ft) free(ft--);
+ exit(EXIT_FAILURE);
}
static int
// we first check that all fields exist before continuing
if(*fmt == '!') {
enum field_types *ftp = ft;
- while(*ft != 66) {
+ while(*ft != ITEM_FIELDS) {
if(! db_fget(item, *ft) )
return 1;
ft++;
fprintf(out, "%s", safe_str(db_fget(item, *ft)));
ft++;
fmt+=2;
- } else if (*ft == 66) {
+ } else if (*ft == ITEM_FIELDS) {
fprintf(out, "%s", fmt);
return 0;
} else {
ui_enable_mouse(TRUE);
}
keypad(stdscr, TRUE);
- if(opt_get_bool(BOOL_USE_COLORS)) {
+ if(opt_get_bool(BOOL_USE_COLORS) && has_colors()) {
start_color();
use_default_colors();
ui_init_color_pairs_user();