aboutsummaryrefslogtreecommitdiff
path: root/fref.lex
diff options
context:
space:
mode:
Diffstat (limited to 'fref.lex')
-rw-r--r--fref.lex127
1 files changed, 90 insertions, 37 deletions
diff --git a/fref.lex b/fref.lex
index d1ee949..dee3658 100644
--- a/fref.lex
+++ b/fref.lex
@@ -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);