diff options
Diffstat (limited to 'fref.lex')
-rw-r--r-- | fref.lex | 127 |
1 files changed, 90 insertions, 37 deletions
@@ -16,18 +16,6 @@ #define MAX 255 /* Max field length. */ - /* - * The following string constants can be redefined to support - * other languages. - */ - #define AND "och" - #define AVAIL "Tillgänglig: " - #define ED "red." - #define P "s." - #define PP "ss." - #define TR "Övers." - #define VOL "vol." - #define DO_FIELDS \ DO("ad",ad,e.ad) /* Access date. */ \ DO("bo",bo,e.bo) /* Book. */ \ @@ -52,14 +40,14 @@ void harvard(void); int pf(char *, ...); + extern char *optarg; + extern int optind; + char *name; int line; /* Line at which entry begins. */ int lines = 0; /* Total number of lines. */ - /* - * e is a struct holding all fields of the current entry. - * It is zeroed at the end of each call to entry(). - */ + /* Fields of current entry. */ struct entry { #define DO(s,n,m) char n[MAX]; DO_FIELDS @@ -68,6 +56,17 @@ char au[MAX][MAX]; /* Authors. */ } e; + /* Translation strings. */ + struct translations { + char *and; + char *avail; + char *ed; + char *p; + char *pp; + char *tr; + char *vo; + } t; + %% \n lines++; ECHO; ^%.*\n line = ++lines; field(yytext); BEGIN(ENTRY); @@ -77,32 +76,74 @@ %% void -main(int argc, char *argv[0]) +main(int argc, char *argv[]) { + char *lang; + int c; + + /* Save program name. */ name = strrchr(argv[0], '/'); if(name) name++; else name = argv[0]; + /* Parse command-line options. */ + while((c = getopt(argc, argv, "l:")) != -1) + switch(c){ + case 'l': + lang = optarg; + break; + default: + fprintf(stderr, "usage: %s [-lLANG]\n", argv[0]); + exit(1); + } + argc -= optind; + argv += optind; + + /* Set translation strings according to -l. */ + if(strncmp(lang, "sv", 2) == 0){ + t.and = strdup("och"); + t.avail = strdup("Tillgänglig: "); + t.ed = strdup("red. "); + t.p = strdup("s. "); + t.pp = strdup("ss. "); + t.tr = strdup("Övers. "); + t.vo = strdup("vol. "); + }else{ + t.and = strdup("and"); + t.avail = strdup("Available: "); + t.ed = strdup("ed. "); + t.p = strdup("p. "); + t.pp = strdup("pp. "); + t.tr = strdup("Trans. "); + t.vo = strdup("vol. "); + } + + /* Clear entry struct. */ memset(&e, 0, sizeof(e)); + yylex(); } /* Save entry field. */ void -field(char *t) +field(char *s) { - t++; - t[strcspn(t, "\n")] = 0; + s++; + s[strcspn(s, "\n")] = 0; /* Fill corresponding field. */ -#define AS(a,b) if(strncmp(t, a, 2) == 0 && (t += 3)){ strcpy(b, t); return; } +#define AS(a,b) if(strncmp(s, a, 2) == 0 && (s += 3)){ strcpy(b, s); return; } AS("au",e.au[e.a++]); #define DO(s,n,m) AS(s,m) DO_FIELDS #undef DO + /* + * As no field matched, an error is printed and the program exits + * with a positive value. + */ fprintf(stderr, "%s: unrecognized field %%%.2s at line %d\n", - name, t, lines); + name, s, lines); exit(1); } @@ -111,8 +152,8 @@ void entry() { /* - * Presently, fref supports only Harvard-style citations, but - * allows for future extensions. + Presently, fref supports only Harvard-style citations, but + this allows for future extensions. */ harvard(); } @@ -130,7 +171,7 @@ harvard() for(i = 0; i < e.a-2; i++) printf("%s, ", e.au[i]); if(i == e.a-2) - printf("%s "AND" ", e.au[i++]); + printf("%s %s ", e.au[i++], t.and); if(i == e.a-1) printf("%s", e.au[i]); @@ -141,16 +182,16 @@ harvard() if(*e.bo || *e.jo){ pf("%.\n", e.ti); pf("\\fI%\\fP", e.bo ? e.bo : e.jo); - pf(" ("ED" %)", e.ed); + pf(" (*%)", t.ed, e.ed); }else pf("\\fI%\\fP", e.ti); /* Print volume. */ - pf(", "VOL" %", e.vo); + pf(", *%", t.vo, e.vo); /* Print pages, converting hyphens to en dashes. */ if(*e.pp){ - printf(", %s ", strpbrk(e.pp, ",-") ? PP : P); + printf(", %s", strpbrk(e.pp, ",-") ? t.pp : t.p); for(i = 0; i < strlen(e.pp); i++){ if(e.pp[i] == '-') putchar('\\'); putchar(e.pp[i]); @@ -160,7 +201,7 @@ harvard() pf(".\n"); /* Print translator. */ - pf(TR" %.\n", e.tr); + pf("*%.\n", t.tr, e.tr); /* Print city, publisher. */ (pf("%: %.\n", e.ci, e.pu) || pf("%.\n", e.pu)); @@ -169,7 +210,7 @@ harvard() pf("%.\n", e.xx); /* Print hypertext reference. */ - pf(AVAIL"%\n", e.hr); + pf("*%\n", t.avail, e.hr); /* Print access date. */ pf("[%]\n", e.ad); @@ -184,7 +225,12 @@ harvard() #undef DO } -/* Print formatted text if given fields are non-empty. Clear fields. */ +/* + * This function interpolates any number of strings into a formatted + * string, which is printed only if all interpolated strings are non-empty. + * Interpolation points are marked by % or *. If a string is interpolated + * using %, the function empties it after printing it. + */ int pf(char *fmt, ...) { @@ -192,16 +238,18 @@ pf(char *fmt, ...) int i, n, sz; va_list ap; - /* Count given fields. */ + /* Count interpolated strings. */ for(n = 0, p = fmt; *p; p++) - if(*p == '%') + if(*p == '%' || *p == '*') n++; - /* Allocate memory. */ if(!(fs = malloc(n))) err(1, "malloc"); - /* Verify that no field is empty. */ + /* + * The strings to be interpolated are saved in fs. + * If any string is empty, the function returns false. + */ va_start(ap, fmt); for(i = 0; i < n; i++){ p = va_arg(ap, char *); @@ -211,12 +259,17 @@ pf(char *fmt, ...) } va_end(ap); - /* Print fields according to format. */ + /* Print formatted string. */ for(i = 0; *fmt; fmt++) switch(*fmt){ case '%': printf("%s", fs[i]); - fs[i++][0] = 0; + fs[i][0] = 0; + i++; + break; + case '*': + printf("%s", fs[i]); + i++; break; default: putchar(*fmt); |