* src/Makefile.am
authorChristoph Hohmann <reboot@gmx.ch>
Fri, 22 Feb 2002 03:08:20 +0000 (03:08 +0000)
committerChristoph Hohmann <reboot@gmx.ch>
Fri, 22 Feb 2002 03:08:20 +0000 (03:08 +0000)
        added quote_fmt.c
* src/prefs_common.[ch]
* src/prefs_template.c
* src/quote_fmt.c               *** NEW FILE ***
* src/quote_fmt.h
        move quote format symbol description code
        to it's own file because it is used from
        differnent code parts
        Rewrote symbol description GUI
          + use table
          + add separators
          + get data from array (no more long constant strings)
* src/quote_fmt_lex.l
* src/quote_fmt_parse.y
        Symbol for Literal % changed to \% instead of %%
        (More logical as \ is used for quoting for other symbols)
        Add |f and |p to include files and program output
        Examples:
            |f{/home/.../.signature}
            |p{date}
* po/de.po
        Correct wrong spelling for "Referenzen"

ChangeLog.claws
configure.in
po/de.po
src/Makefile.am
src/prefs_common.c
src/prefs_common.h
src/prefs_template.c
src/quote_fmt.c [new file with mode: 0644]
src/quote_fmt.h
src/quote_fmt_lex.l
src/quote_fmt_parse.y

index 884d131423cb8905b1b5555426d9fd00e4a99ea0..a6219d2dc1c254e5ff2550802f4322235961df67 100644 (file)
@@ -1,3 +1,29 @@
+2002-02-22 [christoph] 0.7.2claws5
+
+       * src/Makefile.am
+               added quote_fmt.c
+       * src/prefs_common.[ch]
+       * src/prefs_template.c
+       * src/quote_fmt.c               *** NEW FILE ***
+       * src/quote_fmt.h
+               move quote format symbol description code
+               to it's own file because it is used from
+               differnent code parts
+               Rewrote symbol description GUI
+                 + use table
+                 + add separators
+                 + get data from array (no more long constant strings)
+       * src/quote_fmt_lex.l
+       * src/quote_fmt_parse.y
+               Symbol for Literal % changed to \% instead of %%
+               (More logical as \ is used for quoting for other symbols)
+               Add |f and |p to include files and program output
+               Examples:
+                   |f{/home/.../.signature}
+                   |p{date}
+       * po/de.po
+               Correct wrong spelling for "Referenzen"
+
 2002-02-21 [paul]      0.7.2claws4
 
        * src/procmsg.c
index b1822a93635b8d82e56e0ba89969c19dcbfbb69d..0ec6f0b4e2d540f559b7655a691744421ce33d6b 100644 (file)
@@ -8,7 +8,7 @@ MINOR_VERSION=7
 MICRO_VERSION=2
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=claws4
+EXTRA_VERSION=claws5
 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
 
 dnl set $target
index 2dd323c855d0047a8a40fb3e0d741cd10358238b..eadb09c935d724b1018953dfcb097922d2b85706 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -5391,7 +5391,7 @@ msgstr "In Antwort auf"
 
 #: src/prefs_matcher.c:144
 msgid "References"
-msgstr "Referenzrn"
+msgstr "Referenzen"
 
 #: src/prefs_matcher.c:145
 msgid "Age greater than"
index b0ed63e8c7a71bdea0d8b1d9b36efc13148e519e..9a6c669a9310bda0f158f73f0827b21c156ea866 100644 (file)
@@ -124,7 +124,7 @@ sylpheed_SOURCES = \
        prefs_filtering.c prefs_filtering.h \
        mbox_folder.c mbox_folder.h \
        quote_fmt_lex.l quote_fmt_lex.h \
-       quote_fmt_parse.y quote_fmt.h \
+       quote_fmt_parse.y quote_fmt.c quote_fmt.h \
        gtkspell.c gtkspell.h gtkxtext.h \
        matcher_parser_lex.l matcher_parser_lex.h \
        matcher_parser_parse.y matcher_parser.h \
index 4b9af4997da2693a0f4f5dbde005c4cadf2bb791..de249b1c3e1d9b923da78f355d3f2fc6c39f84cf 100644 (file)
@@ -54,6 +54,7 @@
 #include "filesel.h"
 #include "folderview.h"
 #include "stock_pixmap.h"
+#include "quote_fmt.h"
 
 #if USE_PSPELL
 #include "gtkspell.h"
@@ -230,7 +231,6 @@ static struct KeybindDialog {
        GtkWidget *combo;
 } keybind;
 
-static GtkWidget *quote_desc_win;
 static GtkWidget *font_sel_win;
 static guint font_sel_conn_id; 
 static GtkWidget *quote_color_win;
@@ -760,13 +760,8 @@ static void date_format_select_row         (GtkWidget      *date_format_list,
                                                 gint            column,
                                                 GdkEventButton *event,
                                                 GtkWidget      *date_format);
-static GtkWidget *date_format_create           (GtkButton      *button,
-                                                void           *data);
-
-static void prefs_quote_description_create     (void);
-static void prefs_quote_description_key_pressed        (GtkWidget      *widget,
-                                                GdkEventKey    *event,
-                                                gpointer        data);
+static GtkWidget *date_format_create            (GtkButton      *button,
+                                                 void           *data);
 
 static void prefs_quote_colors_dialog          (void);
 static void prefs_quote_colors_dialog_create   (void);
@@ -1886,7 +1881,7 @@ static void prefs_quote_create(void)
        gtk_widget_show (btn_quotedesc);
        gtk_box_pack_start (GTK_BOX (hbox1), btn_quotedesc, FALSE, FALSE, 0);
        gtk_signal_connect(GTK_OBJECT(btn_quotedesc), "clicked",
-                          GTK_SIGNAL_FUNC(prefs_quote_description), NULL);
+                          GTK_SIGNAL_FUNC(quote_fmt_quote_description), NULL);
 
        compose.checkbtn_reply_with_quote= checkbtn_reply_with_quote;
        quote.entry_quotemark    = entry_quotemark;
@@ -3296,144 +3291,6 @@ static void prefs_recycle_colors_toggled(GtkWidget *widget)
        prefs_common.recycle_quote_colors = is_active;
 }
 
-void prefs_quote_description(void)
-{
-       if (!quote_desc_win)
-               prefs_quote_description_create();
-
-       manage_window_set_transient(GTK_WINDOW(quote_desc_win));
-       gtk_widget_show(quote_desc_win);
-       gtk_main();
-       gtk_widget_hide(quote_desc_win);
-}
-
-static void prefs_quote_description_create(void)
-{
-       GtkWidget *vbox;
-       GtkWidget *hbox;
-       GtkWidget *vbox2;
-       GtkWidget *label;
-       GtkWidget *hbbox;
-       GtkWidget *ok_btn;
-
-       quote_desc_win = gtk_window_new(GTK_WINDOW_DIALOG);
-       gtk_window_set_title(GTK_WINDOW(quote_desc_win),
-                            _("Description of symbols"));
-       gtk_container_set_border_width(GTK_CONTAINER(quote_desc_win), 8);
-       gtk_window_set_position(GTK_WINDOW(quote_desc_win), GTK_WIN_POS_CENTER);
-       gtk_window_set_modal(GTK_WINDOW(quote_desc_win), TRUE);
-       gtk_window_set_policy(GTK_WINDOW(quote_desc_win), FALSE, FALSE, FALSE);
-
-       vbox = gtk_vbox_new(FALSE, 8);
-       gtk_container_add(GTK_CONTAINER(quote_desc_win), vbox);
-
-       hbox = gtk_hbox_new(FALSE, 8);
-       gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
-
-       vbox2 = gtk_vbox_new(FALSE, 8);
-       gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
-
-#define PACK_LABEL() \
-       gtk_box_pack_start(GTK_BOX(vbox2), label, TRUE, TRUE, 0); \
-       gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); \
-       gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-
-       label = gtk_label_new
-               ("%d\n"         /* date */
-                "%f\n"         /* from */
-                "%N\n"         /* full name of sender */
-                "%F\n"         /* first name of sender */
-                "%I\n"         /* initial of sender */
-                "%s\n"         /* subject */
-                "%t\n"         /* to */
-                "%c\n"         /* cc */
-                "%n\n"         /* newsgroups */
-                "%r\n"         /* references */
-                "%i");         /* message id */
-       PACK_LABEL();
-
-       label = gtk_label_new
-               ("?x{expr}");   /* condition */
-       PACK_LABEL();
-
-       label = gtk_label_new
-               ("%M\n"         /* message body */
-                "%Q\n"         /* quoted message body */
-                "%m\n"         /* message body without signature */
-                "%q\n"         /* quoted message body without signature */
-                "%%");         /* literal percent */
-       PACK_LABEL();
-
-       label = gtk_label_new
-               ("\\\\\n"       /* literal backslash */
-                "\\?\n"        /* literal question mark */
-                "\\{\n"        /* literal opening curly brace */
-                "\\}");        /* literal closing curly brace */
-       PACK_LABEL();
-
-       vbox2 = gtk_vbox_new(FALSE, 8);
-       gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
-
-       label = gtk_label_new
-               (_("Date\n"
-                  "From\n"
-                  "Full Name of Sender\n"
-                  "First Name of Sender\n"
-                  "Initial of Sender\n"
-                  "Subject\n"
-                  "To\n"
-                  "Cc\n"
-                  "Newsgroups\n"
-                  "References\n"
-                  "Message-ID"));
-       PACK_LABEL();
-
-       label = gtk_label_new
-               (_("If x is set, displays expr"));
-       PACK_LABEL();
-
-       label = gtk_label_new
-               (_("Message body\n"
-                  "Quoted message body\n"
-                  "Message body without signature\n"
-                  "Quoted message body without signature\n"
-                  "Literal %"));
-       PACK_LABEL();
-
-       label = gtk_label_new
-               (_("Literal backslash\n"
-                  "Literal question mark\n"
-                  "Literal opening curly brace\n"
-                  "Literal closing curly brace"));
-       PACK_LABEL();
-
-#undef PACK_LABEL
-
-       gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
-                               NULL, NULL, NULL, NULL);
-       gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
-
-       gtk_widget_grab_default(ok_btn);
-       gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
-                          GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
-       gtk_signal_connect
-               (GTK_OBJECT(quote_desc_win), "key_press_event",
-                GTK_SIGNAL_FUNC(prefs_quote_description_key_pressed),
-                NULL);
-       gtk_signal_connect(GTK_OBJECT(quote_desc_win), "delete_event",
-                          GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
-
-       gtk_widget_show_all(vbox);
-}
-
-static void prefs_quote_description_key_pressed(GtkWidget *widget,
-                                               GdkEventKey *event,
-                                               gpointer data)
-{
-       if (event && event->keyval == GDK_Escape)
-               gtk_main_quit();
-}
-
 static void prefs_font_select(GtkButton *button, GtkEntry *entry)
 {
        gchar *font_name;
@@ -3980,8 +3837,6 @@ static void prefs_common_ok(void)
 {
        prefs_common_apply();
        gtk_widget_hide(dialog.window);
-       if (quote_desc_win && GTK_WIDGET_VISIBLE(quote_desc_win))
-               gtk_widget_hide(quote_desc_win);
 
        inc_unlock();
 }
index 8be868a31427bb9e156115918f2b2c894072c509..e7c54abae656ae0bc13ea7e4882576fd100b4e15 100644 (file)
@@ -230,6 +230,4 @@ void prefs_common_read_config       (void);
 void prefs_common_save_config  (void);
 void prefs_common_open         (void);
 
-void prefs_quote_description   (void);
-
 #endif /* __PREFS_COMMON_H__ */
index 22c98681cccaf109f7eb9f5ad1387715e018d012..b8e8f8c058aca11d93a9ca3d64b109b12aaf1324 100644 (file)
@@ -35,7 +35,6 @@
 #include "gtkutils.h"
 #include "alertpanel.h"
 #include "manage_window.h"
-#include "prefs_common.h"
 #include "compose.h"
 #include "addr_compl.h"
 #include "quote_fmt.h"
@@ -231,7 +230,7 @@ static void prefs_template_window_create(void)
        gtk_widget_show(desc_btn);
        gtk_box_pack_end(GTK_BOX(hbox2), desc_btn, FALSE, FALSE, 0);
        gtk_signal_connect(GTK_OBJECT(desc_btn), "clicked",
-                          GTK_SIGNAL_FUNC(prefs_quote_description), NULL);
+                          GTK_SIGNAL_FUNC(quote_fmt_quote_description), NULL);
 
        /* templates list */
        scroll1 = gtk_scrolled_window_new(NULL, NULL);
diff --git a/src/quote_fmt.c b/src/quote_fmt.c
new file mode 100644 (file)
index 0000000..3922a9d
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "intl.h"
+
+static GtkWidget *quote_desc_win;
+
+static void quote_fmt_quote_description_create         (void);
+static void quote_fmt_quote_description_key_pressed    (GtkWidget *widget,
+                                                        GdkEventKey *event,
+                                                        gpointer data);
+
+static gchar *symbol_table[][2] =
+{
+       {"%d",          N_("Date")}, /* date */
+       {"%f",          N_("From")}, /* from */
+       {"%N",          N_("Full Name of Sender")}, /* full name */
+       {"%F",          N_("First Name of Sender")}, /* first name */
+       {"%I",          N_("Initial of Sender")}, /* initial of sender */
+       {"%s",          N_("Subject")}, /* subject */ 
+       {"%t",          N_("To")}, /* to */ 
+       {"%c",          N_("Cc")}, /* cc */ 
+       {"%n",          N_("Newsgroups")}, /* newsgroups */ 
+       {"%r",          N_("References")}, /* references */ 
+       {"%i",          N_("Message-ID")}, /* message-id */ 
+       {"%M",          N_("Message body")}, /* message */ 
+       {"%Q",          N_("Quoted message body")}, /* quoted message */ 
+       {"%m",          N_("Message body without signature")}, /* message with no signature */ 
+       {"%q",          N_("Quoted message body without signature")}, /* quoted message with no signature */ 
+       {"",            NULL},
+       {"?x{expr}",    N_("Insert expr if x is set\nx is one of the characters above after \%")},
+       {"",            NULL},
+       {"\\%",         N_("Literal \%")}, /* % */ 
+       {"\\\\",        N_("Literal backslash")}, /* \ */ 
+       {"\\?",         N_("Literal question mark")}, /* ? */ 
+       {"\\|",         N_("Literal pipe")}, /* | */
+       {"\\{",         N_("Literal opening curly brace")},
+       {"\\}",         N_("Literal closing curly brace")},
+       {"",            NULL},
+       {"|f{file}",    N_("Insert File")}, /* insert file */ 
+       {"|p{command}", N_("Insert program output")}, /* insert program output */ 
+       {NULL,NULL},
+};
+
+void quote_fmt_quote_description(void)
+{
+       if (!quote_desc_win)
+               quote_fmt_quote_description_create();
+
+       manage_window_set_transient(GTK_WINDOW(quote_desc_win));
+       gtk_widget_show(quote_desc_win);
+       gtk_main();
+       gtk_widget_hide(quote_desc_win);
+}
+
+static void quote_fmt_quote_description_create(void)
+{
+       GtkWidget *table;
+       GtkWidget *hbbox;
+       GtkWidget *ok_btn;
+       int i;
+
+       quote_desc_win = gtk_window_new(GTK_WINDOW_DIALOG);
+       gtk_window_set_title(GTK_WINDOW(quote_desc_win),
+                            _("Description of symbols"));
+       gtk_container_set_border_width(GTK_CONTAINER(quote_desc_win), 8);
+       gtk_window_set_position(GTK_WINDOW(quote_desc_win), GTK_WIN_POS_CENTER);
+       gtk_window_set_modal(GTK_WINDOW(quote_desc_win), TRUE);
+       gtk_window_set_policy(GTK_WINDOW(quote_desc_win), FALSE, FALSE, FALSE);
+
+       table = gtk_table_new(sizeof(symbol_table), 2, FALSE);
+       gtk_container_add(GTK_CONTAINER(quote_desc_win), table);
+
+       for(i = 0; symbol_table[i][0] != NULL; i++) {
+               if(symbol_table[i][0][0] != '\0') {
+                       GtkWidget *label;
+
+                       label = gtk_label_new(symbol_table[i][0]);
+                       gtk_misc_set_alignment (GTK_MISC(label), 0, 0);
+                       gtk_table_attach(GTK_TABLE(table), label,
+                                        0, 1, i, i+1,
+                                        GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                                        0, 0);
+                       label = gtk_label_new(gettext(symbol_table[i][1]));
+                       gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+                       gtk_misc_set_alignment (GTK_MISC(label), 0, 0);
+                       gtk_table_attach(GTK_TABLE(table), label,
+                                        1, 2, i, i+1,
+                                        GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                                        0, 0);
+               } else {
+                       GtkWidget *separator;
+                       
+                       separator = gtk_hseparator_new();
+                       gtk_table_attach(GTK_TABLE(table), separator,
+                                        0, 2, i, i+1,
+                                        GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                                        0, 4);
+               }
+       }
+
+       gtkut_button_set_create(&hbbox, &ok_btn, _("OK"),
+                               NULL, NULL, NULL, NULL);
+       gtk_table_attach_defaults(GTK_TABLE(table), hbbox,
+                                 1, 2, i, i+1);
+
+       gtk_widget_grab_default(ok_btn);
+       gtk_signal_connect(GTK_OBJECT(ok_btn), "clicked",
+                          GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
+       gtk_signal_connect
+               (GTK_OBJECT(quote_desc_win), "key_press_event",
+                GTK_SIGNAL_FUNC(quote_fmt_quote_description_key_pressed),
+                NULL);
+       gtk_signal_connect(GTK_OBJECT(quote_desc_win), "delete_event",
+                          GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
+
+       gtk_widget_show_all(table);
+}
+
+static void quote_fmt_quote_description_key_pressed(GtkWidget *widget,
+                                               GdkEventKey *event,
+                                               gpointer data)
+{
+       if (event && event->keyval == GDK_Escape)
+               gtk_main_quit();
+}
+
index c9c4c004f3a5360860bd3df30a46aef2320739a8..f192f316923b9fb156869198a3f29d64fda449b5 100644 (file)
@@ -4,6 +4,8 @@
 
 #define quote_fmt_parse        quote_fmtparse
 
+void quote_fmt_quote_description(void);
+
 gchar *quote_fmt_get_buffer(void);
 void quote_fmt_init(MsgInfo *info, const gchar *my_quote_str,
                    const gchar *my_body);
index 7f904c17b88c5e960e5768fc5928f0356d12eec3..cac97e28a05fa7aa764c5e3574c22c3780b9b537 100644 (file)
 "%Q" /* quoted message */ return SHOW_QUOTED_MESSAGE;
 "%m" /* message with no signature */ return SHOW_MESSAGE_NO_SIGNATURE;
 "%q" /* quoted message with no signature */ return SHOW_QUOTED_MESSAGE_NO_SIGNATURE;
-"%%" /* % */ return SHOW_PERCENT;
+"\\\%" /* % */ return SHOW_PERCENT;
 "\\\\" /* \ */ return SHOW_BACKSLASH;
 "\\t"|"\t" /* tab */ return SHOW_TAB;
 "\\n"|"\n" /* return */ return SHOW_EOL;
 "\\?" /* ? */ return SHOW_QUESTION_MARK;
+"\\|" return SHOW_PIPE;
 "\\{" return SHOW_OPARENT;
 "\\}" return SHOW_CPARENT;
 "?d" /* query date */ return QUERY_DATE;
@@ -39,6 +40,8 @@
 "?n" /* query newsgroups */ return QUERY_NEWSGROUPS;
 "?i" /* query message-id */ return QUERY_MESSAGEID;
 "?r" /* query references */ return QUERY_REFERENCES;
+"|f" /* insert file */ return INSERT_FILE;
+"|p" /* insert program output */ return INSERT_PROGRAMOUTPUT;
 "{" return OPARENT;
 "}" return CPARENT;
 . { yylval.chr = yytext[0]; return CHARACTER; }
index 66ee7f5bee04610da640d7fe8014030c4e972e90..1989a56f2ff8934d9f613dbb5f8dc403830614de 100644 (file)
@@ -127,6 +127,7 @@ static int isseparator(char ch)
 
 %union {
        char chr;
+       char str[256];
 }
 
 %token SHOW_NEWSGROUPS
@@ -135,10 +136,11 @@ static int isseparator(char ch)
 %token SHOW_PERCENT SHOW_CC SHOW_REFERENCES SHOW_MESSAGE
 %token SHOW_QUOTED_MESSAGE SHOW_BACKSLASH SHOW_TAB
 %token SHOW_QUOTED_MESSAGE_NO_SIGNATURE SHOW_MESSAGE_NO_SIGNATURE
-%token SHOW_EOL SHOW_QUESTION_MARK SHOW_OPARENT SHOW_CPARENT
+%token SHOW_EOL SHOW_QUESTION_MARK SHOW_PIPE SHOW_OPARENT SHOW_CPARENT
 %token QUERY_DATE QUERY_FROM
 %token QUERY_FULLNAME QUERY_SUBJECT QUERY_TO QUERY_NEWSGROUPS
 %token QUERY_MESSAGEID QUERY_CC QUERY_REFERENCES
+%token INSERT_FILE INSERT_PROGRAMOUTPUT
 %token OPARENT CPARENT
 %token CHARACTER
 
@@ -146,29 +148,43 @@ static int isseparator(char ch)
 
 %token <chr> CHARACTER
 %type <chr> character
+%type <str> string
 
 %%
 
 quote_fmt:
-       character_or_special_or_query_list;
+       character_or_special_or_insert_or_query_list;
 
-character_or_special_or_query_list:
-       character_or_special_or_query character_or_special_or_query_list
-       | character_or_special_or_query ;
+character_or_special_or_insert_or_query_list:
+       character_or_special_or_insert_or_query character_or_special_or_insert_or_query_list
+       | character_or_special_or_insert_or_query ;
 
-character_or_special_or_query:
-       special ;
+character_or_special_or_insert_or_query:
+       special
        | character
        {
                INSERT_CHARACTER($1);
        }
        | query ;
-
+       | insert ;
 
 character:
        CHARACTER
        ;
 
+string:
+       CHARACTER
+       {
+               $$[0] = $1;
+               $$[1] = '\0';
+       }
+       | string CHARACTER
+       {
+               strcpy($$, $1);
+               $$[strlen($$) + 1] = '\0';
+               $$[strlen($$)] = $2;
+       };
+
 special:
        SHOW_NEWSGROUPS
        {
@@ -374,6 +390,10 @@ special:
        {
                INSERT("?");
        }
+       | SHOW_PIPE
+       {
+               INSERT("|");
+       }
        | SHOW_OPARENT
        {
                INSERT("{");
@@ -456,3 +476,31 @@ query:
        {
                remove_visibility();
        };
+
+insert:
+       INSERT_FILE OPARENT string CPARENT
+       {
+               {
+                       FILE *file;
+                       char buffer[256];
+                       
+                       if(file = fopen($3, "r")) {
+                               while(fgets(buffer, sizeof(buffer), file)) {
+                                       INSERT(buffer);
+                               }
+                       }
+               }
+       }
+       | INSERT_PROGRAMOUTPUT OPARENT string CPARENT
+       {
+               {
+                       FILE *file;
+                       char buffer[256];
+
+                       if(file = popen($3, "r")) {
+                               while(fgets(buffer, sizeof(buffer), file)) {
+                                       INSERT(buffer);
+                               }
+                       }
+               }
+       };